aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pwc/pwc-if.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/pwc/pwc-if.c')
-rw-r--r--drivers/media/video/pwc/pwc-if.c297
1 files changed, 100 insertions, 197 deletions
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 01ff643e682d..943d37ad0d33 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -134,7 +134,6 @@ static int default_fps = 10;
134#endif 134#endif
135static int power_save = -1; 135static int power_save = -1;
136static int led_on = 100, led_off; /* defaults to LED that is on while in use */ 136static int led_on = 100, led_off; /* defaults to LED that is on while in use */
137static int pwc_preferred_compression = 1; /* 0..3 = uncompressed..high */
138static struct { 137static struct {
139 int type; 138 int type;
140 char serial_number[30]; 139 char serial_number[30];
@@ -144,17 +143,15 @@ static struct {
144 143
145/***/ 144/***/
146 145
147static int pwc_video_open(struct file *file);
148static int pwc_video_close(struct file *file); 146static int pwc_video_close(struct file *file);
149static ssize_t pwc_video_read(struct file *file, char __user *buf, 147static ssize_t pwc_video_read(struct file *file, char __user *buf,
150 size_t count, loff_t *ppos); 148 size_t count, loff_t *ppos);
151static unsigned int pwc_video_poll(struct file *file, poll_table *wait); 149static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
152static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); 150static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
153static void pwc_video_release(struct video_device *vfd);
154 151
155static const struct v4l2_file_operations pwc_fops = { 152static const struct v4l2_file_operations pwc_fops = {
156 .owner = THIS_MODULE, 153 .owner = THIS_MODULE,
157 .open = pwc_video_open, 154 .open = v4l2_fh_open,
158 .release = pwc_video_close, 155 .release = pwc_video_close,
159 .read = pwc_video_read, 156 .read = pwc_video_read,
160 .poll = pwc_video_poll, 157 .poll = pwc_video_poll,
@@ -163,7 +160,7 @@ static const struct v4l2_file_operations pwc_fops = {
163}; 160};
164static struct video_device pwc_template = { 161static struct video_device pwc_template = {
165 .name = "Philips Webcam", /* Filled in later */ 162 .name = "Philips Webcam", /* Filled in later */
166 .release = pwc_video_release, 163 .release = video_device_release_empty,
167 .fops = &pwc_fops, 164 .fops = &pwc_fops,
168 .ioctl_ops = &pwc_ioctl_ops, 165 .ioctl_ops = &pwc_ioctl_ops,
169}; 166};
@@ -191,7 +188,6 @@ static void pwc_snapshot_button(struct pwc_device *pdev, int down)
191{ 188{
192 if (down) { 189 if (down) {
193 PWC_TRACE("Snapshot button pressed.\n"); 190 PWC_TRACE("Snapshot button pressed.\n");
194 pdev->snapshot_button_status = 1;
195 } else { 191 } else {
196 PWC_TRACE("Snapshot button released.\n"); 192 PWC_TRACE("Snapshot button released.\n");
197 } 193 }
@@ -375,6 +371,7 @@ static int pwc_isoc_init(struct pwc_device *pdev)
375 int i, j, ret; 371 int i, j, ret;
376 struct usb_interface *intf; 372 struct usb_interface *intf;
377 struct usb_host_interface *idesc = NULL; 373 struct usb_host_interface *idesc = NULL;
374 int compression = 0; /* 0..3 = uncompressed..high */
378 375
379 if (pdev->iso_init) 376 if (pdev->iso_init)
380 return 0; 377 return 0;
@@ -386,6 +383,12 @@ static int pwc_isoc_init(struct pwc_device *pdev)
386 pdev->visoc_errors = 0; 383 pdev->visoc_errors = 0;
387 udev = pdev->udev; 384 udev = pdev->udev;
388 385
386retry:
387 /* We first try with low compression and then retry with a higher
388 compression setting if there is not enough bandwidth. */
389 ret = pwc_set_video_mode(pdev, pdev->width, pdev->height,
390 pdev->vframes, &compression);
391
389 /* Get the current alternate interface, adjust packet size */ 392 /* Get the current alternate interface, adjust packet size */
390 intf = usb_ifnum_to_if(udev, 0); 393 intf = usb_ifnum_to_if(udev, 0);
391 if (intf) 394 if (intf)
@@ -408,9 +411,12 @@ static int pwc_isoc_init(struct pwc_device *pdev)
408 } 411 }
409 412
410 /* Set alternate interface */ 413 /* Set alternate interface */
411 ret = 0;
412 PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate); 414 PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate);
413 ret = usb_set_interface(pdev->udev, 0, pdev->valternate); 415 ret = usb_set_interface(pdev->udev, 0, pdev->valternate);
416 if (ret == -ENOSPC && compression < 3) {
417 compression++;
418 goto retry;
419 }
414 if (ret < 0) 420 if (ret < 0)
415 return ret; 421 return ret;
416 422
@@ -454,6 +460,12 @@ static int pwc_isoc_init(struct pwc_device *pdev)
454 /* link */ 460 /* link */
455 for (i = 0; i < MAX_ISO_BUFS; i++) { 461 for (i = 0; i < MAX_ISO_BUFS; i++) {
456 ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL); 462 ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL);
463 if (ret == -ENOSPC && compression < 3) {
464 compression++;
465 pdev->iso_init = 1;
466 pwc_isoc_cleanup(pdev);
467 goto retry;
468 }
457 if (ret) { 469 if (ret) {
458 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); 470 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
459 pdev->iso_init = 1; 471 pdev->iso_init = 1;
@@ -517,12 +529,11 @@ static void pwc_isoc_cleanup(struct pwc_device *pdev)
517 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); 529 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
518} 530}
519 531
520/*
521 * Release all queued buffers, no need to take queued_bufs_lock, since all
522 * iso urbs have been killed when we're called so pwc_isoc_handler won't run.
523 */
524static void pwc_cleanup_queued_bufs(struct pwc_device *pdev) 532static void pwc_cleanup_queued_bufs(struct pwc_device *pdev)
525{ 533{
534 unsigned long flags = 0;
535
536 spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
526 while (!list_empty(&pdev->queued_bufs)) { 537 while (!list_empty(&pdev->queued_bufs)) {
527 struct pwc_frame_buf *buf; 538 struct pwc_frame_buf *buf;
528 539
@@ -531,84 +542,7 @@ static void pwc_cleanup_queued_bufs(struct pwc_device *pdev)
531 list_del(&buf->list); 542 list_del(&buf->list);
532 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); 543 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
533 } 544 }
534} 545 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
535
536/*********
537 * sysfs
538 *********/
539static struct pwc_device *cd_to_pwc(struct device *cd)
540{
541 struct video_device *vdev = to_video_device(cd);
542 return video_get_drvdata(vdev);
543}
544
545static ssize_t show_pan_tilt(struct device *class_dev,
546 struct device_attribute *attr, char *buf)
547{
548 struct pwc_device *pdev = cd_to_pwc(class_dev);
549 return sprintf(buf, "%d %d\n", pdev->pan_angle, pdev->tilt_angle);
550}
551
552static ssize_t store_pan_tilt(struct device *class_dev,
553 struct device_attribute *attr,
554 const char *buf, size_t count)
555{
556 struct pwc_device *pdev = cd_to_pwc(class_dev);
557 int pan, tilt;
558 int ret = -EINVAL;
559
560 if (strncmp(buf, "reset", 5) == 0)
561 ret = pwc_mpt_reset(pdev, 0x3);
562
563 else if (sscanf(buf, "%d %d", &pan, &tilt) > 0)
564 ret = pwc_mpt_set_angle(pdev, pan, tilt);
565
566 if (ret < 0)
567 return ret;
568 return strlen(buf);
569}
570static DEVICE_ATTR(pan_tilt, S_IRUGO | S_IWUSR, show_pan_tilt,
571 store_pan_tilt);
572
573static ssize_t show_snapshot_button_status(struct device *class_dev,
574 struct device_attribute *attr, char *buf)
575{
576 struct pwc_device *pdev = cd_to_pwc(class_dev);
577 int status = pdev->snapshot_button_status;
578 pdev->snapshot_button_status = 0;
579 return sprintf(buf, "%d\n", status);
580}
581
582static DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status,
583 NULL);
584
585static int pwc_create_sysfs_files(struct pwc_device *pdev)
586{
587 int rc;
588
589 rc = device_create_file(&pdev->vdev.dev, &dev_attr_button);
590 if (rc)
591 goto err;
592 if (pdev->features & FEATURE_MOTOR_PANTILT) {
593 rc = device_create_file(&pdev->vdev.dev, &dev_attr_pan_tilt);
594 if (rc)
595 goto err_button;
596 }
597
598 return 0;
599
600err_button:
601 device_remove_file(&pdev->vdev.dev, &dev_attr_button);
602err:
603 PWC_ERROR("Could not create sysfs files.\n");
604 return rc;
605}
606
607static void pwc_remove_sysfs_files(struct pwc_device *pdev)
608{
609 if (pdev->features & FEATURE_MOTOR_PANTILT)
610 device_remove_file(&pdev->vdev.dev, &dev_attr_pan_tilt);
611 device_remove_file(&pdev->vdev.dev, &dev_attr_button);
612} 546}
613 547
614#ifdef CONFIG_USB_PWC_DEBUG 548#ifdef CONFIG_USB_PWC_DEBUG
@@ -644,25 +578,25 @@ static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
644/***************************************************************************/ 578/***************************************************************************/
645/* Video4Linux functions */ 579/* Video4Linux functions */
646 580
647static int pwc_video_open(struct file *file) 581int pwc_test_n_set_capt_file(struct pwc_device *pdev, struct file *file)
648{ 582{
649 struct video_device *vdev = video_devdata(file); 583 int r = 0;
650 struct pwc_device *pdev;
651
652 PWC_DEBUG_OPEN(">> video_open called(vdev = 0x%p).\n", vdev);
653 584
654 pdev = video_get_drvdata(vdev); 585 mutex_lock(&pdev->capt_file_lock);
655 if (!pdev->udev) 586 if (pdev->capt_file != NULL &&
656 return -ENODEV; 587 pdev->capt_file != file) {
657 588 r = -EBUSY;
658 file->private_data = vdev; 589 goto leave;
659 PWC_DEBUG_OPEN("<< video_open() returns 0.\n"); 590 }
660 return 0; 591 pdev->capt_file = file;
592leave:
593 mutex_unlock(&pdev->capt_file_lock);
594 return r;
661} 595}
662 596
663static void pwc_video_release(struct video_device *vfd) 597static void pwc_video_release(struct v4l2_device *v)
664{ 598{
665 struct pwc_device *pdev = container_of(vfd, struct pwc_device, vdev); 599 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
666 int hint; 600 int hint;
667 601
668 /* search device_hint[] table if we occupy a slot, by any chance */ 602 /* search device_hint[] table if we occupy a slot, by any chance */
@@ -685,44 +619,33 @@ static void pwc_video_release(struct video_device *vfd)
685 619
686static int pwc_video_close(struct file *file) 620static int pwc_video_close(struct file *file)
687{ 621{
688 struct video_device *vdev = file->private_data; 622 struct pwc_device *pdev = video_drvdata(file);
689 struct pwc_device *pdev;
690
691 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
692 623
693 pdev = video_get_drvdata(vdev);
694 if (pdev->capt_file == file) { 624 if (pdev->capt_file == file) {
695 vb2_queue_release(&pdev->vb_queue); 625 vb2_queue_release(&pdev->vb_queue);
696 pdev->capt_file = NULL; 626 pdev->capt_file = NULL;
697 } 627 }
698 628 return v4l2_fh_release(file);
699 PWC_DEBUG_OPEN("<< video_close()\n");
700 return 0;
701} 629}
702 630
703static ssize_t pwc_video_read(struct file *file, char __user *buf, 631static ssize_t pwc_video_read(struct file *file, char __user *buf,
704 size_t count, loff_t *ppos) 632 size_t count, loff_t *ppos)
705{ 633{
706 struct video_device *vdev = file->private_data; 634 struct pwc_device *pdev = video_drvdata(file);
707 struct pwc_device *pdev = video_get_drvdata(vdev);
708 635
709 if (!pdev->udev) 636 if (!pdev->udev)
710 return -ENODEV; 637 return -ENODEV;
711 638
712 if (pdev->capt_file != NULL && 639 if (pwc_test_n_set_capt_file(pdev, file))
713 pdev->capt_file != file)
714 return -EBUSY; 640 return -EBUSY;
715 641
716 pdev->capt_file = file;
717
718 return vb2_read(&pdev->vb_queue, buf, count, ppos, 642 return vb2_read(&pdev->vb_queue, buf, count, ppos,
719 file->f_flags & O_NONBLOCK); 643 file->f_flags & O_NONBLOCK);
720} 644}
721 645
722static unsigned int pwc_video_poll(struct file *file, poll_table *wait) 646static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
723{ 647{
724 struct video_device *vdev = file->private_data; 648 struct pwc_device *pdev = video_drvdata(file);
725 struct pwc_device *pdev = video_get_drvdata(vdev);
726 649
727 if (!pdev->udev) 650 if (!pdev->udev)
728 return POLL_ERR; 651 return POLL_ERR;
@@ -732,8 +655,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
732 655
733static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) 656static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
734{ 657{
735 struct video_device *vdev = file->private_data; 658 struct pwc_device *pdev = video_drvdata(file);
736 struct pwc_device *pdev = video_get_drvdata(vdev);
737 659
738 if (pdev->capt_file != file) 660 if (pdev->capt_file != file)
739 return -EBUSY; 661 return -EBUSY;
@@ -749,6 +671,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
749 unsigned int sizes[], void *alloc_ctxs[]) 671 unsigned int sizes[], void *alloc_ctxs[])
750{ 672{
751 struct pwc_device *pdev = vb2_get_drv_priv(vq); 673 struct pwc_device *pdev = vb2_get_drv_priv(vq);
674 int size;
752 675
753 if (*nbuffers < MIN_FRAMES) 676 if (*nbuffers < MIN_FRAMES)
754 *nbuffers = MIN_FRAMES; 677 *nbuffers = MIN_FRAMES;
@@ -757,7 +680,9 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
757 680
758 *nplanes = 1; 681 *nplanes = 1;
759 682
760 sizes[0] = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2); 683 size = pwc_get_size(pdev, MAX_WIDTH, MAX_HEIGHT);
684 sizes[0] = PAGE_ALIGN(pwc_image_sizes[size][0] *
685 pwc_image_sizes[size][1] * 3 / 2);
761 686
762 return 0; 687 return 0;
763} 688}
@@ -812,56 +737,59 @@ static void buffer_queue(struct vb2_buffer *vb)
812 unsigned long flags = 0; 737 unsigned long flags = 0;
813 738
814 spin_lock_irqsave(&pdev->queued_bufs_lock, flags); 739 spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
815 list_add_tail(&buf->list, &pdev->queued_bufs); 740 /* Check the device has not disconnected between prep and queuing */
741 if (pdev->udev)
742 list_add_tail(&buf->list, &pdev->queued_bufs);
743 else
744 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
816 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags); 745 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
817} 746}
818 747
819static int start_streaming(struct vb2_queue *vq, unsigned int count) 748static int start_streaming(struct vb2_queue *vq, unsigned int count)
820{ 749{
821 struct pwc_device *pdev = vb2_get_drv_priv(vq); 750 struct pwc_device *pdev = vb2_get_drv_priv(vq);
751 int r;
822 752
823 if (!pdev->udev) 753 mutex_lock(&pdev->udevlock);
824 return -ENODEV; 754 if (!pdev->udev) {
755 r = -ENODEV;
756 goto leave;
757 }
825 758
826 /* Turn on camera and set LEDS on */ 759 /* Turn on camera and set LEDS on */
827 pwc_camera_power(pdev, 1); 760 pwc_camera_power(pdev, 1);
828 if (pdev->power_save) {
829 /* Restore video mode */
830 pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y,
831 pdev->vframes, pdev->vcompression,
832 pdev->vsnapshot);
833 }
834 pwc_set_leds(pdev, led_on, led_off); 761 pwc_set_leds(pdev, led_on, led_off);
835 762
836 return pwc_isoc_init(pdev); 763 r = pwc_isoc_init(pdev);
764 if (r) {
765 /* If we failed turn camera and LEDS back off */
766 pwc_set_leds(pdev, 0, 0);
767 pwc_camera_power(pdev, 0);
768 /* And cleanup any queued bufs!! */
769 pwc_cleanup_queued_bufs(pdev);
770 }
771leave:
772 mutex_unlock(&pdev->udevlock);
773 return r;
837} 774}
838 775
839static int stop_streaming(struct vb2_queue *vq) 776static int stop_streaming(struct vb2_queue *vq)
840{ 777{
841 struct pwc_device *pdev = vb2_get_drv_priv(vq); 778 struct pwc_device *pdev = vb2_get_drv_priv(vq);
842 779
780 mutex_lock(&pdev->udevlock);
843 if (pdev->udev) { 781 if (pdev->udev) {
844 pwc_set_leds(pdev, 0, 0); 782 pwc_set_leds(pdev, 0, 0);
845 pwc_camera_power(pdev, 0); 783 pwc_camera_power(pdev, 0);
846 pwc_isoc_cleanup(pdev); 784 pwc_isoc_cleanup(pdev);
847 } 785 }
786 mutex_unlock(&pdev->udevlock);
787
848 pwc_cleanup_queued_bufs(pdev); 788 pwc_cleanup_queued_bufs(pdev);
849 789
850 return 0; 790 return 0;
851} 791}
852 792
853static void pwc_lock(struct vb2_queue *vq)
854{
855 struct pwc_device *pdev = vb2_get_drv_priv(vq);
856 mutex_lock(&pdev->modlock);
857}
858
859static void pwc_unlock(struct vb2_queue *vq)
860{
861 struct pwc_device *pdev = vb2_get_drv_priv(vq);
862 mutex_unlock(&pdev->modlock);
863}
864
865static struct vb2_ops pwc_vb_queue_ops = { 793static struct vb2_ops pwc_vb_queue_ops = {
866 .queue_setup = queue_setup, 794 .queue_setup = queue_setup,
867 .buf_init = buffer_init, 795 .buf_init = buffer_init,
@@ -871,8 +799,6 @@ static struct vb2_ops pwc_vb_queue_ops = {
871 .buf_queue = buffer_queue, 799 .buf_queue = buffer_queue,
872 .start_streaming = start_streaming, 800 .start_streaming = start_streaming,
873 .stop_streaming = stop_streaming, 801 .stop_streaming = stop_streaming,
874 .wait_prepare = pwc_unlock,
875 .wait_finish = pwc_lock,
876}; 802};
877 803
878/***************************************************************************/ 804/***************************************************************************/
@@ -889,6 +815,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
889 int vendor_id, product_id, type_id; 815 int vendor_id, product_id, type_id;
890 int hint, rc; 816 int hint, rc;
891 int features = 0; 817 int features = 0;
818 int compression = 0;
892 int video_nr = -1; /* default: use next available device */ 819 int video_nr = -1; /* default: use next available device */
893 int my_power_save = power_save; 820 int my_power_save = power_save;
894 char serial_number[30], *name; 821 char serial_number[30], *name;
@@ -1150,27 +1077,15 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1150 } 1077 }
1151 pdev->type = type_id; 1078 pdev->type = type_id;
1152 pdev->vframes = default_fps; 1079 pdev->vframes = default_fps;
1153 strcpy(pdev->serial, serial_number);
1154 pdev->features = features; 1080 pdev->features = features;
1155 if (vendor_id == 0x046D && product_id == 0x08B5) {
1156 /* Logitech QuickCam Orbit
1157 The ranges have been determined experimentally; they may differ from cam to cam.
1158 Also, the exact ranges left-right and up-down are different for my cam
1159 */
1160 pdev->angle_range.pan_min = -7000;
1161 pdev->angle_range.pan_max = 7000;
1162 pdev->angle_range.tilt_min = -3000;
1163 pdev->angle_range.tilt_max = 2500;
1164 }
1165 pwc_construct(pdev); /* set min/max sizes correct */ 1081 pwc_construct(pdev); /* set min/max sizes correct */
1166 1082
1167 mutex_init(&pdev->modlock); 1083 mutex_init(&pdev->capt_file_lock);
1168 mutex_init(&pdev->udevlock); 1084 mutex_init(&pdev->udevlock);
1169 spin_lock_init(&pdev->queued_bufs_lock); 1085 spin_lock_init(&pdev->queued_bufs_lock);
1170 INIT_LIST_HEAD(&pdev->queued_bufs); 1086 INIT_LIST_HEAD(&pdev->queued_bufs);
1171 1087
1172 pdev->udev = udev; 1088 pdev->udev = udev;
1173 pdev->vcompression = pwc_preferred_compression;
1174 pdev->power_save = my_power_save; 1089 pdev->power_save = my_power_save;
1175 1090
1176 /* Init videobuf2 queue structure */ 1091 /* Init videobuf2 queue structure */
@@ -1185,9 +1100,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1185 1100
1186 /* Init video_device structure */ 1101 /* Init video_device structure */
1187 memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template)); 1102 memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template));
1188 pdev->vdev.parent = &intf->dev;
1189 pdev->vdev.lock = &pdev->modlock;
1190 strcpy(pdev->vdev.name, name); 1103 strcpy(pdev->vdev.name, name);
1104 set_bit(V4L2_FL_USE_FH_PRIO, &pdev->vdev.flags);
1191 video_set_drvdata(&pdev->vdev, pdev); 1105 video_set_drvdata(&pdev->vdev, pdev);
1192 1106
1193 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); 1107 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
@@ -1211,9 +1125,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1211 if (hint < MAX_DEV_HINTS) 1125 if (hint < MAX_DEV_HINTS)
1212 device_hint[hint].pdev = pdev; 1126 device_hint[hint].pdev = pdev;
1213 1127
1214 PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev);
1215 usb_set_intfdata(intf, pdev);
1216
1217#ifdef CONFIG_USB_PWC_DEBUG 1128#ifdef CONFIG_USB_PWC_DEBUG
1218 /* Query sensor type */ 1129 /* Query sensor type */
1219 if (pwc_get_cmos_sensor(pdev, &rc) >= 0) { 1130 if (pwc_get_cmos_sensor(pdev, &rc) >= 0) {
@@ -1227,8 +1138,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1227 pwc_set_leds(pdev, 0, 0); 1138 pwc_set_leds(pdev, 0, 0);
1228 1139
1229 /* Setup intial videomode */ 1140 /* Setup intial videomode */
1230 rc = pwc_set_video_mode(pdev, pdev->view_max.x, pdev->view_max.y, 1141 rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, pdev->vframes,
1231 pdev->vframes, pdev->vcompression, 0); 1142 &compression);
1232 if (rc) 1143 if (rc)
1233 goto err_free_mem; 1144 goto err_free_mem;
1234 1145
@@ -1239,20 +1150,25 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1239 goto err_free_mem; 1150 goto err_free_mem;
1240 } 1151 }
1241 1152
1242 pdev->vdev.ctrl_handler = &pdev->ctrl_handler;
1243
1244 /* And powerdown the camera until streaming starts */ 1153 /* And powerdown the camera until streaming starts */
1245 pwc_camera_power(pdev, 0); 1154 pwc_camera_power(pdev, 0);
1246 1155
1156 /* Register the v4l2_device structure */
1157 pdev->v4l2_dev.release = pwc_video_release;
1158 rc = v4l2_device_register(&intf->dev, &pdev->v4l2_dev);
1159 if (rc) {
1160 PWC_ERROR("Failed to register v4l2-device (%d).\n", rc);
1161 goto err_free_controls;
1162 }
1163
1164 pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler;
1165 pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
1166
1247 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr); 1167 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr);
1248 if (rc < 0) { 1168 if (rc < 0) {
1249 PWC_ERROR("Failed to register as video device (%d).\n", rc); 1169 PWC_ERROR("Failed to register as video device (%d).\n", rc);
1250 goto err_free_controls; 1170 goto err_unregister_v4l2_dev;
1251 } 1171 }
1252 rc = pwc_create_sysfs_files(pdev);
1253 if (rc)
1254 goto err_video_unreg;
1255
1256 PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev)); 1172 PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev));
1257 1173
1258#ifdef CONFIG_USB_PWC_INPUT_EVDEV 1174#ifdef CONFIG_USB_PWC_INPUT_EVDEV
@@ -1261,7 +1177,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1261 if (!pdev->button_dev) { 1177 if (!pdev->button_dev) {
1262 PWC_ERROR("Err, insufficient memory for webcam snapshot button device."); 1178 PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
1263 rc = -ENOMEM; 1179 rc = -ENOMEM;
1264 pwc_remove_sysfs_files(pdev);
1265 goto err_video_unreg; 1180 goto err_video_unreg;
1266 } 1181 }
1267 1182
@@ -1279,7 +1194,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1279 if (rc) { 1194 if (rc) {
1280 input_free_device(pdev->button_dev); 1195 input_free_device(pdev->button_dev);
1281 pdev->button_dev = NULL; 1196 pdev->button_dev = NULL;
1282 pwc_remove_sysfs_files(pdev);
1283 goto err_video_unreg; 1197 goto err_video_unreg;
1284 } 1198 }
1285#endif 1199#endif
@@ -1287,13 +1201,14 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1287 return 0; 1201 return 0;
1288 1202
1289err_video_unreg: 1203err_video_unreg:
1290 if (hint < MAX_DEV_HINTS)
1291 device_hint[hint].pdev = NULL;
1292 video_unregister_device(&pdev->vdev); 1204 video_unregister_device(&pdev->vdev);
1205err_unregister_v4l2_dev:
1206 v4l2_device_unregister(&pdev->v4l2_dev);
1293err_free_controls: 1207err_free_controls:
1294 v4l2_ctrl_handler_free(&pdev->ctrl_handler); 1208 v4l2_ctrl_handler_free(&pdev->ctrl_handler);
1295err_free_mem: 1209err_free_mem:
1296 usb_set_intfdata(intf, NULL); 1210 if (hint < MAX_DEV_HINTS)
1211 device_hint[hint].pdev = NULL;
1297 kfree(pdev); 1212 kfree(pdev);
1298 return rc; 1213 return rc;
1299} 1214}
@@ -1301,27 +1216,26 @@ err_free_mem:
1301/* The user yanked out the cable... */ 1216/* The user yanked out the cable... */
1302static void usb_pwc_disconnect(struct usb_interface *intf) 1217static void usb_pwc_disconnect(struct usb_interface *intf)
1303{ 1218{
1304 struct pwc_device *pdev = usb_get_intfdata(intf); 1219 struct v4l2_device *v = usb_get_intfdata(intf);
1220 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
1305 1221
1306 mutex_lock(&pdev->udevlock); 1222 mutex_lock(&pdev->udevlock);
1307 mutex_lock(&pdev->modlock);
1308
1309 usb_set_intfdata(intf, NULL);
1310 /* No need to keep the urbs around after disconnection */ 1223 /* No need to keep the urbs around after disconnection */
1311 pwc_isoc_cleanup(pdev); 1224 pwc_isoc_cleanup(pdev);
1312 pwc_cleanup_queued_bufs(pdev);
1313 pdev->udev = NULL; 1225 pdev->udev = NULL;
1314
1315 mutex_unlock(&pdev->modlock);
1316 mutex_unlock(&pdev->udevlock); 1226 mutex_unlock(&pdev->udevlock);
1317 1227
1318 pwc_remove_sysfs_files(pdev); 1228 pwc_cleanup_queued_bufs(pdev);
1229
1319 video_unregister_device(&pdev->vdev); 1230 video_unregister_device(&pdev->vdev);
1231 v4l2_device_unregister(&pdev->v4l2_dev);
1320 1232
1321#ifdef CONFIG_USB_PWC_INPUT_EVDEV 1233#ifdef CONFIG_USB_PWC_INPUT_EVDEV
1322 if (pdev->button_dev) 1234 if (pdev->button_dev)
1323 input_unregister_device(pdev->button_dev); 1235 input_unregister_device(pdev->button_dev);
1324#endif 1236#endif
1237
1238 v4l2_device_put(&pdev->v4l2_dev);
1325} 1239}
1326 1240
1327 1241
@@ -1330,7 +1244,6 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1330 */ 1244 */
1331 1245
1332static int fps; 1246static int fps;
1333static int compression = -1;
1334static int leds[2] = { -1, -1 }; 1247static int leds[2] = { -1, -1 };
1335static unsigned int leds_nargs; 1248static unsigned int leds_nargs;
1336static char *dev_hint[MAX_DEV_HINTS]; 1249static char *dev_hint[MAX_DEV_HINTS];
@@ -1341,7 +1254,6 @@ module_param(fps, int, 0444);
1341module_param_named(trace, pwc_trace, int, 0644); 1254module_param_named(trace, pwc_trace, int, 0644);
1342#endif 1255#endif
1343module_param(power_save, int, 0644); 1256module_param(power_save, int, 0644);
1344module_param(compression, int, 0444);
1345module_param_array(leds, int, &leds_nargs, 0444); 1257module_param_array(leds, int, &leds_nargs, 0444);
1346module_param_array(dev_hint, charp, &dev_hint_nargs, 0444); 1258module_param_array(dev_hint, charp, &dev_hint_nargs, 0444);
1347 1259
@@ -1350,7 +1262,6 @@ MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful rang
1350MODULE_PARM_DESC(trace, "For debugging purposes"); 1262MODULE_PARM_DESC(trace, "For debugging purposes");
1351#endif 1263#endif
1352MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off"); 1264MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off");
1353MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
1354MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); 1265MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
1355MODULE_PARM_DESC(dev_hint, "Device node hints"); 1266MODULE_PARM_DESC(dev_hint, "Device node hints");
1356 1267
@@ -1384,14 +1295,6 @@ static int __init usb_pwc_init(void)
1384 PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps); 1295 PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps);
1385 } 1296 }
1386 1297
1387 if (compression >= 0) {
1388 if (compression > 3) {
1389 PWC_ERROR("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n");
1390 return -EINVAL;
1391 }
1392 pwc_preferred_compression = compression;
1393 PWC_DEBUG_MODULE("Preferred compression set to %d.\n", pwc_preferred_compression);
1394 }
1395 if (leds[0] >= 0) 1298 if (leds[0] >= 0)
1396 led_on = leds[0]; 1299 led_on = leds[0];
1397 if (leds[1] >= 0) 1300 if (leds[1] >= 0)