diff options
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-video.c')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 851 |
1 files changed, 264 insertions, 587 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 4ea1f1e04897..53527536481e 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include "em28xx.h" | 39 | #include "em28xx.h" |
40 | #include <media/v4l2-common.h> | 40 | #include <media/v4l2-common.h> |
41 | #include <media/v4l2-ioctl.h> | 41 | #include <media/v4l2-ioctl.h> |
42 | #include <media/v4l2-chip-ident.h> | ||
42 | #include <media/msp3400.h> | 43 | #include <media/msp3400.h> |
43 | #include <media/tuner.h> | 44 | #include <media/tuner.h> |
44 | 45 | ||
@@ -47,9 +48,8 @@ | |||
47 | "Mauro Carvalho Chehab <mchehab@infradead.org>, " \ | 48 | "Mauro Carvalho Chehab <mchehab@infradead.org>, " \ |
48 | "Sascha Sommer <saschasommer@freenet.de>" | 49 | "Sascha Sommer <saschasommer@freenet.de>" |
49 | 50 | ||
50 | #define DRIVER_NAME "em28xx" | ||
51 | #define DRIVER_DESC "Empia em28xx based USB video device driver" | 51 | #define DRIVER_DESC "Empia em28xx based USB video device driver" |
52 | #define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 0) | 52 | #define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 1) |
53 | 53 | ||
54 | #define em28xx_videodbg(fmt, arg...) do {\ | 54 | #define em28xx_videodbg(fmt, arg...) do {\ |
55 | if (video_debug) \ | 55 | if (video_debug) \ |
@@ -72,19 +72,13 @@ MODULE_AUTHOR(DRIVER_AUTHOR); | |||
72 | MODULE_DESCRIPTION(DRIVER_DESC); | 72 | MODULE_DESCRIPTION(DRIVER_DESC); |
73 | MODULE_LICENSE("GPL"); | 73 | MODULE_LICENSE("GPL"); |
74 | 74 | ||
75 | static LIST_HEAD(em28xx_devlist); | ||
76 | static DEFINE_MUTEX(em28xx_devlist_mutex); | ||
77 | |||
78 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | ||
79 | static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | 75 | static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; |
80 | static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | 76 | static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; |
81 | static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | 77 | static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; |
82 | 78 | ||
83 | module_param_array(card, int, NULL, 0444); | ||
84 | module_param_array(video_nr, int, NULL, 0444); | 79 | module_param_array(video_nr, int, NULL, 0444); |
85 | module_param_array(vbi_nr, int, NULL, 0444); | 80 | module_param_array(vbi_nr, int, NULL, 0444); |
86 | module_param_array(radio_nr, int, NULL, 0444); | 81 | module_param_array(radio_nr, int, NULL, 0444); |
87 | MODULE_PARM_DESC(card, "card type"); | ||
88 | MODULE_PARM_DESC(video_nr, "video device numbers"); | 82 | MODULE_PARM_DESC(video_nr, "video device numbers"); |
89 | MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); | 83 | MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); |
90 | MODULE_PARM_DESC(radio_nr, "radio device numbers"); | 84 | MODULE_PARM_DESC(radio_nr, "radio device numbers"); |
@@ -93,8 +87,15 @@ static unsigned int video_debug; | |||
93 | module_param(video_debug, int, 0644); | 87 | module_param(video_debug, int, 0644); |
94 | MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); | 88 | MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); |
95 | 89 | ||
96 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ | 90 | /* supported video standards */ |
97 | static unsigned long em28xx_devused; | 91 | static struct em28xx_fmt format[] = { |
92 | { | ||
93 | .name = "16bpp YUY2, 4:2:2, packed", | ||
94 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
95 | .depth = 16, | ||
96 | .reg = EM28XX_OUTFMT_YUV422_Y0UY1V, | ||
97 | }, | ||
98 | }; | ||
98 | 99 | ||
99 | /* supported controls */ | 100 | /* supported controls */ |
100 | /* Common to all boards */ | 101 | /* Common to all boards */ |
@@ -120,8 +121,6 @@ static struct v4l2_queryctrl em28xx_qctrl[] = { | |||
120 | } | 121 | } |
121 | }; | 122 | }; |
122 | 123 | ||
123 | static struct usb_driver em28xx_usb_driver; | ||
124 | |||
125 | /* ------------------------------------------------------------------ | 124 | /* ------------------------------------------------------------------ |
126 | DMA and thread functions | 125 | DMA and thread functions |
127 | ------------------------------------------------------------------*/ | 126 | ------------------------------------------------------------------*/ |
@@ -386,16 +385,18 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | |||
386 | struct em28xx *dev = fh->dev; | 385 | struct em28xx *dev = fh->dev; |
387 | struct v4l2_frequency f; | 386 | struct v4l2_frequency f; |
388 | 387 | ||
389 | *size = 16 * fh->dev->width * fh->dev->height >> 3; | 388 | *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3; |
389 | |||
390 | if (0 == *count) | 390 | if (0 == *count) |
391 | *count = EM28XX_DEF_BUF; | 391 | *count = EM28XX_DEF_BUF; |
392 | 392 | ||
393 | if (*count < EM28XX_MIN_BUF) | 393 | if (*count < EM28XX_MIN_BUF) |
394 | *count = EM28XX_MIN_BUF; | 394 | *count = EM28XX_MIN_BUF; |
395 | 395 | ||
396 | /* Ask tuner to go to analog mode */ | 396 | /* Ask tuner to go to analog or radio mode */ |
397 | memset(&f, 0, sizeof(f)); | 397 | memset(&f, 0, sizeof(f)); |
398 | f.frequency = dev->ctl_freq; | 398 | f.frequency = dev->ctl_freq; |
399 | f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
399 | 400 | ||
400 | em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f); | 401 | em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f); |
401 | 402 | ||
@@ -438,9 +439,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
438 | struct em28xx *dev = fh->dev; | 439 | struct em28xx *dev = fh->dev; |
439 | int rc = 0, urb_init = 0; | 440 | int rc = 0, urb_init = 0; |
440 | 441 | ||
441 | /* FIXME: It assumes depth = 16 */ | 442 | buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3; |
442 | /* The only currently supported format is 16 bits/pixel */ | ||
443 | buf->vb.size = 16 * dev->width * dev->height >> 3; | ||
444 | 443 | ||
445 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 444 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) |
446 | return -EINVAL; | 445 | return -EINVAL; |
@@ -508,56 +507,6 @@ static struct videobuf_queue_ops em28xx_video_qops = { | |||
508 | 507 | ||
509 | /********************* v4l2 interface **************************************/ | 508 | /********************* v4l2 interface **************************************/ |
510 | 509 | ||
511 | /* | ||
512 | * em28xx_config() | ||
513 | * inits registers with sane defaults | ||
514 | */ | ||
515 | static int em28xx_config(struct em28xx *dev) | ||
516 | { | ||
517 | int retval; | ||
518 | |||
519 | /* Sets I2C speed to 100 KHz */ | ||
520 | if (!dev->is_em2800) { | ||
521 | retval = em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1); | ||
522 | if (retval < 0) { | ||
523 | em28xx_errdev("%s: em28xx_write_regs_req failed! retval [%d]\n", | ||
524 | __func__, retval); | ||
525 | return retval; | ||
526 | } | ||
527 | } | ||
528 | |||
529 | /* enable vbi capturing */ | ||
530 | |||
531 | /* em28xx_write_regs_req(dev, 0x00, 0x0e, "\xC0", 1); audio register */ | ||
532 | /* em28xx_write_regs_req(dev, 0x00, 0x0f, "\x80", 1); clk register */ | ||
533 | em28xx_write_regs_req(dev, 0x00, 0x11, "\x51", 1); | ||
534 | |||
535 | dev->mute = 1; /* maybe not the right place... */ | ||
536 | dev->volume = 0x1f; | ||
537 | |||
538 | em28xx_outfmt_set_yuv422(dev); | ||
539 | em28xx_colorlevels_set_default(dev); | ||
540 | em28xx_compression_disable(dev); | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | /* | ||
546 | * em28xx_config_i2c() | ||
547 | * configure i2c attached devices | ||
548 | */ | ||
549 | static void em28xx_config_i2c(struct em28xx *dev) | ||
550 | { | ||
551 | struct v4l2_routing route; | ||
552 | int zero = 0; | ||
553 | |||
554 | route.input = INPUT(dev->ctl_input)->vmux; | ||
555 | route.output = 0; | ||
556 | em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, &zero); | ||
557 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); | ||
558 | em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); | ||
559 | } | ||
560 | |||
561 | static void video_mux(struct em28xx *dev, int index) | 510 | static void video_mux(struct em28xx *dev, int index) |
562 | { | 511 | { |
563 | struct v4l2_routing route; | 512 | struct v4l2_routing route; |
@@ -566,10 +515,14 @@ static void video_mux(struct em28xx *dev, int index) | |||
566 | route.output = 0; | 515 | route.output = 0; |
567 | dev->ctl_input = index; | 516 | dev->ctl_input = index; |
568 | dev->ctl_ainput = INPUT(index)->amux; | 517 | dev->ctl_ainput = INPUT(index)->amux; |
518 | dev->ctl_aoutput = INPUT(index)->aout; | ||
519 | |||
520 | if (!dev->ctl_aoutput) | ||
521 | dev->ctl_aoutput = EM28XX_AOUT_MASTER; | ||
569 | 522 | ||
570 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); | 523 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); |
571 | 524 | ||
572 | if (dev->has_msp34xx) { | 525 | if (dev->board.has_msp34xx) { |
573 | if (dev->i2s_speed) { | 526 | if (dev->i2s_speed) { |
574 | em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, | 527 | em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, |
575 | &dev->i2s_speed); | 528 | &dev->i2s_speed); |
@@ -595,12 +548,10 @@ static int res_get(struct em28xx_fh *fh) | |||
595 | return rc; | 548 | return rc; |
596 | 549 | ||
597 | if (dev->stream_on) | 550 | if (dev->stream_on) |
598 | return -EINVAL; | 551 | return -EBUSY; |
599 | 552 | ||
600 | mutex_lock(&dev->lock); | ||
601 | dev->stream_on = 1; | 553 | dev->stream_on = 1; |
602 | fh->stream_on = 1; | 554 | fh->stream_on = 1; |
603 | mutex_unlock(&dev->lock); | ||
604 | return rc; | 555 | return rc; |
605 | } | 556 | } |
606 | 557 | ||
@@ -613,10 +564,8 @@ static void res_free(struct em28xx_fh *fh) | |||
613 | { | 564 | { |
614 | struct em28xx *dev = fh->dev; | 565 | struct em28xx *dev = fh->dev; |
615 | 566 | ||
616 | mutex_lock(&dev->lock); | ||
617 | fh->stream_on = 0; | 567 | fh->stream_on = 0; |
618 | dev->stream_on = 0; | 568 | dev->stream_on = 0; |
619 | mutex_unlock(&dev->lock); | ||
620 | } | 569 | } |
621 | 570 | ||
622 | /* | 571 | /* |
@@ -703,8 +652,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
703 | 652 | ||
704 | f->fmt.pix.width = dev->width; | 653 | f->fmt.pix.width = dev->width; |
705 | f->fmt.pix.height = dev->height; | 654 | f->fmt.pix.height = dev->height; |
706 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; | 655 | f->fmt.pix.pixelformat = dev->format->fourcc; |
707 | f->fmt.pix.bytesperline = dev->width * 2; | 656 | f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3; |
708 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height; | 657 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height; |
709 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 658 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
710 | 659 | ||
@@ -716,6 +665,17 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
716 | return 0; | 665 | return 0; |
717 | } | 666 | } |
718 | 667 | ||
668 | static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc) | ||
669 | { | ||
670 | unsigned int i; | ||
671 | |||
672 | for (i = 0; i < ARRAY_SIZE(format); i++) | ||
673 | if (format[i].fourcc == fourcc) | ||
674 | return &format[i]; | ||
675 | |||
676 | return NULL; | ||
677 | } | ||
678 | |||
719 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | 679 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, |
720 | struct v4l2_format *f) | 680 | struct v4l2_format *f) |
721 | { | 681 | { |
@@ -726,24 +686,30 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
726 | unsigned int maxw = norm_maxw(dev); | 686 | unsigned int maxw = norm_maxw(dev); |
727 | unsigned int maxh = norm_maxh(dev); | 687 | unsigned int maxh = norm_maxh(dev); |
728 | unsigned int hscale, vscale; | 688 | unsigned int hscale, vscale; |
689 | struct em28xx_fmt *fmt; | ||
690 | |||
691 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | ||
692 | if (!fmt) { | ||
693 | em28xx_videodbg("Fourcc format (%08x) invalid.\n", | ||
694 | f->fmt.pix.pixelformat); | ||
695 | return -EINVAL; | ||
696 | } | ||
729 | 697 | ||
730 | /* width must even because of the YUYV format | 698 | /* width must even because of the YUYV format |
731 | height must be even because of interlacing */ | 699 | height must be even because of interlacing */ |
732 | height &= 0xfffe; | 700 | height &= 0xfffe; |
733 | width &= 0xfffe; | 701 | width &= 0xfffe; |
734 | 702 | ||
735 | if (height < 32) | 703 | if (unlikely(height < 32)) |
736 | height = 32; | 704 | height = 32; |
737 | if (height > maxh) | 705 | if (unlikely(height > maxh)) |
738 | height = maxh; | 706 | height = maxh; |
739 | if (width < 48) | 707 | if (unlikely(width < 48)) |
740 | width = 48; | 708 | width = 48; |
741 | if (width > maxw) | 709 | if (unlikely(width > maxw)) |
742 | width = maxw; | 710 | width = maxw; |
743 | 711 | ||
744 | mutex_lock(&dev->lock); | 712 | if (dev->board.is_em2800) { |
745 | |||
746 | if (dev->is_em2800) { | ||
747 | /* the em2800 can only scale down to 50% */ | 713 | /* the em2800 can only scale down to 50% */ |
748 | if (height % (maxh / 2)) | 714 | if (height % (maxh / 2)) |
749 | height = maxh; | 715 | height = maxh; |
@@ -766,13 +732,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
766 | 732 | ||
767 | f->fmt.pix.width = width; | 733 | f->fmt.pix.width = width; |
768 | f->fmt.pix.height = height; | 734 | f->fmt.pix.height = height; |
769 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; | 735 | f->fmt.pix.pixelformat = fmt->fourcc; |
770 | f->fmt.pix.bytesperline = width * 2; | 736 | f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3; |
771 | f->fmt.pix.sizeimage = width * 2 * height; | 737 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height; |
772 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 738 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
773 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; | 739 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; |
774 | 740 | ||
775 | mutex_unlock(&dev->lock); | ||
776 | return 0; | 741 | return 0; |
777 | } | 742 | } |
778 | 743 | ||
@@ -782,14 +747,21 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
782 | struct em28xx_fh *fh = priv; | 747 | struct em28xx_fh *fh = priv; |
783 | struct em28xx *dev = fh->dev; | 748 | struct em28xx *dev = fh->dev; |
784 | int rc; | 749 | int rc; |
750 | struct em28xx_fmt *fmt; | ||
785 | 751 | ||
786 | rc = check_dev(dev); | 752 | rc = check_dev(dev); |
787 | if (rc < 0) | 753 | if (rc < 0) |
788 | return rc; | 754 | return rc; |
789 | 755 | ||
756 | mutex_lock(&dev->lock); | ||
757 | |||
790 | vidioc_try_fmt_vid_cap(file, priv, f); | 758 | vidioc_try_fmt_vid_cap(file, priv, f); |
791 | 759 | ||
792 | mutex_lock(&dev->lock); | 760 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
761 | if (!fmt) { | ||
762 | rc = -EINVAL; | ||
763 | goto out; | ||
764 | } | ||
793 | 765 | ||
794 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { | 766 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { |
795 | em28xx_errdev("%s queue busy\n", __func__); | 767 | em28xx_errdev("%s queue busy\n", __func__); |
@@ -806,6 +778,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
806 | /* set new image size */ | 778 | /* set new image size */ |
807 | dev->width = f->fmt.pix.width; | 779 | dev->width = f->fmt.pix.width; |
808 | dev->height = f->fmt.pix.height; | 780 | dev->height = f->fmt.pix.height; |
781 | dev->format = fmt; | ||
809 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); | 782 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); |
810 | 783 | ||
811 | em28xx_set_alternate(dev); | 784 | em28xx_set_alternate(dev); |
@@ -831,15 +804,12 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm) | |||
831 | 804 | ||
832 | mutex_lock(&dev->lock); | 805 | mutex_lock(&dev->lock); |
833 | dev->norm = *norm; | 806 | dev->norm = *norm; |
834 | mutex_unlock(&dev->lock); | ||
835 | 807 | ||
836 | /* Adjusts width/height, if needed */ | 808 | /* Adjusts width/height, if needed */ |
837 | f.fmt.pix.width = dev->width; | 809 | f.fmt.pix.width = dev->width; |
838 | f.fmt.pix.height = dev->height; | 810 | f.fmt.pix.height = dev->height; |
839 | vidioc_try_fmt_vid_cap(file, priv, &f); | 811 | vidioc_try_fmt_vid_cap(file, priv, &f); |
840 | 812 | ||
841 | mutex_lock(&dev->lock); | ||
842 | |||
843 | /* set new image size */ | 813 | /* set new image size */ |
844 | dev->width = f.fmt.pix.width; | 814 | dev->width = f.fmt.pix.width; |
845 | dev->height = f.fmt.pix.height; | 815 | dev->height = f.fmt.pix.height; |
@@ -928,20 +898,38 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) | |||
928 | { | 898 | { |
929 | struct em28xx_fh *fh = priv; | 899 | struct em28xx_fh *fh = priv; |
930 | struct em28xx *dev = fh->dev; | 900 | struct em28xx *dev = fh->dev; |
931 | unsigned int index = a->index; | ||
932 | |||
933 | if (a->index > 1) | ||
934 | return -EINVAL; | ||
935 | |||
936 | index = dev->ctl_ainput; | ||
937 | 901 | ||
938 | if (index == 0) | 902 | switch (a->index) { |
903 | case EM28XX_AMUX_VIDEO: | ||
939 | strcpy(a->name, "Television"); | 904 | strcpy(a->name, "Television"); |
940 | else | 905 | break; |
906 | case EM28XX_AMUX_LINE_IN: | ||
941 | strcpy(a->name, "Line In"); | 907 | strcpy(a->name, "Line In"); |
908 | break; | ||
909 | case EM28XX_AMUX_VIDEO2: | ||
910 | strcpy(a->name, "Television alt"); | ||
911 | break; | ||
912 | case EM28XX_AMUX_PHONE: | ||
913 | strcpy(a->name, "Phone"); | ||
914 | break; | ||
915 | case EM28XX_AMUX_MIC: | ||
916 | strcpy(a->name, "Mic"); | ||
917 | break; | ||
918 | case EM28XX_AMUX_CD: | ||
919 | strcpy(a->name, "CD"); | ||
920 | break; | ||
921 | case EM28XX_AMUX_AUX: | ||
922 | strcpy(a->name, "Aux"); | ||
923 | break; | ||
924 | case EM28XX_AMUX_PCM_OUT: | ||
925 | strcpy(a->name, "PCM"); | ||
926 | break; | ||
927 | default: | ||
928 | return -EINVAL; | ||
929 | } | ||
942 | 930 | ||
931 | a->index = dev->ctl_ainput; | ||
943 | a->capability = V4L2_AUDCAP_STEREO; | 932 | a->capability = V4L2_AUDCAP_STEREO; |
944 | a->index = index; | ||
945 | 933 | ||
946 | return 0; | 934 | return 0; |
947 | } | 935 | } |
@@ -951,9 +939,15 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) | |||
951 | struct em28xx_fh *fh = priv; | 939 | struct em28xx_fh *fh = priv; |
952 | struct em28xx *dev = fh->dev; | 940 | struct em28xx *dev = fh->dev; |
953 | 941 | ||
954 | if (a->index != dev->ctl_ainput) | 942 | mutex_lock(&dev->lock); |
955 | return -EINVAL; | 943 | |
944 | dev->ctl_ainput = INPUT(a->index)->amux; | ||
945 | dev->ctl_aoutput = INPUT(a->index)->aout; | ||
956 | 946 | ||
947 | if (!dev->ctl_aoutput) | ||
948 | dev->ctl_aoutput = EM28XX_AOUT_MASTER; | ||
949 | |||
950 | mutex_unlock(&dev->lock); | ||
957 | return 0; | 951 | return 0; |
958 | } | 952 | } |
959 | 953 | ||
@@ -974,7 +968,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, | |||
974 | 968 | ||
975 | qc->id = id; | 969 | qc->id = id; |
976 | 970 | ||
977 | if (!dev->has_msp34xx) { | 971 | if (!dev->board.has_msp34xx) { |
978 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { | 972 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { |
979 | if (qc->id && qc->id == em28xx_qctrl[i].id) { | 973 | if (qc->id && qc->id == em28xx_qctrl[i].id) { |
980 | memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc)); | 974 | memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc)); |
@@ -1002,17 +996,14 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
1002 | rc = check_dev(dev); | 996 | rc = check_dev(dev); |
1003 | if (rc < 0) | 997 | if (rc < 0) |
1004 | return rc; | 998 | return rc; |
1005 | mutex_lock(&dev->lock); | 999 | rc = 0; |
1006 | 1000 | ||
1007 | if (!dev->has_msp34xx) | 1001 | mutex_lock(&dev->lock); |
1008 | rc = em28xx_get_ctrl(dev, ctrl); | ||
1009 | else | ||
1010 | rc = -EINVAL; | ||
1011 | 1002 | ||
1012 | if (rc == -EINVAL) { | 1003 | if (dev->board.has_msp34xx) |
1013 | em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl); | 1004 | em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl); |
1014 | rc = 0; | 1005 | else |
1015 | } | 1006 | rc = em28xx_get_ctrl(dev, ctrl); |
1016 | 1007 | ||
1017 | mutex_unlock(&dev->lock); | 1008 | mutex_unlock(&dev->lock); |
1018 | return rc; | 1009 | return rc; |
@@ -1032,7 +1023,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1032 | 1023 | ||
1033 | mutex_lock(&dev->lock); | 1024 | mutex_lock(&dev->lock); |
1034 | 1025 | ||
1035 | if (dev->has_msp34xx) | 1026 | if (dev->board.has_msp34xx) |
1036 | em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl); | 1027 | em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl); |
1037 | else { | 1028 | else { |
1038 | rc = 1; | 1029 | rc = 1; |
@@ -1112,8 +1103,10 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
1112 | struct em28xx_fh *fh = priv; | 1103 | struct em28xx_fh *fh = priv; |
1113 | struct em28xx *dev = fh->dev; | 1104 | struct em28xx *dev = fh->dev; |
1114 | 1105 | ||
1106 | mutex_lock(&dev->lock); | ||
1115 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1107 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
1116 | f->frequency = dev->ctl_freq; | 1108 | f->frequency = dev->ctl_freq; |
1109 | mutex_unlock(&dev->lock); | ||
1117 | 1110 | ||
1118 | return 0; | 1111 | return 0; |
1119 | } | 1112 | } |
@@ -1143,6 +1136,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
1143 | em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); | 1136 | em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); |
1144 | 1137 | ||
1145 | mutex_unlock(&dev->lock); | 1138 | mutex_unlock(&dev->lock); |
1139 | |||
1146 | return 0; | 1140 | return 0; |
1147 | } | 1141 | } |
1148 | 1142 | ||
@@ -1159,6 +1153,21 @@ static int em28xx_reg_len(int reg) | |||
1159 | } | 1153 | } |
1160 | } | 1154 | } |
1161 | 1155 | ||
1156 | static int vidioc_g_chip_ident(struct file *file, void *priv, | ||
1157 | struct v4l2_chip_ident *chip) | ||
1158 | { | ||
1159 | struct em28xx_fh *fh = priv; | ||
1160 | struct em28xx *dev = fh->dev; | ||
1161 | |||
1162 | chip->ident = V4L2_IDENT_NONE; | ||
1163 | chip->revision = 0; | ||
1164 | |||
1165 | em28xx_i2c_call_clients(dev, VIDIOC_G_CHIP_IDENT, chip); | ||
1166 | |||
1167 | return 0; | ||
1168 | } | ||
1169 | |||
1170 | |||
1162 | static int vidioc_g_register(struct file *file, void *priv, | 1171 | static int vidioc_g_register(struct file *file, void *priv, |
1163 | struct v4l2_register *reg) | 1172 | struct v4l2_register *reg) |
1164 | { | 1173 | { |
@@ -1166,19 +1175,43 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
1166 | struct em28xx *dev = fh->dev; | 1175 | struct em28xx *dev = fh->dev; |
1167 | int ret; | 1176 | int ret; |
1168 | 1177 | ||
1169 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 1178 | switch (reg->match_type) { |
1179 | case V4L2_CHIP_MATCH_AC97: | ||
1180 | mutex_lock(&dev->lock); | ||
1181 | ret = em28xx_read_ac97(dev, reg->reg); | ||
1182 | mutex_unlock(&dev->lock); | ||
1183 | if (ret < 0) | ||
1184 | return ret; | ||
1185 | |||
1186 | reg->val = ret; | ||
1187 | return 0; | ||
1188 | case V4L2_CHIP_MATCH_I2C_DRIVER: | ||
1189 | em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_REGISTER, reg); | ||
1190 | return 0; | ||
1191 | case V4L2_CHIP_MATCH_I2C_ADDR: | ||
1192 | /* Not supported yet */ | ||
1170 | return -EINVAL; | 1193 | return -EINVAL; |
1194 | default: | ||
1195 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | ||
1196 | return -EINVAL; | ||
1197 | } | ||
1171 | 1198 | ||
1199 | /* Match host */ | ||
1172 | if (em28xx_reg_len(reg->reg) == 1) { | 1200 | if (em28xx_reg_len(reg->reg) == 1) { |
1201 | mutex_lock(&dev->lock); | ||
1173 | ret = em28xx_read_reg(dev, reg->reg); | 1202 | ret = em28xx_read_reg(dev, reg->reg); |
1203 | mutex_unlock(&dev->lock); | ||
1204 | |||
1174 | if (ret < 0) | 1205 | if (ret < 0) |
1175 | return ret; | 1206 | return ret; |
1176 | 1207 | ||
1177 | reg->val = ret; | 1208 | reg->val = ret; |
1178 | } else { | 1209 | } else { |
1179 | __le64 val = 0; | 1210 | __le64 val = 0; |
1211 | mutex_lock(&dev->lock); | ||
1180 | ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, | 1212 | ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, |
1181 | reg->reg, (char *)&val, 2); | 1213 | reg->reg, (char *)&val, 2); |
1214 | mutex_unlock(&dev->lock); | ||
1182 | if (ret < 0) | 1215 | if (ret < 0) |
1183 | return ret; | 1216 | return ret; |
1184 | 1217 | ||
@@ -1194,11 +1227,35 @@ static int vidioc_s_register(struct file *file, void *priv, | |||
1194 | struct em28xx_fh *fh = priv; | 1227 | struct em28xx_fh *fh = priv; |
1195 | struct em28xx *dev = fh->dev; | 1228 | struct em28xx *dev = fh->dev; |
1196 | __le64 buf; | 1229 | __le64 buf; |
1230 | int rc; | ||
1197 | 1231 | ||
1232 | switch (reg->match_type) { | ||
1233 | case V4L2_CHIP_MATCH_AC97: | ||
1234 | mutex_lock(&dev->lock); | ||
1235 | rc = em28xx_write_ac97(dev, reg->reg, reg->val); | ||
1236 | mutex_unlock(&dev->lock); | ||
1237 | |||
1238 | return rc; | ||
1239 | case V4L2_CHIP_MATCH_I2C_DRIVER: | ||
1240 | em28xx_i2c_call_clients(dev, VIDIOC_DBG_S_REGISTER, reg); | ||
1241 | return 0; | ||
1242 | case V4L2_CHIP_MATCH_I2C_ADDR: | ||
1243 | /* Not supported yet */ | ||
1244 | return -EINVAL; | ||
1245 | default: | ||
1246 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | ||
1247 | return -EINVAL; | ||
1248 | } | ||
1249 | |||
1250 | /* Match host */ | ||
1198 | buf = cpu_to_le64(reg->val); | 1251 | buf = cpu_to_le64(reg->val); |
1199 | 1252 | ||
1200 | return em28xx_write_regs(dev, reg->reg, (char *)&buf, | 1253 | mutex_lock(&dev->lock); |
1201 | em28xx_reg_len(reg->reg)); | 1254 | rc = em28xx_write_regs(dev, reg->reg, (char *)&buf, |
1255 | em28xx_reg_len(reg->reg)); | ||
1256 | mutex_unlock(&dev->lock); | ||
1257 | |||
1258 | return rc; | ||
1202 | } | 1259 | } |
1203 | #endif | 1260 | #endif |
1204 | 1261 | ||
@@ -1235,10 +1292,15 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1235 | return rc; | 1292 | return rc; |
1236 | 1293 | ||
1237 | 1294 | ||
1238 | if (unlikely(res_get(fh) < 0)) | 1295 | mutex_lock(&dev->lock); |
1239 | return -EBUSY; | 1296 | rc = res_get(fh); |
1297 | |||
1298 | if (likely(rc >= 0)) | ||
1299 | rc = videobuf_streamon(&fh->vb_vidq); | ||
1240 | 1300 | ||
1241 | return (videobuf_streamon(&fh->vb_vidq)); | 1301 | mutex_unlock(&dev->lock); |
1302 | |||
1303 | return rc; | ||
1242 | } | 1304 | } |
1243 | 1305 | ||
1244 | static int vidioc_streamoff(struct file *file, void *priv, | 1306 | static int vidioc_streamoff(struct file *file, void *priv, |
@@ -1257,9 +1319,13 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1257 | if (type != fh->type) | 1319 | if (type != fh->type) |
1258 | return -EINVAL; | 1320 | return -EINVAL; |
1259 | 1321 | ||
1322 | mutex_lock(&dev->lock); | ||
1323 | |||
1260 | videobuf_streamoff(&fh->vb_vidq); | 1324 | videobuf_streamoff(&fh->vb_vidq); |
1261 | res_free(fh); | 1325 | res_free(fh); |
1262 | 1326 | ||
1327 | mutex_unlock(&dev->lock); | ||
1328 | |||
1263 | return 0; | 1329 | return 0; |
1264 | } | 1330 | } |
1265 | 1331 | ||
@@ -1271,7 +1337,7 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
1271 | 1337 | ||
1272 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); | 1338 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); |
1273 | strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); | 1339 | strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); |
1274 | strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info)); | 1340 | strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); |
1275 | 1341 | ||
1276 | cap->version = EM28XX_VERSION_CODE; | 1342 | cap->version = EM28XX_VERSION_CODE; |
1277 | 1343 | ||
@@ -1288,15 +1354,13 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
1288 | } | 1354 | } |
1289 | 1355 | ||
1290 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | 1356 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, |
1291 | struct v4l2_fmtdesc *fmtd) | 1357 | struct v4l2_fmtdesc *f) |
1292 | { | 1358 | { |
1293 | if (fmtd->index != 0) | 1359 | if (unlikely(f->index >= ARRAY_SIZE(format))) |
1294 | return -EINVAL; | 1360 | return -EINVAL; |
1295 | 1361 | ||
1296 | fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1362 | strlcpy(f->description, format[f->index].name, sizeof(f->description)); |
1297 | strcpy(fmtd->description, "Packed YUY2"); | 1363 | f->pixelformat = format[f->index].fourcc; |
1298 | fmtd->pixelformat = V4L2_PIX_FMT_YUYV; | ||
1299 | memset(fmtd->reserved, 0, sizeof(fmtd->reserved)); | ||
1300 | 1364 | ||
1301 | return 0; | 1365 | return 0; |
1302 | } | 1366 | } |
@@ -1424,7 +1488,7 @@ static int radio_querycap(struct file *file, void *priv, | |||
1424 | 1488 | ||
1425 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); | 1489 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); |
1426 | strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); | 1490 | strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); |
1427 | strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info)); | 1491 | strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); |
1428 | 1492 | ||
1429 | cap->version = EM28XX_VERSION_CODE; | 1493 | cap->version = EM28XX_VERSION_CODE; |
1430 | cap->capabilities = V4L2_CAP_TUNER; | 1494 | cap->capabilities = V4L2_CAP_TUNER; |
@@ -1442,7 +1506,10 @@ static int radio_g_tuner(struct file *file, void *priv, | |||
1442 | strcpy(t->name, "Radio"); | 1506 | strcpy(t->name, "Radio"); |
1443 | t->type = V4L2_TUNER_RADIO; | 1507 | t->type = V4L2_TUNER_RADIO; |
1444 | 1508 | ||
1509 | mutex_lock(&dev->lock); | ||
1445 | em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t); | 1510 | em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t); |
1511 | mutex_unlock(&dev->lock); | ||
1512 | |||
1446 | return 0; | 1513 | return 0; |
1447 | } | 1514 | } |
1448 | 1515 | ||
@@ -1474,7 +1541,9 @@ static int radio_s_tuner(struct file *file, void *priv, | |||
1474 | if (0 != t->index) | 1541 | if (0 != t->index) |
1475 | return -EINVAL; | 1542 | return -EINVAL; |
1476 | 1543 | ||
1544 | mutex_lock(&dev->lock); | ||
1477 | em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t); | 1545 | em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t); |
1546 | mutex_unlock(&dev->lock); | ||
1478 | 1547 | ||
1479 | return 0; | 1548 | return 0; |
1480 | } | 1549 | } |
@@ -1516,28 +1585,13 @@ static int radio_queryctrl(struct file *file, void *priv, | |||
1516 | static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | 1585 | static int em28xx_v4l2_open(struct inode *inode, struct file *filp) |
1517 | { | 1586 | { |
1518 | int minor = iminor(inode); | 1587 | int minor = iminor(inode); |
1519 | int errCode = 0, radio = 0; | 1588 | int errCode = 0, radio; |
1520 | struct em28xx *h, *dev = NULL; | 1589 | struct em28xx *dev; |
1590 | enum v4l2_buf_type fh_type; | ||
1521 | struct em28xx_fh *fh; | 1591 | struct em28xx_fh *fh; |
1522 | enum v4l2_buf_type fh_type = 0; | ||
1523 | 1592 | ||
1524 | mutex_lock(&em28xx_devlist_mutex); | 1593 | dev = em28xx_get_device(inode, &fh_type, &radio); |
1525 | list_for_each_entry(h, &em28xx_devlist, devlist) { | 1594 | |
1526 | if (h->vdev->minor == minor) { | ||
1527 | dev = h; | ||
1528 | fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1529 | } | ||
1530 | if (h->vbi_dev->minor == minor) { | ||
1531 | dev = h; | ||
1532 | fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
1533 | } | ||
1534 | if (h->radio_dev && | ||
1535 | h->radio_dev->minor == minor) { | ||
1536 | radio = 1; | ||
1537 | dev = h; | ||
1538 | } | ||
1539 | } | ||
1540 | mutex_unlock(&em28xx_devlist_mutex); | ||
1541 | if (NULL == dev) | 1595 | if (NULL == dev) |
1542 | return -ENODEV; | 1596 | return -ENODEV; |
1543 | 1597 | ||
@@ -1571,7 +1625,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1571 | /* Needed, since GPIO might have disabled power of | 1625 | /* Needed, since GPIO might have disabled power of |
1572 | some i2c device | 1626 | some i2c device |
1573 | */ | 1627 | */ |
1574 | em28xx_config_i2c(dev); | 1628 | em28xx_wake_i2c(dev); |
1575 | 1629 | ||
1576 | } | 1630 | } |
1577 | if (fh->radio) { | 1631 | if (fh->radio) { |
@@ -1595,16 +1649,11 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1595 | * unregisters the v4l2,i2c and usb devices | 1649 | * unregisters the v4l2,i2c and usb devices |
1596 | * called when the device gets disconected or at module unload | 1650 | * called when the device gets disconected or at module unload |
1597 | */ | 1651 | */ |
1598 | static void em28xx_release_resources(struct em28xx *dev) | 1652 | void em28xx_release_analog_resources(struct em28xx *dev) |
1599 | { | 1653 | { |
1600 | 1654 | ||
1601 | /*FIXME: I2C IR should be disconnected */ | 1655 | /*FIXME: I2C IR should be disconnected */ |
1602 | 1656 | ||
1603 | em28xx_info("V4L2 devices /dev/video%d and /dev/vbi%d deregistered\n", | ||
1604 | dev->vdev->num, dev->vbi_dev->num); | ||
1605 | list_del(&dev->devlist); | ||
1606 | if (dev->sbutton_input_dev) | ||
1607 | em28xx_deregister_snapshot_button(dev); | ||
1608 | if (dev->radio_dev) { | 1657 | if (dev->radio_dev) { |
1609 | if (-1 != dev->radio_dev->minor) | 1658 | if (-1 != dev->radio_dev->minor) |
1610 | video_unregister_device(dev->radio_dev); | 1659 | video_unregister_device(dev->radio_dev); |
@@ -1613,6 +1662,8 @@ static void em28xx_release_resources(struct em28xx *dev) | |||
1613 | dev->radio_dev = NULL; | 1662 | dev->radio_dev = NULL; |
1614 | } | 1663 | } |
1615 | if (dev->vbi_dev) { | 1664 | if (dev->vbi_dev) { |
1665 | em28xx_info("V4L2 device /dev/vbi%d deregistered\n", | ||
1666 | dev->vbi_dev->num); | ||
1616 | if (-1 != dev->vbi_dev->minor) | 1667 | if (-1 != dev->vbi_dev->minor) |
1617 | video_unregister_device(dev->vbi_dev); | 1668 | video_unregister_device(dev->vbi_dev); |
1618 | else | 1669 | else |
@@ -1620,17 +1671,14 @@ static void em28xx_release_resources(struct em28xx *dev) | |||
1620 | dev->vbi_dev = NULL; | 1671 | dev->vbi_dev = NULL; |
1621 | } | 1672 | } |
1622 | if (dev->vdev) { | 1673 | if (dev->vdev) { |
1674 | em28xx_info("V4L2 device /dev/video%d deregistered\n", | ||
1675 | dev->vdev->num); | ||
1623 | if (-1 != dev->vdev->minor) | 1676 | if (-1 != dev->vdev->minor) |
1624 | video_unregister_device(dev->vdev); | 1677 | video_unregister_device(dev->vdev); |
1625 | else | 1678 | else |
1626 | video_device_release(dev->vdev); | 1679 | video_device_release(dev->vdev); |
1627 | dev->vdev = NULL; | 1680 | dev->vdev = NULL; |
1628 | } | 1681 | } |
1629 | em28xx_i2c_unregister(dev); | ||
1630 | usb_put_dev(dev->udev); | ||
1631 | |||
1632 | /* Mark device as unused */ | ||
1633 | em28xx_devused &= ~(1<<dev->devno); | ||
1634 | } | 1682 | } |
1635 | 1683 | ||
1636 | /* | 1684 | /* |
@@ -1647,11 +1695,10 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | |||
1647 | em28xx_videodbg("users=%d\n", dev->users); | 1695 | em28xx_videodbg("users=%d\n", dev->users); |
1648 | 1696 | ||
1649 | 1697 | ||
1698 | mutex_lock(&dev->lock); | ||
1650 | if (res_check(fh)) | 1699 | if (res_check(fh)) |
1651 | res_free(fh); | 1700 | res_free(fh); |
1652 | 1701 | ||
1653 | mutex_lock(&dev->lock); | ||
1654 | |||
1655 | if (dev->users == 1) { | 1702 | if (dev->users == 1) { |
1656 | videobuf_stop(&fh->vb_vidq); | 1703 | videobuf_stop(&fh->vb_vidq); |
1657 | videobuf_mmap_free(&fh->vb_vidq); | 1704 | videobuf_mmap_free(&fh->vb_vidq); |
@@ -1665,9 +1712,12 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | |||
1665 | return 0; | 1712 | return 0; |
1666 | } | 1713 | } |
1667 | 1714 | ||
1715 | /* Save some power by putting tuner to sleep */ | ||
1716 | em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL); | ||
1717 | |||
1668 | /* do this before setting alternate! */ | 1718 | /* do this before setting alternate! */ |
1669 | em28xx_uninit_isoc(dev); | 1719 | em28xx_uninit_isoc(dev); |
1670 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | 1720 | em28xx_set_mode(dev, EM28XX_SUSPEND); |
1671 | 1721 | ||
1672 | /* set alternate 0 */ | 1722 | /* set alternate 0 */ |
1673 | dev->alt = 0; | 1723 | dev->alt = 0; |
@@ -1706,8 +1756,12 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count, | |||
1706 | */ | 1756 | */ |
1707 | 1757 | ||
1708 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1758 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
1709 | if (unlikely(res_get(fh))) | 1759 | mutex_lock(&dev->lock); |
1710 | return -EBUSY; | 1760 | rc = res_get(fh); |
1761 | mutex_unlock(&dev->lock); | ||
1762 | |||
1763 | if (unlikely(rc < 0)) | ||
1764 | return rc; | ||
1711 | 1765 | ||
1712 | return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, | 1766 | return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, |
1713 | filp->f_flags & O_NONBLOCK); | 1767 | filp->f_flags & O_NONBLOCK); |
@@ -1729,7 +1783,11 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait) | |||
1729 | if (rc < 0) | 1783 | if (rc < 0) |
1730 | return rc; | 1784 | return rc; |
1731 | 1785 | ||
1732 | if (unlikely(res_get(fh) < 0)) | 1786 | mutex_lock(&dev->lock); |
1787 | rc = res_get(fh); | ||
1788 | mutex_unlock(&dev->lock); | ||
1789 | |||
1790 | if (unlikely(rc < 0)) | ||
1733 | return POLLERR; | 1791 | return POLLERR; |
1734 | 1792 | ||
1735 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) | 1793 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) |
@@ -1747,13 +1805,17 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | |||
1747 | struct em28xx *dev = fh->dev; | 1805 | struct em28xx *dev = fh->dev; |
1748 | int rc; | 1806 | int rc; |
1749 | 1807 | ||
1750 | if (unlikely(res_get(fh) < 0)) | ||
1751 | return -EBUSY; | ||
1752 | |||
1753 | rc = check_dev(dev); | 1808 | rc = check_dev(dev); |
1754 | if (rc < 0) | 1809 | if (rc < 0) |
1755 | return rc; | 1810 | return rc; |
1756 | 1811 | ||
1812 | mutex_lock(&dev->lock); | ||
1813 | rc = res_get(fh); | ||
1814 | mutex_unlock(&dev->lock); | ||
1815 | |||
1816 | if (unlikely(rc < 0)) | ||
1817 | return rc; | ||
1818 | |||
1757 | rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); | 1819 | rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); |
1758 | 1820 | ||
1759 | em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n", | 1821 | em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n", |
@@ -1810,6 +1872,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1810 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1872 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1811 | .vidioc_g_register = vidioc_g_register, | 1873 | .vidioc_g_register = vidioc_g_register, |
1812 | .vidioc_s_register = vidioc_s_register, | 1874 | .vidioc_s_register = vidioc_s_register, |
1875 | .vidioc_g_chip_ident = vidioc_g_chip_ident, | ||
1813 | #endif | 1876 | #endif |
1814 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1877 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1815 | .vidiocgmbuf = vidiocgmbuf, | 1878 | .vidiocgmbuf = vidiocgmbuf, |
@@ -1865,44 +1928,6 @@ static struct video_device em28xx_radio_template = { | |||
1865 | /******************************** usb interface ******************************/ | 1928 | /******************************** usb interface ******************************/ |
1866 | 1929 | ||
1867 | 1930 | ||
1868 | static LIST_HEAD(em28xx_extension_devlist); | ||
1869 | static DEFINE_MUTEX(em28xx_extension_devlist_lock); | ||
1870 | |||
1871 | int em28xx_register_extension(struct em28xx_ops *ops) | ||
1872 | { | ||
1873 | struct em28xx *dev = NULL; | ||
1874 | |||
1875 | mutex_lock(&em28xx_devlist_mutex); | ||
1876 | mutex_lock(&em28xx_extension_devlist_lock); | ||
1877 | list_add_tail(&ops->next, &em28xx_extension_devlist); | ||
1878 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | ||
1879 | if (dev) | ||
1880 | ops->init(dev); | ||
1881 | } | ||
1882 | printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); | ||
1883 | mutex_unlock(&em28xx_extension_devlist_lock); | ||
1884 | mutex_unlock(&em28xx_devlist_mutex); | ||
1885 | return 0; | ||
1886 | } | ||
1887 | EXPORT_SYMBOL(em28xx_register_extension); | ||
1888 | |||
1889 | void em28xx_unregister_extension(struct em28xx_ops *ops) | ||
1890 | { | ||
1891 | struct em28xx *dev = NULL; | ||
1892 | |||
1893 | mutex_lock(&em28xx_devlist_mutex); | ||
1894 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | ||
1895 | if (dev) | ||
1896 | ops->fini(dev); | ||
1897 | } | ||
1898 | |||
1899 | mutex_lock(&em28xx_extension_devlist_lock); | ||
1900 | printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); | ||
1901 | list_del(&ops->next); | ||
1902 | mutex_unlock(&em28xx_extension_devlist_lock); | ||
1903 | mutex_unlock(&em28xx_devlist_mutex); | ||
1904 | } | ||
1905 | EXPORT_SYMBOL(em28xx_unregister_extension); | ||
1906 | 1931 | ||
1907 | static struct video_device *em28xx_vdev_init(struct em28xx *dev, | 1932 | static struct video_device *em28xx_vdev_init(struct em28xx *dev, |
1908 | const struct video_device *template, | 1933 | const struct video_device *template, |
@@ -1925,11 +1950,43 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, | |||
1925 | return vfd; | 1950 | return vfd; |
1926 | } | 1951 | } |
1927 | 1952 | ||
1928 | 1953 | int em28xx_register_analog_devices(struct em28xx *dev) | |
1929 | static int register_analog_devices(struct em28xx *dev) | ||
1930 | { | 1954 | { |
1931 | int ret; | 1955 | int ret; |
1932 | 1956 | ||
1957 | printk(KERN_INFO "%s: v4l2 driver version %d.%d.%d\n", | ||
1958 | dev->name, | ||
1959 | (EM28XX_VERSION_CODE >> 16) & 0xff, | ||
1960 | (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff); | ||
1961 | |||
1962 | /* Analog specific initialization */ | ||
1963 | dev->format = &format[0]; | ||
1964 | video_mux(dev, 0); | ||
1965 | |||
1966 | /* enable vbi capturing */ | ||
1967 | |||
1968 | /* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */ | ||
1969 | /* em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */ | ||
1970 | em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51); | ||
1971 | |||
1972 | dev->mute = 1; /* maybe not the right place... */ | ||
1973 | dev->volume = 0x1f; | ||
1974 | |||
1975 | em28xx_set_outfmt(dev); | ||
1976 | em28xx_colorlevels_set_default(dev); | ||
1977 | em28xx_compression_disable(dev); | ||
1978 | |||
1979 | /* set default norm */ | ||
1980 | dev->norm = em28xx_video_template.current_norm; | ||
1981 | dev->width = norm_maxw(dev); | ||
1982 | dev->height = norm_maxh(dev); | ||
1983 | dev->interlaced = EM28XX_INTERLACED_DEFAULT; | ||
1984 | dev->hscale = 0; | ||
1985 | dev->vscale = 0; | ||
1986 | |||
1987 | /* FIXME: This is a very bad hack! Not all devices have TV on input 2 */ | ||
1988 | dev->ctl_input = 2; | ||
1989 | |||
1933 | /* allocate and fill video video_device struct */ | 1990 | /* allocate and fill video video_device struct */ |
1934 | dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); | 1991 | dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); |
1935 | if (!dev->vdev) { | 1992 | if (!dev->vdev) { |
@@ -1978,383 +2035,3 @@ static int register_analog_devices(struct em28xx *dev) | |||
1978 | 2035 | ||
1979 | return 0; | 2036 | return 0; |
1980 | } | 2037 | } |
1981 | |||
1982 | |||
1983 | /* | ||
1984 | * em28xx_init_dev() | ||
1985 | * allocates and inits the device structs, registers i2c bus and v4l device | ||
1986 | */ | ||
1987 | static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | ||
1988 | int minor) | ||
1989 | { | ||
1990 | struct em28xx_ops *ops = NULL; | ||
1991 | struct em28xx *dev = *devhandle; | ||
1992 | int retval = -ENOMEM; | ||
1993 | int errCode; | ||
1994 | unsigned int maxh, maxw; | ||
1995 | |||
1996 | dev->udev = udev; | ||
1997 | mutex_init(&dev->lock); | ||
1998 | mutex_init(&dev->ctrl_urb_lock); | ||
1999 | spin_lock_init(&dev->slock); | ||
2000 | init_waitqueue_head(&dev->open); | ||
2001 | init_waitqueue_head(&dev->wait_frame); | ||
2002 | init_waitqueue_head(&dev->wait_stream); | ||
2003 | |||
2004 | dev->em28xx_write_regs = em28xx_write_regs; | ||
2005 | dev->em28xx_read_reg = em28xx_read_reg; | ||
2006 | dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len; | ||
2007 | dev->em28xx_write_regs_req = em28xx_write_regs_req; | ||
2008 | dev->em28xx_read_reg_req = em28xx_read_reg_req; | ||
2009 | dev->is_em2800 = em28xx_boards[dev->model].is_em2800; | ||
2010 | |||
2011 | em28xx_pre_card_setup(dev); | ||
2012 | |||
2013 | errCode = em28xx_config(dev); | ||
2014 | if (errCode) { | ||
2015 | em28xx_errdev("error configuring device\n"); | ||
2016 | return -ENOMEM; | ||
2017 | } | ||
2018 | |||
2019 | /* register i2c bus */ | ||
2020 | errCode = em28xx_i2c_register(dev); | ||
2021 | if (errCode < 0) { | ||
2022 | em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n", | ||
2023 | __func__, errCode); | ||
2024 | return errCode; | ||
2025 | } | ||
2026 | |||
2027 | /* Do board specific init and eeprom reading */ | ||
2028 | em28xx_card_setup(dev); | ||
2029 | |||
2030 | /* Configure audio */ | ||
2031 | errCode = em28xx_audio_analog_set(dev); | ||
2032 | if (errCode < 0) { | ||
2033 | em28xx_errdev("%s: em28xx_audio_analog_set - errCode [%d]!\n", | ||
2034 | __func__, errCode); | ||
2035 | return errCode; | ||
2036 | } | ||
2037 | |||
2038 | /* configure the device */ | ||
2039 | em28xx_config_i2c(dev); | ||
2040 | |||
2041 | /* set default norm */ | ||
2042 | dev->norm = em28xx_video_template.current_norm; | ||
2043 | |||
2044 | maxw = norm_maxw(dev); | ||
2045 | maxh = norm_maxh(dev); | ||
2046 | |||
2047 | /* set default image size */ | ||
2048 | dev->width = maxw; | ||
2049 | dev->height = maxh; | ||
2050 | dev->interlaced = EM28XX_INTERLACED_DEFAULT; | ||
2051 | dev->hscale = 0; | ||
2052 | dev->vscale = 0; | ||
2053 | dev->ctl_input = 2; | ||
2054 | |||
2055 | errCode = em28xx_config(dev); | ||
2056 | if (errCode < 0) { | ||
2057 | em28xx_errdev("%s: em28xx_config - errCode [%d]!\n", | ||
2058 | __func__, errCode); | ||
2059 | return errCode; | ||
2060 | } | ||
2061 | |||
2062 | /* init video dma queues */ | ||
2063 | INIT_LIST_HEAD(&dev->vidq.active); | ||
2064 | INIT_LIST_HEAD(&dev->vidq.queued); | ||
2065 | |||
2066 | |||
2067 | if (dev->has_msp34xx) { | ||
2068 | /* Send a reset to other chips via gpio */ | ||
2069 | errCode = em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1); | ||
2070 | if (errCode < 0) { | ||
2071 | em28xx_errdev("%s: em28xx_write_regs_req - msp34xx(1) failed! errCode [%d]\n", | ||
2072 | __func__, errCode); | ||
2073 | return errCode; | ||
2074 | } | ||
2075 | msleep(3); | ||
2076 | |||
2077 | errCode = em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1); | ||
2078 | if (errCode < 0) { | ||
2079 | em28xx_errdev("%s: em28xx_write_regs_req - msp34xx(2) failed! errCode [%d]\n", | ||
2080 | __func__, errCode); | ||
2081 | return errCode; | ||
2082 | } | ||
2083 | msleep(3); | ||
2084 | } | ||
2085 | |||
2086 | video_mux(dev, 0); | ||
2087 | |||
2088 | mutex_lock(&em28xx_devlist_mutex); | ||
2089 | list_add_tail(&dev->devlist, &em28xx_devlist); | ||
2090 | retval = register_analog_devices(dev); | ||
2091 | if (retval < 0) { | ||
2092 | em28xx_release_resources(dev); | ||
2093 | mutex_unlock(&em28xx_devlist_mutex); | ||
2094 | goto fail_reg_devices; | ||
2095 | } | ||
2096 | |||
2097 | mutex_lock(&em28xx_extension_devlist_lock); | ||
2098 | if (!list_empty(&em28xx_extension_devlist)) { | ||
2099 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { | ||
2100 | if (ops->id) | ||
2101 | ops->init(dev); | ||
2102 | } | ||
2103 | } | ||
2104 | mutex_unlock(&em28xx_extension_devlist_lock); | ||
2105 | mutex_unlock(&em28xx_devlist_mutex); | ||
2106 | |||
2107 | return 0; | ||
2108 | |||
2109 | fail_reg_devices: | ||
2110 | mutex_unlock(&dev->lock); | ||
2111 | return retval; | ||
2112 | } | ||
2113 | |||
2114 | #if defined(CONFIG_MODULES) && defined(MODULE) | ||
2115 | static void request_module_async(struct work_struct *work) | ||
2116 | { | ||
2117 | struct em28xx *dev = container_of(work, | ||
2118 | struct em28xx, request_module_wk); | ||
2119 | |||
2120 | if (dev->has_audio_class) | ||
2121 | request_module("snd-usb-audio"); | ||
2122 | else | ||
2123 | request_module("em28xx-alsa"); | ||
2124 | |||
2125 | if (dev->has_dvb) | ||
2126 | request_module("em28xx-dvb"); | ||
2127 | } | ||
2128 | |||
2129 | static void request_modules(struct em28xx *dev) | ||
2130 | { | ||
2131 | INIT_WORK(&dev->request_module_wk, request_module_async); | ||
2132 | schedule_work(&dev->request_module_wk); | ||
2133 | } | ||
2134 | #else | ||
2135 | #define request_modules(dev) | ||
2136 | #endif /* CONFIG_MODULES */ | ||
2137 | |||
2138 | /* | ||
2139 | * em28xx_usb_probe() | ||
2140 | * checks for supported devices | ||
2141 | */ | ||
2142 | static int em28xx_usb_probe(struct usb_interface *interface, | ||
2143 | const struct usb_device_id *id) | ||
2144 | { | ||
2145 | const struct usb_endpoint_descriptor *endpoint; | ||
2146 | struct usb_device *udev; | ||
2147 | struct usb_interface *uif; | ||
2148 | struct em28xx *dev = NULL; | ||
2149 | int retval = -ENODEV; | ||
2150 | int i, nr, ifnum; | ||
2151 | |||
2152 | udev = usb_get_dev(interface_to_usbdev(interface)); | ||
2153 | ifnum = interface->altsetting[0].desc.bInterfaceNumber; | ||
2154 | |||
2155 | /* Check to see next free device and mark as used */ | ||
2156 | nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS); | ||
2157 | em28xx_devused |= 1<<nr; | ||
2158 | |||
2159 | /* Don't register audio interfaces */ | ||
2160 | if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | ||
2161 | em28xx_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n", | ||
2162 | udev->descriptor.idVendor, | ||
2163 | udev->descriptor.idProduct, | ||
2164 | ifnum, | ||
2165 | interface->altsetting[0].desc.bInterfaceClass); | ||
2166 | |||
2167 | em28xx_devused &= ~(1<<nr); | ||
2168 | return -ENODEV; | ||
2169 | } | ||
2170 | |||
2171 | em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n", | ||
2172 | udev->descriptor.idVendor, | ||
2173 | udev->descriptor.idProduct, | ||
2174 | ifnum, | ||
2175 | interface->altsetting[0].desc.bInterfaceClass); | ||
2176 | |||
2177 | endpoint = &interface->cur_altsetting->endpoint[1].desc; | ||
2178 | |||
2179 | /* check if the device has the iso in endpoint at the correct place */ | ||
2180 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != | ||
2181 | USB_ENDPOINT_XFER_ISOC) { | ||
2182 | em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); | ||
2183 | em28xx_devused &= ~(1<<nr); | ||
2184 | return -ENODEV; | ||
2185 | } | ||
2186 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { | ||
2187 | em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); | ||
2188 | em28xx_devused &= ~(1<<nr); | ||
2189 | return -ENODEV; | ||
2190 | } | ||
2191 | |||
2192 | if (nr >= EM28XX_MAXBOARDS) { | ||
2193 | printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", | ||
2194 | EM28XX_MAXBOARDS); | ||
2195 | em28xx_devused &= ~(1<<nr); | ||
2196 | return -ENOMEM; | ||
2197 | } | ||
2198 | |||
2199 | /* allocate memory for our device state and initialize it */ | ||
2200 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
2201 | if (dev == NULL) { | ||
2202 | em28xx_err(DRIVER_NAME ": out of memory!\n"); | ||
2203 | em28xx_devused &= ~(1<<nr); | ||
2204 | return -ENOMEM; | ||
2205 | } | ||
2206 | |||
2207 | snprintf(dev->name, 29, "em28xx #%d", nr); | ||
2208 | dev->devno = nr; | ||
2209 | dev->model = id->driver_info; | ||
2210 | dev->alt = -1; | ||
2211 | |||
2212 | /* Checks if audio is provided by some interface */ | ||
2213 | for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { | ||
2214 | uif = udev->config->interface[i]; | ||
2215 | if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | ||
2216 | dev->has_audio_class = 1; | ||
2217 | break; | ||
2218 | } | ||
2219 | } | ||
2220 | |||
2221 | printk(KERN_INFO DRIVER_NAME " %s usb audio class\n", | ||
2222 | dev->has_audio_class ? "Has" : "Doesn't have"); | ||
2223 | |||
2224 | /* compute alternate max packet sizes */ | ||
2225 | uif = udev->actconfig->interface[0]; | ||
2226 | |||
2227 | dev->num_alt = uif->num_altsetting; | ||
2228 | em28xx_info("Alternate settings: %i\n", dev->num_alt); | ||
2229 | /* dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)* */ | ||
2230 | dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL); | ||
2231 | |||
2232 | if (dev->alt_max_pkt_size == NULL) { | ||
2233 | em28xx_errdev("out of memory!\n"); | ||
2234 | em28xx_devused &= ~(1<<nr); | ||
2235 | kfree(dev); | ||
2236 | return -ENOMEM; | ||
2237 | } | ||
2238 | |||
2239 | for (i = 0; i < dev->num_alt ; i++) { | ||
2240 | u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc. | ||
2241 | wMaxPacketSize); | ||
2242 | dev->alt_max_pkt_size[i] = | ||
2243 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | ||
2244 | em28xx_info("Alternate setting %i, max size= %i\n", i, | ||
2245 | dev->alt_max_pkt_size[i]); | ||
2246 | } | ||
2247 | |||
2248 | if ((card[nr] >= 0) && (card[nr] < em28xx_bcount)) | ||
2249 | dev->model = card[nr]; | ||
2250 | |||
2251 | /* allocate device struct */ | ||
2252 | retval = em28xx_init_dev(&dev, udev, nr); | ||
2253 | if (retval) { | ||
2254 | em28xx_devused &= ~(1<<dev->devno); | ||
2255 | kfree(dev); | ||
2256 | |||
2257 | return retval; | ||
2258 | } | ||
2259 | |||
2260 | em28xx_info("Found %s\n", em28xx_boards[dev->model].name); | ||
2261 | |||
2262 | /* save our data pointer in this interface device */ | ||
2263 | usb_set_intfdata(interface, dev); | ||
2264 | |||
2265 | request_modules(dev); | ||
2266 | |||
2267 | return 0; | ||
2268 | } | ||
2269 | |||
2270 | /* | ||
2271 | * em28xx_usb_disconnect() | ||
2272 | * called when the device gets diconencted | ||
2273 | * video device will be unregistered on v4l2_close in case it is still open | ||
2274 | */ | ||
2275 | static void em28xx_usb_disconnect(struct usb_interface *interface) | ||
2276 | { | ||
2277 | struct em28xx *dev; | ||
2278 | struct em28xx_ops *ops = NULL; | ||
2279 | |||
2280 | dev = usb_get_intfdata(interface); | ||
2281 | usb_set_intfdata(interface, NULL); | ||
2282 | |||
2283 | if (!dev) | ||
2284 | return; | ||
2285 | |||
2286 | em28xx_info("disconnecting %s\n", dev->vdev->name); | ||
2287 | |||
2288 | /* wait until all current v4l2 io is finished then deallocate | ||
2289 | resources */ | ||
2290 | mutex_lock(&dev->lock); | ||
2291 | |||
2292 | wake_up_interruptible_all(&dev->open); | ||
2293 | |||
2294 | if (dev->users) { | ||
2295 | em28xx_warn | ||
2296 | ("device /dev/video%d is open! Deregistration and memory " | ||
2297 | "deallocation are deferred on close.\n", | ||
2298 | dev->vdev->num); | ||
2299 | |||
2300 | dev->state |= DEV_MISCONFIGURED; | ||
2301 | em28xx_uninit_isoc(dev); | ||
2302 | dev->state |= DEV_DISCONNECTED; | ||
2303 | wake_up_interruptible(&dev->wait_frame); | ||
2304 | wake_up_interruptible(&dev->wait_stream); | ||
2305 | } else { | ||
2306 | dev->state |= DEV_DISCONNECTED; | ||
2307 | em28xx_release_resources(dev); | ||
2308 | } | ||
2309 | mutex_unlock(&dev->lock); | ||
2310 | |||
2311 | mutex_lock(&em28xx_extension_devlist_lock); | ||
2312 | if (!list_empty(&em28xx_extension_devlist)) { | ||
2313 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { | ||
2314 | ops->fini(dev); | ||
2315 | } | ||
2316 | } | ||
2317 | mutex_unlock(&em28xx_extension_devlist_lock); | ||
2318 | |||
2319 | if (!dev->users) { | ||
2320 | kfree(dev->alt_max_pkt_size); | ||
2321 | kfree(dev); | ||
2322 | } | ||
2323 | } | ||
2324 | |||
2325 | static struct usb_driver em28xx_usb_driver = { | ||
2326 | .name = "em28xx", | ||
2327 | .probe = em28xx_usb_probe, | ||
2328 | .disconnect = em28xx_usb_disconnect, | ||
2329 | .id_table = em28xx_id_table, | ||
2330 | }; | ||
2331 | |||
2332 | static int __init em28xx_module_init(void) | ||
2333 | { | ||
2334 | int result; | ||
2335 | |||
2336 | printk(KERN_INFO DRIVER_NAME " v4l2 driver version %d.%d.%d loaded\n", | ||
2337 | (EM28XX_VERSION_CODE >> 16) & 0xff, | ||
2338 | (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff); | ||
2339 | #ifdef SNAPSHOT | ||
2340 | printk(KERN_INFO DRIVER_NAME " snapshot date %04d-%02d-%02d\n", | ||
2341 | SNAPSHOT / 10000, (SNAPSHOT / 100) % 100, SNAPSHOT % 100); | ||
2342 | #endif | ||
2343 | |||
2344 | /* register this driver with the USB subsystem */ | ||
2345 | result = usb_register(&em28xx_usb_driver); | ||
2346 | if (result) | ||
2347 | em28xx_err(DRIVER_NAME | ||
2348 | " usb_register failed. Error number %d.\n", result); | ||
2349 | |||
2350 | return result; | ||
2351 | } | ||
2352 | |||
2353 | static void __exit em28xx_module_exit(void) | ||
2354 | { | ||
2355 | /* deregister this driver with the USB subsystem */ | ||
2356 | usb_deregister(&em28xx_usb_driver); | ||
2357 | } | ||
2358 | |||
2359 | module_init(em28xx_module_init); | ||
2360 | module_exit(em28xx_module_exit); | ||