diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2010-09-12 16:05:11 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-20 23:05:57 -0400 |
commit | 479567ce3af7b99d645a3c53b8ca2fc65e46efdc (patch) | |
tree | d16fd87d5eec337c82fd195cd03ed301e883b68f /drivers/media/video/pwc | |
parent | a1de2e4b72f27b906cb2eea3003fd62377dbf5ea (diff) |
V4L/DVB: pwc: fully convert driver to V4L2
Remove the V4L1 API from this driver, making it fully V4L2.
Also fix a bug where the /dev/videoX device was created too early, which led
to initialization problems of the camera, making it unable to capture video.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/pwc')
-rw-r--r-- | drivers/media/video/pwc/Kconfig | 2 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-ctrl.c | 20 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-if.c | 23 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-misc.c | 4 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-uncompress.c | 2 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-v4l.c | 322 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc.h | 6 |
7 files changed, 40 insertions, 339 deletions
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig index 11980db22d31..8da42e4f1ba0 100644 --- a/drivers/media/video/pwc/Kconfig +++ b/drivers/media/video/pwc/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config USB_PWC | 1 | config USB_PWC |
2 | tristate "USB Philips Cameras" | 2 | tristate "USB Philips Cameras" |
3 | depends on VIDEO_V4L1 | 3 | depends on VIDEO_V4L2 |
4 | ---help--- | 4 | ---help--- |
5 | Say Y or M here if you want to use one of these Philips & OEM | 5 | Say Y or M here if you want to use one of these Philips & OEM |
6 | webcams: | 6 | webcams: |
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index f7f7e04cf485..6b8fbddc0747 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c | |||
@@ -261,7 +261,7 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) | |||
261 | PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret); | 261 | PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret); |
262 | return ret; | 262 | return ret; |
263 | } | 263 | } |
264 | if (pEntry->compressed && pdev->vpalette != VIDEO_PALETTE_RAW) | 264 | if (pEntry->compressed && pdev->pixfmt == V4L2_PIX_FMT_YUV420) |
265 | pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); | 265 | pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); |
266 | 266 | ||
267 | pdev->cmd_len = 3; | 267 | pdev->cmd_len = 3; |
@@ -321,7 +321,7 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, i | |||
321 | if (ret < 0) | 321 | if (ret < 0) |
322 | return ret; | 322 | return ret; |
323 | 323 | ||
324 | if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) | 324 | if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) |
325 | pwc_dec23_init(pdev, pdev->type, buf); | 325 | pwc_dec23_init(pdev, pdev->type, buf); |
326 | 326 | ||
327 | pdev->cmd_len = 13; | 327 | pdev->cmd_len = 13; |
@@ -356,7 +356,7 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i | |||
356 | fps = (frames / 5) - 1; | 356 | fps = (frames / 5) - 1; |
357 | 357 | ||
358 | /* special case: VGA @ 5 fps and snapshot is raw bayer mode */ | 358 | /* special case: VGA @ 5 fps and snapshot is raw bayer mode */ |
359 | if (size == PSZ_VGA && frames == 5 && snapshot && pdev->vpalette == VIDEO_PALETTE_RAW) | 359 | if (size == PSZ_VGA && frames == 5 && snapshot && pdev->pixfmt != V4L2_PIX_FMT_YUV420) |
360 | { | 360 | { |
361 | /* Only available in case the raw palette is selected or | 361 | /* Only available in case the raw palette is selected or |
362 | we have the decompressor available. This mode is | 362 | we have the decompressor available. This mode is |
@@ -394,7 +394,7 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i | |||
394 | if (ret < 0) | 394 | if (ret < 0) |
395 | return ret; | 395 | return ret; |
396 | 396 | ||
397 | if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) | 397 | if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) |
398 | pwc_dec23_init(pdev, pdev->type, buf); | 398 | pwc_dec23_init(pdev, pdev->type, buf); |
399 | 399 | ||
400 | pdev->cmd_len = 12; | 400 | pdev->cmd_len = 12; |
@@ -429,7 +429,7 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame | |||
429 | { | 429 | { |
430 | int ret, size; | 430 | int ret, size; |
431 | 431 | ||
432 | PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette); | 432 | PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n", width, height, frames, pdev->pixfmt); |
433 | size = pwc_decode_size(pdev, width, height); | 433 | size = pwc_decode_size(pdev, width, height); |
434 | if (size < 0) { | 434 | if (size < 0) { |
435 | PWC_DEBUG_MODULE("Could not find suitable size.\n"); | 435 | PWC_DEBUG_MODULE("Could not find suitable size.\n"); |
@@ -519,13 +519,13 @@ static void pwc_set_image_buffer_size(struct pwc_device *pdev) | |||
519 | { | 519 | { |
520 | int i, factor = 0; | 520 | int i, factor = 0; |
521 | 521 | ||
522 | /* for PALETTE_YUV420P */ | 522 | /* for V4L2_PIX_FMT_YUV420 */ |
523 | switch(pdev->vpalette) | 523 | switch (pdev->pixfmt) { |
524 | { | 524 | case V4L2_PIX_FMT_YUV420: |
525 | case VIDEO_PALETTE_YUV420P: | ||
526 | factor = 6; | 525 | factor = 6; |
527 | break; | 526 | break; |
528 | case VIDEO_PALETTE_RAW: | 527 | case V4L2_PIX_FMT_PWC1: |
528 | case V4L2_PIX_FMT_PWC2: | ||
529 | factor = 6; /* can be uncompressed YUV420P */ | 529 | factor = 6; /* can be uncompressed YUV420P */ |
530 | break; | 530 | break; |
531 | } | 531 | } |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index aea7e224cef6..d06e157657ac 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -1365,7 +1365,7 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf, | |||
1365 | } | 1365 | } |
1366 | 1366 | ||
1367 | PWC_DEBUG_READ("Copying data to user space.\n"); | 1367 | PWC_DEBUG_READ("Copying data to user space.\n"); |
1368 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | 1368 | if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) |
1369 | bytes_to_read = pdev->frame_size + sizeof(struct pwc_raw_frame); | 1369 | bytes_to_read = pdev->frame_size + sizeof(struct pwc_raw_frame); |
1370 | else | 1370 | else |
1371 | bytes_to_read = pdev->view.size; | 1371 | bytes_to_read = pdev->view.size; |
@@ -1800,13 +1800,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1800 | } | 1800 | } |
1801 | 1801 | ||
1802 | pdev->vdev->release = video_device_release; | 1802 | pdev->vdev->release = video_device_release; |
1803 | rc = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); | ||
1804 | if (rc < 0) { | ||
1805 | PWC_ERROR("Failed to register as video device (%d).\n", rc); | ||
1806 | goto err_video_release; | ||
1807 | } | ||
1808 | |||
1809 | PWC_INFO("Registered as %s.\n", video_device_node_name(pdev->vdev)); | ||
1810 | 1803 | ||
1811 | /* occupy slot */ | 1804 | /* occupy slot */ |
1812 | if (hint < MAX_DEV_HINTS) | 1805 | if (hint < MAX_DEV_HINTS) |
@@ -1814,14 +1807,22 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1814 | 1807 | ||
1815 | PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev); | 1808 | PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev); |
1816 | usb_set_intfdata(intf, pdev); | 1809 | usb_set_intfdata(intf, pdev); |
1817 | rc = pwc_create_sysfs_files(pdev->vdev); | ||
1818 | if (rc) | ||
1819 | goto err_video_unreg; | ||
1820 | 1810 | ||
1821 | /* Set the leds off */ | 1811 | /* Set the leds off */ |
1822 | pwc_set_leds(pdev, 0, 0); | 1812 | pwc_set_leds(pdev, 0, 0); |
1823 | pwc_camera_power(pdev, 0); | 1813 | pwc_camera_power(pdev, 0); |
1824 | 1814 | ||
1815 | rc = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); | ||
1816 | if (rc < 0) { | ||
1817 | PWC_ERROR("Failed to register as video device (%d).\n", rc); | ||
1818 | goto err_video_release; | ||
1819 | } | ||
1820 | rc = pwc_create_sysfs_files(pdev->vdev); | ||
1821 | if (rc) | ||
1822 | goto err_video_unreg; | ||
1823 | |||
1824 | PWC_INFO("Registered as %s.\n", video_device_node_name(pdev->vdev)); | ||
1825 | |||
1825 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 1826 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV |
1826 | /* register webcam snapshot button input device */ | 1827 | /* register webcam snapshot button input device */ |
1827 | pdev->button_dev = input_allocate_device(); | 1828 | pdev->button_dev = input_allocate_device(); |
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c index 589c687439da..6af5bb538358 100644 --- a/drivers/media/video/pwc/pwc-misc.c +++ b/drivers/media/video/pwc/pwc-misc.c | |||
@@ -47,7 +47,7 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height) | |||
47 | you don't have the decompressor loaded or use RAW mode, | 47 | you don't have the decompressor loaded or use RAW mode, |
48 | the maximum viewable size is smaller. | 48 | the maximum viewable size is smaller. |
49 | */ | 49 | */ |
50 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | 50 | if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) |
51 | { | 51 | { |
52 | if (width > pdev->abs_max.x || height > pdev->abs_max.y) | 52 | if (width > pdev->abs_max.x || height > pdev->abs_max.y) |
53 | { | 53 | { |
@@ -123,7 +123,7 @@ void pwc_construct(struct pwc_device *pdev) | |||
123 | pdev->frame_header_size = 0; | 123 | pdev->frame_header_size = 0; |
124 | pdev->frame_trailer_size = 0; | 124 | pdev->frame_trailer_size = 0; |
125 | } | 125 | } |
126 | pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */ | 126 | pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */ |
127 | pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; | 127 | pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; |
128 | pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; | 128 | pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; |
129 | /* length of image, in YUV format; always allocate enough memory. */ | 129 | /* length of image, in YUV format; always allocate enough memory. */ |
diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c index 5d82028ef942..3b73f295f032 100644 --- a/drivers/media/video/pwc/pwc-uncompress.c +++ b/drivers/media/video/pwc/pwc-uncompress.c | |||
@@ -54,7 +54,7 @@ int pwc_decompress(struct pwc_device *pdev) | |||
54 | yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ | 54 | yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ |
55 | 55 | ||
56 | /* Raw format; that's easy... */ | 56 | /* Raw format; that's easy... */ |
57 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | 57 | if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) |
58 | { | 58 | { |
59 | struct pwc_raw_frame *raw_frame = image; | 59 | struct pwc_raw_frame *raw_frame = image; |
60 | raw_frame->type = cpu_to_le16(pdev->type); | 60 | raw_frame->type = cpu_to_le16(pdev->type); |
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 62d89b3113a4..7061a03f5cf1 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c | |||
@@ -216,7 +216,7 @@ static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_forma | |||
216 | f->fmt.pix.width = pdev->view.x; | 216 | f->fmt.pix.width = pdev->view.x; |
217 | f->fmt.pix.height = pdev->view.y; | 217 | f->fmt.pix.height = pdev->view.y; |
218 | f->fmt.pix.field = V4L2_FIELD_NONE; | 218 | f->fmt.pix.field = V4L2_FIELD_NONE; |
219 | if (pdev->vpalette == VIDEO_PALETTE_YUV420P) { | 219 | if (pdev->pixfmt == V4L2_PIX_FMT_YUV420) { |
220 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; | 220 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; |
221 | f->fmt.pix.bytesperline = (f->fmt.pix.width * 3)/2; | 221 | f->fmt.pix.bytesperline = (f->fmt.pix.width * 3)/2; |
222 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; | 222 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; |
@@ -304,10 +304,10 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) | |||
304 | fps = pdev->vframes; | 304 | fps = pdev->vframes; |
305 | } | 305 | } |
306 | 306 | ||
307 | if (pixelformat == V4L2_PIX_FMT_YUV420) | 307 | if (pixelformat != V4L2_PIX_FMT_YUV420 && |
308 | pdev->vpalette = VIDEO_PALETTE_YUV420P; | 308 | pixelformat != V4L2_PIX_FMT_PWC1 && |
309 | else | 309 | pixelformat != V4L2_PIX_FMT_PWC2) |
310 | pdev->vpalette = VIDEO_PALETTE_RAW; | 310 | return -EINVAL; |
311 | 311 | ||
312 | PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d " | 312 | PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d " |
313 | "compression=%d snapshot=%d format=%c%c%c%c\n", | 313 | "compression=%d snapshot=%d format=%c%c%c%c\n", |
@@ -330,6 +330,8 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) | |||
330 | if (ret) | 330 | if (ret) |
331 | return ret; | 331 | return ret; |
332 | 332 | ||
333 | pdev->pixfmt = pixelformat; | ||
334 | |||
333 | pwc_vidioc_fill_fmt(pdev, f); | 335 | pwc_vidioc_fill_fmt(pdev, f); |
334 | 336 | ||
335 | return 0; | 337 | return 0; |
@@ -357,152 +359,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
357 | 359 | ||
358 | 360 | ||
359 | switch (cmd) { | 361 | switch (cmd) { |
360 | /* Query cabapilities */ | 362 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
361 | case VIDIOCGCAP: | ||
362 | { | ||
363 | struct video_capability *caps = arg; | ||
364 | |||
365 | strcpy(caps->name, vdev->name); | ||
366 | caps->type = VID_TYPE_CAPTURE; | ||
367 | caps->channels = 1; | ||
368 | caps->audios = 1; | ||
369 | caps->minwidth = pdev->view_min.x; | ||
370 | caps->minheight = pdev->view_min.y; | ||
371 | caps->maxwidth = pdev->view_max.x; | ||
372 | caps->maxheight = pdev->view_max.y; | ||
373 | break; | ||
374 | } | ||
375 | |||
376 | /* Channel functions (simulate 1 channel) */ | ||
377 | case VIDIOCGCHAN: | ||
378 | { | ||
379 | struct video_channel *v = arg; | ||
380 | |||
381 | if (v->channel != 0) | ||
382 | return -EINVAL; | ||
383 | v->flags = 0; | ||
384 | v->tuners = 0; | ||
385 | v->type = VIDEO_TYPE_CAMERA; | ||
386 | strcpy(v->name, "Webcam"); | ||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | case VIDIOCSCHAN: | ||
391 | { | ||
392 | /* The spec says the argument is an integer, but | ||
393 | the bttv driver uses a video_channel arg, which | ||
394 | makes sense becasue it also has the norm flag. | ||
395 | */ | ||
396 | struct video_channel *v = arg; | ||
397 | if (v->channel != 0) | ||
398 | return -EINVAL; | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | |||
403 | /* Picture functions; contrast etc. */ | ||
404 | case VIDIOCGPICT: | ||
405 | { | ||
406 | struct video_picture *p = arg; | ||
407 | int val; | ||
408 | |||
409 | val = pwc_get_brightness(pdev); | ||
410 | if (val >= 0) | ||
411 | p->brightness = (val<<9); | ||
412 | else | ||
413 | p->brightness = 0xffff; | ||
414 | val = pwc_get_contrast(pdev); | ||
415 | if (val >= 0) | ||
416 | p->contrast = (val<<10); | ||
417 | else | ||
418 | p->contrast = 0xffff; | ||
419 | /* Gamma, Whiteness, what's the difference? :) */ | ||
420 | val = pwc_get_gamma(pdev); | ||
421 | if (val >= 0) | ||
422 | p->whiteness = (val<<11); | ||
423 | else | ||
424 | p->whiteness = 0xffff; | ||
425 | if (pwc_get_saturation(pdev, &val)<0) | ||
426 | p->colour = 0xffff; | ||
427 | else | ||
428 | p->colour = 32768 + val * 327; | ||
429 | p->depth = 24; | ||
430 | p->palette = pdev->vpalette; | ||
431 | p->hue = 0xFFFF; /* N/A */ | ||
432 | break; | ||
433 | } | ||
434 | |||
435 | case VIDIOCSPICT: | ||
436 | { | ||
437 | struct video_picture *p = arg; | ||
438 | /* | ||
439 | * FIXME: Suppose we are mid read | ||
440 | ANSWER: No problem: the firmware of the camera | ||
441 | can handle brightness/contrast/etc | ||
442 | changes at _any_ time, and the palette | ||
443 | is used exactly once in the uncompress | ||
444 | routine. | ||
445 | */ | ||
446 | pwc_set_brightness(pdev, p->brightness); | ||
447 | pwc_set_contrast(pdev, p->contrast); | ||
448 | pwc_set_gamma(pdev, p->whiteness); | ||
449 | pwc_set_saturation(pdev, (p->colour-32768)/327); | ||
450 | if (p->palette && p->palette != pdev->vpalette) { | ||
451 | switch (p->palette) { | ||
452 | case VIDEO_PALETTE_YUV420P: | ||
453 | case VIDEO_PALETTE_RAW: | ||
454 | pdev->vpalette = p->palette; | ||
455 | return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); | ||
456 | break; | ||
457 | default: | ||
458 | return -EINVAL; | ||
459 | break; | ||
460 | } | ||
461 | } | ||
462 | break; | ||
463 | } | ||
464 | |||
465 | /* Window/size parameters */ | ||
466 | case VIDIOCGWIN: | ||
467 | { | ||
468 | struct video_window *vw = arg; | ||
469 | |||
470 | vw->x = 0; | ||
471 | vw->y = 0; | ||
472 | vw->width = pdev->view.x; | ||
473 | vw->height = pdev->view.y; | ||
474 | vw->chromakey = 0; | ||
475 | vw->flags = (pdev->vframes << PWC_FPS_SHIFT) | | ||
476 | (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0); | ||
477 | break; | ||
478 | } | ||
479 | |||
480 | case VIDIOCSWIN: | ||
481 | { | ||
482 | struct video_window *vw = arg; | ||
483 | int fps, snapshot, ret; | ||
484 | |||
485 | fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT; | ||
486 | snapshot = vw->flags & PWC_FPS_SNAPSHOT; | ||
487 | if (fps == 0) | ||
488 | fps = pdev->vframes; | ||
489 | if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot) | ||
490 | return 0; | ||
491 | ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot); | ||
492 | if (ret) | ||
493 | return ret; | ||
494 | break; | ||
495 | } | ||
496 | |||
497 | /* We don't have overlay support (yet) */ | ||
498 | case VIDIOCGFBUF: | ||
499 | { | ||
500 | struct video_buffer *vb = arg; | ||
501 | |||
502 | memset(vb,0,sizeof(*vb)); | ||
503 | break; | ||
504 | } | ||
505 | |||
506 | /* mmap() functions */ | 363 | /* mmap() functions */ |
507 | case VIDIOCGMBUF: | 364 | case VIDIOCGMBUF: |
508 | { | 365 | { |
@@ -517,164 +374,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
517 | vm->offsets[i] = i * pdev->len_per_image; | 374 | vm->offsets[i] = i * pdev->len_per_image; |
518 | break; | 375 | break; |
519 | } | 376 | } |
520 | 377 | #endif | |
521 | case VIDIOCMCAPTURE: | ||
522 | { | ||
523 | /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */ | ||
524 | struct video_mmap *vm = arg; | ||
525 | |||
526 | PWC_DEBUG_READ("VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format); | ||
527 | if (vm->frame < 0 || vm->frame >= pwc_mbufs) | ||
528 | return -EINVAL; | ||
529 | |||
530 | /* xawtv is nasty. It probes the available palettes | ||
531 | by setting a very small image size and trying | ||
532 | various palettes... The driver doesn't support | ||
533 | such small images, so I'm working around it. | ||
534 | */ | ||
535 | if (vm->format) | ||
536 | { | ||
537 | switch (vm->format) | ||
538 | { | ||
539 | case VIDEO_PALETTE_YUV420P: | ||
540 | case VIDEO_PALETTE_RAW: | ||
541 | break; | ||
542 | default: | ||
543 | return -EINVAL; | ||
544 | break; | ||
545 | } | ||
546 | } | ||
547 | |||
548 | if ((vm->width != pdev->view.x || vm->height != pdev->view.y) && | ||
549 | (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) { | ||
550 | int ret; | ||
551 | |||
552 | PWC_DEBUG_OPEN("VIDIOCMCAPTURE: changing size to please xawtv :-(.\n"); | ||
553 | ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot); | ||
554 | if (ret) | ||
555 | return ret; | ||
556 | } /* ... size mismatch */ | ||
557 | |||
558 | /* FIXME: should we lock here? */ | ||
559 | if (pdev->image_used[vm->frame]) | ||
560 | return -EBUSY; /* buffer wasn't available. Bummer */ | ||
561 | pdev->image_used[vm->frame] = 1; | ||
562 | |||
563 | /* Okay, we're done here. In the SYNC call we wait until a | ||
564 | frame comes available, then expand image into the given | ||
565 | buffer. | ||
566 | In contrast to the CPiA cam the Philips cams deliver a | ||
567 | constant stream, almost like a grabber card. Also, | ||
568 | we have separate buffers for the rawdata and the image, | ||
569 | meaning we can nearly always expand into the requested buffer. | ||
570 | */ | ||
571 | PWC_DEBUG_READ("VIDIOCMCAPTURE done.\n"); | ||
572 | break; | ||
573 | } | ||
574 | |||
575 | case VIDIOCSYNC: | ||
576 | { | ||
577 | /* The doc says: "Whenever a buffer is used it should | ||
578 | call VIDIOCSYNC to free this frame up and continue." | ||
579 | |||
580 | The only odd thing about this whole procedure is | ||
581 | that MCAPTURE flags the buffer as "in use", and | ||
582 | SYNC immediately unmarks it, while it isn't | ||
583 | after SYNC that you know that the buffer actually | ||
584 | got filled! So you better not start a CAPTURE in | ||
585 | the same frame immediately (use double buffering). | ||
586 | This is not a problem for this cam, since it has | ||
587 | extra intermediate buffers, but a hardware | ||
588 | grabber card will then overwrite the buffer | ||
589 | you're working on. | ||
590 | */ | ||
591 | int *mbuf = arg; | ||
592 | int ret; | ||
593 | |||
594 | PWC_DEBUG_READ("VIDIOCSYNC called (%d).\n", *mbuf); | ||
595 | |||
596 | /* bounds check */ | ||
597 | if (*mbuf < 0 || *mbuf >= pwc_mbufs) | ||
598 | return -EINVAL; | ||
599 | /* check if this buffer was requested anyway */ | ||
600 | if (pdev->image_used[*mbuf] == 0) | ||
601 | return -EINVAL; | ||
602 | |||
603 | /* Add ourselves to the frame wait-queue. | ||
604 | |||
605 | FIXME: needs auditing for safety. | ||
606 | QUESTION: In what respect? I think that using the | ||
607 | frameq is safe now. | ||
608 | */ | ||
609 | add_wait_queue(&pdev->frameq, &wait); | ||
610 | while (pdev->full_frames == NULL) { | ||
611 | /* Check for unplugged/etc. here */ | ||
612 | if (pdev->error_status) { | ||
613 | remove_wait_queue(&pdev->frameq, &wait); | ||
614 | set_current_state(TASK_RUNNING); | ||
615 | return -pdev->error_status; | ||
616 | } | ||
617 | |||
618 | if (signal_pending(current)) { | ||
619 | remove_wait_queue(&pdev->frameq, &wait); | ||
620 | set_current_state(TASK_RUNNING); | ||
621 | return -ERESTARTSYS; | ||
622 | } | ||
623 | schedule(); | ||
624 | set_current_state(TASK_INTERRUPTIBLE); | ||
625 | } | ||
626 | remove_wait_queue(&pdev->frameq, &wait); | ||
627 | set_current_state(TASK_RUNNING); | ||
628 | |||
629 | /* The frame is ready. Expand in the image buffer | ||
630 | requested by the user. I don't care if you | ||
631 | mmap() 5 buffers and request data in this order: | ||
632 | buffer 4 2 3 0 1 2 3 0 4 3 1 . . . | ||
633 | Grabber hardware may not be so forgiving. | ||
634 | */ | ||
635 | PWC_DEBUG_READ("VIDIOCSYNC: frame ready.\n"); | ||
636 | pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */ | ||
637 | /* Decompress, etc */ | ||
638 | ret = pwc_handle_frame(pdev); | ||
639 | pdev->image_used[*mbuf] = 0; | ||
640 | if (ret) | ||
641 | return -EFAULT; | ||
642 | break; | ||
643 | } | ||
644 | |||
645 | case VIDIOCGAUDIO: | ||
646 | { | ||
647 | struct video_audio *v = arg; | ||
648 | |||
649 | strcpy(v->name, "Microphone"); | ||
650 | v->audio = -1; /* unknown audio minor */ | ||
651 | v->flags = 0; | ||
652 | v->mode = VIDEO_SOUND_MONO; | ||
653 | v->volume = 0; | ||
654 | v->bass = 0; | ||
655 | v->treble = 0; | ||
656 | v->balance = 0x8000; | ||
657 | v->step = 1; | ||
658 | break; | ||
659 | } | ||
660 | |||
661 | case VIDIOCSAUDIO: | ||
662 | { | ||
663 | /* Dummy: nothing can be set */ | ||
664 | break; | ||
665 | } | ||
666 | |||
667 | case VIDIOCGUNIT: | ||
668 | { | ||
669 | struct video_unit *vu = arg; | ||
670 | |||
671 | vu->video = pdev->vdev->minor & 0x3F; | ||
672 | vu->audio = -1; /* not known yet */ | ||
673 | vu->vbi = -1; | ||
674 | vu->radio = -1; | ||
675 | vu->teletext = -1; | ||
676 | break; | ||
677 | } | ||
678 | 378 | ||
679 | /* V4L2 Layer */ | 379 | /* V4L2 Layer */ |
680 | case VIDIOC_QUERYCAP: | 380 | case VIDIOC_QUERYCAP: |
@@ -1081,7 +781,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1081 | buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 781 | buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1082 | buf->index = index; | 782 | buf->index = index; |
1083 | buf->m.offset = index * pdev->len_per_image; | 783 | buf->m.offset = index * pdev->len_per_image; |
1084 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | 784 | if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) |
1085 | buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); | 785 | buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); |
1086 | else | 786 | else |
1087 | buf->bytesused = pdev->view.size; | 787 | buf->bytesused = pdev->view.size; |
@@ -1158,7 +858,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1158 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n"); | 858 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n"); |
1159 | 859 | ||
1160 | buf->index = pdev->fill_image; | 860 | buf->index = pdev->fill_image; |
1161 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | 861 | if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) |
1162 | buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); | 862 | buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); |
1163 | else | 863 | else |
1164 | buf->bytesused = pdev->view.size; | 864 | buf->bytesused = pdev->view.size; |
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index f1b206632957..36a9c83b5f5d 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <asm/errno.h> | 36 | #include <asm/errno.h> |
37 | #include <linux/videodev.h> | 37 | #include <linux/videodev2.h> |
38 | #include <media/v4l2-common.h> | 38 | #include <media/v4l2-common.h> |
39 | #include <media/v4l2-ioctl.h> | 39 | #include <media/v4l2-ioctl.h> |
40 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 40 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV |
@@ -49,7 +49,7 @@ | |||
49 | #define PWC_MINOR 0 | 49 | #define PWC_MINOR 0 |
50 | #define PWC_EXTRAMINOR 12 | 50 | #define PWC_EXTRAMINOR 12 |
51 | #define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR) | 51 | #define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR) |
52 | #define PWC_VERSION "10.0.13" | 52 | #define PWC_VERSION "10.0.14" |
53 | #define PWC_NAME "pwc" | 53 | #define PWC_NAME "pwc" |
54 | #define PFX PWC_NAME ": " | 54 | #define PFX PWC_NAME ": " |
55 | 55 | ||
@@ -180,7 +180,7 @@ struct pwc_device | |||
180 | int vcinterface; /* video control interface */ | 180 | int vcinterface; /* video control interface */ |
181 | int valternate; /* alternate interface needed */ | 181 | int valternate; /* alternate interface needed */ |
182 | int vframes, vsize; /* frames-per-second & size (see PSZ_*) */ | 182 | int vframes, vsize; /* frames-per-second & size (see PSZ_*) */ |
183 | int vpalette; /* palette: 420P, RAW or RGBBAYER */ | 183 | int pixfmt; /* pixelformat: V4L2_PIX_FMT_YUV420 or raw: _PWC1, _PWC2 */ |
184 | int vframe_count; /* received frames */ | 184 | int vframe_count; /* received frames */ |
185 | int vframes_dumped; /* counter for dumped frames */ | 185 | int vframes_dumped; /* counter for dumped frames */ |
186 | int vframes_error; /* frames received in error */ | 186 | int vframes_error; /* frames received in error */ |