diff options
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/gspca/sonixb.c | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 346305b12647..5033810f56fc 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -74,6 +74,10 @@ struct sensor_data { | |||
74 | /* sensor_data flags */ | 74 | /* sensor_data flags */ |
75 | #define F_GAIN 0x01 /* has gain */ | 75 | #define F_GAIN 0x01 /* has gain */ |
76 | #define F_SIF 0x02 /* sif or vga */ | 76 | #define F_SIF 0x02 /* sif or vga */ |
77 | #define F_RAW 0x04 /* sensor tested ok with raw bayer mode */ | ||
78 | |||
79 | /* priv field of struct v4l2_pix_format flags (do not use low nibble!) */ | ||
80 | #define MODE_RAW 0x10 /* raw bayer mode */ | ||
77 | 81 | ||
78 | /* ctrl_dis helper macros */ | 82 | /* ctrl_dis helper macros */ |
79 | #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) | 83 | #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) |
@@ -205,6 +209,11 @@ static struct ctrl sd_ctrls[] = { | |||
205 | }; | 209 | }; |
206 | 210 | ||
207 | static struct v4l2_pix_format vga_mode[] = { | 211 | static struct v4l2_pix_format vga_mode[] = { |
212 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
213 | .bytesperline = 160, | ||
214 | .sizeimage = 160 * 120, | ||
215 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
216 | .priv = 2 | MODE_RAW}, | ||
208 | {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, | 217 | {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, |
209 | .bytesperline = 160, | 218 | .bytesperline = 160, |
210 | .sizeimage = 160 * 120 * 5 / 4, | 219 | .sizeimage = 160 * 120 * 5 / 4, |
@@ -222,6 +231,11 @@ static struct v4l2_pix_format vga_mode[] = { | |||
222 | .priv = 0}, | 231 | .priv = 0}, |
223 | }; | 232 | }; |
224 | static struct v4l2_pix_format sif_mode[] = { | 233 | static struct v4l2_pix_format sif_mode[] = { |
234 | {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
235 | .bytesperline = 176, | ||
236 | .sizeimage = 176 * 144, | ||
237 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
238 | .priv = 1 | MODE_RAW}, | ||
225 | {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, | 239 | {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, |
226 | .bytesperline = 176, | 240 | .bytesperline = 176, |
227 | .sizeimage = 176 * 144 * 5 / 4, | 241 | .sizeimage = 176 * 144 * 5 / 4, |
@@ -237,7 +251,7 @@ static struct v4l2_pix_format sif_mode[] = { | |||
237 | static const __u8 initHv7131[] = { | 251 | static const __u8 initHv7131[] = { |
238 | 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, | 252 | 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, |
239 | 0x00, 0x00, | 253 | 0x00, 0x00, |
240 | 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* shift from 0x02 0x01 0x00 */ | 254 | 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, |
241 | 0x28, 0x1e, 0x60, 0x8a, 0x20, | 255 | 0x28, 0x1e, 0x60, 0x8a, 0x20, |
242 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c | 256 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c |
243 | }; | 257 | }; |
@@ -251,7 +265,7 @@ static const __u8 hv7131_sensor_init[][8] = { | |||
251 | static const __u8 initOv6650[] = { | 265 | static const __u8 initOv6650[] = { |
252 | 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, | 266 | 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, |
253 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 267 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
254 | 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, | 268 | 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, |
255 | 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 | 269 | 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 |
256 | }; | 270 | }; |
257 | static const __u8 ov6650_sensor_init[][8] = | 271 | static const __u8 ov6650_sensor_init[][8] = |
@@ -290,7 +304,7 @@ static const __u8 ov6650_sensor_init[][8] = | |||
290 | static const __u8 initOv7630[] = { | 304 | static const __u8 initOv7630[] = { |
291 | 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */ | 305 | 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */ |
292 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ | 306 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ |
293 | 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ | 307 | 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ |
294 | 0x28, 0x1e, /* H & V sizes r15 .. r16 */ | 308 | 0x28, 0x1e, /* H & V sizes r15 .. r16 */ |
295 | 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */ | 309 | 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */ |
296 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ | 310 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ |
@@ -334,7 +348,7 @@ static const __u8 ov7630_sensor_init_3[][8] = { | |||
334 | static const __u8 initPas106[] = { | 348 | static const __u8 initPas106[] = { |
335 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, | 349 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, |
336 | 0x00, 0x00, | 350 | 0x00, 0x00, |
337 | 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, | 351 | 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, |
338 | 0x16, 0x12, 0x24, COMP1, MCK_INIT1, | 352 | 0x16, 0x12, 0x24, COMP1, MCK_INIT1, |
339 | 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c | 353 | 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c |
340 | }; | 354 | }; |
@@ -384,7 +398,7 @@ static const __u8 pas106_sensor_init[][8] = { | |||
384 | static const __u8 initPas202[] = { | 398 | static const __u8 initPas202[] = { |
385 | 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, | 399 | 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, |
386 | 0x00, 0x00, | 400 | 0x00, 0x00, |
387 | 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */ | 401 | 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a, |
388 | 0x28, 0x1e, 0x28, 0x89, 0x20, | 402 | 0x28, 0x1e, 0x28, 0x89, 0x20, |
389 | 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c | 403 | 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c |
390 | }; | 404 | }; |
@@ -415,7 +429,7 @@ static const __u8 pas202_sensor_init[][8] = { | |||
415 | static const __u8 initTas5110[] = { | 429 | static const __u8 initTas5110[] = { |
416 | 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, | 430 | 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, |
417 | 0x00, 0x00, | 431 | 0x00, 0x00, |
418 | 0x00, 0x01, 0x00, 0x46, 0x09, 0x0a, /* shift from 0x45 0x09 0x0a */ | 432 | 0x00, 0x01, 0x00, 0x45, 0x09, 0x0a, |
419 | 0x16, 0x12, 0x60, 0x86, 0x2b, | 433 | 0x16, 0x12, 0x60, 0x86, 0x2b, |
420 | 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 | 434 | 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 |
421 | }; | 435 | }; |
@@ -428,7 +442,7 @@ static const __u8 tas5110_sensor_init[][8] = { | |||
428 | static const __u8 initTas5130[] = { | 442 | static const __u8 initTas5130[] = { |
429 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, | 443 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, |
430 | 0x00, 0x00, | 444 | 0x00, 0x00, |
431 | 0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a, | 445 | 0x00, 0x01, 0x00, 0x68, 0x0c, 0x0a, |
432 | 0x28, 0x1e, 0x60, COMP, MCK_INIT, | 446 | 0x28, 0x1e, 0x60, COMP, MCK_INIT, |
433 | 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c | 447 | 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c |
434 | }; | 448 | }; |
@@ -442,14 +456,15 @@ static const __u8 tas5130_sensor_init[][8] = { | |||
442 | 456 | ||
443 | struct sensor_data sensor_data[] = { | 457 | struct sensor_data sensor_data[] = { |
444 | SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), | 458 | SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), |
445 | SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), | 459 | SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW, 0, |
460 | 0x60), | ||
446 | SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, | 461 | SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, |
447 | F_GAIN, 0, 0x21), | 462 | F_GAIN, 0, 0x21), |
448 | SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ, | 463 | SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ, |
449 | 0), | 464 | 0), |
450 | SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0, | 465 | SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_RAW, |
451 | NO_EXPO|NO_FREQ, 0), | 466 | NO_EXPO|NO_FREQ, 0), |
452 | SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF, | 467 | SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW, |
453 | NO_BRIGHTNESS|NO_FREQ, 0), | 468 | NO_BRIGHTNESS|NO_FREQ, 0), |
454 | SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, | 469 | SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, |
455 | 0), | 470 | 0), |
@@ -819,6 +834,10 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
819 | cam->cam_mode = sif_mode; | 834 | cam->cam_mode = sif_mode; |
820 | cam->nmodes = ARRAY_SIZE(sif_mode); | 835 | cam->nmodes = ARRAY_SIZE(sif_mode); |
821 | } | 836 | } |
837 | if (!(sensor_data[sd->sensor].flags & F_RAW)) { | ||
838 | cam->cam_mode++; | ||
839 | cam->nmodes--; | ||
840 | } | ||
822 | sd->brightness = BRIGHTNESS_DEF; | 841 | sd->brightness = BRIGHTNESS_DEF; |
823 | sd->gain = GAIN_DEF; | 842 | sd->gain = GAIN_DEF; |
824 | sd->exposure = EXPOSURE_DEF; | 843 | sd->exposure = EXPOSURE_DEF; |
@@ -867,6 +886,9 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
867 | reg17_19[2] = mode ? 0x23 : 0x43; | 886 | reg17_19[2] = mode ? 0x23 : 0x43; |
868 | break; | 887 | break; |
869 | } | 888 | } |
889 | /* Disable compression when the raw bayer format has been selected */ | ||
890 | if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) | ||
891 | reg17_19[1] &= ~0x80; | ||
870 | 892 | ||
871 | /* reg 0x01 bit 2 video transfert on */ | 893 | /* reg 0x01 bit 2 video transfert on */ |
872 | reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1); | 894 | reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1); |
@@ -929,6 +951,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
929 | { | 951 | { |
930 | int i; | 952 | int i; |
931 | struct sd *sd = (struct sd *) gspca_dev; | 953 | struct sd *sd = (struct sd *) gspca_dev; |
954 | struct cam *cam = &gspca_dev->cam; | ||
932 | 955 | ||
933 | /* frames start with: | 956 | /* frames start with: |
934 | * ff ff 00 c4 c4 96 synchro | 957 | * ff ff 00 c4 c4 96 synchro |
@@ -982,6 +1005,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
982 | } | 1005 | } |
983 | } | 1006 | } |
984 | } | 1007 | } |
1008 | |||
1009 | if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) { | ||
1010 | /* In raw mode we sometimes get some garbage after the frame | ||
1011 | ignore this */ | ||
1012 | int used = frame->data_end - frame->data; | ||
1013 | int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage; | ||
1014 | |||
1015 | if (used + len > size) | ||
1016 | len = size - used; | ||
1017 | } | ||
1018 | |||
985 | gspca_frame_add(gspca_dev, INTER_PACKET, | 1019 | gspca_frame_add(gspca_dev, INTER_PACKET, |
986 | frame, data, len); | 1020 | frame, data, len); |
987 | } | 1021 | } |