diff options
Diffstat (limited to 'drivers/media/video/gspca/spca505.c')
-rw-r--r-- | drivers/media/video/gspca/spca505.c | 140 |
1 files changed, 32 insertions, 108 deletions
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index ddea6e140aa8..3c2be80cbd65 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c | |||
@@ -23,9 +23,6 @@ | |||
23 | 23 | ||
24 | #include "gspca.h" | 24 | #include "gspca.h" |
25 | 25 | ||
26 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
27 | static const char version[] = "2.1.7"; | ||
28 | |||
29 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | 26 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); |
30 | MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver"); | 27 | MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver"); |
31 | MODULE_LICENSE("GPL"); | 28 | MODULE_LICENSE("GPL"); |
@@ -34,10 +31,6 @@ MODULE_LICENSE("GPL"); | |||
34 | struct sd { | 31 | struct sd { |
35 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 32 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
36 | 33 | ||
37 | int buflen; | ||
38 | unsigned char tmpbuf[640 * 480 * 3 / 2]; /* YYUV per line */ | ||
39 | unsigned char tmpbuf2[640 * 480 * 2]; /* YUYV */ | ||
40 | |||
41 | unsigned char brightness; | 34 | unsigned char brightness; |
42 | 35 | ||
43 | char subtype; | 36 | char subtype; |
@@ -67,29 +60,29 @@ static struct ctrl sd_ctrls[] = { | |||
67 | }; | 60 | }; |
68 | 61 | ||
69 | static struct v4l2_pix_format vga_mode[] = { | 62 | static struct v4l2_pix_format vga_mode[] = { |
70 | {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 63 | {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
71 | .bytesperline = 160 * 2, | 64 | .bytesperline = 160 * 3, |
72 | .sizeimage = 160 * 120 * 2, | 65 | .sizeimage = 160 * 120 * 3 / 2, |
73 | .colorspace = V4L2_COLORSPACE_SRGB, | 66 | .colorspace = V4L2_COLORSPACE_SRGB, |
74 | .priv = 5}, | 67 | .priv = 5}, |
75 | {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 68 | {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
76 | .bytesperline = 176 * 2, | 69 | .bytesperline = 176 * 3, |
77 | .sizeimage = 176 * 144 * 2, | 70 | .sizeimage = 176 * 144 * 3 / 2, |
78 | .colorspace = V4L2_COLORSPACE_SRGB, | 71 | .colorspace = V4L2_COLORSPACE_SRGB, |
79 | .priv = 4}, | 72 | .priv = 4}, |
80 | {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 73 | {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
81 | .bytesperline = 320 * 2, | 74 | .bytesperline = 320 * 3, |
82 | .sizeimage = 320 * 240 * 2, | 75 | .sizeimage = 320 * 240 * 3 / 2, |
83 | .colorspace = V4L2_COLORSPACE_SRGB, | 76 | .colorspace = V4L2_COLORSPACE_SRGB, |
84 | .priv = 2}, | 77 | .priv = 2}, |
85 | {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 78 | {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
86 | .bytesperline = 352 * 2, | 79 | .bytesperline = 352 * 3, |
87 | .sizeimage = 352 * 288 * 2, | 80 | .sizeimage = 352 * 288 * 3 / 2, |
88 | .colorspace = V4L2_COLORSPACE_SRGB, | 81 | .colorspace = V4L2_COLORSPACE_SRGB, |
89 | .priv = 1}, | 82 | .priv = 1}, |
90 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 83 | {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
91 | .bytesperline = 640 * 2, | 84 | .bytesperline = 640 * 3, |
92 | .sizeimage = 640 * 480 * 2, | 85 | .sizeimage = 640 * 480 * 3 / 2, |
93 | .colorspace = V4L2_COLORSPACE_SRGB, | 86 | .colorspace = V4L2_COLORSPACE_SRGB, |
94 | .priv = 0}, | 87 | .priv = 0}, |
95 | }; | 88 | }; |
@@ -641,33 +634,11 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
641 | { | 634 | { |
642 | struct sd *sd = (struct sd *) gspca_dev; | 635 | struct sd *sd = (struct sd *) gspca_dev; |
643 | struct cam *cam; | 636 | struct cam *cam; |
644 | __u16 vendor; | ||
645 | __u16 product; | ||
646 | |||
647 | vendor = id->idVendor; | ||
648 | product = id->idProduct; | ||
649 | switch (vendor) { | ||
650 | case 0x041e: /* Creative cameras */ | ||
651 | /* switch (product) { */ | ||
652 | /* case 0x401d: * here505b */ | ||
653 | sd->subtype = Nxultra; | ||
654 | /* break; */ | ||
655 | /* } */ | ||
656 | break; | ||
657 | case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ | ||
658 | /* switch (product) { */ | ||
659 | /* case 0x0430: */ | ||
660 | /* fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ | ||
661 | sd->subtype = IntelPCCameraPro; | ||
662 | /* break; */ | ||
663 | /* } */ | ||
664 | break; | ||
665 | } | ||
666 | 637 | ||
667 | cam = &gspca_dev->cam; | 638 | cam = &gspca_dev->cam; |
668 | cam->dev_name = (char *) id->driver_info; | ||
669 | cam->epaddr = 0x01; | 639 | cam->epaddr = 0x01; |
670 | cam->cam_mode = vga_mode; | 640 | cam->cam_mode = vga_mode; |
641 | sd->subtype = id->driver_info; | ||
671 | if (sd->subtype != IntelPCCameraPro) | 642 | if (sd->subtype != IntelPCCameraPro) |
672 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | 643 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; |
673 | else /* no 640x480 for IntelPCCameraPro */ | 644 | else /* no 640x480 for IntelPCCameraPro */ |
@@ -785,77 +756,30 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
785 | reg_write(gspca_dev->dev, 0x05, 0x11, 0xf); | 756 | reg_write(gspca_dev->dev, 0x05, 0x11, 0xf); |
786 | } | 757 | } |
787 | 758 | ||
788 | /* convert YYUV per line to YUYV (YUV 4:2:2) */ | ||
789 | static void yyuv_decode(unsigned char *out, | ||
790 | unsigned char *in, | ||
791 | int width, | ||
792 | int height) | ||
793 | { | ||
794 | unsigned char *Ui, *Vi, *yi, *yi1; | ||
795 | unsigned char *out1; | ||
796 | int i, j; | ||
797 | |||
798 | yi = in; | ||
799 | for (i = height / 2; --i >= 0; ) { | ||
800 | out1 = out + width * 2; /* next line */ | ||
801 | yi1 = yi + width; | ||
802 | Ui = yi1 + width; | ||
803 | Vi = Ui + width / 2; | ||
804 | for (j = width / 2; --j >= 0; ) { | ||
805 | *out++ = 128 + *yi++; | ||
806 | *out++ = 128 + *Ui; | ||
807 | *out++ = 128 + *yi++; | ||
808 | *out++ = 128 + *Vi; | ||
809 | |||
810 | *out1++ = 128 + *yi1++; | ||
811 | *out1++ = 128 + *Ui++; | ||
812 | *out1++ = 128 + *yi1++; | ||
813 | *out1++ = 128 + *Vi++; | ||
814 | } | ||
815 | yi += width * 2; | ||
816 | out = out1; | ||
817 | } | ||
818 | } | ||
819 | |||
820 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 759 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
821 | struct gspca_frame *frame, /* target */ | 760 | struct gspca_frame *frame, /* target */ |
822 | __u8 *data, /* isoc packet */ | 761 | __u8 *data, /* isoc packet */ |
823 | int len) /* iso packet length */ | 762 | int len) /* iso packet length */ |
824 | { | 763 | { |
825 | struct sd *sd = (struct sd *) gspca_dev; | ||
826 | |||
827 | switch (data[0]) { | 764 | switch (data[0]) { |
828 | case 0: /* start of frame */ | 765 | case 0: /* start of frame */ |
829 | if (gspca_dev->last_packet_type == FIRST_PACKET) { | 766 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, |
830 | yyuv_decode(sd->tmpbuf2, sd->tmpbuf, | 767 | data, 0); |
831 | gspca_dev->width, | ||
832 | gspca_dev->height); | ||
833 | frame = gspca_frame_add(gspca_dev, | ||
834 | LAST_PACKET, | ||
835 | frame, | ||
836 | sd->tmpbuf2, | ||
837 | gspca_dev->width | ||
838 | * gspca_dev->height | ||
839 | * 2); | ||
840 | } | ||
841 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
842 | data, 0); | ||
843 | data += SPCA50X_OFFSET_DATA; | 768 | data += SPCA50X_OFFSET_DATA; |
844 | len -= SPCA50X_OFFSET_DATA; | 769 | len -= SPCA50X_OFFSET_DATA; |
845 | if (len > 0) | 770 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, |
846 | memcpy(sd->tmpbuf, data, len); | 771 | data, len); |
847 | else | 772 | break; |
848 | len = 0; | ||
849 | sd->buflen = len; | ||
850 | return; | ||
851 | case 0xff: /* drop */ | 773 | case 0xff: /* drop */ |
852 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | 774 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ |
853 | return; | 775 | break; |
776 | default: | ||
777 | data += 1; | ||
778 | len -= 1; | ||
779 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
780 | data, len); | ||
781 | break; | ||
854 | } | 782 | } |
855 | data += 1; | ||
856 | len -= 1; | ||
857 | memcpy(&sd->tmpbuf[sd->buflen], data, len); | ||
858 | sd->buflen += len; | ||
859 | } | 783 | } |
860 | 784 | ||
861 | static void setbrightness(struct gspca_dev *gspca_dev) | 785 | static void setbrightness(struct gspca_dev *gspca_dev) |
@@ -910,10 +834,10 @@ static const struct sd_desc sd_desc = { | |||
910 | }; | 834 | }; |
911 | 835 | ||
912 | /* -- module initialisation -- */ | 836 | /* -- module initialisation -- */ |
913 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
914 | static const __devinitdata struct usb_device_id device_table[] = { | 837 | static const __devinitdata struct usb_device_id device_table[] = { |
915 | {USB_DEVICE(0x041e, 0x401d), DVNM("Creative Webcam NX ULTRA")}, | 838 | {USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra}, |
916 | {USB_DEVICE(0x0733, 0x0430), DVNM("Intel PC Camera Pro")}, | 839 | {USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro}, |
840 | /*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ | ||
917 | {} | 841 | {} |
918 | }; | 842 | }; |
919 | MODULE_DEVICE_TABLE(usb, device_table); | 843 | MODULE_DEVICE_TABLE(usb, device_table); |
@@ -938,7 +862,7 @@ static int __init sd_mod_init(void) | |||
938 | { | 862 | { |
939 | if (usb_register(&sd_driver) < 0) | 863 | if (usb_register(&sd_driver) < 0) |
940 | return -1; | 864 | return -1; |
941 | PDEBUG(D_PROBE, "v%s registered", version); | 865 | PDEBUG(D_PROBE, "registered"); |
942 | return 0; | 866 | return 0; |
943 | } | 867 | } |
944 | static void __exit sd_mod_exit(void) | 868 | static void __exit sd_mod_exit(void) |