aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2010-07-26 06:23:00 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-08 22:42:52 -0400
commit82d2c7aa85e0c7902cd309acafa375b61e147ce6 (patch)
treee3b3a6696f714ae0761a4e1adefff130945822ed /drivers
parentd6f5bd6d197cb91de296632c4667fcce74e4f5fb (diff)
V4L/DVB: gspca - sq930x: Change image format to Bayer mode
The JPEG format did not work fine. The Bayer format offers correct VGA (640x480) resolution, but bad QQVGA (160x120). This last resolution is removed. Signed-off-by: Jean-François Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/gspca/sq930x.c312
1 files changed, 56 insertions, 256 deletions
diff --git a/drivers/media/video/gspca/sq930x.c b/drivers/media/video/gspca/sq930x.c
index cec3dafd2f55..4b50aa151f5c 100644
--- a/drivers/media/video/gspca/sq930x.c
+++ b/drivers/media/video/gspca/sq930x.c
@@ -23,7 +23,6 @@
23#define MODULE_NAME "sq930x" 23#define MODULE_NAME "sq930x"
24 24
25#include "gspca.h" 25#include "gspca.h"
26#include "jpeg.h"
27 26
28MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>\n" 27MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>\n"
29 "Gerard Klaver <gerard at gkall dot hobby dot nl\n" 28 "Gerard Klaver <gerard at gkall dot hobby dot nl\n"
@@ -31,8 +30,6 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>\n"
31MODULE_DESCRIPTION("GSPCA/SQ930x USB Camera Driver"); 30MODULE_DESCRIPTION("GSPCA/SQ930x USB Camera Driver");
32MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
33 32
34#define BULK_TRANSFER_LEN 5128
35
36/* Structure to hold all of our device specific stuff */ 33/* Structure to hold all of our device specific stuff */
37struct sd { 34struct sd {
38 struct gspca_dev gspca_dev; /* !! must be the first item */ 35 struct gspca_dev gspca_dev; /* !! must be the first item */
@@ -40,14 +37,8 @@ struct sd {
40 u16 expo; 37 u16 expo;
41 u8 gain; 38 u8 gain;
42 39
43 u8 quality; /* webcam quality 0..3 */
44#define QUALITY_DEF 1
45
46 u8 gpio[2];
47
48 u8 eof_len;
49 u8 do_ctrl; 40 u8 do_ctrl;
50 41 u8 gpio[2];
51 u8 sensor; 42 u8 sensor;
52 u8 type; 43 u8 type;
53#define Generic 0 44#define Generic 0
@@ -99,30 +90,18 @@ static const struct ctrl sd_ctrls[] = {
99}; 90};
100 91
101static struct v4l2_pix_format vga_mode[] = { 92static struct v4l2_pix_format vga_mode[] = {
102 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 93 {320, 240, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE,
103 .bytesperline = 160,
104 .sizeimage = 160 * 120 * 5 / 8 + 590,
105 .colorspace = V4L2_COLORSPACE_JPEG,
106 .priv = 0},
107 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
108 .bytesperline = 320, 94 .bytesperline = 320,
109 .sizeimage = 320 * 240 * 4 / 8 + 590, 95 .sizeimage = 320 * 240,
110 .colorspace = V4L2_COLORSPACE_JPEG, 96 .colorspace = V4L2_COLORSPACE_SRGB,
111 .priv = 1}, 97 .priv = 0},
112 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 98 {640, 480, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE,
113 .bytesperline = 640, 99 .bytesperline = 640,
114 .sizeimage = 640 * 480 * 3 / 8 + 590, 100 .sizeimage = 640 * 480,
115 .colorspace = V4L2_COLORSPACE_JPEG, 101 .colorspace = V4L2_COLORSPACE_SRGB,
116 .priv = 2}, 102 .priv = 1},
117}; 103};
118 104
119/* JPEG quality indexed by webcam quality */
120#define QUAL_0 90
121#define QUAL_1 85
122#define QUAL_2 75
123#define QUAL_3 70
124static const u8 quality_tb[4] = { QUAL_0, QUAL_1, QUAL_2, QUAL_3 };
125
126/* sq930x registers */ 105/* sq930x registers */
127#define SQ930_CTRL_UCBUS_IO 0x0001 106#define SQ930_CTRL_UCBUS_IO 0x0001
128#define SQ930_CTRL_I2C_IO 0x0002 107#define SQ930_CTRL_I2C_IO 0x0002
@@ -344,75 +323,54 @@ static const struct ucbus_write_cmd ov9630_start_0[] = {
344static const struct cap_s { 323static const struct cap_s {
345 u8 cc_sizeid; 324 u8 cc_sizeid;
346 u8 cc_bytes[32]; 325 u8 cc_bytes[32];
347} capconfig[4][3] = { 326} capconfig[4][2] = {
348 [SENSOR_ICX098BQ] = { 327 [SENSOR_ICX098BQ] = {
349 {0, /* JPEG, 160x120 */ 328 {2, /* Bayer 320x240 */
329 {0x05, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
330 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
333 {4, /* Bayer 640x480 */
350 {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee, 334 {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
351 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 335 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
352 0x02, 0x8b, 0x00, 0x8b, 0x00, 0x41, 0x01, 0x41, 336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x01, 0x41, 0x01, 0x05, 0x40, 0x01, 0xf0, 0x00} }, 337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
354 {2, /* JPEG, 320x240 */
355 {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
356 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
357 0x02, 0xdf, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x3f,
358 0x01, 0x00, 0x00, 0x05, 0x40, 0x01, 0xf0, 0x00} },
359 {4, /* JPEG, 640x480 */
360 {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xf0,
361 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
362 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f,
363 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} },
364 }, 338 },
365 [SENSOR_LZ24BP] = { 339 [SENSOR_LZ24BP] = {
366 {0, /* JPEG, 160x120 */ 340 {2, /* Bayer 320x240 */
367 {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee, 341 {0x05, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee,
368 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 342 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
369 0x02, 0x8b, 0x00, 0x8b, 0x00, 0x41, 0x01, 0x41, 343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x01, 0x41, 0x01, 0x05, 0x40, 0x01, 0xf0, 0x00} }, 344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
371 {2, /* JPEG, 320x240 */ 345 {4, /* Bayer 640x480 */
372 {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee, 346 {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee,
373 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 347 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
374 0x02, 0xdf, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x3f, 348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0x01, 0x00, 0x00, 0x05, 0x40, 0x01, 0xf0, 0x00} }, 349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
376 {4, /* JPEG, 640x480 */
377 {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xf0,
378 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
379 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f,
380 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} },
381 }, 350 },
382 [SENSOR_MI0360] = { 351 [SENSOR_MI0360] = {
383 {0, /* JPEG, 160x120 */ 352 {2, /* Bayer 320x240 */
384 {0x05, 0x3d, 0x20, 0x0b, 0x00, 0xbd, 0x02, 0x0b, 353 {0x05, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
385 0x02, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 354 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
386 0x02, 0x01, 0x01, 0x01, 0x01, 0x9f, 0x00, 0x9f, 355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0x9f, 0x01, 0x05, 0xa0, 0x00, 0x80, 0x00} }, 356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
388 {2, /* JPEG, 320x240 */ 357 {4, /* Bayer 640x480 */
389 {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1, 358 {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
390/*fixme 03 e3 */
391 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
392 0x02, 0xdf, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x3f,
393 0x01, 0x00, 0x00, 0x05, 0x40, 0x01, 0xf0, 0x00} },
394 {4, /* JPEG, 640x480 */
395 {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe3,
396 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 359 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
397 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f, 360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} }, 361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
399 }, 362 },
400 [SENSOR_MT9V111] = { 363 [SENSOR_MT9V111] = {
401 {0, /* JPEG, 160x120 */ 364 {2, /* Bayer 320x240 */
402 {0x05, 0x3d, 0x20, 0x0b, 0x00, 0xbd, 0x02, 0x0b, 365 {0x05, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
403 0x02, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 366 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
404 0x02, 0x01, 0x01, 0x01, 0x01, 0x9f, 0x00, 0x9f, 367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x9f, 0x01, 0x05, 0xa0, 0x00, 0x80, 0x00} }, 368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
406 {2, /* JPEG, 320x240 */ 369 {4, /* Bayer 640x480 */
407 {0x01, 0x02, 0x20, 0x03, 0x20, 0x82, 0x02, 0xe3, 370 {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
408 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
409 0x02, 0xdf, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x3f,
410 0x01, 0x00, 0x00, 0x05, 0x40, 0x01, 0xf0, 0x00} },
411 {4, /* JPEG, 640x480 */
412 {0x01, 0x02, 0x20, 0x03, 0x20, 0x82, 0x02, 0xe3,
413 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 371 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
414 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f, 372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} }, 373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
416 }, 374 },
417}; 375};
418 376
@@ -887,10 +845,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
887 cam->nmodes = ARRAY_SIZE(vga_mode); 845 cam->nmodes = ARRAY_SIZE(vga_mode);
888 846
889 cam->bulk = 1; 847 cam->bulk = 1;
890 cam->bulk_size = BULK_TRANSFER_LEN;
891/* cam->bulk_nurbs = 2; fixme: if no setexpo sync */
892 848
893 sd->quality = QUALITY_DEF;
894 sd->gain = GAIN_DEF; 849 sd->gain = GAIN_DEF;
895 sd->expo = EXPO_DEF; 850 sd->expo = EXPO_DEF;
896 851
@@ -943,13 +898,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
943 if (sd->sensor == SENSOR_MI0360) { 898 if (sd->sensor == SENSOR_MI0360) {
944 899
945 /* no sensor probe for icam tracer */ 900 /* no sensor probe for icam tracer */
946 if (gspca_dev->usb_buf[5] == 0xf6) { /* if CMOS */ 901 if (gspca_dev->usb_buf[5] == 0xf6) /* if CMOS */
947 sd->sensor = SENSOR_ICX098BQ; 902 sd->sensor = SENSOR_ICX098BQ;
948 gspca_dev->cam.cam_mode = &vga_mode[1]; 903 else
949 gspca_dev->cam.nmodes = 1; /* only 320x240 */
950 } else {
951 cmos_probe(gspca_dev); 904 cmos_probe(gspca_dev);
952 }
953 } 905 }
954 906
955 PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name); 907 PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name);
@@ -958,45 +910,17 @@ static int sd_init(struct gspca_dev *gspca_dev)
958 return gspca_dev->usb_err; 910 return gspca_dev->usb_err;
959} 911}
960 912
961/* special function to create the quantization tables of the JPEG header */
962static void sd_jpeg_set_qual(u8 *jpeg_hdr,
963 int quality)
964{
965 int i, sc1, sc2;
966
967 quality = quality_tb[quality]; /* convert to JPEG quality */
968/*
969 * approximative qualities for Y and U/V:
970 * quant = 0:94%/91% 1:91%/87% 2:82%/73% 3:69%/56%
971 * should have:
972 * quant = 0:94%/91% 1:91%/87.5% 2:81.5%/72% 3:69%/54.5%
973 */
974 sc1 = 200 - quality * 2;
975 quality = quality * 7 / 5 - 40; /* UV quality */
976 sc2 = 200 - quality * 2;
977 for (i = 0; i < 64; i++) {
978 jpeg_hdr[JPEG_QT0_OFFSET + i] =
979 (jpeg_head[JPEG_QT0_OFFSET + i] * sc1 + 50) / 100;
980 jpeg_hdr[JPEG_QT1_OFFSET + i] =
981 (jpeg_head[JPEG_QT1_OFFSET + i] * sc2 + 50) / 100;
982 }
983}
984
985/* send the start/stop commands to the webcam */ 913/* send the start/stop commands to the webcam */
986static void send_start(struct gspca_dev *gspca_dev) 914static void send_start(struct gspca_dev *gspca_dev)
987{ 915{
988 struct sd *sd = (struct sd *) gspca_dev; 916 struct sd *sd = (struct sd *) gspca_dev;
989 const struct cap_s *cap; 917 const struct cap_s *cap;
990 int mode, quality; 918 int mode;
991 919
992 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 920 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
993 cap = &capconfig[sd->sensor][mode]; 921 cap = &capconfig[sd->sensor][mode];
994 quality = sd->quality; 922 reg_wb(gspca_dev, 0x0900 | SQ930_CTRL_CAP_START,
995 reg_wb(gspca_dev, (quality << 12) 923 0x0a00 | cap->cc_sizeid,
996 | 0x0a00 /* 900 for Bayer */
997 | SQ930_CTRL_CAP_START,
998 0x0500 /* a00 for Bayer */
999 | cap->cc_sizeid,
1000 cap->cc_bytes, 32); 924 cap->cc_bytes, 32);
1001}; 925};
1002static void send_stop(struct gspca_dev *gspca_dev) 926static void send_stop(struct gspca_dev *gspca_dev)
@@ -1011,6 +935,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev)
1011 935
1012 gspca_dev->cam.bulk_nurbs = 1; /* there must be one URB only */ 936 gspca_dev->cam.bulk_nurbs = 1; /* there must be one URB only */
1013 sd->do_ctrl = 0; 937 sd->do_ctrl = 0;
938 gspca_dev->cam.bulk_size = gspca_dev->width * gspca_dev->height + 8;
1014 return 0; 939 return 0;
1015} 940}
1016 941
@@ -1020,11 +945,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
1020 struct sd *sd = (struct sd *) gspca_dev; 945 struct sd *sd = (struct sd *) gspca_dev;
1021 int mode; 946 int mode;
1022 947
1023 /* initialize the JPEG header */
1024 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
1025 0x21); /* JPEG 422 */
1026 sd_jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1027
1028 bridge_init(sd); 948 bridge_init(sd);
1029 global_init(sd, 0); 949 global_init(sd, 0);
1030 msleep(100); 950 msleep(100);
@@ -1069,7 +989,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1069 ARRAY_SIZE(lz24bp_start_2), 989 ARRAY_SIZE(lz24bp_start_2),
1070 6); 990 6);
1071 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 991 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1072 lz24bp_ppl(sd, mode == 2 ? 0x0564 : 0x0310); 992 lz24bp_ppl(sd, mode == 1 ? 0x0564 : 0x0310);
1073 msleep(10); 993 msleep(10);
1074 break; 994 break;
1075 case SENSOR_MI0360: 995 case SENSOR_MI0360:
@@ -1123,8 +1043,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
1123out: 1043out:
1124 msleep(1000); 1044 msleep(1000);
1125 1045
1126 sd->eof_len = 0; /* init packet scan */
1127
1128 if (sd->sensor == SENSOR_MT9V111) 1046 if (sd->sensor == SENSOR_MT9V111)
1129 gpio_set(sd, SQ930_GPIO_DFL_LED, SQ930_GPIO_DFL_LED); 1047 gpio_set(sd, SQ930_GPIO_DFL_LED, SQ930_GPIO_DFL_LED);
1130 1048
@@ -1164,94 +1082,17 @@ static void sd_dq_callback(struct gspca_dev *gspca_dev)
1164 msleep(100); 1082 msleep(100);
1165} 1083}
1166 1084
1167/* move a packet adding 0x00 after 0xff */
1168static void add_packet(struct gspca_dev *gspca_dev,
1169 u8 *data,
1170 int len)
1171{
1172 int i;
1173
1174 i = 0;
1175 do {
1176 if (data[i] == 0xff) {
1177 gspca_frame_add(gspca_dev, INTER_PACKET,
1178 data, i + 1);
1179 len -= i;
1180 data += i;
1181 *data = 0x00;
1182 i = 0;
1183 }
1184 } while (++i < len);
1185 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1186}
1187
1188/* end a frame and start a new one */
1189static void eof_sof(struct gspca_dev *gspca_dev)
1190{
1191 struct sd *sd = (struct sd *) gspca_dev;
1192 static const u8 ffd9[] = {0xff, 0xd9};
1193
1194 /* if control set, stop bulk transfer */
1195 if (sd->do_ctrl
1196 && gspca_dev->last_packet_type == INTER_PACKET)
1197 gspca_dev->cam.bulk_nurbs = 0;
1198 gspca_frame_add(gspca_dev, LAST_PACKET,
1199 ffd9, 2);
1200 gspca_frame_add(gspca_dev, FIRST_PACKET,
1201 sd->jpeg_hdr, JPEG_HDR_SZ);
1202}
1203
1204static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1085static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1205 u8 *data, /* isoc packet */ 1086 u8 *data, /* isoc packet */
1206 int len) /* iso packet length */ 1087 int len) /* iso packet length */
1207{ 1088{
1208 struct sd *sd = (struct sd *) gspca_dev; 1089 struct sd *sd = (struct sd *) gspca_dev;
1209 u8 *p; 1090
1210 int l; 1091 if (sd->do_ctrl)
1211 1092 gspca_dev->cam.bulk_nurbs = 0;
1212 len -= 8; /* ignore last 8 bytes (00 00 55 aa 55 aa 00 00) */ 1093 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
1213 1094 gspca_frame_add(gspca_dev, INTER_PACKET, data, len - 8);
1214 /* 1095 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1215 * the end/start of frame is indicated by
1216 * 0x00 * 16 - 0xab * 8
1217 * aligned on 8 bytes boundary
1218 */
1219 if (sd->eof_len != 0) { /* if 'abababab' in previous pkt */
1220 if (*((u32 *) data) == 0xabababab) {
1221 /*fixme: should remove previous 0000ababab*/
1222 eof_sof(gspca_dev);
1223 data += 4;
1224 len -= 4;
1225 }
1226 sd->eof_len = 0;
1227 }
1228 p = data;
1229 l = len;
1230 for (;;) {
1231 if (*((u32 *) p) == 0xabababab) {
1232 if (l < 8) { /* (may be 4 only) */
1233 sd->eof_len = 1;
1234 break;
1235 }
1236 if (*((u32 *) p + 1) == 0xabababab) {
1237 add_packet(gspca_dev, data, p - data - 16);
1238 /* remove previous zeros */
1239 eof_sof(gspca_dev);
1240 p += 8;
1241 l -= 8;
1242 if (l <= 0)
1243 return;
1244 len = l;
1245 data = p;
1246 continue;
1247 }
1248 }
1249 p += 4;
1250 l -= 4;
1251 if (l <= 0)
1252 break;
1253 }
1254 add_packet(gspca_dev, data, len);
1255} 1096}
1256 1097
1257static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 1098static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
@@ -1289,45 +1130,6 @@ static int sd_getexpo(struct gspca_dev *gspca_dev, __s32 *val)
1289 return 0; 1130 return 0;
1290} 1131}
1291 1132
1292static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1293 struct v4l2_jpegcompression *jcomp)
1294{
1295 struct sd *sd = (struct sd *) gspca_dev;
1296 int quality;
1297
1298 if (jcomp->quality >= (QUAL_0 + QUAL_1) / 2)
1299 quality = 0;
1300 else if (jcomp->quality >= (QUAL_1 + QUAL_2) / 2)
1301 quality = 1;
1302 else if (jcomp->quality >= (QUAL_2 + QUAL_3) / 2)
1303 quality = 2;
1304 else
1305 quality = 3;
1306
1307 if (quality != sd->quality) {
1308 sd->quality = quality;
1309 if (gspca_dev->streaming) {
1310 send_stop(gspca_dev);
1311 sd_jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1312 msleep(70);
1313 send_start(gspca_dev);
1314 }
1315 }
1316 return gspca_dev->usb_err;
1317}
1318
1319static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1320 struct v4l2_jpegcompression *jcomp)
1321{
1322 struct sd *sd = (struct sd *) gspca_dev;
1323
1324 memset(jcomp, 0, sizeof *jcomp);
1325 jcomp->quality = quality_tb[sd->quality];
1326 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1327 | V4L2_JPEG_MARKER_DQT;
1328 return 0;
1329}
1330
1331/* sub-driver description */ 1133/* sub-driver description */
1332static const struct sd_desc sd_desc = { 1134static const struct sd_desc sd_desc = {
1333 .name = MODULE_NAME, 1135 .name = MODULE_NAME,
@@ -1340,8 +1142,6 @@ static const struct sd_desc sd_desc = {
1340 .stopN = sd_stopN, 1142 .stopN = sd_stopN,
1341 .pkt_scan = sd_pkt_scan, 1143 .pkt_scan = sd_pkt_scan,
1342 .dq_callback = sd_dq_callback, 1144 .dq_callback = sd_dq_callback,
1343 .get_jcomp = sd_get_jcomp,
1344 .set_jcomp = sd_set_jcomp,
1345}; 1145};
1346 1146
1347/* Table of supported USB devices */ 1147/* Table of supported USB devices */