aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pwc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/pwc')
-rw-r--r--drivers/media/video/pwc/Kconfig2
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c20
-rw-r--r--drivers/media/video/pwc/pwc-if.c35
-rw-r--r--drivers/media/video/pwc/pwc-misc.c4
-rw-r--r--drivers/media/video/pwc/pwc-uncompress.c2
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c322
-rw-r--r--drivers/media/video/pwc/pwc.h6
7 files changed, 45 insertions, 346 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 @@
1config USB_PWC 1config 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..e62beb4efdb4 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -163,7 +163,7 @@ static const struct v4l2_file_operations pwc_fops = {
163 .read = pwc_video_read, 163 .read = pwc_video_read,
164 .poll = pwc_video_poll, 164 .poll = pwc_video_poll,
165 .mmap = pwc_video_mmap, 165 .mmap = pwc_video_mmap,
166 .ioctl = pwc_video_ioctl, 166 .unlocked_ioctl = pwc_video_ioctl,
167}; 167};
168static struct video_device pwc_template = { 168static struct video_device pwc_template = {
169 .name = "Philips Webcam", /* Filled in later */ 169 .name = "Philips Webcam", /* Filled in later */
@@ -1247,8 +1247,8 @@ static int pwc_video_close(struct file *file)
1247 1247
1248 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); 1248 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
1249 1249
1250 lock_kernel();
1251 pdev = video_get_drvdata(vdev); 1250 pdev = video_get_drvdata(vdev);
1251 mutex_lock(&pdev->modlock);
1252 if (pdev->vopen == 0) 1252 if (pdev->vopen == 0)
1253 PWC_DEBUG_MODULE("video_close() called on closed device?\n"); 1253 PWC_DEBUG_MODULE("video_close() called on closed device?\n");
1254 1254
@@ -1286,7 +1286,7 @@ static int pwc_video_close(struct file *file)
1286 if (device_hint[hint].pdev == pdev) 1286 if (device_hint[hint].pdev == pdev)
1287 device_hint[hint].pdev = NULL; 1287 device_hint[hint].pdev = NULL;
1288 } 1288 }
1289 unlock_kernel(); 1289 mutex_unlock(&pdev->modlock);
1290 1290
1291 return 0; 1291 return 0;
1292} 1292}
@@ -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();
@@ -1871,8 +1872,8 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1871 struct pwc_device *pdev; 1872 struct pwc_device *pdev;
1872 int hint; 1873 int hint;
1873 1874
1874 lock_kernel();
1875 pdev = usb_get_intfdata (intf); 1875 pdev = usb_get_intfdata (intf);
1876 mutex_lock(&pdev->modlock);
1876 usb_set_intfdata (intf, NULL); 1877 usb_set_intfdata (intf, NULL);
1877 if (pdev == NULL) { 1878 if (pdev == NULL) {
1878 PWC_ERROR("pwc_disconnect() Called without private pointer.\n"); 1879 PWC_ERROR("pwc_disconnect() Called without private pointer.\n");
@@ -1897,9 +1898,7 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1897 wake_up_interruptible(&pdev->frameq); 1898 wake_up_interruptible(&pdev->frameq);
1898 /* Wait until device is closed */ 1899 /* Wait until device is closed */
1899 if (pdev->vopen) { 1900 if (pdev->vopen) {
1900 mutex_lock(&pdev->modlock);
1901 pdev->unplugged = 1; 1901 pdev->unplugged = 1;
1902 mutex_unlock(&pdev->modlock);
1903 pwc_iso_stop(pdev); 1902 pwc_iso_stop(pdev);
1904 } else { 1903 } else {
1905 /* Device is closed, so we can safely unregister it */ 1904 /* Device is closed, so we can safely unregister it */
@@ -1913,7 +1912,7 @@ disconnect_out:
1913 device_hint[hint].pdev = NULL; 1912 device_hint[hint].pdev = NULL;
1914 } 1913 }
1915 1914
1916 unlock_kernel(); 1915 mutex_unlock(&pdev->modlock);
1917} 1916}
1918 1917
1919 1918
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 */