diff options
Diffstat (limited to 'drivers/media/video/gspca/sq930x.c')
-rw-r--r-- | drivers/media/video/gspca/sq930x.c | 347 |
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 | ||
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,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; |
52 | enum { | 43 | u8 type; |
44 | #define Generic 0 | ||
45 | #define Creative_live_motion 1 | ||
46 | }; | ||
47 | enum 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 | ||
67 | static int sd_setexpo(struct gspca_dev *gspca_dev, __s32 val); | 56 | static 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 | ||
103 | static struct v4l2_pix_format vga_mode[] = { | 92 | static 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 | ||
126 | static 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 | }; |
307 | static const struct i2c_write_cmd mt9v111_init_1[] = { | 284 | static 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 | }; |
332 | static const struct i2c_write_cmd mt9v111_init_4[] = { | 309 | static 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 | ||
336 | static const struct ucbus_write_cmd ov7660_start_0[] = { | 314 | static 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] */ | ||
346 | static const struct cap_s { | 325 | static 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 */ | ||
964 | static 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 */ |
988 | static void send_start(struct gspca_dev *gspca_dev) | 916 | static 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 | |||
1004 | static void send_stop(struct gspca_dev *gspca_dev) | 929 | static 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 */ |
1010 | static int sd_isoc_init(struct gspca_dev *gspca_dev) | 935 | static 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) | |||
1125 | out: | 1046 | out: |
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 */ | ||
1170 | static 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 */ | ||
1191 | static 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 | |||
1206 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1088 | static 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 | ||
1259 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | 1101 | static 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 | ||
1294 | static 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 | |||
1321 | static 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 */ |
1334 | static const struct sd_desc sd_desc = { | 1137 | static 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 */ |