diff options
-rw-r--r-- | drivers/media/video/gspca/sq930x.c | 312 |
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 | ||
28 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>\n" | 27 | MODULE_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" | |||
31 | MODULE_DESCRIPTION("GSPCA/SQ930x USB Camera Driver"); | 30 | MODULE_DESCRIPTION("GSPCA/SQ930x USB Camera Driver"); |
32 | MODULE_LICENSE("GPL"); | 31 | MODULE_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 */ |
37 | struct sd { | 34 | struct 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 | ||
101 | static struct v4l2_pix_format vga_mode[] = { | 92 | static 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 | ||
124 | static 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[] = { | |||
344 | static const struct cap_s { | 323 | static 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 */ | ||
962 | static 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 */ |
986 | static void send_start(struct gspca_dev *gspca_dev) | 914 | static 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 | }; |
1002 | static void send_stop(struct gspca_dev *gspca_dev) | 926 | static 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) | |||
1123 | out: | 1043 | out: |
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 */ | ||
1168 | static 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 */ | ||
1189 | static 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 | |||
1204 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1085 | static 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 | ||
1257 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | 1098 | static 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 | ||
1292 | static 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 | |||
1319 | static 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 */ |
1332 | static const struct sd_desc sd_desc = { | 1134 | static 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 */ |