aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/sq930x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/sq930x.c')
-rw-r--r--drivers/media/video/gspca/sq930x.c347
1 files changed, 74 insertions, 273 deletions
diff --git a/drivers/media/video/gspca/sq930x.c b/drivers/media/video/gspca/sq930x.c
index 37cee5e063cf..7ae6522d4edf 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,28 +37,20 @@ 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;
52enum { 43 u8 type;
44#define Generic 0
45#define Creative_live_motion 1
46};
47enum sensors {
53 SENSOR_ICX098BQ, 48 SENSOR_ICX098BQ,
54 SENSOR_LZ24BP, 49 SENSOR_LZ24BP,
55 SENSOR_MI0360, 50 SENSOR_MI0360,
56 SENSOR_MT9V111, 51 SENSOR_MT9V111, /* = MI360SOC */
57 SENSOR_OV7660, 52 SENSOR_OV7660,
58 SENSOR_OV9630, 53 SENSOR_OV9630,
59} sensors;
60 u8 type;
61#define Generic 0
62#define Creative_live_motion 1
63
64 u8 jpeg_hdr[JPEG_HDR_SZ];
65}; 54};
66 55
67static int sd_setexpo(struct gspca_dev *gspca_dev, __s32 val); 56static int sd_setexpo(struct gspca_dev *gspca_dev, __s32 val);
@@ -78,7 +67,7 @@ static const struct ctrl sd_ctrls[] = {
78 .minimum = 0x0001, 67 .minimum = 0x0001,
79 .maximum = 0x0fff, 68 .maximum = 0x0fff,
80 .step = 1, 69 .step = 1,
81#define EXPO_DEF 0x027d 70#define EXPO_DEF 0x0356
82 .default_value = EXPO_DEF, 71 .default_value = EXPO_DEF,
83 }, 72 },
84 .set = sd_setexpo, 73 .set = sd_setexpo,
@@ -92,7 +81,7 @@ static const struct ctrl sd_ctrls[] = {
92 .minimum = 0x01, 81 .minimum = 0x01,
93 .maximum = 0xff, 82 .maximum = 0xff,
94 .step = 1, 83 .step = 1,
95#define GAIN_DEF 0x61 84#define GAIN_DEF 0x8d
96 .default_value = GAIN_DEF, 85 .default_value = GAIN_DEF,
97 }, 86 },
98 .set = sd_setgain, 87 .set = sd_setgain,
@@ -101,30 +90,18 @@ static const struct ctrl sd_ctrls[] = {
101}; 90};
102 91
103static struct v4l2_pix_format vga_mode[] = { 92static struct v4l2_pix_format vga_mode[] = {
104 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 93 {320, 240, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE,
105 .bytesperline = 160,
106 .sizeimage = 160 * 120 * 5 / 8 + 590,
107 .colorspace = V4L2_COLORSPACE_JPEG,
108 .priv = 0},
109 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
110 .bytesperline = 320, 94 .bytesperline = 320,
111 .sizeimage = 320 * 240 * 4 / 8 + 590, 95 .sizeimage = 320 * 240,
112 .colorspace = V4L2_COLORSPACE_JPEG, 96 .colorspace = V4L2_COLORSPACE_SRGB,
113 .priv = 1}, 97 .priv = 0},
114 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 98 {640, 480, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE,
115 .bytesperline = 640, 99 .bytesperline = 640,
116 .sizeimage = 640 * 480 * 3 / 8 + 590, 100 .sizeimage = 640 * 480,
117 .colorspace = V4L2_COLORSPACE_JPEG, 101 .colorspace = V4L2_COLORSPACE_SRGB,
118 .priv = 2}, 102 .priv = 1},
119}; 103};
120 104
121/* JPEG quality indexed by webcam quality */
122#define QUAL_0 90
123#define QUAL_1 85
124#define QUAL_2 75
125#define QUAL_3 70
126static const u8 quality_tb[4] = { QUAL_0, QUAL_1, QUAL_2, QUAL_3 };
127
128/* sq930x registers */ 105/* sq930x registers */
129#define SQ930_CTRL_UCBUS_IO 0x0001 106#define SQ930_CTRL_UCBUS_IO 0x0001
130#define SQ930_CTRL_I2C_IO 0x0002 107#define SQ930_CTRL_I2C_IO 0x0002
@@ -302,7 +279,7 @@ static const struct i2c_write_cmd mt9v111_init_0[] = {
302 {0x01, 0x0001}, /* select IFP/SOC registers */ 279 {0x01, 0x0001}, /* select IFP/SOC registers */
303 {0x06, 0x300c}, /* operating mode control */ 280 {0x06, 0x300c}, /* operating mode control */
304 {0x08, 0xcc00}, /* output format control (RGB) */ 281 {0x08, 0xcc00}, /* output format control (RGB) */
305 {0x01, 0x0004}, /* select core registers */ 282 {0x01, 0x0004}, /* select sensor core registers */
306}; 283};
307static const struct i2c_write_cmd mt9v111_init_1[] = { 284static const struct i2c_write_cmd mt9v111_init_1[] = {
308 {0x03, 0x01e5}, /* window height */ 285 {0x03, 0x01e5}, /* window height */
@@ -330,7 +307,8 @@ static const struct i2c_write_cmd mt9v111_init_3[] = {
330 {0x62, 0x0405}, 307 {0x62, 0x0405},
331}; 308};
332static const struct i2c_write_cmd mt9v111_init_4[] = { 309static const struct i2c_write_cmd mt9v111_init_4[] = {
333 {0x05, 0x00ce}, /* horizontal blanking */ 310/* {0x05, 0x00ce}, */
311 {0x05, 0x005d}, /* horizontal blanking */
334}; 312};
335 313
336static const struct ucbus_write_cmd ov7660_start_0[] = { 314static const struct ucbus_write_cmd ov7660_start_0[] = {
@@ -343,78 +321,58 @@ static const struct ucbus_write_cmd ov9630_start_0[] = {
343 {0xf334, 0x3e}, {0xf335, 0xf8}, {0xf33f, 0x03} 321 {0xf334, 0x3e}, {0xf335, 0xf8}, {0xf33f, 0x03}
344}; 322};
345 323
324/* start parameters indexed by [sensor][mode] */
346static const struct cap_s { 325static const struct cap_s {
347 u8 cc_sizeid; 326 u8 cc_sizeid;
348 u8 cc_bytes[32]; 327 u8 cc_bytes[32];
349} capconfig[4][3] = { 328} capconfig[4][2] = {
350 [SENSOR_ICX098BQ] = { 329 [SENSOR_ICX098BQ] = {
351 {0, /* JPEG, 160x120 */ 330 {2, /* Bayer 320x240 */
331 {0x05, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
332 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
335 {4, /* Bayer 640x480 */
352 {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee, 336 {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
353 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 337 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
354 0x02, 0x8b, 0x00, 0x8b, 0x00, 0x41, 0x01, 0x41, 338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x01, 0x41, 0x01, 0x05, 0x40, 0x01, 0xf0, 0x00} }, 339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
356 {2, /* JPEG, 320x240 */
357 {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
358 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
359 0x02, 0xdf, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x3f,
360 0x01, 0x00, 0x00, 0x05, 0x40, 0x01, 0xf0, 0x00} },
361 {4, /* JPEG, 640x480 */
362 {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xf0,
363 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
364 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f,
365 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} },
366 }, 340 },
367 [SENSOR_LZ24BP] = { 341 [SENSOR_LZ24BP] = {
368 {0, /* JPEG, 160x120 */ 342 {2, /* Bayer 320x240 */
369 {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee, 343 {0x05, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee,
370 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 344 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
371 0x02, 0x8b, 0x00, 0x8b, 0x00, 0x41, 0x01, 0x41, 345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x01, 0x41, 0x01, 0x05, 0x40, 0x01, 0xf0, 0x00} }, 346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
373 {2, /* JPEG, 320x240 */ 347 {4, /* Bayer 640x480 */
374 {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee, 348 {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee,
375 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 349 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
376 0x02, 0xdf, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x3f, 350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x01, 0x00, 0x00, 0x05, 0x40, 0x01, 0xf0, 0x00} }, 351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
378 {4, /* JPEG, 640x480 */
379 {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xf0,
380 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
381 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f,
382 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} },
383 }, 352 },
384 [SENSOR_MI0360] = { 353 [SENSOR_MI0360] = {
385 {0, /* JPEG, 160x120 */ 354 {2, /* Bayer 320x240 */
386 {0x05, 0x3d, 0x20, 0x0b, 0x00, 0xbd, 0x02, 0x0b, 355 {0x05, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
387 0x02, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 356 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
388 0x02, 0x01, 0x01, 0x01, 0x01, 0x9f, 0x00, 0x9f, 357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x9f, 0x01, 0x05, 0xa0, 0x00, 0x80, 0x00} }, 358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
390 {2, /* JPEG, 320x240 */ 359 {4, /* Bayer 640x480 */
391 {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1, 360 {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
392/*fixme 03 e3 */
393 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 361 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
394 0x02, 0xdf, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x3f, 362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 0x01, 0x00, 0x00, 0x05, 0x40, 0x01, 0xf0, 0x00} }, 363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
396 {4, /* JPEG, 640x480 */
397 {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe3,
398 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
399 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f,
400 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} },
401 }, 364 },
402 [SENSOR_MT9V111] = { 365 [SENSOR_MT9V111] = {
403 {0, /* JPEG, 160x120 */ 366 {2, /* Bayer 320x240 */
404 {0x05, 0x3d, 0x20, 0x0b, 0x00, 0xbd, 0x02, 0x0b, 367 {0x05, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
405 0x02, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 368 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
406 0x02, 0x01, 0x01, 0x01, 0x01, 0x9f, 0x00, 0x9f, 369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407 0x00, 0x9f, 0x01, 0x05, 0xa0, 0x00, 0x80, 0x00} }, 370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
408 {2, /* JPEG, 320x240 */ 371 {4, /* Bayer 640x480 */
409 {0x01, 0x02, 0x20, 0x03, 0x20, 0x82, 0x02, 0xe3, 372 {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
410 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
411 0x02, 0xdf, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x3f,
412 0x01, 0x00, 0x00, 0x05, 0x40, 0x01, 0xf0, 0x00} },
413 {4, /* JPEG, 640x480 */
414 {0x01, 0x02, 0x20, 0x03, 0x20, 0x82, 0x02, 0xe3,
415 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, 373 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
416 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f, 374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
417 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} }, 375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
418 }, 376 },
419}; 377};
420 378
@@ -864,7 +822,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
864 buf[i++] = 0x35; /* reg = global gain */ 822 buf[i++] = 0x35; /* reg = global gain */
865 buf[i++] = 0x00; /* val H */ 823 buf[i++] = 0x00; /* val H */
866 buf[i++] = sensor->i2c_dum; 824 buf[i++] = sensor->i2c_dum;
867 buf[i++] = sd->gain; /* val L */ 825 buf[i++] = 0x80 + sd->gain / 2; /* val L */
868 buf[i++] = 0x00; 826 buf[i++] = 0x00;
869 buf[i++] = 0x00; 827 buf[i++] = 0x00;
870 buf[i++] = 0x00; 828 buf[i++] = 0x00;
@@ -889,10 +847,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
889 cam->nmodes = ARRAY_SIZE(vga_mode); 847 cam->nmodes = ARRAY_SIZE(vga_mode);
890 848
891 cam->bulk = 1; 849 cam->bulk = 1;
892 cam->bulk_size = BULK_TRANSFER_LEN;
893/* cam->bulk_nurbs = 2; fixme: if no setexpo sync */
894 850
895 sd->quality = QUALITY_DEF;
896 sd->gain = GAIN_DEF; 851 sd->gain = GAIN_DEF;
897 sd->expo = EXPO_DEF; 852 sd->expo = EXPO_DEF;
898 853
@@ -945,13 +900,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
945 if (sd->sensor == SENSOR_MI0360) { 900 if (sd->sensor == SENSOR_MI0360) {
946 901
947 /* no sensor probe for icam tracer */ 902 /* no sensor probe for icam tracer */
948 if (gspca_dev->usb_buf[5] == 0xf6) { /* if CMOS */ 903 if (gspca_dev->usb_buf[5] == 0xf6) /* if CMOS */
949 sd->sensor = SENSOR_ICX098BQ; 904 sd->sensor = SENSOR_ICX098BQ;
950 gspca_dev->cam.cam_mode = &vga_mode[1]; 905 else
951 gspca_dev->cam.nmodes = 1; /* only 320x240 */
952 } else {
953 cmos_probe(gspca_dev); 906 cmos_probe(gspca_dev);
954 }
955 } 907 }
956 908
957 PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name); 909 PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name);
@@ -960,51 +912,24 @@ static int sd_init(struct gspca_dev *gspca_dev)
960 return gspca_dev->usb_err; 912 return gspca_dev->usb_err;
961} 913}
962 914
963/* special function to create the quantization tables of the JPEG header */
964static void sd_jpeg_set_qual(u8 *jpeg_hdr,
965 int quality)
966{
967 int i, sc1, sc2;
968
969 quality = quality_tb[quality]; /* convert to JPEG quality */
970/*
971 * approximative qualities for Y and U/V:
972 * quant = 0:94%/91% 1:91%/87% 2:82%/73% 3:69%/56%
973 * should have:
974 * quant = 0:94%/91% 1:91%/87.5% 2:81.5%/72% 3:69%/54.5%
975 */
976 sc1 = 200 - quality * 2;
977 quality = quality * 7 / 5 - 40; /* UV quality */
978 sc2 = 200 - quality * 2;
979 for (i = 0; i < 64; i++) {
980 jpeg_hdr[JPEG_QT0_OFFSET + i] =
981 (jpeg_head[JPEG_QT0_OFFSET + i] * sc1 + 50) / 100;
982 jpeg_hdr[JPEG_QT1_OFFSET + i] =
983 (jpeg_head[JPEG_QT1_OFFSET + i] * sc2 + 50) / 100;
984 }
985}
986
987/* send the start/stop commands to the webcam */ 915/* send the start/stop commands to the webcam */
988static void send_start(struct gspca_dev *gspca_dev) 916static void send_start(struct gspca_dev *gspca_dev)
989{ 917{
990 struct sd *sd = (struct sd *) gspca_dev; 918 struct sd *sd = (struct sd *) gspca_dev;
991 const struct cap_s *cap; 919 const struct cap_s *cap;
992 int mode, quality; 920 int mode;
993 921
994 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 922 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
995 cap = &capconfig[sd->sensor][mode]; 923 cap = &capconfig[sd->sensor][mode];
996 quality = sd->quality; 924 reg_wb(gspca_dev, 0x0900 | SQ930_CTRL_CAP_START,
997 reg_wb(gspca_dev, (quality << 12) 925 0x0a00 | cap->cc_sizeid,
998 | 0x0a00 /* 900 for Bayer */
999 | SQ930_CTRL_CAP_START,
1000 0x0500 /* a00 for Bayer */
1001 | cap->cc_sizeid,
1002 cap->cc_bytes, 32); 926 cap->cc_bytes, 32);
1003}; 927}
928
1004static void send_stop(struct gspca_dev *gspca_dev) 929static void send_stop(struct gspca_dev *gspca_dev)
1005{ 930{
1006 reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0); 931 reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0);
1007}; 932}
1008 933
1009/* function called at start time before URB creation */ 934/* function called at start time before URB creation */
1010static int sd_isoc_init(struct gspca_dev *gspca_dev) 935static int sd_isoc_init(struct gspca_dev *gspca_dev)
@@ -1013,6 +938,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev)
1013 938
1014 gspca_dev->cam.bulk_nurbs = 1; /* there must be one URB only */ 939 gspca_dev->cam.bulk_nurbs = 1; /* there must be one URB only */
1015 sd->do_ctrl = 0; 940 sd->do_ctrl = 0;
941 gspca_dev->cam.bulk_size = gspca_dev->width * gspca_dev->height + 8;
1016 return 0; 942 return 0;
1017} 943}
1018 944
@@ -1022,11 +948,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
1022 struct sd *sd = (struct sd *) gspca_dev; 948 struct sd *sd = (struct sd *) gspca_dev;
1023 int mode; 949 int mode;
1024 950
1025 /* initialize the JPEG header */
1026 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
1027 0x21); /* JPEG 422 */
1028 sd_jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1029
1030 bridge_init(sd); 951 bridge_init(sd);
1031 global_init(sd, 0); 952 global_init(sd, 0);
1032 msleep(100); 953 msleep(100);
@@ -1071,7 +992,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1071 ARRAY_SIZE(lz24bp_start_2), 992 ARRAY_SIZE(lz24bp_start_2),
1072 6); 993 6);
1073 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 994 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1074 lz24bp_ppl(sd, mode == 2 ? 0x0564 : 0x0310); 995 lz24bp_ppl(sd, mode == 1 ? 0x0564 : 0x0310);
1075 msleep(10); 996 msleep(10);
1076 break; 997 break;
1077 case SENSOR_MI0360: 998 case SENSOR_MI0360:
@@ -1095,7 +1016,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1095 /* 1st start */ 1016 /* 1st start */
1096 send_start(gspca_dev); 1017 send_start(gspca_dev);
1097 msleep(60); 1018 msleep(60);
1098 reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0x0000); 1019 send_stop(gspca_dev);
1099 1020
1100 i2c_write(sd, 1021 i2c_write(sd,
1101 mi0360_start_4, ARRAY_SIZE(mi0360_start_4)); 1022 mi0360_start_4, ARRAY_SIZE(mi0360_start_4));
@@ -1113,7 +1034,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1113 ARRAY_SIZE(mt9v111_init_2)); 1034 ARRAY_SIZE(mt9v111_init_2));
1114 ucbus_write(gspca_dev, mt9v111_start_1, 1035 ucbus_write(gspca_dev, mt9v111_start_1,
1115 ARRAY_SIZE(mt9v111_start_1), 1036 ARRAY_SIZE(mt9v111_start_1),
1116 8); 1037 5);
1117 i2c_write(sd, mt9v111_init_3, 1038 i2c_write(sd, mt9v111_init_3,
1118 ARRAY_SIZE(mt9v111_init_3)); 1039 ARRAY_SIZE(mt9v111_init_3));
1119 i2c_write(sd, mt9v111_init_4, 1040 i2c_write(sd, mt9v111_init_4,
@@ -1125,8 +1046,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
1125out: 1046out:
1126 msleep(1000); 1047 msleep(1000);
1127 1048
1128 sd->eof_len = 0; /* init packet scan */
1129
1130 if (sd->sensor == SENSOR_MT9V111) 1049 if (sd->sensor == SENSOR_MT9V111)
1131 gpio_set(sd, SQ930_GPIO_DFL_LED, SQ930_GPIO_DFL_LED); 1050 gpio_set(sd, SQ930_GPIO_DFL_LED, SQ930_GPIO_DFL_LED);
1132 1051
@@ -1166,94 +1085,17 @@ static void sd_dq_callback(struct gspca_dev *gspca_dev)
1166 msleep(100); 1085 msleep(100);
1167} 1086}
1168 1087
1169/* move a packet adding 0x00 after 0xff */
1170static void add_packet(struct gspca_dev *gspca_dev,
1171 u8 *data,
1172 int len)
1173{
1174 int i;
1175
1176 i = 0;
1177 do {
1178 if (data[i] == 0xff) {
1179 gspca_frame_add(gspca_dev, INTER_PACKET,
1180 data, i + 1);
1181 len -= i;
1182 data += i;
1183 *data = 0x00;
1184 i = 0;
1185 }
1186 } while (++i < len);
1187 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1188}
1189
1190/* end a frame and start a new one */
1191static void eof_sof(struct gspca_dev *gspca_dev)
1192{
1193 struct sd *sd = (struct sd *) gspca_dev;
1194 static const u8 ffd9[] = {0xff, 0xd9};
1195
1196 /* if control set, stop bulk transfer */
1197 if (sd->do_ctrl
1198 && gspca_dev->last_packet_type == INTER_PACKET)
1199 gspca_dev->cam.bulk_nurbs = 0;
1200 gspca_frame_add(gspca_dev, LAST_PACKET,
1201 ffd9, 2);
1202 gspca_frame_add(gspca_dev, FIRST_PACKET,
1203 sd->jpeg_hdr, JPEG_HDR_SZ);
1204}
1205
1206static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1088static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1207 u8 *data, /* isoc packet */ 1089 u8 *data, /* isoc packet */
1208 int len) /* iso packet length */ 1090 int len) /* iso packet length */
1209{ 1091{
1210 struct sd *sd = (struct sd *) gspca_dev; 1092 struct sd *sd = (struct sd *) gspca_dev;
1211 u8 *p; 1093
1212 int l; 1094 if (sd->do_ctrl)
1213 1095 gspca_dev->cam.bulk_nurbs = 0;
1214 len -= 8; /* ignore last 8 bytes (00 00 55 aa 55 aa 00 00) */ 1096 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
1215 1097 gspca_frame_add(gspca_dev, INTER_PACKET, data, len - 8);
1216 /* 1098 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1217 * the end/start of frame is indicated by
1218 * 0x00 * 16 - 0xab * 8
1219 * aligned on 8 bytes boundary
1220 */
1221 if (sd->eof_len != 0) { /* if 'abababab' in previous pkt */
1222 if (*((u32 *) data) == 0xabababab) {
1223 /*fixme: should remove previous 0000ababab*/
1224 eof_sof(gspca_dev);
1225 data += 4;
1226 len -= 4;
1227 }
1228 sd->eof_len = 0;
1229 }
1230 p = data;
1231 l = len;
1232 for (;;) {
1233 if (*((u32 *) p) == 0xabababab) {
1234 if (l < 8) { /* (may be 4 only) */
1235 sd->eof_len = 1;
1236 break;
1237 }
1238 if (*((u32 *) p + 1) == 0xabababab) {
1239 add_packet(gspca_dev, data, p - data - 16);
1240 /* remove previous zeros */
1241 eof_sof(gspca_dev);
1242 p += 8;
1243 l -= 8;
1244 if (l <= 0)
1245 return;
1246 len = l;
1247 data = p;
1248 continue;
1249 }
1250 }
1251 p += 4;
1252 l -= 4;
1253 if (l <= 0)
1254 break;
1255 }
1256 add_packet(gspca_dev, data, len);
1257} 1099}
1258 1100
1259static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 1101static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
@@ -1291,45 +1133,6 @@ static int sd_getexpo(struct gspca_dev *gspca_dev, __s32 *val)
1291 return 0; 1133 return 0;
1292} 1134}
1293 1135
1294static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1295 struct v4l2_jpegcompression *jcomp)
1296{
1297 struct sd *sd = (struct sd *) gspca_dev;
1298 int quality;
1299
1300 if (jcomp->quality >= (QUAL_0 + QUAL_1) / 2)
1301 quality = 0;
1302 else if (jcomp->quality >= (QUAL_1 + QUAL_2) / 2)
1303 quality = 1;
1304 else if (jcomp->quality >= (QUAL_2 + QUAL_3) / 2)
1305 quality = 2;
1306 else
1307 quality = 3;
1308
1309 if (quality != sd->quality) {
1310 sd->quality = quality;
1311 if (gspca_dev->streaming) {
1312 send_stop(gspca_dev);
1313 sd_jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1314 msleep(70);
1315 send_start(gspca_dev);
1316 }
1317 }
1318 return gspca_dev->usb_err;
1319}
1320
1321static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1322 struct v4l2_jpegcompression *jcomp)
1323{
1324 struct sd *sd = (struct sd *) gspca_dev;
1325
1326 memset(jcomp, 0, sizeof *jcomp);
1327 jcomp->quality = quality_tb[sd->quality];
1328 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1329 | V4L2_JPEG_MARKER_DQT;
1330 return 0;
1331}
1332
1333/* sub-driver description */ 1136/* sub-driver description */
1334static const struct sd_desc sd_desc = { 1137static const struct sd_desc sd_desc = {
1335 .name = MODULE_NAME, 1138 .name = MODULE_NAME,
@@ -1342,8 +1145,6 @@ static const struct sd_desc sd_desc = {
1342 .stopN = sd_stopN, 1145 .stopN = sd_stopN,
1343 .pkt_scan = sd_pkt_scan, 1146 .pkt_scan = sd_pkt_scan,
1344 .dq_callback = sd_dq_callback, 1147 .dq_callback = sd_dq_callback,
1345 .get_jcomp = sd_get_jcomp,
1346 .set_jcomp = sd_set_jcomp,
1347}; 1148};
1348 1149
1349/* Table of supported USB devices */ 1150/* Table of supported USB devices */