diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-06 21:32:12 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-06 21:32:12 -0500 |
commit | 9e9bc9736756f25d6c47b4eba0ebf25b20a6f153 (patch) | |
tree | 647240f479c5f23910c3e6194d1c35b6ba54d75e /drivers/media/video | |
parent | 3c0cb7c31c206aaedb967e44b98442bbeb17a6c4 (diff) | |
parent | e3c92215198cb6aa00ad38db2780faa6b72e0a3f (diff) |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (255 commits)
[media] radio-aimslab.c: Fix gcc 4.5+ bug
[media] cx25821: Fix compilation breakage due to BKL dependency
[media] v4l2-compat-ioctl32: fix compile warning
[media] zoran: fix compiler warning
[media] tda18218: fix compile warning
[media] ngene: fix compile warning
[media] DVB: IR support for TechnoTrend CT-3650
[media] cx23885, cimax2.c: Fix case of two CAM insertion irq
[media] ir-nec-decoder: fix repeat key issue
[media] staging: se401 depends on USB
[media] staging: usbvideo/vicam depends on USB
[media] soc_camera: Add the ability to bind regulators to soc_camedra devices
[media] V4L2: Add a v4l2-subdev (soc-camera) driver for OmniVision OV2640 sensor
[media] v4l: soc-camera: switch to .unlocked_ioctl
[media] v4l: ov772x: simplify pointer dereference
[media] ov9640: fix OmniVision OV9640 sensor driver's priv data retrieving
[media] ov9640: use macro to request OmniVision OV9640 sensor private data
[media] ivtv-i2c: Fix two warnings
[media] staging/lirc: Update lirc TODO files
[media] cx88: Remove the obsolete i2c_adapter.id field
...
Diffstat (limited to 'drivers/media/video')
190 files changed, 8444 insertions, 19757 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 6830d2848bd7..eb875af05e79 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -7,11 +7,6 @@ config VIDEO_V4L2 | |||
7 | depends on VIDEO_DEV && VIDEO_V4L2_COMMON | 7 | depends on VIDEO_DEV && VIDEO_V4L2_COMMON |
8 | default VIDEO_DEV && VIDEO_V4L2_COMMON | 8 | default VIDEO_DEV && VIDEO_V4L2_COMMON |
9 | 9 | ||
10 | config VIDEO_V4L1 | ||
11 | tristate | ||
12 | depends on VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1 | ||
13 | default VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1 | ||
14 | |||
15 | config VIDEOBUF_GEN | 10 | config VIDEOBUF_GEN |
16 | tristate | 11 | tristate |
17 | 12 | ||
@@ -96,7 +91,7 @@ config VIDEO_HELPER_CHIPS_AUTO | |||
96 | 91 | ||
97 | config VIDEO_IR_I2C | 92 | config VIDEO_IR_I2C |
98 | tristate "I2C module for IR" if !VIDEO_HELPER_CHIPS_AUTO | 93 | tristate "I2C module for IR" if !VIDEO_HELPER_CHIPS_AUTO |
99 | depends on I2C && VIDEO_IR | 94 | depends on I2C && RC_CORE |
100 | default y | 95 | default y |
101 | ---help--- | 96 | ---help--- |
102 | Most boards have an IR chip directly connected via GPIO. However, | 97 | Most boards have an IR chip directly connected via GPIO. However, |
@@ -666,6 +661,16 @@ config VIDEO_HEXIUM_GEMINI | |||
666 | To compile this driver as a module, choose M here: the | 661 | To compile this driver as a module, choose M here: the |
667 | module will be called hexium_gemini. | 662 | module will be called hexium_gemini. |
668 | 663 | ||
664 | config VIDEO_TIMBERDALE | ||
665 | tristate "Support for timberdale Video In/LogiWIN" | ||
666 | depends on VIDEO_V4L2 && I2C | ||
667 | select DMA_ENGINE | ||
668 | select TIMB_DMA | ||
669 | select VIDEO_ADV7180 | ||
670 | select VIDEOBUF_DMA_CONTIG | ||
671 | ---help--- | ||
672 | Add support for the Video In peripherial of the timberdale FPGA. | ||
673 | |||
669 | source "drivers/media/video/cx88/Kconfig" | 674 | source "drivers/media/video/cx88/Kconfig" |
670 | 675 | ||
671 | source "drivers/media/video/cx23885/Kconfig" | 676 | source "drivers/media/video/cx23885/Kconfig" |
@@ -789,6 +794,12 @@ config SOC_CAMERA_PLATFORM | |||
789 | help | 794 | help |
790 | This is a generic SoC camera platform driver, useful for testing | 795 | This is a generic SoC camera platform driver, useful for testing |
791 | 796 | ||
797 | config SOC_CAMERA_OV2640 | ||
798 | tristate "ov2640 camera support" | ||
799 | depends on SOC_CAMERA && I2C | ||
800 | help | ||
801 | This is a ov2640 camera driver | ||
802 | |||
792 | config SOC_CAMERA_OV6650 | 803 | config SOC_CAMERA_OV6650 |
793 | tristate "ov6650 sensor support" | 804 | tristate "ov6650 sensor support" |
794 | depends on SOC_CAMERA && I2C | 805 | depends on SOC_CAMERA && I2C |
@@ -905,21 +916,8 @@ source "drivers/media/video/cx231xx/Kconfig" | |||
905 | 916 | ||
906 | source "drivers/media/video/usbvision/Kconfig" | 917 | source "drivers/media/video/usbvision/Kconfig" |
907 | 918 | ||
908 | source "drivers/media/video/usbvideo/Kconfig" | ||
909 | |||
910 | source "drivers/media/video/et61x251/Kconfig" | 919 | source "drivers/media/video/et61x251/Kconfig" |
911 | 920 | ||
912 | config USB_SE401 | ||
913 | tristate "USB SE401 Camera support" | ||
914 | depends on VIDEO_V4L1 | ||
915 | ---help--- | ||
916 | Say Y here if you want to connect this type of camera to your | ||
917 | computer's USB port. See <file:Documentation/video4linux/se401.txt> | ||
918 | for more information and for a list of supported cameras. | ||
919 | |||
920 | To compile this driver as a module, choose M here: the | ||
921 | module will be called se401. | ||
922 | |||
923 | source "drivers/media/video/sn9c102/Kconfig" | 921 | source "drivers/media/video/sn9c102/Kconfig" |
924 | 922 | ||
925 | source "drivers/media/video/pwc/Kconfig" | 923 | source "drivers/media/video/pwc/Kconfig" |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index af79d476a4c8..81e38cb0b846 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -22,10 +22,6 @@ endif | |||
22 | 22 | ||
23 | obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o | 23 | obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o |
24 | 24 | ||
25 | ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y) | ||
26 | obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o | ||
27 | endif | ||
28 | |||
29 | # All i2c modules must come first: | 25 | # All i2c modules must come first: |
30 | 26 | ||
31 | obj-$(CONFIG_VIDEO_TUNER) += tuner.o | 27 | obj-$(CONFIG_VIDEO_TUNER) += tuner.o |
@@ -79,6 +75,7 @@ obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o | |||
79 | obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o | 75 | obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o |
80 | obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o | 76 | obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o |
81 | obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o | 77 | obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o |
78 | obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o | ||
82 | obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o | 79 | obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o |
83 | obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o | 80 | obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o |
84 | obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o | 81 | obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o |
@@ -106,6 +103,7 @@ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ | |||
106 | obj-$(CONFIG_VIDEO_MXB) += mxb.o | 103 | obj-$(CONFIG_VIDEO_MXB) += mxb.o |
107 | obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o | 104 | obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o |
108 | obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o | 105 | obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o |
106 | obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o | ||
109 | 107 | ||
110 | obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o | 108 | obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o |
111 | obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o | 109 | obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o |
@@ -124,8 +122,6 @@ obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o | |||
124 | 122 | ||
125 | obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o | 123 | obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o |
126 | 124 | ||
127 | obj-$(CONFIG_USB_DABUSB) += dabusb.o | ||
128 | obj-$(CONFIG_USB_SE401) += se401.o | ||
129 | obj-$(CONFIG_USB_ZR364XX) += zr364xx.o | 125 | obj-$(CONFIG_USB_ZR364XX) += zr364xx.o |
130 | obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o | 126 | obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o |
131 | 127 | ||
@@ -136,10 +132,6 @@ obj-$(CONFIG_USB_GSPCA) += gspca/ | |||
136 | 132 | ||
137 | obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/ | 133 | obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/ |
138 | 134 | ||
139 | obj-$(CONFIG_USB_IBMCAM) += usbvideo/ | ||
140 | obj-$(CONFIG_USB_KONICAWC) += usbvideo/ | ||
141 | obj-$(CONFIG_USB_VICAM) += usbvideo/ | ||
142 | obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/ | ||
143 | obj-$(CONFIG_USB_S2255) += s2255drv.o | 135 | obj-$(CONFIG_USB_S2255) += s2255drv.o |
144 | 136 | ||
145 | obj-$(CONFIG_VIDEO_IVTV) += ivtv/ | 137 | obj-$(CONFIG_VIDEO_IVTV) += ivtv/ |
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index 162fd5f9d448..e41e4ad5cc40 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c | |||
@@ -122,6 +122,7 @@ static void au0828_irq_callback(struct urb *urb) | |||
122 | { | 122 | { |
123 | struct au0828_dmaqueue *dma_q = urb->context; | 123 | struct au0828_dmaqueue *dma_q = urb->context; |
124 | struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq); | 124 | struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq); |
125 | unsigned long flags = 0; | ||
125 | int rc, i; | 126 | int rc, i; |
126 | 127 | ||
127 | switch (urb->status) { | 128 | switch (urb->status) { |
@@ -139,9 +140,9 @@ static void au0828_irq_callback(struct urb *urb) | |||
139 | } | 140 | } |
140 | 141 | ||
141 | /* Copy data from URB */ | 142 | /* Copy data from URB */ |
142 | spin_lock(&dev->slock); | 143 | spin_lock_irqsave(&dev->slock, flags); |
143 | rc = dev->isoc_ctl.isoc_copy(dev, urb); | 144 | rc = dev->isoc_ctl.isoc_copy(dev, urb); |
144 | spin_unlock(&dev->slock); | 145 | spin_unlock_irqrestore(&dev->slock, flags); |
145 | 146 | ||
146 | /* Reset urb buffers */ | 147 | /* Reset urb buffers */ |
147 | for (i = 0; i < urb->number_of_packets; i++) { | 148 | for (i = 0; i < urb->number_of_packets; i++) { |
@@ -576,7 +577,7 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb) | |||
576 | p += 4; | 577 | p += 4; |
577 | au0828_isocdbg("Video frame %s\n", | 578 | au0828_isocdbg("Video frame %s\n", |
578 | (fbyte & 0x40) ? "odd" : "even"); | 579 | (fbyte & 0x40) ? "odd" : "even"); |
579 | if (!(fbyte & 0x40)) { | 580 | if (fbyte & 0x40) { |
580 | /* VBI */ | 581 | /* VBI */ |
581 | if (vbi_buf != NULL) | 582 | if (vbi_buf != NULL) |
582 | vbi_buffer_filled(dev, | 583 | vbi_buffer_filled(dev, |
@@ -597,6 +598,15 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb) | |||
597 | outp = NULL; | 598 | outp = NULL; |
598 | else | 599 | else |
599 | outp = videobuf_to_vmalloc(&buf->vb); | 600 | outp = videobuf_to_vmalloc(&buf->vb); |
601 | |||
602 | /* As long as isoc traffic is arriving, keep | ||
603 | resetting the timer */ | ||
604 | if (dev->vid_timeout_running) | ||
605 | mod_timer(&dev->vid_timeout, | ||
606 | jiffies + (HZ / 10)); | ||
607 | if (dev->vbi_timeout_running) | ||
608 | mod_timer(&dev->vbi_timeout, | ||
609 | jiffies + (HZ / 10)); | ||
600 | } | 610 | } |
601 | 611 | ||
602 | if (buf != NULL) { | 612 | if (buf != NULL) { |
@@ -907,6 +917,57 @@ static int get_ressource(struct au0828_fh *fh) | |||
907 | } | 917 | } |
908 | } | 918 | } |
909 | 919 | ||
920 | /* This function ensures that video frames continue to be delivered even if | ||
921 | the ITU-656 input isn't receiving any data (thereby preventing applications | ||
922 | such as tvtime from hanging) */ | ||
923 | void au0828_vid_buffer_timeout(unsigned long data) | ||
924 | { | ||
925 | struct au0828_dev *dev = (struct au0828_dev *) data; | ||
926 | struct au0828_dmaqueue *dma_q = &dev->vidq; | ||
927 | struct au0828_buffer *buf; | ||
928 | unsigned char *vid_data; | ||
929 | unsigned long flags = 0; | ||
930 | |||
931 | spin_lock_irqsave(&dev->slock, flags); | ||
932 | |||
933 | buf = dev->isoc_ctl.buf; | ||
934 | if (buf != NULL) { | ||
935 | vid_data = videobuf_to_vmalloc(&buf->vb); | ||
936 | memset(vid_data, 0x00, buf->vb.size); /* Blank green frame */ | ||
937 | buffer_filled(dev, dma_q, buf); | ||
938 | } | ||
939 | get_next_buf(dma_q, &buf); | ||
940 | |||
941 | if (dev->vid_timeout_running == 1) | ||
942 | mod_timer(&dev->vid_timeout, jiffies + (HZ / 10)); | ||
943 | |||
944 | spin_unlock_irqrestore(&dev->slock, flags); | ||
945 | } | ||
946 | |||
947 | void au0828_vbi_buffer_timeout(unsigned long data) | ||
948 | { | ||
949 | struct au0828_dev *dev = (struct au0828_dev *) data; | ||
950 | struct au0828_dmaqueue *dma_q = &dev->vbiq; | ||
951 | struct au0828_buffer *buf; | ||
952 | unsigned char *vbi_data; | ||
953 | unsigned long flags = 0; | ||
954 | |||
955 | spin_lock_irqsave(&dev->slock, flags); | ||
956 | |||
957 | buf = dev->isoc_ctl.vbi_buf; | ||
958 | if (buf != NULL) { | ||
959 | vbi_data = videobuf_to_vmalloc(&buf->vb); | ||
960 | memset(vbi_data, 0x00, buf->vb.size); | ||
961 | vbi_buffer_filled(dev, dma_q, buf); | ||
962 | } | ||
963 | vbi_get_next_buf(dma_q, &buf); | ||
964 | |||
965 | if (dev->vbi_timeout_running == 1) | ||
966 | mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10)); | ||
967 | spin_unlock_irqrestore(&dev->slock, flags); | ||
968 | } | ||
969 | |||
970 | |||
910 | static int au0828_v4l2_open(struct file *filp) | 971 | static int au0828_v4l2_open(struct file *filp) |
911 | { | 972 | { |
912 | int ret = 0; | 973 | int ret = 0; |
@@ -976,7 +1037,6 @@ static int au0828_v4l2_open(struct file *filp) | |||
976 | V4L2_FIELD_SEQ_TB, | 1037 | V4L2_FIELD_SEQ_TB, |
977 | sizeof(struct au0828_buffer), fh, NULL); | 1038 | sizeof(struct au0828_buffer), fh, NULL); |
978 | 1039 | ||
979 | |||
980 | return ret; | 1040 | return ret; |
981 | } | 1041 | } |
982 | 1042 | ||
@@ -987,11 +1047,19 @@ static int au0828_v4l2_close(struct file *filp) | |||
987 | struct au0828_dev *dev = fh->dev; | 1047 | struct au0828_dev *dev = fh->dev; |
988 | 1048 | ||
989 | if (res_check(fh, AU0828_RESOURCE_VIDEO)) { | 1049 | if (res_check(fh, AU0828_RESOURCE_VIDEO)) { |
1050 | /* Cancel timeout thread in case they didn't call streamoff */ | ||
1051 | dev->vid_timeout_running = 0; | ||
1052 | del_timer_sync(&dev->vid_timeout); | ||
1053 | |||
990 | videobuf_stop(&fh->vb_vidq); | 1054 | videobuf_stop(&fh->vb_vidq); |
991 | res_free(fh, AU0828_RESOURCE_VIDEO); | 1055 | res_free(fh, AU0828_RESOURCE_VIDEO); |
992 | } | 1056 | } |
993 | 1057 | ||
994 | if (res_check(fh, AU0828_RESOURCE_VBI)) { | 1058 | if (res_check(fh, AU0828_RESOURCE_VBI)) { |
1059 | /* Cancel timeout thread in case they didn't call streamoff */ | ||
1060 | dev->vbi_timeout_running = 0; | ||
1061 | del_timer_sync(&dev->vbi_timeout); | ||
1062 | |||
995 | videobuf_stop(&fh->vb_vbiq); | 1063 | videobuf_stop(&fh->vb_vbiq); |
996 | res_free(fh, AU0828_RESOURCE_VBI); | 1064 | res_free(fh, AU0828_RESOURCE_VBI); |
997 | } | 1065 | } |
@@ -1048,6 +1116,13 @@ static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf, | |||
1048 | if (!res_get(fh, AU0828_RESOURCE_VBI)) | 1116 | if (!res_get(fh, AU0828_RESOURCE_VBI)) |
1049 | return -EBUSY; | 1117 | return -EBUSY; |
1050 | 1118 | ||
1119 | if (dev->vbi_timeout_running == 0) { | ||
1120 | /* Handle case where caller tries to read without | ||
1121 | calling streamon first */ | ||
1122 | dev->vbi_timeout_running = 1; | ||
1123 | mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10)); | ||
1124 | } | ||
1125 | |||
1051 | return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0, | 1126 | return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0, |
1052 | filp->f_flags & O_NONBLOCK); | 1127 | filp->f_flags & O_NONBLOCK); |
1053 | } | 1128 | } |
@@ -1577,10 +1652,15 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1577 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1); | 1652 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1); |
1578 | } | 1653 | } |
1579 | 1654 | ||
1580 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1655 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
1581 | rc = videobuf_streamon(&fh->vb_vidq); | 1656 | rc = videobuf_streamon(&fh->vb_vidq); |
1582 | else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) | 1657 | dev->vid_timeout_running = 1; |
1658 | mod_timer(&dev->vid_timeout, jiffies + (HZ / 10)); | ||
1659 | } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | ||
1583 | rc = videobuf_streamon(&fh->vb_vbiq); | 1660 | rc = videobuf_streamon(&fh->vb_vbiq); |
1661 | dev->vbi_timeout_running = 1; | ||
1662 | mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10)); | ||
1663 | } | ||
1584 | 1664 | ||
1585 | return rc; | 1665 | return rc; |
1586 | } | 1666 | } |
@@ -1607,6 +1687,9 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1607 | fh, type, fh->resources, dev->resources); | 1687 | fh, type, fh->resources, dev->resources); |
1608 | 1688 | ||
1609 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1689 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
1690 | dev->vid_timeout_running = 0; | ||
1691 | del_timer_sync(&dev->vid_timeout); | ||
1692 | |||
1610 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); | 1693 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); |
1611 | rc = au0828_stream_interrupt(dev); | 1694 | rc = au0828_stream_interrupt(dev); |
1612 | if (rc != 0) | 1695 | if (rc != 0) |
@@ -1621,6 +1704,9 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1621 | videobuf_streamoff(&fh->vb_vidq); | 1704 | videobuf_streamoff(&fh->vb_vidq); |
1622 | res_free(fh, AU0828_RESOURCE_VIDEO); | 1705 | res_free(fh, AU0828_RESOURCE_VIDEO); |
1623 | } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | 1706 | } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { |
1707 | dev->vbi_timeout_running = 0; | ||
1708 | del_timer_sync(&dev->vbi_timeout); | ||
1709 | |||
1624 | videobuf_streamoff(&fh->vb_vbiq); | 1710 | videobuf_streamoff(&fh->vb_vbiq); |
1625 | res_free(fh, AU0828_RESOURCE_VBI); | 1711 | res_free(fh, AU0828_RESOURCE_VBI); |
1626 | } | 1712 | } |
@@ -1723,15 +1809,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) | |||
1723 | return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); | 1809 | return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); |
1724 | } | 1810 | } |
1725 | 1811 | ||
1726 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1727 | static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | ||
1728 | { | ||
1729 | struct au0828_fh *fh = priv; | ||
1730 | |||
1731 | return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); | ||
1732 | } | ||
1733 | #endif | ||
1734 | |||
1735 | static struct v4l2_file_operations au0828_v4l_fops = { | 1812 | static struct v4l2_file_operations au0828_v4l_fops = { |
1736 | .owner = THIS_MODULE, | 1813 | .owner = THIS_MODULE, |
1737 | .open = au0828_v4l2_open, | 1814 | .open = au0828_v4l2_open, |
@@ -1775,9 +1852,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1775 | .vidioc_s_register = vidioc_s_register, | 1852 | .vidioc_s_register = vidioc_s_register, |
1776 | #endif | 1853 | #endif |
1777 | .vidioc_g_chip_ident = vidioc_g_chip_ident, | 1854 | .vidioc_g_chip_ident = vidioc_g_chip_ident, |
1778 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1779 | .vidiocgmbuf = vidiocgmbuf, | ||
1780 | #endif | ||
1781 | }; | 1855 | }; |
1782 | 1856 | ||
1783 | static const struct video_device au0828_video_template = { | 1857 | static const struct video_device au0828_video_template = { |
@@ -1840,6 +1914,14 @@ int au0828_analog_register(struct au0828_dev *dev, | |||
1840 | INIT_LIST_HEAD(&dev->vbiq.active); | 1914 | INIT_LIST_HEAD(&dev->vbiq.active); |
1841 | INIT_LIST_HEAD(&dev->vbiq.queued); | 1915 | INIT_LIST_HEAD(&dev->vbiq.queued); |
1842 | 1916 | ||
1917 | dev->vid_timeout.function = au0828_vid_buffer_timeout; | ||
1918 | dev->vid_timeout.data = (unsigned long) dev; | ||
1919 | init_timer(&dev->vid_timeout); | ||
1920 | |||
1921 | dev->vbi_timeout.function = au0828_vbi_buffer_timeout; | ||
1922 | dev->vbi_timeout.data = (unsigned long) dev; | ||
1923 | init_timer(&dev->vbi_timeout); | ||
1924 | |||
1843 | dev->width = NTSC_STD_W; | 1925 | dev->width = NTSC_STD_W; |
1844 | dev->height = NTSC_STD_H; | 1926 | dev->height = NTSC_STD_H; |
1845 | dev->field_size = dev->width * dev->height; | 1927 | dev->field_size = dev->width * dev->height; |
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h index 9905bc4f5f59..9cde35321824 100644 --- a/drivers/media/video/au0828/au0828.h +++ b/drivers/media/video/au0828/au0828.h | |||
@@ -53,7 +53,7 @@ | |||
53 | 53 | ||
54 | /* Defination for AU0828 USB transfer */ | 54 | /* Defination for AU0828 USB transfer */ |
55 | #define AU0828_MAX_ISO_BUFS 12 /* maybe resize this value in the future */ | 55 | #define AU0828_MAX_ISO_BUFS 12 /* maybe resize this value in the future */ |
56 | #define AU0828_ISO_PACKETS_PER_URB 10 | 56 | #define AU0828_ISO_PACKETS_PER_URB 128 |
57 | 57 | ||
58 | #define AU0828_MIN_BUF 4 | 58 | #define AU0828_MIN_BUF 4 |
59 | #define AU0828_DEF_BUF 8 | 59 | #define AU0828_DEF_BUF 8 |
@@ -204,6 +204,10 @@ struct au0828_dev { | |||
204 | unsigned int resources; /* resources in use */ | 204 | unsigned int resources; /* resources in use */ |
205 | struct video_device *vdev; | 205 | struct video_device *vdev; |
206 | struct video_device *vbi_dev; | 206 | struct video_device *vbi_dev; |
207 | struct timer_list vid_timeout; | ||
208 | int vid_timeout_running; | ||
209 | struct timer_list vbi_timeout; | ||
210 | int vbi_timeout_running; | ||
207 | int width; | 211 | int width; |
208 | int height; | 212 | int height; |
209 | int vbi_width; | 213 | int vbi_width; |
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig index 1a4a89fdf767..7da5c2e1fc12 100644 --- a/drivers/media/video/bt8xx/Kconfig +++ b/drivers/media/video/bt8xx/Kconfig | |||
@@ -1,10 +1,10 @@ | |||
1 | config VIDEO_BT848 | 1 | config VIDEO_BT848 |
2 | tristate "BT848 Video For Linux" | 2 | tristate "BT848 Video For Linux" |
3 | depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT | 3 | depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 |
4 | select I2C_ALGOBIT | 4 | select I2C_ALGOBIT |
5 | select VIDEO_BTCX | 5 | select VIDEO_BTCX |
6 | select VIDEOBUF_DMA_SG | 6 | select VIDEOBUF_DMA_SG |
7 | depends on VIDEO_IR | 7 | depends on RC_CORE |
8 | select VIDEO_TUNER | 8 | select VIDEO_TUNER |
9 | select VIDEO_TVEEPROM | 9 | select VIDEO_TVEEPROM |
10 | select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO | 10 | select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 0902ec041c7a..849cd170b821 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -55,7 +55,7 @@ | |||
55 | #include <asm/io.h> | 55 | #include <asm/io.h> |
56 | #include <asm/byteorder.h> | 56 | #include <asm/byteorder.h> |
57 | 57 | ||
58 | #include <media/rds.h> | 58 | #include <media/saa6588.h> |
59 | 59 | ||
60 | 60 | ||
61 | unsigned int bttv_num; /* number of Bt848s in use */ | 61 | unsigned int bttv_num; /* number of Bt848s in use */ |
@@ -2597,31 +2597,6 @@ static int bttv_s_fmt_vid_overlay(struct file *file, void *priv, | |||
2597 | return setup_window_lock(fh, btv, &f->fmt.win, 1); | 2597 | return setup_window_lock(fh, btv, &f->fmt.win, 1); |
2598 | } | 2598 | } |
2599 | 2599 | ||
2600 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
2601 | static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | ||
2602 | { | ||
2603 | int retval; | ||
2604 | unsigned int i; | ||
2605 | struct bttv_fh *fh = priv; | ||
2606 | |||
2607 | retval = __videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize, | ||
2608 | V4L2_MEMORY_MMAP); | ||
2609 | if (retval < 0) { | ||
2610 | return retval; | ||
2611 | } | ||
2612 | |||
2613 | gbuffers = retval; | ||
2614 | memset(mbuf, 0, sizeof(*mbuf)); | ||
2615 | mbuf->frames = gbuffers; | ||
2616 | mbuf->size = gbuffers * gbufsize; | ||
2617 | |||
2618 | for (i = 0; i < gbuffers; i++) | ||
2619 | mbuf->offsets[i] = i * gbufsize; | ||
2620 | |||
2621 | return 0; | ||
2622 | } | ||
2623 | #endif | ||
2624 | |||
2625 | static int bttv_querycap(struct file *file, void *priv, | 2600 | static int bttv_querycap(struct file *file, void *priv, |
2626 | struct v4l2_capability *cap) | 2601 | struct v4l2_capability *cap) |
2627 | { | 2602 | { |
@@ -3354,9 +3329,6 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = { | |||
3354 | .vidioc_streamoff = bttv_streamoff, | 3329 | .vidioc_streamoff = bttv_streamoff, |
3355 | .vidioc_g_tuner = bttv_g_tuner, | 3330 | .vidioc_g_tuner = bttv_g_tuner, |
3356 | .vidioc_s_tuner = bttv_s_tuner, | 3331 | .vidioc_s_tuner = bttv_s_tuner, |
3357 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
3358 | .vidiocgmbuf = vidiocgmbuf, | ||
3359 | #endif | ||
3360 | .vidioc_g_crop = bttv_g_crop, | 3332 | .vidioc_g_crop = bttv_g_crop, |
3361 | .vidioc_s_crop = bttv_s_crop, | 3333 | .vidioc_s_crop = bttv_s_crop, |
3362 | .vidioc_g_fbuf = bttv_g_fbuf, | 3334 | .vidioc_g_fbuf = bttv_g_fbuf, |
@@ -3416,7 +3388,7 @@ static int radio_release(struct file *file) | |||
3416 | { | 3388 | { |
3417 | struct bttv_fh *fh = file->private_data; | 3389 | struct bttv_fh *fh = file->private_data; |
3418 | struct bttv *btv = fh->btv; | 3390 | struct bttv *btv = fh->btv; |
3419 | struct rds_command cmd; | 3391 | struct saa6588_command cmd; |
3420 | 3392 | ||
3421 | v4l2_prio_close(&btv->prio, fh->prio); | 3393 | v4l2_prio_close(&btv->prio, fh->prio); |
3422 | file->private_data = NULL; | 3394 | file->private_data = NULL; |
@@ -3424,7 +3396,7 @@ static int radio_release(struct file *file) | |||
3424 | 3396 | ||
3425 | btv->radio_user--; | 3397 | btv->radio_user--; |
3426 | 3398 | ||
3427 | bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd); | 3399 | bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd); |
3428 | 3400 | ||
3429 | return 0; | 3401 | return 0; |
3430 | } | 3402 | } |
@@ -3551,13 +3523,13 @@ static ssize_t radio_read(struct file *file, char __user *data, | |||
3551 | { | 3523 | { |
3552 | struct bttv_fh *fh = file->private_data; | 3524 | struct bttv_fh *fh = file->private_data; |
3553 | struct bttv *btv = fh->btv; | 3525 | struct bttv *btv = fh->btv; |
3554 | struct rds_command cmd; | 3526 | struct saa6588_command cmd; |
3555 | cmd.block_count = count/3; | 3527 | cmd.block_count = count/3; |
3556 | cmd.buffer = data; | 3528 | cmd.buffer = data; |
3557 | cmd.instance = file; | 3529 | cmd.instance = file; |
3558 | cmd.result = -ENODEV; | 3530 | cmd.result = -ENODEV; |
3559 | 3531 | ||
3560 | bttv_call_all(btv, core, ioctl, RDS_CMD_READ, &cmd); | 3532 | bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd); |
3561 | 3533 | ||
3562 | return cmd.result; | 3534 | return cmd.result; |
3563 | } | 3535 | } |
@@ -3566,11 +3538,11 @@ static unsigned int radio_poll(struct file *file, poll_table *wait) | |||
3566 | { | 3538 | { |
3567 | struct bttv_fh *fh = file->private_data; | 3539 | struct bttv_fh *fh = file->private_data; |
3568 | struct bttv *btv = fh->btv; | 3540 | struct bttv *btv = fh->btv; |
3569 | struct rds_command cmd; | 3541 | struct saa6588_command cmd; |
3570 | cmd.instance = file; | 3542 | cmd.instance = file; |
3571 | cmd.event_list = wait; | 3543 | cmd.event_list = wait; |
3572 | cmd.result = -ENODEV; | 3544 | cmd.result = -ENODEV; |
3573 | bttv_call_all(btv, core, ioctl, RDS_CMD_POLL, &cmd); | 3545 | bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd); |
3574 | 3546 | ||
3575 | return cmd.result; | 3547 | return cmd.result; |
3576 | } | 3548 | } |
@@ -4041,9 +4013,6 @@ static irqreturn_t bttv_irq(int irq, void *dev_id) | |||
4041 | 4013 | ||
4042 | btv=(struct bttv *)dev_id; | 4014 | btv=(struct bttv *)dev_id; |
4043 | 4015 | ||
4044 | if (btv->custom_irq) | ||
4045 | handled = btv->custom_irq(btv); | ||
4046 | |||
4047 | count=0; | 4016 | count=0; |
4048 | while (1) { | 4017 | while (1) { |
4049 | /* get/clear interrupt status bits */ | 4018 | /* get/clear interrupt status bits */ |
@@ -4079,7 +4048,6 @@ static irqreturn_t bttv_irq(int irq, void *dev_id) | |||
4079 | btv->field_count++; | 4048 | btv->field_count++; |
4080 | 4049 | ||
4081 | if ((astat & BT848_INT_GPINT) && btv->remote) { | 4050 | if ((astat & BT848_INT_GPINT) && btv->remote) { |
4082 | wake_up(&btv->gpioq); | ||
4083 | bttv_input_irq(btv); | 4051 | bttv_input_irq(btv); |
4084 | } | 4052 | } |
4085 | 4053 | ||
@@ -4284,7 +4252,6 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
4284 | mutex_init(&btv->lock); | 4252 | mutex_init(&btv->lock); |
4285 | spin_lock_init(&btv->s_lock); | 4253 | spin_lock_init(&btv->s_lock); |
4286 | spin_lock_init(&btv->gpio_lock); | 4254 | spin_lock_init(&btv->gpio_lock); |
4287 | init_waitqueue_head(&btv->gpioq); | ||
4288 | init_waitqueue_head(&btv->i2c_queue); | 4255 | init_waitqueue_head(&btv->i2c_queue); |
4289 | INIT_LIST_HEAD(&btv->c.subs); | 4256 | INIT_LIST_HEAD(&btv->c.subs); |
4290 | INIT_LIST_HEAD(&btv->capture); | 4257 | INIT_LIST_HEAD(&btv->capture); |
@@ -4472,7 +4439,6 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev) | |||
4472 | 4439 | ||
4473 | /* tell gpio modules we are leaving ... */ | 4440 | /* tell gpio modules we are leaving ... */ |
4474 | btv->shutdown=1; | 4441 | btv->shutdown=1; |
4475 | wake_up(&btv->gpioq); | ||
4476 | bttv_input_fini(btv); | 4442 | bttv_input_fini(btv); |
4477 | bttv_sub_del_devices(&btv->c); | 4443 | bttv_sub_del_devices(&btv->c); |
4478 | 4444 | ||
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index 6bf05a7dc5f9..97793b960600 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c | |||
@@ -31,15 +31,9 @@ | |||
31 | 31 | ||
32 | static int ir_debug; | 32 | static int ir_debug; |
33 | module_param(ir_debug, int, 0644); | 33 | module_param(ir_debug, int, 0644); |
34 | static int repeat_delay = 500; | ||
35 | module_param(repeat_delay, int, 0644); | ||
36 | static int repeat_period = 33; | ||
37 | module_param(repeat_period, int, 0644); | ||
38 | 34 | ||
39 | static int ir_rc5_remote_gap = 885; | 35 | static int ir_rc5_remote_gap = 885; |
40 | module_param(ir_rc5_remote_gap, int, 0644); | 36 | module_param(ir_rc5_remote_gap, int, 0644); |
41 | static int ir_rc5_key_timeout = 200; | ||
42 | module_param(ir_rc5_key_timeout, int, 0644); | ||
43 | 37 | ||
44 | #undef dprintk | 38 | #undef dprintk |
45 | #define dprintk(arg...) do { \ | 39 | #define dprintk(arg...) do { \ |
@@ -55,7 +49,7 @@ module_param(ir_rc5_key_timeout, int, 0644); | |||
55 | 49 | ||
56 | static void ir_handle_key(struct bttv *btv) | 50 | static void ir_handle_key(struct bttv *btv) |
57 | { | 51 | { |
58 | struct card_ir *ir = btv->remote; | 52 | struct bttv_ir *ir = btv->remote; |
59 | u32 gpio,data; | 53 | u32 gpio,data; |
60 | 54 | ||
61 | /* read gpio value */ | 55 | /* read gpio value */ |
@@ -74,23 +68,22 @@ static void ir_handle_key(struct bttv *btv) | |||
74 | (gpio & ir->mask_keydown) ? " down" : "", | 68 | (gpio & ir->mask_keydown) ? " down" : "", |
75 | (gpio & ir->mask_keyup) ? " up" : ""); | 69 | (gpio & ir->mask_keyup) ? " up" : ""); |
76 | 70 | ||
77 | if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || | 71 | if ((ir->mask_keydown && (gpio & ir->mask_keydown)) || |
78 | (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { | 72 | (ir->mask_keyup && !(gpio & ir->mask_keyup))) { |
79 | ir_input_keydown(ir->dev, &ir->ir, data); | 73 | rc_keydown_notimeout(ir->dev, data, 0); |
80 | } else { | 74 | } else { |
81 | /* HACK: Probably, ir->mask_keydown is missing | 75 | /* HACK: Probably, ir->mask_keydown is missing |
82 | for this board */ | 76 | for this board */ |
83 | if (btv->c.type == BTTV_BOARD_WINFAST2000) | 77 | if (btv->c.type == BTTV_BOARD_WINFAST2000) |
84 | ir_input_keydown(ir->dev, &ir->ir, data); | 78 | rc_keydown_notimeout(ir->dev, data, 0); |
85 | 79 | ||
86 | ir_input_nokey(ir->dev,&ir->ir); | 80 | rc_keyup(ir->dev); |
87 | } | 81 | } |
88 | |||
89 | } | 82 | } |
90 | 83 | ||
91 | static void ir_enltv_handle_key(struct bttv *btv) | 84 | static void ir_enltv_handle_key(struct bttv *btv) |
92 | { | 85 | { |
93 | struct card_ir *ir = btv->remote; | 86 | struct bttv_ir *ir = btv->remote; |
94 | u32 gpio, data, keyup; | 87 | u32 gpio, data, keyup; |
95 | 88 | ||
96 | /* read gpio value */ | 89 | /* read gpio value */ |
@@ -107,9 +100,9 @@ static void ir_enltv_handle_key(struct bttv *btv) | |||
107 | gpio, data, | 100 | gpio, data, |
108 | (gpio & ir->mask_keyup) ? " up" : "up/down"); | 101 | (gpio & ir->mask_keyup) ? " up" : "up/down"); |
109 | 102 | ||
110 | ir_input_keydown(ir->dev, &ir->ir, data); | 103 | rc_keydown_notimeout(ir->dev, data, 0); |
111 | if (keyup) | 104 | if (keyup) |
112 | ir_input_nokey(ir->dev, &ir->ir); | 105 | rc_keyup(ir->dev); |
113 | } else { | 106 | } else { |
114 | if ((ir->last_gpio & 1 << 31) == keyup) | 107 | if ((ir->last_gpio & 1 << 31) == keyup) |
115 | return; | 108 | return; |
@@ -119,26 +112,30 @@ static void ir_enltv_handle_key(struct bttv *btv) | |||
119 | (gpio & ir->mask_keyup) ? " up" : "down"); | 112 | (gpio & ir->mask_keyup) ? " up" : "down"); |
120 | 113 | ||
121 | if (keyup) | 114 | if (keyup) |
122 | ir_input_nokey(ir->dev, &ir->ir); | 115 | rc_keyup(ir->dev); |
123 | else | 116 | else |
124 | ir_input_keydown(ir->dev, &ir->ir, data); | 117 | rc_keydown_notimeout(ir->dev, data, 0); |
125 | } | 118 | } |
126 | 119 | ||
127 | ir->last_gpio = data | keyup; | 120 | ir->last_gpio = data | keyup; |
128 | } | 121 | } |
129 | 122 | ||
123 | static int bttv_rc5_irq(struct bttv *btv); | ||
124 | |||
130 | void bttv_input_irq(struct bttv *btv) | 125 | void bttv_input_irq(struct bttv *btv) |
131 | { | 126 | { |
132 | struct card_ir *ir = btv->remote; | 127 | struct bttv_ir *ir = btv->remote; |
133 | 128 | ||
134 | if (!ir->polling) | 129 | if (ir->rc5_gpio) |
130 | bttv_rc5_irq(btv); | ||
131 | else if (!ir->polling) | ||
135 | ir_handle_key(btv); | 132 | ir_handle_key(btv); |
136 | } | 133 | } |
137 | 134 | ||
138 | static void bttv_input_timer(unsigned long data) | 135 | static void bttv_input_timer(unsigned long data) |
139 | { | 136 | { |
140 | struct bttv *btv = (struct bttv*)data; | 137 | struct bttv *btv = (struct bttv*)data; |
141 | struct card_ir *ir = btv->remote; | 138 | struct bttv_ir *ir = btv->remote; |
142 | 139 | ||
143 | if (btv->c.type == BTTV_BOARD_ENLTV_FM_2) | 140 | if (btv->c.type == BTTV_BOARD_ENLTV_FM_2) |
144 | ir_enltv_handle_key(btv); | 141 | ir_enltv_handle_key(btv); |
@@ -147,11 +144,109 @@ static void bttv_input_timer(unsigned long data) | |||
147 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); | 144 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); |
148 | } | 145 | } |
149 | 146 | ||
150 | /* ---------------------------------------------------------------*/ | 147 | /* |
148 | * FIXME: Nebula digi uses the legacy way to decode RC5, instead of relying | ||
149 | * on the rc-core way. As we need to be sure that both IRQ transitions are | ||
150 | * properly triggered, Better to touch it only with this hardware for | ||
151 | * testing. | ||
152 | */ | ||
153 | |||
154 | #define RC5_START(x) (((x) >> 12) & 3) | ||
155 | #define RC5_TOGGLE(x) (((x) >> 11) & 1) | ||
156 | #define RC5_ADDR(x) (((x) >> 6) & 31) | ||
157 | #define RC5_INSTR(x) ((x) & 63) | ||
158 | |||
159 | /* decode raw bit pattern to RC5 code */ | ||
160 | static u32 bttv_rc5_decode(unsigned int code) | ||
161 | { | ||
162 | unsigned int org_code = code; | ||
163 | unsigned int pair; | ||
164 | unsigned int rc5 = 0; | ||
165 | int i; | ||
166 | |||
167 | for (i = 0; i < 14; ++i) { | ||
168 | pair = code & 0x3; | ||
169 | code >>= 2; | ||
170 | |||
171 | rc5 <<= 1; | ||
172 | switch (pair) { | ||
173 | case 0: | ||
174 | case 2: | ||
175 | break; | ||
176 | case 1: | ||
177 | rc5 |= 1; | ||
178 | break; | ||
179 | case 3: | ||
180 | dprintk(KERN_INFO DEVNAME ":rc5_decode(%x) bad code\n", | ||
181 | org_code); | ||
182 | return 0; | ||
183 | } | ||
184 | } | ||
185 | dprintk(KERN_INFO DEVNAME ":" | ||
186 | "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " | ||
187 | "instr=%x\n", rc5, org_code, RC5_START(rc5), | ||
188 | RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); | ||
189 | return rc5; | ||
190 | } | ||
191 | |||
192 | static void bttv_rc5_timer_end(unsigned long data) | ||
193 | { | ||
194 | struct bttv_ir *ir = (struct bttv_ir *)data; | ||
195 | struct timeval tv; | ||
196 | unsigned long current_jiffies; | ||
197 | u32 gap; | ||
198 | u32 rc5 = 0; | ||
199 | |||
200 | /* get time */ | ||
201 | current_jiffies = jiffies; | ||
202 | do_gettimeofday(&tv); | ||
203 | |||
204 | /* avoid overflow with gap >1s */ | ||
205 | if (tv.tv_sec - ir->base_time.tv_sec > 1) { | ||
206 | gap = 200000; | ||
207 | } else { | ||
208 | gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + | ||
209 | tv.tv_usec - ir->base_time.tv_usec; | ||
210 | } | ||
211 | |||
212 | /* signal we're ready to start a new code */ | ||
213 | ir->active = false; | ||
214 | |||
215 | /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ | ||
216 | if (gap < 28000) { | ||
217 | dprintk(KERN_INFO DEVNAME ": spurious timer_end\n"); | ||
218 | return; | ||
219 | } | ||
220 | |||
221 | if (ir->last_bit < 20) { | ||
222 | /* ignore spurious codes (caused by light/other remotes) */ | ||
223 | dprintk(KERN_INFO DEVNAME ": short code: %x\n", ir->code); | ||
224 | } else { | ||
225 | ir->code = (ir->code << ir->shift_by) | 1; | ||
226 | rc5 = bttv_rc5_decode(ir->code); | ||
227 | |||
228 | /* two start bits? */ | ||
229 | if (RC5_START(rc5) != ir->start) { | ||
230 | printk(KERN_INFO DEVNAME ":" | ||
231 | " rc5 start bits invalid: %u\n", RC5_START(rc5)); | ||
232 | |||
233 | /* right address? */ | ||
234 | } else if (RC5_ADDR(rc5) == ir->addr) { | ||
235 | u32 toggle = RC5_TOGGLE(rc5); | ||
236 | u32 instr = RC5_INSTR(rc5); | ||
237 | |||
238 | /* Good code */ | ||
239 | rc_keydown(ir->dev, instr, toggle); | ||
240 | dprintk(KERN_INFO DEVNAME ":" | ||
241 | " instruction %x, toggle %x\n", | ||
242 | instr, toggle); | ||
243 | } | ||
244 | } | ||
245 | } | ||
151 | 246 | ||
152 | static int bttv_rc5_irq(struct bttv *btv) | 247 | static int bttv_rc5_irq(struct bttv *btv) |
153 | { | 248 | { |
154 | struct card_ir *ir = btv->remote; | 249 | struct bttv_ir *ir = btv->remote; |
155 | struct timeval tv; | 250 | struct timeval tv; |
156 | u32 gpio; | 251 | u32 gpio; |
157 | u32 gap; | 252 | u32 gap; |
@@ -160,10 +255,6 @@ static int bttv_rc5_irq(struct bttv *btv) | |||
160 | /* read gpio port */ | 255 | /* read gpio port */ |
161 | gpio = bttv_gpio_read(&btv->c); | 256 | gpio = bttv_gpio_read(&btv->c); |
162 | 257 | ||
163 | /* remote IRQ? */ | ||
164 | if (!(gpio & 0x20)) | ||
165 | return 0; | ||
166 | |||
167 | /* get time of bit */ | 258 | /* get time of bit */ |
168 | current_jiffies = jiffies; | 259 | current_jiffies = jiffies; |
169 | do_gettimeofday(&tv); | 260 | do_gettimeofday(&tv); |
@@ -176,6 +267,13 @@ static int bttv_rc5_irq(struct bttv *btv) | |||
176 | tv.tv_usec - ir->base_time.tv_usec; | 267 | tv.tv_usec - ir->base_time.tv_usec; |
177 | } | 268 | } |
178 | 269 | ||
270 | dprintk(KERN_INFO DEVNAME ": RC5 IRQ: gap %d us for %s\n", | ||
271 | gap, (gpio & 0x20) ? "mark" : "space"); | ||
272 | |||
273 | /* remote IRQ? */ | ||
274 | if (!(gpio & 0x20)) | ||
275 | return 0; | ||
276 | |||
179 | /* active code => add bit */ | 277 | /* active code => add bit */ |
180 | if (ir->active) { | 278 | if (ir->active) { |
181 | /* only if in the code (otherwise spurious IRQ or timer | 279 | /* only if in the code (otherwise spurious IRQ or timer |
@@ -187,13 +285,12 @@ static int bttv_rc5_irq(struct bttv *btv) | |||
187 | } | 285 | } |
188 | /* starting new code */ | 286 | /* starting new code */ |
189 | } else { | 287 | } else { |
190 | ir->active = 1; | 288 | ir->active = true; |
191 | ir->code = 0; | 289 | ir->code = 0; |
192 | ir->base_time = tv; | 290 | ir->base_time = tv; |
193 | ir->last_bit = 0; | 291 | ir->last_bit = 0; |
194 | 292 | ||
195 | mod_timer(&ir->timer_end, | 293 | mod_timer(&ir->timer, current_jiffies + msecs_to_jiffies(30)); |
196 | current_jiffies + msecs_to_jiffies(30)); | ||
197 | } | 294 | } |
198 | 295 | ||
199 | /* toggle GPIO pin 4 to reset the irq */ | 296 | /* toggle GPIO pin 4 to reset the irq */ |
@@ -204,7 +301,7 @@ static int bttv_rc5_irq(struct bttv *btv) | |||
204 | 301 | ||
205 | /* ---------------------------------------------------------------------- */ | 302 | /* ---------------------------------------------------------------------- */ |
206 | 303 | ||
207 | static void bttv_ir_start(struct bttv *btv, struct card_ir *ir) | 304 | static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir) |
208 | { | 305 | { |
209 | if (ir->polling) { | 306 | if (ir->polling) { |
210 | setup_timer(&ir->timer, bttv_input_timer, (unsigned long)btv); | 307 | setup_timer(&ir->timer, bttv_input_timer, (unsigned long)btv); |
@@ -212,17 +309,10 @@ static void bttv_ir_start(struct bttv *btv, struct card_ir *ir) | |||
212 | add_timer(&ir->timer); | 309 | add_timer(&ir->timer); |
213 | } else if (ir->rc5_gpio) { | 310 | } else if (ir->rc5_gpio) { |
214 | /* set timer_end for code completion */ | 311 | /* set timer_end for code completion */ |
215 | init_timer(&ir->timer_end); | 312 | setup_timer(&ir->timer, bttv_rc5_timer_end, (unsigned long)ir); |
216 | ir->timer_end.function = ir_rc5_timer_end; | ||
217 | ir->timer_end.data = (unsigned long)ir; | ||
218 | |||
219 | init_timer(&ir->timer_keyup); | ||
220 | ir->timer_keyup.function = ir_rc5_timer_keyup; | ||
221 | ir->timer_keyup.data = (unsigned long)ir; | ||
222 | ir->shift_by = 1; | 313 | ir->shift_by = 1; |
223 | ir->start = 3; | 314 | ir->start = 3; |
224 | ir->addr = 0x0; | 315 | ir->addr = 0x0; |
225 | ir->rc5_key_timeout = ir_rc5_key_timeout; | ||
226 | ir->rc5_remote_gap = ir_rc5_remote_gap; | 316 | ir->rc5_remote_gap = ir_rc5_remote_gap; |
227 | } | 317 | } |
228 | } | 318 | } |
@@ -237,7 +327,7 @@ static void bttv_ir_stop(struct bttv *btv) | |||
237 | if (btv->remote->rc5_gpio) { | 327 | if (btv->remote->rc5_gpio) { |
238 | u32 gpio; | 328 | u32 gpio; |
239 | 329 | ||
240 | del_timer_sync(&btv->remote->timer_end); | 330 | del_timer_sync(&btv->remote->timer); |
241 | flush_scheduled_work(); | 331 | flush_scheduled_work(); |
242 | 332 | ||
243 | gpio = bttv_gpio_read(&btv->c); | 333 | gpio = bttv_gpio_read(&btv->c); |
@@ -264,6 +354,18 @@ static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
264 | return 0; | 354 | return 0; |
265 | dprintk(KERN_INFO DEVNAME ": key %02x\n", b); | 355 | dprintk(KERN_INFO DEVNAME ": key %02x\n", b); |
266 | 356 | ||
357 | /* | ||
358 | * NOTE: | ||
359 | * lirc_i2c maps the pv951 code as: | ||
360 | * addr = 0x61D6 | ||
361 | * cmd = bit_reverse (b) | ||
362 | * So, it seems that this device uses NEC extended | ||
363 | * I decided to not fix the table, due to two reasons: | ||
364 | * 1) Without the actual device, this is only a guess; | ||
365 | * 2) As the addr is not reported via I2C, nor can be changed, | ||
366 | * the device is bound to the vendor-provided RC. | ||
367 | */ | ||
368 | |||
267 | *ir_key = b; | 369 | *ir_key = b; |
268 | *ir_raw = b; | 370 | *ir_raw = b; |
269 | return 1; | 371 | return 1; |
@@ -290,16 +392,15 @@ void __devinit init_bttv_i2c_ir(struct bttv *btv) | |||
290 | btv->init_data.name = "PV951"; | 392 | btv->init_data.name = "PV951"; |
291 | btv->init_data.get_key = get_key_pv951; | 393 | btv->init_data.get_key = get_key_pv951; |
292 | btv->init_data.ir_codes = RC_MAP_PV951; | 394 | btv->init_data.ir_codes = RC_MAP_PV951; |
293 | btv->init_data.type = IR_TYPE_OTHER; | ||
294 | info.addr = 0x4b; | 395 | info.addr = 0x4b; |
295 | break; | 396 | break; |
296 | default: | 397 | default: |
297 | /* | 398 | /* |
298 | * The external IR receiver is at i2c address 0x34 (0x35 for | 399 | * The external IR receiver is at i2c address 0x34 (0x35 for |
299 | * reads). Future Hauppauge cards will have an internal | 400 | * reads). Future Hauppauge cards will have an internal |
300 | * receiver at 0x30 (0x31 for reads). In theory, both can be | 401 | * receiver at 0x30 (0x31 for reads). In theory, both can be |
301 | * fitted, and Hauppauge suggest an external overrides an | 402 | * fitted, and Hauppauge suggest an external overrides an |
302 | * internal. | 403 | * internal. |
303 | * That's why we probe 0x1a (~0x34) first. CB | 404 | * That's why we probe 0x1a (~0x34) first. CB |
304 | */ | 405 | */ |
305 | 406 | ||
@@ -324,18 +425,17 @@ int __devexit fini_bttv_i2c(struct bttv *btv) | |||
324 | 425 | ||
325 | int bttv_input_init(struct bttv *btv) | 426 | int bttv_input_init(struct bttv *btv) |
326 | { | 427 | { |
327 | struct card_ir *ir; | 428 | struct bttv_ir *ir; |
328 | char *ir_codes = NULL; | 429 | char *ir_codes = NULL; |
329 | struct input_dev *input_dev; | 430 | struct rc_dev *rc; |
330 | u64 ir_type = IR_TYPE_OTHER; | ||
331 | int err = -ENOMEM; | 431 | int err = -ENOMEM; |
332 | 432 | ||
333 | if (!btv->has_remote) | 433 | if (!btv->has_remote) |
334 | return -ENODEV; | 434 | return -ENODEV; |
335 | 435 | ||
336 | ir = kzalloc(sizeof(*ir),GFP_KERNEL); | 436 | ir = kzalloc(sizeof(*ir),GFP_KERNEL); |
337 | input_dev = input_allocate_device(); | 437 | rc = rc_allocate_device(); |
338 | if (!ir || !input_dev) | 438 | if (!ir || !rc) |
339 | goto err_out_free; | 439 | goto err_out_free; |
340 | 440 | ||
341 | /* detect & configure */ | 441 | /* detect & configure */ |
@@ -398,8 +498,7 @@ int bttv_input_init(struct bttv *btv) | |||
398 | break; | 498 | break; |
399 | case BTTV_BOARD_NEBULA_DIGITV: | 499 | case BTTV_BOARD_NEBULA_DIGITV: |
400 | ir_codes = RC_MAP_NEBULA; | 500 | ir_codes = RC_MAP_NEBULA; |
401 | btv->custom_irq = bttv_rc5_irq; | 501 | ir->rc5_gpio = true; |
402 | ir->rc5_gpio = 1; | ||
403 | break; | 502 | break; |
404 | case BTTV_BOARD_MACHTV_MAGICTV: | 503 | case BTTV_BOARD_MACHTV_MAGICTV: |
405 | ir_codes = RC_MAP_APAC_VIEWCOMP; | 504 | ir_codes = RC_MAP_APAC_VIEWCOMP; |
@@ -441,48 +540,43 @@ int bttv_input_init(struct bttv *btv) | |||
441 | } | 540 | } |
442 | 541 | ||
443 | /* init input device */ | 542 | /* init input device */ |
444 | ir->dev = input_dev; | 543 | ir->dev = rc; |
445 | 544 | ||
446 | snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)", | 545 | snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)", |
447 | btv->c.type); | 546 | btv->c.type); |
448 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", | 547 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", |
449 | pci_name(btv->c.pci)); | 548 | pci_name(btv->c.pci)); |
450 | 549 | ||
451 | err = ir_input_init(input_dev, &ir->ir, ir_type); | 550 | rc->input_name = ir->name; |
452 | if (err < 0) | 551 | rc->input_phys = ir->phys; |
453 | goto err_out_free; | 552 | rc->input_id.bustype = BUS_PCI; |
454 | 553 | rc->input_id.version = 1; | |
455 | input_dev->name = ir->name; | ||
456 | input_dev->phys = ir->phys; | ||
457 | input_dev->id.bustype = BUS_PCI; | ||
458 | input_dev->id.version = 1; | ||
459 | if (btv->c.pci->subsystem_vendor) { | 554 | if (btv->c.pci->subsystem_vendor) { |
460 | input_dev->id.vendor = btv->c.pci->subsystem_vendor; | 555 | rc->input_id.vendor = btv->c.pci->subsystem_vendor; |
461 | input_dev->id.product = btv->c.pci->subsystem_device; | 556 | rc->input_id.product = btv->c.pci->subsystem_device; |
462 | } else { | 557 | } else { |
463 | input_dev->id.vendor = btv->c.pci->vendor; | 558 | rc->input_id.vendor = btv->c.pci->vendor; |
464 | input_dev->id.product = btv->c.pci->device; | 559 | rc->input_id.product = btv->c.pci->device; |
465 | } | 560 | } |
466 | input_dev->dev.parent = &btv->c.pci->dev; | 561 | rc->dev.parent = &btv->c.pci->dev; |
562 | rc->map_name = ir_codes; | ||
563 | rc->driver_name = MODULE_NAME; | ||
467 | 564 | ||
468 | btv->remote = ir; | 565 | btv->remote = ir; |
469 | bttv_ir_start(btv, ir); | 566 | bttv_ir_start(btv, ir); |
470 | 567 | ||
471 | /* all done */ | 568 | /* all done */ |
472 | err = ir_input_register(btv->remote->dev, ir_codes, NULL, MODULE_NAME); | 569 | err = rc_register_device(rc); |
473 | if (err) | 570 | if (err) |
474 | goto err_out_stop; | 571 | goto err_out_stop; |
475 | 572 | ||
476 | /* the remote isn't as bouncy as a keyboard */ | ||
477 | ir->dev->rep[REP_DELAY] = repeat_delay; | ||
478 | ir->dev->rep[REP_PERIOD] = repeat_period; | ||
479 | |||
480 | return 0; | 573 | return 0; |
481 | 574 | ||
482 | err_out_stop: | 575 | err_out_stop: |
483 | bttv_ir_stop(btv); | 576 | bttv_ir_stop(btv); |
484 | btv->remote = NULL; | 577 | btv->remote = NULL; |
485 | err_out_free: | 578 | err_out_free: |
579 | rc_free_device(rc); | ||
486 | kfree(ir); | 580 | kfree(ir); |
487 | return err; | 581 | return err; |
488 | } | 582 | } |
@@ -493,7 +587,7 @@ void bttv_input_fini(struct bttv *btv) | |||
493 | return; | 587 | return; |
494 | 588 | ||
495 | bttv_ir_stop(btv); | 589 | bttv_ir_stop(btv); |
496 | ir_input_unregister(btv->remote->dev); | 590 | rc_unregister_device(btv->remote->dev); |
497 | kfree(btv->remote); | 591 | kfree(btv->remote); |
498 | btv->remote = NULL; | 592 | btv->remote = NULL; |
499 | } | 593 | } |
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index 6fd2a8ebda1e..fd62bf15d779 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/videodev2.h> | 17 | #include <linux/videodev2.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <media/v4l2-device.h> | 19 | #include <media/v4l2-device.h> |
20 | #include <media/ir-common.h> | ||
21 | #include <media/i2c-addr.h> | 20 | #include <media/i2c-addr.h> |
22 | #include <media/tuner.h> | 21 | #include <media/tuner.h> |
23 | 22 | ||
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index d1e26a448ed2..9b776faf0741 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h | |||
@@ -41,7 +41,7 @@ | |||
41 | #include <linux/device.h> | 41 | #include <linux/device.h> |
42 | #include <media/videobuf-dma-sg.h> | 42 | #include <media/videobuf-dma-sg.h> |
43 | #include <media/tveeprom.h> | 43 | #include <media/tveeprom.h> |
44 | #include <media/ir-common.h> | 44 | #include <media/rc-core.h> |
45 | #include <media/ir-kbd-i2c.h> | 45 | #include <media/ir-kbd-i2c.h> |
46 | 46 | ||
47 | #include "bt848.h" | 47 | #include "bt848.h" |
@@ -120,6 +120,33 @@ struct bttv_format { | |||
120 | int hshift,vshift; /* for planar modes */ | 120 | int hshift,vshift; /* for planar modes */ |
121 | }; | 121 | }; |
122 | 122 | ||
123 | struct bttv_ir { | ||
124 | struct rc_dev *dev; | ||
125 | struct timer_list timer; | ||
126 | |||
127 | char name[32]; | ||
128 | char phys[32]; | ||
129 | |||
130 | /* Usual gpio signalling */ | ||
131 | u32 mask_keycode; | ||
132 | u32 mask_keydown; | ||
133 | u32 mask_keyup; | ||
134 | u32 polling; | ||
135 | u32 last_gpio; | ||
136 | int shift_by; | ||
137 | int start; // What should RC5_START() be | ||
138 | int addr; // What RC5_ADDR() should be. | ||
139 | int rc5_remote_gap; | ||
140 | |||
141 | /* RC5 gpio */ | ||
142 | bool rc5_gpio; /* Is RC5 legacy GPIO enabled? */ | ||
143 | u32 last_bit; /* last raw bit seen */ | ||
144 | u32 code; /* raw code under construction */ | ||
145 | struct timeval base_time; /* time of last seen code */ | ||
146 | bool active; /* building raw code */ | ||
147 | }; | ||
148 | |||
149 | |||
123 | /* ---------------------------------------------------------- */ | 150 | /* ---------------------------------------------------------- */ |
124 | 151 | ||
125 | struct bttv_geometry { | 152 | struct bttv_geometry { |
@@ -305,7 +332,6 @@ struct bttv_pll_info { | |||
305 | /* for gpio-connected remote control */ | 332 | /* for gpio-connected remote control */ |
306 | struct bttv_input { | 333 | struct bttv_input { |
307 | struct input_dev *dev; | 334 | struct input_dev *dev; |
308 | struct ir_input_state ir; | ||
309 | char name[32]; | 335 | char name[32]; |
310 | char phys[32]; | 336 | char phys[32]; |
311 | u32 mask_keycode; | 337 | u32 mask_keycode; |
@@ -338,12 +364,10 @@ struct bttv { | |||
338 | struct bttv_pll_info pll; | 364 | struct bttv_pll_info pll; |
339 | int triton1; | 365 | int triton1; |
340 | int gpioirq; | 366 | int gpioirq; |
341 | int (*custom_irq)(struct bttv *btv); | ||
342 | 367 | ||
343 | int use_i2c_hw; | 368 | int use_i2c_hw; |
344 | 369 | ||
345 | /* old gpio interface */ | 370 | /* old gpio interface */ |
346 | wait_queue_head_t gpioq; | ||
347 | int shutdown; | 371 | int shutdown; |
348 | 372 | ||
349 | void (*volume_gpio)(struct bttv *btv, __u16 volume); | 373 | void (*volume_gpio)(struct bttv *btv, __u16 volume); |
@@ -368,7 +392,7 @@ struct bttv { | |||
368 | 392 | ||
369 | /* infrared remote */ | 393 | /* infrared remote */ |
370 | int has_remote; | 394 | int has_remote; |
371 | struct card_ir *remote; | 395 | struct bttv_ir *remote; |
372 | 396 | ||
373 | /* I2C remote data */ | 397 | /* I2C remote data */ |
374 | struct IR_i2c_init_data init_data; | 398 | struct IR_i2c_init_data init_data; |
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 0dfff50891e4..789087cd6a9c 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
@@ -859,8 +859,6 @@ static int cafe_cam_configure(struct cafe_camera *cam) | |||
859 | struct v4l2_mbus_framefmt mbus_fmt; | 859 | struct v4l2_mbus_framefmt mbus_fmt; |
860 | int ret; | 860 | int ret; |
861 | 861 | ||
862 | if (cam->state != S_IDLE) | ||
863 | return -EINVAL; | ||
864 | v4l2_fill_mbus_format(&mbus_fmt, &cam->pix_format, cam->mbus_code); | 862 | v4l2_fill_mbus_format(&mbus_fmt, &cam->pix_format, cam->mbus_code); |
865 | ret = sensor_call(cam, core, init, 0); | 863 | ret = sensor_call(cam, core, init, 0); |
866 | if (ret == 0) | 864 | if (ret == 0) |
@@ -2196,12 +2194,13 @@ static int cafe_pci_resume(struct pci_dev *pdev) | |||
2196 | return ret; | 2194 | return ret; |
2197 | } | 2195 | } |
2198 | cafe_ctlr_init(cam); | 2196 | cafe_ctlr_init(cam); |
2199 | cafe_ctlr_power_down(cam); | ||
2200 | 2197 | ||
2201 | mutex_lock(&cam->s_mutex); | 2198 | mutex_lock(&cam->s_mutex); |
2202 | if (cam->users > 0) { | 2199 | if (cam->users > 0) { |
2203 | cafe_ctlr_power_up(cam); | 2200 | cafe_ctlr_power_up(cam); |
2204 | __cafe_cam_reset(cam); | 2201 | __cafe_cam_reset(cam); |
2202 | } else { | ||
2203 | cafe_ctlr_power_down(cam); | ||
2205 | } | 2204 | } |
2206 | mutex_unlock(&cam->s_mutex); | 2205 | mutex_unlock(&cam->s_mutex); |
2207 | 2206 | ||
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 46b433bbf2c1..7edf80b0d01a 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c | |||
@@ -419,28 +419,6 @@ static int sync(struct camera_data *cam, int frame_nr) | |||
419 | 419 | ||
420 | /****************************************************************************** | 420 | /****************************************************************************** |
421 | * | 421 | * |
422 | * ioctl_get_mbuf | ||
423 | * | ||
424 | *****************************************************************************/ | ||
425 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
426 | static int ioctl_get_mbuf(void *arg, struct camera_data *cam) | ||
427 | { | ||
428 | struct video_mbuf *vm; | ||
429 | int i; | ||
430 | vm = arg; | ||
431 | |||
432 | memset(vm, 0, sizeof(*vm)); | ||
433 | vm->size = cam->frame_size*cam->num_frames; | ||
434 | vm->frames = cam->num_frames; | ||
435 | for (i = 0; i < cam->num_frames; i++) | ||
436 | vm->offsets[i] = cam->frame_size * i; | ||
437 | |||
438 | return 0; | ||
439 | } | ||
440 | #endif | ||
441 | |||
442 | /****************************************************************************** | ||
443 | * | ||
444 | * ioctl_set_gpio | 422 | * ioctl_set_gpio |
445 | * | 423 | * |
446 | *****************************************************************************/ | 424 | *****************************************************************************/ |
@@ -1380,17 +1358,6 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1380 | } | 1358 | } |
1381 | break; | 1359 | break; |
1382 | } | 1360 | } |
1383 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1384 | case VIDIOCGMBUF: | ||
1385 | { | ||
1386 | struct cpia2_fh *fh = file->private_data; | ||
1387 | if(fh->prio != V4L2_PRIORITY_RECORD) { | ||
1388 | mutex_unlock(&cam->busy_lock); | ||
1389 | return -EBUSY; | ||
1390 | } | ||
1391 | break; | ||
1392 | } | ||
1393 | #endif | ||
1394 | default: | 1361 | default: |
1395 | break; | 1362 | break; |
1396 | } | 1363 | } |
@@ -1400,11 +1367,6 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1400 | case CPIA2_IOC_SET_GPIO: | 1367 | case CPIA2_IOC_SET_GPIO: |
1401 | retval = ioctl_set_gpio(arg, cam); | 1368 | retval = ioctl_set_gpio(arg, cam); |
1402 | break; | 1369 | break; |
1403 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1404 | case VIDIOCGMBUF: /* mmap interface */ | ||
1405 | retval = ioctl_get_mbuf(arg, cam); | ||
1406 | break; | ||
1407 | #endif | ||
1408 | case VIDIOC_QUERYCAP: | 1370 | case VIDIOC_QUERYCAP: |
1409 | retval = ioctl_querycap(arg,cam); | 1371 | retval = ioctl_querycap(arg,cam); |
1410 | break; | 1372 | break; |
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig index 76c054d1eef9..d9d2f6ad6ffb 100644 --- a/drivers/media/video/cx18/Kconfig +++ b/drivers/media/video/cx18/Kconfig | |||
@@ -1,9 +1,8 @@ | |||
1 | config VIDEO_CX18 | 1 | config VIDEO_CX18 |
2 | tristate "Conexant cx23418 MPEG encoder support" | 2 | tristate "Conexant cx23418 MPEG encoder support" |
3 | depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL | 3 | depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL |
4 | depends on INPUT # due to VIDEO_IR | ||
5 | select I2C_ALGOBIT | 4 | select I2C_ALGOBIT |
6 | depends on VIDEO_IR | 5 | depends on RC_CORE |
7 | select VIDEO_TUNER | 6 | select VIDEO_TUNER |
8 | select VIDEO_TVEEPROM | 7 | select VIDEO_TVEEPROM |
9 | select VIDEO_CX2341X | 8 | select VIDEO_CX2341X |
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index fe1090940b01..87177733cf92 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c | |||
@@ -39,7 +39,7 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = { | |||
39 | .tv = { 0x61, 0x60, I2C_CLIENT_END }, | 39 | .tv = { 0x61, 0x60, I2C_CLIENT_END }, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | /* Please add new PCI IDs to: http://pci-ids.ucw.cz/ | 42 | /* Please add new PCI IDs to: http://pci-ids.ucw.cz/ |
43 | This keeps the PCI ID database up to date. Note that the entries | 43 | This keeps the PCI ID database up to date. Note that the entries |
44 | must be added under vendor 0x4444 (Conexant) as subsystem IDs. | 44 | must be added under vendor 0x4444 (Conexant) as subsystem IDs. |
45 | New vendor IDs should still be added to the vendor ID list. */ | 45 | New vendor IDs should still be added to the vendor ID list. */ |
@@ -251,6 +251,66 @@ static const struct cx18_card cx18_card_mpc718 = { | |||
251 | 251 | ||
252 | /* ------------------------------------------------------------------------- */ | 252 | /* ------------------------------------------------------------------------- */ |
253 | 253 | ||
254 | /* GoTView PCI */ | ||
255 | |||
256 | static const struct cx18_card_pci_info cx18_pci_gotview_dvd3[] = { | ||
257 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_GOTVIEW, 0x3343 }, | ||
258 | { 0, 0, 0 } | ||
259 | }; | ||
260 | |||
261 | static const struct cx18_card cx18_card_gotview_dvd3 = { | ||
262 | .type = CX18_CARD_GOTVIEW_PCI_DVD3, | ||
263 | .name = "GoTView PCI DVD3 Hybrid", | ||
264 | .comment = "Experimenters needed for device to work well.\n" | ||
265 | "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", | ||
266 | .v4l2_capabilities = CX18_CAP_ENCODER, | ||
267 | .hw_audio_ctrl = CX18_HW_418_AV, | ||
268 | .hw_muxer = CX18_HW_GPIO_MUX, | ||
269 | .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER | | ||
270 | CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL, | ||
271 | .video_inputs = { | ||
272 | { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, | ||
273 | { CX18_CARD_INPUT_SVIDEO1, 1, | ||
274 | CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, | ||
275 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, | ||
276 | { CX18_CARD_INPUT_SVIDEO2, 2, | ||
277 | CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 }, | ||
278 | { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 }, | ||
279 | }, | ||
280 | .audio_inputs = { | ||
281 | { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, | ||
282 | { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, | ||
283 | { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 }, | ||
284 | }, | ||
285 | .tuners = { | ||
286 | /* XC3028 tuner */ | ||
287 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | ||
288 | }, | ||
289 | /* FIXME - the FM radio is just a guess and driver doesn't use SIF */ | ||
290 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 }, | ||
291 | .ddr = { | ||
292 | /* Hynix HY5DU283222B DDR RAM */ | ||
293 | .chip_config = 0x303, | ||
294 | .refresh = 0x3bd, | ||
295 | .timing1 = 0x36320966, | ||
296 | .timing2 = 0x1f, | ||
297 | .tune_lane = 0, | ||
298 | .initial_emrs = 2, | ||
299 | }, | ||
300 | .gpio_init.initial_value = 0x1, | ||
301 | .gpio_init.direction = 0x3, | ||
302 | |||
303 | .gpio_audio_input = { .mask = 0x3, | ||
304 | .tuner = 0x1, | ||
305 | .linein = 0x2, | ||
306 | .radio = 0x1 }, | ||
307 | .xceive_pin = 0, | ||
308 | .pci_list = cx18_pci_gotview_dvd3, | ||
309 | .i2c = &cx18_i2c_std, | ||
310 | }; | ||
311 | |||
312 | /* ------------------------------------------------------------------------- */ | ||
313 | |||
254 | /* Conexant Raptor PAL/SECAM: note that this card is analog only! */ | 314 | /* Conexant Raptor PAL/SECAM: note that this card is analog only! */ |
255 | 315 | ||
256 | static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = { | 316 | static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = { |
@@ -463,6 +523,7 @@ static const struct cx18_card *cx18_card_list[] = { | |||
463 | &cx18_card_toshiba_qosmio_dvbt, | 523 | &cx18_card_toshiba_qosmio_dvbt, |
464 | &cx18_card_leadtek_pvr2100, | 524 | &cx18_card_leadtek_pvr2100, |
465 | &cx18_card_leadtek_dvr3100h, | 525 | &cx18_card_leadtek_dvr3100h, |
526 | &cx18_card_gotview_dvd3 | ||
466 | }; | 527 | }; |
467 | 528 | ||
468 | const struct cx18_card *cx18_get_card(u16 index) | 529 | const struct cx18_card *cx18_get_card(u16 index) |
@@ -485,7 +546,6 @@ int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input) | |||
485 | "Component 1" | 546 | "Component 1" |
486 | }; | 547 | }; |
487 | 548 | ||
488 | memset(input, 0, sizeof(*input)); | ||
489 | if (index >= cx->nof_inputs) | 549 | if (index >= cx->nof_inputs) |
490 | return -EINVAL; | 550 | return -EINVAL; |
491 | input->index = index; | 551 | input->index = index; |
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c index 67043c7b452b..97d7b7e100a3 100644 --- a/drivers/media/video/cx18/cx18-controls.c +++ b/drivers/media/video/cx18/cx18-controls.c | |||
@@ -108,7 +108,7 @@ static int cx18_try_ctrl(struct file *file, void *fh, | |||
108 | struct v4l2_ext_control *vctrl) | 108 | struct v4l2_ext_control *vctrl) |
109 | { | 109 | { |
110 | struct v4l2_queryctrl qctrl; | 110 | struct v4l2_queryctrl qctrl; |
111 | const char **menu_items = NULL; | 111 | const char * const *menu_items = NULL; |
112 | int err; | 112 | int err; |
113 | 113 | ||
114 | qctrl.id = vctrl->id; | 114 | qctrl.id = vctrl->id; |
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index df60f27337cf..676e5bef89eb 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
@@ -156,6 +156,7 @@ MODULE_PARM_DESC(cardtype, | |||
156 | "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n" | 156 | "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n" |
157 | "\t\t\t 7 = Leadtek WinFast PVR2100\n" | 157 | "\t\t\t 7 = Leadtek WinFast PVR2100\n" |
158 | "\t\t\t 8 = Leadtek WinFast DVR3100 H\n" | 158 | "\t\t\t 8 = Leadtek WinFast DVR3100 H\n" |
159 | "\t\t\t 9 = GoTView PCI DVD3 Hybrid\n" | ||
159 | "\t\t\t 0 = Autodetect (default)\n" | 160 | "\t\t\t 0 = Autodetect (default)\n" |
160 | "\t\t\t-1 = Ignore this card\n\t\t"); | 161 | "\t\t\t-1 = Ignore this card\n\t\t"); |
161 | MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); | 162 | MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); |
@@ -333,6 +334,7 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv) | |||
333 | tveeprom_hauppauge_analog(&c, tv, eedata); | 334 | tveeprom_hauppauge_analog(&c, tv, eedata); |
334 | break; | 335 | break; |
335 | case CX18_CARD_YUAN_MPC718: | 336 | case CX18_CARD_YUAN_MPC718: |
337 | case CX18_CARD_GOTVIEW_PCI_DVD3: | ||
336 | tv->model = 0x718; | 338 | tv->model = 0x718; |
337 | cx18_eeprom_dump(cx, eedata, sizeof(eedata)); | 339 | cx18_eeprom_dump(cx, eedata, sizeof(eedata)); |
338 | CX18_INFO("eeprom PCI ID: %02x%02x:%02x%02x\n", | 340 | CX18_INFO("eeprom PCI ID: %02x%02x:%02x%02x\n", |
@@ -923,8 +925,13 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, | |||
923 | cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET, | 925 | cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET, |
924 | CX18_MEM_SIZE); | 926 | CX18_MEM_SIZE); |
925 | if (!cx->enc_mem) { | 927 | if (!cx->enc_mem) { |
926 | CX18_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n"); | 928 | CX18_ERR("ioremap failed. Can't get a window into CX23418 " |
927 | CX18_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n"); | 929 | "memory and register space\n"); |
930 | CX18_ERR("Each capture card with a CX23418 needs 64 MB of " | ||
931 | "vmalloc address space for the window\n"); | ||
932 | CX18_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n"); | ||
933 | CX18_ERR("Use the vmalloc= kernel command line option to set " | ||
934 | "VmallocTotal to a larger value\n"); | ||
928 | retval = -ENOMEM; | 935 | retval = -ENOMEM; |
929 | goto free_mem; | 936 | goto free_mem; |
930 | } | 937 | } |
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 77be58c1096b..f6f3e50d4bdf 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
@@ -84,7 +84,8 @@ | |||
84 | #define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/ | 84 | #define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/ |
85 | #define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */ | 85 | #define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */ |
86 | #define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */ | 86 | #define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */ |
87 | #define CX18_CARD_LAST 7 | 87 | #define CX18_CARD_GOTVIEW_PCI_DVD3 8 /* GoTView PCI DVD3 Hybrid */ |
88 | #define CX18_CARD_LAST 8 | ||
88 | 89 | ||
89 | #define CX18_ENC_STREAM_TYPE_MPG 0 | 90 | #define CX18_ENC_STREAM_TYPE_MPG 0 |
90 | #define CX18_ENC_STREAM_TYPE_TS 1 | 91 | #define CX18_ENC_STREAM_TYPE_TS 1 |
@@ -106,6 +107,7 @@ | |||
106 | #define CX18_PCI_ID_CONEXANT 0x14f1 | 107 | #define CX18_PCI_ID_CONEXANT 0x14f1 |
107 | #define CX18_PCI_ID_TOSHIBA 0x1179 | 108 | #define CX18_PCI_ID_TOSHIBA 0x1179 |
108 | #define CX18_PCI_ID_LEADTEK 0x107D | 109 | #define CX18_PCI_ID_LEADTEK 0x107D |
110 | #define CX18_PCI_ID_GOTVIEW 0x5854 | ||
109 | 111 | ||
110 | /* ======================================================================== */ | 112 | /* ======================================================================== */ |
111 | /* ========================== START USER SETTABLE DMA VARIABLES =========== */ | 113 | /* ========================== START USER SETTABLE DMA VARIABLES =========== */ |
@@ -323,7 +325,10 @@ struct cx18_queue { | |||
323 | spinlock_t lock; | 325 | spinlock_t lock; |
324 | }; | 326 | }; |
325 | 327 | ||
328 | struct cx18_stream; /* forward reference */ | ||
329 | |||
326 | struct cx18_dvb { | 330 | struct cx18_dvb { |
331 | struct cx18_stream *stream; | ||
327 | struct dmx_frontend hw_frontend; | 332 | struct dmx_frontend hw_frontend; |
328 | struct dmx_frontend mem_frontend; | 333 | struct dmx_frontend mem_frontend; |
329 | struct dmxdev dmxdev; | 334 | struct dmxdev dmxdev; |
@@ -363,9 +368,10 @@ struct cx18_in_work_order { | |||
363 | #define CX18_INVALID_TASK_HANDLE 0xffffffff | 368 | #define CX18_INVALID_TASK_HANDLE 0xffffffff |
364 | 369 | ||
365 | struct cx18_stream { | 370 | struct cx18_stream { |
366 | /* These first four fields are always set, even if the stream | 371 | /* These first five fields are always set, even if the stream |
367 | is not actually created. */ | 372 | is not actually created. */ |
368 | struct video_device *video_dev; /* NULL when stream not created */ | 373 | struct video_device *video_dev; /* NULL when stream not created */ |
374 | struct cx18_dvb *dvb; /* DVB / Digital Transport */ | ||
369 | struct cx18 *cx; /* for ease of use */ | 375 | struct cx18 *cx; /* for ease of use */ |
370 | const char *name; /* name of the stream */ | 376 | const char *name; /* name of the stream */ |
371 | int type; /* stream type */ | 377 | int type; /* stream type */ |
@@ -395,9 +401,6 @@ struct cx18_stream { | |||
395 | struct cx18_queue q_idle; /* idle - not in rotation */ | 401 | struct cx18_queue q_idle; /* idle - not in rotation */ |
396 | 402 | ||
397 | struct work_struct out_work_order; | 403 | struct work_struct out_work_order; |
398 | |||
399 | /* DVB / Digital Transport */ | ||
400 | struct cx18_dvb dvb; | ||
401 | }; | 404 | }; |
402 | 405 | ||
403 | struct cx18_open_id { | 406 | struct cx18_open_id { |
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index 6d19f040d70f..f0381d62518d 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c | |||
@@ -137,7 +137,7 @@ static int yuan_mpc718_mt352_init(struct dvb_frontend *fe) | |||
137 | { | 137 | { |
138 | struct cx18_dvb *dvb = container_of(fe->dvb, | 138 | struct cx18_dvb *dvb = container_of(fe->dvb, |
139 | struct cx18_dvb, dvb_adapter); | 139 | struct cx18_dvb, dvb_adapter); |
140 | struct cx18_stream *stream = container_of(dvb, struct cx18_stream, dvb); | 140 | struct cx18_stream *stream = dvb->stream; |
141 | const struct firmware *fw = NULL; | 141 | const struct firmware *fw = NULL; |
142 | int ret; | 142 | int ret; |
143 | int i; | 143 | int i; |
@@ -203,6 +203,14 @@ static struct zl10353_config yuan_mpc718_zl10353_demod = { | |||
203 | .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */ | 203 | .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */ |
204 | }; | 204 | }; |
205 | 205 | ||
206 | static struct zl10353_config gotview_dvd3_zl10353_demod = { | ||
207 | .demod_address = 0x1e >> 1, /* Datasheet suggested straps */ | ||
208 | .if2 = 45600, /* 4.560 MHz IF from the XC3028 */ | ||
209 | .parallel_ts = 1, /* Not a serial TS */ | ||
210 | .no_tuner = 1, /* XC3028 is not behind the gate */ | ||
211 | .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */ | ||
212 | }; | ||
213 | |||
206 | static int dvb_register(struct cx18_stream *stream); | 214 | static int dvb_register(struct cx18_stream *stream); |
207 | 215 | ||
208 | /* Kernel DVB framework calls this when the feed needs to start. | 216 | /* Kernel DVB framework calls this when the feed needs to start. |
@@ -247,6 +255,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) | |||
247 | 255 | ||
248 | case CX18_CARD_LEADTEK_DVR3100H: | 256 | case CX18_CARD_LEADTEK_DVR3100H: |
249 | case CX18_CARD_YUAN_MPC718: | 257 | case CX18_CARD_YUAN_MPC718: |
258 | case CX18_CARD_GOTVIEW_PCI_DVD3: | ||
250 | default: | 259 | default: |
251 | /* Assumption - Parallel transport - Signalling | 260 | /* Assumption - Parallel transport - Signalling |
252 | * undefined or default. | 261 | * undefined or default. |
@@ -257,22 +266,22 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) | |||
257 | if (!demux->dmx.frontend) | 266 | if (!demux->dmx.frontend) |
258 | return -EINVAL; | 267 | return -EINVAL; |
259 | 268 | ||
260 | mutex_lock(&stream->dvb.feedlock); | 269 | mutex_lock(&stream->dvb->feedlock); |
261 | if (stream->dvb.feeding++ == 0) { | 270 | if (stream->dvb->feeding++ == 0) { |
262 | CX18_DEBUG_INFO("Starting Transport DMA\n"); | 271 | CX18_DEBUG_INFO("Starting Transport DMA\n"); |
263 | mutex_lock(&cx->serialize_lock); | 272 | mutex_lock(&cx->serialize_lock); |
264 | set_bit(CX18_F_S_STREAMING, &stream->s_flags); | 273 | set_bit(CX18_F_S_STREAMING, &stream->s_flags); |
265 | ret = cx18_start_v4l2_encode_stream(stream); | 274 | ret = cx18_start_v4l2_encode_stream(stream); |
266 | if (ret < 0) { | 275 | if (ret < 0) { |
267 | CX18_DEBUG_INFO("Failed to start Transport DMA\n"); | 276 | CX18_DEBUG_INFO("Failed to start Transport DMA\n"); |
268 | stream->dvb.feeding--; | 277 | stream->dvb->feeding--; |
269 | if (stream->dvb.feeding == 0) | 278 | if (stream->dvb->feeding == 0) |
270 | clear_bit(CX18_F_S_STREAMING, &stream->s_flags); | 279 | clear_bit(CX18_F_S_STREAMING, &stream->s_flags); |
271 | } | 280 | } |
272 | mutex_unlock(&cx->serialize_lock); | 281 | mutex_unlock(&cx->serialize_lock); |
273 | } else | 282 | } else |
274 | ret = 0; | 283 | ret = 0; |
275 | mutex_unlock(&stream->dvb.feedlock); | 284 | mutex_unlock(&stream->dvb->feedlock); |
276 | 285 | ||
277 | return ret; | 286 | return ret; |
278 | } | 287 | } |
@@ -290,15 +299,15 @@ static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed) | |||
290 | CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n", | 299 | CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n", |
291 | feed->pid, feed->index); | 300 | feed->pid, feed->index); |
292 | 301 | ||
293 | mutex_lock(&stream->dvb.feedlock); | 302 | mutex_lock(&stream->dvb->feedlock); |
294 | if (--stream->dvb.feeding == 0) { | 303 | if (--stream->dvb->feeding == 0) { |
295 | CX18_DEBUG_INFO("Stopping Transport DMA\n"); | 304 | CX18_DEBUG_INFO("Stopping Transport DMA\n"); |
296 | mutex_lock(&cx->serialize_lock); | 305 | mutex_lock(&cx->serialize_lock); |
297 | ret = cx18_stop_v4l2_encode_stream(stream, 0); | 306 | ret = cx18_stop_v4l2_encode_stream(stream, 0); |
298 | mutex_unlock(&cx->serialize_lock); | 307 | mutex_unlock(&cx->serialize_lock); |
299 | } else | 308 | } else |
300 | ret = 0; | 309 | ret = 0; |
301 | mutex_unlock(&stream->dvb.feedlock); | 310 | mutex_unlock(&stream->dvb->feedlock); |
302 | } | 311 | } |
303 | 312 | ||
304 | return ret; | 313 | return ret; |
@@ -307,7 +316,7 @@ static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed) | |||
307 | int cx18_dvb_register(struct cx18_stream *stream) | 316 | int cx18_dvb_register(struct cx18_stream *stream) |
308 | { | 317 | { |
309 | struct cx18 *cx = stream->cx; | 318 | struct cx18 *cx = stream->cx; |
310 | struct cx18_dvb *dvb = &stream->dvb; | 319 | struct cx18_dvb *dvb = stream->dvb; |
311 | struct dvb_adapter *dvb_adapter; | 320 | struct dvb_adapter *dvb_adapter; |
312 | struct dvb_demux *dvbdemux; | 321 | struct dvb_demux *dvbdemux; |
313 | struct dmx_demux *dmx; | 322 | struct dmx_demux *dmx; |
@@ -316,6 +325,9 @@ int cx18_dvb_register(struct cx18_stream *stream) | |||
316 | if (!dvb) | 325 | if (!dvb) |
317 | return -EINVAL; | 326 | return -EINVAL; |
318 | 327 | ||
328 | dvb->enabled = 0; | ||
329 | dvb->stream = stream; | ||
330 | |||
319 | ret = dvb_register_adapter(&dvb->dvb_adapter, | 331 | ret = dvb_register_adapter(&dvb->dvb_adapter, |
320 | CX18_DRIVER_NAME, | 332 | CX18_DRIVER_NAME, |
321 | THIS_MODULE, &cx->pci_dev->dev, adapter_nr); | 333 | THIS_MODULE, &cx->pci_dev->dev, adapter_nr); |
@@ -369,7 +381,7 @@ int cx18_dvb_register(struct cx18_stream *stream) | |||
369 | 381 | ||
370 | CX18_INFO("DVB Frontend registered\n"); | 382 | CX18_INFO("DVB Frontend registered\n"); |
371 | CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n", | 383 | CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n", |
372 | stream->dvb.dvb_adapter.num, stream->name, | 384 | stream->dvb->dvb_adapter.num, stream->name, |
373 | stream->buffers, stream->buf_size/1024, | 385 | stream->buffers, stream->buf_size/1024, |
374 | (stream->buf_size * 100 / 1024) % 100); | 386 | (stream->buf_size * 100 / 1024) % 100); |
375 | 387 | ||
@@ -396,13 +408,16 @@ err_out: | |||
396 | void cx18_dvb_unregister(struct cx18_stream *stream) | 408 | void cx18_dvb_unregister(struct cx18_stream *stream) |
397 | { | 409 | { |
398 | struct cx18 *cx = stream->cx; | 410 | struct cx18 *cx = stream->cx; |
399 | struct cx18_dvb *dvb = &stream->dvb; | 411 | struct cx18_dvb *dvb = stream->dvb; |
400 | struct dvb_adapter *dvb_adapter; | 412 | struct dvb_adapter *dvb_adapter; |
401 | struct dvb_demux *dvbdemux; | 413 | struct dvb_demux *dvbdemux; |
402 | struct dmx_demux *dmx; | 414 | struct dmx_demux *dmx; |
403 | 415 | ||
404 | CX18_INFO("unregister DVB\n"); | 416 | CX18_INFO("unregister DVB\n"); |
405 | 417 | ||
418 | if (dvb == NULL || !dvb->enabled) | ||
419 | return; | ||
420 | |||
406 | dvb_adapter = &dvb->dvb_adapter; | 421 | dvb_adapter = &dvb->dvb_adapter; |
407 | dvbdemux = &dvb->demux; | 422 | dvbdemux = &dvb->demux; |
408 | dmx = &dvbdemux->dmx; | 423 | dmx = &dvbdemux->dmx; |
@@ -423,7 +438,7 @@ void cx18_dvb_unregister(struct cx18_stream *stream) | |||
423 | */ | 438 | */ |
424 | static int dvb_register(struct cx18_stream *stream) | 439 | static int dvb_register(struct cx18_stream *stream) |
425 | { | 440 | { |
426 | struct cx18_dvb *dvb = &stream->dvb; | 441 | struct cx18_dvb *dvb = stream->dvb; |
427 | struct cx18 *cx = stream->cx; | 442 | struct cx18 *cx = stream->cx; |
428 | int ret = 0; | 443 | int ret = 0; |
429 | 444 | ||
@@ -495,6 +510,29 @@ static int dvb_register(struct cx18_stream *stream) | |||
495 | fe->ops.tuner_ops.set_config(fe, &ctrl); | 510 | fe->ops.tuner_ops.set_config(fe, &ctrl); |
496 | } | 511 | } |
497 | break; | 512 | break; |
513 | case CX18_CARD_GOTVIEW_PCI_DVD3: | ||
514 | dvb->fe = dvb_attach(zl10353_attach, | ||
515 | &gotview_dvd3_zl10353_demod, | ||
516 | &cx->i2c_adap[1]); | ||
517 | if (dvb->fe != NULL) { | ||
518 | struct dvb_frontend *fe; | ||
519 | struct xc2028_config cfg = { | ||
520 | .i2c_adap = &cx->i2c_adap[1], | ||
521 | .i2c_addr = 0xc2 >> 1, | ||
522 | .ctrl = NULL, | ||
523 | }; | ||
524 | static struct xc2028_ctrl ctrl = { | ||
525 | .fname = XC2028_DEFAULT_FIRMWARE, | ||
526 | .max_len = 64, | ||
527 | .demod = XC3028_FE_ZARLINK456, | ||
528 | .type = XC2028_AUTO, | ||
529 | }; | ||
530 | |||
531 | fe = dvb_attach(xc2028_attach, dvb->fe, &cfg); | ||
532 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | ||
533 | fe->ops.tuner_ops.set_config(fe, &ctrl); | ||
534 | } | ||
535 | break; | ||
498 | default: | 536 | default: |
499 | /* No Digital Tv Support */ | 537 | /* No Digital Tv Support */ |
500 | break; | 538 | break; |
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index e71a026f3419..c330fb917b50 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c | |||
@@ -98,7 +98,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw, | |||
98 | case CX18_HW_Z8F0811_IR_RX_HAUP: | 98 | case CX18_HW_Z8F0811_IR_RX_HAUP: |
99 | init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; | 99 | init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; |
100 | init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; | 100 | init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; |
101 | init_data->type = IR_TYPE_RC5; | 101 | init_data->type = RC_TYPE_RC5; |
102 | init_data->name = cx->card_name; | 102 | init_data->name = cx->card_name; |
103 | info.platform_data = init_data; | 103 | info.platform_data = init_data; |
104 | break; | 104 | break; |
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index 956aa190ecca..c545f3beef78 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c | |||
@@ -136,7 +136,7 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl) | |||
136 | { | 136 | { |
137 | struct cx18_buffer *buf; | 137 | struct cx18_buffer *buf; |
138 | 138 | ||
139 | if (!s->dvb.enabled || mdl->bytesused == 0) | 139 | if (s->dvb == NULL || !s->dvb->enabled || mdl->bytesused == 0) |
140 | return; | 140 | return; |
141 | 141 | ||
142 | /* We ignore mdl and buf readpos accounting here - it doesn't matter */ | 142 | /* We ignore mdl and buf readpos accounting here - it doesn't matter */ |
@@ -146,7 +146,7 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl) | |||
146 | buf = list_first_entry(&mdl->buf_list, struct cx18_buffer, | 146 | buf = list_first_entry(&mdl->buf_list, struct cx18_buffer, |
147 | list); | 147 | list); |
148 | if (buf->bytesused) | 148 | if (buf->bytesused) |
149 | dvb_dmx_swfilter(&s->dvb.demux, | 149 | dvb_dmx_swfilter(&s->dvb->demux, |
150 | buf->buf, buf->bytesused); | 150 | buf->buf, buf->bytesused); |
151 | return; | 151 | return; |
152 | } | 152 | } |
@@ -154,7 +154,7 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl) | |||
154 | list_for_each_entry(buf, &mdl->buf_list, list) { | 154 | list_for_each_entry(buf, &mdl->buf_list, list) { |
155 | if (buf->bytesused == 0) | 155 | if (buf->bytesused == 0) |
156 | break; | 156 | break; |
157 | dvb_dmx_swfilter(&s->dvb.demux, buf->buf, buf->bytesused); | 157 | dvb_dmx_swfilter(&s->dvb->demux, buf->buf, buf->bytesused); |
158 | } | 158 | } |
159 | } | 159 | } |
160 | 160 | ||
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index ab461e27d9dd..94f5d7967c5c 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
@@ -107,6 +107,7 @@ static void cx18_stream_init(struct cx18 *cx, int type) | |||
107 | s->video_dev = video_dev; | 107 | s->video_dev = video_dev; |
108 | 108 | ||
109 | /* initialize cx18_stream fields */ | 109 | /* initialize cx18_stream fields */ |
110 | s->dvb = NULL; | ||
110 | s->cx = cx; | 111 | s->cx = cx; |
111 | s->type = type; | 112 | s->type = type; |
112 | s->name = cx18_stream_info[type].name; | 113 | s->name = cx18_stream_info[type].name; |
@@ -140,10 +141,15 @@ static int cx18_prep_dev(struct cx18 *cx, int type) | |||
140 | int num_offset = cx18_stream_info[type].num_offset; | 141 | int num_offset = cx18_stream_info[type].num_offset; |
141 | int num = cx->instance + cx18_first_minor + num_offset; | 142 | int num = cx->instance + cx18_first_minor + num_offset; |
142 | 143 | ||
143 | /* These four fields are always initialized. If video_dev == NULL, then | 144 | /* |
144 | this stream is not in use. In that case no other fields but these | 145 | * These five fields are always initialized. |
145 | four can be used. */ | 146 | * For analog capture related streams, if video_dev == NULL then the |
147 | * stream is not in use. | ||
148 | * For the TS stream, if dvb == NULL then the stream is not in use. | ||
149 | * In those cases no other fields but these four can be used. | ||
150 | */ | ||
146 | s->video_dev = NULL; | 151 | s->video_dev = NULL; |
152 | s->dvb = NULL; | ||
147 | s->cx = cx; | 153 | s->cx = cx; |
148 | s->type = type; | 154 | s->type = type; |
149 | s->name = cx18_stream_info[type].name; | 155 | s->name = cx18_stream_info[type].name; |
@@ -167,6 +173,21 @@ static int cx18_prep_dev(struct cx18 *cx, int type) | |||
167 | 173 | ||
168 | cx18_stream_init(cx, type); | 174 | cx18_stream_init(cx, type); |
169 | 175 | ||
176 | /* Allocate the cx18_dvb struct only for the TS on cards with DTV */ | ||
177 | if (type == CX18_ENC_STREAM_TYPE_TS) { | ||
178 | if (cx->card->hw_all & CX18_HW_DVB) { | ||
179 | s->dvb = kzalloc(sizeof(struct cx18_dvb), GFP_KERNEL); | ||
180 | if (s->dvb == NULL) { | ||
181 | CX18_ERR("Couldn't allocate cx18_dvb structure" | ||
182 | " for %s\n", s->name); | ||
183 | return -ENOMEM; | ||
184 | } | ||
185 | } else { | ||
186 | /* Don't need buffers for the TS, if there is no DVB */ | ||
187 | s->buffers = 0; | ||
188 | } | ||
189 | } | ||
190 | |||
170 | if (num_offset == -1) | 191 | if (num_offset == -1) |
171 | return 0; | 192 | return 0; |
172 | 193 | ||
@@ -222,13 +243,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type) | |||
222 | const char *name; | 243 | const char *name; |
223 | int num, ret; | 244 | int num, ret; |
224 | 245 | ||
225 | /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something? | 246 | if (type == CX18_ENC_STREAM_TYPE_TS && s->dvb != NULL) { |
226 | * We need a VFL_TYPE_TS defined. | ||
227 | */ | ||
228 | if (strcmp("TS", s->name) == 0) { | ||
229 | /* just return if no DVB is supported */ | ||
230 | if ((cx->card->hw_all & CX18_HW_DVB) == 0) | ||
231 | return 0; | ||
232 | ret = cx18_dvb_register(s); | 247 | ret = cx18_dvb_register(s); |
233 | if (ret < 0) { | 248 | if (ret < 0) { |
234 | CX18_ERR("DVB failed to register\n"); | 249 | CX18_ERR("DVB failed to register\n"); |
@@ -320,11 +335,13 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister) | |||
320 | /* Teardown all streams */ | 335 | /* Teardown all streams */ |
321 | for (type = 0; type < CX18_MAX_STREAMS; type++) { | 336 | for (type = 0; type < CX18_MAX_STREAMS; type++) { |
322 | 337 | ||
323 | /* No struct video_device, but can have buffers allocated */ | 338 | /* The TS has a cx18_dvb structure, not a video_device */ |
324 | if (type == CX18_ENC_STREAM_TYPE_TS) { | 339 | if (type == CX18_ENC_STREAM_TYPE_TS) { |
325 | if (cx->streams[type].dvb.enabled) { | 340 | if (cx->streams[type].dvb != NULL) { |
326 | cx18_dvb_unregister(&cx->streams[type]); | 341 | if (unregister) |
327 | cx->streams[type].dvb.enabled = false; | 342 | cx18_dvb_unregister(&cx->streams[type]); |
343 | kfree(cx->streams[type].dvb); | ||
344 | cx->streams[type].dvb = NULL; | ||
328 | cx18_stream_free(&cx->streams[type]); | 345 | cx18_stream_free(&cx->streams[type]); |
329 | } | 346 | } |
330 | continue; | 347 | continue; |
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h index 77412bee5963..51765eb12d39 100644 --- a/drivers/media/video/cx18/cx18-streams.h +++ b/drivers/media/video/cx18/cx18-streams.h | |||
@@ -33,7 +33,8 @@ void cx18_stream_rotate_idx_mdls(struct cx18 *cx); | |||
33 | 33 | ||
34 | static inline bool cx18_stream_enabled(struct cx18_stream *s) | 34 | static inline bool cx18_stream_enabled(struct cx18_stream *s) |
35 | { | 35 | { |
36 | return s->video_dev || s->dvb.enabled || | 36 | return s->video_dev || |
37 | (s->dvb && s->dvb->enabled) || | ||
37 | (s->type == CX18_ENC_STREAM_TYPE_IDX && | 38 | (s->type == CX18_ENC_STREAM_TYPE_IDX && |
38 | s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0); | 39 | s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0); |
39 | } | 40 | } |
diff --git a/drivers/media/video/cx231xx/Kconfig b/drivers/media/video/cx231xx/Kconfig index bb04914983fd..ae85a7a7bd73 100644 --- a/drivers/media/video/cx231xx/Kconfig +++ b/drivers/media/video/cx231xx/Kconfig | |||
@@ -1,9 +1,9 @@ | |||
1 | config VIDEO_CX231XX | 1 | config VIDEO_CX231XX |
2 | tristate "Conexant cx231xx USB video capture support" | 2 | tristate "Conexant cx231xx USB video capture support" |
3 | depends on VIDEO_DEV && I2C && INPUT | 3 | depends on VIDEO_DEV && I2C |
4 | select VIDEO_TUNER | 4 | select VIDEO_TUNER |
5 | select VIDEO_TVEEPROM | 5 | select VIDEO_TVEEPROM |
6 | depends on VIDEO_IR | 6 | depends on RC_CORE |
7 | select VIDEOBUF_VMALLOC | 7 | select VIDEOBUF_VMALLOC |
8 | select VIDEO_CX25840 | 8 | select VIDEO_CX25840 |
9 | select VIDEO_CX2341X | 9 | select VIDEO_CX2341X |
@@ -14,6 +14,19 @@ config VIDEO_CX231XX | |||
14 | To compile this driver as a module, choose M here: the | 14 | To compile this driver as a module, choose M here: the |
15 | module will be called cx231xx | 15 | module will be called cx231xx |
16 | 16 | ||
17 | config VIDEO_CX231XX_RC | ||
18 | bool "Conexant cx231xx Remote Controller additional support" | ||
19 | depends on RC_CORE | ||
20 | depends on VIDEO_CX231XX | ||
21 | default y | ||
22 | ---help--- | ||
23 | cx231xx hardware has a builtin RX/TX support. However, a few | ||
24 | designs opted to not use it, but, instead, some other hardware. | ||
25 | This module enables the usage of those other hardware, like the | ||
26 | ones used with ISDB-T boards. | ||
27 | |||
28 | On most cases, all you need for IR is mceusb module. | ||
29 | |||
17 | config VIDEO_CX231XX_ALSA | 30 | config VIDEO_CX231XX_ALSA |
18 | tristate "Conexant Cx231xx ALSA audio module" | 31 | tristate "Conexant Cx231xx ALSA audio module" |
19 | depends on VIDEO_CX231XX && SND | 32 | depends on VIDEO_CX231XX && SND |
@@ -30,6 +43,8 @@ config VIDEO_CX231XX_DVB | |||
30 | depends on VIDEO_CX231XX && DVB_CORE | 43 | depends on VIDEO_CX231XX && DVB_CORE |
31 | select VIDEOBUF_DVB | 44 | select VIDEOBUF_DVB |
32 | select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMISE | 45 | select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMISE |
46 | select MEDIA_TUNER_NXP18271 if !DVB_FE_CUSTOMISE | ||
47 | select DVB_MB86A20S if !DVB_FE_CUSTOMISE | ||
33 | 48 | ||
34 | ---help--- | 49 | ---help--- |
35 | This adds support for DVB cards based on the | 50 | This adds support for DVB cards based on the |
diff --git a/drivers/media/video/cx231xx/Makefile b/drivers/media/video/cx231xx/Makefile index a6bc4cc54677..2c2484355449 100644 --- a/drivers/media/video/cx231xx/Makefile +++ b/drivers/media/video/cx231xx/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | cx231xx-objs := cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o \ | 1 | cx231xx-y += cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o |
2 | cx231xx-avcore.o cx231xx-417.o cx231xx-pcb-cfg.o cx231xx-vbi.o | 2 | cx231xx-y += cx231xx-avcore.o cx231xx-417.o cx231xx-pcb-cfg.o cx231xx-vbi.o |
3 | cx231xx-$(CONFIG_VIDEO_CX231XX_RC) += cx231xx-input.o | ||
3 | 4 | ||
4 | cx231xx-alsa-objs := cx231xx-audio.o | 5 | cx231xx-alsa-objs := cx231xx-audio.o |
5 | 6 | ||
diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/video/cx231xx/cx231xx-417.c index 4c7cac3b6254..fc9526a5b746 100644 --- a/drivers/media/video/cx231xx/cx231xx-417.c +++ b/drivers/media/video/cx231xx/cx231xx-417.c | |||
@@ -940,14 +940,14 @@ static int cx231xx_load_firmware(struct cx231xx *dev) | |||
940 | u16 _buffer_size = 4096; | 940 | u16 _buffer_size = 4096; |
941 | u8 *p_buffer; | 941 | u8 *p_buffer; |
942 | 942 | ||
943 | p_current_fw = (u32 *)vmalloc(1884180*4); | 943 | p_current_fw = vmalloc(1884180 * 4); |
944 | p_fw = p_current_fw; | 944 | p_fw = p_current_fw; |
945 | if (p_current_fw == 0) { | 945 | if (p_current_fw == 0) { |
946 | dprintk(2, "FAIL!!!\n"); | 946 | dprintk(2, "FAIL!!!\n"); |
947 | return -1; | 947 | return -1; |
948 | } | 948 | } |
949 | 949 | ||
950 | p_buffer = (u8 *)vmalloc(4096); | 950 | p_buffer = vmalloc(4096); |
951 | if (p_buffer == 0) { | 951 | if (p_buffer == 0) { |
952 | dprintk(2, "FAIL!!!\n"); | 952 | dprintk(2, "FAIL!!!\n"); |
953 | return -1; | 953 | return -1; |
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c index cf50fafa8abb..c53e97295a0d 100644 --- a/drivers/media/video/cx231xx/cx231xx-avcore.c +++ b/drivers/media/video/cx231xx/cx231xx-avcore.c | |||
@@ -274,7 +274,7 @@ int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux) | |||
274 | 274 | ||
275 | if (ch1_setting != 0) { | 275 | if (ch1_setting != 0) { |
276 | status = afe_read_byte(dev, ADC_INPUT_CH1, &value); | 276 | status = afe_read_byte(dev, ADC_INPUT_CH1, &value); |
277 | value &= (!INPUT_SEL_MASK); | 277 | value &= ~INPUT_SEL_MASK; |
278 | value |= (ch1_setting - 1) << 4; | 278 | value |= (ch1_setting - 1) << 4; |
279 | value &= 0xff; | 279 | value &= 0xff; |
280 | status = afe_write_byte(dev, ADC_INPUT_CH1, value); | 280 | status = afe_write_byte(dev, ADC_INPUT_CH1, value); |
@@ -282,7 +282,7 @@ int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux) | |||
282 | 282 | ||
283 | if (ch2_setting != 0) { | 283 | if (ch2_setting != 0) { |
284 | status = afe_read_byte(dev, ADC_INPUT_CH2, &value); | 284 | status = afe_read_byte(dev, ADC_INPUT_CH2, &value); |
285 | value &= (!INPUT_SEL_MASK); | 285 | value &= ~INPUT_SEL_MASK; |
286 | value |= (ch2_setting - 1) << 4; | 286 | value |= (ch2_setting - 1) << 4; |
287 | value &= 0xff; | 287 | value &= 0xff; |
288 | status = afe_write_byte(dev, ADC_INPUT_CH2, value); | 288 | status = afe_write_byte(dev, ADC_INPUT_CH2, value); |
@@ -292,7 +292,7 @@ int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux) | |||
292 | 7 less than the input number */ | 292 | 7 less than the input number */ |
293 | if (ch3_setting != 0) { | 293 | if (ch3_setting != 0) { |
294 | status = afe_read_byte(dev, ADC_INPUT_CH3, &value); | 294 | status = afe_read_byte(dev, ADC_INPUT_CH3, &value); |
295 | value &= (!INPUT_SEL_MASK); | 295 | value &= ~INPUT_SEL_MASK; |
296 | value |= (ch3_setting - 1) << 4; | 296 | value |= (ch3_setting - 1) << 4; |
297 | value &= 0xff; | 297 | value &= 0xff; |
298 | status = afe_write_byte(dev, ADC_INPUT_CH3, value); | 298 | status = afe_write_byte(dev, ADC_INPUT_CH3, value); |
@@ -354,6 +354,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, | |||
354 | case CX231XX_BOARD_CNXT_VIDEO_GRABBER: | 354 | case CX231XX_BOARD_CNXT_VIDEO_GRABBER: |
355 | case CX231XX_BOARD_HAUPPAUGE_EXETER: | 355 | case CX231XX_BOARD_HAUPPAUGE_EXETER: |
356 | case CX231XX_BOARD_HAUPPAUGE_USBLIVE2: | 356 | case CX231XX_BOARD_HAUPPAUGE_USBLIVE2: |
357 | case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: | ||
357 | if (avmode == POLARIS_AVMODE_ANALOGT_TV) { | 358 | if (avmode == POLARIS_AVMODE_ANALOGT_TV) { |
358 | while (afe_power_status != (FLD_PWRDN_TUNING_BIAS | | 359 | while (afe_power_status != (FLD_PWRDN_TUNING_BIAS | |
359 | FLD_PWRDN_ENABLE_PLL)) { | 360 | FLD_PWRDN_ENABLE_PLL)) { |
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index 2c78d188bb06..6905607ffca3 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <media/cx25840.h> | 34 | #include <media/cx25840.h> |
35 | #include "dvb-usb-ids.h" | 35 | #include "dvb-usb-ids.h" |
36 | #include "xc5000.h" | 36 | #include "xc5000.h" |
37 | #include "tda18271.h" | ||
37 | 38 | ||
38 | #include "cx231xx.h" | 39 | #include "cx231xx.h" |
39 | 40 | ||
@@ -395,6 +396,45 @@ struct cx231xx_board cx231xx_boards[] = { | |||
395 | .gpio = 0, | 396 | .gpio = 0, |
396 | } }, | 397 | } }, |
397 | }, | 398 | }, |
399 | [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = { | ||
400 | .name = "Pixelview PlayTV USB Hybrid", | ||
401 | .tuner_type = TUNER_NXP_TDA18271, | ||
402 | .tuner_addr = 0x60, | ||
403 | .decoder = CX231XX_AVDECODER, | ||
404 | .output_mode = OUT_MODE_VIP11, | ||
405 | .demod_xfer_mode = 0, | ||
406 | .ctl_pin_status_mask = 0xFFFFFFC4, | ||
407 | .agc_analog_digital_select_gpio = 0x00, /* According with PV cxPolaris.inf file */ | ||
408 | .tuner_sif_gpio = -1, | ||
409 | .tuner_scl_gpio = -1, | ||
410 | .tuner_sda_gpio = -1, | ||
411 | .gpio_pin_status_mask = 0x4001000, | ||
412 | .tuner_i2c_master = 2, | ||
413 | .demod_i2c_master = 1, | ||
414 | .ir_i2c_master = 2, | ||
415 | .rc_map_name = RC_MAP_PIXELVIEW_002T, | ||
416 | .has_dvb = 1, | ||
417 | .demod_addr = 0x10, | ||
418 | .norm = V4L2_STD_PAL_M, | ||
419 | .input = {{ | ||
420 | .type = CX231XX_VMUX_TELEVISION, | ||
421 | .vmux = CX231XX_VIN_3_1, | ||
422 | .amux = CX231XX_AMUX_VIDEO, | ||
423 | .gpio = 0, | ||
424 | }, { | ||
425 | .type = CX231XX_VMUX_COMPOSITE1, | ||
426 | .vmux = CX231XX_VIN_2_1, | ||
427 | .amux = CX231XX_AMUX_LINE_IN, | ||
428 | .gpio = 0, | ||
429 | }, { | ||
430 | .type = CX231XX_VMUX_SVIDEO, | ||
431 | .vmux = CX231XX_VIN_1_1 | | ||
432 | (CX231XX_VIN_1_2 << 8) | | ||
433 | CX25840_SVIDEO_ON, | ||
434 | .amux = CX231XX_AMUX_LINE_IN, | ||
435 | .gpio = 0, | ||
436 | } }, | ||
437 | }, | ||
398 | }; | 438 | }; |
399 | const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); | 439 | const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); |
400 | 440 | ||
@@ -402,8 +442,6 @@ const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); | |||
402 | struct usb_device_id cx231xx_id_table[] = { | 442 | struct usb_device_id cx231xx_id_table[] = { |
403 | {USB_DEVICE(0x0572, 0x5A3C), | 443 | {USB_DEVICE(0x0572, 0x5A3C), |
404 | .driver_info = CX231XX_BOARD_UNKNOWN}, | 444 | .driver_info = CX231XX_BOARD_UNKNOWN}, |
405 | {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff), | ||
406 | .driver_info = CX231XX_BOARD_UNKNOWN}, | ||
407 | {USB_DEVICE(0x0572, 0x58A2), | 445 | {USB_DEVICE(0x0572, 0x58A2), |
408 | .driver_info = CX231XX_BOARD_CNXT_CARRAERA}, | 446 | .driver_info = CX231XX_BOARD_CNXT_CARRAERA}, |
409 | {USB_DEVICE(0x0572, 0x58A1), | 447 | {USB_DEVICE(0x0572, 0x58A1), |
@@ -424,6 +462,8 @@ struct usb_device_id cx231xx_id_table[] = { | |||
424 | .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, | 462 | .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, |
425 | {USB_DEVICE(0x2040, 0xc200), | 463 | {USB_DEVICE(0x2040, 0xc200), |
426 | .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2}, | 464 | .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2}, |
465 | {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001), | ||
466 | .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID}, | ||
427 | {}, | 467 | {}, |
428 | }; | 468 | }; |
429 | 469 | ||
@@ -453,6 +493,16 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg) | |||
453 | 1); | 493 | 1); |
454 | msleep(10); | 494 | msleep(10); |
455 | } | 495 | } |
496 | } else if (dev->tuner_type == TUNER_NXP_TDA18271) { | ||
497 | switch (command) { | ||
498 | case TDA18271_CALLBACK_CMD_AGC_ENABLE: | ||
499 | if (dev->model == CX231XX_BOARD_PV_PLAYTV_USB_HYBRID) | ||
500 | rc = cx231xx_set_agc_analog_digital_mux_select(dev, arg); | ||
501 | break; | ||
502 | default: | ||
503 | rc = -EINVAL; | ||
504 | break; | ||
505 | } | ||
456 | } | 506 | } |
457 | return rc; | 507 | return rc; |
458 | } | 508 | } |
@@ -615,8 +665,11 @@ void cx231xx_release_resources(struct cx231xx *dev) | |||
615 | 665 | ||
616 | cx231xx_remove_from_devlist(dev); | 666 | cx231xx_remove_from_devlist(dev); |
617 | 667 | ||
668 | /* Release I2C buses */ | ||
618 | cx231xx_dev_uninit(dev); | 669 | cx231xx_dev_uninit(dev); |
619 | 670 | ||
671 | cx231xx_ir_exit(dev); | ||
672 | |||
620 | usb_put_dev(dev->udev); | 673 | usb_put_dev(dev->udev); |
621 | 674 | ||
622 | /* Mark device as unused */ | 675 | /* Mark device as unused */ |
@@ -731,16 +784,14 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, | |||
731 | retval = cx231xx_register_analog_devices(dev); | 784 | retval = cx231xx_register_analog_devices(dev); |
732 | if (retval < 0) { | 785 | if (retval < 0) { |
733 | cx231xx_release_resources(dev); | 786 | cx231xx_release_resources(dev); |
734 | goto fail_reg_devices; | 787 | return retval; |
735 | } | 788 | } |
736 | 789 | ||
790 | cx231xx_ir_init(dev); | ||
791 | |||
737 | cx231xx_init_extension(dev); | 792 | cx231xx_init_extension(dev); |
738 | 793 | ||
739 | return 0; | 794 | return 0; |
740 | |||
741 | fail_reg_devices: | ||
742 | mutex_unlock(&dev->lock); | ||
743 | return retval; | ||
744 | } | 795 | } |
745 | 796 | ||
746 | #if defined(CONFIG_MODULES) && defined(MODULE) | 797 | #if defined(CONFIG_MODULES) && defined(MODULE) |
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c index 4af46fca9b0a..7d62d58617f5 100644 --- a/drivers/media/video/cx231xx/cx231xx-core.c +++ b/drivers/media/video/cx231xx/cx231xx-core.c | |||
@@ -740,6 +740,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode) | |||
740 | case CX231XX_BOARD_CNXT_RDE_253S: | 740 | case CX231XX_BOARD_CNXT_RDE_253S: |
741 | case CX231XX_BOARD_CNXT_RDU_253S: | 741 | case CX231XX_BOARD_CNXT_RDU_253S: |
742 | case CX231XX_BOARD_HAUPPAUGE_EXETER: | 742 | case CX231XX_BOARD_HAUPPAUGE_EXETER: |
743 | case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: | ||
743 | errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0); | 744 | errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0); |
744 | break; | 745 | break; |
745 | default: | 746 | default: |
@@ -1288,7 +1289,7 @@ int cx231xx_dev_init(struct cx231xx *dev) | |||
1288 | /* Internal Master 3 Bus */ | 1289 | /* Internal Master 3 Bus */ |
1289 | dev->i2c_bus[2].nr = 2; | 1290 | dev->i2c_bus[2].nr = 2; |
1290 | dev->i2c_bus[2].dev = dev; | 1291 | dev->i2c_bus[2].dev = dev; |
1291 | dev->i2c_bus[2].i2c_period = I2C_SPEED_400K; /* 400kHz */ | 1292 | dev->i2c_bus[2].i2c_period = I2C_SPEED_100K; /* 100kHz */ |
1292 | dev->i2c_bus[2].i2c_nostop = 0; | 1293 | dev->i2c_bus[2].i2c_nostop = 0; |
1293 | dev->i2c_bus[2].i2c_reserve = 0; | 1294 | dev->i2c_bus[2].i2c_reserve = 0; |
1294 | 1295 | ||
@@ -1381,6 +1382,7 @@ int cx231xx_dev_init(struct cx231xx *dev) | |||
1381 | case CX231XX_BOARD_CNXT_RDE_253S: | 1382 | case CX231XX_BOARD_CNXT_RDE_253S: |
1382 | case CX231XX_BOARD_CNXT_RDU_253S: | 1383 | case CX231XX_BOARD_CNXT_RDU_253S: |
1383 | case CX231XX_BOARD_HAUPPAUGE_EXETER: | 1384 | case CX231XX_BOARD_HAUPPAUGE_EXETER: |
1385 | case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: | ||
1384 | errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0); | 1386 | errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0); |
1385 | break; | 1387 | break; |
1386 | default: | 1388 | default: |
@@ -1513,7 +1515,7 @@ int cx231xx_read_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr, | |||
1513 | 1515 | ||
1514 | if (saddr_len == 0) | 1516 | if (saddr_len == 0) |
1515 | saddr = 0; | 1517 | saddr = 0; |
1516 | else if (saddr_len == 0) | 1518 | else if (saddr_len == 1) |
1517 | saddr &= 0xff; | 1519 | saddr &= 0xff; |
1518 | 1520 | ||
1519 | /* prepare xfer_data struct */ | 1521 | /* prepare xfer_data struct */ |
@@ -1564,7 +1566,7 @@ int cx231xx_write_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr, | |||
1564 | 1566 | ||
1565 | if (saddr_len == 0) | 1567 | if (saddr_len == 0) |
1566 | saddr = 0; | 1568 | saddr = 0; |
1567 | else if (saddr_len == 0) | 1569 | else if (saddr_len == 1) |
1568 | saddr &= 0xff; | 1570 | saddr &= 0xff; |
1569 | 1571 | ||
1570 | /* prepare xfer_data struct */ | 1572 | /* prepare xfer_data struct */ |
@@ -1598,7 +1600,7 @@ int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr, | |||
1598 | 1600 | ||
1599 | if (saddr_len == 0) | 1601 | if (saddr_len == 0) |
1600 | saddr = 0; | 1602 | saddr = 0; |
1601 | else if (saddr_len == 0) | 1603 | else if (saddr_len == 1) |
1602 | saddr &= 0xff; | 1604 | saddr &= 0xff; |
1603 | 1605 | ||
1604 | /* prepare xfer_data struct */ | 1606 | /* prepare xfer_data struct */ |
@@ -1639,7 +1641,7 @@ int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr, | |||
1639 | 1641 | ||
1640 | if (saddr_len == 0) | 1642 | if (saddr_len == 0) |
1641 | saddr = 0; | 1643 | saddr = 0; |
1642 | else if (saddr_len == 0) | 1644 | else if (saddr_len == 1) |
1643 | saddr &= 0xff; | 1645 | saddr &= 0xff; |
1644 | 1646 | ||
1645 | /* prepare xfer_data struct */ | 1647 | /* prepare xfer_data struct */ |
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c index 5feb3ee640d9..fe59a1c3f064 100644 --- a/drivers/media/video/cx231xx/cx231xx-dvb.c +++ b/drivers/media/video/cx231xx/cx231xx-dvb.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "tda18271.h" | 33 | #include "tda18271.h" |
34 | #include "s5h1411.h" | 34 | #include "s5h1411.h" |
35 | #include "lgdt3305.h" | 35 | #include "lgdt3305.h" |
36 | #include "mb86a20s.h" | ||
36 | 37 | ||
37 | MODULE_DESCRIPTION("driver for cx231xx based DVB cards"); | 38 | MODULE_DESCRIPTION("driver for cx231xx based DVB cards"); |
38 | MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>"); | 39 | MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>"); |
@@ -88,6 +89,11 @@ static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = { | |||
88 | .if_lvl = 1, .rfagc_top = 0x37, }, | 89 | .if_lvl = 1, .rfagc_top = 0x37, }, |
89 | }; | 90 | }; |
90 | 91 | ||
92 | static struct tda18271_std_map mb86a20s_tda18271_config = { | ||
93 | .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4, | ||
94 | .if_lvl = 7, .rfagc_top = 0x37, }, | ||
95 | }; | ||
96 | |||
91 | static struct tda18271_config cnxt_rde253s_tunerconfig = { | 97 | static struct tda18271_config cnxt_rde253s_tunerconfig = { |
92 | .std_map = &cnxt_rde253s_tda18271_std_map, | 98 | .std_map = &cnxt_rde253s_tda18271_std_map, |
93 | .gate = TDA18271_GATE_ANALOG, | 99 | .gate = TDA18271_GATE_ANALOG, |
@@ -135,6 +141,17 @@ static struct tda18271_config hcw_tda18271_config = { | |||
135 | .gate = TDA18271_GATE_DIGITAL, | 141 | .gate = TDA18271_GATE_DIGITAL, |
136 | }; | 142 | }; |
137 | 143 | ||
144 | static const struct mb86a20s_config pv_mb86a20s_config = { | ||
145 | .demod_address = 0x10, | ||
146 | .is_serial = true, | ||
147 | }; | ||
148 | |||
149 | static struct tda18271_config pv_tda18271_config = { | ||
150 | .std_map = &mb86a20s_tda18271_config, | ||
151 | .gate = TDA18271_GATE_DIGITAL, | ||
152 | .small_i2c = TDA18271_03_BYTE_CHUNK_INIT, | ||
153 | }; | ||
154 | |||
138 | static inline void print_err_status(struct cx231xx *dev, int packet, int status) | 155 | static inline void print_err_status(struct cx231xx *dev, int packet, int status) |
139 | { | 156 | { |
140 | char *errmsg = "Unknown"; | 157 | char *errmsg = "Unknown"; |
@@ -687,6 +704,29 @@ static int dvb_init(struct cx231xx *dev) | |||
687 | &hcw_tda18271_config); | 704 | &hcw_tda18271_config); |
688 | break; | 705 | break; |
689 | 706 | ||
707 | case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: | ||
708 | |||
709 | printk(KERN_INFO "%s: looking for demod on i2c bus: %d\n", | ||
710 | __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap)); | ||
711 | |||
712 | dev->dvb->frontend = dvb_attach(mb86a20s_attach, | ||
713 | &pv_mb86a20s_config, | ||
714 | &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); | ||
715 | |||
716 | if (dev->dvb->frontend == NULL) { | ||
717 | printk(DRIVER_NAME | ||
718 | ": Failed to attach mb86a20s demod\n"); | ||
719 | result = -EINVAL; | ||
720 | goto out_free; | ||
721 | } | ||
722 | |||
723 | /* define general-purpose callback pointer */ | ||
724 | dvb->frontend->callback = cx231xx_tuner_callback; | ||
725 | |||
726 | dvb_attach(tda18271_attach, dev->dvb->frontend, | ||
727 | 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, | ||
728 | &pv_tda18271_config); | ||
729 | break; | ||
690 | 730 | ||
691 | default: | 731 | default: |
692 | printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" | 732 | printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" |
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c new file mode 100644 index 000000000000..45e14cac4622 --- /dev/null +++ b/drivers/media/video/cx231xx/cx231xx-input.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * cx231xx IR glue driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com> | ||
5 | * | ||
6 | * Polaris (cx231xx) has its support for IR's with a design close to MCE. | ||
7 | * however, a few designs are using an external I2C chip for IR, instead | ||
8 | * of using the one provided by the chip. | ||
9 | * This driver provides support for those extra devices | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License as | ||
13 | * published by the Free Software Foundation version 2. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | * General Public License for more details. | ||
19 | */ | ||
20 | |||
21 | #include "cx231xx.h" | ||
22 | #include <linux/usb.h> | ||
23 | #include <linux/slab.h> | ||
24 | |||
25 | #define MODULE_NAME "cx231xx-input" | ||
26 | |||
27 | static int get_key_isdbt(struct IR_i2c *ir, u32 *ir_key, | ||
28 | u32 *ir_raw) | ||
29 | { | ||
30 | u8 cmd, scancode; | ||
31 | |||
32 | dev_dbg(&ir->rc->input_dev->dev, "%s\n", __func__); | ||
33 | |||
34 | /* poll IR chip */ | ||
35 | if (1 != i2c_master_recv(ir->c, &cmd, 1)) | ||
36 | return -EIO; | ||
37 | |||
38 | /* it seems that 0xFE indicates that a button is still hold | ||
39 | down, while 0xff indicates that no button is hold | ||
40 | down. 0xfe sequences are sometimes interrupted by 0xFF */ | ||
41 | |||
42 | if (cmd == 0xff) | ||
43 | return 0; | ||
44 | |||
45 | scancode = | ||
46 | ((cmd & 0x01) ? 0x80 : 0) | | ||
47 | ((cmd & 0x02) ? 0x40 : 0) | | ||
48 | ((cmd & 0x04) ? 0x20 : 0) | | ||
49 | ((cmd & 0x08) ? 0x10 : 0) | | ||
50 | ((cmd & 0x10) ? 0x08 : 0) | | ||
51 | ((cmd & 0x20) ? 0x04 : 0) | | ||
52 | ((cmd & 0x40) ? 0x02 : 0) | | ||
53 | ((cmd & 0x80) ? 0x01 : 0); | ||
54 | |||
55 | dev_dbg(&ir->rc->input_dev->dev, "cmd %02x, scan = %02x\n", | ||
56 | cmd, scancode); | ||
57 | |||
58 | *ir_key = scancode; | ||
59 | *ir_raw = scancode; | ||
60 | return 1; | ||
61 | } | ||
62 | |||
63 | int cx231xx_ir_init(struct cx231xx *dev) | ||
64 | { | ||
65 | struct i2c_board_info info; | ||
66 | u8 ir_i2c_bus; | ||
67 | |||
68 | dev_dbg(&dev->udev->dev, "%s\n", __func__); | ||
69 | |||
70 | /* Only initialize if a rc keycode map is defined */ | ||
71 | if (!cx231xx_boards[dev->model].rc_map_name) | ||
72 | return -ENODEV; | ||
73 | |||
74 | request_module("ir-kbd-i2c"); | ||
75 | |||
76 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
77 | memset(&dev->init_data, 0, sizeof(dev->init_data)); | ||
78 | dev->init_data.rc_dev = rc_allocate_device(); | ||
79 | if (!dev->init_data.rc_dev) | ||
80 | return -ENOMEM; | ||
81 | |||
82 | dev->init_data.name = cx231xx_boards[dev->model].name; | ||
83 | |||
84 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
85 | info.platform_data = &dev->init_data; | ||
86 | |||
87 | /* | ||
88 | * Board-dependent values | ||
89 | * | ||
90 | * For now, there's just one type of hardware design using | ||
91 | * an i2c device. | ||
92 | */ | ||
93 | dev->init_data.get_key = get_key_isdbt; | ||
94 | dev->init_data.ir_codes = cx231xx_boards[dev->model].rc_map_name; | ||
95 | /* The i2c micro-controller only outputs the cmd part of NEC protocol */ | ||
96 | dev->init_data.rc_dev->scanmask = 0xff; | ||
97 | dev->init_data.rc_dev->driver_name = "cx231xx"; | ||
98 | dev->init_data.type = RC_TYPE_NEC; | ||
99 | info.addr = 0x30; | ||
100 | |||
101 | /* Load and bind ir-kbd-i2c */ | ||
102 | ir_i2c_bus = cx231xx_boards[dev->model].ir_i2c_master; | ||
103 | dev_dbg(&dev->udev->dev, "Trying to bind ir at bus %d, addr 0x%02x\n", | ||
104 | ir_i2c_bus, info.addr); | ||
105 | i2c_new_device(&dev->i2c_bus[ir_i2c_bus].i2c_adap, &info); | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | void cx231xx_ir_exit(struct cx231xx *dev) | ||
111 | { | ||
112 | } | ||
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c index b13b69fb2af6..7e3e8c4f19b7 100644 --- a/drivers/media/video/cx231xx/cx231xx-video.c +++ b/drivers/media/video/cx231xx/cx231xx-video.c | |||
@@ -2044,15 +2044,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) | |||
2044 | return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); | 2044 | return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); |
2045 | } | 2045 | } |
2046 | 2046 | ||
2047 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
2048 | static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | ||
2049 | { | ||
2050 | struct cx231xx_fh *fh = priv; | ||
2051 | |||
2052 | return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); | ||
2053 | } | ||
2054 | #endif | ||
2055 | |||
2056 | /* ----------------------------------------------------------- */ | 2047 | /* ----------------------------------------------------------- */ |
2057 | /* RADIO ESPECIFIC IOCTLS */ | 2048 | /* RADIO ESPECIFIC IOCTLS */ |
2058 | /* ----------------------------------------------------------- */ | 2049 | /* ----------------------------------------------------------- */ |
@@ -2507,9 +2498,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
2507 | .vidioc_g_register = vidioc_g_register, | 2498 | .vidioc_g_register = vidioc_g_register, |
2508 | .vidioc_s_register = vidioc_s_register, | 2499 | .vidioc_s_register = vidioc_s_register, |
2509 | #endif | 2500 | #endif |
2510 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
2511 | .vidiocgmbuf = vidiocgmbuf, | ||
2512 | #endif | ||
2513 | }; | 2501 | }; |
2514 | 2502 | ||
2515 | static struct video_device cx231xx_vbi_template; | 2503 | static struct video_device cx231xx_vbi_template; |
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h index d067df9b81e7..72bbea2bcd56 100644 --- a/drivers/media/video/cx231xx/cx231xx.h +++ b/drivers/media/video/cx231xx/cx231xx.h | |||
@@ -34,7 +34,8 @@ | |||
34 | 34 | ||
35 | #include <media/videobuf-vmalloc.h> | 35 | #include <media/videobuf-vmalloc.h> |
36 | #include <media/v4l2-device.h> | 36 | #include <media/v4l2-device.h> |
37 | #include <media/ir-core.h> | 37 | #include <media/rc-core.h> |
38 | #include <media/ir-kbd-i2c.h> | ||
38 | #include <media/videobuf-dvb.h> | 39 | #include <media/videobuf-dvb.h> |
39 | 40 | ||
40 | #include "cx231xx-reg.h" | 41 | #include "cx231xx-reg.h" |
@@ -62,6 +63,7 @@ | |||
62 | #define CX231XX_BOARD_CNXT_RDU_250 7 | 63 | #define CX231XX_BOARD_CNXT_RDU_250 7 |
63 | #define CX231XX_BOARD_HAUPPAUGE_EXETER 8 | 64 | #define CX231XX_BOARD_HAUPPAUGE_EXETER 8 |
64 | #define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9 | 65 | #define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9 |
66 | #define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10 | ||
65 | 67 | ||
66 | /* Limits minimum and default number of buffers */ | 68 | /* Limits minimum and default number of buffers */ |
67 | #define CX231XX_MIN_BUF 4 | 69 | #define CX231XX_MIN_BUF 4 |
@@ -344,6 +346,10 @@ struct cx231xx_board { | |||
344 | /* i2c masters */ | 346 | /* i2c masters */ |
345 | u8 tuner_i2c_master; | 347 | u8 tuner_i2c_master; |
346 | u8 demod_i2c_master; | 348 | u8 demod_i2c_master; |
349 | u8 ir_i2c_master; | ||
350 | |||
351 | /* for devices with I2C chips for IR */ | ||
352 | char *rc_map_name; | ||
347 | 353 | ||
348 | unsigned int max_range_640_480:1; | 354 | unsigned int max_range_640_480:1; |
349 | unsigned int has_dvb:1; | 355 | unsigned int has_dvb:1; |
@@ -356,7 +362,7 @@ struct cx231xx_board { | |||
356 | 362 | ||
357 | struct cx231xx_input input[MAX_CX231XX_INPUT]; | 363 | struct cx231xx_input input[MAX_CX231XX_INPUT]; |
358 | struct cx231xx_input radio; | 364 | struct cx231xx_input radio; |
359 | struct ir_scancode_table *ir_codes; | 365 | struct rc_map *ir_codes; |
360 | }; | 366 | }; |
361 | 367 | ||
362 | /* device states */ | 368 | /* device states */ |
@@ -605,6 +611,9 @@ struct cx231xx { | |||
605 | 611 | ||
606 | struct cx231xx_board board; | 612 | struct cx231xx_board board; |
607 | 613 | ||
614 | /* For I2C IR support */ | ||
615 | struct IR_i2c_init_data init_data; | ||
616 | |||
608 | unsigned int stream_on:1; /* Locks streams */ | 617 | unsigned int stream_on:1; /* Locks streams */ |
609 | unsigned int vbi_stream_on:1; /* Locks streams for VBI */ | 618 | unsigned int vbi_stream_on:1; /* Locks streams for VBI */ |
610 | unsigned int has_audio_class:1; | 619 | unsigned int has_audio_class:1; |
@@ -616,8 +625,6 @@ struct cx231xx { | |||
616 | struct v4l2_subdev *sd_cx25840; | 625 | struct v4l2_subdev *sd_cx25840; |
617 | struct v4l2_subdev *sd_tuner; | 626 | struct v4l2_subdev *sd_tuner; |
618 | 627 | ||
619 | struct cx231xx_IR *ir; | ||
620 | |||
621 | struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ | 628 | struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ |
622 | atomic_t stream_started; /* stream should be running if true */ | 629 | atomic_t stream_started; /* stream should be running if true */ |
623 | 630 | ||
@@ -954,6 +961,17 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg); | |||
954 | extern int cx231xx_417_register(struct cx231xx *dev); | 961 | extern int cx231xx_417_register(struct cx231xx *dev); |
955 | extern void cx231xx_417_unregister(struct cx231xx *dev); | 962 | extern void cx231xx_417_unregister(struct cx231xx *dev); |
956 | 963 | ||
964 | /* cx23885-input.c */ | ||
965 | |||
966 | #if defined(CONFIG_VIDEO_CX231XX_RC) | ||
967 | int cx231xx_ir_init(struct cx231xx *dev); | ||
968 | void cx231xx_ir_exit(struct cx231xx *dev); | ||
969 | #else | ||
970 | #define cx231xx_ir_init(dev) (0) | ||
971 | #define cx231xx_ir_exit(dev) (0) | ||
972 | #endif | ||
973 | |||
974 | |||
957 | /* printk macros */ | 975 | /* printk macros */ |
958 | 976 | ||
959 | #define cx231xx_err(fmt, arg...) do {\ | 977 | #define cx231xx_err(fmt, arg...) do {\ |
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c index e5c3c8da4be3..103ef6bad2e2 100644 --- a/drivers/media/video/cx2341x.c +++ b/drivers/media/video/cx2341x.c | |||
@@ -853,9 +853,9 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, | |||
853 | } | 853 | } |
854 | EXPORT_SYMBOL(cx2341x_ctrl_query); | 854 | EXPORT_SYMBOL(cx2341x_ctrl_query); |
855 | 855 | ||
856 | const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id) | 856 | const char * const *cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id) |
857 | { | 857 | { |
858 | static const char *mpeg_stream_type_without_ts[] = { | 858 | static const char * const mpeg_stream_type_without_ts[] = { |
859 | "MPEG-2 Program Stream", | 859 | "MPEG-2 Program Stream", |
860 | "", | 860 | "", |
861 | "MPEG-1 System Stream", | 861 | "MPEG-1 System Stream", |
@@ -952,7 +952,7 @@ int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy, | |||
952 | for (i = 0; i < ctrls->count; i++) { | 952 | for (i = 0; i < ctrls->count; i++) { |
953 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | 953 | struct v4l2_ext_control *ctrl = ctrls->controls + i; |
954 | struct v4l2_queryctrl qctrl; | 954 | struct v4l2_queryctrl qctrl; |
955 | const char **menu_items = NULL; | 955 | const char * const *menu_items = NULL; |
956 | 956 | ||
957 | qctrl.id = ctrl->id; | 957 | qctrl.id = ctrl->id; |
958 | err = cx2341x_ctrl_query(params, &qctrl); | 958 | err = cx2341x_ctrl_query(params, &qctrl); |
@@ -1135,7 +1135,7 @@ EXPORT_SYMBOL(cx2341x_update); | |||
1135 | 1135 | ||
1136 | static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 id) | 1136 | static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 id) |
1137 | { | 1137 | { |
1138 | const char **menu = cx2341x_ctrl_get_menu(p, id); | 1138 | const char * const *menu = cx2341x_ctrl_get_menu(p, id); |
1139 | struct v4l2_ext_control ctrl; | 1139 | struct v4l2_ext_control ctrl; |
1140 | 1140 | ||
1141 | if (menu == NULL) | 1141 | if (menu == NULL) |
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig index e1367b35647a..6b4a516addfe 100644 --- a/drivers/media/video/cx23885/Kconfig +++ b/drivers/media/video/cx23885/Kconfig | |||
@@ -5,7 +5,7 @@ config VIDEO_CX23885 | |||
5 | select VIDEO_BTCX | 5 | select VIDEO_BTCX |
6 | select VIDEO_TUNER | 6 | select VIDEO_TUNER |
7 | select VIDEO_TVEEPROM | 7 | select VIDEO_TVEEPROM |
8 | depends on IR_CORE | 8 | depends on RC_CORE |
9 | select VIDEOBUF_DVB | 9 | select VIDEOBUF_DVB |
10 | select VIDEOBUF_DMA_SG | 10 | select VIDEOBUF_DMA_SG |
11 | select VIDEO_CX25840 | 11 | select VIDEO_CX25840 |
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c index c95e7bc14745..209b971bd267 100644 --- a/drivers/media/video/cx23885/cimax2.c +++ b/drivers/media/video/cx23885/cimax2.c | |||
@@ -368,7 +368,7 @@ static void netup_read_ci_status(struct work_struct *work) | |||
368 | DVB_CA_EN50221_POLL_CAM_READY; | 368 | DVB_CA_EN50221_POLL_CAM_READY; |
369 | else | 369 | else |
370 | state->status = 0; | 370 | state->status = 0; |
371 | }; | 371 | } |
372 | } | 372 | } |
373 | 373 | ||
374 | /* CI irq handler */ | 374 | /* CI irq handler */ |
@@ -377,16 +377,24 @@ int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status) | |||
377 | struct cx23885_tsport *port = NULL; | 377 | struct cx23885_tsport *port = NULL; |
378 | struct netup_ci_state *state = NULL; | 378 | struct netup_ci_state *state = NULL; |
379 | 379 | ||
380 | if (pci_status & PCI_MSK_GPIO0) | 380 | ci_dbg_print("%s:\n", __func__); |
381 | port = &dev->ts1; | 381 | |
382 | else if (pci_status & PCI_MSK_GPIO1) | 382 | if (0 == (pci_status & (PCI_MSK_GPIO0 | PCI_MSK_GPIO1))) |
383 | port = &dev->ts2; | ||
384 | else /* who calls ? */ | ||
385 | return 0; | 383 | return 0; |
386 | 384 | ||
387 | state = port->port_priv; | 385 | if (pci_status & PCI_MSK_GPIO0) { |
386 | port = &dev->ts1; | ||
387 | state = port->port_priv; | ||
388 | schedule_work(&state->work); | ||
389 | ci_dbg_print("%s: Wakeup CI0\n", __func__); | ||
390 | } | ||
388 | 391 | ||
389 | schedule_work(&state->work); | 392 | if (pci_status & PCI_MSK_GPIO1) { |
393 | port = &dev->ts2; | ||
394 | state = port->port_priv; | ||
395 | schedule_work(&state->work); | ||
396 | ci_dbg_print("%s: Wakeup CI1\n", __func__); | ||
397 | } | ||
390 | 398 | ||
391 | return 1; | 399 | return 1; |
392 | } | 400 | } |
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 8861309268b1..b298b730943c 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c | |||
@@ -309,6 +309,26 @@ struct cx23885_board cx23885_boards[] = { | |||
309 | CX25840_COMPONENT_ON, | 309 | CX25840_COMPONENT_ON, |
310 | } }, | 310 | } }, |
311 | }, | 311 | }, |
312 | [CX23885_BOARD_GOTVIEW_X5_3D_HYBRID] = { | ||
313 | .name = "GoTView X5 3D Hybrid", | ||
314 | .tuner_type = TUNER_XC5000, | ||
315 | .tuner_addr = 0x64, | ||
316 | .porta = CX23885_ANALOG_VIDEO, | ||
317 | .portb = CX23885_MPEG_DVB, | ||
318 | .input = {{ | ||
319 | .type = CX23885_VMUX_TELEVISION, | ||
320 | .vmux = CX25840_VIN2_CH1 | | ||
321 | CX25840_VIN5_CH2, | ||
322 | .gpio0 = 0x02, | ||
323 | }, { | ||
324 | .type = CX23885_VMUX_COMPOSITE1, | ||
325 | .vmux = CX23885_VMUX_COMPOSITE1, | ||
326 | }, { | ||
327 | .type = CX23885_VMUX_SVIDEO, | ||
328 | .vmux = CX25840_SVIDEO_LUMA3 | | ||
329 | CX25840_SVIDEO_CHROMA4, | ||
330 | } }, | ||
331 | }, | ||
312 | }; | 332 | }; |
313 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); | 333 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); |
314 | 334 | ||
@@ -496,6 +516,10 @@ struct cx23885_subid cx23885_subids[] = { | |||
496 | .subvendor = 0x107d, | 516 | .subvendor = 0x107d, |
497 | .subdevice = 0x6f22, | 517 | .subdevice = 0x6f22, |
498 | .card = CX23885_BOARD_LEADTEK_WINFAST_PXTV1200, | 518 | .card = CX23885_BOARD_LEADTEK_WINFAST_PXTV1200, |
519 | }, { | ||
520 | .subvendor = 0x5654, | ||
521 | .subdevice = 0x2390, | ||
522 | .card = CX23885_BOARD_GOTVIEW_X5_3D_HYBRID, | ||
499 | }, | 523 | }, |
500 | }; | 524 | }; |
501 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); | 525 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); |
@@ -712,6 +736,10 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg) | |||
712 | else if (port->nr == 2) | 736 | else if (port->nr == 2) |
713 | bitmask = 0x04; | 737 | bitmask = 0x04; |
714 | break; | 738 | break; |
739 | case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: | ||
740 | /* Tuner Reset Command */ | ||
741 | bitmask = 0x02; | ||
742 | break; | ||
715 | } | 743 | } |
716 | 744 | ||
717 | if (bitmask) { | 745 | if (bitmask) { |
@@ -967,6 +995,9 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) | |||
967 | /* CX24228 GPIO */ | 995 | /* CX24228 GPIO */ |
968 | /* Connected to IF / Mux */ | 996 | /* Connected to IF / Mux */ |
969 | break; | 997 | break; |
998 | case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: | ||
999 | cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ | ||
1000 | break; | ||
970 | } | 1001 | } |
971 | } | 1002 | } |
972 | 1003 | ||
@@ -1218,6 +1249,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
1218 | case CX23885_BOARD_HAUPPAUGE_HVR1850: | 1249 | case CX23885_BOARD_HAUPPAUGE_HVR1850: |
1219 | case CX23885_BOARD_COMPRO_VIDEOMATE_E800: | 1250 | case CX23885_BOARD_COMPRO_VIDEOMATE_E800: |
1220 | case CX23885_BOARD_HAUPPAUGE_HVR1290: | 1251 | case CX23885_BOARD_HAUPPAUGE_HVR1290: |
1252 | case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: | ||
1221 | default: | 1253 | default: |
1222 | ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ | 1254 | ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ |
1223 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 1255 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
@@ -1245,6 +1277,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
1245 | case CX23885_BOARD_MAGICPRO_PROHDTVE2: | 1277 | case CX23885_BOARD_MAGICPRO_PROHDTVE2: |
1246 | case CX23885_BOARD_HAUPPAUGE_HVR1290: | 1278 | case CX23885_BOARD_HAUPPAUGE_HVR1290: |
1247 | case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200: | 1279 | case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200: |
1280 | case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: | ||
1248 | dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, | 1281 | dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, |
1249 | &dev->i2c_bus[2].i2c_adap, | 1282 | &dev->i2c_bus[2].i2c_adap, |
1250 | "cx25840", 0x88 >> 1, NULL); | 1283 | "cx25840", 0x88 >> 1, NULL); |
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c index bb61870b8d6e..0b0d0664382a 100644 --- a/drivers/media/video/cx23885/cx23885-input.c +++ b/drivers/media/video/cx23885/cx23885-input.c | |||
@@ -35,9 +35,8 @@ | |||
35 | * 02110-1301, USA. | 35 | * 02110-1301, USA. |
36 | */ | 36 | */ |
37 | 37 | ||
38 | #include <linux/input.h> | ||
39 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
40 | #include <media/ir-core.h> | 39 | #include <media/rc-core.h> |
41 | #include <media/v4l2-subdev.h> | 40 | #include <media/v4l2-subdev.h> |
42 | 41 | ||
43 | #include "cx23885.h" | 42 | #include "cx23885.h" |
@@ -62,16 +61,16 @@ static void cx23885_input_process_measurements(struct cx23885_dev *dev, | |||
62 | count = num / sizeof(struct ir_raw_event); | 61 | count = num / sizeof(struct ir_raw_event); |
63 | 62 | ||
64 | for (i = 0; i < count; i++) { | 63 | for (i = 0; i < count; i++) { |
65 | ir_raw_event_store(kernel_ir->inp_dev, | 64 | ir_raw_event_store(kernel_ir->rc, |
66 | &ir_core_event[i]); | 65 | &ir_core_event[i]); |
67 | handle = true; | 66 | handle = true; |
68 | } | 67 | } |
69 | } while (num != 0); | 68 | } while (num != 0); |
70 | 69 | ||
71 | if (overrun) | 70 | if (overrun) |
72 | ir_raw_event_reset(kernel_ir->inp_dev); | 71 | ir_raw_event_reset(kernel_ir->rc); |
73 | else if (handle) | 72 | else if (handle) |
74 | ir_raw_event_handle(kernel_ir->inp_dev); | 73 | ir_raw_event_handle(kernel_ir->rc); |
75 | } | 74 | } |
76 | 75 | ||
77 | void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) | 76 | void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) |
@@ -197,9 +196,9 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev) | |||
197 | return 0; | 196 | return 0; |
198 | } | 197 | } |
199 | 198 | ||
200 | static int cx23885_input_ir_open(void *priv) | 199 | static int cx23885_input_ir_open(struct rc_dev *rc) |
201 | { | 200 | { |
202 | struct cx23885_kernel_ir *kernel_ir = priv; | 201 | struct cx23885_kernel_ir *kernel_ir = rc->priv; |
203 | 202 | ||
204 | if (kernel_ir->cx == NULL) | 203 | if (kernel_ir->cx == NULL) |
205 | return -ENODEV; | 204 | return -ENODEV; |
@@ -234,9 +233,9 @@ static void cx23885_input_ir_stop(struct cx23885_dev *dev) | |||
234 | flush_scheduled_work(); | 233 | flush_scheduled_work(); |
235 | } | 234 | } |
236 | 235 | ||
237 | static void cx23885_input_ir_close(void *priv) | 236 | static void cx23885_input_ir_close(struct rc_dev *rc) |
238 | { | 237 | { |
239 | struct cx23885_kernel_ir *kernel_ir = priv; | 238 | struct cx23885_kernel_ir *kernel_ir = rc->priv; |
240 | 239 | ||
241 | if (kernel_ir->cx != NULL) | 240 | if (kernel_ir->cx != NULL) |
242 | cx23885_input_ir_stop(kernel_ir->cx); | 241 | cx23885_input_ir_stop(kernel_ir->cx); |
@@ -245,9 +244,7 @@ static void cx23885_input_ir_close(void *priv) | |||
245 | int cx23885_input_init(struct cx23885_dev *dev) | 244 | int cx23885_input_init(struct cx23885_dev *dev) |
246 | { | 245 | { |
247 | struct cx23885_kernel_ir *kernel_ir; | 246 | struct cx23885_kernel_ir *kernel_ir; |
248 | struct input_dev *inp_dev; | 247 | struct rc_dev *rc; |
249 | struct ir_dev_props *props; | ||
250 | |||
251 | char *rc_map; | 248 | char *rc_map; |
252 | enum rc_driver_type driver_type; | 249 | enum rc_driver_type driver_type; |
253 | unsigned long allowed_protos; | 250 | unsigned long allowed_protos; |
@@ -267,14 +264,14 @@ int cx23885_input_init(struct cx23885_dev *dev) | |||
267 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 264 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
268 | /* Integrated CX2388[58] IR controller */ | 265 | /* Integrated CX2388[58] IR controller */ |
269 | driver_type = RC_DRIVER_IR_RAW; | 266 | driver_type = RC_DRIVER_IR_RAW; |
270 | allowed_protos = IR_TYPE_ALL; | 267 | allowed_protos = RC_TYPE_ALL; |
271 | /* The grey Hauppauge RC-5 remote */ | 268 | /* The grey Hauppauge RC-5 remote */ |
272 | rc_map = RC_MAP_RC5_HAUPPAUGE_NEW; | 269 | rc_map = RC_MAP_RC5_HAUPPAUGE_NEW; |
273 | break; | 270 | break; |
274 | case CX23885_BOARD_TEVII_S470: | 271 | case CX23885_BOARD_TEVII_S470: |
275 | /* Integrated CX23885 IR controller */ | 272 | /* Integrated CX23885 IR controller */ |
276 | driver_type = RC_DRIVER_IR_RAW; | 273 | driver_type = RC_DRIVER_IR_RAW; |
277 | allowed_protos = IR_TYPE_ALL; | 274 | allowed_protos = RC_TYPE_ALL; |
278 | /* A guess at the remote */ | 275 | /* A guess at the remote */ |
279 | rc_map = RC_MAP_TEVII_NEC; | 276 | rc_map = RC_MAP_TEVII_NEC; |
280 | break; | 277 | break; |
@@ -294,37 +291,36 @@ int cx23885_input_init(struct cx23885_dev *dev) | |||
294 | pci_name(dev->pci)); | 291 | pci_name(dev->pci)); |
295 | 292 | ||
296 | /* input device */ | 293 | /* input device */ |
297 | inp_dev = input_allocate_device(); | 294 | rc = rc_allocate_device(); |
298 | if (inp_dev == NULL) { | 295 | if (!rc) { |
299 | ret = -ENOMEM; | 296 | ret = -ENOMEM; |
300 | goto err_out_free; | 297 | goto err_out_free; |
301 | } | 298 | } |
302 | 299 | ||
303 | kernel_ir->inp_dev = inp_dev; | 300 | kernel_ir->rc = rc; |
304 | inp_dev->name = kernel_ir->name; | 301 | rc->input_name = kernel_ir->name; |
305 | inp_dev->phys = kernel_ir->phys; | 302 | rc->input_phys = kernel_ir->phys; |
306 | inp_dev->id.bustype = BUS_PCI; | 303 | rc->input_id.bustype = BUS_PCI; |
307 | inp_dev->id.version = 1; | 304 | rc->input_id.version = 1; |
308 | if (dev->pci->subsystem_vendor) { | 305 | if (dev->pci->subsystem_vendor) { |
309 | inp_dev->id.vendor = dev->pci->subsystem_vendor; | 306 | rc->input_id.vendor = dev->pci->subsystem_vendor; |
310 | inp_dev->id.product = dev->pci->subsystem_device; | 307 | rc->input_id.product = dev->pci->subsystem_device; |
311 | } else { | 308 | } else { |
312 | inp_dev->id.vendor = dev->pci->vendor; | 309 | rc->input_id.vendor = dev->pci->vendor; |
313 | inp_dev->id.product = dev->pci->device; | 310 | rc->input_id.product = dev->pci->device; |
314 | } | 311 | } |
315 | inp_dev->dev.parent = &dev->pci->dev; | 312 | rc->dev.parent = &dev->pci->dev; |
316 | 313 | rc->driver_type = driver_type; | |
317 | /* kernel ir device properties */ | 314 | rc->allowed_protos = allowed_protos; |
318 | props = &kernel_ir->props; | 315 | rc->priv = kernel_ir; |
319 | props->driver_type = driver_type; | 316 | rc->open = cx23885_input_ir_open; |
320 | props->allowed_protos = allowed_protos; | 317 | rc->close = cx23885_input_ir_close; |
321 | props->priv = kernel_ir; | 318 | rc->map_name = rc_map; |
322 | props->open = cx23885_input_ir_open; | 319 | rc->driver_name = MODULE_NAME; |
323 | props->close = cx23885_input_ir_close; | ||
324 | 320 | ||
325 | /* Go */ | 321 | /* Go */ |
326 | dev->kernel_ir = kernel_ir; | 322 | dev->kernel_ir = kernel_ir; |
327 | ret = ir_input_register(inp_dev, rc_map, props, MODULE_NAME); | 323 | ret = rc_register_device(rc); |
328 | if (ret) | 324 | if (ret) |
329 | goto err_out_stop; | 325 | goto err_out_stop; |
330 | 326 | ||
@@ -333,7 +329,7 @@ int cx23885_input_init(struct cx23885_dev *dev) | |||
333 | err_out_stop: | 329 | err_out_stop: |
334 | cx23885_input_ir_stop(dev); | 330 | cx23885_input_ir_stop(dev); |
335 | dev->kernel_ir = NULL; | 331 | dev->kernel_ir = NULL; |
336 | /* TODO: double check clean-up of kernel_ir->inp_dev */ | 332 | rc_free_device(rc); |
337 | err_out_free: | 333 | err_out_free: |
338 | kfree(kernel_ir->phys); | 334 | kfree(kernel_ir->phys); |
339 | kfree(kernel_ir->name); | 335 | kfree(kernel_ir->name); |
@@ -348,7 +344,7 @@ void cx23885_input_fini(struct cx23885_dev *dev) | |||
348 | 344 | ||
349 | if (dev->kernel_ir == NULL) | 345 | if (dev->kernel_ir == NULL) |
350 | return; | 346 | return; |
351 | ir_input_unregister(dev->kernel_ir->inp_dev); | 347 | rc_unregister_device(dev->kernel_ir->rc); |
352 | kfree(dev->kernel_ir->phys); | 348 | kfree(dev->kernel_ir->phys); |
353 | kfree(dev->kernel_ir->name); | 349 | kfree(dev->kernel_ir->name); |
354 | kfree(dev->kernel_ir); | 350 | kfree(dev->kernel_ir); |
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 8b2fb8a4375c..644fcb808c0b 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
@@ -1024,35 +1024,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | |||
1024 | return 0; | 1024 | return 0; |
1025 | } | 1025 | } |
1026 | 1026 | ||
1027 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1028 | static int vidiocgmbuf(struct file *file, void *priv, | ||
1029 | struct video_mbuf *mbuf) | ||
1030 | { | ||
1031 | struct cx23885_fh *fh = priv; | ||
1032 | struct videobuf_queue *q; | ||
1033 | struct v4l2_requestbuffers req; | ||
1034 | unsigned int i; | ||
1035 | int err; | ||
1036 | |||
1037 | q = get_queue(fh); | ||
1038 | memset(&req, 0, sizeof(req)); | ||
1039 | req.type = q->type; | ||
1040 | req.count = 8; | ||
1041 | req.memory = V4L2_MEMORY_MMAP; | ||
1042 | err = videobuf_reqbufs(q, &req); | ||
1043 | if (err < 0) | ||
1044 | return err; | ||
1045 | |||
1046 | mbuf->frames = req.count; | ||
1047 | mbuf->size = 0; | ||
1048 | for (i = 0; i < mbuf->frames; i++) { | ||
1049 | mbuf->offsets[i] = q->bufs[i]->boff; | ||
1050 | mbuf->size += q->bufs[i]->bsize; | ||
1051 | } | ||
1052 | return 0; | ||
1053 | } | ||
1054 | #endif | ||
1055 | |||
1056 | static int vidioc_reqbufs(struct file *file, void *priv, | 1027 | static int vidioc_reqbufs(struct file *file, void *priv, |
1057 | struct v4l2_requestbuffers *p) | 1028 | struct v4l2_requestbuffers *p) |
1058 | { | 1029 | { |
@@ -1155,7 +1126,6 @@ static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) | |||
1155 | if (0 == INPUT(n)->type) | 1126 | if (0 == INPUT(n)->type) |
1156 | return -EINVAL; | 1127 | return -EINVAL; |
1157 | 1128 | ||
1158 | memset(i, 0, sizeof(*i)); | ||
1159 | i->index = n; | 1129 | i->index = n; |
1160 | i->type = V4L2_INPUT_TYPE_CAMERA; | 1130 | i->type = V4L2_INPUT_TYPE_CAMERA; |
1161 | strcpy(i->name, iname[INPUT(n)->type]); | 1131 | strcpy(i->name, iname[INPUT(n)->type]); |
@@ -1427,9 +1397,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1427 | .vidioc_s_ctrl = vidioc_s_ctrl, | 1397 | .vidioc_s_ctrl = vidioc_s_ctrl, |
1428 | .vidioc_streamon = vidioc_streamon, | 1398 | .vidioc_streamon = vidioc_streamon, |
1429 | .vidioc_streamoff = vidioc_streamoff, | 1399 | .vidioc_streamoff = vidioc_streamoff, |
1430 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1431 | .vidiocgmbuf = vidiocgmbuf, | ||
1432 | #endif | ||
1433 | .vidioc_g_tuner = vidioc_g_tuner, | 1400 | .vidioc_g_tuner = vidioc_g_tuner, |
1434 | .vidioc_s_tuner = vidioc_s_tuner, | 1401 | .vidioc_s_tuner = vidioc_s_tuner, |
1435 | .vidioc_g_frequency = vidioc_g_frequency, | 1402 | .vidioc_g_frequency = vidioc_g_frequency, |
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index ed94b17dd8a5..62e41ab65810 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <media/tveeprom.h> | 30 | #include <media/tveeprom.h> |
31 | #include <media/videobuf-dma-sg.h> | 31 | #include <media/videobuf-dma-sg.h> |
32 | #include <media/videobuf-dvb.h> | 32 | #include <media/videobuf-dvb.h> |
33 | #include <media/ir-core.h> | 33 | #include <media/rc-core.h> |
34 | 34 | ||
35 | #include "btcx-risc.h" | 35 | #include "btcx-risc.h" |
36 | #include "cx23885-reg.h" | 36 | #include "cx23885-reg.h" |
@@ -84,6 +84,7 @@ | |||
84 | #define CX23885_BOARD_HAUPPAUGE_HVR1290 26 | 84 | #define CX23885_BOARD_HAUPPAUGE_HVR1290 26 |
85 | #define CX23885_BOARD_MYGICA_X8558PRO 27 | 85 | #define CX23885_BOARD_MYGICA_X8558PRO 27 |
86 | #define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28 | 86 | #define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28 |
87 | #define CX23885_BOARD_GOTVIEW_X5_3D_HYBRID 29 | ||
87 | 88 | ||
88 | #define GPIO_0 0x00000001 | 89 | #define GPIO_0 0x00000001 |
89 | #define GPIO_1 0x00000002 | 90 | #define GPIO_1 0x00000002 |
@@ -310,8 +311,7 @@ struct cx23885_kernel_ir { | |||
310 | char *name; | 311 | char *name; |
311 | char *phys; | 312 | char *phys; |
312 | 313 | ||
313 | struct input_dev *inp_dev; | 314 | struct rc_dev *rc; |
314 | struct ir_dev_props props; | ||
315 | }; | 315 | }; |
316 | 316 | ||
317 | struct cx23885_dev { | 317 | struct cx23885_dev { |
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c index e78e3e4c8112..e37be6fcf67d 100644 --- a/drivers/media/video/cx23885/cx23888-ir.c +++ b/drivers/media/video/cx23885/cx23888-ir.c | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | #include <media/v4l2-device.h> | 27 | #include <media/v4l2-device.h> |
28 | #include <media/v4l2-chip-ident.h> | 28 | #include <media/v4l2-chip-ident.h> |
29 | #include <media/ir-core.h> | 29 | #include <media/rc-core.h> |
30 | 30 | ||
31 | #include "cx23885.h" | 31 | #include "cx23885.h" |
32 | 32 | ||
diff --git a/drivers/media/video/cx25840/cx25840-ir.c b/drivers/media/video/cx25840/cx25840-ir.c index 97a4e9b25fe4..627926f6bde8 100644 --- a/drivers/media/video/cx25840/cx25840-ir.c +++ b/drivers/media/video/cx25840/cx25840-ir.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/kfifo.h> | 25 | #include <linux/kfifo.h> |
26 | #include <media/cx25840.h> | 26 | #include <media/cx25840.h> |
27 | #include <media/ir-core.h> | 27 | #include <media/rc-core.h> |
28 | 28 | ||
29 | #include "cx25840-core.h" | 29 | #include "cx25840-core.h" |
30 | 30 | ||
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 0fa85cbefbb1..5c42abdf422f 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig | |||
@@ -1,12 +1,11 @@ | |||
1 | config VIDEO_CX88 | 1 | config VIDEO_CX88 |
2 | tristate "Conexant 2388x (bt878 successor) support" | 2 | tristate "Conexant 2388x (bt878 successor) support" |
3 | depends on VIDEO_DEV && PCI && I2C && INPUT | 3 | depends on VIDEO_DEV && PCI && I2C && RC_CORE |
4 | select I2C_ALGOBIT | 4 | select I2C_ALGOBIT |
5 | select VIDEO_BTCX | 5 | select VIDEO_BTCX |
6 | select VIDEOBUF_DMA_SG | 6 | select VIDEOBUF_DMA_SG |
7 | select VIDEO_TUNER | 7 | select VIDEO_TUNER |
8 | select VIDEO_TVEEPROM | 8 | select VIDEO_TVEEPROM |
9 | depends on VIDEO_IR | ||
10 | select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO | 9 | select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO |
11 | ---help--- | 10 | ---help--- |
12 | This is a video4linux driver for Conexant 2388x based | 11 | This is a video4linux driver for Conexant 2388x based |
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index d7c94848249e..bca307eb1e24 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -1064,7 +1064,7 @@ static int mpeg_open(struct file *file) | |||
1064 | err = drv->request_acquire(drv); | 1064 | err = drv->request_acquire(drv); |
1065 | if(err != 0) { | 1065 | if(err != 0) { |
1066 | dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err); | 1066 | dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err); |
1067 | mutex_unlock(&dev->core->lock);; | 1067 | mutex_unlock(&dev->core->lock); |
1068 | return err; | 1068 | return err; |
1069 | } | 1069 | } |
1070 | } | 1070 | } |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 0ccc2afd7266..4e6ee5584cb3 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -47,7 +47,7 @@ MODULE_PARM_DESC(latency,"pci latency timer"); | |||
47 | 47 | ||
48 | static int disable_ir; | 48 | static int disable_ir; |
49 | module_param(disable_ir, int, 0444); | 49 | module_param(disable_ir, int, 0444); |
50 | MODULE_PARM_DESC(latency, "Disable IR support"); | 50 | MODULE_PARM_DESC(disable_ir, "Disable IR support"); |
51 | 51 | ||
52 | #define info_printk(core, fmt, arg...) \ | 52 | #define info_printk(core, fmt, arg...) \ |
53 | printk(KERN_INFO "%s: " fmt, core->name , ## arg) | 53 | printk(KERN_INFO "%s: " fmt, core->name , ## arg) |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 367a653f4c95..90717ee944ec 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -67,6 +67,10 @@ static unsigned int debug; | |||
67 | module_param(debug, int, 0644); | 67 | module_param(debug, int, 0644); |
68 | MODULE_PARM_DESC(debug,"enable debug messages [dvb]"); | 68 | MODULE_PARM_DESC(debug,"enable debug messages [dvb]"); |
69 | 69 | ||
70 | static unsigned int dvb_buf_tscnt = 32; | ||
71 | module_param(dvb_buf_tscnt, int, 0644); | ||
72 | MODULE_PARM_DESC(dvb_buf_tscnt, "DVB Buffer TS count [dvb]"); | ||
73 | |||
70 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 74 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
71 | 75 | ||
72 | #define dprintk(level,fmt, arg...) if (debug >= level) \ | 76 | #define dprintk(level,fmt, arg...) if (debug >= level) \ |
@@ -80,10 +84,10 @@ static int dvb_buf_setup(struct videobuf_queue *q, | |||
80 | struct cx8802_dev *dev = q->priv_data; | 84 | struct cx8802_dev *dev = q->priv_data; |
81 | 85 | ||
82 | dev->ts_packet_size = 188 * 4; | 86 | dev->ts_packet_size = 188 * 4; |
83 | dev->ts_packet_count = 32; | 87 | dev->ts_packet_count = dvb_buf_tscnt; |
84 | 88 | ||
85 | *size = dev->ts_packet_size * dev->ts_packet_count; | 89 | *size = dev->ts_packet_size * dev->ts_packet_count; |
86 | *count = 32; | 90 | *count = dvb_buf_tscnt; |
87 | return 0; | 91 | return 0; |
88 | } | 92 | } |
89 | 93 | ||
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index f53836bb6a5a..a1fe0abb6e43 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -146,7 +146,6 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) | |||
146 | core->i2c_adap.dev.parent = &pci->dev; | 146 | core->i2c_adap.dev.parent = &pci->dev; |
147 | strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); | 147 | strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); |
148 | core->i2c_adap.owner = THIS_MODULE; | 148 | core->i2c_adap.owner = THIS_MODULE; |
149 | core->i2c_adap.id = I2C_HW_B_CX2388x; | ||
150 | core->i2c_algo.udelay = i2c_udelay; | 149 | core->i2c_algo.udelay = i2c_udelay; |
151 | core->i2c_algo.data = core; | 150 | core->i2c_algo.data = core; |
152 | i2c_set_adapdata(&core->i2c_adap, &core->v4l2_dev); | 151 | i2c_set_adapdata(&core->i2c_adap, &core->v4l2_dev); |
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index fc777bc6e716..06f7d1d00944 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -24,14 +24,12 @@ | |||
24 | 24 | ||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/hrtimer.h> | 26 | #include <linux/hrtimer.h> |
27 | #include <linux/input.h> | ||
28 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
29 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
30 | #include <linux/module.h> | 29 | #include <linux/module.h> |
31 | 30 | ||
32 | #include "cx88.h" | 31 | #include "cx88.h" |
33 | #include <media/ir-core.h> | 32 | #include <media/rc-core.h> |
34 | #include <media/ir-common.h> | ||
35 | 33 | ||
36 | #define MODULE_NAME "cx88xx" | 34 | #define MODULE_NAME "cx88xx" |
37 | 35 | ||
@@ -39,9 +37,7 @@ | |||
39 | 37 | ||
40 | struct cx88_IR { | 38 | struct cx88_IR { |
41 | struct cx88_core *core; | 39 | struct cx88_core *core; |
42 | struct input_dev *input; | 40 | struct rc_dev *dev; |
43 | struct ir_dev_props props; | ||
44 | u64 ir_type; | ||
45 | 41 | ||
46 | int users; | 42 | int users; |
47 | 43 | ||
@@ -50,8 +46,6 @@ struct cx88_IR { | |||
50 | 46 | ||
51 | /* sample from gpio pin 16 */ | 47 | /* sample from gpio pin 16 */ |
52 | u32 sampling; | 48 | u32 sampling; |
53 | u32 samples[16]; | ||
54 | int scount; | ||
55 | 49 | ||
56 | /* poll external decoder */ | 50 | /* poll external decoder */ |
57 | int polling; | 51 | int polling; |
@@ -63,6 +57,10 @@ struct cx88_IR { | |||
63 | u32 mask_keyup; | 57 | u32 mask_keyup; |
64 | }; | 58 | }; |
65 | 59 | ||
60 | static unsigned ir_samplerate = 4; | ||
61 | module_param(ir_samplerate, uint, 0444); | ||
62 | MODULE_PARM_DESC(ir_samplerate, "IR samplerate in kHz, 1 - 20, default 4"); | ||
63 | |||
66 | static int ir_debug; | 64 | static int ir_debug; |
67 | module_param(ir_debug, int, 0644); /* debug level [IR] */ | 65 | module_param(ir_debug, int, 0644); /* debug level [IR] */ |
68 | MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | 66 | MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); |
@@ -70,6 +68,9 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | |||
70 | #define ir_dprintk(fmt, arg...) if (ir_debug) \ | 68 | #define ir_dprintk(fmt, arg...) if (ir_debug) \ |
71 | printk(KERN_DEBUG "%s IR: " fmt , ir->core->name , ##arg) | 69 | printk(KERN_DEBUG "%s IR: " fmt , ir->core->name , ##arg) |
72 | 70 | ||
71 | #define dprintk(fmt, arg...) if (ir_debug) \ | ||
72 | printk(KERN_DEBUG "cx88 IR: " fmt , ##arg) | ||
73 | |||
73 | /* ---------------------------------------------------------------------- */ | 74 | /* ---------------------------------------------------------------------- */ |
74 | 75 | ||
75 | static void cx88_ir_handle_key(struct cx88_IR *ir) | 76 | static void cx88_ir_handle_key(struct cx88_IR *ir) |
@@ -125,21 +126,26 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) | |||
125 | 126 | ||
126 | data = (data << 4) | ((gpio_key & 0xf0) >> 4); | 127 | data = (data << 4) | ((gpio_key & 0xf0) >> 4); |
127 | 128 | ||
128 | ir_keydown(ir->input, data, 0); | 129 | rc_keydown(ir->dev, data, 0); |
129 | 130 | ||
130 | } else if (ir->mask_keydown) { | 131 | } else if (ir->mask_keydown) { |
131 | /* bit set on keydown */ | 132 | /* bit set on keydown */ |
132 | if (gpio & ir->mask_keydown) | 133 | if (gpio & ir->mask_keydown) |
133 | ir_keydown(ir->input, data, 0); | 134 | rc_keydown_notimeout(ir->dev, data, 0); |
135 | else | ||
136 | rc_keyup(ir->dev); | ||
134 | 137 | ||
135 | } else if (ir->mask_keyup) { | 138 | } else if (ir->mask_keyup) { |
136 | /* bit cleared on keydown */ | 139 | /* bit cleared on keydown */ |
137 | if (0 == (gpio & ir->mask_keyup)) | 140 | if (0 == (gpio & ir->mask_keyup)) |
138 | ir_keydown(ir->input, data, 0); | 141 | rc_keydown_notimeout(ir->dev, data, 0); |
142 | else | ||
143 | rc_keyup(ir->dev); | ||
139 | 144 | ||
140 | } else { | 145 | } else { |
141 | /* can't distinguish keydown/up :-/ */ | 146 | /* can't distinguish keydown/up :-/ */ |
142 | ir_keydown(ir->input, data, 0); | 147 | rc_keydown_notimeout(ir->dev, data, 0); |
148 | rc_keyup(ir->dev); | ||
143 | } | 149 | } |
144 | } | 150 | } |
145 | 151 | ||
@@ -176,8 +182,8 @@ static int __cx88_ir_start(void *priv) | |||
176 | } | 182 | } |
177 | if (ir->sampling) { | 183 | if (ir->sampling) { |
178 | core->pci_irqmask |= PCI_INT_IR_SMPINT; | 184 | core->pci_irqmask |= PCI_INT_IR_SMPINT; |
179 | cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */ | 185 | cx_write(MO_DDS_IO, 0x33F286 * ir_samplerate); /* samplerate */ |
180 | cx_write(MO_DDSCFG_IO, 0x5); /* enable */ | 186 | cx_write(MO_DDSCFG_IO, 0x5); /* enable */ |
181 | } | 187 | } |
182 | return 0; | 188 | return 0; |
183 | } | 189 | } |
@@ -214,17 +220,17 @@ void cx88_ir_stop(struct cx88_core *core) | |||
214 | __cx88_ir_stop(core); | 220 | __cx88_ir_stop(core); |
215 | } | 221 | } |
216 | 222 | ||
217 | static int cx88_ir_open(void *priv) | 223 | static int cx88_ir_open(struct rc_dev *rc) |
218 | { | 224 | { |
219 | struct cx88_core *core = priv; | 225 | struct cx88_core *core = rc->priv; |
220 | 226 | ||
221 | core->ir->users++; | 227 | core->ir->users++; |
222 | return __cx88_ir_start(core); | 228 | return __cx88_ir_start(core); |
223 | } | 229 | } |
224 | 230 | ||
225 | static void cx88_ir_close(void *priv) | 231 | static void cx88_ir_close(struct rc_dev *rc) |
226 | { | 232 | { |
227 | struct cx88_core *core = priv; | 233 | struct cx88_core *core = rc->priv; |
228 | 234 | ||
229 | core->ir->users--; | 235 | core->ir->users--; |
230 | if (!core->ir->users) | 236 | if (!core->ir->users) |
@@ -236,20 +242,20 @@ static void cx88_ir_close(void *priv) | |||
236 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | 242 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) |
237 | { | 243 | { |
238 | struct cx88_IR *ir; | 244 | struct cx88_IR *ir; |
239 | struct input_dev *input_dev; | 245 | struct rc_dev *dev; |
240 | char *ir_codes = NULL; | 246 | char *ir_codes = NULL; |
241 | u64 ir_type = IR_TYPE_OTHER; | 247 | u64 rc_type = RC_TYPE_OTHER; |
242 | int err = -ENOMEM; | 248 | int err = -ENOMEM; |
243 | u32 hardware_mask = 0; /* For devices with a hardware mask, when | 249 | u32 hardware_mask = 0; /* For devices with a hardware mask, when |
244 | * used with a full-code IR table | 250 | * used with a full-code IR table |
245 | */ | 251 | */ |
246 | 252 | ||
247 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | 253 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); |
248 | input_dev = input_allocate_device(); | 254 | dev = rc_allocate_device(); |
249 | if (!ir || !input_dev) | 255 | if (!ir || !dev) |
250 | goto err_out_free; | 256 | goto err_out_free; |
251 | 257 | ||
252 | ir->input = input_dev; | 258 | ir->dev = dev; |
253 | 259 | ||
254 | /* detect & configure */ | 260 | /* detect & configure */ |
255 | switch (core->boardnr) { | 261 | switch (core->boardnr) { |
@@ -264,7 +270,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
264 | break; | 270 | break; |
265 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: | 271 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: |
266 | ir_codes = RC_MAP_CINERGY_1400; | 272 | ir_codes = RC_MAP_CINERGY_1400; |
267 | ir_type = IR_TYPE_NEC; | ||
268 | ir->sampling = 0xeb04; /* address */ | 273 | ir->sampling = 0xeb04; /* address */ |
269 | break; | 274 | break; |
270 | case CX88_BOARD_HAUPPAUGE: | 275 | case CX88_BOARD_HAUPPAUGE: |
@@ -279,7 +284,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
279 | case CX88_BOARD_PCHDTV_HD5500: | 284 | case CX88_BOARD_PCHDTV_HD5500: |
280 | case CX88_BOARD_HAUPPAUGE_IRONLY: | 285 | case CX88_BOARD_HAUPPAUGE_IRONLY: |
281 | ir_codes = RC_MAP_HAUPPAUGE_NEW; | 286 | ir_codes = RC_MAP_HAUPPAUGE_NEW; |
282 | ir_type = IR_TYPE_RC5; | ||
283 | ir->sampling = 1; | 287 | ir->sampling = 1; |
284 | break; | 288 | break; |
285 | case CX88_BOARD_WINFAST_DTV2000H: | 289 | case CX88_BOARD_WINFAST_DTV2000H: |
@@ -367,18 +371,15 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
367 | case CX88_BOARD_PROF_7301: | 371 | case CX88_BOARD_PROF_7301: |
368 | case CX88_BOARD_PROF_6200: | 372 | case CX88_BOARD_PROF_6200: |
369 | ir_codes = RC_MAP_TBS_NEC; | 373 | ir_codes = RC_MAP_TBS_NEC; |
370 | ir_type = IR_TYPE_NEC; | ||
371 | ir->sampling = 0xff00; /* address */ | 374 | ir->sampling = 0xff00; /* address */ |
372 | break; | 375 | break; |
373 | case CX88_BOARD_TEVII_S460: | 376 | case CX88_BOARD_TEVII_S460: |
374 | case CX88_BOARD_TEVII_S420: | 377 | case CX88_BOARD_TEVII_S420: |
375 | ir_codes = RC_MAP_TEVII_NEC; | 378 | ir_codes = RC_MAP_TEVII_NEC; |
376 | ir_type = IR_TYPE_NEC; | ||
377 | ir->sampling = 0xff00; /* address */ | 379 | ir->sampling = 0xff00; /* address */ |
378 | break; | 380 | break; |
379 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: | 381 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: |
380 | ir_codes = RC_MAP_DNTV_LIVE_DVBT_PRO; | 382 | ir_codes = RC_MAP_DNTV_LIVE_DVBT_PRO; |
381 | ir_type = IR_TYPE_NEC; | ||
382 | ir->sampling = 0xff00; /* address */ | 383 | ir->sampling = 0xff00; /* address */ |
383 | break; | 384 | break; |
384 | case CX88_BOARD_NORWOOD_MICRO: | 385 | case CX88_BOARD_NORWOOD_MICRO: |
@@ -396,7 +397,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
396 | break; | 397 | break; |
397 | case CX88_BOARD_PINNACLE_PCTV_HD_800i: | 398 | case CX88_BOARD_PINNACLE_PCTV_HD_800i: |
398 | ir_codes = RC_MAP_PINNACLE_PCTV_HD; | 399 | ir_codes = RC_MAP_PINNACLE_PCTV_HD; |
399 | ir_type = IR_TYPE_RC5; | ||
400 | ir->sampling = 1; | 400 | ir->sampling = 1; |
401 | break; | 401 | break; |
402 | case CX88_BOARD_POWERCOLOR_REAL_ANGEL: | 402 | case CX88_BOARD_POWERCOLOR_REAL_ANGEL: |
@@ -407,12 +407,12 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
407 | break; | 407 | break; |
408 | case CX88_BOARD_TWINHAN_VP1027_DVBS: | 408 | case CX88_BOARD_TWINHAN_VP1027_DVBS: |
409 | ir_codes = RC_MAP_TWINHAN_VP1027_DVBS; | 409 | ir_codes = RC_MAP_TWINHAN_VP1027_DVBS; |
410 | ir_type = IR_TYPE_NEC; | 410 | rc_type = RC_TYPE_NEC; |
411 | ir->sampling = 0xff00; /* address */ | 411 | ir->sampling = 0xff00; /* address */ |
412 | break; | 412 | break; |
413 | } | 413 | } |
414 | 414 | ||
415 | if (NULL == ir_codes) { | 415 | if (!ir_codes) { |
416 | err = -ENODEV; | 416 | err = -ENODEV; |
417 | goto err_out_free; | 417 | goto err_out_free; |
418 | } | 418 | } |
@@ -436,37 +436,45 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
436 | snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name); | 436 | snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name); |
437 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci)); | 437 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci)); |
438 | 438 | ||
439 | ir->ir_type = ir_type; | 439 | dev->input_name = ir->name; |
440 | 440 | dev->input_phys = ir->phys; | |
441 | input_dev->name = ir->name; | 441 | dev->input_id.bustype = BUS_PCI; |
442 | input_dev->phys = ir->phys; | 442 | dev->input_id.version = 1; |
443 | input_dev->id.bustype = BUS_PCI; | ||
444 | input_dev->id.version = 1; | ||
445 | if (pci->subsystem_vendor) { | 443 | if (pci->subsystem_vendor) { |
446 | input_dev->id.vendor = pci->subsystem_vendor; | 444 | dev->input_id.vendor = pci->subsystem_vendor; |
447 | input_dev->id.product = pci->subsystem_device; | 445 | dev->input_id.product = pci->subsystem_device; |
448 | } else { | 446 | } else { |
449 | input_dev->id.vendor = pci->vendor; | 447 | dev->input_id.vendor = pci->vendor; |
450 | input_dev->id.product = pci->device; | 448 | dev->input_id.product = pci->device; |
451 | } | 449 | } |
452 | input_dev->dev.parent = &pci->dev; | 450 | dev->dev.parent = &pci->dev; |
453 | /* record handles to ourself */ | 451 | dev->map_name = ir_codes; |
452 | dev->driver_name = MODULE_NAME; | ||
453 | dev->priv = core; | ||
454 | dev->open = cx88_ir_open; | ||
455 | dev->close = cx88_ir_close; | ||
456 | dev->scanmask = hardware_mask; | ||
457 | |||
458 | if (ir->sampling) { | ||
459 | dev->driver_type = RC_DRIVER_IR_RAW; | ||
460 | dev->timeout = 10 * 1000 * 1000; /* 10 ms */ | ||
461 | } else { | ||
462 | dev->driver_type = RC_DRIVER_SCANCODE; | ||
463 | dev->allowed_protos = rc_type; | ||
464 | } | ||
465 | |||
454 | ir->core = core; | 466 | ir->core = core; |
455 | core->ir = ir; | 467 | core->ir = ir; |
456 | 468 | ||
457 | ir->props.priv = core; | ||
458 | ir->props.open = cx88_ir_open; | ||
459 | ir->props.close = cx88_ir_close; | ||
460 | ir->props.scanmask = hardware_mask; | ||
461 | |||
462 | /* all done */ | 469 | /* all done */ |
463 | err = ir_input_register(ir->input, ir_codes, &ir->props, MODULE_NAME); | 470 | err = rc_register_device(dev); |
464 | if (err) | 471 | if (err) |
465 | goto err_out_free; | 472 | goto err_out_free; |
466 | 473 | ||
467 | return 0; | 474 | return 0; |
468 | 475 | ||
469 | err_out_free: | 476 | err_out_free: |
477 | rc_free_device(dev); | ||
470 | core->ir = NULL; | 478 | core->ir = NULL; |
471 | kfree(ir); | 479 | kfree(ir); |
472 | return err; | 480 | return err; |
@@ -481,7 +489,7 @@ int cx88_ir_fini(struct cx88_core *core) | |||
481 | return 0; | 489 | return 0; |
482 | 490 | ||
483 | cx88_ir_stop(core); | 491 | cx88_ir_stop(core); |
484 | ir_input_unregister(ir->input); | 492 | rc_unregister_device(ir->dev); |
485 | kfree(ir); | 493 | kfree(ir); |
486 | 494 | ||
487 | /* done */ | 495 | /* done */ |
@@ -494,135 +502,75 @@ int cx88_ir_fini(struct cx88_core *core) | |||
494 | void cx88_ir_irq(struct cx88_core *core) | 502 | void cx88_ir_irq(struct cx88_core *core) |
495 | { | 503 | { |
496 | struct cx88_IR *ir = core->ir; | 504 | struct cx88_IR *ir = core->ir; |
497 | u32 samples, ircode; | 505 | u32 samples; |
498 | int i, start, range, toggle, dev, code; | 506 | unsigned todo, bits; |
507 | struct ir_raw_event ev; | ||
499 | 508 | ||
500 | if (NULL == ir) | 509 | if (!ir || !ir->sampling) |
501 | return; | ||
502 | if (!ir->sampling) | ||
503 | return; | 510 | return; |
504 | 511 | ||
512 | /* | ||
513 | * Samples are stored in a 32 bit register, oldest sample in | ||
514 | * the msb. A set bit represents space and an unset bit | ||
515 | * represents a pulse. | ||
516 | */ | ||
505 | samples = cx_read(MO_SAMPLE_IO); | 517 | samples = cx_read(MO_SAMPLE_IO); |
506 | if (0 != samples && 0xffffffff != samples) { | ||
507 | /* record sample data */ | ||
508 | if (ir->scount < ARRAY_SIZE(ir->samples)) | ||
509 | ir->samples[ir->scount++] = samples; | ||
510 | return; | ||
511 | } | ||
512 | if (!ir->scount) { | ||
513 | /* nothing to sample */ | ||
514 | return; | ||
515 | } | ||
516 | |||
517 | /* have a complete sample */ | ||
518 | if (ir->scount < ARRAY_SIZE(ir->samples)) | ||
519 | ir->samples[ir->scount++] = samples; | ||
520 | for (i = 0; i < ir->scount; i++) | ||
521 | ir->samples[i] = ~ir->samples[i]; | ||
522 | if (ir_debug) | ||
523 | ir_dump_samples(ir->samples, ir->scount); | ||
524 | 518 | ||
525 | /* decode it */ | 519 | if (samples == 0xff && ir->dev->idle) |
526 | switch (core->boardnr) { | 520 | return; |
527 | case CX88_BOARD_TEVII_S460: | ||
528 | case CX88_BOARD_TEVII_S420: | ||
529 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: | ||
530 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: | ||
531 | case CX88_BOARD_OMICOM_SS4_PCI: | ||
532 | case CX88_BOARD_SATTRADE_ST4200: | ||
533 | case CX88_BOARD_TBS_8920: | ||
534 | case CX88_BOARD_TBS_8910: | ||
535 | case CX88_BOARD_PROF_7300: | ||
536 | case CX88_BOARD_PROF_7301: | ||
537 | case CX88_BOARD_PROF_6200: | ||
538 | case CX88_BOARD_TWINHAN_VP1027_DVBS: | ||
539 | ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); | ||
540 | |||
541 | if (ircode == 0xffffffff) { /* decoding error */ | ||
542 | ir_dprintk("pulse distance decoding error\n"); | ||
543 | break; | ||
544 | } | ||
545 | |||
546 | ir_dprintk("pulse distance decoded: %x\n", ircode); | ||
547 | 521 | ||
548 | if (ircode == 0) { /* key still pressed */ | 522 | init_ir_raw_event(&ev); |
549 | ir_dprintk("pulse distance decoded repeat code\n"); | 523 | for (todo = 32; todo > 0; todo -= bits) { |
550 | ir_repeat(ir->input); | 524 | ev.pulse = samples & 0x80000000 ? false : true; |
551 | break; | 525 | bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples)); |
552 | } | 526 | ev.duration = (bits * NSEC_PER_SEC) / (1000 * ir_samplerate); |
527 | ir_raw_event_store_with_filter(ir->dev, &ev); | ||
528 | samples <<= bits; | ||
529 | } | ||
530 | ir_raw_event_handle(ir->dev); | ||
531 | } | ||
553 | 532 | ||
554 | if ((ircode & 0xffff) != (ir->sampling & 0xffff)) { /* wrong address */ | 533 | static int get_key_pvr2000(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
555 | ir_dprintk("pulse distance decoded wrong address\n"); | 534 | { |
556 | break; | 535 | int flags, code; |
557 | } | ||
558 | 536 | ||
559 | if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */ | 537 | /* poll IR chip */ |
560 | ir_dprintk("pulse distance decoded wrong check sum\n"); | 538 | flags = i2c_smbus_read_byte_data(ir->c, 0x10); |
561 | break; | 539 | if (flags < 0) { |
562 | } | 540 | dprintk("read error\n"); |
541 | return 0; | ||
542 | } | ||
543 | /* key pressed ? */ | ||
544 | if (0 == (flags & 0x80)) | ||
545 | return 0; | ||
563 | 546 | ||
564 | ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0xff); | 547 | /* read actual key code */ |
565 | ir_keydown(ir->input, (ircode >> 16) & 0xff, 0); | 548 | code = i2c_smbus_read_byte_data(ir->c, 0x00); |
566 | break; | 549 | if (code < 0) { |
567 | case CX88_BOARD_HAUPPAUGE: | 550 | dprintk("read error\n"); |
568 | case CX88_BOARD_HAUPPAUGE_DVB_T1: | 551 | return 0; |
569 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | ||
570 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | ||
571 | case CX88_BOARD_HAUPPAUGE_HVR1100: | ||
572 | case CX88_BOARD_HAUPPAUGE_HVR3000: | ||
573 | case CX88_BOARD_HAUPPAUGE_HVR4000: | ||
574 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: | ||
575 | case CX88_BOARD_PCHDTV_HD3000: | ||
576 | case CX88_BOARD_PCHDTV_HD5500: | ||
577 | case CX88_BOARD_HAUPPAUGE_IRONLY: | ||
578 | ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); | ||
579 | ir_dprintk("biphase decoded: %x\n", ircode); | ||
580 | /* | ||
581 | * RC5 has an extension bit which adds a new range | ||
582 | * of available codes, this is detected here. Also | ||
583 | * hauppauge remotes (black/silver) always use | ||
584 | * specific device ids. If we do not filter the | ||
585 | * device ids then messages destined for devices | ||
586 | * such as TVs (id=0) will get through to the | ||
587 | * device causing mis-fired events. | ||
588 | */ | ||
589 | /* split rc5 data block ... */ | ||
590 | start = (ircode & 0x2000) >> 13; | ||
591 | range = (ircode & 0x1000) >> 12; | ||
592 | toggle= (ircode & 0x0800) >> 11; | ||
593 | dev = (ircode & 0x07c0) >> 6; | ||
594 | code = (ircode & 0x003f) | ((range << 6) ^ 0x0040); | ||
595 | if( start != 1) | ||
596 | /* no key pressed */ | ||
597 | break; | ||
598 | if ( dev != 0x1e && dev != 0x1f ) | ||
599 | /* not a hauppauge remote */ | ||
600 | break; | ||
601 | ir_keydown(ir->input, code, toggle); | ||
602 | break; | ||
603 | case CX88_BOARD_PINNACLE_PCTV_HD_800i: | ||
604 | ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); | ||
605 | ir_dprintk("biphase decoded: %x\n", ircode); | ||
606 | if ((ircode & 0xfffff000) != 0x3000) | ||
607 | break; | ||
608 | /* Note: bit 0x800 being the toggle is assumed, not checked | ||
609 | with real hardware */ | ||
610 | ir_keydown(ir->input, ircode & 0x3f, ircode & 0x0800 ? 1 : 0); | ||
611 | break; | ||
612 | } | 552 | } |
613 | 553 | ||
614 | ir->scount = 0; | 554 | dprintk("IR Key/Flags: (0x%02x/0x%02x)\n", |
615 | return; | 555 | code & 0xff, flags & 0xff); |
616 | } | ||
617 | 556 | ||
557 | *ir_key = code & 0xff; | ||
558 | *ir_raw = code; | ||
559 | return 1; | ||
560 | } | ||
618 | 561 | ||
619 | void cx88_i2c_init_ir(struct cx88_core *core) | 562 | void cx88_i2c_init_ir(struct cx88_core *core) |
620 | { | 563 | { |
621 | struct i2c_board_info info; | 564 | struct i2c_board_info info; |
622 | const unsigned short addr_list[] = { | 565 | const unsigned short default_addr_list[] = { |
623 | 0x18, 0x6b, 0x71, | 566 | 0x18, 0x6b, 0x71, |
624 | I2C_CLIENT_END | 567 | I2C_CLIENT_END |
625 | }; | 568 | }; |
569 | const unsigned short pvr2000_addr_list[] = { | ||
570 | 0x18, 0x1a, | ||
571 | I2C_CLIENT_END | ||
572 | }; | ||
573 | const unsigned short *addr_list = default_addr_list; | ||
626 | const unsigned short *addrp; | 574 | const unsigned short *addrp; |
627 | /* Instantiate the IR receiver device, if present */ | 575 | /* Instantiate the IR receiver device, if present */ |
628 | if (0 != core->i2c_rc) | 576 | if (0 != core->i2c_rc) |
@@ -631,6 +579,16 @@ void cx88_i2c_init_ir(struct cx88_core *core) | |||
631 | memset(&info, 0, sizeof(struct i2c_board_info)); | 579 | memset(&info, 0, sizeof(struct i2c_board_info)); |
632 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | 580 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); |
633 | 581 | ||
582 | switch (core->boardnr) { | ||
583 | case CX88_BOARD_LEADTEK_PVR2000: | ||
584 | addr_list = pvr2000_addr_list; | ||
585 | core->init_data.name = "cx88 Leadtek PVR 2000 remote"; | ||
586 | core->init_data.type = RC_TYPE_UNKNOWN; | ||
587 | core->init_data.get_key = get_key_pvr2000; | ||
588 | core->init_data.ir_codes = RC_MAP_EMPTY; | ||
589 | break; | ||
590 | } | ||
591 | |||
634 | /* | 592 | /* |
635 | * We can't call i2c_new_probed_device() because it uses | 593 | * We can't call i2c_new_probed_device() because it uses |
636 | * quick writes for probing and at least some RC receiver | 594 | * quick writes for probing and at least some RC receiver |
@@ -646,7 +604,7 @@ void cx88_i2c_init_ir(struct cx88_core *core) | |||
646 | /* Hauppauge XVR */ | 604 | /* Hauppauge XVR */ |
647 | core->init_data.name = "cx88 Hauppauge XVR remote"; | 605 | core->init_data.name = "cx88 Hauppauge XVR remote"; |
648 | core->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW; | 606 | core->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW; |
649 | core->init_data.type = IR_TYPE_RC5; | 607 | core->init_data.type = RC_TYPE_RC5; |
650 | core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; | 608 | core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; |
651 | 609 | ||
652 | info.platform_data = &core->init_data; | 610 | info.platform_data = &core->init_data; |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index d9249e5a04c9..508dabbed986 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -1156,15 +1156,6 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, | |||
1156 | return 0; | 1156 | return 0; |
1157 | } | 1157 | } |
1158 | 1158 | ||
1159 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1160 | static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf) | ||
1161 | { | ||
1162 | struct cx8800_fh *fh = priv; | ||
1163 | |||
1164 | return videobuf_cgmbuf (get_queue(fh), mbuf, 8); | ||
1165 | } | ||
1166 | #endif | ||
1167 | |||
1168 | static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p) | 1159 | static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p) |
1169 | { | 1160 | { |
1170 | struct cx8800_fh *fh = priv; | 1161 | struct cx8800_fh *fh = priv; |
@@ -1706,9 +1697,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1706 | .vidioc_s_ctrl = vidioc_s_ctrl, | 1697 | .vidioc_s_ctrl = vidioc_s_ctrl, |
1707 | .vidioc_streamon = vidioc_streamon, | 1698 | .vidioc_streamon = vidioc_streamon, |
1708 | .vidioc_streamoff = vidioc_streamoff, | 1699 | .vidioc_streamoff = vidioc_streamoff, |
1709 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1710 | .vidiocgmbuf = vidiocgmbuf, | ||
1711 | #endif | ||
1712 | .vidioc_g_tuner = vidioc_g_tuner, | 1700 | .vidioc_g_tuner = vidioc_g_tuner, |
1713 | .vidioc_s_tuner = vidioc_s_tuner, | 1701 | .vidioc_s_tuner = vidioc_s_tuner, |
1714 | .vidioc_g_frequency = vidioc_g_frequency, | 1702 | .vidioc_g_frequency = vidioc_g_frequency, |
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c index ec5476d8b10b..d77f8ecab9d7 100644 --- a/drivers/media/video/cx88/cx88-vp3054-i2c.c +++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c | |||
@@ -125,7 +125,6 @@ int vp3054_i2c_probe(struct cx8802_dev *dev) | |||
125 | strlcpy(vp3054_i2c->adap.name, core->name, | 125 | strlcpy(vp3054_i2c->adap.name, core->name, |
126 | sizeof(vp3054_i2c->adap.name)); | 126 | sizeof(vp3054_i2c->adap.name)); |
127 | vp3054_i2c->adap.owner = THIS_MODULE; | 127 | vp3054_i2c->adap.owner = THIS_MODULE; |
128 | vp3054_i2c->adap.id = I2C_HW_B_CX2388x; | ||
129 | vp3054_i2c->algo.data = dev; | 128 | vp3054_i2c->algo.data = dev; |
130 | i2c_set_adapdata(&vp3054_i2c->adap, dev); | 129 | i2c_set_adapdata(&vp3054_i2c->adap, dev); |
131 | vp3054_i2c->adap.algo_data = &vp3054_i2c->algo; | 130 | vp3054_i2c->adap.algo_data = &vp3054_i2c->algo; |
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c deleted file mode 100644 index f3e25e91366d..000000000000 --- a/drivers/media/video/dabusb.c +++ /dev/null | |||
@@ -1,914 +0,0 @@ | |||
1 | /*****************************************************************************/ | ||
2 | |||
3 | /* | ||
4 | * dabusb.c -- dab usb driver. | ||
5 | * | ||
6 | * Copyright (C) 1999 Deti Fliegl (deti@fliegl.de) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * | ||
23 | * | ||
24 | * $Id: dabusb.c,v 1.54 2000/07/24 21:39:39 deti Exp $ | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | /*****************************************************************************/ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/socket.h> | ||
32 | #include <linux/list.h> | ||
33 | #include <linux/vmalloc.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <asm/uaccess.h> | ||
37 | #include <asm/atomic.h> | ||
38 | #include <linux/delay.h> | ||
39 | #include <linux/usb.h> | ||
40 | #include <linux/mutex.h> | ||
41 | #include <linux/firmware.h> | ||
42 | #include <linux/ihex.h> | ||
43 | |||
44 | #include "dabusb.h" | ||
45 | |||
46 | /* | ||
47 | * Version Information | ||
48 | */ | ||
49 | #define DRIVER_VERSION "v1.54" | ||
50 | #define DRIVER_AUTHOR "Deti Fliegl, deti@fliegl.de" | ||
51 | #define DRIVER_DESC "DAB-USB Interface Driver for Linux (c)1999" | ||
52 | |||
53 | /* --------------------------------------------------------------------- */ | ||
54 | |||
55 | #ifdef CONFIG_USB_DYNAMIC_MINORS | ||
56 | #define NRDABUSB 256 | ||
57 | #else | ||
58 | #define NRDABUSB 4 | ||
59 | #endif | ||
60 | |||
61 | /*-------------------------------------------------------------------*/ | ||
62 | |||
63 | static dabusb_t dabusb[NRDABUSB]; | ||
64 | static int buffers = 256; | ||
65 | static struct usb_driver dabusb_driver; | ||
66 | |||
67 | /*-------------------------------------------------------------------*/ | ||
68 | |||
69 | static int dabusb_add_buf_tail (pdabusb_t s, struct list_head *dst, struct list_head *src) | ||
70 | { | ||
71 | unsigned long flags; | ||
72 | struct list_head *tmp; | ||
73 | int ret = 0; | ||
74 | |||
75 | spin_lock_irqsave (&s->lock, flags); | ||
76 | |||
77 | if (list_empty (src)) { | ||
78 | // no elements in source buffer | ||
79 | ret = -1; | ||
80 | goto err; | ||
81 | } | ||
82 | tmp = src->next; | ||
83 | list_move_tail (tmp, dst); | ||
84 | |||
85 | err: spin_unlock_irqrestore (&s->lock, flags); | ||
86 | return ret; | ||
87 | } | ||
88 | /*-------------------------------------------------------------------*/ | ||
89 | #ifdef DEBUG | ||
90 | static void dump_urb (struct urb *urb) | ||
91 | { | ||
92 | dbg("urb :%p", urb); | ||
93 | dbg("dev :%p", urb->dev); | ||
94 | dbg("pipe :%08X", urb->pipe); | ||
95 | dbg("status :%d", urb->status); | ||
96 | dbg("transfer_flags :%08X", urb->transfer_flags); | ||
97 | dbg("transfer_buffer :%p", urb->transfer_buffer); | ||
98 | dbg("transfer_buffer_length:%d", urb->transfer_buffer_length); | ||
99 | dbg("actual_length :%d", urb->actual_length); | ||
100 | dbg("setup_packet :%p", urb->setup_packet); | ||
101 | dbg("start_frame :%d", urb->start_frame); | ||
102 | dbg("number_of_packets :%d", urb->number_of_packets); | ||
103 | dbg("interval :%d", urb->interval); | ||
104 | dbg("error_count :%d", urb->error_count); | ||
105 | dbg("context :%p", urb->context); | ||
106 | dbg("complete :%p", urb->complete); | ||
107 | } | ||
108 | #endif | ||
109 | /*-------------------------------------------------------------------*/ | ||
110 | static int dabusb_cancel_queue (pdabusb_t s, struct list_head *q) | ||
111 | { | ||
112 | unsigned long flags; | ||
113 | pbuff_t b; | ||
114 | |||
115 | dbg("dabusb_cancel_queue"); | ||
116 | |||
117 | spin_lock_irqsave (&s->lock, flags); | ||
118 | |||
119 | list_for_each_entry(b, q, buff_list) { | ||
120 | #ifdef DEBUG | ||
121 | dump_urb(b->purb); | ||
122 | #endif | ||
123 | usb_unlink_urb (b->purb); | ||
124 | } | ||
125 | spin_unlock_irqrestore (&s->lock, flags); | ||
126 | return 0; | ||
127 | } | ||
128 | /*-------------------------------------------------------------------*/ | ||
129 | static int dabusb_free_queue (struct list_head *q) | ||
130 | { | ||
131 | struct list_head *tmp; | ||
132 | struct list_head *p; | ||
133 | pbuff_t b; | ||
134 | |||
135 | dbg("dabusb_free_queue"); | ||
136 | for (p = q->next; p != q;) { | ||
137 | b = list_entry (p, buff_t, buff_list); | ||
138 | |||
139 | #ifdef DEBUG | ||
140 | dump_urb(b->purb); | ||
141 | #endif | ||
142 | kfree(b->purb->transfer_buffer); | ||
143 | usb_free_urb(b->purb); | ||
144 | tmp = p->next; | ||
145 | list_del (p); | ||
146 | kfree (b); | ||
147 | p = tmp; | ||
148 | } | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | /*-------------------------------------------------------------------*/ | ||
153 | static int dabusb_free_buffers (pdabusb_t s) | ||
154 | { | ||
155 | unsigned long flags; | ||
156 | dbg("dabusb_free_buffers"); | ||
157 | |||
158 | spin_lock_irqsave(&s->lock, flags); | ||
159 | |||
160 | dabusb_free_queue (&s->free_buff_list); | ||
161 | dabusb_free_queue (&s->rec_buff_list); | ||
162 | |||
163 | spin_unlock_irqrestore(&s->lock, flags); | ||
164 | |||
165 | s->got_mem = 0; | ||
166 | return 0; | ||
167 | } | ||
168 | /*-------------------------------------------------------------------*/ | ||
169 | static void dabusb_iso_complete (struct urb *purb) | ||
170 | { | ||
171 | pbuff_t b = purb->context; | ||
172 | pdabusb_t s = b->s; | ||
173 | int i; | ||
174 | int len; | ||
175 | int dst = 0; | ||
176 | void *buf = purb->transfer_buffer; | ||
177 | |||
178 | dbg("dabusb_iso_complete"); | ||
179 | |||
180 | // process if URB was not killed | ||
181 | if (purb->status != -ENOENT) { | ||
182 | unsigned int pipe = usb_rcvisocpipe (purb->dev, _DABUSB_ISOPIPE); | ||
183 | int pipesize = usb_maxpacket (purb->dev, pipe, usb_pipeout (pipe)); | ||
184 | for (i = 0; i < purb->number_of_packets; i++) | ||
185 | if (!purb->iso_frame_desc[i].status) { | ||
186 | len = purb->iso_frame_desc[i].actual_length; | ||
187 | if (len <= pipesize) { | ||
188 | memcpy (buf + dst, buf + purb->iso_frame_desc[i].offset, len); | ||
189 | dst += len; | ||
190 | } | ||
191 | else | ||
192 | dev_err(&purb->dev->dev, | ||
193 | "dabusb_iso_complete: invalid len %d\n", len); | ||
194 | } | ||
195 | else | ||
196 | dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status); | ||
197 | if (dst != purb->actual_length) | ||
198 | dev_err(&purb->dev->dev, | ||
199 | "dst!=purb->actual_length:%d!=%d\n", | ||
200 | dst, purb->actual_length); | ||
201 | } | ||
202 | |||
203 | if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) { | ||
204 | s->overruns++; | ||
205 | dev_err(&purb->dev->dev, "overrun (%d)\n", s->overruns); | ||
206 | } | ||
207 | wake_up (&s->wait); | ||
208 | } | ||
209 | /*-------------------------------------------------------------------*/ | ||
210 | static int dabusb_alloc_buffers (pdabusb_t s) | ||
211 | { | ||
212 | int transfer_len = 0; | ||
213 | pbuff_t b; | ||
214 | unsigned int pipe = usb_rcvisocpipe (s->usbdev, _DABUSB_ISOPIPE); | ||
215 | int pipesize = usb_maxpacket (s->usbdev, pipe, usb_pipeout (pipe)); | ||
216 | int packets = _ISOPIPESIZE / pipesize; | ||
217 | int transfer_buffer_length = packets * pipesize; | ||
218 | int i; | ||
219 | |||
220 | dbg("dabusb_alloc_buffers pipesize:%d packets:%d transfer_buffer_len:%d", | ||
221 | pipesize, packets, transfer_buffer_length); | ||
222 | |||
223 | while (transfer_len < (s->total_buffer_size << 10)) { | ||
224 | b = kzalloc(sizeof (buff_t), GFP_KERNEL); | ||
225 | if (!b) { | ||
226 | dev_err(&s->usbdev->dev, | ||
227 | "kzalloc(sizeof(buff_t))==NULL\n"); | ||
228 | goto err; | ||
229 | } | ||
230 | b->s = s; | ||
231 | b->purb = usb_alloc_urb(packets, GFP_KERNEL); | ||
232 | if (!b->purb) { | ||
233 | dev_err(&s->usbdev->dev, "usb_alloc_urb == NULL\n"); | ||
234 | kfree (b); | ||
235 | goto err; | ||
236 | } | ||
237 | |||
238 | b->purb->transfer_buffer = kmalloc (transfer_buffer_length, GFP_KERNEL); | ||
239 | if (!b->purb->transfer_buffer) { | ||
240 | kfree (b->purb); | ||
241 | kfree (b); | ||
242 | dev_err(&s->usbdev->dev, | ||
243 | "kmalloc(%d)==NULL\n", transfer_buffer_length); | ||
244 | goto err; | ||
245 | } | ||
246 | |||
247 | b->purb->transfer_buffer_length = transfer_buffer_length; | ||
248 | b->purb->number_of_packets = packets; | ||
249 | b->purb->complete = dabusb_iso_complete; | ||
250 | b->purb->context = b; | ||
251 | b->purb->dev = s->usbdev; | ||
252 | b->purb->pipe = pipe; | ||
253 | b->purb->transfer_flags = URB_ISO_ASAP; | ||
254 | |||
255 | for (i = 0; i < packets; i++) { | ||
256 | b->purb->iso_frame_desc[i].offset = i * pipesize; | ||
257 | b->purb->iso_frame_desc[i].length = pipesize; | ||
258 | } | ||
259 | |||
260 | transfer_len += transfer_buffer_length; | ||
261 | list_add_tail (&b->buff_list, &s->free_buff_list); | ||
262 | } | ||
263 | s->got_mem = transfer_len; | ||
264 | |||
265 | return 0; | ||
266 | |||
267 | err: | ||
268 | dabusb_free_buffers (s); | ||
269 | return -ENOMEM; | ||
270 | } | ||
271 | /*-------------------------------------------------------------------*/ | ||
272 | static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb) | ||
273 | { | ||
274 | int ret; | ||
275 | unsigned int pipe; | ||
276 | int actual_length; | ||
277 | |||
278 | dbg("dabusb_bulk"); | ||
279 | |||
280 | if (!pb->pipe) | ||
281 | pipe = usb_rcvbulkpipe (s->usbdev, 2); | ||
282 | else | ||
283 | pipe = usb_sndbulkpipe (s->usbdev, 2); | ||
284 | |||
285 | ret=usb_bulk_msg(s->usbdev, pipe, pb->data, pb->size, &actual_length, 100); | ||
286 | if(ret<0) { | ||
287 | dev_err(&s->usbdev->dev, | ||
288 | "usb_bulk_msg failed(%d)\n", ret); | ||
289 | |||
290 | if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) { | ||
291 | dev_err(&s->usbdev->dev, "set_interface failed\n"); | ||
292 | return -EINVAL; | ||
293 | } | ||
294 | |||
295 | } | ||
296 | |||
297 | if( ret == -EPIPE ) { | ||
298 | dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n"); | ||
299 | if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe))) | ||
300 | dev_err(&s->usbdev->dev, "request failed\n"); | ||
301 | } | ||
302 | |||
303 | pb->size = actual_length; | ||
304 | return ret; | ||
305 | } | ||
306 | /* --------------------------------------------------------------------- */ | ||
307 | static int dabusb_writemem (pdabusb_t s, int pos, const unsigned char *data, | ||
308 | int len) | ||
309 | { | ||
310 | int ret; | ||
311 | unsigned char *transfer_buffer = kmalloc (len, GFP_KERNEL); | ||
312 | |||
313 | if (!transfer_buffer) { | ||
314 | dev_err(&s->usbdev->dev, | ||
315 | "dabusb_writemem: kmalloc(%d) failed.\n", len); | ||
316 | return -ENOMEM; | ||
317 | } | ||
318 | |||
319 | memcpy (transfer_buffer, data, len); | ||
320 | |||
321 | ret=usb_control_msg(s->usbdev, usb_sndctrlpipe( s->usbdev, 0 ), 0xa0, 0x40, pos, 0, transfer_buffer, len, 300); | ||
322 | |||
323 | kfree (transfer_buffer); | ||
324 | return ret; | ||
325 | } | ||
326 | /* --------------------------------------------------------------------- */ | ||
327 | static int dabusb_8051_reset (pdabusb_t s, unsigned char reset_bit) | ||
328 | { | ||
329 | dbg("dabusb_8051_reset: %d",reset_bit); | ||
330 | return dabusb_writemem (s, CPUCS_REG, &reset_bit, 1); | ||
331 | } | ||
332 | /* --------------------------------------------------------------------- */ | ||
333 | static int dabusb_loadmem (pdabusb_t s, const char *fname) | ||
334 | { | ||
335 | int ret; | ||
336 | const struct ihex_binrec *rec; | ||
337 | const struct firmware *uninitialized_var(fw); | ||
338 | |||
339 | dbg("Enter dabusb_loadmem (internal)"); | ||
340 | |||
341 | ret = request_ihex_firmware(&fw, "dabusb/firmware.fw", &s->usbdev->dev); | ||
342 | if (ret) { | ||
343 | dev_err(&s->usbdev->dev, | ||
344 | "Failed to load \"dabusb/firmware.fw\": %d\n", ret); | ||
345 | goto out; | ||
346 | } | ||
347 | ret = dabusb_8051_reset (s, 1); | ||
348 | |||
349 | for (rec = (const struct ihex_binrec *)fw->data; rec; | ||
350 | rec = ihex_next_binrec(rec)) { | ||
351 | dbg("dabusb_writemem: %04X %p %d)", be32_to_cpu(rec->addr), | ||
352 | rec->data, be16_to_cpu(rec->len)); | ||
353 | |||
354 | ret = dabusb_writemem(s, be32_to_cpu(rec->addr), rec->data, | ||
355 | be16_to_cpu(rec->len)); | ||
356 | if (ret < 0) { | ||
357 | dev_err(&s->usbdev->dev, | ||
358 | "dabusb_writemem failed (%d %04X %p %d)\n", | ||
359 | ret, be32_to_cpu(rec->addr), | ||
360 | rec->data, be16_to_cpu(rec->len)); | ||
361 | break; | ||
362 | } | ||
363 | } | ||
364 | ret = dabusb_8051_reset (s, 0); | ||
365 | release_firmware(fw); | ||
366 | out: | ||
367 | dbg("dabusb_loadmem: exit"); | ||
368 | |||
369 | return ret; | ||
370 | } | ||
371 | /* --------------------------------------------------------------------- */ | ||
372 | static int dabusb_fpga_clear (pdabusb_t s, pbulk_transfer_t b) | ||
373 | { | ||
374 | b->size = 4; | ||
375 | b->data[0] = 0x2a; | ||
376 | b->data[1] = 0; | ||
377 | b->data[2] = 0; | ||
378 | b->data[3] = 0; | ||
379 | |||
380 | dbg("dabusb_fpga_clear"); | ||
381 | |||
382 | return dabusb_bulk (s, b); | ||
383 | } | ||
384 | /* --------------------------------------------------------------------- */ | ||
385 | static int dabusb_fpga_init (pdabusb_t s, pbulk_transfer_t b) | ||
386 | { | ||
387 | b->size = 4; | ||
388 | b->data[0] = 0x2c; | ||
389 | b->data[1] = 0; | ||
390 | b->data[2] = 0; | ||
391 | b->data[3] = 0; | ||
392 | |||
393 | dbg("dabusb_fpga_init"); | ||
394 | |||
395 | return dabusb_bulk (s, b); | ||
396 | } | ||
397 | /* --------------------------------------------------------------------- */ | ||
398 | static int dabusb_fpga_download (pdabusb_t s, const char *fname) | ||
399 | { | ||
400 | pbulk_transfer_t b = kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL); | ||
401 | const struct firmware *fw; | ||
402 | unsigned int blen, n; | ||
403 | int ret; | ||
404 | |||
405 | dbg("Enter dabusb_fpga_download (internal)"); | ||
406 | |||
407 | if (!b) { | ||
408 | dev_err(&s->usbdev->dev, | ||
409 | "kmalloc(sizeof(bulk_transfer_t))==NULL\n"); | ||
410 | return -ENOMEM; | ||
411 | } | ||
412 | |||
413 | ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev); | ||
414 | if (ret) { | ||
415 | dev_err(&s->usbdev->dev, | ||
416 | "Failed to load \"dabusb/bitstream.bin\": %d\n", ret); | ||
417 | kfree(b); | ||
418 | return ret; | ||
419 | } | ||
420 | |||
421 | b->pipe = 1; | ||
422 | ret = dabusb_fpga_clear (s, b); | ||
423 | mdelay (10); | ||
424 | blen = fw->data[73] + (fw->data[72] << 8); | ||
425 | |||
426 | dbg("Bitstream len: %i", blen); | ||
427 | |||
428 | b->data[0] = 0x2b; | ||
429 | b->data[1] = 0; | ||
430 | b->data[2] = 0; | ||
431 | b->data[3] = 60; | ||
432 | |||
433 | for (n = 0; n <= blen + 60; n += 60) { | ||
434 | // some cclks for startup | ||
435 | b->size = 64; | ||
436 | memcpy (b->data + 4, fw->data + 74 + n, 60); | ||
437 | ret = dabusb_bulk (s, b); | ||
438 | if (ret < 0) { | ||
439 | dev_err(&s->usbdev->dev, "dabusb_bulk failed.\n"); | ||
440 | break; | ||
441 | } | ||
442 | mdelay (1); | ||
443 | } | ||
444 | |||
445 | ret = dabusb_fpga_init (s, b); | ||
446 | kfree (b); | ||
447 | release_firmware(fw); | ||
448 | |||
449 | dbg("exit dabusb_fpga_download"); | ||
450 | |||
451 | return ret; | ||
452 | } | ||
453 | |||
454 | static int dabusb_stop (pdabusb_t s) | ||
455 | { | ||
456 | dbg("dabusb_stop"); | ||
457 | |||
458 | s->state = _stopped; | ||
459 | dabusb_cancel_queue (s, &s->rec_buff_list); | ||
460 | |||
461 | dbg("pending_io: %d", s->pending_io.counter); | ||
462 | |||
463 | s->pending_io.counter = 0; | ||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | static int dabusb_startrek (pdabusb_t s) | ||
468 | { | ||
469 | if (!s->got_mem && s->state != _started) { | ||
470 | |||
471 | dbg("dabusb_startrek"); | ||
472 | |||
473 | if (dabusb_alloc_buffers (s) < 0) | ||
474 | return -ENOMEM; | ||
475 | dabusb_stop (s); | ||
476 | s->state = _started; | ||
477 | s->readptr = 0; | ||
478 | } | ||
479 | |||
480 | if (!list_empty (&s->free_buff_list)) { | ||
481 | pbuff_t end; | ||
482 | int ret; | ||
483 | |||
484 | while (!dabusb_add_buf_tail (s, &s->rec_buff_list, &s->free_buff_list)) { | ||
485 | |||
486 | dbg("submitting: end:%p s->rec_buff_list:%p", s->rec_buff_list.prev, &s->rec_buff_list); | ||
487 | |||
488 | end = list_entry (s->rec_buff_list.prev, buff_t, buff_list); | ||
489 | |||
490 | ret = usb_submit_urb (end->purb, GFP_KERNEL); | ||
491 | if (ret) { | ||
492 | dev_err(&s->usbdev->dev, | ||
493 | "usb_submit_urb returned:%d\n", ret); | ||
494 | if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list)) | ||
495 | dev_err(&s->usbdev->dev, | ||
496 | "startrek: dabusb_add_buf_tail failed\n"); | ||
497 | break; | ||
498 | } | ||
499 | else | ||
500 | atomic_inc (&s->pending_io); | ||
501 | } | ||
502 | dbg("pending_io: %d",s->pending_io.counter); | ||
503 | } | ||
504 | |||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, loff_t * ppos) | ||
509 | { | ||
510 | pdabusb_t s = (pdabusb_t) file->private_data; | ||
511 | unsigned long flags; | ||
512 | unsigned ret = 0; | ||
513 | int rem; | ||
514 | int cnt; | ||
515 | pbuff_t b; | ||
516 | struct urb *purb = NULL; | ||
517 | |||
518 | dbg("dabusb_read"); | ||
519 | |||
520 | if (*ppos) | ||
521 | return -ESPIPE; | ||
522 | |||
523 | if (s->remove_pending) | ||
524 | return -EIO; | ||
525 | |||
526 | |||
527 | if (!s->usbdev) | ||
528 | return -EIO; | ||
529 | |||
530 | while (count > 0) { | ||
531 | dabusb_startrek (s); | ||
532 | |||
533 | spin_lock_irqsave (&s->lock, flags); | ||
534 | |||
535 | if (list_empty (&s->rec_buff_list)) { | ||
536 | |||
537 | spin_unlock_irqrestore(&s->lock, flags); | ||
538 | |||
539 | dev_err(&s->usbdev->dev, | ||
540 | "error: rec_buf_list is empty\n"); | ||
541 | goto err; | ||
542 | } | ||
543 | |||
544 | b = list_entry (s->rec_buff_list.next, buff_t, buff_list); | ||
545 | purb = b->purb; | ||
546 | |||
547 | spin_unlock_irqrestore(&s->lock, flags); | ||
548 | |||
549 | if (purb->status == -EINPROGRESS) { | ||
550 | if (file->f_flags & O_NONBLOCK) // return nonblocking | ||
551 | { | ||
552 | if (!ret) | ||
553 | ret = -EAGAIN; | ||
554 | goto err; | ||
555 | } | ||
556 | |||
557 | interruptible_sleep_on (&s->wait); | ||
558 | |||
559 | if (signal_pending (current)) { | ||
560 | if (!ret) | ||
561 | ret = -ERESTARTSYS; | ||
562 | goto err; | ||
563 | } | ||
564 | |||
565 | spin_lock_irqsave (&s->lock, flags); | ||
566 | |||
567 | if (list_empty (&s->rec_buff_list)) { | ||
568 | spin_unlock_irqrestore(&s->lock, flags); | ||
569 | dev_err(&s->usbdev->dev, | ||
570 | "error: still no buffer available.\n"); | ||
571 | goto err; | ||
572 | } | ||
573 | spin_unlock_irqrestore(&s->lock, flags); | ||
574 | s->readptr = 0; | ||
575 | } | ||
576 | if (s->remove_pending) { | ||
577 | ret = -EIO; | ||
578 | goto err; | ||
579 | } | ||
580 | |||
581 | rem = purb->actual_length - s->readptr; // set remaining bytes to copy | ||
582 | |||
583 | if (count >= rem) | ||
584 | cnt = rem; | ||
585 | else | ||
586 | cnt = count; | ||
587 | |||
588 | dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt); | ||
589 | |||
590 | if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) { | ||
591 | dev_err(&s->usbdev->dev, "read: copy_to_user failed\n"); | ||
592 | if (!ret) | ||
593 | ret = -EFAULT; | ||
594 | goto err; | ||
595 | } | ||
596 | |||
597 | s->readptr += cnt; | ||
598 | count -= cnt; | ||
599 | buf += cnt; | ||
600 | ret += cnt; | ||
601 | |||
602 | if (s->readptr == purb->actual_length) { | ||
603 | // finished, take next buffer | ||
604 | if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list)) | ||
605 | dev_err(&s->usbdev->dev, | ||
606 | "read: dabusb_add_buf_tail failed\n"); | ||
607 | s->readptr = 0; | ||
608 | } | ||
609 | } | ||
610 | err: //mutex_unlock(&s->mutex); | ||
611 | return ret; | ||
612 | } | ||
613 | |||
614 | static int dabusb_open (struct inode *inode, struct file *file) | ||
615 | { | ||
616 | int devnum = iminor(inode); | ||
617 | pdabusb_t s; | ||
618 | int r; | ||
619 | |||
620 | if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB)) | ||
621 | return -EIO; | ||
622 | |||
623 | s = &dabusb[devnum - DABUSB_MINOR]; | ||
624 | |||
625 | dbg("dabusb_open"); | ||
626 | mutex_lock(&s->mutex); | ||
627 | |||
628 | while (!s->usbdev || s->opened) { | ||
629 | mutex_unlock(&s->mutex); | ||
630 | |||
631 | if (file->f_flags & O_NONBLOCK) | ||
632 | return -EBUSY; | ||
633 | msleep_interruptible(500); | ||
634 | |||
635 | if (signal_pending (current)) | ||
636 | return -EAGAIN; | ||
637 | mutex_lock(&s->mutex); | ||
638 | } | ||
639 | if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) { | ||
640 | mutex_unlock(&s->mutex); | ||
641 | dev_err(&s->usbdev->dev, "set_interface failed\n"); | ||
642 | return -EINVAL; | ||
643 | } | ||
644 | s->opened = 1; | ||
645 | mutex_unlock(&s->mutex); | ||
646 | |||
647 | file->f_pos = 0; | ||
648 | file->private_data = s; | ||
649 | |||
650 | r = nonseekable_open(inode, file); | ||
651 | return r; | ||
652 | } | ||
653 | |||
654 | static int dabusb_release (struct inode *inode, struct file *file) | ||
655 | { | ||
656 | pdabusb_t s = (pdabusb_t) file->private_data; | ||
657 | |||
658 | dbg("dabusb_release"); | ||
659 | |||
660 | mutex_lock(&s->mutex); | ||
661 | dabusb_stop (s); | ||
662 | dabusb_free_buffers (s); | ||
663 | mutex_unlock(&s->mutex); | ||
664 | |||
665 | if (!s->remove_pending) { | ||
666 | if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) | ||
667 | dev_err(&s->usbdev->dev, "set_interface failed\n"); | ||
668 | } | ||
669 | else | ||
670 | wake_up (&s->remove_ok); | ||
671 | |||
672 | s->opened = 0; | ||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg) | ||
677 | { | ||
678 | pdabusb_t s = (pdabusb_t) file->private_data; | ||
679 | pbulk_transfer_t pbulk; | ||
680 | int ret = 0; | ||
681 | int version = DABUSB_VERSION; | ||
682 | |||
683 | dbg("dabusb_ioctl"); | ||
684 | |||
685 | if (s->remove_pending) | ||
686 | return -EIO; | ||
687 | |||
688 | mutex_lock(&s->mutex); | ||
689 | |||
690 | if (!s->usbdev) { | ||
691 | mutex_unlock(&s->mutex); | ||
692 | return -EIO; | ||
693 | } | ||
694 | |||
695 | switch (cmd) { | ||
696 | |||
697 | case IOCTL_DAB_BULK: | ||
698 | pbulk = memdup_user((void __user *)arg, | ||
699 | sizeof(bulk_transfer_t)); | ||
700 | |||
701 | if (IS_ERR(pbulk)) { | ||
702 | ret = PTR_ERR(pbulk); | ||
703 | break; | ||
704 | } | ||
705 | |||
706 | ret=dabusb_bulk (s, pbulk); | ||
707 | if(ret==0) | ||
708 | if (copy_to_user((void __user *)arg, pbulk, | ||
709 | sizeof(bulk_transfer_t))) | ||
710 | ret = -EFAULT; | ||
711 | kfree (pbulk); | ||
712 | break; | ||
713 | |||
714 | case IOCTL_DAB_OVERRUNS: | ||
715 | ret = put_user (s->overruns, (unsigned int __user *) arg); | ||
716 | break; | ||
717 | |||
718 | case IOCTL_DAB_VERSION: | ||
719 | ret = put_user (version, (unsigned int __user *) arg); | ||
720 | break; | ||
721 | |||
722 | default: | ||
723 | ret = -ENOIOCTLCMD; | ||
724 | break; | ||
725 | } | ||
726 | mutex_unlock(&s->mutex); | ||
727 | return ret; | ||
728 | } | ||
729 | |||
730 | static const struct file_operations dabusb_fops = | ||
731 | { | ||
732 | .owner = THIS_MODULE, | ||
733 | .llseek = no_llseek, | ||
734 | .read = dabusb_read, | ||
735 | .unlocked_ioctl = dabusb_ioctl, | ||
736 | .open = dabusb_open, | ||
737 | .release = dabusb_release, | ||
738 | }; | ||
739 | |||
740 | static char *dabusb_devnode(struct device *dev, mode_t *mode) | ||
741 | { | ||
742 | return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); | ||
743 | } | ||
744 | |||
745 | static struct usb_class_driver dabusb_class = { | ||
746 | .name = "dabusb%d", | ||
747 | .devnode = dabusb_devnode, | ||
748 | .fops = &dabusb_fops, | ||
749 | .minor_base = DABUSB_MINOR, | ||
750 | }; | ||
751 | |||
752 | |||
753 | /* --------------------------------------------------------------------- */ | ||
754 | static int dabusb_probe (struct usb_interface *intf, | ||
755 | const struct usb_device_id *id) | ||
756 | { | ||
757 | struct usb_device *usbdev = interface_to_usbdev(intf); | ||
758 | int retval; | ||
759 | pdabusb_t s; | ||
760 | |||
761 | dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d", | ||
762 | le16_to_cpu(usbdev->descriptor.idVendor), | ||
763 | le16_to_cpu(usbdev->descriptor.idProduct), | ||
764 | intf->altsetting->desc.bInterfaceNumber); | ||
765 | |||
766 | /* We don't handle multiple configurations */ | ||
767 | if (usbdev->descriptor.bNumConfigurations != 1) | ||
768 | return -ENODEV; | ||
769 | |||
770 | if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF && | ||
771 | le16_to_cpu(usbdev->descriptor.idProduct) == 0x9999) | ||
772 | return -ENODEV; | ||
773 | |||
774 | |||
775 | |||
776 | s = &dabusb[intf->minor]; | ||
777 | |||
778 | mutex_lock(&s->mutex); | ||
779 | s->remove_pending = 0; | ||
780 | s->usbdev = usbdev; | ||
781 | s->devnum = intf->minor; | ||
782 | |||
783 | if (usb_reset_configuration (usbdev) < 0) { | ||
784 | dev_err(&intf->dev, "reset_configuration failed\n"); | ||
785 | goto reject; | ||
786 | } | ||
787 | if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) { | ||
788 | dabusb_loadmem (s, NULL); | ||
789 | goto reject; | ||
790 | } | ||
791 | else { | ||
792 | dabusb_fpga_download (s, NULL); | ||
793 | |||
794 | if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) { | ||
795 | dev_err(&intf->dev, "set_interface failed\n"); | ||
796 | goto reject; | ||
797 | } | ||
798 | } | ||
799 | dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber); | ||
800 | usb_set_intfdata (intf, s); | ||
801 | mutex_unlock(&s->mutex); | ||
802 | |||
803 | retval = usb_register_dev(intf, &dabusb_class); | ||
804 | if (retval) { | ||
805 | usb_set_intfdata (intf, NULL); | ||
806 | return -ENOMEM; | ||
807 | } | ||
808 | |||
809 | return 0; | ||
810 | |||
811 | reject: | ||
812 | mutex_unlock(&s->mutex); | ||
813 | s->usbdev = NULL; | ||
814 | return -ENODEV; | ||
815 | } | ||
816 | |||
817 | static void dabusb_disconnect (struct usb_interface *intf) | ||
818 | { | ||
819 | wait_queue_t __wait; | ||
820 | pdabusb_t s = usb_get_intfdata (intf); | ||
821 | |||
822 | dbg("dabusb_disconnect"); | ||
823 | |||
824 | init_waitqueue_entry(&__wait, current); | ||
825 | |||
826 | usb_set_intfdata (intf, NULL); | ||
827 | if (s) { | ||
828 | usb_deregister_dev (intf, &dabusb_class); | ||
829 | s->remove_pending = 1; | ||
830 | wake_up (&s->wait); | ||
831 | add_wait_queue(&s->remove_ok, &__wait); | ||
832 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
833 | if (s->state == _started) | ||
834 | schedule(); | ||
835 | current->state = TASK_RUNNING; | ||
836 | remove_wait_queue(&s->remove_ok, &__wait); | ||
837 | |||
838 | s->usbdev = NULL; | ||
839 | s->overruns = 0; | ||
840 | } | ||
841 | } | ||
842 | |||
843 | static struct usb_device_id dabusb_ids [] = { | ||
844 | // { USB_DEVICE(0x0547, 0x2131) }, /* An2131 chip, no boot ROM */ | ||
845 | { USB_DEVICE(0x0547, 0x9999) }, | ||
846 | { } /* Terminating entry */ | ||
847 | }; | ||
848 | |||
849 | MODULE_DEVICE_TABLE (usb, dabusb_ids); | ||
850 | |||
851 | static struct usb_driver dabusb_driver = { | ||
852 | .name = "dabusb", | ||
853 | .probe = dabusb_probe, | ||
854 | .disconnect = dabusb_disconnect, | ||
855 | .id_table = dabusb_ids, | ||
856 | }; | ||
857 | |||
858 | /* --------------------------------------------------------------------- */ | ||
859 | |||
860 | static int __init dabusb_init (void) | ||
861 | { | ||
862 | int retval; | ||
863 | unsigned u; | ||
864 | |||
865 | /* initialize struct */ | ||
866 | for (u = 0; u < NRDABUSB; u++) { | ||
867 | pdabusb_t s = &dabusb[u]; | ||
868 | memset (s, 0, sizeof (dabusb_t)); | ||
869 | mutex_init (&s->mutex); | ||
870 | s->usbdev = NULL; | ||
871 | s->total_buffer_size = buffers; | ||
872 | init_waitqueue_head (&s->wait); | ||
873 | init_waitqueue_head (&s->remove_ok); | ||
874 | spin_lock_init (&s->lock); | ||
875 | INIT_LIST_HEAD (&s->free_buff_list); | ||
876 | INIT_LIST_HEAD (&s->rec_buff_list); | ||
877 | } | ||
878 | |||
879 | /* register misc device */ | ||
880 | retval = usb_register(&dabusb_driver); | ||
881 | if (retval) | ||
882 | goto out; | ||
883 | |||
884 | dbg("dabusb_init: driver registered"); | ||
885 | |||
886 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" | ||
887 | DRIVER_DESC "\n"); | ||
888 | |||
889 | out: | ||
890 | return retval; | ||
891 | } | ||
892 | |||
893 | static void __exit dabusb_cleanup (void) | ||
894 | { | ||
895 | dbg("dabusb_cleanup"); | ||
896 | |||
897 | usb_deregister (&dabusb_driver); | ||
898 | } | ||
899 | |||
900 | /* --------------------------------------------------------------------- */ | ||
901 | |||
902 | MODULE_AUTHOR( DRIVER_AUTHOR ); | ||
903 | MODULE_DESCRIPTION( DRIVER_DESC ); | ||
904 | MODULE_LICENSE("GPL"); | ||
905 | MODULE_FIRMWARE("dabusb/firmware.fw"); | ||
906 | MODULE_FIRMWARE("dabusb/bitstream.bin"); | ||
907 | |||
908 | module_param(buffers, int, 0); | ||
909 | MODULE_PARM_DESC (buffers, "Number of buffers (default=256)"); | ||
910 | |||
911 | module_init (dabusb_init); | ||
912 | module_exit (dabusb_cleanup); | ||
913 | |||
914 | /* --------------------------------------------------------------------- */ | ||
diff --git a/drivers/media/video/dabusb.h b/drivers/media/video/dabusb.h deleted file mode 100644 index 00eb34c863eb..000000000000 --- a/drivers/media/video/dabusb.h +++ /dev/null | |||
@@ -1,85 +0,0 @@ | |||
1 | #define _BULK_DATA_LEN 64 | ||
2 | typedef struct | ||
3 | { | ||
4 | unsigned char data[_BULK_DATA_LEN]; | ||
5 | unsigned int size; | ||
6 | unsigned int pipe; | ||
7 | }bulk_transfer_t,*pbulk_transfer_t; | ||
8 | |||
9 | #define DABUSB_MINOR 240 /* some unassigned USB minor */ | ||
10 | #define DABUSB_VERSION 0x1000 | ||
11 | #define IOCTL_DAB_BULK _IOWR('d', 0x30, bulk_transfer_t) | ||
12 | #define IOCTL_DAB_OVERRUNS _IOR('d', 0x15, int) | ||
13 | #define IOCTL_DAB_VERSION _IOR('d', 0x3f, int) | ||
14 | |||
15 | #ifdef __KERNEL__ | ||
16 | |||
17 | typedef enum { _stopped=0, _started } driver_state_t; | ||
18 | |||
19 | typedef struct | ||
20 | { | ||
21 | struct mutex mutex; | ||
22 | struct usb_device *usbdev; | ||
23 | wait_queue_head_t wait; | ||
24 | wait_queue_head_t remove_ok; | ||
25 | spinlock_t lock; | ||
26 | atomic_t pending_io; | ||
27 | driver_state_t state; | ||
28 | int remove_pending; | ||
29 | int got_mem; | ||
30 | int total_buffer_size; | ||
31 | unsigned int overruns; | ||
32 | int readptr; | ||
33 | int opened; | ||
34 | int devnum; | ||
35 | struct list_head free_buff_list; | ||
36 | struct list_head rec_buff_list; | ||
37 | } dabusb_t,*pdabusb_t; | ||
38 | |||
39 | typedef struct | ||
40 | { | ||
41 | pdabusb_t s; | ||
42 | struct urb *purb; | ||
43 | struct list_head buff_list; | ||
44 | } buff_t,*pbuff_t; | ||
45 | |||
46 | typedef struct | ||
47 | { | ||
48 | wait_queue_head_t wait; | ||
49 | } bulk_completion_context_t, *pbulk_completion_context_t; | ||
50 | |||
51 | |||
52 | #define _DABUSB_IF 2 | ||
53 | #define _DABUSB_ISOPIPE 0x09 | ||
54 | #define _ISOPIPESIZE 16384 | ||
55 | |||
56 | #define _BULK_DATA_LEN 64 | ||
57 | // Vendor specific request code for Anchor Upload/Download | ||
58 | // This one is implemented in the core | ||
59 | #define ANCHOR_LOAD_INTERNAL 0xA0 | ||
60 | |||
61 | // EZ-USB Control and Status Register. Bit 0 controls 8051 reset | ||
62 | #define CPUCS_REG 0x7F92 | ||
63 | #define _TOTAL_BUFFERS 384 | ||
64 | |||
65 | #define MAX_INTEL_HEX_RECORD_LENGTH 16 | ||
66 | |||
67 | #ifndef _BYTE_DEFINED | ||
68 | #define _BYTE_DEFINED | ||
69 | typedef unsigned char BYTE; | ||
70 | #endif // !_BYTE_DEFINED | ||
71 | |||
72 | #ifndef _WORD_DEFINED | ||
73 | #define _WORD_DEFINED | ||
74 | typedef unsigned short WORD; | ||
75 | #endif // !_WORD_DEFINED | ||
76 | |||
77 | typedef struct _INTEL_HEX_RECORD | ||
78 | { | ||
79 | BYTE Length; | ||
80 | WORD Address; | ||
81 | BYTE Type; | ||
82 | BYTE Data[MAX_INTEL_HEX_RECORD_LENGTH]; | ||
83 | } INTEL_HEX_RECORD, *PINTEL_HEX_RECORD; | ||
84 | |||
85 | #endif | ||
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index 7333a9bb2549..353eadaa823e 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c | |||
@@ -1276,7 +1276,7 @@ static int vpfe_videobuf_prepare(struct videobuf_queue *vq, | |||
1276 | vb->size = vpfe_dev->fmt.fmt.pix.sizeimage; | 1276 | vb->size = vpfe_dev->fmt.fmt.pix.sizeimage; |
1277 | vb->field = field; | 1277 | vb->field = field; |
1278 | 1278 | ||
1279 | ret = videobuf_iolock(vq, vb, NULL);; | 1279 | ret = videobuf_iolock(vq, vb, NULL); |
1280 | if (ret < 0) | 1280 | if (ret < 0) |
1281 | return ret; | 1281 | return ret; |
1282 | 1282 | ||
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig index 66aefd6eef55..985100ea17a4 100644 --- a/drivers/media/video/em28xx/Kconfig +++ b/drivers/media/video/em28xx/Kconfig | |||
@@ -1,9 +1,9 @@ | |||
1 | config VIDEO_EM28XX | 1 | config VIDEO_EM28XX |
2 | tristate "Empia EM28xx USB video capture support" | 2 | tristate "Empia EM28xx USB video capture support" |
3 | depends on VIDEO_DEV && I2C && INPUT | 3 | depends on VIDEO_DEV && I2C |
4 | select VIDEO_TUNER | 4 | select VIDEO_TUNER |
5 | select VIDEO_TVEEPROM | 5 | select VIDEO_TVEEPROM |
6 | depends on VIDEO_IR | 6 | depends on RC_CORE |
7 | select VIDEOBUF_VMALLOC | 7 | select VIDEOBUF_VMALLOC |
8 | select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO | 8 | select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO |
9 | select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO | 9 | select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO |
@@ -37,6 +37,7 @@ config VIDEO_EM28XX_DVB | |||
37 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | 37 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE |
38 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | 38 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE |
39 | select DVB_TDA10023 if !DVB_FE_CUSTOMISE | 39 | select DVB_TDA10023 if !DVB_FE_CUSTOMISE |
40 | select DVB_S921 if !DVB_FE_CUSTOMISE | ||
40 | select VIDEOBUF_DVB | 41 | select VIDEOBUF_DVB |
41 | ---help--- | 42 | ---help--- |
42 | This adds support for DVB cards based on the | 43 | This adds support for DVB cards based on the |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index f7e9168157a5..8af302b425b3 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -268,6 +268,20 @@ static struct em28xx_reg_seq dikom_dk300_digital[] = { | |||
268 | }; | 268 | }; |
269 | 269 | ||
270 | 270 | ||
271 | /* Reset for the most [digital] boards */ | ||
272 | static struct em28xx_reg_seq leadership_digital[] = { | ||
273 | {EM2874_R80_GPIO, 0x70, 0xff, 10}, | ||
274 | { -1, -1, -1, -1}, | ||
275 | }; | ||
276 | |||
277 | static struct em28xx_reg_seq leadership_reset[] = { | ||
278 | {EM2874_R80_GPIO, 0xf0, 0xff, 10}, | ||
279 | {EM2874_R80_GPIO, 0xb0, 0xff, 10}, | ||
280 | {EM2874_R80_GPIO, 0xf0, 0xff, 10}, | ||
281 | { -1, -1, -1, -1}, | ||
282 | }; | ||
283 | |||
284 | |||
271 | /* | 285 | /* |
272 | * Board definitions | 286 | * Board definitions |
273 | */ | 287 | */ |
@@ -1224,6 +1238,19 @@ struct em28xx_board em28xx_boards[] = { | |||
1224 | .vmux = SAA7115_COMPOSITE0, | 1238 | .vmux = SAA7115_COMPOSITE0, |
1225 | } }, | 1239 | } }, |
1226 | }, | 1240 | }, |
1241 | |||
1242 | [EM2874_LEADERSHIP_ISDBT] = { | ||
1243 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
1244 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
1245 | EM28XX_I2C_FREQ_100_KHZ, | ||
1246 | .xclk = EM28XX_XCLK_FREQUENCY_10MHZ, | ||
1247 | .name = "EM2874 Leadership ISDBT", | ||
1248 | .tuner_type = TUNER_ABSENT, | ||
1249 | .tuner_gpio = leadership_reset, | ||
1250 | .dvb_gpio = leadership_digital, | ||
1251 | .has_dvb = 1, | ||
1252 | }, | ||
1253 | |||
1227 | [EM2880_BOARD_MSI_DIGIVOX_AD] = { | 1254 | [EM2880_BOARD_MSI_DIGIVOX_AD] = { |
1228 | .name = "MSI DigiVox A/D", | 1255 | .name = "MSI DigiVox A/D", |
1229 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 1256 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
@@ -1469,7 +1496,7 @@ struct em28xx_board em28xx_boards[] = { | |||
1469 | } }, | 1496 | } }, |
1470 | }, | 1497 | }, |
1471 | [EM2882_BOARD_TERRATEC_HYBRID_XS] = { | 1498 | [EM2882_BOARD_TERRATEC_HYBRID_XS] = { |
1472 | .name = "Terratec Hybrid XS (em2882)", | 1499 | .name = "Terratec Cinnergy Hybrid T USB XS (em2882)", |
1473 | .tuner_type = TUNER_XC2028, | 1500 | .tuner_type = TUNER_XC2028, |
1474 | .tuner_gpio = default_tuner_gpio, | 1501 | .tuner_gpio = default_tuner_gpio, |
1475 | .mts_firmware = 1, | 1502 | .mts_firmware = 1, |
@@ -1633,11 +1660,11 @@ struct em28xx_board em28xx_boards[] = { | |||
1633 | .input = { { | 1660 | .input = { { |
1634 | .type = EM28XX_VMUX_COMPOSITE1, | 1661 | .type = EM28XX_VMUX_COMPOSITE1, |
1635 | .vmux = SAA7115_COMPOSITE0, | 1662 | .vmux = SAA7115_COMPOSITE0, |
1636 | .amux = EM28XX_AMUX_VIDEO2, | 1663 | .amux = EM28XX_AMUX_LINE_IN, |
1637 | }, { | 1664 | }, { |
1638 | .type = EM28XX_VMUX_SVIDEO, | 1665 | .type = EM28XX_VMUX_SVIDEO, |
1639 | .vmux = SAA7115_SVIDEO3, | 1666 | .vmux = SAA7115_SVIDEO3, |
1640 | .amux = EM28XX_AMUX_VIDEO2, | 1667 | .amux = EM28XX_AMUX_LINE_IN, |
1641 | } }, | 1668 | } }, |
1642 | }, | 1669 | }, |
1643 | [EM2860_BOARD_TERRATEC_AV350] = { | 1670 | [EM2860_BOARD_TERRATEC_AV350] = { |
@@ -1754,6 +1781,8 @@ struct usb_device_id em28xx_id_table[] = { | |||
1754 | .driver_info = EM2820_BOARD_UNKNOWN }, | 1781 | .driver_info = EM2820_BOARD_UNKNOWN }, |
1755 | { USB_DEVICE(0xeb1a, 0x2868), | 1782 | { USB_DEVICE(0xeb1a, 0x2868), |
1756 | .driver_info = EM2820_BOARD_UNKNOWN }, | 1783 | .driver_info = EM2820_BOARD_UNKNOWN }, |
1784 | { USB_DEVICE(0xeb1a, 0x2875), | ||
1785 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
1757 | { USB_DEVICE(0xeb1a, 0xe300), | 1786 | { USB_DEVICE(0xeb1a, 0xe300), |
1758 | .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U }, | 1787 | .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U }, |
1759 | { USB_DEVICE(0xeb1a, 0xe303), | 1788 | { USB_DEVICE(0xeb1a, 0xe303), |
@@ -1791,7 +1820,7 @@ struct usb_device_id em28xx_id_table[] = { | |||
1791 | { USB_DEVICE(0x0ccd, 0x005e), | 1820 | { USB_DEVICE(0x0ccd, 0x005e), |
1792 | .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, | 1821 | .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, |
1793 | { USB_DEVICE(0x0ccd, 0x0042), | 1822 | { USB_DEVICE(0x0ccd, 0x0042), |
1794 | .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS }, | 1823 | .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, |
1795 | { USB_DEVICE(0x0ccd, 0x0043), | 1824 | { USB_DEVICE(0x0ccd, 0x0043), |
1796 | .driver_info = EM2870_BOARD_TERRATEC_XS }, | 1825 | .driver_info = EM2870_BOARD_TERRATEC_XS }, |
1797 | { USB_DEVICE(0x0ccd, 0x0047), | 1826 | { USB_DEVICE(0x0ccd, 0x0047), |
@@ -1873,6 +1902,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = { | |||
1873 | {0x77800080, EM2860_BOARD_TVP5150_REFERENCE_DESIGN, TUNER_ABSENT}, | 1902 | {0x77800080, EM2860_BOARD_TVP5150_REFERENCE_DESIGN, TUNER_ABSENT}, |
1874 | {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC}, | 1903 | {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC}, |
1875 | {0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF}, | 1904 | {0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF}, |
1905 | {0x6b800080, EM2874_LEADERSHIP_ISDBT, TUNER_ABSENT}, | ||
1876 | }; | 1906 | }; |
1877 | 1907 | ||
1878 | /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */ | 1908 | /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */ |
@@ -2408,7 +2438,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev) | |||
2408 | dev->init_data.get_key = em28xx_get_key_em_haup; | 2438 | dev->init_data.get_key = em28xx_get_key_em_haup; |
2409 | dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; | 2439 | dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; |
2410 | case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE: | 2440 | case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE: |
2411 | dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;; | 2441 | dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE; |
2412 | dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe; | 2442 | dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe; |
2413 | dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)"; | 2443 | dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)"; |
2414 | break; | 2444 | break; |
@@ -2430,8 +2460,36 @@ void em28xx_card_setup(struct em28xx *dev) | |||
2430 | dev->board.is_webcam = 0; | 2460 | dev->board.is_webcam = 0; |
2431 | else | 2461 | else |
2432 | dev->progressive = 1; | 2462 | dev->progressive = 1; |
2433 | } else | 2463 | } |
2434 | em28xx_set_model(dev); | 2464 | |
2465 | if (!dev->board.is_webcam) { | ||
2466 | switch (dev->model) { | ||
2467 | case EM2820_BOARD_UNKNOWN: | ||
2468 | case EM2800_BOARD_UNKNOWN: | ||
2469 | /* | ||
2470 | * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD. | ||
2471 | * | ||
2472 | * This occurs because they share identical USB vendor and | ||
2473 | * product IDs. | ||
2474 | * | ||
2475 | * What we do here is look up the EEPROM hash of the K-WORLD | ||
2476 | * and if it is found then we decide that we do not have | ||
2477 | * a DIGIVOX and reset the device to the K-WORLD instead. | ||
2478 | * | ||
2479 | * This solution is only valid if they do not share eeprom | ||
2480 | * hash identities which has not been determined as yet. | ||
2481 | */ | ||
2482 | if (em28xx_hint_board(dev) < 0) | ||
2483 | em28xx_errdev("Board not discovered\n"); | ||
2484 | else { | ||
2485 | em28xx_set_model(dev); | ||
2486 | em28xx_pre_card_setup(dev); | ||
2487 | } | ||
2488 | break; | ||
2489 | default: | ||
2490 | em28xx_set_model(dev); | ||
2491 | } | ||
2492 | } | ||
2435 | 2493 | ||
2436 | em28xx_info("Identified as %s (card=%d)\n", | 2494 | em28xx_info("Identified as %s (card=%d)\n", |
2437 | dev->board.name, dev->model); | 2495 | dev->board.name, dev->model); |
@@ -2749,8 +2807,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
2749 | em28xx_pre_card_setup(dev); | 2807 | em28xx_pre_card_setup(dev); |
2750 | 2808 | ||
2751 | if (!dev->board.is_em2800) { | 2809 | if (!dev->board.is_em2800) { |
2752 | /* Sets I2C speed to 100 KHz */ | 2810 | /* Resets I2C speed */ |
2753 | retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | 2811 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); |
2754 | if (retval < 0) { | 2812 | if (retval < 0) { |
2755 | em28xx_errdev("%s: em28xx_write_regs_req failed!" | 2813 | em28xx_errdev("%s: em28xx_write_regs_req failed!" |
2756 | " retval [%d]\n", | 2814 | " retval [%d]\n", |
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 3ac8d3025fea..c7c04bf712aa 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "mt352_priv.h" /* FIXME */ | 37 | #include "mt352_priv.h" /* FIXME */ |
38 | #include "tda1002x.h" | 38 | #include "tda1002x.h" |
39 | #include "tda18271.h" | 39 | #include "tda18271.h" |
40 | #include "s921.h" | ||
40 | 41 | ||
41 | MODULE_DESCRIPTION("driver for em28xx based DVB cards"); | 42 | MODULE_DESCRIPTION("driver for em28xx based DVB cards"); |
42 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 43 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); |
@@ -245,6 +246,10 @@ static struct lgdt3305_config em2870_lgdt3304_dev = { | |||
245 | .qam_if_khz = 4000, | 246 | .qam_if_khz = 4000, |
246 | }; | 247 | }; |
247 | 248 | ||
249 | static struct s921_config sharp_isdbt = { | ||
250 | .demod_address = 0x30 >> 1 | ||
251 | }; | ||
252 | |||
248 | static struct zl10353_config em28xx_zl10353_with_xc3028 = { | 253 | static struct zl10353_config em28xx_zl10353_with_xc3028 = { |
249 | .demod_address = (0x1e >> 1), | 254 | .demod_address = (0x1e >> 1), |
250 | .no_tuner = 1, | 255 | .no_tuner = 1, |
@@ -481,6 +486,7 @@ static int dvb_init(struct em28xx *dev) | |||
481 | 486 | ||
482 | if (!dev->board.has_dvb) { | 487 | if (!dev->board.has_dvb) { |
483 | /* This device does not support the extension */ | 488 | /* This device does not support the extension */ |
489 | printk(KERN_INFO "em28xx_dvb: This device does not support the extension\n"); | ||
484 | return 0; | 490 | return 0; |
485 | } | 491 | } |
486 | 492 | ||
@@ -496,6 +502,16 @@ static int dvb_init(struct em28xx *dev) | |||
496 | em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | 502 | em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); |
497 | /* init frontend */ | 503 | /* init frontend */ |
498 | switch (dev->model) { | 504 | switch (dev->model) { |
505 | case EM2874_LEADERSHIP_ISDBT: | ||
506 | dvb->frontend = dvb_attach(s921_attach, | ||
507 | &sharp_isdbt, &dev->i2c_adap); | ||
508 | |||
509 | if (!dvb->frontend) { | ||
510 | result = -EINVAL; | ||
511 | goto out_free; | ||
512 | } | ||
513 | |||
514 | break; | ||
499 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: | 515 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: |
500 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: | 516 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: |
501 | case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: | 517 | case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: |
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 6759cd5570dd..29cc74441a7d 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/input.h> | ||
29 | #include <linux/usb.h> | 28 | #include <linux/usb.h> |
30 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
31 | 30 | ||
@@ -64,7 +63,7 @@ struct em28xx_ir_poll_result { | |||
64 | 63 | ||
65 | struct em28xx_IR { | 64 | struct em28xx_IR { |
66 | struct em28xx *dev; | 65 | struct em28xx *dev; |
67 | struct input_dev *input; | 66 | struct rc_dev *rc; |
68 | char name[32]; | 67 | char name[32]; |
69 | char phys[32]; | 68 | char phys[32]; |
70 | 69 | ||
@@ -75,10 +74,6 @@ struct em28xx_IR { | |||
75 | unsigned int last_readcount; | 74 | unsigned int last_readcount; |
76 | 75 | ||
77 | int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); | 76 | int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); |
78 | |||
79 | /* IR device properties */ | ||
80 | |||
81 | struct ir_dev_props props; | ||
82 | }; | 77 | }; |
83 | 78 | ||
84 | /********************************************************** | 79 | /********************************************************** |
@@ -302,12 +297,12 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir) | |||
302 | poll_result.toggle_bit, poll_result.read_count, | 297 | poll_result.toggle_bit, poll_result.read_count, |
303 | poll_result.rc_address, poll_result.rc_data[0]); | 298 | poll_result.rc_address, poll_result.rc_data[0]); |
304 | if (ir->full_code) | 299 | if (ir->full_code) |
305 | ir_keydown(ir->input, | 300 | rc_keydown(ir->rc, |
306 | poll_result.rc_address << 8 | | 301 | poll_result.rc_address << 8 | |
307 | poll_result.rc_data[0], | 302 | poll_result.rc_data[0], |
308 | poll_result.toggle_bit); | 303 | poll_result.toggle_bit); |
309 | else | 304 | else |
310 | ir_keydown(ir->input, | 305 | rc_keydown(ir->rc, |
311 | poll_result.rc_data[0], | 306 | poll_result.rc_data[0], |
312 | poll_result.toggle_bit); | 307 | poll_result.toggle_bit); |
313 | 308 | ||
@@ -331,9 +326,9 @@ static void em28xx_ir_work(struct work_struct *work) | |||
331 | schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); | 326 | schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); |
332 | } | 327 | } |
333 | 328 | ||
334 | static int em28xx_ir_start(void *priv) | 329 | static int em28xx_ir_start(struct rc_dev *rc) |
335 | { | 330 | { |
336 | struct em28xx_IR *ir = priv; | 331 | struct em28xx_IR *ir = rc->priv; |
337 | 332 | ||
338 | INIT_DELAYED_WORK(&ir->work, em28xx_ir_work); | 333 | INIT_DELAYED_WORK(&ir->work, em28xx_ir_work); |
339 | schedule_delayed_work(&ir->work, 0); | 334 | schedule_delayed_work(&ir->work, 0); |
@@ -341,30 +336,30 @@ static int em28xx_ir_start(void *priv) | |||
341 | return 0; | 336 | return 0; |
342 | } | 337 | } |
343 | 338 | ||
344 | static void em28xx_ir_stop(void *priv) | 339 | static void em28xx_ir_stop(struct rc_dev *rc) |
345 | { | 340 | { |
346 | struct em28xx_IR *ir = priv; | 341 | struct em28xx_IR *ir = rc->priv; |
347 | 342 | ||
348 | cancel_delayed_work_sync(&ir->work); | 343 | cancel_delayed_work_sync(&ir->work); |
349 | } | 344 | } |
350 | 345 | ||
351 | int em28xx_ir_change_protocol(void *priv, u64 ir_type) | 346 | int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type) |
352 | { | 347 | { |
353 | int rc = 0; | 348 | int rc = 0; |
354 | struct em28xx_IR *ir = priv; | 349 | struct em28xx_IR *ir = rc_dev->priv; |
355 | struct em28xx *dev = ir->dev; | 350 | struct em28xx *dev = ir->dev; |
356 | u8 ir_config = EM2874_IR_RC5; | 351 | u8 ir_config = EM2874_IR_RC5; |
357 | 352 | ||
358 | /* Adjust xclk based o IR table for RC5/NEC tables */ | 353 | /* Adjust xclk based o IR table for RC5/NEC tables */ |
359 | 354 | ||
360 | if (ir_type == IR_TYPE_RC5) { | 355 | if (rc_type == RC_TYPE_RC5) { |
361 | dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; | 356 | dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; |
362 | ir->full_code = 1; | 357 | ir->full_code = 1; |
363 | } else if (ir_type == IR_TYPE_NEC) { | 358 | } else if (rc_type == RC_TYPE_NEC) { |
364 | dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; | 359 | dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; |
365 | ir_config = EM2874_IR_NEC; | 360 | ir_config = EM2874_IR_NEC; |
366 | ir->full_code = 1; | 361 | ir->full_code = 1; |
367 | } else if (ir_type != IR_TYPE_UNKNOWN) | 362 | } else if (rc_type != RC_TYPE_UNKNOWN) |
368 | rc = -EINVAL; | 363 | rc = -EINVAL; |
369 | 364 | ||
370 | em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, | 365 | em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, |
@@ -391,7 +386,7 @@ int em28xx_ir_change_protocol(void *priv, u64 ir_type) | |||
391 | int em28xx_ir_init(struct em28xx *dev) | 386 | int em28xx_ir_init(struct em28xx *dev) |
392 | { | 387 | { |
393 | struct em28xx_IR *ir; | 388 | struct em28xx_IR *ir; |
394 | struct input_dev *input_dev; | 389 | struct rc_dev *rc; |
395 | int err = -ENOMEM; | 390 | int err = -ENOMEM; |
396 | 391 | ||
397 | if (dev->board.ir_codes == NULL) { | 392 | if (dev->board.ir_codes == NULL) { |
@@ -400,28 +395,27 @@ int em28xx_ir_init(struct em28xx *dev) | |||
400 | } | 395 | } |
401 | 396 | ||
402 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | 397 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); |
403 | input_dev = input_allocate_device(); | 398 | rc = rc_allocate_device(); |
404 | if (!ir || !input_dev) | 399 | if (!ir || !rc) |
405 | goto err_out_free; | 400 | goto err_out_free; |
406 | 401 | ||
407 | /* record handles to ourself */ | 402 | /* record handles to ourself */ |
408 | ir->dev = dev; | 403 | ir->dev = dev; |
409 | dev->ir = ir; | 404 | dev->ir = ir; |
410 | 405 | ir->rc = rc; | |
411 | ir->input = input_dev; | ||
412 | 406 | ||
413 | /* | 407 | /* |
414 | * em2874 supports more protocols. For now, let's just announce | 408 | * em2874 supports more protocols. For now, let's just announce |
415 | * the two protocols that were already tested | 409 | * the two protocols that were already tested |
416 | */ | 410 | */ |
417 | ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; | 411 | rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC; |
418 | ir->props.priv = ir; | 412 | rc->priv = ir; |
419 | ir->props.change_protocol = em28xx_ir_change_protocol; | 413 | rc->change_protocol = em28xx_ir_change_protocol; |
420 | ir->props.open = em28xx_ir_start; | 414 | rc->open = em28xx_ir_start; |
421 | ir->props.close = em28xx_ir_stop; | 415 | rc->close = em28xx_ir_stop; |
422 | 416 | ||
423 | /* By default, keep protocol field untouched */ | 417 | /* By default, keep protocol field untouched */ |
424 | err = em28xx_ir_change_protocol(ir, IR_TYPE_UNKNOWN); | 418 | err = em28xx_ir_change_protocol(rc, RC_TYPE_UNKNOWN); |
425 | if (err) | 419 | if (err) |
426 | goto err_out_free; | 420 | goto err_out_free; |
427 | 421 | ||
@@ -435,27 +429,27 @@ int em28xx_ir_init(struct em28xx *dev) | |||
435 | usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); | 429 | usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); |
436 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); | 430 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); |
437 | 431 | ||
438 | input_dev->name = ir->name; | 432 | rc->input_name = ir->name; |
439 | input_dev->phys = ir->phys; | 433 | rc->input_phys = ir->phys; |
440 | input_dev->id.bustype = BUS_USB; | 434 | rc->input_id.bustype = BUS_USB; |
441 | input_dev->id.version = 1; | 435 | rc->input_id.version = 1; |
442 | input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); | 436 | rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); |
443 | input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); | 437 | rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct); |
444 | 438 | rc->dev.parent = &dev->udev->dev; | |
445 | input_dev->dev.parent = &dev->udev->dev; | 439 | rc->map_name = dev->board.ir_codes; |
446 | 440 | rc->driver_name = MODULE_NAME; | |
447 | |||
448 | 441 | ||
449 | /* all done */ | 442 | /* all done */ |
450 | err = ir_input_register(ir->input, dev->board.ir_codes, | 443 | err = rc_register_device(rc); |
451 | &ir->props, MODULE_NAME); | ||
452 | if (err) | 444 | if (err) |
453 | goto err_out_stop; | 445 | goto err_out_stop; |
454 | 446 | ||
455 | return 0; | 447 | return 0; |
448 | |||
456 | err_out_stop: | 449 | err_out_stop: |
457 | dev->ir = NULL; | 450 | dev->ir = NULL; |
458 | err_out_free: | 451 | err_out_free: |
452 | rc_free_device(rc); | ||
459 | kfree(ir); | 453 | kfree(ir); |
460 | return err; | 454 | return err; |
461 | } | 455 | } |
@@ -468,8 +462,8 @@ int em28xx_ir_fini(struct em28xx *dev) | |||
468 | if (!ir) | 462 | if (!ir) |
469 | return 0; | 463 | return 0; |
470 | 464 | ||
471 | em28xx_ir_stop(ir); | 465 | em28xx_ir_stop(ir->rc); |
472 | ir_input_unregister(ir->input); | 466 | rc_unregister_device(ir->rc); |
473 | kfree(ir); | 467 | kfree(ir); |
474 | 468 | ||
475 | /* done */ | 469 | /* done */ |
diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/video/em28xx/em28xx-vbi.c index 7f1c4a2173b6..2b4c9cba2d67 100644 --- a/drivers/media/video/em28xx/em28xx-vbi.c +++ b/drivers/media/video/em28xx/em28xx-vbi.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/hardirq.h> | ||
26 | #include <linux/init.h> | 27 | #include <linux/init.h> |
27 | 28 | ||
28 | #include "em28xx.h" | 29 | #include "em28xx.h" |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 2c3007280032..f34d524ccb09 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -1434,7 +1434,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1434 | 1434 | ||
1435 | /* It isn't an AC97 control. Sends it to the v4l2 dev interface */ | 1435 | /* It isn't an AC97 control. Sends it to the v4l2 dev interface */ |
1436 | if (rc == 1) { | 1436 | if (rc == 1) { |
1437 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl); | 1437 | rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0, core, s_ctrl, ctrl); |
1438 | 1438 | ||
1439 | /* | 1439 | /* |
1440 | * In the case of non-AC97 volume controls, we still need | 1440 | * In the case of non-AC97 volume controls, we still need |
@@ -1708,11 +1708,15 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1708 | fh, type, fh->resources, dev->resources); | 1708 | fh, type, fh->resources, dev->resources); |
1709 | 1709 | ||
1710 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1710 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
1711 | videobuf_streamoff(&fh->vb_vidq); | 1711 | if (res_check(fh, EM28XX_RESOURCE_VIDEO)) { |
1712 | res_free(fh, EM28XX_RESOURCE_VIDEO); | 1712 | videobuf_streamoff(&fh->vb_vidq); |
1713 | res_free(fh, EM28XX_RESOURCE_VIDEO); | ||
1714 | } | ||
1713 | } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | 1715 | } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { |
1714 | videobuf_streamoff(&fh->vb_vbiq); | 1716 | if (res_check(fh, EM28XX_RESOURCE_VBI)) { |
1715 | res_free(fh, EM28XX_RESOURCE_VBI); | 1717 | videobuf_streamoff(&fh->vb_vbiq); |
1718 | res_free(fh, EM28XX_RESOURCE_VBI); | ||
1719 | } | ||
1716 | } | 1720 | } |
1717 | 1721 | ||
1718 | return 0; | 1722 | return 0; |
@@ -1934,19 +1938,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) | |||
1934 | O_NONBLOCK); | 1938 | O_NONBLOCK); |
1935 | } | 1939 | } |
1936 | 1940 | ||
1937 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1938 | static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | ||
1939 | { | ||
1940 | struct em28xx_fh *fh = priv; | ||
1941 | |||
1942 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1943 | return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); | ||
1944 | else | ||
1945 | return videobuf_cgmbuf(&fh->vb_vbiq, mbuf, 8); | ||
1946 | } | ||
1947 | #endif | ||
1948 | |||
1949 | |||
1950 | /* ----------------------------------------------------------- */ | 1941 | /* ----------------------------------------------------------- */ |
1951 | /* RADIO ESPECIFIC IOCTLS */ | 1942 | /* RADIO ESPECIFIC IOCTLS */ |
1952 | /* ----------------------------------------------------------- */ | 1943 | /* ----------------------------------------------------------- */ |
@@ -2359,9 +2350,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
2359 | .vidioc_s_register = vidioc_s_register, | 2350 | .vidioc_s_register = vidioc_s_register, |
2360 | .vidioc_g_chip_ident = vidioc_g_chip_ident, | 2351 | .vidioc_g_chip_ident = vidioc_g_chip_ident, |
2361 | #endif | 2352 | #endif |
2362 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
2363 | .vidiocgmbuf = vidiocgmbuf, | ||
2364 | #endif | ||
2365 | }; | 2353 | }; |
2366 | 2354 | ||
2367 | static const struct video_device em28xx_video_template = { | 2355 | static const struct video_device em28xx_video_template = { |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 6a75e6a4fc21..6f2795a3d4b7 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <media/videobuf-vmalloc.h> | 33 | #include <media/videobuf-vmalloc.h> |
34 | #include <media/v4l2-device.h> | 34 | #include <media/v4l2-device.h> |
35 | #include <media/ir-kbd-i2c.h> | 35 | #include <media/ir-kbd-i2c.h> |
36 | #include <media/ir-core.h> | 36 | #include <media/rc-core.h> |
37 | #if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE) | 37 | #if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE) |
38 | #include <media/videobuf-dvb.h> | 38 | #include <media/videobuf-dvb.h> |
39 | #endif | 39 | #endif |
@@ -117,6 +117,8 @@ | |||
117 | #define EM2800_BOARD_VC211A 74 | 117 | #define EM2800_BOARD_VC211A 74 |
118 | #define EM2882_BOARD_DIKOM_DK300 75 | 118 | #define EM2882_BOARD_DIKOM_DK300 75 |
119 | #define EM2870_BOARD_KWORLD_A340 76 | 119 | #define EM2870_BOARD_KWORLD_A340 76 |
120 | #define EM2874_LEADERSHIP_ISDBT 77 | ||
121 | |||
120 | 122 | ||
121 | /* Limits minimum and default number of buffers */ | 123 | /* Limits minimum and default number of buffers */ |
122 | #define EM28XX_MIN_BUF 4 | 124 | #define EM28XX_MIN_BUF 4 |
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index bb164099ea2c..a982750dcef1 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c | |||
@@ -1610,6 +1610,7 @@ et61x251_vidioc_enuminput(struct et61x251_device* cam, void __user * arg) | |||
1610 | memset(&i, 0, sizeof(i)); | 1610 | memset(&i, 0, sizeof(i)); |
1611 | strcpy(i.name, "Camera"); | 1611 | strcpy(i.name, "Camera"); |
1612 | i.type = V4L2_INPUT_TYPE_CAMERA; | 1612 | i.type = V4L2_INPUT_TYPE_CAMERA; |
1613 | i.capabilities = V4L2_IN_CAP_STD; | ||
1613 | 1614 | ||
1614 | if (copy_to_user(arg, &i, sizeof(i))) | 1615 | if (copy_to_user(arg, &i, sizeof(i))) |
1615 | return -EFAULT; | 1616 | return -EFAULT; |
diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/video/fsl-viu.c index b8faff2dd711..e4bba88254c7 100644 --- a/drivers/media/video/fsl-viu.c +++ b/drivers/media/video/fsl-viu.c | |||
@@ -194,6 +194,8 @@ struct viu_dev { | |||
194 | 194 | ||
195 | /* decoder */ | 195 | /* decoder */ |
196 | struct v4l2_subdev *decoder; | 196 | struct v4l2_subdev *decoder; |
197 | |||
198 | v4l2_std_id std; | ||
197 | }; | 199 | }; |
198 | 200 | ||
199 | struct viu_fh { | 201 | struct viu_fh { |
@@ -915,6 +917,8 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | |||
915 | if (fh->type != i) | 917 | if (fh->type != i) |
916 | return -EINVAL; | 918 | return -EINVAL; |
917 | 919 | ||
920 | viu_start_dma(fh->dev); | ||
921 | |||
918 | return videobuf_streamon(&fh->vb_vidq); | 922 | return videobuf_streamon(&fh->vb_vidq); |
919 | } | 923 | } |
920 | 924 | ||
@@ -927,20 +931,39 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | |||
927 | if (fh->type != i) | 931 | if (fh->type != i) |
928 | return -EINVAL; | 932 | return -EINVAL; |
929 | 933 | ||
934 | viu_stop_dma(fh->dev); | ||
935 | |||
930 | return videobuf_streamoff(&fh->vb_vidq); | 936 | return videobuf_streamoff(&fh->vb_vidq); |
931 | } | 937 | } |
932 | 938 | ||
933 | #define decoder_call(viu, o, f, args...) \ | 939 | #define decoder_call(viu, o, f, args...) \ |
934 | v4l2_subdev_call(viu->decoder, o, f, ##args) | 940 | v4l2_subdev_call(viu->decoder, o, f, ##args) |
935 | 941 | ||
942 | static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std_id) | ||
943 | { | ||
944 | struct viu_fh *fh = priv; | ||
945 | |||
946 | decoder_call(fh->dev, video, querystd, std_id); | ||
947 | return 0; | ||
948 | } | ||
949 | |||
936 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) | 950 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) |
937 | { | 951 | { |
938 | struct viu_fh *fh = priv; | 952 | struct viu_fh *fh = priv; |
939 | 953 | ||
954 | fh->dev->std = *id; | ||
940 | decoder_call(fh->dev, core, s_std, *id); | 955 | decoder_call(fh->dev, core, s_std, *id); |
941 | return 0; | 956 | return 0; |
942 | } | 957 | } |
943 | 958 | ||
959 | static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std_id) | ||
960 | { | ||
961 | struct viu_fh *fh = priv; | ||
962 | |||
963 | *std_id = fh->dev->std; | ||
964 | return 0; | ||
965 | } | ||
966 | |||
944 | /* only one input in this driver */ | 967 | /* only one input in this driver */ |
945 | static int vidioc_enum_input(struct file *file, void *priv, | 968 | static int vidioc_enum_input(struct file *file, void *priv, |
946 | struct v4l2_input *inp) | 969 | struct v4l2_input *inp) |
@@ -1331,6 +1354,7 @@ static int viu_release(struct file *file) | |||
1331 | 1354 | ||
1332 | viu_stop_dma(dev); | 1355 | viu_stop_dma(dev); |
1333 | videobuf_stop(&fh->vb_vidq); | 1356 | videobuf_stop(&fh->vb_vidq); |
1357 | videobuf_mmap_free(&fh->vb_vidq); | ||
1334 | 1358 | ||
1335 | kfree(fh); | 1359 | kfree(fh); |
1336 | 1360 | ||
@@ -1397,7 +1421,9 @@ static const struct v4l2_ioctl_ops viu_ioctl_ops = { | |||
1397 | .vidioc_querybuf = vidioc_querybuf, | 1421 | .vidioc_querybuf = vidioc_querybuf, |
1398 | .vidioc_qbuf = vidioc_qbuf, | 1422 | .vidioc_qbuf = vidioc_qbuf, |
1399 | .vidioc_dqbuf = vidioc_dqbuf, | 1423 | .vidioc_dqbuf = vidioc_dqbuf, |
1424 | .vidioc_g_std = vidioc_g_std, | ||
1400 | .vidioc_s_std = vidioc_s_std, | 1425 | .vidioc_s_std = vidioc_s_std, |
1426 | .vidioc_querystd = vidioc_querystd, | ||
1401 | .vidioc_enum_input = vidioc_enum_input, | 1427 | .vidioc_enum_input = vidioc_enum_input, |
1402 | .vidioc_g_input = vidioc_g_input, | 1428 | .vidioc_g_input = vidioc_g_input, |
1403 | .vidioc_s_input = vidioc_s_input, | 1429 | .vidioc_s_input = vidioc_s_input, |
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c index 9b121681d135..c1ae05f4661f 100644 --- a/drivers/media/video/gspca/cpia1.c +++ b/drivers/media/video/gspca/cpia1.c | |||
@@ -37,7 +37,7 @@ MODULE_LICENSE("GPL"); | |||
37 | /* constant value's */ | 37 | /* constant value's */ |
38 | #define MAGIC_0 0x19 | 38 | #define MAGIC_0 0x19 |
39 | #define MAGIC_1 0x68 | 39 | #define MAGIC_1 0x68 |
40 | #define DATA_IN 0xC0 | 40 | #define DATA_IN 0xc0 |
41 | #define DATA_OUT 0x40 | 41 | #define DATA_OUT 0x40 |
42 | #define VIDEOSIZE_QCIF 0 /* 176x144 */ | 42 | #define VIDEOSIZE_QCIF 0 /* 176x144 */ |
43 | #define VIDEOSIZE_CIF 1 /* 352x288 */ | 43 | #define VIDEOSIZE_CIF 1 /* 352x288 */ |
@@ -660,9 +660,9 @@ static int do_command(struct gspca_dev *gspca_dev, u16 command, | |||
660 | if (sd->params.qx3.button) { | 660 | if (sd->params.qx3.button) { |
661 | /* button pressed - unlock the latch */ | 661 | /* button pressed - unlock the latch */ |
662 | do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, | 662 | do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, |
663 | 3, 0xDF, 0xDF, 0); | 663 | 3, 0xdf, 0xdf, 0); |
664 | do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, | 664 | do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, |
665 | 3, 0xFF, 0xFF, 0); | 665 | 3, 0xff, 0xff, 0); |
666 | } | 666 | } |
667 | 667 | ||
668 | /* test whether microscope is cradled */ | 668 | /* test whether microscope is cradled */ |
@@ -829,7 +829,7 @@ static int goto_low_power(struct gspca_dev *gspca_dev) | |||
829 | if (ret) | 829 | if (ret) |
830 | return ret; | 830 | return ret; |
831 | 831 | ||
832 | do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0); | 832 | ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0); |
833 | if (ret) | 833 | if (ret) |
834 | return ret; | 834 | return ret; |
835 | 835 | ||
@@ -1110,12 +1110,12 @@ static int command_setlights(struct gspca_dev *gspca_dev) | |||
1110 | p2 = (sd->params.qx3.toplight == 0) << 3; | 1110 | p2 = (sd->params.qx3.toplight == 0) << 3; |
1111 | 1111 | ||
1112 | ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg, | 1112 | ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg, |
1113 | 0x90, 0x8F, 0x50, 0); | 1113 | 0x90, 0x8f, 0x50, 0); |
1114 | if (ret) | 1114 | if (ret) |
1115 | return ret; | 1115 | return ret; |
1116 | 1116 | ||
1117 | return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0, | 1117 | return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0, |
1118 | p1 | p2 | 0xE0, 0); | 1118 | p1 | p2 | 0xe0, 0); |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply) | 1121 | static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply) |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 8fe8fb486d62..442970073e8a 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -55,7 +55,7 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); | |||
55 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); | 55 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); |
56 | MODULE_LICENSE("GPL"); | 56 | MODULE_LICENSE("GPL"); |
57 | 57 | ||
58 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 10, 0) | 58 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 11, 0) |
59 | 59 | ||
60 | #ifdef GSPCA_DEBUG | 60 | #ifdef GSPCA_DEBUG |
61 | int gspca_debug = D_ERR | D_PROBE; | 61 | int gspca_debug = D_ERR | D_PROBE; |
@@ -224,12 +224,12 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev, | |||
224 | buffer, buffer_len, | 224 | buffer, buffer_len, |
225 | int_irq, (void *)gspca_dev, interval); | 225 | int_irq, (void *)gspca_dev, interval); |
226 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 226 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
227 | gspca_dev->int_urb = urb; | ||
228 | ret = usb_submit_urb(urb, GFP_KERNEL); | 227 | ret = usb_submit_urb(urb, GFP_KERNEL); |
229 | if (ret < 0) { | 228 | if (ret < 0) { |
230 | PDEBUG(D_ERR, "submit int URB failed with error %i", ret); | 229 | PDEBUG(D_ERR, "submit int URB failed with error %i", ret); |
231 | goto error_submit; | 230 | goto error_submit; |
232 | } | 231 | } |
232 | gspca_dev->int_urb = urb; | ||
233 | return ret; | 233 | return ret; |
234 | 234 | ||
235 | error_submit: | 235 | error_submit: |
@@ -318,14 +318,9 @@ static void fill_frame(struct gspca_dev *gspca_dev, | |||
318 | } | 318 | } |
319 | pkt_scan = gspca_dev->sd_desc->pkt_scan; | 319 | pkt_scan = gspca_dev->sd_desc->pkt_scan; |
320 | for (i = 0; i < urb->number_of_packets; i++) { | 320 | for (i = 0; i < urb->number_of_packets; i++) { |
321 | len = urb->iso_frame_desc[i].actual_length; | ||
321 | 322 | ||
322 | /* check the packet status and length */ | 323 | /* check the packet status and length */ |
323 | len = urb->iso_frame_desc[i].actual_length; | ||
324 | if (len == 0) { | ||
325 | if (gspca_dev->empty_packet == 0) | ||
326 | gspca_dev->empty_packet = 1; | ||
327 | continue; | ||
328 | } | ||
329 | st = urb->iso_frame_desc[i].status; | 324 | st = urb->iso_frame_desc[i].status; |
330 | if (st) { | 325 | if (st) { |
331 | err("ISOC data error: [%d] len=%d, status=%d", | 326 | err("ISOC data error: [%d] len=%d, status=%d", |
@@ -333,6 +328,11 @@ static void fill_frame(struct gspca_dev *gspca_dev, | |||
333 | gspca_dev->last_packet_type = DISCARD_PACKET; | 328 | gspca_dev->last_packet_type = DISCARD_PACKET; |
334 | continue; | 329 | continue; |
335 | } | 330 | } |
331 | if (len == 0) { | ||
332 | if (gspca_dev->empty_packet == 0) | ||
333 | gspca_dev->empty_packet = 1; | ||
334 | continue; | ||
335 | } | ||
336 | 336 | ||
337 | /* let the packet be analyzed by the subdriver */ | 337 | /* let the packet be analyzed by the subdriver */ |
338 | PDEBUG(D_PACK, "packet [%d] o:%d l:%d", | 338 | PDEBUG(D_PACK, "packet [%d] o:%d l:%d", |
@@ -652,16 +652,12 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) | |||
652 | : USB_ENDPOINT_XFER_ISOC; | 652 | : USB_ENDPOINT_XFER_ISOC; |
653 | i = gspca_dev->alt; /* previous alt setting */ | 653 | i = gspca_dev->alt; /* previous alt setting */ |
654 | if (gspca_dev->cam.reverse_alts) { | 654 | if (gspca_dev->cam.reverse_alts) { |
655 | if (gspca_dev->audio && i < gspca_dev->nbalt - 2) | ||
656 | i++; | ||
657 | while (++i < gspca_dev->nbalt) { | 655 | while (++i < gspca_dev->nbalt) { |
658 | ep = alt_xfer(&intf->altsetting[i], xfer); | 656 | ep = alt_xfer(&intf->altsetting[i], xfer); |
659 | if (ep) | 657 | if (ep) |
660 | break; | 658 | break; |
661 | } | 659 | } |
662 | } else { | 660 | } else { |
663 | if (gspca_dev->audio && i > 1) | ||
664 | i--; | ||
665 | while (--i >= 0) { | 661 | while (--i >= 0) { |
666 | ep = alt_xfer(&intf->altsetting[i], xfer); | 662 | ep = alt_xfer(&intf->altsetting[i], xfer); |
667 | if (ep) | 663 | if (ep) |
@@ -676,13 +672,11 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) | |||
676 | i, ep->desc.bEndpointAddress); | 672 | i, ep->desc.bEndpointAddress); |
677 | gspca_dev->alt = i; /* memorize the current alt setting */ | 673 | gspca_dev->alt = i; /* memorize the current alt setting */ |
678 | if (gspca_dev->nbalt > 1) { | 674 | if (gspca_dev->nbalt > 1) { |
679 | gspca_input_destroy_urb(gspca_dev); | ||
680 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); | 675 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); |
681 | if (ret < 0) { | 676 | if (ret < 0) { |
682 | err("set alt %d err %d", i, ret); | 677 | err("set alt %d err %d", i, ret); |
683 | ep = NULL; | 678 | ep = NULL; |
684 | } | 679 | } |
685 | gspca_input_create_urb(gspca_dev); | ||
686 | } | 680 | } |
687 | return ep; | 681 | return ep; |
688 | } | 682 | } |
@@ -759,7 +753,7 @@ static int create_urbs(struct gspca_dev *gspca_dev, | |||
759 | } | 753 | } |
760 | } else { /* bulk */ | 754 | } else { /* bulk */ |
761 | urb->pipe = usb_rcvbulkpipe(gspca_dev->dev, | 755 | urb->pipe = usb_rcvbulkpipe(gspca_dev->dev, |
762 | ep->desc.bEndpointAddress), | 756 | ep->desc.bEndpointAddress); |
763 | urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | 757 | urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; |
764 | urb->complete = bulk_irq; | 758 | urb->complete = bulk_irq; |
765 | } | 759 | } |
@@ -781,7 +775,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
781 | 775 | ||
782 | if (!gspca_dev->present) { | 776 | if (!gspca_dev->present) { |
783 | ret = -ENODEV; | 777 | ret = -ENODEV; |
784 | goto out; | 778 | goto unlock; |
785 | } | 779 | } |
786 | 780 | ||
787 | /* reset the streaming variables */ | 781 | /* reset the streaming variables */ |
@@ -802,8 +796,10 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
802 | if (gspca_dev->sd_desc->isoc_init) { | 796 | if (gspca_dev->sd_desc->isoc_init) { |
803 | ret = gspca_dev->sd_desc->isoc_init(gspca_dev); | 797 | ret = gspca_dev->sd_desc->isoc_init(gspca_dev); |
804 | if (ret < 0) | 798 | if (ret < 0) |
805 | goto out; | 799 | goto unlock; |
806 | } | 800 | } |
801 | |||
802 | gspca_input_destroy_urb(gspca_dev); | ||
807 | ep = get_ep(gspca_dev); | 803 | ep = get_ep(gspca_dev); |
808 | if (ep == NULL) { | 804 | if (ep == NULL) { |
809 | ret = -EIO; | 805 | ret = -EIO; |
@@ -873,6 +869,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
873 | } | 869 | } |
874 | } | 870 | } |
875 | out: | 871 | out: |
872 | gspca_input_create_urb(gspca_dev); | ||
873 | unlock: | ||
876 | mutex_unlock(&gspca_dev->usb_lock); | 874 | mutex_unlock(&gspca_dev->usb_lock); |
877 | return ret; | 875 | return ret; |
878 | } | 876 | } |
@@ -1299,17 +1297,19 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
1299 | ret = -ENODEV; | 1297 | ret = -ENODEV; |
1300 | goto out; | 1298 | goto out; |
1301 | } | 1299 | } |
1302 | strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver); | 1300 | strncpy((char *) cap->driver, gspca_dev->sd_desc->name, |
1301 | sizeof cap->driver); | ||
1303 | if (gspca_dev->dev->product != NULL) { | 1302 | if (gspca_dev->dev->product != NULL) { |
1304 | strncpy(cap->card, gspca_dev->dev->product, | 1303 | strncpy((char *) cap->card, gspca_dev->dev->product, |
1305 | sizeof cap->card); | 1304 | sizeof cap->card); |
1306 | } else { | 1305 | } else { |
1307 | snprintf(cap->card, sizeof cap->card, | 1306 | snprintf((char *) cap->card, sizeof cap->card, |
1308 | "USB Camera (%04x:%04x)", | 1307 | "USB Camera (%04x:%04x)", |
1309 | le16_to_cpu(gspca_dev->dev->descriptor.idVendor), | 1308 | le16_to_cpu(gspca_dev->dev->descriptor.idVendor), |
1310 | le16_to_cpu(gspca_dev->dev->descriptor.idProduct)); | 1309 | le16_to_cpu(gspca_dev->dev->descriptor.idProduct)); |
1311 | } | 1310 | } |
1312 | usb_make_path(gspca_dev->dev, cap->bus_info, sizeof(cap->bus_info)); | 1311 | usb_make_path(gspca_dev->dev, (char *) cap->bus_info, |
1312 | sizeof(cap->bus_info)); | ||
1313 | cap->version = DRIVER_VERSION_NUMBER; | 1313 | cap->version = DRIVER_VERSION_NUMBER; |
1314 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 1314 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1315 | | V4L2_CAP_STREAMING | 1315 | | V4L2_CAP_STREAMING |
@@ -1710,12 +1710,13 @@ static int vidioc_g_parm(struct file *filp, void *priv, | |||
1710 | 1710 | ||
1711 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1711 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1712 | return -ERESTARTSYS; | 1712 | return -ERESTARTSYS; |
1713 | gspca_dev->usb_err = 0; | 1713 | if (gspca_dev->present) { |
1714 | if (gspca_dev->present) | 1714 | gspca_dev->usb_err = 0; |
1715 | ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, | 1715 | gspca_dev->sd_desc->get_streamparm(gspca_dev, parm); |
1716 | parm); | 1716 | ret = gspca_dev->usb_err; |
1717 | else | 1717 | } else { |
1718 | ret = -ENODEV; | 1718 | ret = -ENODEV; |
1719 | } | ||
1719 | mutex_unlock(&gspca_dev->usb_lock); | 1720 | mutex_unlock(&gspca_dev->usb_lock); |
1720 | return ret; | 1721 | return ret; |
1721 | } | 1722 | } |
@@ -1740,12 +1741,13 @@ static int vidioc_s_parm(struct file *filp, void *priv, | |||
1740 | 1741 | ||
1741 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1742 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1742 | return -ERESTARTSYS; | 1743 | return -ERESTARTSYS; |
1743 | gspca_dev->usb_err = 0; | 1744 | if (gspca_dev->present) { |
1744 | if (gspca_dev->present) | 1745 | gspca_dev->usb_err = 0; |
1745 | ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, | 1746 | gspca_dev->sd_desc->set_streamparm(gspca_dev, parm); |
1746 | parm); | 1747 | ret = gspca_dev->usb_err; |
1747 | else | 1748 | } else { |
1748 | ret = -ENODEV; | 1749 | ret = -ENODEV; |
1750 | } | ||
1749 | mutex_unlock(&gspca_dev->usb_lock); | 1751 | mutex_unlock(&gspca_dev->usb_lock); |
1750 | return ret; | 1752 | return ret; |
1751 | } | 1753 | } |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index d4d210b56b49..97b77a26a2eb 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
@@ -62,7 +62,7 @@ struct gspca_ctrl { | |||
62 | /* device information - set at probe time */ | 62 | /* device information - set at probe time */ |
63 | struct cam { | 63 | struct cam { |
64 | const struct v4l2_pix_format *cam_mode; /* size nmodes */ | 64 | const struct v4l2_pix_format *cam_mode; /* size nmodes */ |
65 | const struct framerates *mode_framerates; /* must have size nmode, | 65 | const struct framerates *mode_framerates; /* must have size nmodes, |
66 | * just like cam_mode */ | 66 | * just like cam_mode */ |
67 | struct gspca_ctrl *ctrls; /* control table - size nctrls */ | 67 | struct gspca_ctrl *ctrls; /* control table - size nctrls */ |
68 | /* may be NULL */ | 68 | /* may be NULL */ |
@@ -93,7 +93,7 @@ typedef int (*cam_reg_op) (struct gspca_dev *, | |||
93 | struct v4l2_dbg_register *); | 93 | struct v4l2_dbg_register *); |
94 | typedef int (*cam_ident_op) (struct gspca_dev *, | 94 | typedef int (*cam_ident_op) (struct gspca_dev *, |
95 | struct v4l2_dbg_chip_ident *); | 95 | struct v4l2_dbg_chip_ident *); |
96 | typedef int (*cam_streamparm_op) (struct gspca_dev *, | 96 | typedef void (*cam_streamparm_op) (struct gspca_dev *, |
97 | struct v4l2_streamparm *); | 97 | struct v4l2_streamparm *); |
98 | typedef int (*cam_qmnu_op) (struct gspca_dev *, | 98 | typedef int (*cam_qmnu_op) (struct gspca_dev *, |
99 | struct v4l2_querymenu *); | 99 | struct v4l2_querymenu *); |
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index 8ded8b100576..703d48670a24 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c | |||
@@ -624,7 +624,7 @@ static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
624 | 624 | ||
625 | /* Mask away all uninteresting bits */ | 625 | /* Mask away all uninteresting bits */ |
626 | i2c_data = ((val & 0x0300) >> 2) | | 626 | i2c_data = ((val & 0x0300) >> 2) | |
627 | (i2c_data & 0x3F); | 627 | (i2c_data & 0x3f); |
628 | err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1); | 628 | err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1); |
629 | if (err < 0) | 629 | if (err < 0) |
630 | return err; | 630 | return err; |
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 6cf6855aa506..e1c3b9328ace 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -75,14 +75,14 @@ struct sd { | |||
75 | 75 | ||
76 | struct gspca_ctrl ctrls[NCTRL]; | 76 | struct gspca_ctrl ctrls[NCTRL]; |
77 | 77 | ||
78 | __u8 packet_nr; | 78 | u8 packet_nr; |
79 | 79 | ||
80 | char bridge; | 80 | char bridge; |
81 | #define BRIDGE_OV511 0 | 81 | #define BRIDGE_OV511 0 |
82 | #define BRIDGE_OV511PLUS 1 | 82 | #define BRIDGE_OV511PLUS 1 |
83 | #define BRIDGE_OV518 2 | 83 | #define BRIDGE_OV518 2 |
84 | #define BRIDGE_OV518PLUS 3 | 84 | #define BRIDGE_OV518PLUS 3 |
85 | #define BRIDGE_OV519 4 | 85 | #define BRIDGE_OV519 4 /* = ov530 */ |
86 | #define BRIDGE_OVFX2 5 | 86 | #define BRIDGE_OVFX2 5 |
87 | #define BRIDGE_W9968CF 6 | 87 | #define BRIDGE_W9968CF 6 |
88 | #define BRIDGE_MASK 7 | 88 | #define BRIDGE_MASK 7 |
@@ -94,42 +94,44 @@ struct sd { | |||
94 | char snapshot_needs_reset; | 94 | char snapshot_needs_reset; |
95 | 95 | ||
96 | /* Determined by sensor type */ | 96 | /* Determined by sensor type */ |
97 | __u8 sif; | 97 | u8 sif; |
98 | 98 | ||
99 | __u8 quality; | 99 | u8 quality; |
100 | #define QUALITY_MIN 50 | 100 | #define QUALITY_MIN 50 |
101 | #define QUALITY_MAX 70 | 101 | #define QUALITY_MAX 70 |
102 | #define QUALITY_DEF 50 | 102 | #define QUALITY_DEF 50 |
103 | 103 | ||
104 | __u8 stopped; /* Streaming is temporarily paused */ | 104 | u8 stopped; /* Streaming is temporarily paused */ |
105 | __u8 first_frame; | 105 | u8 first_frame; |
106 | 106 | ||
107 | __u8 frame_rate; /* current Framerate */ | 107 | u8 frame_rate; /* current Framerate */ |
108 | __u8 clockdiv; /* clockdiv override */ | 108 | u8 clockdiv; /* clockdiv override */ |
109 | 109 | ||
110 | char sensor; /* Type of image sensor chip (SEN_*) */ | 110 | s8 sensor; /* Type of image sensor chip (SEN_*) */ |
111 | #define SEN_UNKNOWN 0 | ||
112 | #define SEN_OV2610 1 | ||
113 | #define SEN_OV3610 2 | ||
114 | #define SEN_OV6620 3 | ||
115 | #define SEN_OV6630 4 | ||
116 | #define SEN_OV66308AF 5 | ||
117 | #define SEN_OV7610 6 | ||
118 | #define SEN_OV7620 7 | ||
119 | #define SEN_OV7620AE 8 | ||
120 | #define SEN_OV7640 9 | ||
121 | #define SEN_OV7648 10 | ||
122 | #define SEN_OV7670 11 | ||
123 | #define SEN_OV76BE 12 | ||
124 | #define SEN_OV8610 13 | ||
125 | 111 | ||
126 | u8 sensor_addr; | 112 | u8 sensor_addr; |
127 | int sensor_width; | 113 | u16 sensor_width; |
128 | int sensor_height; | 114 | u16 sensor_height; |
129 | int sensor_reg_cache[256]; | 115 | s16 sensor_reg_cache[256]; |
130 | 116 | ||
131 | u8 jpeg_hdr[JPEG_HDR_SZ]; | 117 | u8 jpeg_hdr[JPEG_HDR_SZ]; |
132 | }; | 118 | }; |
119 | enum sensors { | ||
120 | SEN_OV2610, | ||
121 | SEN_OV3610, | ||
122 | SEN_OV6620, | ||
123 | SEN_OV6630, | ||
124 | SEN_OV66308AF, | ||
125 | SEN_OV7610, | ||
126 | SEN_OV7620, | ||
127 | SEN_OV7620AE, | ||
128 | SEN_OV7640, | ||
129 | SEN_OV7648, | ||
130 | SEN_OV7660, | ||
131 | SEN_OV7670, | ||
132 | SEN_OV76BE, | ||
133 | SEN_OV8610, | ||
134 | }; | ||
133 | 135 | ||
134 | /* Note this is a bit of a hack, but the w9968cf driver needs the code for all | 136 | /* Note this is a bit of a hack, but the w9968cf driver needs the code for all |
135 | the ov sensors which is already present here. When we have the time we | 137 | the ov sensors which is already present here. When we have the time we |
@@ -182,7 +184,7 @@ static const struct ctrl sd_ctrls[] = { | |||
182 | }, | 184 | }, |
183 | .set_control = setcolors, | 185 | .set_control = setcolors, |
184 | }, | 186 | }, |
185 | /* The flip controls work with ov7670 only */ | 187 | /* The flip controls work for sensors ov7660 and ov7670 only */ |
186 | [HFLIP] = { | 188 | [HFLIP] = { |
187 | { | 189 | { |
188 | .id = V4L2_CID_HFLIP, | 190 | .id = V4L2_CID_HFLIP, |
@@ -225,7 +227,7 @@ static const struct ctrl sd_ctrls[] = { | |||
225 | .type = V4L2_CTRL_TYPE_MENU, | 227 | .type = V4L2_CTRL_TYPE_MENU, |
226 | .name = "Light frequency filter", | 228 | .name = "Light frequency filter", |
227 | .minimum = 0, | 229 | .minimum = 0, |
228 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | 230 | .maximum = 2, /* 0: no flicker, 1: 50Hz, 2:60Hz, 3: auto */ |
229 | .step = 1, | 231 | .step = 1, |
230 | .default_value = 0, | 232 | .default_value = 0, |
231 | }, | 233 | }, |
@@ -233,6 +235,53 @@ static const struct ctrl sd_ctrls[] = { | |||
233 | }, | 235 | }, |
234 | }; | 236 | }; |
235 | 237 | ||
238 | /* table of the disabled controls */ | ||
239 | static const unsigned ctrl_dis[] = { | ||
240 | [SEN_OV2610] = (1 << NCTRL) - 1, /* no control */ | ||
241 | |||
242 | [SEN_OV3610] = (1 << NCTRL) - 1, /* no control */ | ||
243 | |||
244 | [SEN_OV6620] = (1 << HFLIP) | | ||
245 | (1 << VFLIP), | ||
246 | |||
247 | [SEN_OV6630] = (1 << HFLIP) | | ||
248 | (1 << VFLIP), | ||
249 | |||
250 | [SEN_OV66308AF] = (1 << HFLIP) | | ||
251 | (1 << VFLIP), | ||
252 | |||
253 | [SEN_OV7610] = (1 << HFLIP) | | ||
254 | (1 << VFLIP), | ||
255 | |||
256 | [SEN_OV7620] = (1 << HFLIP) | | ||
257 | (1 << VFLIP), | ||
258 | |||
259 | [SEN_OV7620AE] = (1 << HFLIP) | | ||
260 | (1 << VFLIP), | ||
261 | |||
262 | [SEN_OV7640] = (1 << HFLIP) | | ||
263 | (1 << VFLIP) | | ||
264 | (1 << AUTOBRIGHT) | | ||
265 | (1 << CONTRAST), | ||
266 | |||
267 | [SEN_OV7648] = (1 << HFLIP) | | ||
268 | (1 << VFLIP) | | ||
269 | (1 << AUTOBRIGHT) | | ||
270 | (1 << CONTRAST), | ||
271 | |||
272 | [SEN_OV7660] = (1 << AUTOBRIGHT), | ||
273 | |||
274 | [SEN_OV7670] = (1 << COLORS) | | ||
275 | (1 << AUTOBRIGHT), | ||
276 | |||
277 | [SEN_OV76BE] = (1 << HFLIP) | | ||
278 | (1 << VFLIP), | ||
279 | |||
280 | [SEN_OV8610] = (1 << HFLIP) | | ||
281 | (1 << VFLIP) | | ||
282 | (1 << FREQ), | ||
283 | }; | ||
284 | |||
236 | static const struct v4l2_pix_format ov519_vga_mode[] = { | 285 | static const struct v4l2_pix_format ov519_vga_mode[] = { |
237 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 286 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
238 | .bytesperline = 320, | 287 | .bytesperline = 320, |
@@ -412,7 +461,6 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { | |||
412 | .priv = 0}, | 461 | .priv = 0}, |
413 | }; | 462 | }; |
414 | 463 | ||
415 | |||
416 | /* Registers common to OV511 / OV518 */ | 464 | /* Registers common to OV511 / OV518 */ |
417 | #define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ | 465 | #define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ |
418 | #define R51x_SYS_RESET 0x50 | 466 | #define R51x_SYS_RESET 0x50 |
@@ -420,7 +468,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { | |||
420 | #define OV511_RESET_OMNICE 0x08 | 468 | #define OV511_RESET_OMNICE 0x08 |
421 | #define R51x_SYS_INIT 0x53 | 469 | #define R51x_SYS_INIT 0x53 |
422 | #define R51x_SYS_SNAP 0x52 | 470 | #define R51x_SYS_SNAP 0x52 |
423 | #define R51x_SYS_CUST_ID 0x5F | 471 | #define R51x_SYS_CUST_ID 0x5f |
424 | #define R51x_COMP_LUT_BEGIN 0x80 | 472 | #define R51x_COMP_LUT_BEGIN 0x80 |
425 | 473 | ||
426 | /* OV511 Camera interface register numbers */ | 474 | /* OV511 Camera interface register numbers */ |
@@ -435,13 +483,13 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { | |||
435 | #define R511_CAM_OPTS 0x18 | 483 | #define R511_CAM_OPTS 0x18 |
436 | 484 | ||
437 | #define R511_SNAP_FRAME 0x19 | 485 | #define R511_SNAP_FRAME 0x19 |
438 | #define R511_SNAP_PXCNT 0x1A | 486 | #define R511_SNAP_PXCNT 0x1a |
439 | #define R511_SNAP_LNCNT 0x1B | 487 | #define R511_SNAP_LNCNT 0x1b |
440 | #define R511_SNAP_PXDIV 0x1C | 488 | #define R511_SNAP_PXDIV 0x1c |
441 | #define R511_SNAP_LNDIV 0x1D | 489 | #define R511_SNAP_LNDIV 0x1d |
442 | #define R511_SNAP_UV_EN 0x1E | 490 | #define R511_SNAP_UV_EN 0x1e |
443 | #define R511_SNAP_UV_EN 0x1E | 491 | #define R511_SNAP_UV_EN 0x1e |
444 | #define R511_SNAP_OPTS 0x1F | 492 | #define R511_SNAP_OPTS 0x1f |
445 | 493 | ||
446 | #define R511_DRAM_FLOW_CTL 0x20 | 494 | #define R511_DRAM_FLOW_CTL 0x20 |
447 | #define R511_FIFO_OPTS 0x31 | 495 | #define R511_FIFO_OPTS 0x31 |
@@ -466,13 +514,14 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { | |||
466 | #define OV519_R25_FORMAT 0x25 | 514 | #define OV519_R25_FORMAT 0x25 |
467 | 515 | ||
468 | /* OV519 System Controller register numbers */ | 516 | /* OV519 System Controller register numbers */ |
469 | #define OV519_SYS_RESET1 0x51 | 517 | #define OV519_R51_RESET1 0x51 |
470 | #define OV519_SYS_EN_CLK1 0x54 | 518 | #define OV519_R54_EN_CLK1 0x54 |
519 | #define OV519_R57_SNAPSHOT 0x57 | ||
471 | 520 | ||
472 | #define OV519_GPIO_DATA_OUT0 0x71 | 521 | #define OV519_GPIO_DATA_OUT0 0x71 |
473 | #define OV519_GPIO_IO_CTRL0 0x72 | 522 | #define OV519_GPIO_IO_CTRL0 0x72 |
474 | 523 | ||
475 | #define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */ | 524 | /*#define OV511_ENDPOINT_ADDRESS 1 * Isoc endpoint number */ |
476 | 525 | ||
477 | /* | 526 | /* |
478 | * The FX2 chip does not give us a zero length read at end of frame. | 527 | * The FX2 chip does not give us a zero length read at end of frame. |
@@ -526,80 +575,81 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { | |||
526 | #define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */ | 575 | #define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */ |
527 | #define OV7610_REG_COM_I 0x29 /* misc settings */ | 576 | #define OV7610_REG_COM_I 0x29 /* misc settings */ |
528 | 577 | ||
529 | /* OV7670 registers */ | 578 | /* OV7660 and OV7670 registers */ |
530 | #define OV7670_REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */ | 579 | #define OV7670_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */ |
531 | #define OV7670_REG_BLUE 0x01 /* blue gain */ | 580 | #define OV7670_R01_BLUE 0x01 /* blue gain */ |
532 | #define OV7670_REG_RED 0x02 /* red gain */ | 581 | #define OV7670_R02_RED 0x02 /* red gain */ |
533 | #define OV7670_REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */ | 582 | #define OV7670_R03_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */ |
534 | #define OV7670_REG_COM1 0x04 /* Control 1 */ | 583 | #define OV7670_R04_COM1 0x04 /* Control 1 */ |
535 | #define OV7670_REG_AECHH 0x07 /* AEC MS 5 bits */ | 584 | /*#define OV7670_R07_AECHH 0x07 * AEC MS 5 bits */ |
536 | #define OV7670_REG_COM3 0x0c /* Control 3 */ | 585 | #define OV7670_R0C_COM3 0x0c /* Control 3 */ |
537 | #define OV7670_REG_COM4 0x0d /* Control 4 */ | 586 | #define OV7670_R0D_COM4 0x0d /* Control 4 */ |
538 | #define OV7670_REG_COM5 0x0e /* All "reserved" */ | 587 | #define OV7670_R0E_COM5 0x0e /* All "reserved" */ |
539 | #define OV7670_REG_COM6 0x0f /* Control 6 */ | 588 | #define OV7670_R0F_COM6 0x0f /* Control 6 */ |
540 | #define OV7670_REG_AECH 0x10 /* More bits of AEC value */ | 589 | #define OV7670_R10_AECH 0x10 /* More bits of AEC value */ |
541 | #define OV7670_REG_CLKRC 0x11 /* Clock control */ | 590 | #define OV7670_R11_CLKRC 0x11 /* Clock control */ |
542 | #define OV7670_REG_COM7 0x12 /* Control 7 */ | 591 | #define OV7670_R12_COM7 0x12 /* Control 7 */ |
543 | #define OV7670_COM7_FMT_VGA 0x00 | 592 | #define OV7670_COM7_FMT_VGA 0x00 |
544 | #define OV7670_COM7_YUV 0x00 /* YUV */ | 593 | /*#define OV7670_COM7_YUV 0x00 * YUV */ |
545 | #define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */ | 594 | #define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */ |
546 | #define OV7670_COM7_FMT_MASK 0x38 | 595 | #define OV7670_COM7_FMT_MASK 0x38 |
547 | #define OV7670_COM7_RESET 0x80 /* Register reset */ | 596 | #define OV7670_COM7_RESET 0x80 /* Register reset */ |
548 | #define OV7670_REG_COM8 0x13 /* Control 8 */ | 597 | #define OV7670_R13_COM8 0x13 /* Control 8 */ |
549 | #define OV7670_COM8_AEC 0x01 /* Auto exposure enable */ | 598 | #define OV7670_COM8_AEC 0x01 /* Auto exposure enable */ |
550 | #define OV7670_COM8_AWB 0x02 /* White balance enable */ | 599 | #define OV7670_COM8_AWB 0x02 /* White balance enable */ |
551 | #define OV7670_COM8_AGC 0x04 /* Auto gain enable */ | 600 | #define OV7670_COM8_AGC 0x04 /* Auto gain enable */ |
552 | #define OV7670_COM8_BFILT 0x20 /* Band filter enable */ | 601 | #define OV7670_COM8_BFILT 0x20 /* Band filter enable */ |
553 | #define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */ | 602 | #define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */ |
554 | #define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */ | 603 | #define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */ |
555 | #define OV7670_REG_COM9 0x14 /* Control 9 - gain ceiling */ | 604 | #define OV7670_R14_COM9 0x14 /* Control 9 - gain ceiling */ |
556 | #define OV7670_REG_COM10 0x15 /* Control 10 */ | 605 | #define OV7670_R15_COM10 0x15 /* Control 10 */ |
557 | #define OV7670_REG_HSTART 0x17 /* Horiz start high bits */ | 606 | #define OV7670_R17_HSTART 0x17 /* Horiz start high bits */ |
558 | #define OV7670_REG_HSTOP 0x18 /* Horiz stop high bits */ | 607 | #define OV7670_R18_HSTOP 0x18 /* Horiz stop high bits */ |
559 | #define OV7670_REG_VSTART 0x19 /* Vert start high bits */ | 608 | #define OV7670_R19_VSTART 0x19 /* Vert start high bits */ |
560 | #define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ | 609 | #define OV7670_R1A_VSTOP 0x1a /* Vert stop high bits */ |
561 | #define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ | 610 | #define OV7670_R1E_MVFP 0x1e /* Mirror / vflip */ |
562 | #define OV7670_MVFP_VFLIP 0x10 /* vertical flip */ | 611 | #define OV7670_MVFP_VFLIP 0x10 /* vertical flip */ |
563 | #define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ | 612 | #define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ |
564 | #define OV7670_REG_AEW 0x24 /* AGC upper limit */ | 613 | #define OV7670_R24_AEW 0x24 /* AGC upper limit */ |
565 | #define OV7670_REG_AEB 0x25 /* AGC lower limit */ | 614 | #define OV7670_R25_AEB 0x25 /* AGC lower limit */ |
566 | #define OV7670_REG_VPT 0x26 /* AGC/AEC fast mode op region */ | 615 | #define OV7670_R26_VPT 0x26 /* AGC/AEC fast mode op region */ |
567 | #define OV7670_REG_HREF 0x32 /* HREF pieces */ | 616 | #define OV7670_R32_HREF 0x32 /* HREF pieces */ |
568 | #define OV7670_REG_TSLB 0x3a /* lots of stuff */ | 617 | #define OV7670_R3A_TSLB 0x3a /* lots of stuff */ |
569 | #define OV7670_REG_COM11 0x3b /* Control 11 */ | 618 | #define OV7670_R3B_COM11 0x3b /* Control 11 */ |
570 | #define OV7670_COM11_EXP 0x02 | 619 | #define OV7670_COM11_EXP 0x02 |
571 | #define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */ | 620 | #define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */ |
572 | #define OV7670_REG_COM12 0x3c /* Control 12 */ | 621 | #define OV7670_R3C_COM12 0x3c /* Control 12 */ |
573 | #define OV7670_REG_COM13 0x3d /* Control 13 */ | 622 | #define OV7670_R3D_COM13 0x3d /* Control 13 */ |
574 | #define OV7670_COM13_GAMMA 0x80 /* Gamma enable */ | 623 | #define OV7670_COM13_GAMMA 0x80 /* Gamma enable */ |
575 | #define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */ | 624 | #define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */ |
576 | #define OV7670_REG_COM14 0x3e /* Control 14 */ | 625 | #define OV7670_R3E_COM14 0x3e /* Control 14 */ |
577 | #define OV7670_REG_EDGE 0x3f /* Edge enhancement factor */ | 626 | #define OV7670_R3F_EDGE 0x3f /* Edge enhancement factor */ |
578 | #define OV7670_REG_COM15 0x40 /* Control 15 */ | 627 | #define OV7670_R40_COM15 0x40 /* Control 15 */ |
579 | #define OV7670_COM15_R00FF 0xc0 /* 00 to FF */ | 628 | /*#define OV7670_COM15_R00FF 0xc0 * 00 to FF */ |
580 | #define OV7670_REG_COM16 0x41 /* Control 16 */ | 629 | #define OV7670_R41_COM16 0x41 /* Control 16 */ |
581 | #define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */ | 630 | #define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */ |
582 | #define OV7670_REG_BRIGHT 0x55 /* Brightness */ | 631 | /* end of ov7660 common registers */ |
583 | #define OV7670_REG_CONTRAS 0x56 /* Contrast control */ | 632 | #define OV7670_R55_BRIGHT 0x55 /* Brightness */ |
584 | #define OV7670_REG_GFIX 0x69 /* Fix gain control */ | 633 | #define OV7670_R56_CONTRAS 0x56 /* Contrast control */ |
585 | #define OV7670_REG_RGB444 0x8c /* RGB 444 control */ | 634 | #define OV7670_R69_GFIX 0x69 /* Fix gain control */ |
586 | #define OV7670_REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */ | 635 | /*#define OV7670_R8C_RGB444 0x8c * RGB 444 control */ |
587 | #define OV7670_REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */ | 636 | #define OV7670_R9F_HAECC1 0x9f /* Hist AEC/AGC control 1 */ |
588 | #define OV7670_REG_BD50MAX 0xa5 /* 50hz banding step limit */ | 637 | #define OV7670_RA0_HAECC2 0xa0 /* Hist AEC/AGC control 2 */ |
589 | #define OV7670_REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */ | 638 | #define OV7670_RA5_BD50MAX 0xa5 /* 50hz banding step limit */ |
590 | #define OV7670_REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */ | 639 | #define OV7670_RA6_HAECC3 0xa6 /* Hist AEC/AGC control 3 */ |
591 | #define OV7670_REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */ | 640 | #define OV7670_RA7_HAECC4 0xa7 /* Hist AEC/AGC control 4 */ |
592 | #define OV7670_REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */ | 641 | #define OV7670_RA8_HAECC5 0xa8 /* Hist AEC/AGC control 5 */ |
593 | #define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ | 642 | #define OV7670_RA9_HAECC6 0xa9 /* Hist AEC/AGC control 6 */ |
594 | #define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ | 643 | #define OV7670_RAA_HAECC7 0xaa /* Hist AEC/AGC control 7 */ |
644 | #define OV7670_RAB_BD60MAX 0xab /* 60hz banding step limit */ | ||
595 | 645 | ||
596 | struct ov_regvals { | 646 | struct ov_regvals { |
597 | __u8 reg; | 647 | u8 reg; |
598 | __u8 val; | 648 | u8 val; |
599 | }; | 649 | }; |
600 | struct ov_i2c_regvals { | 650 | struct ov_i2c_regvals { |
601 | __u8 reg; | 651 | u8 reg; |
602 | __u8 val; | 652 | u8 val; |
603 | }; | 653 | }; |
604 | 654 | ||
605 | /* Settings for OV2610 camera chip */ | 655 | /* Settings for OV2610 camera chip */ |
@@ -617,7 +667,6 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
617 | * "wait 4096 external clock ... to make sure the sensor is | 667 | * "wait 4096 external clock ... to make sure the sensor is |
618 | * stable and ready to access registers" i.e. 160us at 24MHz | 668 | * stable and ready to access registers" i.e. 160us at 24MHz |
619 | */ | 669 | */ |
620 | |||
621 | { 0x12, 0x80 }, /* COMH reset */ | 670 | { 0x12, 0x80 }, /* COMH reset */ |
622 | { 0x12, 0x00 }, /* QXGA, master */ | 671 | { 0x12, 0x00 }, /* QXGA, master */ |
623 | 672 | ||
@@ -650,7 +699,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
650 | * COMI[0] "Exposure control" | 699 | * COMI[0] "Exposure control" |
651 | * = 0 (0x00) .......0 "Manual" | 700 | * = 0 (0x00) .......0 "Manual" |
652 | */ | 701 | */ |
653 | { 0x13, 0xC0 }, | 702 | { 0x13, 0xc0 }, |
654 | 703 | ||
655 | /* | 704 | /* |
656 | * 09 COMC "Common Control C" | 705 | * 09 COMC "Common Control C" |
@@ -706,7 +755,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
706 | * COME[0] "Auto zero circuit select" | 755 | * COME[0] "Auto zero circuit select" |
707 | * = 1 (0x01) .......1 "On" | 756 | * = 1 (0x01) .......1 "On" |
708 | */ | 757 | */ |
709 | { 0x0d, 0xA1 }, | 758 | { 0x0d, 0xa1 }, |
710 | 759 | ||
711 | /* | 760 | /* |
712 | * 0E COMF "Common Control F" | 761 | * 0E COMF "Common Control F" |
@@ -770,7 +819,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
770 | * COMJ[0] "Reserved" | 819 | * COMJ[0] "Reserved" |
771 | * = 0 (0x00) .......0 | 820 | * = 0 (0x00) .......0 |
772 | */ | 821 | */ |
773 | { 0x14, 0xC6 }, | 822 | { 0x14, 0xc6 }, |
774 | 823 | ||
775 | /* | 824 | /* |
776 | * 15 COMK "Common Control K" | 825 | * 15 COMK "Common Control K" |
@@ -876,7 +925,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
876 | * FVOPT[7:0] "Range" | 925 | * FVOPT[7:0] "Range" |
877 | * = 31 (0x1F) 00011111 | 926 | * = 31 (0x1F) 00011111 |
878 | */ | 927 | */ |
879 | { 0x3c, 0x1F }, | 928 | { 0x3c, 0x1f }, |
880 | 929 | ||
881 | /* | 930 | /* |
882 | * 44 Undocumented = 0 (0x00) 00000000 | 931 | * 44 Undocumented = 0 (0x00) 00000000 |
@@ -925,7 +974,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
925 | * 48[7:0] "It's a secret" | 974 | * 48[7:0] "It's a secret" |
926 | * = 192 (0xC0) 11000000 | 975 | * = 192 (0xC0) 11000000 |
927 | */ | 976 | */ |
928 | { 0x48, 0xC0 }, | 977 | { 0x48, 0xc0 }, |
929 | 978 | ||
930 | /* | 979 | /* |
931 | * 49 Undocumented = 25 (0x19) 00011001 | 980 | * 49 Undocumented = 25 (0x19) 00011001 |
@@ -939,18 +988,18 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
939 | * 4B[7:0] "It's a secret" | 988 | * 4B[7:0] "It's a secret" |
940 | * = 128 (0x80) 10000000 | 989 | * = 128 (0x80) 10000000 |
941 | */ | 990 | */ |
942 | { 0x4B, 0x80 }, | 991 | { 0x4b, 0x80 }, |
943 | 992 | ||
944 | /* | 993 | /* |
945 | * 4D Undocumented = 196 (0xC4) 11000100 | 994 | * 4D Undocumented = 196 (0xC4) 11000100 |
946 | * 4D[7:0] "It's a secret" | 995 | * 4D[7:0] "It's a secret" |
947 | * = 196 (0xC4) 11000100 | 996 | * = 196 (0xC4) 11000100 |
948 | */ | 997 | */ |
949 | { 0x4D, 0xC4 }, | 998 | { 0x4d, 0xc4 }, |
950 | 999 | ||
951 | /* | 1000 | /* |
952 | * 35 VREF "Reference Voltage Control" | 1001 | * 35 VREF "Reference Voltage Control" |
953 | * = 76 (0x4C) 01001100 | 1002 | * = 76 (0x4c) 01001100 |
954 | * VREF[7:5] "Column high reference control" | 1003 | * VREF[7:5] "Column high reference control" |
955 | * = 2 (0x02) 010..... "higher voltage" | 1004 | * = 2 (0x02) 010..... "higher voltage" |
956 | * VREF[4:2] "Column low reference control" | 1005 | * VREF[4:2] "Column low reference control" |
@@ -958,21 +1007,21 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
958 | * VREF[1:0] "Reserved" | 1007 | * VREF[1:0] "Reserved" |
959 | * = 0 (0x00) ......00 | 1008 | * = 0 (0x00) ......00 |
960 | */ | 1009 | */ |
961 | { 0x35, 0x4C }, | 1010 | { 0x35, 0x4c }, |
962 | 1011 | ||
963 | /* | 1012 | /* |
964 | * 3D Undocumented = 0 (0x00) 00000000 | 1013 | * 3D Undocumented = 0 (0x00) 00000000 |
965 | * 3D[7:0] "It's a secret" | 1014 | * 3D[7:0] "It's a secret" |
966 | * = 0 (0x00) 00000000 | 1015 | * = 0 (0x00) 00000000 |
967 | */ | 1016 | */ |
968 | { 0x3D, 0x00 }, | 1017 | { 0x3d, 0x00 }, |
969 | 1018 | ||
970 | /* | 1019 | /* |
971 | * 3E Undocumented = 0 (0x00) 00000000 | 1020 | * 3E Undocumented = 0 (0x00) 00000000 |
972 | * 3E[7:0] "It's a secret" | 1021 | * 3E[7:0] "It's a secret" |
973 | * = 0 (0x00) 00000000 | 1022 | * = 0 (0x00) 00000000 |
974 | */ | 1023 | */ |
975 | { 0x3E, 0x00 }, | 1024 | { 0x3e, 0x00 }, |
976 | 1025 | ||
977 | /* | 1026 | /* |
978 | * 3B FREFB "Internal Reference Adjustment" | 1027 | * 3B FREFB "Internal Reference Adjustment" |
@@ -1012,7 +1061,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1012 | * VBLM[3:0] "Sensor current control" | 1061 | * VBLM[3:0] "Sensor current control" |
1013 | * = 10 (0x0A) ....1010 | 1062 | * = 10 (0x0A) ....1010 |
1014 | */ | 1063 | */ |
1015 | { 0x34, 0x5A }, | 1064 | { 0x34, 0x5a }, |
1016 | 1065 | ||
1017 | /* | 1066 | /* |
1018 | * 3B FREFB "Internal Reference Adjustment" | 1067 | * 3B FREFB "Internal Reference Adjustment" |
@@ -1078,7 +1127,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1078 | * HREFST[7:0] "Horizontal window start, 8 MSBs" | 1127 | * HREFST[7:0] "Horizontal window start, 8 MSBs" |
1079 | * = 31 (0x1F) 00011111 | 1128 | * = 31 (0x1F) 00011111 |
1080 | */ | 1129 | */ |
1081 | { 0x17, 0x1F }, | 1130 | { 0x17, 0x1f }, |
1082 | 1131 | ||
1083 | /* | 1132 | /* |
1084 | * 18 HREFEND "Horizontal window end" | 1133 | * 18 HREFEND "Horizontal window end" |
@@ -1086,7 +1135,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1086 | * HREFEND[7:0] "Horizontal Window End, 8 MSBs" | 1135 | * HREFEND[7:0] "Horizontal Window End, 8 MSBs" |
1087 | * = 95 (0x5F) 01011111 | 1136 | * = 95 (0x5F) 01011111 |
1088 | */ | 1137 | */ |
1089 | { 0x18, 0x5F }, | 1138 | { 0x18, 0x5f }, |
1090 | 1139 | ||
1091 | /* | 1140 | /* |
1092 | * 19 VSTRT "Vertical window start" | 1141 | * 19 VSTRT "Vertical window start" |
@@ -1126,7 +1175,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1126 | * COMA[1:0] "Vertical window start line control 2 LSBs" | 1175 | * COMA[1:0] "Vertical window start line control 2 LSBs" |
1127 | * = 2 (0x02) ......10 | 1176 | * = 2 (0x02) ......10 |
1128 | */ | 1177 | */ |
1129 | { 0x03, 0x4A }, | 1178 | { 0x03, 0x4a }, |
1130 | 1179 | ||
1131 | /* | 1180 | /* |
1132 | * 11 CLKRC "Clock Rate Control" | 1181 | * 11 CLKRC "Clock Rate Control" |
@@ -1183,7 +1232,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1183 | * HREFST[7:0] "Horizontal window start, 8 MSBs" | 1232 | * HREFST[7:0] "Horizontal window start, 8 MSBs" |
1184 | * = 31 (0x1F) 00011111 | 1233 | * = 31 (0x1F) 00011111 |
1185 | */ | 1234 | */ |
1186 | { 0x17, 0x1F }, | 1235 | { 0x17, 0x1f }, |
1187 | 1236 | ||
1188 | /* | 1237 | /* |
1189 | * 18 HREFEND "Horizontal window end" | 1238 | * 18 HREFEND "Horizontal window end" |
@@ -1191,7 +1240,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1191 | * HREFEND[7:0] "Horizontal Window End, 8 MSBs" | 1240 | * HREFEND[7:0] "Horizontal Window End, 8 MSBs" |
1192 | * = 95 (0x5F) 01011111 | 1241 | * = 95 (0x5F) 01011111 |
1193 | */ | 1242 | */ |
1194 | { 0x18, 0x5F }, | 1243 | { 0x18, 0x5f }, |
1195 | 1244 | ||
1196 | /* | 1245 | /* |
1197 | * 19 VSTRT "Vertical window start" | 1246 | * 19 VSTRT "Vertical window start" |
@@ -1231,7 +1280,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1231 | * COMA[1:0] "Vertical window start line control 2 LSBs" | 1280 | * COMA[1:0] "Vertical window start line control 2 LSBs" |
1232 | * = 2 (0x02) ......10 | 1281 | * = 2 (0x02) ......10 |
1233 | */ | 1282 | */ |
1234 | { 0x03, 0x4A }, | 1283 | { 0x03, 0x4a }, |
1235 | 1284 | ||
1236 | /* | 1285 | /* |
1237 | * 02 RED "Red Gain Control" | 1286 | * 02 RED "Red Gain Control" |
@@ -1241,7 +1290,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1241 | * RED[6:0] "Value" | 1290 | * RED[6:0] "Value" |
1242 | * = 47 (0x2F) .0101111 | 1291 | * = 47 (0x2F) .0101111 |
1243 | */ | 1292 | */ |
1244 | { 0x02, 0xAF }, | 1293 | { 0x02, 0xaf }, |
1245 | 1294 | ||
1246 | /* | 1295 | /* |
1247 | * 2D ADDVSL "VSYNC Pulse Width" | 1296 | * 2D ADDVSL "VSYNC Pulse Width" |
@@ -1249,7 +1298,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1249 | * ADDVSL[7:0] "VSYNC pulse width, LSB" | 1298 | * ADDVSL[7:0] "VSYNC pulse width, LSB" |
1250 | * = 210 (0xD2) 11010010 | 1299 | * = 210 (0xD2) 11010010 |
1251 | */ | 1300 | */ |
1252 | { 0x2d, 0xD2 }, | 1301 | { 0x2d, 0xd2 }, |
1253 | 1302 | ||
1254 | /* | 1303 | /* |
1255 | * 00 GAIN = 24 (0x18) 00011000 | 1304 | * 00 GAIN = 24 (0x18) 00011000 |
@@ -1272,7 +1321,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1272 | * BLUE[6:0] "Value" | 1321 | * BLUE[6:0] "Value" |
1273 | * = 112 (0x70) .1110000 | 1322 | * = 112 (0x70) .1110000 |
1274 | */ | 1323 | */ |
1275 | { 0x01, 0xF0 }, | 1324 | { 0x01, 0xf0 }, |
1276 | 1325 | ||
1277 | /* | 1326 | /* |
1278 | * 10 AEC "Automatic Exposure Control" | 1327 | * 10 AEC "Automatic Exposure Control" |
@@ -1280,14 +1329,14 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1280 | * AEC[7:0] "Automatic Exposure Control, 8 MSBs" | 1329 | * AEC[7:0] "Automatic Exposure Control, 8 MSBs" |
1281 | * = 10 (0x0A) 00001010 | 1330 | * = 10 (0x0A) 00001010 |
1282 | */ | 1331 | */ |
1283 | { 0x10, 0x0A }, | 1332 | { 0x10, 0x0a }, |
1284 | 1333 | ||
1285 | { 0xE1, 0x67 }, | 1334 | { 0xe1, 0x67 }, |
1286 | { 0xE3, 0x03 }, | 1335 | { 0xe3, 0x03 }, |
1287 | { 0xE4, 0x26 }, | 1336 | { 0xe4, 0x26 }, |
1288 | { 0xE5, 0x3E }, | 1337 | { 0xe5, 0x3e }, |
1289 | { 0xF8, 0x01 }, | 1338 | { 0xf8, 0x01 }, |
1290 | { 0xFF, 0x01 }, | 1339 | { 0xff, 0x01 }, |
1291 | }; | 1340 | }; |
1292 | 1341 | ||
1293 | static const struct ov_i2c_regvals norm_6x20[] = { | 1342 | static const struct ov_i2c_regvals norm_6x20[] = { |
@@ -1296,7 +1345,7 @@ static const struct ov_i2c_regvals norm_6x20[] = { | |||
1296 | { 0x03, 0x60 }, | 1345 | { 0x03, 0x60 }, |
1297 | { 0x05, 0x7f }, /* For when autoadjust is off */ | 1346 | { 0x05, 0x7f }, /* For when autoadjust is off */ |
1298 | { 0x07, 0xa8 }, | 1347 | { 0x07, 0xa8 }, |
1299 | /* The ratio of 0x0c and 0x0d controls the white point */ | 1348 | /* The ratio of 0x0c and 0x0d controls the white point */ |
1300 | { 0x0c, 0x24 }, | 1349 | { 0x0c, 0x24 }, |
1301 | { 0x0d, 0x24 }, | 1350 | { 0x0d, 0x24 }, |
1302 | { 0x0f, 0x15 }, /* COMS */ | 1351 | { 0x0f, 0x15 }, /* COMS */ |
@@ -1464,7 +1513,7 @@ static const struct ov_i2c_regvals norm_7620[] = { | |||
1464 | { 0x00, 0x00 }, /* gain */ | 1513 | { 0x00, 0x00 }, /* gain */ |
1465 | { 0x01, 0x80 }, /* blue gain */ | 1514 | { 0x01, 0x80 }, /* blue gain */ |
1466 | { 0x02, 0x80 }, /* red gain */ | 1515 | { 0x02, 0x80 }, /* red gain */ |
1467 | { 0x03, 0xc0 }, /* OV7670_REG_VREF */ | 1516 | { 0x03, 0xc0 }, /* OV7670_R03_VREF */ |
1468 | { 0x06, 0x60 }, | 1517 | { 0x06, 0x60 }, |
1469 | { 0x07, 0x00 }, | 1518 | { 0x07, 0x00 }, |
1470 | { 0x0c, 0x24 }, | 1519 | { 0x0c, 0x24 }, |
@@ -1532,33 +1581,177 @@ static const struct ov_i2c_regvals norm_7640[] = { | |||
1532 | { 0x12, 0x14 }, | 1581 | { 0x12, 0x14 }, |
1533 | }; | 1582 | }; |
1534 | 1583 | ||
1584 | static const struct ov_regvals init_519_ov7660[] = { | ||
1585 | { 0x5d, 0x03 }, /* Turn off suspend mode */ | ||
1586 | { 0x53, 0x9b }, /* 0x9f enables the (unused) microcontroller */ | ||
1587 | { 0x54, 0x0f }, /* bit2 (jpeg enable) */ | ||
1588 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ | ||
1589 | { 0xa3, 0x18 }, | ||
1590 | { 0xa4, 0x04 }, | ||
1591 | { 0xa5, 0x28 }, | ||
1592 | { 0x37, 0x00 }, /* SetUsbInit */ | ||
1593 | { 0x55, 0x02 }, /* 4.096 Mhz audio clock */ | ||
1594 | /* Enable both fields, YUV Input, disable defect comp (why?) */ | ||
1595 | { 0x20, 0x0c }, /* 0x0d does U <-> V swap */ | ||
1596 | { 0x21, 0x38 }, | ||
1597 | { 0x22, 0x1d }, | ||
1598 | { 0x17, 0x50 }, /* undocumented */ | ||
1599 | { 0x37, 0x00 }, /* undocumented */ | ||
1600 | { 0x40, 0xff }, /* I2C timeout counter */ | ||
1601 | { 0x46, 0x00 }, /* I2C clock prescaler */ | ||
1602 | }; | ||
1603 | static const struct ov_i2c_regvals norm_7660[] = { | ||
1604 | {OV7670_R12_COM7, OV7670_COM7_RESET}, | ||
1605 | {OV7670_R11_CLKRC, 0x81}, | ||
1606 | {0x92, 0x00}, /* DM_LNL */ | ||
1607 | {0x93, 0x00}, /* DM_LNH */ | ||
1608 | {0x9d, 0x4c}, /* BD50ST */ | ||
1609 | {0x9e, 0x3f}, /* BD60ST */ | ||
1610 | {OV7670_R3B_COM11, 0x02}, | ||
1611 | {OV7670_R13_COM8, 0xf5}, | ||
1612 | {OV7670_R10_AECH, 0x00}, | ||
1613 | {OV7670_R00_GAIN, 0x00}, | ||
1614 | {OV7670_R01_BLUE, 0x7c}, | ||
1615 | {OV7670_R02_RED, 0x9d}, | ||
1616 | {OV7670_R12_COM7, 0x00}, | ||
1617 | {OV7670_R04_COM1, 00}, | ||
1618 | {OV7670_R18_HSTOP, 0x01}, | ||
1619 | {OV7670_R17_HSTART, 0x13}, | ||
1620 | {OV7670_R32_HREF, 0x92}, | ||
1621 | {OV7670_R19_VSTART, 0x02}, | ||
1622 | {OV7670_R1A_VSTOP, 0x7a}, | ||
1623 | {OV7670_R03_VREF, 0x00}, | ||
1624 | {OV7670_R0E_COM5, 0x04}, | ||
1625 | {OV7670_R0F_COM6, 0x62}, | ||
1626 | {OV7670_R15_COM10, 0x00}, | ||
1627 | {0x16, 0x02}, /* RSVD */ | ||
1628 | {0x1b, 0x00}, /* PSHFT */ | ||
1629 | {OV7670_R1E_MVFP, 0x01}, | ||
1630 | {0x29, 0x3c}, /* RSVD */ | ||
1631 | {0x33, 0x00}, /* CHLF */ | ||
1632 | {0x34, 0x07}, /* ARBLM */ | ||
1633 | {0x35, 0x84}, /* RSVD */ | ||
1634 | {0x36, 0x00}, /* RSVD */ | ||
1635 | {0x37, 0x04}, /* ADC */ | ||
1636 | {0x39, 0x43}, /* OFON */ | ||
1637 | {OV7670_R3A_TSLB, 0x00}, | ||
1638 | {OV7670_R3C_COM12, 0x6c}, | ||
1639 | {OV7670_R3D_COM13, 0x98}, | ||
1640 | {OV7670_R3F_EDGE, 0x23}, | ||
1641 | {OV7670_R40_COM15, 0xc1}, | ||
1642 | {OV7670_R41_COM16, 0x22}, | ||
1643 | {0x6b, 0x0a}, /* DBLV */ | ||
1644 | {0xa1, 0x08}, /* RSVD */ | ||
1645 | {0x69, 0x80}, /* HV */ | ||
1646 | {0x43, 0xf0}, /* RSVD.. */ | ||
1647 | {0x44, 0x10}, | ||
1648 | {0x45, 0x78}, | ||
1649 | {0x46, 0xa8}, | ||
1650 | {0x47, 0x60}, | ||
1651 | {0x48, 0x80}, | ||
1652 | {0x59, 0xba}, | ||
1653 | {0x5a, 0x9a}, | ||
1654 | {0x5b, 0x22}, | ||
1655 | {0x5c, 0xb9}, | ||
1656 | {0x5d, 0x9b}, | ||
1657 | {0x5e, 0x10}, | ||
1658 | {0x5f, 0xe0}, | ||
1659 | {0x60, 0x85}, | ||
1660 | {0x61, 0x60}, | ||
1661 | {0x9f, 0x9d}, /* RSVD */ | ||
1662 | {0xa0, 0xa0}, /* DSPC2 */ | ||
1663 | {0x4f, 0x60}, /* matrix */ | ||
1664 | {0x50, 0x64}, | ||
1665 | {0x51, 0x04}, | ||
1666 | {0x52, 0x18}, | ||
1667 | {0x53, 0x3c}, | ||
1668 | {0x54, 0x54}, | ||
1669 | {0x55, 0x40}, | ||
1670 | {0x56, 0x40}, | ||
1671 | {0x57, 0x40}, | ||
1672 | {0x58, 0x0d}, /* matrix sign */ | ||
1673 | {0x8b, 0xcc}, /* RSVD */ | ||
1674 | {0x8c, 0xcc}, | ||
1675 | {0x8d, 0xcf}, | ||
1676 | {0x6c, 0x40}, /* gamma curve */ | ||
1677 | {0x6d, 0xe0}, | ||
1678 | {0x6e, 0xa0}, | ||
1679 | {0x6f, 0x80}, | ||
1680 | {0x70, 0x70}, | ||
1681 | {0x71, 0x80}, | ||
1682 | {0x72, 0x60}, | ||
1683 | {0x73, 0x60}, | ||
1684 | {0x74, 0x50}, | ||
1685 | {0x75, 0x40}, | ||
1686 | {0x76, 0x38}, | ||
1687 | {0x77, 0x3c}, | ||
1688 | {0x78, 0x32}, | ||
1689 | {0x79, 0x1a}, | ||
1690 | {0x7a, 0x28}, | ||
1691 | {0x7b, 0x24}, | ||
1692 | {0x7c, 0x04}, /* gamma curve */ | ||
1693 | {0x7d, 0x12}, | ||
1694 | {0x7e, 0x26}, | ||
1695 | {0x7f, 0x46}, | ||
1696 | {0x80, 0x54}, | ||
1697 | {0x81, 0x64}, | ||
1698 | {0x82, 0x70}, | ||
1699 | {0x83, 0x7c}, | ||
1700 | {0x84, 0x86}, | ||
1701 | {0x85, 0x8e}, | ||
1702 | {0x86, 0x9c}, | ||
1703 | {0x87, 0xab}, | ||
1704 | {0x88, 0xc4}, | ||
1705 | {0x89, 0xd1}, | ||
1706 | {0x8a, 0xe5}, | ||
1707 | {OV7670_R14_COM9, 0x1e}, | ||
1708 | {OV7670_R24_AEW, 0x80}, | ||
1709 | {OV7670_R25_AEB, 0x72}, | ||
1710 | {OV7670_R26_VPT, 0xb3}, | ||
1711 | {0x62, 0x80}, /* LCC1 */ | ||
1712 | {0x63, 0x80}, /* LCC2 */ | ||
1713 | {0x64, 0x06}, /* LCC3 */ | ||
1714 | {0x65, 0x00}, /* LCC4 */ | ||
1715 | {0x66, 0x01}, /* LCC5 */ | ||
1716 | {0x94, 0x0e}, /* RSVD.. */ | ||
1717 | {0x95, 0x14}, | ||
1718 | {OV7670_R13_COM8, OV7670_COM8_FASTAEC | ||
1719 | | OV7670_COM8_AECSTEP | ||
1720 | | OV7670_COM8_BFILT | ||
1721 | | 0x10 | ||
1722 | | OV7670_COM8_AGC | ||
1723 | | OV7670_COM8_AWB | ||
1724 | | OV7670_COM8_AEC}, | ||
1725 | {0xa1, 0xc8} | ||
1726 | }; | ||
1727 | |||
1535 | /* 7670. Defaults taken from OmniVision provided data, | 1728 | /* 7670. Defaults taken from OmniVision provided data, |
1536 | * as provided by Jonathan Corbet of OLPC */ | 1729 | * as provided by Jonathan Corbet of OLPC */ |
1537 | static const struct ov_i2c_regvals norm_7670[] = { | 1730 | static const struct ov_i2c_regvals norm_7670[] = { |
1538 | { OV7670_REG_COM7, OV7670_COM7_RESET }, | 1731 | { OV7670_R12_COM7, OV7670_COM7_RESET }, |
1539 | { OV7670_REG_TSLB, 0x04 }, /* OV */ | 1732 | { OV7670_R3A_TSLB, 0x04 }, /* OV */ |
1540 | { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ | 1733 | { OV7670_R12_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ |
1541 | { OV7670_REG_CLKRC, 0x01 }, | 1734 | { OV7670_R11_CLKRC, 0x01 }, |
1542 | /* | 1735 | /* |
1543 | * Set the hardware window. These values from OV don't entirely | 1736 | * Set the hardware window. These values from OV don't entirely |
1544 | * make sense - hstop is less than hstart. But they work... | 1737 | * make sense - hstop is less than hstart. But they work... |
1545 | */ | 1738 | */ |
1546 | { OV7670_REG_HSTART, 0x13 }, | 1739 | { OV7670_R17_HSTART, 0x13 }, |
1547 | { OV7670_REG_HSTOP, 0x01 }, | 1740 | { OV7670_R18_HSTOP, 0x01 }, |
1548 | { OV7670_REG_HREF, 0xb6 }, | 1741 | { OV7670_R32_HREF, 0xb6 }, |
1549 | { OV7670_REG_VSTART, 0x02 }, | 1742 | { OV7670_R19_VSTART, 0x02 }, |
1550 | { OV7670_REG_VSTOP, 0x7a }, | 1743 | { OV7670_R1A_VSTOP, 0x7a }, |
1551 | { OV7670_REG_VREF, 0x0a }, | 1744 | { OV7670_R03_VREF, 0x0a }, |
1552 | 1745 | ||
1553 | { OV7670_REG_COM3, 0x00 }, | 1746 | { OV7670_R0C_COM3, 0x00 }, |
1554 | { OV7670_REG_COM14, 0x00 }, | 1747 | { OV7670_R3E_COM14, 0x00 }, |
1555 | /* Mystery scaling numbers */ | 1748 | /* Mystery scaling numbers */ |
1556 | { 0x70, 0x3a }, | 1749 | { 0x70, 0x3a }, |
1557 | { 0x71, 0x35 }, | 1750 | { 0x71, 0x35 }, |
1558 | { 0x72, 0x11 }, | 1751 | { 0x72, 0x11 }, |
1559 | { 0x73, 0xf0 }, | 1752 | { 0x73, 0xf0 }, |
1560 | { 0xa2, 0x02 }, | 1753 | { 0xa2, 0x02 }, |
1561 | /* { OV7670_REG_COM10, 0x0 }, */ | 1754 | /* { OV7670_R15_COM10, 0x0 }, */ |
1562 | 1755 | ||
1563 | /* Gamma curve values */ | 1756 | /* Gamma curve values */ |
1564 | { 0x7a, 0x20 }, | 1757 | { 0x7a, 0x20 }, |
@@ -1580,37 +1773,37 @@ static const struct ov_i2c_regvals norm_7670[] = { | |||
1580 | 1773 | ||
1581 | /* AGC and AEC parameters. Note we start by disabling those features, | 1774 | /* AGC and AEC parameters. Note we start by disabling those features, |
1582 | then turn them only after tweaking the values. */ | 1775 | then turn them only after tweaking the values. */ |
1583 | { OV7670_REG_COM8, OV7670_COM8_FASTAEC | 1776 | { OV7670_R13_COM8, OV7670_COM8_FASTAEC |
1584 | | OV7670_COM8_AECSTEP | 1777 | | OV7670_COM8_AECSTEP |
1585 | | OV7670_COM8_BFILT }, | 1778 | | OV7670_COM8_BFILT }, |
1586 | { OV7670_REG_GAIN, 0x00 }, | 1779 | { OV7670_R00_GAIN, 0x00 }, |
1587 | { OV7670_REG_AECH, 0x00 }, | 1780 | { OV7670_R10_AECH, 0x00 }, |
1588 | { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ | 1781 | { OV7670_R0D_COM4, 0x40 }, /* magic reserved bit */ |
1589 | { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ | 1782 | { OV7670_R14_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ |
1590 | { OV7670_REG_BD50MAX, 0x05 }, | 1783 | { OV7670_RA5_BD50MAX, 0x05 }, |
1591 | { OV7670_REG_BD60MAX, 0x07 }, | 1784 | { OV7670_RAB_BD60MAX, 0x07 }, |
1592 | { OV7670_REG_AEW, 0x95 }, | 1785 | { OV7670_R24_AEW, 0x95 }, |
1593 | { OV7670_REG_AEB, 0x33 }, | 1786 | { OV7670_R25_AEB, 0x33 }, |
1594 | { OV7670_REG_VPT, 0xe3 }, | 1787 | { OV7670_R26_VPT, 0xe3 }, |
1595 | { OV7670_REG_HAECC1, 0x78 }, | 1788 | { OV7670_R9F_HAECC1, 0x78 }, |
1596 | { OV7670_REG_HAECC2, 0x68 }, | 1789 | { OV7670_RA0_HAECC2, 0x68 }, |
1597 | { 0xa1, 0x03 }, /* magic */ | 1790 | { 0xa1, 0x03 }, /* magic */ |
1598 | { OV7670_REG_HAECC3, 0xd8 }, | 1791 | { OV7670_RA6_HAECC3, 0xd8 }, |
1599 | { OV7670_REG_HAECC4, 0xd8 }, | 1792 | { OV7670_RA7_HAECC4, 0xd8 }, |
1600 | { OV7670_REG_HAECC5, 0xf0 }, | 1793 | { OV7670_RA8_HAECC5, 0xf0 }, |
1601 | { OV7670_REG_HAECC6, 0x90 }, | 1794 | { OV7670_RA9_HAECC6, 0x90 }, |
1602 | { OV7670_REG_HAECC7, 0x94 }, | 1795 | { OV7670_RAA_HAECC7, 0x94 }, |
1603 | { OV7670_REG_COM8, OV7670_COM8_FASTAEC | 1796 | { OV7670_R13_COM8, OV7670_COM8_FASTAEC |
1604 | | OV7670_COM8_AECSTEP | 1797 | | OV7670_COM8_AECSTEP |
1605 | | OV7670_COM8_BFILT | 1798 | | OV7670_COM8_BFILT |
1606 | | OV7670_COM8_AGC | 1799 | | OV7670_COM8_AGC |
1607 | | OV7670_COM8_AEC }, | 1800 | | OV7670_COM8_AEC }, |
1608 | 1801 | ||
1609 | /* Almost all of these are magic "reserved" values. */ | 1802 | /* Almost all of these are magic "reserved" values. */ |
1610 | { OV7670_REG_COM5, 0x61 }, | 1803 | { OV7670_R0E_COM5, 0x61 }, |
1611 | { OV7670_REG_COM6, 0x4b }, | 1804 | { OV7670_R0F_COM6, 0x4b }, |
1612 | { 0x16, 0x02 }, | 1805 | { 0x16, 0x02 }, |
1613 | { OV7670_REG_MVFP, 0x07 }, | 1806 | { OV7670_R1E_MVFP, 0x07 }, |
1614 | { 0x21, 0x02 }, | 1807 | { 0x21, 0x02 }, |
1615 | { 0x22, 0x91 }, | 1808 | { 0x22, 0x91 }, |
1616 | { 0x29, 0x07 }, | 1809 | { 0x29, 0x07 }, |
@@ -1619,10 +1812,10 @@ static const struct ov_i2c_regvals norm_7670[] = { | |||
1619 | { 0x37, 0x1d }, | 1812 | { 0x37, 0x1d }, |
1620 | { 0x38, 0x71 }, | 1813 | { 0x38, 0x71 }, |
1621 | { 0x39, 0x2a }, | 1814 | { 0x39, 0x2a }, |
1622 | { OV7670_REG_COM12, 0x78 }, | 1815 | { OV7670_R3C_COM12, 0x78 }, |
1623 | { 0x4d, 0x40 }, | 1816 | { 0x4d, 0x40 }, |
1624 | { 0x4e, 0x20 }, | 1817 | { 0x4e, 0x20 }, |
1625 | { OV7670_REG_GFIX, 0x00 }, | 1818 | { OV7670_R69_GFIX, 0x00 }, |
1626 | { 0x6b, 0x4a }, | 1819 | { 0x6b, 0x4a }, |
1627 | { 0x74, 0x10 }, | 1820 | { 0x74, 0x10 }, |
1628 | { 0x8d, 0x4f }, | 1821 | { 0x8d, 0x4f }, |
@@ -1657,9 +1850,9 @@ static const struct ov_i2c_regvals norm_7670[] = { | |||
1657 | { 0x6f, 0x9f }, | 1850 | { 0x6f, 0x9f }, |
1658 | /* "9e for advance AWB" */ | 1851 | /* "9e for advance AWB" */ |
1659 | { 0x6a, 0x40 }, | 1852 | { 0x6a, 0x40 }, |
1660 | { OV7670_REG_BLUE, 0x40 }, | 1853 | { OV7670_R01_BLUE, 0x40 }, |
1661 | { OV7670_REG_RED, 0x60 }, | 1854 | { OV7670_R02_RED, 0x60 }, |
1662 | { OV7670_REG_COM8, OV7670_COM8_FASTAEC | 1855 | { OV7670_R13_COM8, OV7670_COM8_FASTAEC |
1663 | | OV7670_COM8_AECSTEP | 1856 | | OV7670_COM8_AECSTEP |
1664 | | OV7670_COM8_BFILT | 1857 | | OV7670_COM8_BFILT |
1665 | | OV7670_COM8_AGC | 1858 | | OV7670_COM8_AGC |
@@ -1675,22 +1868,22 @@ static const struct ov_i2c_regvals norm_7670[] = { | |||
1675 | { 0x54, 0x80 }, | 1868 | { 0x54, 0x80 }, |
1676 | { 0x58, 0x9e }, | 1869 | { 0x58, 0x9e }, |
1677 | 1870 | ||
1678 | { OV7670_REG_COM16, OV7670_COM16_AWBGAIN }, | 1871 | { OV7670_R41_COM16, OV7670_COM16_AWBGAIN }, |
1679 | { OV7670_REG_EDGE, 0x00 }, | 1872 | { OV7670_R3F_EDGE, 0x00 }, |
1680 | { 0x75, 0x05 }, | 1873 | { 0x75, 0x05 }, |
1681 | { 0x76, 0xe1 }, | 1874 | { 0x76, 0xe1 }, |
1682 | { 0x4c, 0x00 }, | 1875 | { 0x4c, 0x00 }, |
1683 | { 0x77, 0x01 }, | 1876 | { 0x77, 0x01 }, |
1684 | { OV7670_REG_COM13, OV7670_COM13_GAMMA | 1877 | { OV7670_R3D_COM13, OV7670_COM13_GAMMA |
1685 | | OV7670_COM13_UVSAT | 1878 | | OV7670_COM13_UVSAT |
1686 | | 2}, /* was 3 */ | 1879 | | 2}, /* was 3 */ |
1687 | { 0x4b, 0x09 }, | 1880 | { 0x4b, 0x09 }, |
1688 | { 0xc9, 0x60 }, | 1881 | { 0xc9, 0x60 }, |
1689 | { OV7670_REG_COM16, 0x38 }, | 1882 | { OV7670_R41_COM16, 0x38 }, |
1690 | { 0x56, 0x40 }, | 1883 | { 0x56, 0x40 }, |
1691 | 1884 | ||
1692 | { 0x34, 0x11 }, | 1885 | { 0x34, 0x11 }, |
1693 | { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO }, | 1886 | { OV7670_R3B_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO }, |
1694 | { 0xa4, 0x88 }, | 1887 | { 0xa4, 0x88 }, |
1695 | { 0x96, 0x00 }, | 1888 | { 0x96, 0x00 }, |
1696 | { 0x97, 0x30 }, | 1889 | { 0x97, 0x30 }, |
@@ -1825,10 +2018,13 @@ static unsigned char ov7670_abs_to_sm(unsigned char v) | |||
1825 | } | 2018 | } |
1826 | 2019 | ||
1827 | /* Write a OV519 register */ | 2020 | /* Write a OV519 register */ |
1828 | static int reg_w(struct sd *sd, __u16 index, __u16 value) | 2021 | static void reg_w(struct sd *sd, u16 index, u16 value) |
1829 | { | 2022 | { |
1830 | int ret, req = 0; | 2023 | int ret, req = 0; |
1831 | 2024 | ||
2025 | if (sd->gspca_dev.usb_err < 0) | ||
2026 | return; | ||
2027 | |||
1832 | switch (sd->bridge) { | 2028 | switch (sd->bridge) { |
1833 | case BRIDGE_OV511: | 2029 | case BRIDGE_OV511: |
1834 | case BRIDGE_OV511PLUS: | 2030 | case BRIDGE_OV511PLUS: |
@@ -1838,6 +2034,8 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value) | |||
1838 | req = 0x0a; | 2034 | req = 0x0a; |
1839 | /* fall through */ | 2035 | /* fall through */ |
1840 | case BRIDGE_W9968CF: | 2036 | case BRIDGE_W9968CF: |
2037 | PDEBUG(D_USBO, "SET %02x %04x %04x", | ||
2038 | req, value, index); | ||
1841 | ret = usb_control_msg(sd->gspca_dev.dev, | 2039 | ret = usb_control_msg(sd->gspca_dev.dev, |
1842 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | 2040 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), |
1843 | req, | 2041 | req, |
@@ -1848,6 +2046,8 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value) | |||
1848 | req = 1; | 2046 | req = 1; |
1849 | } | 2047 | } |
1850 | 2048 | ||
2049 | PDEBUG(D_USBO, "SET %02x 0000 %04x %02x", | ||
2050 | req, index, value); | ||
1851 | sd->gspca_dev.usb_buf[0] = value; | 2051 | sd->gspca_dev.usb_buf[0] = value; |
1852 | ret = usb_control_msg(sd->gspca_dev.dev, | 2052 | ret = usb_control_msg(sd->gspca_dev.dev, |
1853 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | 2053 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), |
@@ -1857,22 +2057,22 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value) | |||
1857 | sd->gspca_dev.usb_buf, 1, 500); | 2057 | sd->gspca_dev.usb_buf, 1, 500); |
1858 | leave: | 2058 | leave: |
1859 | if (ret < 0) { | 2059 | if (ret < 0) { |
1860 | err("Write reg 0x%04x -> [0x%02x] failed", | 2060 | err("reg_w %02x failed %d", index, ret); |
1861 | value, index); | 2061 | sd->gspca_dev.usb_err = ret; |
1862 | return ret; | 2062 | return; |
1863 | } | 2063 | } |
1864 | |||
1865 | PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index); | ||
1866 | return 0; | ||
1867 | } | 2064 | } |
1868 | 2065 | ||
1869 | /* Read from a OV519 register, note not valid for the w9968cf!! */ | 2066 | /* Read from a OV519 register, note not valid for the w9968cf!! */ |
1870 | /* returns: negative is error, pos or zero is data */ | 2067 | /* returns: negative is error, pos or zero is data */ |
1871 | static int reg_r(struct sd *sd, __u16 index) | 2068 | static int reg_r(struct sd *sd, u16 index) |
1872 | { | 2069 | { |
1873 | int ret; | 2070 | int ret; |
1874 | int req; | 2071 | int req; |
1875 | 2072 | ||
2073 | if (sd->gspca_dev.usb_err < 0) | ||
2074 | return -1; | ||
2075 | |||
1876 | switch (sd->bridge) { | 2076 | switch (sd->bridge) { |
1877 | case BRIDGE_OV511: | 2077 | case BRIDGE_OV511: |
1878 | case BRIDGE_OV511PLUS: | 2078 | case BRIDGE_OV511PLUS: |
@@ -1893,29 +2093,37 @@ static int reg_r(struct sd *sd, __u16 index) | |||
1893 | 2093 | ||
1894 | if (ret >= 0) { | 2094 | if (ret >= 0) { |
1895 | ret = sd->gspca_dev.usb_buf[0]; | 2095 | ret = sd->gspca_dev.usb_buf[0]; |
1896 | PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret); | 2096 | PDEBUG(D_USBI, "GET %02x 0000 %04x %02x", |
1897 | } else | 2097 | req, index, ret); |
1898 | err("Read reg [0x%02x] failed", index); | 2098 | } else { |
2099 | err("reg_r %02x failed %d", index, ret); | ||
2100 | sd->gspca_dev.usb_err = ret; | ||
2101 | } | ||
1899 | 2102 | ||
1900 | return ret; | 2103 | return ret; |
1901 | } | 2104 | } |
1902 | 2105 | ||
1903 | /* Read 8 values from a OV519 register */ | 2106 | /* Read 8 values from a OV519 register */ |
1904 | static int reg_r8(struct sd *sd, | 2107 | static int reg_r8(struct sd *sd, |
1905 | __u16 index) | 2108 | u16 index) |
1906 | { | 2109 | { |
1907 | int ret; | 2110 | int ret; |
1908 | 2111 | ||
2112 | if (sd->gspca_dev.usb_err < 0) | ||
2113 | return -1; | ||
2114 | |||
1909 | ret = usb_control_msg(sd->gspca_dev.dev, | 2115 | ret = usb_control_msg(sd->gspca_dev.dev, |
1910 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), | 2116 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), |
1911 | 1, /* REQ_IO */ | 2117 | 1, /* REQ_IO */ |
1912 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 2118 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
1913 | 0, index, sd->gspca_dev.usb_buf, 8, 500); | 2119 | 0, index, sd->gspca_dev.usb_buf, 8, 500); |
1914 | 2120 | ||
1915 | if (ret >= 0) | 2121 | if (ret >= 0) { |
1916 | ret = sd->gspca_dev.usb_buf[0]; | 2122 | ret = sd->gspca_dev.usb_buf[0]; |
1917 | else | 2123 | } else { |
1918 | err("Read reg 8 [0x%02x] failed", index); | 2124 | err("reg_r8 %02x failed %d", index, ret); |
2125 | sd->gspca_dev.usb_err = ret; | ||
2126 | } | ||
1919 | 2127 | ||
1920 | return ret; | 2128 | return ret; |
1921 | } | 2129 | } |
@@ -1926,34 +2134,37 @@ static int reg_r8(struct sd *sd, | |||
1926 | * that are in the same position as 0's in "mask" are preserved, regardless | 2134 | * that are in the same position as 0's in "mask" are preserved, regardless |
1927 | * of their respective state in "value". | 2135 | * of their respective state in "value". |
1928 | */ | 2136 | */ |
1929 | static int reg_w_mask(struct sd *sd, | 2137 | static void reg_w_mask(struct sd *sd, |
1930 | __u16 index, | 2138 | u16 index, |
1931 | __u8 value, | 2139 | u8 value, |
1932 | __u8 mask) | 2140 | u8 mask) |
1933 | { | 2141 | { |
1934 | int ret; | 2142 | int ret; |
1935 | __u8 oldval; | 2143 | u8 oldval; |
1936 | 2144 | ||
1937 | if (mask != 0xff) { | 2145 | if (mask != 0xff) { |
1938 | value &= mask; /* Enforce mask on value */ | 2146 | value &= mask; /* Enforce mask on value */ |
1939 | ret = reg_r(sd, index); | 2147 | ret = reg_r(sd, index); |
1940 | if (ret < 0) | 2148 | if (ret < 0) |
1941 | return ret; | 2149 | return; |
1942 | 2150 | ||
1943 | oldval = ret & ~mask; /* Clear the masked bits */ | 2151 | oldval = ret & ~mask; /* Clear the masked bits */ |
1944 | value |= oldval; /* Set the desired bits */ | 2152 | value |= oldval; /* Set the desired bits */ |
1945 | } | 2153 | } |
1946 | return reg_w(sd, index, value); | 2154 | reg_w(sd, index, value); |
1947 | } | 2155 | } |
1948 | 2156 | ||
1949 | /* | 2157 | /* |
1950 | * Writes multiple (n) byte value to a single register. Only valid with certain | 2158 | * Writes multiple (n) byte value to a single register. Only valid with certain |
1951 | * registers (0x30 and 0xc4 - 0xce). | 2159 | * registers (0x30 and 0xc4 - 0xce). |
1952 | */ | 2160 | */ |
1953 | static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n) | 2161 | static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n) |
1954 | { | 2162 | { |
1955 | int ret; | 2163 | int ret; |
1956 | 2164 | ||
2165 | if (sd->gspca_dev.usb_err < 0) | ||
2166 | return; | ||
2167 | |||
1957 | *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value); | 2168 | *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value); |
1958 | 2169 | ||
1959 | ret = usb_control_msg(sd->gspca_dev.dev, | 2170 | ret = usb_control_msg(sd->gspca_dev.dev, |
@@ -1963,69 +2174,55 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n) | |||
1963 | 0, index, | 2174 | 0, index, |
1964 | sd->gspca_dev.usb_buf, n, 500); | 2175 | sd->gspca_dev.usb_buf, n, 500); |
1965 | if (ret < 0) { | 2176 | if (ret < 0) { |
1966 | err("Write reg32 [%02x] %08x failed", index, value); | 2177 | err("reg_w32 %02x failed %d", index, ret); |
1967 | return ret; | 2178 | sd->gspca_dev.usb_err = ret; |
1968 | } | 2179 | } |
1969 | |||
1970 | return 0; | ||
1971 | } | 2180 | } |
1972 | 2181 | ||
1973 | static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value) | 2182 | static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value) |
1974 | { | 2183 | { |
1975 | int rc, retries; | 2184 | int rc, retries; |
1976 | 2185 | ||
1977 | PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); | 2186 | PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value); |
1978 | 2187 | ||
1979 | /* Three byte write cycle */ | 2188 | /* Three byte write cycle */ |
1980 | for (retries = 6; ; ) { | 2189 | for (retries = 6; ; ) { |
1981 | /* Select camera register */ | 2190 | /* Select camera register */ |
1982 | rc = reg_w(sd, R51x_I2C_SADDR_3, reg); | 2191 | reg_w(sd, R51x_I2C_SADDR_3, reg); |
1983 | if (rc < 0) | ||
1984 | return rc; | ||
1985 | 2192 | ||
1986 | /* Write "value" to I2C data port of OV511 */ | 2193 | /* Write "value" to I2C data port of OV511 */ |
1987 | rc = reg_w(sd, R51x_I2C_DATA, value); | 2194 | reg_w(sd, R51x_I2C_DATA, value); |
1988 | if (rc < 0) | ||
1989 | return rc; | ||
1990 | 2195 | ||
1991 | /* Initiate 3-byte write cycle */ | 2196 | /* Initiate 3-byte write cycle */ |
1992 | rc = reg_w(sd, R511_I2C_CTL, 0x01); | 2197 | reg_w(sd, R511_I2C_CTL, 0x01); |
1993 | if (rc < 0) | ||
1994 | return rc; | ||
1995 | 2198 | ||
1996 | do { | 2199 | do { |
1997 | rc = reg_r(sd, R511_I2C_CTL); | 2200 | rc = reg_r(sd, R511_I2C_CTL); |
1998 | } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ | 2201 | } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ |
1999 | 2202 | ||
2000 | if (rc < 0) | 2203 | if (rc < 0) |
2001 | return rc; | 2204 | return; |
2002 | 2205 | ||
2003 | if ((rc & 2) == 0) /* Ack? */ | 2206 | if ((rc & 2) == 0) /* Ack? */ |
2004 | break; | 2207 | break; |
2005 | if (--retries < 0) { | 2208 | if (--retries < 0) { |
2006 | PDEBUG(D_USBO, "i2c write retries exhausted"); | 2209 | PDEBUG(D_USBO, "i2c write retries exhausted"); |
2007 | return -1; | 2210 | return; |
2008 | } | 2211 | } |
2009 | } | 2212 | } |
2010 | |||
2011 | return 0; | ||
2012 | } | 2213 | } |
2013 | 2214 | ||
2014 | static int ov511_i2c_r(struct sd *sd, __u8 reg) | 2215 | static int ov511_i2c_r(struct sd *sd, u8 reg) |
2015 | { | 2216 | { |
2016 | int rc, value, retries; | 2217 | int rc, value, retries; |
2017 | 2218 | ||
2018 | /* Two byte write cycle */ | 2219 | /* Two byte write cycle */ |
2019 | for (retries = 6; ; ) { | 2220 | for (retries = 6; ; ) { |
2020 | /* Select camera register */ | 2221 | /* Select camera register */ |
2021 | rc = reg_w(sd, R51x_I2C_SADDR_2, reg); | 2222 | reg_w(sd, R51x_I2C_SADDR_2, reg); |
2022 | if (rc < 0) | ||
2023 | return rc; | ||
2024 | 2223 | ||
2025 | /* Initiate 2-byte write cycle */ | 2224 | /* Initiate 2-byte write cycle */ |
2026 | rc = reg_w(sd, R511_I2C_CTL, 0x03); | 2225 | reg_w(sd, R511_I2C_CTL, 0x03); |
2027 | if (rc < 0) | ||
2028 | return rc; | ||
2029 | 2226 | ||
2030 | do { | 2227 | do { |
2031 | rc = reg_r(sd, R511_I2C_CTL); | 2228 | rc = reg_r(sd, R511_I2C_CTL); |
@@ -2049,9 +2246,7 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg) | |||
2049 | /* Two byte read cycle */ | 2246 | /* Two byte read cycle */ |
2050 | for (retries = 6; ; ) { | 2247 | for (retries = 6; ; ) { |
2051 | /* Initiate 2-byte read cycle */ | 2248 | /* Initiate 2-byte read cycle */ |
2052 | rc = reg_w(sd, R511_I2C_CTL, 0x05); | 2249 | reg_w(sd, R511_I2C_CTL, 0x05); |
2053 | if (rc < 0) | ||
2054 | return rc; | ||
2055 | 2250 | ||
2056 | do { | 2251 | do { |
2057 | rc = reg_r(sd, R511_I2C_CTL); | 2252 | rc = reg_r(sd, R511_I2C_CTL); |
@@ -2064,9 +2259,7 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg) | |||
2064 | break; | 2259 | break; |
2065 | 2260 | ||
2066 | /* I2C abort */ | 2261 | /* I2C abort */ |
2067 | rc = reg_w(sd, R511_I2C_CTL, 0x10); | 2262 | reg_w(sd, R511_I2C_CTL, 0x10); |
2068 | if (rc < 0) | ||
2069 | return rc; | ||
2070 | 2263 | ||
2071 | if (--retries < 0) { | 2264 | if (--retries < 0) { |
2072 | PDEBUG(D_USBI, "i2c read retries exhausted"); | 2265 | PDEBUG(D_USBI, "i2c read retries exhausted"); |
@@ -2076,12 +2269,10 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg) | |||
2076 | 2269 | ||
2077 | value = reg_r(sd, R51x_I2C_DATA); | 2270 | value = reg_r(sd, R51x_I2C_DATA); |
2078 | 2271 | ||
2079 | PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); | 2272 | PDEBUG(D_USBI, "ov511_i2c_r %02x %02x", reg, value); |
2080 | 2273 | ||
2081 | /* This is needed to make i2c_w() work */ | 2274 | /* This is needed to make i2c_w() work */ |
2082 | rc = reg_w(sd, R511_I2C_CTL, 0x05); | 2275 | reg_w(sd, R511_I2C_CTL, 0x05); |
2083 | if (rc < 0) | ||
2084 | return rc; | ||
2085 | 2276 | ||
2086 | return value; | 2277 | return value; |
2087 | } | 2278 | } |
@@ -2091,32 +2282,24 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg) | |||
2091 | * This is normally only called from i2c_w(). Note that this function | 2282 | * This is normally only called from i2c_w(). Note that this function |
2092 | * always succeeds regardless of whether the sensor is present and working. | 2283 | * always succeeds regardless of whether the sensor is present and working. |
2093 | */ | 2284 | */ |
2094 | static int ov518_i2c_w(struct sd *sd, | 2285 | static void ov518_i2c_w(struct sd *sd, |
2095 | __u8 reg, | 2286 | u8 reg, |
2096 | __u8 value) | 2287 | u8 value) |
2097 | { | 2288 | { |
2098 | int rc; | 2289 | PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value); |
2099 | |||
2100 | PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); | ||
2101 | 2290 | ||
2102 | /* Select camera register */ | 2291 | /* Select camera register */ |
2103 | rc = reg_w(sd, R51x_I2C_SADDR_3, reg); | 2292 | reg_w(sd, R51x_I2C_SADDR_3, reg); |
2104 | if (rc < 0) | ||
2105 | return rc; | ||
2106 | 2293 | ||
2107 | /* Write "value" to I2C data port of OV511 */ | 2294 | /* Write "value" to I2C data port of OV511 */ |
2108 | rc = reg_w(sd, R51x_I2C_DATA, value); | 2295 | reg_w(sd, R51x_I2C_DATA, value); |
2109 | if (rc < 0) | ||
2110 | return rc; | ||
2111 | 2296 | ||
2112 | /* Initiate 3-byte write cycle */ | 2297 | /* Initiate 3-byte write cycle */ |
2113 | rc = reg_w(sd, R518_I2C_CTL, 0x01); | 2298 | reg_w(sd, R518_I2C_CTL, 0x01); |
2114 | if (rc < 0) | ||
2115 | return rc; | ||
2116 | 2299 | ||
2117 | /* wait for write complete */ | 2300 | /* wait for write complete */ |
2118 | msleep(4); | 2301 | msleep(4); |
2119 | return reg_r8(sd, R518_I2C_CTL); | 2302 | reg_r8(sd, R518_I2C_CTL); |
2120 | } | 2303 | } |
2121 | 2304 | ||
2122 | /* | 2305 | /* |
@@ -2126,105 +2309,102 @@ static int ov518_i2c_w(struct sd *sd, | |||
2126 | * This is normally only called from i2c_r(). Note that this function | 2309 | * This is normally only called from i2c_r(). Note that this function |
2127 | * always succeeds regardless of whether the sensor is present and working. | 2310 | * always succeeds regardless of whether the sensor is present and working. |
2128 | */ | 2311 | */ |
2129 | static int ov518_i2c_r(struct sd *sd, __u8 reg) | 2312 | static int ov518_i2c_r(struct sd *sd, u8 reg) |
2130 | { | 2313 | { |
2131 | int rc, value; | 2314 | int value; |
2132 | 2315 | ||
2133 | /* Select camera register */ | 2316 | /* Select camera register */ |
2134 | rc = reg_w(sd, R51x_I2C_SADDR_2, reg); | 2317 | reg_w(sd, R51x_I2C_SADDR_2, reg); |
2135 | if (rc < 0) | ||
2136 | return rc; | ||
2137 | 2318 | ||
2138 | /* Initiate 2-byte write cycle */ | 2319 | /* Initiate 2-byte write cycle */ |
2139 | rc = reg_w(sd, R518_I2C_CTL, 0x03); | 2320 | reg_w(sd, R518_I2C_CTL, 0x03); |
2140 | if (rc < 0) | ||
2141 | return rc; | ||
2142 | 2321 | ||
2143 | /* Initiate 2-byte read cycle */ | 2322 | /* Initiate 2-byte read cycle */ |
2144 | rc = reg_w(sd, R518_I2C_CTL, 0x05); | 2323 | reg_w(sd, R518_I2C_CTL, 0x05); |
2145 | if (rc < 0) | ||
2146 | return rc; | ||
2147 | value = reg_r(sd, R51x_I2C_DATA); | 2324 | value = reg_r(sd, R51x_I2C_DATA); |
2148 | PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); | 2325 | PDEBUG(D_USBI, "ov518_i2c_r %02x %02x", reg, value); |
2149 | return value; | 2326 | return value; |
2150 | } | 2327 | } |
2151 | 2328 | ||
2152 | static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value) | 2329 | static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value) |
2153 | { | 2330 | { |
2154 | int ret; | 2331 | int ret; |
2155 | 2332 | ||
2333 | if (sd->gspca_dev.usb_err < 0) | ||
2334 | return; | ||
2335 | |||
2156 | ret = usb_control_msg(sd->gspca_dev.dev, | 2336 | ret = usb_control_msg(sd->gspca_dev.dev, |
2157 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | 2337 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), |
2158 | 0x02, | 2338 | 0x02, |
2159 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 2339 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
2160 | (__u16)value, (__u16)reg, NULL, 0, 500); | 2340 | (u16) value, (u16) reg, NULL, 0, 500); |
2161 | 2341 | ||
2162 | if (ret < 0) { | 2342 | if (ret < 0) { |
2163 | err("i2c 0x%02x -> [0x%02x] failed", value, reg); | 2343 | err("ovfx2_i2c_w %02x failed %d", reg, ret); |
2164 | return ret; | 2344 | sd->gspca_dev.usb_err = ret; |
2165 | } | 2345 | } |
2166 | 2346 | ||
2167 | PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); | 2347 | PDEBUG(D_USBO, "ovfx2_i2c_w %02x %02x", reg, value); |
2168 | return 0; | ||
2169 | } | 2348 | } |
2170 | 2349 | ||
2171 | static int ovfx2_i2c_r(struct sd *sd, __u8 reg) | 2350 | static int ovfx2_i2c_r(struct sd *sd, u8 reg) |
2172 | { | 2351 | { |
2173 | int ret; | 2352 | int ret; |
2174 | 2353 | ||
2354 | if (sd->gspca_dev.usb_err < 0) | ||
2355 | return -1; | ||
2356 | |||
2175 | ret = usb_control_msg(sd->gspca_dev.dev, | 2357 | ret = usb_control_msg(sd->gspca_dev.dev, |
2176 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), | 2358 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), |
2177 | 0x03, | 2359 | 0x03, |
2178 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 2360 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
2179 | 0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500); | 2361 | 0, (u16) reg, sd->gspca_dev.usb_buf, 1, 500); |
2180 | 2362 | ||
2181 | if (ret >= 0) { | 2363 | if (ret >= 0) { |
2182 | ret = sd->gspca_dev.usb_buf[0]; | 2364 | ret = sd->gspca_dev.usb_buf[0]; |
2183 | PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret); | 2365 | PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret); |
2184 | } else | 2366 | } else { |
2185 | err("i2c read [0x%02x] failed", reg); | 2367 | err("ovfx2_i2c_r %02x failed %d", reg, ret); |
2368 | sd->gspca_dev.usb_err = ret; | ||
2369 | } | ||
2186 | 2370 | ||
2187 | return ret; | 2371 | return ret; |
2188 | } | 2372 | } |
2189 | 2373 | ||
2190 | static int i2c_w(struct sd *sd, __u8 reg, __u8 value) | 2374 | static void i2c_w(struct sd *sd, u8 reg, u8 value) |
2191 | { | 2375 | { |
2192 | int ret = -1; | ||
2193 | |||
2194 | if (sd->sensor_reg_cache[reg] == value) | 2376 | if (sd->sensor_reg_cache[reg] == value) |
2195 | return 0; | 2377 | return; |
2196 | 2378 | ||
2197 | switch (sd->bridge) { | 2379 | switch (sd->bridge) { |
2198 | case BRIDGE_OV511: | 2380 | case BRIDGE_OV511: |
2199 | case BRIDGE_OV511PLUS: | 2381 | case BRIDGE_OV511PLUS: |
2200 | ret = ov511_i2c_w(sd, reg, value); | 2382 | ov511_i2c_w(sd, reg, value); |
2201 | break; | 2383 | break; |
2202 | case BRIDGE_OV518: | 2384 | case BRIDGE_OV518: |
2203 | case BRIDGE_OV518PLUS: | 2385 | case BRIDGE_OV518PLUS: |
2204 | case BRIDGE_OV519: | 2386 | case BRIDGE_OV519: |
2205 | ret = ov518_i2c_w(sd, reg, value); | 2387 | ov518_i2c_w(sd, reg, value); |
2206 | break; | 2388 | break; |
2207 | case BRIDGE_OVFX2: | 2389 | case BRIDGE_OVFX2: |
2208 | ret = ovfx2_i2c_w(sd, reg, value); | 2390 | ovfx2_i2c_w(sd, reg, value); |
2209 | break; | 2391 | break; |
2210 | case BRIDGE_W9968CF: | 2392 | case BRIDGE_W9968CF: |
2211 | ret = w9968cf_i2c_w(sd, reg, value); | 2393 | w9968cf_i2c_w(sd, reg, value); |
2212 | break; | 2394 | break; |
2213 | } | 2395 | } |
2214 | 2396 | ||
2215 | if (ret >= 0) { | 2397 | if (sd->gspca_dev.usb_err >= 0) { |
2216 | /* Up on sensor reset empty the register cache */ | 2398 | /* Up on sensor reset empty the register cache */ |
2217 | if (reg == 0x12 && (value & 0x80)) | 2399 | if (reg == 0x12 && (value & 0x80)) |
2218 | memset(sd->sensor_reg_cache, -1, | 2400 | memset(sd->sensor_reg_cache, -1, |
2219 | sizeof(sd->sensor_reg_cache)); | 2401 | sizeof(sd->sensor_reg_cache)); |
2220 | else | 2402 | else |
2221 | sd->sensor_reg_cache[reg] = value; | 2403 | sd->sensor_reg_cache[reg] = value; |
2222 | } | 2404 | } |
2223 | |||
2224 | return ret; | ||
2225 | } | 2405 | } |
2226 | 2406 | ||
2227 | static int i2c_r(struct sd *sd, __u8 reg) | 2407 | static int i2c_r(struct sd *sd, u8 reg) |
2228 | { | 2408 | { |
2229 | int ret = -1; | 2409 | int ret = -1; |
2230 | 2410 | ||
@@ -2260,95 +2440,99 @@ static int i2c_r(struct sd *sd, __u8 reg) | |||
2260 | * that are in the same position as 0's in "mask" are preserved, regardless | 2440 | * that are in the same position as 0's in "mask" are preserved, regardless |
2261 | * of their respective state in "value". | 2441 | * of their respective state in "value". |
2262 | */ | 2442 | */ |
2263 | static int i2c_w_mask(struct sd *sd, | 2443 | static void i2c_w_mask(struct sd *sd, |
2264 | __u8 reg, | 2444 | u8 reg, |
2265 | __u8 value, | 2445 | u8 value, |
2266 | __u8 mask) | 2446 | u8 mask) |
2267 | { | 2447 | { |
2268 | int rc; | 2448 | int rc; |
2269 | __u8 oldval; | 2449 | u8 oldval; |
2270 | 2450 | ||
2271 | value &= mask; /* Enforce mask on value */ | 2451 | value &= mask; /* Enforce mask on value */ |
2272 | rc = i2c_r(sd, reg); | 2452 | rc = i2c_r(sd, reg); |
2273 | if (rc < 0) | 2453 | if (rc < 0) |
2274 | return rc; | 2454 | return; |
2275 | oldval = rc & ~mask; /* Clear the masked bits */ | 2455 | oldval = rc & ~mask; /* Clear the masked bits */ |
2276 | value |= oldval; /* Set the desired bits */ | 2456 | value |= oldval; /* Set the desired bits */ |
2277 | return i2c_w(sd, reg, value); | 2457 | i2c_w(sd, reg, value); |
2278 | } | 2458 | } |
2279 | 2459 | ||
2280 | /* Temporarily stops OV511 from functioning. Must do this before changing | 2460 | /* Temporarily stops OV511 from functioning. Must do this before changing |
2281 | * registers while the camera is streaming */ | 2461 | * registers while the camera is streaming */ |
2282 | static inline int ov51x_stop(struct sd *sd) | 2462 | static inline void ov51x_stop(struct sd *sd) |
2283 | { | 2463 | { |
2284 | PDEBUG(D_STREAM, "stopping"); | 2464 | PDEBUG(D_STREAM, "stopping"); |
2285 | sd->stopped = 1; | 2465 | sd->stopped = 1; |
2286 | switch (sd->bridge) { | 2466 | switch (sd->bridge) { |
2287 | case BRIDGE_OV511: | 2467 | case BRIDGE_OV511: |
2288 | case BRIDGE_OV511PLUS: | 2468 | case BRIDGE_OV511PLUS: |
2289 | return reg_w(sd, R51x_SYS_RESET, 0x3d); | 2469 | reg_w(sd, R51x_SYS_RESET, 0x3d); |
2470 | break; | ||
2290 | case BRIDGE_OV518: | 2471 | case BRIDGE_OV518: |
2291 | case BRIDGE_OV518PLUS: | 2472 | case BRIDGE_OV518PLUS: |
2292 | return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a); | 2473 | reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a); |
2474 | break; | ||
2293 | case BRIDGE_OV519: | 2475 | case BRIDGE_OV519: |
2294 | return reg_w(sd, OV519_SYS_RESET1, 0x0f); | 2476 | reg_w(sd, OV519_R51_RESET1, 0x0f); |
2477 | reg_w(sd, OV519_R51_RESET1, 0x00); | ||
2478 | reg_w(sd, 0x22, 0x00); /* FRAR */ | ||
2479 | break; | ||
2295 | case BRIDGE_OVFX2: | 2480 | case BRIDGE_OVFX2: |
2296 | return reg_w_mask(sd, 0x0f, 0x00, 0x02); | 2481 | reg_w_mask(sd, 0x0f, 0x00, 0x02); |
2482 | break; | ||
2297 | case BRIDGE_W9968CF: | 2483 | case BRIDGE_W9968CF: |
2298 | return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */ | 2484 | reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */ |
2485 | break; | ||
2299 | } | 2486 | } |
2300 | |||
2301 | return 0; | ||
2302 | } | 2487 | } |
2303 | 2488 | ||
2304 | /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not | 2489 | /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not |
2305 | * actually stopped (for performance). */ | 2490 | * actually stopped (for performance). */ |
2306 | static inline int ov51x_restart(struct sd *sd) | 2491 | static inline void ov51x_restart(struct sd *sd) |
2307 | { | 2492 | { |
2308 | int rc; | ||
2309 | |||
2310 | PDEBUG(D_STREAM, "restarting"); | 2493 | PDEBUG(D_STREAM, "restarting"); |
2311 | if (!sd->stopped) | 2494 | if (!sd->stopped) |
2312 | return 0; | 2495 | return; |
2313 | sd->stopped = 0; | 2496 | sd->stopped = 0; |
2314 | 2497 | ||
2315 | /* Reinitialize the stream */ | 2498 | /* Reinitialize the stream */ |
2316 | switch (sd->bridge) { | 2499 | switch (sd->bridge) { |
2317 | case BRIDGE_OV511: | 2500 | case BRIDGE_OV511: |
2318 | case BRIDGE_OV511PLUS: | 2501 | case BRIDGE_OV511PLUS: |
2319 | return reg_w(sd, R51x_SYS_RESET, 0x00); | 2502 | reg_w(sd, R51x_SYS_RESET, 0x00); |
2503 | break; | ||
2320 | case BRIDGE_OV518: | 2504 | case BRIDGE_OV518: |
2321 | case BRIDGE_OV518PLUS: | 2505 | case BRIDGE_OV518PLUS: |
2322 | rc = reg_w(sd, 0x2f, 0x80); | 2506 | reg_w(sd, 0x2f, 0x80); |
2323 | if (rc < 0) | 2507 | reg_w(sd, R51x_SYS_RESET, 0x00); |
2324 | return rc; | 2508 | break; |
2325 | return reg_w(sd, R51x_SYS_RESET, 0x00); | ||
2326 | case BRIDGE_OV519: | 2509 | case BRIDGE_OV519: |
2327 | return reg_w(sd, OV519_SYS_RESET1, 0x00); | 2510 | reg_w(sd, OV519_R51_RESET1, 0x0f); |
2511 | reg_w(sd, OV519_R51_RESET1, 0x00); | ||
2512 | reg_w(sd, 0x22, 0x1d); /* FRAR */ | ||
2513 | break; | ||
2328 | case BRIDGE_OVFX2: | 2514 | case BRIDGE_OVFX2: |
2329 | return reg_w_mask(sd, 0x0f, 0x02, 0x02); | 2515 | reg_w_mask(sd, 0x0f, 0x02, 0x02); |
2516 | break; | ||
2330 | case BRIDGE_W9968CF: | 2517 | case BRIDGE_W9968CF: |
2331 | return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */ | 2518 | reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */ |
2519 | break; | ||
2332 | } | 2520 | } |
2333 | |||
2334 | return 0; | ||
2335 | } | 2521 | } |
2336 | 2522 | ||
2337 | static int ov51x_set_slave_ids(struct sd *sd, __u8 slave); | 2523 | static void ov51x_set_slave_ids(struct sd *sd, u8 slave); |
2338 | 2524 | ||
2339 | /* This does an initial reset of an OmniVision sensor and ensures that I2C | 2525 | /* This does an initial reset of an OmniVision sensor and ensures that I2C |
2340 | * is synchronized. Returns <0 on failure. | 2526 | * is synchronized. Returns <0 on failure. |
2341 | */ | 2527 | */ |
2342 | static int init_ov_sensor(struct sd *sd, __u8 slave) | 2528 | static int init_ov_sensor(struct sd *sd, u8 slave) |
2343 | { | 2529 | { |
2344 | int i; | 2530 | int i; |
2345 | 2531 | ||
2346 | if (ov51x_set_slave_ids(sd, slave) < 0) | 2532 | ov51x_set_slave_ids(sd, slave); |
2347 | return -EIO; | ||
2348 | 2533 | ||
2349 | /* Reset the sensor */ | 2534 | /* Reset the sensor */ |
2350 | if (i2c_w(sd, 0x12, 0x80) < 0) | 2535 | i2c_w(sd, 0x12, 0x80); |
2351 | return -EIO; | ||
2352 | 2536 | ||
2353 | /* Wait for it to initialize */ | 2537 | /* Wait for it to initialize */ |
2354 | msleep(150); | 2538 | msleep(150); |
@@ -2361,15 +2545,16 @@ static int init_ov_sensor(struct sd *sd, __u8 slave) | |||
2361 | } | 2545 | } |
2362 | 2546 | ||
2363 | /* Reset the sensor */ | 2547 | /* Reset the sensor */ |
2364 | if (i2c_w(sd, 0x12, 0x80) < 0) | 2548 | i2c_w(sd, 0x12, 0x80); |
2365 | return -EIO; | 2549 | |
2366 | /* Wait for it to initialize */ | 2550 | /* Wait for it to initialize */ |
2367 | msleep(150); | 2551 | msleep(150); |
2552 | |||
2368 | /* Dummy read to sync I2C */ | 2553 | /* Dummy read to sync I2C */ |
2369 | if (i2c_r(sd, 0x00) < 0) | 2554 | if (i2c_r(sd, 0x00) < 0) |
2370 | return -EIO; | 2555 | return -1; |
2371 | } | 2556 | } |
2372 | return -EIO; | 2557 | return -1; |
2373 | } | 2558 | } |
2374 | 2559 | ||
2375 | /* Set the read and write slave IDs. The "slave" argument is the write slave, | 2560 | /* Set the read and write slave IDs. The "slave" argument is the write slave, |
@@ -2377,53 +2562,40 @@ static int init_ov_sensor(struct sd *sd, __u8 slave) | |||
2377 | * This should not be called from outside the i2c I/O functions. | 2562 | * This should not be called from outside the i2c I/O functions. |
2378 | * Sets I2C read and write slave IDs. Returns <0 for error | 2563 | * Sets I2C read and write slave IDs. Returns <0 for error |
2379 | */ | 2564 | */ |
2380 | static int ov51x_set_slave_ids(struct sd *sd, | 2565 | static void ov51x_set_slave_ids(struct sd *sd, |
2381 | __u8 slave) | 2566 | u8 slave) |
2382 | { | 2567 | { |
2383 | int rc; | ||
2384 | |||
2385 | switch (sd->bridge) { | 2568 | switch (sd->bridge) { |
2386 | case BRIDGE_OVFX2: | 2569 | case BRIDGE_OVFX2: |
2387 | return reg_w(sd, OVFX2_I2C_ADDR, slave); | 2570 | reg_w(sd, OVFX2_I2C_ADDR, slave); |
2571 | return; | ||
2388 | case BRIDGE_W9968CF: | 2572 | case BRIDGE_W9968CF: |
2389 | sd->sensor_addr = slave; | 2573 | sd->sensor_addr = slave; |
2390 | return 0; | 2574 | return; |
2391 | } | 2575 | } |
2392 | 2576 | ||
2393 | rc = reg_w(sd, R51x_I2C_W_SID, slave); | 2577 | reg_w(sd, R51x_I2C_W_SID, slave); |
2394 | if (rc < 0) | 2578 | reg_w(sd, R51x_I2C_R_SID, slave + 1); |
2395 | return rc; | ||
2396 | return reg_w(sd, R51x_I2C_R_SID, slave + 1); | ||
2397 | } | 2579 | } |
2398 | 2580 | ||
2399 | static int write_regvals(struct sd *sd, | 2581 | static void write_regvals(struct sd *sd, |
2400 | const struct ov_regvals *regvals, | 2582 | const struct ov_regvals *regvals, |
2401 | int n) | 2583 | int n) |
2402 | { | 2584 | { |
2403 | int rc; | ||
2404 | |||
2405 | while (--n >= 0) { | 2585 | while (--n >= 0) { |
2406 | rc = reg_w(sd, regvals->reg, regvals->val); | 2586 | reg_w(sd, regvals->reg, regvals->val); |
2407 | if (rc < 0) | ||
2408 | return rc; | ||
2409 | regvals++; | 2587 | regvals++; |
2410 | } | 2588 | } |
2411 | return 0; | ||
2412 | } | 2589 | } |
2413 | 2590 | ||
2414 | static int write_i2c_regvals(struct sd *sd, | 2591 | static void write_i2c_regvals(struct sd *sd, |
2415 | const struct ov_i2c_regvals *regvals, | 2592 | const struct ov_i2c_regvals *regvals, |
2416 | int n) | 2593 | int n) |
2417 | { | 2594 | { |
2418 | int rc; | ||
2419 | |||
2420 | while (--n >= 0) { | 2595 | while (--n >= 0) { |
2421 | rc = i2c_w(sd, regvals->reg, regvals->val); | 2596 | i2c_w(sd, regvals->reg, regvals->val); |
2422 | if (rc < 0) | ||
2423 | return rc; | ||
2424 | regvals++; | 2597 | regvals++; |
2425 | } | 2598 | } |
2426 | return 0; | ||
2427 | } | 2599 | } |
2428 | 2600 | ||
2429 | /**************************************************************************** | 2601 | /**************************************************************************** |
@@ -2433,13 +2605,13 @@ static int write_i2c_regvals(struct sd *sd, | |||
2433 | ***************************************************************************/ | 2605 | ***************************************************************************/ |
2434 | 2606 | ||
2435 | /* This initializes the OV2x10 / OV3610 / OV3620 */ | 2607 | /* This initializes the OV2x10 / OV3610 / OV3620 */ |
2436 | static int ov_hires_configure(struct sd *sd) | 2608 | static void ov_hires_configure(struct sd *sd) |
2437 | { | 2609 | { |
2438 | int high, low; | 2610 | int high, low; |
2439 | 2611 | ||
2440 | if (sd->bridge != BRIDGE_OVFX2) { | 2612 | if (sd->bridge != BRIDGE_OVFX2) { |
2441 | err("error hires sensors only supported with ovfx2"); | 2613 | err("error hires sensors only supported with ovfx2"); |
2442 | return -1; | 2614 | return; |
2443 | } | 2615 | } |
2444 | 2616 | ||
2445 | PDEBUG(D_PROBE, "starting ov hires configuration"); | 2617 | PDEBUG(D_PROBE, "starting ov hires configuration"); |
@@ -2455,20 +2627,15 @@ static int ov_hires_configure(struct sd *sd) | |||
2455 | PDEBUG(D_PROBE, "Sensor is an OV3610"); | 2627 | PDEBUG(D_PROBE, "Sensor is an OV3610"); |
2456 | sd->sensor = SEN_OV3610; | 2628 | sd->sensor = SEN_OV3610; |
2457 | } else { | 2629 | } else { |
2458 | err("Error unknown sensor type: 0x%02x%02x", | 2630 | err("Error unknown sensor type: %02x%02x", |
2459 | high, low); | 2631 | high, low); |
2460 | return -1; | ||
2461 | } | 2632 | } |
2462 | |||
2463 | /* Set sensor-specific vars */ | ||
2464 | return 0; | ||
2465 | } | 2633 | } |
2466 | 2634 | ||
2467 | |||
2468 | /* This initializes the OV8110, OV8610 sensor. The OV8110 uses | 2635 | /* This initializes the OV8110, OV8610 sensor. The OV8110 uses |
2469 | * the same register settings as the OV8610, since they are very similar. | 2636 | * the same register settings as the OV8610, since they are very similar. |
2470 | */ | 2637 | */ |
2471 | static int ov8xx0_configure(struct sd *sd) | 2638 | static void ov8xx0_configure(struct sd *sd) |
2472 | { | 2639 | { |
2473 | int rc; | 2640 | int rc; |
2474 | 2641 | ||
@@ -2478,27 +2645,21 @@ static int ov8xx0_configure(struct sd *sd) | |||
2478 | rc = i2c_r(sd, OV7610_REG_COM_I); | 2645 | rc = i2c_r(sd, OV7610_REG_COM_I); |
2479 | if (rc < 0) { | 2646 | if (rc < 0) { |
2480 | PDEBUG(D_ERR, "Error detecting sensor type"); | 2647 | PDEBUG(D_ERR, "Error detecting sensor type"); |
2481 | return -1; | 2648 | return; |
2482 | } | 2649 | } |
2483 | if ((rc & 3) == 1) { | 2650 | if ((rc & 3) == 1) |
2484 | sd->sensor = SEN_OV8610; | 2651 | sd->sensor = SEN_OV8610; |
2485 | } else { | 2652 | else |
2486 | err("Unknown image sensor version: %d", rc & 3); | 2653 | err("Unknown image sensor version: %d", rc & 3); |
2487 | return -1; | ||
2488 | } | ||
2489 | |||
2490 | /* Set sensor-specific vars */ | ||
2491 | return 0; | ||
2492 | } | 2654 | } |
2493 | 2655 | ||
2494 | /* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses | 2656 | /* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses |
2495 | * the same register settings as the OV7610, since they are very similar. | 2657 | * the same register settings as the OV7610, since they are very similar. |
2496 | */ | 2658 | */ |
2497 | static int ov7xx0_configure(struct sd *sd) | 2659 | static void ov7xx0_configure(struct sd *sd) |
2498 | { | 2660 | { |
2499 | int rc, high, low; | 2661 | int rc, high, low; |
2500 | 2662 | ||
2501 | |||
2502 | PDEBUG(D_PROBE, "starting OV7xx0 configuration"); | 2663 | PDEBUG(D_PROBE, "starting OV7xx0 configuration"); |
2503 | 2664 | ||
2504 | /* Detect sensor (sub)type */ | 2665 | /* Detect sensor (sub)type */ |
@@ -2508,15 +2669,15 @@ static int ov7xx0_configure(struct sd *sd) | |||
2508 | * it appears to be wrongly detected as a 7610 by default */ | 2669 | * it appears to be wrongly detected as a 7610 by default */ |
2509 | if (rc < 0) { | 2670 | if (rc < 0) { |
2510 | PDEBUG(D_ERR, "Error detecting sensor type"); | 2671 | PDEBUG(D_ERR, "Error detecting sensor type"); |
2511 | return -1; | 2672 | return; |
2512 | } | 2673 | } |
2513 | if ((rc & 3) == 3) { | 2674 | if ((rc & 3) == 3) { |
2514 | /* quick hack to make OV7670s work */ | 2675 | /* quick hack to make OV7670s work */ |
2515 | high = i2c_r(sd, 0x0a); | 2676 | high = i2c_r(sd, 0x0a); |
2516 | low = i2c_r(sd, 0x0b); | 2677 | low = i2c_r(sd, 0x0b); |
2517 | /* info("%x, %x", high, low); */ | 2678 | /* info("%x, %x", high, low); */ |
2518 | if (high == 0x76 && low == 0x73) { | 2679 | if (high == 0x76 && (low & 0xf0) == 0x70) { |
2519 | PDEBUG(D_PROBE, "Sensor is an OV7670"); | 2680 | PDEBUG(D_PROBE, "Sensor is an OV76%02x", low); |
2520 | sd->sensor = SEN_OV7670; | 2681 | sd->sensor = SEN_OV7670; |
2521 | } else { | 2682 | } else { |
2522 | PDEBUG(D_PROBE, "Sensor is an OV7610"); | 2683 | PDEBUG(D_PROBE, "Sensor is an OV7610"); |
@@ -2536,19 +2697,19 @@ static int ov7xx0_configure(struct sd *sd) | |||
2536 | high = i2c_r(sd, 0x0a); | 2697 | high = i2c_r(sd, 0x0a); |
2537 | if (high < 0) { | 2698 | if (high < 0) { |
2538 | PDEBUG(D_ERR, "Error detecting camera chip PID"); | 2699 | PDEBUG(D_ERR, "Error detecting camera chip PID"); |
2539 | return high; | 2700 | return; |
2540 | } | 2701 | } |
2541 | low = i2c_r(sd, 0x0b); | 2702 | low = i2c_r(sd, 0x0b); |
2542 | if (low < 0) { | 2703 | if (low < 0) { |
2543 | PDEBUG(D_ERR, "Error detecting camera chip VER"); | 2704 | PDEBUG(D_ERR, "Error detecting camera chip VER"); |
2544 | return low; | 2705 | return; |
2545 | } | 2706 | } |
2546 | if (high == 0x76) { | 2707 | if (high == 0x76) { |
2547 | switch (low) { | 2708 | switch (low) { |
2548 | case 0x30: | 2709 | case 0x30: |
2549 | err("Sensor is an OV7630/OV7635"); | 2710 | err("Sensor is an OV7630/OV7635"); |
2550 | err("7630 is not supported by this driver"); | 2711 | err("7630 is not supported by this driver"); |
2551 | return -1; | 2712 | return; |
2552 | case 0x40: | 2713 | case 0x40: |
2553 | PDEBUG(D_PROBE, "Sensor is an OV7645"); | 2714 | PDEBUG(D_PROBE, "Sensor is an OV7645"); |
2554 | sd->sensor = SEN_OV7640; /* FIXME */ | 2715 | sd->sensor = SEN_OV7640; /* FIXME */ |
@@ -2561,9 +2722,14 @@ static int ov7xx0_configure(struct sd *sd) | |||
2561 | PDEBUG(D_PROBE, "Sensor is an OV7648"); | 2722 | PDEBUG(D_PROBE, "Sensor is an OV7648"); |
2562 | sd->sensor = SEN_OV7648; | 2723 | sd->sensor = SEN_OV7648; |
2563 | break; | 2724 | break; |
2725 | case 0x60: | ||
2726 | PDEBUG(D_PROBE, "Sensor is a OV7660"); | ||
2727 | sd->sensor = SEN_OV7660; | ||
2728 | sd->invert_led = 0; | ||
2729 | break; | ||
2564 | default: | 2730 | default: |
2565 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); | 2731 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); |
2566 | return -1; | 2732 | return; |
2567 | } | 2733 | } |
2568 | } else { | 2734 | } else { |
2569 | PDEBUG(D_PROBE, "Sensor is an OV7620"); | 2735 | PDEBUG(D_PROBE, "Sensor is an OV7620"); |
@@ -2571,15 +2737,11 @@ static int ov7xx0_configure(struct sd *sd) | |||
2571 | } | 2737 | } |
2572 | } else { | 2738 | } else { |
2573 | err("Unknown image sensor version: %d", rc & 3); | 2739 | err("Unknown image sensor version: %d", rc & 3); |
2574 | return -1; | ||
2575 | } | 2740 | } |
2576 | |||
2577 | /* Set sensor-specific vars */ | ||
2578 | return 0; | ||
2579 | } | 2741 | } |
2580 | 2742 | ||
2581 | /* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */ | 2743 | /* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */ |
2582 | static int ov6xx0_configure(struct sd *sd) | 2744 | static void ov6xx0_configure(struct sd *sd) |
2583 | { | 2745 | { |
2584 | int rc; | 2746 | int rc; |
2585 | PDEBUG(D_PROBE, "starting OV6xx0 configuration"); | 2747 | PDEBUG(D_PROBE, "starting OV6xx0 configuration"); |
@@ -2588,7 +2750,7 @@ static int ov6xx0_configure(struct sd *sd) | |||
2588 | rc = i2c_r(sd, OV7610_REG_COM_I); | 2750 | rc = i2c_r(sd, OV7610_REG_COM_I); |
2589 | if (rc < 0) { | 2751 | if (rc < 0) { |
2590 | PDEBUG(D_ERR, "Error detecting sensor type"); | 2752 | PDEBUG(D_ERR, "Error detecting sensor type"); |
2591 | return -1; | 2753 | return; |
2592 | } | 2754 | } |
2593 | 2755 | ||
2594 | /* Ugh. The first two bits are the version bits, but | 2756 | /* Ugh. The first two bits are the version bits, but |
@@ -2619,13 +2781,11 @@ static int ov6xx0_configure(struct sd *sd) | |||
2619 | break; | 2781 | break; |
2620 | default: | 2782 | default: |
2621 | err("FATAL: Unknown sensor version: 0x%02x", rc); | 2783 | err("FATAL: Unknown sensor version: 0x%02x", rc); |
2622 | return -1; | 2784 | return; |
2623 | } | 2785 | } |
2624 | 2786 | ||
2625 | /* Set sensor-specific vars */ | 2787 | /* Set sensor-specific vars */ |
2626 | sd->sif = 1; | 2788 | sd->sif = 1; |
2627 | |||
2628 | return 0; | ||
2629 | } | 2789 | } |
2630 | 2790 | ||
2631 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ | 2791 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ |
@@ -2637,14 +2797,14 @@ static void ov51x_led_control(struct sd *sd, int on) | |||
2637 | switch (sd->bridge) { | 2797 | switch (sd->bridge) { |
2638 | /* OV511 has no LED control */ | 2798 | /* OV511 has no LED control */ |
2639 | case BRIDGE_OV511PLUS: | 2799 | case BRIDGE_OV511PLUS: |
2640 | reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); | 2800 | reg_w(sd, R511_SYS_LED_CTL, on); |
2641 | break; | 2801 | break; |
2642 | case BRIDGE_OV518: | 2802 | case BRIDGE_OV518: |
2643 | case BRIDGE_OV518PLUS: | 2803 | case BRIDGE_OV518PLUS: |
2644 | reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); | 2804 | reg_w_mask(sd, R518_GPIO_OUT, 0x02 * on, 0x02); |
2645 | break; | 2805 | break; |
2646 | case BRIDGE_OV519: | 2806 | case BRIDGE_OV519: |
2647 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | 2807 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, on, 1); |
2648 | break; | 2808 | break; |
2649 | } | 2809 | } |
2650 | } | 2810 | } |
@@ -2679,7 +2839,7 @@ static void sd_reset_snapshot(struct gspca_dev *gspca_dev) | |||
2679 | } | 2839 | } |
2680 | } | 2840 | } |
2681 | 2841 | ||
2682 | static int ov51x_upload_quan_tables(struct sd *sd) | 2842 | static void ov51x_upload_quan_tables(struct sd *sd) |
2683 | { | 2843 | { |
2684 | const unsigned char yQuanTable511[] = { | 2844 | const unsigned char yQuanTable511[] = { |
2685 | 0, 1, 1, 2, 2, 3, 3, 4, | 2845 | 0, 1, 1, 2, 2, 3, 3, 4, |
@@ -2710,7 +2870,6 @@ static int ov51x_upload_quan_tables(struct sd *sd) | |||
2710 | 6, 6, 6, 6, 7, 7, 7, 8, | 2870 | 6, 6, 6, 6, 7, 7, 7, 8, |
2711 | 7, 7, 6, 7, 7, 7, 8, 8 | 2871 | 7, 7, 6, 7, 7, 7, 8, 8 |
2712 | }; | 2872 | }; |
2713 | |||
2714 | const unsigned char uvQuanTable518[] = { | 2873 | const unsigned char uvQuanTable518[] = { |
2715 | 6, 6, 6, 7, 7, 7, 7, 7, | 2874 | 6, 6, 6, 7, 7, 7, 7, 7, |
2716 | 6, 6, 6, 7, 7, 7, 7, 7, | 2875 | 6, 6, 6, 7, 7, 7, 7, 7, |
@@ -2720,18 +2879,18 @@ static int ov51x_upload_quan_tables(struct sd *sd) | |||
2720 | 2879 | ||
2721 | const unsigned char *pYTable, *pUVTable; | 2880 | const unsigned char *pYTable, *pUVTable; |
2722 | unsigned char val0, val1; | 2881 | unsigned char val0, val1; |
2723 | int i, size, rc, reg = R51x_COMP_LUT_BEGIN; | 2882 | int i, size, reg = R51x_COMP_LUT_BEGIN; |
2724 | 2883 | ||
2725 | PDEBUG(D_PROBE, "Uploading quantization tables"); | 2884 | PDEBUG(D_PROBE, "Uploading quantization tables"); |
2726 | 2885 | ||
2727 | if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) { | 2886 | if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) { |
2728 | pYTable = yQuanTable511; | 2887 | pYTable = yQuanTable511; |
2729 | pUVTable = uvQuanTable511; | 2888 | pUVTable = uvQuanTable511; |
2730 | size = 32; | 2889 | size = 32; |
2731 | } else { | 2890 | } else { |
2732 | pYTable = yQuanTable518; | 2891 | pYTable = yQuanTable518; |
2733 | pUVTable = uvQuanTable518; | 2892 | pUVTable = uvQuanTable518; |
2734 | size = 16; | 2893 | size = 16; |
2735 | } | 2894 | } |
2736 | 2895 | ||
2737 | for (i = 0; i < size; i++) { | 2896 | for (i = 0; i < size; i++) { |
@@ -2740,30 +2899,23 @@ static int ov51x_upload_quan_tables(struct sd *sd) | |||
2740 | val0 &= 0x0f; | 2899 | val0 &= 0x0f; |
2741 | val1 &= 0x0f; | 2900 | val1 &= 0x0f; |
2742 | val0 |= val1 << 4; | 2901 | val0 |= val1 << 4; |
2743 | rc = reg_w(sd, reg, val0); | 2902 | reg_w(sd, reg, val0); |
2744 | if (rc < 0) | ||
2745 | return rc; | ||
2746 | 2903 | ||
2747 | val0 = *pUVTable++; | 2904 | val0 = *pUVTable++; |
2748 | val1 = *pUVTable++; | 2905 | val1 = *pUVTable++; |
2749 | val0 &= 0x0f; | 2906 | val0 &= 0x0f; |
2750 | val1 &= 0x0f; | 2907 | val1 &= 0x0f; |
2751 | val0 |= val1 << 4; | 2908 | val0 |= val1 << 4; |
2752 | rc = reg_w(sd, reg + size, val0); | 2909 | reg_w(sd, reg + size, val0); |
2753 | if (rc < 0) | ||
2754 | return rc; | ||
2755 | 2910 | ||
2756 | reg++; | 2911 | reg++; |
2757 | } | 2912 | } |
2758 | |||
2759 | return 0; | ||
2760 | } | 2913 | } |
2761 | 2914 | ||
2762 | /* This initializes the OV511/OV511+ and the sensor */ | 2915 | /* This initializes the OV511/OV511+ and the sensor */ |
2763 | static int ov511_configure(struct gspca_dev *gspca_dev) | 2916 | static void ov511_configure(struct gspca_dev *gspca_dev) |
2764 | { | 2917 | { |
2765 | struct sd *sd = (struct sd *) gspca_dev; | 2918 | struct sd *sd = (struct sd *) gspca_dev; |
2766 | int rc; | ||
2767 | 2919 | ||
2768 | /* For 511 and 511+ */ | 2920 | /* For 511 and 511+ */ |
2769 | const struct ov_regvals init_511[] = { | 2921 | const struct ov_regvals init_511[] = { |
@@ -2809,42 +2961,27 @@ static int ov511_configure(struct gspca_dev *gspca_dev) | |||
2809 | 2961 | ||
2810 | PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID)); | 2962 | PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID)); |
2811 | 2963 | ||
2812 | rc = write_regvals(sd, init_511, ARRAY_SIZE(init_511)); | 2964 | write_regvals(sd, init_511, ARRAY_SIZE(init_511)); |
2813 | if (rc < 0) | ||
2814 | return rc; | ||
2815 | 2965 | ||
2816 | switch (sd->bridge) { | 2966 | switch (sd->bridge) { |
2817 | case BRIDGE_OV511: | 2967 | case BRIDGE_OV511: |
2818 | rc = write_regvals(sd, norm_511, ARRAY_SIZE(norm_511)); | 2968 | write_regvals(sd, norm_511, ARRAY_SIZE(norm_511)); |
2819 | if (rc < 0) | ||
2820 | return rc; | ||
2821 | break; | 2969 | break; |
2822 | case BRIDGE_OV511PLUS: | 2970 | case BRIDGE_OV511PLUS: |
2823 | rc = write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p)); | 2971 | write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p)); |
2824 | if (rc < 0) | ||
2825 | return rc; | ||
2826 | break; | 2972 | break; |
2827 | } | 2973 | } |
2828 | 2974 | ||
2829 | /* Init compression */ | 2975 | /* Init compression */ |
2830 | rc = write_regvals(sd, compress_511, ARRAY_SIZE(compress_511)); | 2976 | write_regvals(sd, compress_511, ARRAY_SIZE(compress_511)); |
2831 | if (rc < 0) | ||
2832 | return rc; | ||
2833 | |||
2834 | rc = ov51x_upload_quan_tables(sd); | ||
2835 | if (rc < 0) { | ||
2836 | PDEBUG(D_ERR, "Error uploading quantization tables"); | ||
2837 | return rc; | ||
2838 | } | ||
2839 | 2977 | ||
2840 | return 0; | 2978 | ov51x_upload_quan_tables(sd); |
2841 | } | 2979 | } |
2842 | 2980 | ||
2843 | /* This initializes the OV518/OV518+ and the sensor */ | 2981 | /* This initializes the OV518/OV518+ and the sensor */ |
2844 | static int ov518_configure(struct gspca_dev *gspca_dev) | 2982 | static void ov518_configure(struct gspca_dev *gspca_dev) |
2845 | { | 2983 | { |
2846 | struct sd *sd = (struct sd *) gspca_dev; | 2984 | struct sd *sd = (struct sd *) gspca_dev; |
2847 | int rc; | ||
2848 | 2985 | ||
2849 | /* For 518 and 518+ */ | 2986 | /* For 518 and 518+ */ |
2850 | const struct ov_regvals init_518[] = { | 2987 | const struct ov_regvals init_518[] = { |
@@ -2892,65 +3029,49 @@ static int ov518_configure(struct gspca_dev *gspca_dev) | |||
2892 | 3029 | ||
2893 | /* First 5 bits of custom ID reg are a revision ID on OV518 */ | 3030 | /* First 5 bits of custom ID reg are a revision ID on OV518 */ |
2894 | PDEBUG(D_PROBE, "Device revision %d", | 3031 | PDEBUG(D_PROBE, "Device revision %d", |
2895 | 0x1F & reg_r(sd, R51x_SYS_CUST_ID)); | 3032 | 0x1f & reg_r(sd, R51x_SYS_CUST_ID)); |
2896 | 3033 | ||
2897 | rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518)); | 3034 | write_regvals(sd, init_518, ARRAY_SIZE(init_518)); |
2898 | if (rc < 0) | ||
2899 | return rc; | ||
2900 | 3035 | ||
2901 | /* Set LED GPIO pin to output mode */ | 3036 | /* Set LED GPIO pin to output mode */ |
2902 | rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02); | 3037 | reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02); |
2903 | if (rc < 0) | ||
2904 | return rc; | ||
2905 | 3038 | ||
2906 | switch (sd->bridge) { | 3039 | switch (sd->bridge) { |
2907 | case BRIDGE_OV518: | 3040 | case BRIDGE_OV518: |
2908 | rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518)); | 3041 | write_regvals(sd, norm_518, ARRAY_SIZE(norm_518)); |
2909 | if (rc < 0) | ||
2910 | return rc; | ||
2911 | break; | 3042 | break; |
2912 | case BRIDGE_OV518PLUS: | 3043 | case BRIDGE_OV518PLUS: |
2913 | rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p)); | 3044 | write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p)); |
2914 | if (rc < 0) | ||
2915 | return rc; | ||
2916 | break; | 3045 | break; |
2917 | } | 3046 | } |
2918 | 3047 | ||
2919 | rc = ov51x_upload_quan_tables(sd); | 3048 | ov51x_upload_quan_tables(sd); |
2920 | if (rc < 0) { | ||
2921 | PDEBUG(D_ERR, "Error uploading quantization tables"); | ||
2922 | return rc; | ||
2923 | } | ||
2924 | 3049 | ||
2925 | rc = reg_w(sd, 0x2f, 0x80); | 3050 | reg_w(sd, 0x2f, 0x80); |
2926 | if (rc < 0) | ||
2927 | return rc; | ||
2928 | |||
2929 | return 0; | ||
2930 | } | 3051 | } |
2931 | 3052 | ||
2932 | static int ov519_configure(struct sd *sd) | 3053 | static void ov519_configure(struct sd *sd) |
2933 | { | 3054 | { |
2934 | static const struct ov_regvals init_519[] = { | 3055 | static const struct ov_regvals init_519[] = { |
2935 | { 0x5a, 0x6d }, /* EnableSystem */ | 3056 | { 0x5a, 0x6d }, /* EnableSystem */ |
2936 | { 0x53, 0x9b }, | 3057 | { 0x53, 0x9b }, |
2937 | { 0x54, 0xff }, /* set bit2 to enable jpeg */ | 3058 | { OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */ |
2938 | { 0x5d, 0x03 }, | 3059 | { 0x5d, 0x03 }, |
2939 | { 0x49, 0x01 }, | 3060 | { 0x49, 0x01 }, |
2940 | { 0x48, 0x00 }, | 3061 | { 0x48, 0x00 }, |
2941 | /* Set LED pin to output mode. Bit 4 must be cleared or sensor | 3062 | /* Set LED pin to output mode. Bit 4 must be cleared or sensor |
2942 | * detection will fail. This deserves further investigation. */ | 3063 | * detection will fail. This deserves further investigation. */ |
2943 | { OV519_GPIO_IO_CTRL0, 0xee }, | 3064 | { OV519_GPIO_IO_CTRL0, 0xee }, |
2944 | { 0x51, 0x0f }, /* SetUsbInit */ | 3065 | { OV519_R51_RESET1, 0x0f }, |
2945 | { 0x51, 0x00 }, | 3066 | { OV519_R51_RESET1, 0x00 }, |
2946 | { 0x22, 0x00 }, | 3067 | { 0x22, 0x00 }, |
2947 | /* windows reads 0x55 at this point*/ | 3068 | /* windows reads 0x55 at this point*/ |
2948 | }; | 3069 | }; |
2949 | 3070 | ||
2950 | return write_regvals(sd, init_519, ARRAY_SIZE(init_519)); | 3071 | write_regvals(sd, init_519, ARRAY_SIZE(init_519)); |
2951 | } | 3072 | } |
2952 | 3073 | ||
2953 | static int ovfx2_configure(struct sd *sd) | 3074 | static void ovfx2_configure(struct sd *sd) |
2954 | { | 3075 | { |
2955 | static const struct ov_regvals init_fx2[] = { | 3076 | static const struct ov_regvals init_fx2[] = { |
2956 | { 0x00, 0x60 }, | 3077 | { 0x00, 0x60 }, |
@@ -2964,7 +3085,92 @@ static int ovfx2_configure(struct sd *sd) | |||
2964 | 3085 | ||
2965 | sd->stopped = 1; | 3086 | sd->stopped = 1; |
2966 | 3087 | ||
2967 | return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2)); | 3088 | write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2)); |
3089 | } | ||
3090 | |||
3091 | /* set the mode */ | ||
3092 | /* This function works for ov7660 only */ | ||
3093 | static void ov519_set_mode(struct sd *sd) | ||
3094 | { | ||
3095 | static const struct ov_regvals bridge_ov7660[2][10] = { | ||
3096 | {{0x10, 0x14}, {0x11, 0x1e}, {0x12, 0x00}, {0x13, 0x00}, | ||
3097 | {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c}, | ||
3098 | {0x25, 0x01}, {0x26, 0x00}}, | ||
3099 | {{0x10, 0x28}, {0x11, 0x3c}, {0x12, 0x00}, {0x13, 0x00}, | ||
3100 | {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c}, | ||
3101 | {0x25, 0x03}, {0x26, 0x00}} | ||
3102 | }; | ||
3103 | static const struct ov_i2c_regvals sensor_ov7660[2][3] = { | ||
3104 | {{0x12, 0x00}, {0x24, 0x00}, {0x0c, 0x0c}}, | ||
3105 | {{0x12, 0x00}, {0x04, 0x00}, {0x0c, 0x00}} | ||
3106 | }; | ||
3107 | static const struct ov_i2c_regvals sensor_ov7660_2[] = { | ||
3108 | {OV7670_R17_HSTART, 0x13}, | ||
3109 | {OV7670_R18_HSTOP, 0x01}, | ||
3110 | {OV7670_R32_HREF, 0x92}, | ||
3111 | {OV7670_R19_VSTART, 0x02}, | ||
3112 | {OV7670_R1A_VSTOP, 0x7a}, | ||
3113 | {OV7670_R03_VREF, 0x00}, | ||
3114 | /* {0x33, 0x00}, */ | ||
3115 | /* {0x34, 0x07}, */ | ||
3116 | /* {0x36, 0x00}, */ | ||
3117 | /* {0x6b, 0x0a}, */ | ||
3118 | }; | ||
3119 | |||
3120 | write_regvals(sd, bridge_ov7660[sd->gspca_dev.curr_mode], | ||
3121 | ARRAY_SIZE(bridge_ov7660[0])); | ||
3122 | write_i2c_regvals(sd, sensor_ov7660[sd->gspca_dev.curr_mode], | ||
3123 | ARRAY_SIZE(sensor_ov7660[0])); | ||
3124 | write_i2c_regvals(sd, sensor_ov7660_2, | ||
3125 | ARRAY_SIZE(sensor_ov7660_2)); | ||
3126 | } | ||
3127 | |||
3128 | /* set the frame rate */ | ||
3129 | /* This function works for sensors ov7640, ov7648 ov7660 and ov7670 only */ | ||
3130 | static void ov519_set_fr(struct sd *sd) | ||
3131 | { | ||
3132 | int fr; | ||
3133 | u8 clock; | ||
3134 | /* frame rate table with indices: | ||
3135 | * - mode = 0: 320x240, 1: 640x480 | ||
3136 | * - fr rate = 0: 30, 1: 25, 2: 20, 3: 15, 4: 10, 5: 5 | ||
3137 | * - reg = 0: bridge a4, 1: bridge 23, 2: sensor 11 (clock) | ||
3138 | */ | ||
3139 | static const u8 fr_tb[2][6][3] = { | ||
3140 | {{0x04, 0xff, 0x00}, | ||
3141 | {0x04, 0x1f, 0x00}, | ||
3142 | {0x04, 0x1b, 0x00}, | ||
3143 | {0x04, 0x15, 0x00}, | ||
3144 | {0x04, 0x09, 0x00}, | ||
3145 | {0x04, 0x01, 0x00}}, | ||
3146 | {{0x0c, 0xff, 0x00}, | ||
3147 | {0x0c, 0x1f, 0x00}, | ||
3148 | {0x0c, 0x1b, 0x00}, | ||
3149 | {0x04, 0xff, 0x01}, | ||
3150 | {0x04, 0x1f, 0x01}, | ||
3151 | {0x04, 0x1b, 0x01}}, | ||
3152 | }; | ||
3153 | |||
3154 | if (frame_rate > 0) | ||
3155 | sd->frame_rate = frame_rate; | ||
3156 | if (sd->frame_rate >= 30) | ||
3157 | fr = 0; | ||
3158 | else if (sd->frame_rate >= 25) | ||
3159 | fr = 1; | ||
3160 | else if (sd->frame_rate >= 20) | ||
3161 | fr = 2; | ||
3162 | else if (sd->frame_rate >= 15) | ||
3163 | fr = 3; | ||
3164 | else if (sd->frame_rate >= 10) | ||
3165 | fr = 4; | ||
3166 | else | ||
3167 | fr = 5; | ||
3168 | reg_w(sd, 0xa4, fr_tb[sd->gspca_dev.curr_mode][fr][0]); | ||
3169 | reg_w(sd, 0x23, fr_tb[sd->gspca_dev.curr_mode][fr][1]); | ||
3170 | clock = fr_tb[sd->gspca_dev.curr_mode][fr][2]; | ||
3171 | if (sd->sensor == SEN_OV7660) | ||
3172 | clock |= 0x80; /* enable double clock */ | ||
3173 | ov518_i2c_w(sd, OV7670_R11_CLKRC, clock); | ||
2968 | } | 3174 | } |
2969 | 3175 | ||
2970 | /* this function is called at probe time */ | 3176 | /* this function is called at probe time */ |
@@ -2973,99 +3179,119 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2973 | { | 3179 | { |
2974 | struct sd *sd = (struct sd *) gspca_dev; | 3180 | struct sd *sd = (struct sd *) gspca_dev; |
2975 | struct cam *cam = &gspca_dev->cam; | 3181 | struct cam *cam = &gspca_dev->cam; |
2976 | int ret = 0; | ||
2977 | 3182 | ||
2978 | sd->bridge = id->driver_info & BRIDGE_MASK; | 3183 | sd->bridge = id->driver_info & BRIDGE_MASK; |
2979 | sd->invert_led = id->driver_info & BRIDGE_INVERT_LED; | 3184 | sd->invert_led = (id->driver_info & BRIDGE_INVERT_LED) != 0; |
2980 | 3185 | ||
2981 | switch (sd->bridge) { | 3186 | switch (sd->bridge) { |
2982 | case BRIDGE_OV511: | 3187 | case BRIDGE_OV511: |
2983 | case BRIDGE_OV511PLUS: | 3188 | case BRIDGE_OV511PLUS: |
2984 | ret = ov511_configure(gspca_dev); | 3189 | cam->cam_mode = ov511_vga_mode; |
3190 | cam->nmodes = ARRAY_SIZE(ov511_vga_mode); | ||
2985 | break; | 3191 | break; |
2986 | case BRIDGE_OV518: | 3192 | case BRIDGE_OV518: |
2987 | case BRIDGE_OV518PLUS: | 3193 | case BRIDGE_OV518PLUS: |
2988 | ret = ov518_configure(gspca_dev); | 3194 | cam->cam_mode = ov518_vga_mode; |
3195 | cam->nmodes = ARRAY_SIZE(ov518_vga_mode); | ||
2989 | break; | 3196 | break; |
2990 | case BRIDGE_OV519: | 3197 | case BRIDGE_OV519: |
2991 | ret = ov519_configure(sd); | 3198 | cam->cam_mode = ov519_vga_mode; |
3199 | cam->nmodes = ARRAY_SIZE(ov519_vga_mode); | ||
3200 | sd->invert_led = !sd->invert_led; | ||
2992 | break; | 3201 | break; |
2993 | case BRIDGE_OVFX2: | 3202 | case BRIDGE_OVFX2: |
2994 | ret = ovfx2_configure(sd); | 3203 | cam->cam_mode = ov519_vga_mode; |
3204 | cam->nmodes = ARRAY_SIZE(ov519_vga_mode); | ||
2995 | cam->bulk_size = OVFX2_BULK_SIZE; | 3205 | cam->bulk_size = OVFX2_BULK_SIZE; |
2996 | cam->bulk_nurbs = MAX_NURBS; | 3206 | cam->bulk_nurbs = MAX_NURBS; |
2997 | cam->bulk = 1; | 3207 | cam->bulk = 1; |
2998 | break; | 3208 | break; |
2999 | case BRIDGE_W9968CF: | 3209 | case BRIDGE_W9968CF: |
3000 | ret = w9968cf_configure(sd); | 3210 | cam->cam_mode = w9968cf_vga_mode; |
3211 | cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode); | ||
3001 | cam->reverse_alts = 1; | 3212 | cam->reverse_alts = 1; |
3002 | break; | 3213 | break; |
3003 | } | 3214 | } |
3004 | 3215 | ||
3005 | if (ret) | 3216 | gspca_dev->cam.ctrls = sd->ctrls; |
3006 | goto error; | 3217 | sd->quality = QUALITY_DEF; |
3007 | 3218 | ||
3008 | ov51x_led_control(sd, 0); /* turn LED off */ | 3219 | return 0; |
3220 | } | ||
3221 | |||
3222 | /* this function is called at probe and resume time */ | ||
3223 | static int sd_init(struct gspca_dev *gspca_dev) | ||
3224 | { | ||
3225 | struct sd *sd = (struct sd *) gspca_dev; | ||
3226 | struct cam *cam = &gspca_dev->cam; | ||
3227 | |||
3228 | switch (sd->bridge) { | ||
3229 | case BRIDGE_OV511: | ||
3230 | case BRIDGE_OV511PLUS: | ||
3231 | ov511_configure(gspca_dev); | ||
3232 | break; | ||
3233 | case BRIDGE_OV518: | ||
3234 | case BRIDGE_OV518PLUS: | ||
3235 | ov518_configure(gspca_dev); | ||
3236 | break; | ||
3237 | case BRIDGE_OV519: | ||
3238 | ov519_configure(sd); | ||
3239 | break; | ||
3240 | case BRIDGE_OVFX2: | ||
3241 | ovfx2_configure(sd); | ||
3242 | break; | ||
3243 | case BRIDGE_W9968CF: | ||
3244 | w9968cf_configure(sd); | ||
3245 | break; | ||
3246 | } | ||
3009 | 3247 | ||
3010 | /* The OV519 must be more aggressive about sensor detection since | 3248 | /* The OV519 must be more aggressive about sensor detection since |
3011 | * I2C write will never fail if the sensor is not present. We have | 3249 | * I2C write will never fail if the sensor is not present. We have |
3012 | * to try to initialize the sensor to detect its presence */ | 3250 | * to try to initialize the sensor to detect its presence */ |
3251 | sd->sensor = -1; | ||
3013 | 3252 | ||
3014 | /* Test for 76xx */ | 3253 | /* Test for 76xx */ |
3015 | if (init_ov_sensor(sd, OV7xx0_SID) >= 0) { | 3254 | if (init_ov_sensor(sd, OV7xx0_SID) >= 0) { |
3016 | if (ov7xx0_configure(sd) < 0) { | 3255 | ov7xx0_configure(sd); |
3017 | PDEBUG(D_ERR, "Failed to configure OV7xx0"); | 3256 | |
3018 | goto error; | ||
3019 | } | ||
3020 | /* Test for 6xx0 */ | 3257 | /* Test for 6xx0 */ |
3021 | } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) { | 3258 | } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) { |
3022 | if (ov6xx0_configure(sd) < 0) { | 3259 | ov6xx0_configure(sd); |
3023 | PDEBUG(D_ERR, "Failed to configure OV6xx0"); | 3260 | |
3024 | goto error; | ||
3025 | } | ||
3026 | /* Test for 8xx0 */ | 3261 | /* Test for 8xx0 */ |
3027 | } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) { | 3262 | } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) { |
3028 | if (ov8xx0_configure(sd) < 0) { | 3263 | ov8xx0_configure(sd); |
3029 | PDEBUG(D_ERR, "Failed to configure OV8xx0"); | 3264 | |
3030 | goto error; | ||
3031 | } | ||
3032 | /* Test for 3xxx / 2xxx */ | 3265 | /* Test for 3xxx / 2xxx */ |
3033 | } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) { | 3266 | } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) { |
3034 | if (ov_hires_configure(sd) < 0) { | 3267 | ov_hires_configure(sd); |
3035 | PDEBUG(D_ERR, "Failed to configure high res OV"); | ||
3036 | goto error; | ||
3037 | } | ||
3038 | } else { | 3268 | } else { |
3039 | err("Can't determine sensor slave IDs"); | 3269 | err("Can't determine sensor slave IDs"); |
3040 | goto error; | 3270 | goto error; |
3041 | } | 3271 | } |
3042 | 3272 | ||
3273 | if (sd->sensor < 0) | ||
3274 | goto error; | ||
3275 | |||
3276 | ov51x_led_control(sd, 0); /* turn LED off */ | ||
3277 | |||
3043 | switch (sd->bridge) { | 3278 | switch (sd->bridge) { |
3044 | case BRIDGE_OV511: | 3279 | case BRIDGE_OV511: |
3045 | case BRIDGE_OV511PLUS: | 3280 | case BRIDGE_OV511PLUS: |
3046 | if (!sd->sif) { | 3281 | if (sd->sif) { |
3047 | cam->cam_mode = ov511_vga_mode; | ||
3048 | cam->nmodes = ARRAY_SIZE(ov511_vga_mode); | ||
3049 | } else { | ||
3050 | cam->cam_mode = ov511_sif_mode; | 3282 | cam->cam_mode = ov511_sif_mode; |
3051 | cam->nmodes = ARRAY_SIZE(ov511_sif_mode); | 3283 | cam->nmodes = ARRAY_SIZE(ov511_sif_mode); |
3052 | } | 3284 | } |
3053 | break; | 3285 | break; |
3054 | case BRIDGE_OV518: | 3286 | case BRIDGE_OV518: |
3055 | case BRIDGE_OV518PLUS: | 3287 | case BRIDGE_OV518PLUS: |
3056 | if (!sd->sif) { | 3288 | if (sd->sif) { |
3057 | cam->cam_mode = ov518_vga_mode; | ||
3058 | cam->nmodes = ARRAY_SIZE(ov518_vga_mode); | ||
3059 | } else { | ||
3060 | cam->cam_mode = ov518_sif_mode; | 3289 | cam->cam_mode = ov518_sif_mode; |
3061 | cam->nmodes = ARRAY_SIZE(ov518_sif_mode); | 3290 | cam->nmodes = ARRAY_SIZE(ov518_sif_mode); |
3062 | } | 3291 | } |
3063 | break; | 3292 | break; |
3064 | case BRIDGE_OV519: | 3293 | case BRIDGE_OV519: |
3065 | if (!sd->sif) { | 3294 | if (sd->sif) { |
3066 | cam->cam_mode = ov519_vga_mode; | ||
3067 | cam->nmodes = ARRAY_SIZE(ov519_vga_mode); | ||
3068 | } else { | ||
3069 | cam->cam_mode = ov519_sif_mode; | 3295 | cam->cam_mode = ov519_sif_mode; |
3070 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); | 3296 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); |
3071 | } | 3297 | } |
@@ -3077,118 +3303,107 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
3077 | } else if (sd->sensor == SEN_OV3610) { | 3303 | } else if (sd->sensor == SEN_OV3610) { |
3078 | cam->cam_mode = ovfx2_ov3610_mode; | 3304 | cam->cam_mode = ovfx2_ov3610_mode; |
3079 | cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode); | 3305 | cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode); |
3080 | } else if (!sd->sif) { | 3306 | } else if (sd->sif) { |
3081 | cam->cam_mode = ov519_vga_mode; | ||
3082 | cam->nmodes = ARRAY_SIZE(ov519_vga_mode); | ||
3083 | } else { | ||
3084 | cam->cam_mode = ov519_sif_mode; | 3307 | cam->cam_mode = ov519_sif_mode; |
3085 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); | 3308 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); |
3086 | } | 3309 | } |
3087 | break; | 3310 | break; |
3088 | case BRIDGE_W9968CF: | 3311 | case BRIDGE_W9968CF: |
3089 | cam->cam_mode = w9968cf_vga_mode; | ||
3090 | cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode); | ||
3091 | if (sd->sif) | 3312 | if (sd->sif) |
3092 | cam->nmodes--; | 3313 | cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode) - 1; |
3093 | 3314 | ||
3094 | /* w9968cf needs initialisation once the sensor is known */ | 3315 | /* w9968cf needs initialisation once the sensor is known */ |
3095 | if (w9968cf_init(sd) < 0) | 3316 | w9968cf_init(sd); |
3096 | goto error; | ||
3097 | break; | 3317 | break; |
3098 | } | 3318 | } |
3099 | gspca_dev->cam.ctrls = sd->ctrls; | ||
3100 | if (sd->sensor == SEN_OV7670) | ||
3101 | gspca_dev->ctrl_dis = 1 << COLORS; | ||
3102 | else | ||
3103 | gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP); | ||
3104 | sd->quality = QUALITY_DEF; | ||
3105 | if (sd->sensor == SEN_OV7640 || | ||
3106 | sd->sensor == SEN_OV7648) | ||
3107 | gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT) | (1 << CONTRAST); | ||
3108 | if (sd->sensor == SEN_OV7670) | ||
3109 | gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT; | ||
3110 | /* OV8610 Frequency filter control should work but needs testing */ | ||
3111 | if (sd->sensor == SEN_OV8610) | ||
3112 | gspca_dev->ctrl_dis |= 1 << FREQ; | ||
3113 | /* No controls for the OV2610/OV3610 */ | ||
3114 | if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | ||
3115 | gspca_dev->ctrl_dis |= (1 << NCTRL) - 1; | ||
3116 | 3319 | ||
3117 | return 0; | 3320 | gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; |
3118 | error: | ||
3119 | PDEBUG(D_ERR, "OV519 Config failed"); | ||
3120 | return -EBUSY; | ||
3121 | } | ||
3122 | |||
3123 | /* this function is called at probe and resume time */ | ||
3124 | static int sd_init(struct gspca_dev *gspca_dev) | ||
3125 | { | ||
3126 | struct sd *sd = (struct sd *) gspca_dev; | ||
3127 | 3321 | ||
3128 | /* initialize the sensor */ | 3322 | /* initialize the sensor */ |
3129 | switch (sd->sensor) { | 3323 | switch (sd->sensor) { |
3130 | case SEN_OV2610: | 3324 | case SEN_OV2610: |
3131 | if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610))) | 3325 | write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)); |
3132 | return -EIO; | 3326 | |
3133 | /* Enable autogain, autoexpo, awb, bandfilter */ | 3327 | /* Enable autogain, autoexpo, awb, bandfilter */ |
3134 | if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0) | 3328 | i2c_w_mask(sd, 0x13, 0x27, 0x27); |
3135 | return -EIO; | ||
3136 | break; | 3329 | break; |
3137 | case SEN_OV3610: | 3330 | case SEN_OV3610: |
3138 | if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b))) | 3331 | write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)); |
3139 | return -EIO; | 3332 | |
3140 | /* Enable autogain, autoexpo, awb, bandfilter */ | 3333 | /* Enable autogain, autoexpo, awb, bandfilter */ |
3141 | if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0) | 3334 | i2c_w_mask(sd, 0x13, 0x27, 0x27); |
3142 | return -EIO; | ||
3143 | break; | 3335 | break; |
3144 | case SEN_OV6620: | 3336 | case SEN_OV6620: |
3145 | if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20))) | 3337 | write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)); |
3146 | return -EIO; | ||
3147 | break; | 3338 | break; |
3148 | case SEN_OV6630: | 3339 | case SEN_OV6630: |
3149 | case SEN_OV66308AF: | 3340 | case SEN_OV66308AF: |
3150 | sd->ctrls[CONTRAST].def = 200; | 3341 | sd->ctrls[CONTRAST].def = 200; |
3151 | /* The default is too low for the ov6630 */ | 3342 | /* The default is too low for the ov6630 */ |
3152 | if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30))) | 3343 | write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)); |
3153 | return -EIO; | ||
3154 | break; | 3344 | break; |
3155 | default: | 3345 | default: |
3156 | /* case SEN_OV7610: */ | 3346 | /* case SEN_OV7610: */ |
3157 | /* case SEN_OV76BE: */ | 3347 | /* case SEN_OV76BE: */ |
3158 | if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610))) | 3348 | write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)); |
3159 | return -EIO; | 3349 | i2c_w_mask(sd, 0x0e, 0x00, 0x40); |
3160 | if (i2c_w_mask(sd, 0x0e, 0x00, 0x40)) | ||
3161 | return -EIO; | ||
3162 | break; | 3350 | break; |
3163 | case SEN_OV7620: | 3351 | case SEN_OV7620: |
3164 | case SEN_OV7620AE: | 3352 | case SEN_OV7620AE: |
3165 | if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620))) | 3353 | write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)); |
3166 | return -EIO; | ||
3167 | break; | 3354 | break; |
3168 | case SEN_OV7640: | 3355 | case SEN_OV7640: |
3169 | case SEN_OV7648: | 3356 | case SEN_OV7648: |
3170 | if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640))) | 3357 | write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)); |
3171 | return -EIO; | 3358 | break; |
3359 | case SEN_OV7660: | ||
3360 | i2c_w(sd, OV7670_R12_COM7, OV7670_COM7_RESET); | ||
3361 | msleep(14); | ||
3362 | reg_w(sd, OV519_R57_SNAPSHOT, 0x23); | ||
3363 | write_regvals(sd, init_519_ov7660, | ||
3364 | ARRAY_SIZE(init_519_ov7660)); | ||
3365 | write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660)); | ||
3366 | sd->gspca_dev.curr_mode = 1; /* 640x480 */ | ||
3367 | sd->frame_rate = 15; | ||
3368 | ov519_set_mode(sd); | ||
3369 | ov519_set_fr(sd); | ||
3370 | sd->ctrls[COLORS].max = 4; /* 0..4 */ | ||
3371 | sd->ctrls[COLORS].val = | ||
3372 | sd->ctrls[COLORS].def = 2; | ||
3373 | setcolors(gspca_dev); | ||
3374 | sd->ctrls[CONTRAST].max = 6; /* 0..6 */ | ||
3375 | sd->ctrls[CONTRAST].val = | ||
3376 | sd->ctrls[CONTRAST].def = 3; | ||
3377 | setcontrast(gspca_dev); | ||
3378 | sd->ctrls[BRIGHTNESS].max = 6; /* 0..6 */ | ||
3379 | sd->ctrls[BRIGHTNESS].val = | ||
3380 | sd->ctrls[BRIGHTNESS].def = 3; | ||
3381 | setbrightness(gspca_dev); | ||
3382 | sd_reset_snapshot(gspca_dev); | ||
3383 | ov51x_restart(sd); | ||
3384 | ov51x_stop(sd); /* not in win traces */ | ||
3385 | ov51x_led_control(sd, 0); | ||
3172 | break; | 3386 | break; |
3173 | case SEN_OV7670: | 3387 | case SEN_OV7670: |
3174 | sd->ctrls[FREQ].max = 3; /* auto */ | 3388 | sd->ctrls[FREQ].max = 3; /* auto */ |
3175 | sd->ctrls[FREQ].def = 3; | 3389 | sd->ctrls[FREQ].def = 3; |
3176 | if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670))) | 3390 | write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)); |
3177 | return -EIO; | ||
3178 | break; | 3391 | break; |
3179 | case SEN_OV8610: | 3392 | case SEN_OV8610: |
3180 | if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610))) | 3393 | write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)); |
3181 | return -EIO; | ||
3182 | break; | 3394 | break; |
3183 | } | 3395 | } |
3184 | return 0; | 3396 | return gspca_dev->usb_err; |
3397 | error: | ||
3398 | PDEBUG(D_ERR, "OV519 Config failed"); | ||
3399 | return -EINVAL; | ||
3185 | } | 3400 | } |
3186 | 3401 | ||
3187 | /* Set up the OV511/OV511+ with the given image parameters. | 3402 | /* Set up the OV511/OV511+ with the given image parameters. |
3188 | * | 3403 | * |
3189 | * Do not put any sensor-specific code in here (including I2C I/O functions) | 3404 | * Do not put any sensor-specific code in here (including I2C I/O functions) |
3190 | */ | 3405 | */ |
3191 | static int ov511_mode_init_regs(struct sd *sd) | 3406 | static void ov511_mode_init_regs(struct sd *sd) |
3192 | { | 3407 | { |
3193 | int hsegs, vsegs, packet_size, fps, needed; | 3408 | int hsegs, vsegs, packet_size, fps, needed; |
3194 | int interlaced = 0; | 3409 | int interlaced = 0; |
@@ -3199,7 +3414,8 @@ static int ov511_mode_init_regs(struct sd *sd) | |||
3199 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); | 3414 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); |
3200 | if (!alt) { | 3415 | if (!alt) { |
3201 | err("Couldn't get altsetting"); | 3416 | err("Couldn't get altsetting"); |
3202 | return -EIO; | 3417 | sd->gspca_dev.usb_err = -EIO; |
3418 | return; | ||
3203 | } | 3419 | } |
3204 | 3420 | ||
3205 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | 3421 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); |
@@ -3302,8 +3518,6 @@ static int ov511_mode_init_regs(struct sd *sd) | |||
3302 | 3518 | ||
3303 | reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE); | 3519 | reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE); |
3304 | reg_w(sd, R51x_SYS_RESET, 0); | 3520 | reg_w(sd, R51x_SYS_RESET, 0); |
3305 | |||
3306 | return 0; | ||
3307 | } | 3521 | } |
3308 | 3522 | ||
3309 | /* Sets up the OV518/OV518+ with the given image parameters | 3523 | /* Sets up the OV518/OV518+ with the given image parameters |
@@ -3313,7 +3527,7 @@ static int ov511_mode_init_regs(struct sd *sd) | |||
3313 | * | 3527 | * |
3314 | * Do not put any sensor-specific code in here (including I2C I/O functions) | 3528 | * Do not put any sensor-specific code in here (including I2C I/O functions) |
3315 | */ | 3529 | */ |
3316 | static int ov518_mode_init_regs(struct sd *sd) | 3530 | static void ov518_mode_init_regs(struct sd *sd) |
3317 | { | 3531 | { |
3318 | int hsegs, vsegs, packet_size; | 3532 | int hsegs, vsegs, packet_size; |
3319 | struct usb_host_interface *alt; | 3533 | struct usb_host_interface *alt; |
@@ -3323,14 +3537,14 @@ static int ov518_mode_init_regs(struct sd *sd) | |||
3323 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); | 3537 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); |
3324 | if (!alt) { | 3538 | if (!alt) { |
3325 | err("Couldn't get altsetting"); | 3539 | err("Couldn't get altsetting"); |
3326 | return -EIO; | 3540 | sd->gspca_dev.usb_err = -EIO; |
3541 | return; | ||
3327 | } | 3542 | } |
3328 | 3543 | ||
3329 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | 3544 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); |
3330 | ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2); | 3545 | ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2); |
3331 | 3546 | ||
3332 | /******** Set the mode ********/ | 3547 | /******** Set the mode ********/ |
3333 | |||
3334 | reg_w(sd, 0x2b, 0); | 3548 | reg_w(sd, 0x2b, 0); |
3335 | reg_w(sd, 0x2c, 0); | 3549 | reg_w(sd, 0x2c, 0); |
3336 | reg_w(sd, 0x2d, 0); | 3550 | reg_w(sd, 0x2d, 0); |
@@ -3364,7 +3578,7 @@ static int ov518_mode_init_regs(struct sd *sd) | |||
3364 | /* Windows driver does this here; who knows why */ | 3578 | /* Windows driver does this here; who knows why */ |
3365 | reg_w(sd, 0x2f, 0x80); | 3579 | reg_w(sd, 0x2f, 0x80); |
3366 | 3580 | ||
3367 | /******** Set the framerate ********/ | 3581 | /******** Set the framerate ********/ |
3368 | sd->clockdiv = 1; | 3582 | sd->clockdiv = 1; |
3369 | 3583 | ||
3370 | /* Mode independent, but framerate dependent, regs */ | 3584 | /* Mode independent, but framerate dependent, regs */ |
@@ -3427,11 +3641,8 @@ static int ov518_mode_init_regs(struct sd *sd) | |||
3427 | } | 3641 | } |
3428 | 3642 | ||
3429 | reg_w(sd, 0x2f, 0x80); | 3643 | reg_w(sd, 0x2f, 0x80); |
3430 | |||
3431 | return 0; | ||
3432 | } | 3644 | } |
3433 | 3645 | ||
3434 | |||
3435 | /* Sets up the OV519 with the given image parameters | 3646 | /* Sets up the OV519 with the given image parameters |
3436 | * | 3647 | * |
3437 | * OV519 needs a completely different approach, until we can figure out what | 3648 | * OV519 needs a completely different approach, until we can figure out what |
@@ -3439,12 +3650,12 @@ static int ov518_mode_init_regs(struct sd *sd) | |||
3439 | * | 3650 | * |
3440 | * Do not put any sensor-specific code in here (including I2C I/O functions) | 3651 | * Do not put any sensor-specific code in here (including I2C I/O functions) |
3441 | */ | 3652 | */ |
3442 | static int ov519_mode_init_regs(struct sd *sd) | 3653 | static void ov519_mode_init_regs(struct sd *sd) |
3443 | { | 3654 | { |
3444 | static const struct ov_regvals mode_init_519_ov7670[] = { | 3655 | static const struct ov_regvals mode_init_519_ov7670[] = { |
3445 | { 0x5d, 0x03 }, /* Turn off suspend mode */ | 3656 | { 0x5d, 0x03 }, /* Turn off suspend mode */ |
3446 | { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ | 3657 | { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ |
3447 | { 0x54, 0x0f }, /* bit2 (jpeg enable) */ | 3658 | { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */ |
3448 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ | 3659 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ |
3449 | { 0xa3, 0x18 }, | 3660 | { 0xa3, 0x18 }, |
3450 | { 0xa4, 0x04 }, | 3661 | { 0xa4, 0x04 }, |
@@ -3467,7 +3678,7 @@ static int ov519_mode_init_regs(struct sd *sd) | |||
3467 | static const struct ov_regvals mode_init_519[] = { | 3678 | static const struct ov_regvals mode_init_519[] = { |
3468 | { 0x5d, 0x03 }, /* Turn off suspend mode */ | 3679 | { 0x5d, 0x03 }, /* Turn off suspend mode */ |
3469 | { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ | 3680 | { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ |
3470 | { 0x54, 0x0f }, /* bit2 (jpeg enable) */ | 3681 | { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */ |
3471 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ | 3682 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ |
3472 | { 0xa3, 0x18 }, | 3683 | { 0xa3, 0x18 }, |
3473 | { 0xa4, 0x04 }, | 3684 | { 0xa4, 0x04 }, |
@@ -3486,19 +3697,21 @@ static int ov519_mode_init_regs(struct sd *sd) | |||
3486 | }; | 3697 | }; |
3487 | 3698 | ||
3488 | /******** Set the mode ********/ | 3699 | /******** Set the mode ********/ |
3489 | if (sd->sensor != SEN_OV7670) { | 3700 | switch (sd->sensor) { |
3490 | if (write_regvals(sd, mode_init_519, | 3701 | default: |
3491 | ARRAY_SIZE(mode_init_519))) | 3702 | write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519)); |
3492 | return -EIO; | ||
3493 | if (sd->sensor == SEN_OV7640 || | 3703 | if (sd->sensor == SEN_OV7640 || |
3494 | sd->sensor == SEN_OV7648) { | 3704 | sd->sensor == SEN_OV7648) { |
3495 | /* Select 8-bit input mode */ | 3705 | /* Select 8-bit input mode */ |
3496 | reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10); | 3706 | reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10); |
3497 | } | 3707 | } |
3498 | } else { | 3708 | break; |
3499 | if (write_regvals(sd, mode_init_519_ov7670, | 3709 | case SEN_OV7660: |
3500 | ARRAY_SIZE(mode_init_519_ov7670))) | 3710 | return; /* done by ov519_set_mode/fr() */ |
3501 | return -EIO; | 3711 | case SEN_OV7670: |
3712 | write_regvals(sd, mode_init_519_ov7670, | ||
3713 | ARRAY_SIZE(mode_init_519_ov7670)); | ||
3714 | break; | ||
3502 | } | 3715 | } |
3503 | 3716 | ||
3504 | reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4); | 3717 | reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4); |
@@ -3594,17 +3807,16 @@ static int ov519_mode_init_regs(struct sd *sd) | |||
3594 | } | 3807 | } |
3595 | break; | 3808 | break; |
3596 | } | 3809 | } |
3597 | return 0; | ||
3598 | } | 3810 | } |
3599 | 3811 | ||
3600 | static int mode_init_ov_sensor_regs(struct sd *sd) | 3812 | static void mode_init_ov_sensor_regs(struct sd *sd) |
3601 | { | 3813 | { |
3602 | struct gspca_dev *gspca_dev; | 3814 | struct gspca_dev *gspca_dev; |
3603 | int qvga, xstart, xend, ystart, yend; | 3815 | int qvga, xstart, xend, ystart, yend; |
3604 | __u8 v; | 3816 | u8 v; |
3605 | 3817 | ||
3606 | gspca_dev = &sd->gspca_dev; | 3818 | gspca_dev = &sd->gspca_dev; |
3607 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; | 3819 | qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1; |
3608 | 3820 | ||
3609 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ | 3821 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ |
3610 | switch (sd->sensor) { | 3822 | switch (sd->sensor) { |
@@ -3616,7 +3828,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3616 | i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); | 3828 | i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); |
3617 | i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); | 3829 | i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); |
3618 | i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); | 3830 | i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); |
3619 | return 0; | 3831 | return; |
3620 | case SEN_OV3610: | 3832 | case SEN_OV3610: |
3621 | if (qvga) { | 3833 | if (qvga) { |
3622 | xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); | 3834 | xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); |
@@ -3640,7 +3852,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3640 | i2c_w(sd, 0x18, xend >> 4); | 3852 | i2c_w(sd, 0x18, xend >> 4); |
3641 | i2c_w(sd, 0x19, ystart >> 3); | 3853 | i2c_w(sd, 0x19, ystart >> 3); |
3642 | i2c_w(sd, 0x1a, yend >> 3); | 3854 | i2c_w(sd, 0x1a, yend >> 3); |
3643 | return 0; | 3855 | return; |
3644 | case SEN_OV8610: | 3856 | case SEN_OV8610: |
3645 | /* For OV8610 qvga means qsvga */ | 3857 | /* For OV8610 qvga means qsvga */ |
3646 | i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); | 3858 | i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); |
@@ -3687,11 +3899,11 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3687 | /* set COM7_FMT_VGA or COM7_FMT_QVGA | 3899 | /* set COM7_FMT_VGA or COM7_FMT_QVGA |
3688 | * do we need to set anything else? | 3900 | * do we need to set anything else? |
3689 | * HSTART etc are set in set_ov_sensor_window itself */ | 3901 | * HSTART etc are set in set_ov_sensor_window itself */ |
3690 | i2c_w_mask(sd, OV7670_REG_COM7, | 3902 | i2c_w_mask(sd, OV7670_R12_COM7, |
3691 | qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, | 3903 | qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, |
3692 | OV7670_COM7_FMT_MASK); | 3904 | OV7670_COM7_FMT_MASK); |
3693 | i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ | 3905 | i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ |
3694 | i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB, | 3906 | i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_AWB, |
3695 | OV7670_COM8_AWB); | 3907 | OV7670_COM8_AWB); |
3696 | if (qvga) { /* QVGA from ov7670.c by | 3908 | if (qvga) { /* QVGA from ov7670.c by |
3697 | * Jonathan Corbet */ | 3909 | * Jonathan Corbet */ |
@@ -3707,21 +3919,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3707 | } | 3919 | } |
3708 | /* OV7670 hardware window registers are split across | 3920 | /* OV7670 hardware window registers are split across |
3709 | * multiple locations */ | 3921 | * multiple locations */ |
3710 | i2c_w(sd, OV7670_REG_HSTART, xstart >> 3); | 3922 | i2c_w(sd, OV7670_R17_HSTART, xstart >> 3); |
3711 | i2c_w(sd, OV7670_REG_HSTOP, xend >> 3); | 3923 | i2c_w(sd, OV7670_R18_HSTOP, xend >> 3); |
3712 | v = i2c_r(sd, OV7670_REG_HREF); | 3924 | v = i2c_r(sd, OV7670_R32_HREF); |
3713 | v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07); | 3925 | v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07); |
3714 | msleep(10); /* need to sleep between read and write to | 3926 | msleep(10); /* need to sleep between read and write to |
3715 | * same reg! */ | 3927 | * same reg! */ |
3716 | i2c_w(sd, OV7670_REG_HREF, v); | 3928 | i2c_w(sd, OV7670_R32_HREF, v); |
3717 | 3929 | ||
3718 | i2c_w(sd, OV7670_REG_VSTART, ystart >> 2); | 3930 | i2c_w(sd, OV7670_R19_VSTART, ystart >> 2); |
3719 | i2c_w(sd, OV7670_REG_VSTOP, yend >> 2); | 3931 | i2c_w(sd, OV7670_R1A_VSTOP, yend >> 2); |
3720 | v = i2c_r(sd, OV7670_REG_VREF); | 3932 | v = i2c_r(sd, OV7670_R03_VREF); |
3721 | v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03); | 3933 | v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03); |
3722 | msleep(10); /* need to sleep between read and write to | 3934 | msleep(10); /* need to sleep between read and write to |
3723 | * same reg! */ | 3935 | * same reg! */ |
3724 | i2c_w(sd, OV7670_REG_VREF, v); | 3936 | i2c_w(sd, OV7670_R03_VREF, v); |
3725 | break; | 3937 | break; |
3726 | case SEN_OV6620: | 3938 | case SEN_OV6620: |
3727 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | 3939 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); |
@@ -3734,46 +3946,50 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3734 | i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ | 3946 | i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ |
3735 | break; | 3947 | break; |
3736 | default: | 3948 | default: |
3737 | return -EINVAL; | 3949 | return; |
3738 | } | 3950 | } |
3739 | 3951 | ||
3740 | /******** Clock programming ********/ | 3952 | /******** Clock programming ********/ |
3741 | i2c_w(sd, 0x11, sd->clockdiv); | 3953 | i2c_w(sd, 0x11, sd->clockdiv); |
3742 | |||
3743 | return 0; | ||
3744 | } | 3954 | } |
3745 | 3955 | ||
3956 | /* this function works for bridge ov519 and sensors ov7660 and ov7670 only */ | ||
3746 | static void sethvflip(struct gspca_dev *gspca_dev) | 3957 | static void sethvflip(struct gspca_dev *gspca_dev) |
3747 | { | 3958 | { |
3748 | struct sd *sd = (struct sd *) gspca_dev; | 3959 | struct sd *sd = (struct sd *) gspca_dev; |
3749 | 3960 | ||
3750 | if (sd->sensor != SEN_OV7670) | ||
3751 | return; | ||
3752 | if (sd->gspca_dev.streaming) | 3961 | if (sd->gspca_dev.streaming) |
3753 | ov51x_stop(sd); | 3962 | reg_w(sd, OV519_R51_RESET1, 0x0f); /* block stream */ |
3754 | i2c_w_mask(sd, OV7670_REG_MVFP, | 3963 | i2c_w_mask(sd, OV7670_R1E_MVFP, |
3755 | OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val | 3964 | OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val |
3756 | | OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val, | 3965 | | OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val, |
3757 | OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); | 3966 | OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); |
3758 | if (sd->gspca_dev.streaming) | 3967 | if (sd->gspca_dev.streaming) |
3759 | ov51x_restart(sd); | 3968 | reg_w(sd, OV519_R51_RESET1, 0x00); /* restart stream */ |
3760 | } | 3969 | } |
3761 | 3970 | ||
3762 | static int set_ov_sensor_window(struct sd *sd) | 3971 | static void set_ov_sensor_window(struct sd *sd) |
3763 | { | 3972 | { |
3764 | struct gspca_dev *gspca_dev; | 3973 | struct gspca_dev *gspca_dev; |
3765 | int qvga, crop; | 3974 | int qvga, crop; |
3766 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; | 3975 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; |
3767 | int ret; | ||
3768 | 3976 | ||
3769 | /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ | 3977 | /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ |
3770 | if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 || | 3978 | switch (sd->sensor) { |
3771 | sd->sensor == SEN_OV7670) | 3979 | case SEN_OV2610: |
3772 | return mode_init_ov_sensor_regs(sd); | 3980 | case SEN_OV3610: |
3981 | case SEN_OV7670: | ||
3982 | mode_init_ov_sensor_regs(sd); | ||
3983 | return; | ||
3984 | case SEN_OV7660: | ||
3985 | ov519_set_mode(sd); | ||
3986 | ov519_set_fr(sd); | ||
3987 | return; | ||
3988 | } | ||
3773 | 3989 | ||
3774 | gspca_dev = &sd->gspca_dev; | 3990 | gspca_dev = &sd->gspca_dev; |
3775 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; | 3991 | qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1; |
3776 | crop = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 2; | 3992 | crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2; |
3777 | 3993 | ||
3778 | /* The different sensor ICs handle setting up of window differently. | 3994 | /* The different sensor ICs handle setting up of window differently. |
3779 | * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ | 3995 | * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ |
@@ -3820,7 +4036,7 @@ static int set_ov_sensor_window(struct sd *sd) | |||
3820 | vwsbase = vwebase = 0x03; | 4036 | vwsbase = vwebase = 0x03; |
3821 | break; | 4037 | break; |
3822 | default: | 4038 | default: |
3823 | return -EINVAL; | 4039 | return; |
3824 | } | 4040 | } |
3825 | 4041 | ||
3826 | switch (sd->sensor) { | 4042 | switch (sd->sensor) { |
@@ -3855,23 +4071,18 @@ static int set_ov_sensor_window(struct sd *sd) | |||
3855 | } | 4071 | } |
3856 | } | 4072 | } |
3857 | 4073 | ||
3858 | ret = mode_init_ov_sensor_regs(sd); | 4074 | mode_init_ov_sensor_regs(sd); |
3859 | if (ret < 0) | ||
3860 | return ret; | ||
3861 | 4075 | ||
3862 | i2c_w(sd, 0x17, hwsbase); | 4076 | i2c_w(sd, 0x17, hwsbase); |
3863 | i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale)); | 4077 | i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale)); |
3864 | i2c_w(sd, 0x19, vwsbase); | 4078 | i2c_w(sd, 0x19, vwsbase); |
3865 | i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale)); | 4079 | i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale)); |
3866 | |||
3867 | return 0; | ||
3868 | } | 4080 | } |
3869 | 4081 | ||
3870 | /* -- start the camera -- */ | 4082 | /* -- start the camera -- */ |
3871 | static int sd_start(struct gspca_dev *gspca_dev) | 4083 | static int sd_start(struct gspca_dev *gspca_dev) |
3872 | { | 4084 | { |
3873 | struct sd *sd = (struct sd *) gspca_dev; | 4085 | struct sd *sd = (struct sd *) gspca_dev; |
3874 | int ret = 0; | ||
3875 | 4086 | ||
3876 | /* Default for most bridges, allow bridge_mode_init_regs to override */ | 4087 | /* Default for most bridges, allow bridge_mode_init_regs to override */ |
3877 | sd->sensor_width = sd->gspca_dev.width; | 4088 | sd->sensor_width = sd->gspca_dev.width; |
@@ -3880,50 +4091,46 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
3880 | switch (sd->bridge) { | 4091 | switch (sd->bridge) { |
3881 | case BRIDGE_OV511: | 4092 | case BRIDGE_OV511: |
3882 | case BRIDGE_OV511PLUS: | 4093 | case BRIDGE_OV511PLUS: |
3883 | ret = ov511_mode_init_regs(sd); | 4094 | ov511_mode_init_regs(sd); |
3884 | break; | 4095 | break; |
3885 | case BRIDGE_OV518: | 4096 | case BRIDGE_OV518: |
3886 | case BRIDGE_OV518PLUS: | 4097 | case BRIDGE_OV518PLUS: |
3887 | ret = ov518_mode_init_regs(sd); | 4098 | ov518_mode_init_regs(sd); |
3888 | break; | 4099 | break; |
3889 | case BRIDGE_OV519: | 4100 | case BRIDGE_OV519: |
3890 | ret = ov519_mode_init_regs(sd); | 4101 | ov519_mode_init_regs(sd); |
3891 | break; | 4102 | break; |
3892 | /* case BRIDGE_OVFX2: nothing to do */ | 4103 | /* case BRIDGE_OVFX2: nothing to do */ |
3893 | case BRIDGE_W9968CF: | 4104 | case BRIDGE_W9968CF: |
3894 | ret = w9968cf_mode_init_regs(sd); | 4105 | w9968cf_mode_init_regs(sd); |
3895 | break; | 4106 | break; |
3896 | } | 4107 | } |
3897 | if (ret < 0) | 4108 | |
3898 | goto out; | 4109 | set_ov_sensor_window(sd); |
3899 | 4110 | ||
3900 | ret = set_ov_sensor_window(sd); | 4111 | if (!(sd->gspca_dev.ctrl_dis & (1 << CONTRAST))) |
3901 | if (ret < 0) | 4112 | setcontrast(gspca_dev); |
3902 | goto out; | 4113 | if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS))) |
3903 | 4114 | setbrightness(gspca_dev); | |
3904 | setcontrast(gspca_dev); | 4115 | if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS))) |
3905 | setbrightness(gspca_dev); | 4116 | setcolors(gspca_dev); |
3906 | setcolors(gspca_dev); | 4117 | if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP)))) |
3907 | sethvflip(gspca_dev); | 4118 | sethvflip(gspca_dev); |
3908 | setautobright(gspca_dev); | 4119 | if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT))) |
3909 | setfreq_i(sd); | 4120 | setautobright(gspca_dev); |
4121 | if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ))) | ||
4122 | setfreq_i(sd); | ||
3910 | 4123 | ||
3911 | /* Force clear snapshot state in case the snapshot button was | 4124 | /* Force clear snapshot state in case the snapshot button was |
3912 | pressed while we weren't streaming */ | 4125 | pressed while we weren't streaming */ |
3913 | sd->snapshot_needs_reset = 1; | 4126 | sd->snapshot_needs_reset = 1; |
3914 | sd_reset_snapshot(gspca_dev); | 4127 | sd_reset_snapshot(gspca_dev); |
3915 | sd->snapshot_pressed = 0; | ||
3916 | 4128 | ||
3917 | sd->first_frame = 3; | 4129 | sd->first_frame = 3; |
3918 | 4130 | ||
3919 | ret = ov51x_restart(sd); | 4131 | ov51x_restart(sd); |
3920 | if (ret < 0) | ||
3921 | goto out; | ||
3922 | ov51x_led_control(sd, 1); | 4132 | ov51x_led_control(sd, 1); |
3923 | return 0; | 4133 | return gspca_dev->usb_err; |
3924 | out: | ||
3925 | PDEBUG(D_ERR, "camera start error:%d", ret); | ||
3926 | return ret; | ||
3927 | } | 4134 | } |
3928 | 4135 | ||
3929 | static void sd_stopN(struct gspca_dev *gspca_dev) | 4136 | static void sd_stopN(struct gspca_dev *gspca_dev) |
@@ -3938,8 +4145,21 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
3938 | { | 4145 | { |
3939 | struct sd *sd = (struct sd *) gspca_dev; | 4146 | struct sd *sd = (struct sd *) gspca_dev; |
3940 | 4147 | ||
4148 | if (!sd->gspca_dev.present) | ||
4149 | return; | ||
3941 | if (sd->bridge == BRIDGE_W9968CF) | 4150 | if (sd->bridge == BRIDGE_W9968CF) |
3942 | w9968cf_stop0(sd); | 4151 | w9968cf_stop0(sd); |
4152 | |||
4153 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | ||
4154 | /* If the last button state is pressed, release it now! */ | ||
4155 | if (sd->snapshot_pressed) { | ||
4156 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); | ||
4157 | input_sync(gspca_dev->input_dev); | ||
4158 | sd->snapshot_pressed = 0; | ||
4159 | } | ||
4160 | #endif | ||
4161 | if (sd->bridge == BRIDGE_OV519) | ||
4162 | reg_w(sd, OV519_R57_SNAPSHOT, 0x23); | ||
3943 | } | 4163 | } |
3944 | 4164 | ||
3945 | static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state) | 4165 | static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state) |
@@ -4160,6 +4380,22 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4160 | { | 4380 | { |
4161 | struct sd *sd = (struct sd *) gspca_dev; | 4381 | struct sd *sd = (struct sd *) gspca_dev; |
4162 | int val; | 4382 | int val; |
4383 | static const struct ov_i2c_regvals brit_7660[][7] = { | ||
4384 | {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90}, | ||
4385 | {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}}, | ||
4386 | {{0x0f, 0x6a}, {0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa1}, | ||
4387 | {0x27, 0xc0}, {0x28, 0xc0}, {0x2c, 0xc0}}, | ||
4388 | {{0x0f, 0x6a}, {0x24, 0x68}, {0x25, 0x58}, {0x26, 0xc2}, | ||
4389 | {0x27, 0xa0}, {0x28, 0xa0}, {0x2c, 0xa0}}, | ||
4390 | {{0x0f, 0x6a}, {0x24, 0x70}, {0x25, 0x68}, {0x26, 0xd3}, | ||
4391 | {0x27, 0x80}, {0x28, 0x80}, {0x2c, 0x80}}, | ||
4392 | {{0x0f, 0x6a}, {0x24, 0x80}, {0x25, 0x70}, {0x26, 0xd3}, | ||
4393 | {0x27, 0x20}, {0x28, 0x20}, {0x2c, 0x20}}, | ||
4394 | {{0x0f, 0x6a}, {0x24, 0x88}, {0x25, 0x78}, {0x26, 0xd3}, | ||
4395 | {0x27, 0x40}, {0x28, 0x40}, {0x2c, 0x40}}, | ||
4396 | {{0x0f, 0x6a}, {0x24, 0x90}, {0x25, 0x80}, {0x26, 0xd4}, | ||
4397 | {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}} | ||
4398 | }; | ||
4163 | 4399 | ||
4164 | val = sd->ctrls[BRIGHTNESS].val; | 4400 | val = sd->ctrls[BRIGHTNESS].val; |
4165 | switch (sd->sensor) { | 4401 | switch (sd->sensor) { |
@@ -4179,10 +4415,14 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4179 | if (!sd->ctrls[AUTOBRIGHT].val) | 4415 | if (!sd->ctrls[AUTOBRIGHT].val) |
4180 | i2c_w(sd, OV7610_REG_BRT, val); | 4416 | i2c_w(sd, OV7610_REG_BRT, val); |
4181 | break; | 4417 | break; |
4418 | case SEN_OV7660: | ||
4419 | write_i2c_regvals(sd, brit_7660[val], | ||
4420 | ARRAY_SIZE(brit_7660[0])); | ||
4421 | break; | ||
4182 | case SEN_OV7670: | 4422 | case SEN_OV7670: |
4183 | /*win trace | 4423 | /*win trace |
4184 | * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ | 4424 | * i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */ |
4185 | i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); | 4425 | i2c_w(sd, OV7670_R55_BRIGHT, ov7670_abs_to_sm(val)); |
4186 | break; | 4426 | break; |
4187 | } | 4427 | } |
4188 | } | 4428 | } |
@@ -4191,6 +4431,64 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4191 | { | 4431 | { |
4192 | struct sd *sd = (struct sd *) gspca_dev; | 4432 | struct sd *sd = (struct sd *) gspca_dev; |
4193 | int val; | 4433 | int val; |
4434 | static const struct ov_i2c_regvals contrast_7660[][31] = { | ||
4435 | {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0}, | ||
4436 | {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30}, | ||
4437 | {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x24}, {0x77, 0x24}, | ||
4438 | {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x34}, | ||
4439 | {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x65}, | ||
4440 | {0x80, 0x70}, {0x81, 0x77}, {0x82, 0x7d}, {0x83, 0x83}, | ||
4441 | {0x84, 0x88}, {0x85, 0x8d}, {0x86, 0x96}, {0x87, 0x9f}, | ||
4442 | {0x88, 0xb0}, {0x89, 0xc4}, {0x8a, 0xd9}}, | ||
4443 | {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0x94}, | ||
4444 | {0x70, 0x58}, {0x71, 0x40}, {0x72, 0x30}, {0x73, 0x30}, | ||
4445 | {0x74, 0x30}, {0x75, 0x30}, {0x76, 0x2c}, {0x77, 0x24}, | ||
4446 | {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x31}, | ||
4447 | {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x62}, | ||
4448 | {0x80, 0x6d}, {0x81, 0x75}, {0x82, 0x7b}, {0x83, 0x81}, | ||
4449 | {0x84, 0x87}, {0x85, 0x8d}, {0x86, 0x98}, {0x87, 0xa1}, | ||
4450 | {0x88, 0xb2}, {0x89, 0xc6}, {0x8a, 0xdb}}, | ||
4451 | {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x84}, | ||
4452 | {0x70, 0x58}, {0x71, 0x48}, {0x72, 0x40}, {0x73, 0x40}, | ||
4453 | {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x28}, {0x77, 0x24}, | ||
4454 | {0x78, 0x26}, {0x79, 0x28}, {0x7a, 0x28}, {0x7b, 0x34}, | ||
4455 | {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x5d}, | ||
4456 | {0x80, 0x68}, {0x81, 0x71}, {0x82, 0x79}, {0x83, 0x81}, | ||
4457 | {0x84, 0x86}, {0x85, 0x8b}, {0x86, 0x95}, {0x87, 0x9e}, | ||
4458 | {0x88, 0xb1}, {0x89, 0xc5}, {0x8a, 0xd9}}, | ||
4459 | {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x70}, | ||
4460 | {0x70, 0x58}, {0x71, 0x58}, {0x72, 0x48}, {0x73, 0x48}, | ||
4461 | {0x74, 0x38}, {0x75, 0x40}, {0x76, 0x34}, {0x77, 0x34}, | ||
4462 | {0x78, 0x2e}, {0x79, 0x28}, {0x7a, 0x24}, {0x7b, 0x22}, | ||
4463 | {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x58}, | ||
4464 | {0x80, 0x63}, {0x81, 0x6e}, {0x82, 0x77}, {0x83, 0x80}, | ||
4465 | {0x84, 0x87}, {0x85, 0x8f}, {0x86, 0x9c}, {0x87, 0xa9}, | ||
4466 | {0x88, 0xc0}, {0x89, 0xd4}, {0x8a, 0xe6}}, | ||
4467 | {{0x6c, 0xa0}, {0x6d, 0xf0}, {0x6e, 0x90}, {0x6f, 0x80}, | ||
4468 | {0x70, 0x70}, {0x71, 0x80}, {0x72, 0x60}, {0x73, 0x60}, | ||
4469 | {0x74, 0x58}, {0x75, 0x60}, {0x76, 0x4c}, {0x77, 0x38}, | ||
4470 | {0x78, 0x38}, {0x79, 0x2a}, {0x7a, 0x20}, {0x7b, 0x0e}, | ||
4471 | {0x7c, 0x0a}, {0x7d, 0x14}, {0x7e, 0x26}, {0x7f, 0x46}, | ||
4472 | {0x80, 0x54}, {0x81, 0x64}, {0x82, 0x70}, {0x83, 0x7c}, | ||
4473 | {0x84, 0x87}, {0x85, 0x93}, {0x86, 0xa6}, {0x87, 0xb4}, | ||
4474 | {0x88, 0xd0}, {0x89, 0xe5}, {0x8a, 0xf5}}, | ||
4475 | {{0x6c, 0x60}, {0x6d, 0x80}, {0x6e, 0x60}, {0x6f, 0x80}, | ||
4476 | {0x70, 0x80}, {0x71, 0x80}, {0x72, 0x88}, {0x73, 0x30}, | ||
4477 | {0x74, 0x70}, {0x75, 0x68}, {0x76, 0x64}, {0x77, 0x50}, | ||
4478 | {0x78, 0x3c}, {0x79, 0x22}, {0x7a, 0x10}, {0x7b, 0x08}, | ||
4479 | {0x7c, 0x06}, {0x7d, 0x0e}, {0x7e, 0x1a}, {0x7f, 0x3a}, | ||
4480 | {0x80, 0x4a}, {0x81, 0x5a}, {0x82, 0x6b}, {0x83, 0x7b}, | ||
4481 | {0x84, 0x89}, {0x85, 0x96}, {0x86, 0xaf}, {0x87, 0xc3}, | ||
4482 | {0x88, 0xe1}, {0x89, 0xf2}, {0x8a, 0xfa}}, | ||
4483 | {{0x6c, 0x20}, {0x6d, 0x40}, {0x6e, 0x20}, {0x6f, 0x60}, | ||
4484 | {0x70, 0x88}, {0x71, 0xc8}, {0x72, 0xc0}, {0x73, 0xb8}, | ||
4485 | {0x74, 0xa8}, {0x75, 0xb8}, {0x76, 0x80}, {0x77, 0x5c}, | ||
4486 | {0x78, 0x26}, {0x79, 0x10}, {0x7a, 0x08}, {0x7b, 0x04}, | ||
4487 | {0x7c, 0x02}, {0x7d, 0x06}, {0x7e, 0x0a}, {0x7f, 0x22}, | ||
4488 | {0x80, 0x33}, {0x81, 0x4c}, {0x82, 0x64}, {0x83, 0x7b}, | ||
4489 | {0x84, 0x90}, {0x85, 0xa7}, {0x86, 0xc7}, {0x87, 0xde}, | ||
4490 | {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}}, | ||
4491 | }; | ||
4194 | 4492 | ||
4195 | val = sd->ctrls[CONTRAST].val; | 4493 | val = sd->ctrls[CONTRAST].val; |
4196 | switch (sd->sensor) { | 4494 | switch (sd->sensor) { |
@@ -4203,7 +4501,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4203 | i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); | 4501 | i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); |
4204 | break; | 4502 | break; |
4205 | case SEN_OV8610: { | 4503 | case SEN_OV8610: { |
4206 | static const __u8 ctab[] = { | 4504 | static const u8 ctab[] = { |
4207 | 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f | 4505 | 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f |
4208 | }; | 4506 | }; |
4209 | 4507 | ||
@@ -4213,7 +4511,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4213 | } | 4511 | } |
4214 | case SEN_OV7620: | 4512 | case SEN_OV7620: |
4215 | case SEN_OV7620AE: { | 4513 | case SEN_OV7620AE: { |
4216 | static const __u8 ctab[] = { | 4514 | static const u8 ctab[] = { |
4217 | 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, | 4515 | 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, |
4218 | 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff | 4516 | 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff |
4219 | }; | 4517 | }; |
@@ -4222,9 +4520,13 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4222 | i2c_w(sd, 0x64, ctab[val >> 4]); | 4520 | i2c_w(sd, 0x64, ctab[val >> 4]); |
4223 | break; | 4521 | break; |
4224 | } | 4522 | } |
4523 | case SEN_OV7660: | ||
4524 | write_i2c_regvals(sd, contrast_7660[val], | ||
4525 | ARRAY_SIZE(contrast_7660[0])); | ||
4526 | break; | ||
4225 | case SEN_OV7670: | 4527 | case SEN_OV7670: |
4226 | /* check that this isn't just the same as ov7610 */ | 4528 | /* check that this isn't just the same as ov7610 */ |
4227 | i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); | 4529 | i2c_w(sd, OV7670_R56_CONTRAS, val >> 1); |
4228 | break; | 4530 | break; |
4229 | } | 4531 | } |
4230 | } | 4532 | } |
@@ -4233,6 +4535,18 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4233 | { | 4535 | { |
4234 | struct sd *sd = (struct sd *) gspca_dev; | 4536 | struct sd *sd = (struct sd *) gspca_dev; |
4235 | int val; | 4537 | int val; |
4538 | static const struct ov_i2c_regvals colors_7660[][6] = { | ||
4539 | {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a}, | ||
4540 | {0x53, 0x19}, {0x54, 0x23}}, | ||
4541 | {{0x4f, 0x47}, {0x50, 0x4a}, {0x51, 0x03}, {0x52, 0x11}, | ||
4542 | {0x53, 0x2c}, {0x54, 0x3e}}, | ||
4543 | {{0x4f, 0x66}, {0x50, 0x6b}, {0x51, 0x05}, {0x52, 0x19}, | ||
4544 | {0x53, 0x40}, {0x54, 0x59}}, | ||
4545 | {{0x4f, 0x84}, {0x50, 0x8b}, {0x51, 0x06}, {0x52, 0x20}, | ||
4546 | {0x53, 0x53}, {0x54, 0x73}}, | ||
4547 | {{0x4f, 0xa3}, {0x50, 0xab}, {0x51, 0x08}, {0x52, 0x28}, | ||
4548 | {0x53, 0x66}, {0x54, 0x8e}}, | ||
4549 | }; | ||
4236 | 4550 | ||
4237 | val = sd->ctrls[COLORS].val; | 4551 | val = sd->ctrls[COLORS].val; |
4238 | switch (sd->sensor) { | 4552 | switch (sd->sensor) { |
@@ -4256,6 +4570,10 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4256 | case SEN_OV7648: | 4570 | case SEN_OV7648: |
4257 | i2c_w(sd, OV7610_REG_SAT, val & 0xf0); | 4571 | i2c_w(sd, OV7610_REG_SAT, val & 0xf0); |
4258 | break; | 4572 | break; |
4573 | case SEN_OV7660: | ||
4574 | write_i2c_regvals(sd, colors_7660[val], | ||
4575 | ARRAY_SIZE(colors_7660[0])); | ||
4576 | break; | ||
4259 | case SEN_OV7670: | 4577 | case SEN_OV7670: |
4260 | /* supported later once I work out how to do it | 4578 | /* supported later once I work out how to do it |
4261 | * transparently fail now! */ | 4579 | * transparently fail now! */ |
@@ -4268,38 +4586,31 @@ static void setautobright(struct gspca_dev *gspca_dev) | |||
4268 | { | 4586 | { |
4269 | struct sd *sd = (struct sd *) gspca_dev; | 4587 | struct sd *sd = (struct sd *) gspca_dev; |
4270 | 4588 | ||
4271 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 || | ||
4272 | sd->sensor == SEN_OV7670 || | ||
4273 | sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | ||
4274 | return; | ||
4275 | |||
4276 | i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10); | 4589 | i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10); |
4277 | } | 4590 | } |
4278 | 4591 | ||
4279 | static void setfreq_i(struct sd *sd) | 4592 | static void setfreq_i(struct sd *sd) |
4280 | { | 4593 | { |
4281 | if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | 4594 | if (sd->sensor == SEN_OV7660 |
4282 | return; | 4595 | || sd->sensor == SEN_OV7670) { |
4283 | |||
4284 | if (sd->sensor == SEN_OV7670) { | ||
4285 | switch (sd->ctrls[FREQ].val) { | 4596 | switch (sd->ctrls[FREQ].val) { |
4286 | case 0: /* Banding filter disabled */ | 4597 | case 0: /* Banding filter disabled */ |
4287 | i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_BFILT); | 4598 | i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT); |
4288 | break; | 4599 | break; |
4289 | case 1: /* 50 hz */ | 4600 | case 1: /* 50 hz */ |
4290 | i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT, | 4601 | i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT, |
4291 | OV7670_COM8_BFILT); | 4602 | OV7670_COM8_BFILT); |
4292 | i2c_w_mask(sd, OV7670_REG_COM11, 0x08, 0x18); | 4603 | i2c_w_mask(sd, OV7670_R3B_COM11, 0x08, 0x18); |
4293 | break; | 4604 | break; |
4294 | case 2: /* 60 hz */ | 4605 | case 2: /* 60 hz */ |
4295 | i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT, | 4606 | i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT, |
4296 | OV7670_COM8_BFILT); | 4607 | OV7670_COM8_BFILT); |
4297 | i2c_w_mask(sd, OV7670_REG_COM11, 0x00, 0x18); | 4608 | i2c_w_mask(sd, OV7670_R3B_COM11, 0x00, 0x18); |
4298 | break; | 4609 | break; |
4299 | case 3: /* Auto hz */ | 4610 | case 3: /* Auto hz - ov7670 only */ |
4300 | i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT, | 4611 | i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT, |
4301 | OV7670_COM8_BFILT); | 4612 | OV7670_COM8_BFILT); |
4302 | i2c_w_mask(sd, OV7670_REG_COM11, OV7670_COM11_HZAUTO, | 4613 | i2c_w_mask(sd, OV7670_R3B_COM11, OV7670_COM11_HZAUTO, |
4303 | 0x18); | 4614 | 0x18); |
4304 | break; | 4615 | break; |
4305 | } | 4616 | } |
@@ -4443,14 +4754,14 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
4443 | {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, | 4754 | {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, |
4444 | {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, | 4755 | {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, |
4445 | {USB_DEVICE(0x041e, 0x4064), | 4756 | {USB_DEVICE(0x041e, 0x4064), |
4446 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, | 4757 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, |
4447 | {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 }, | 4758 | {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 }, |
4448 | {USB_DEVICE(0x041e, 0x4068), | 4759 | {USB_DEVICE(0x041e, 0x4068), |
4449 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, | 4760 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, |
4450 | {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, | 4761 | {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, |
4451 | {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 }, | 4762 | {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 }, |
4452 | {USB_DEVICE(0x054c, 0x0155), | 4763 | {USB_DEVICE(0x054c, 0x0155), |
4453 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, | 4764 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, |
4454 | {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 }, | 4765 | {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 }, |
4455 | {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, | 4766 | {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, |
4456 | {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, | 4767 | {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, |
@@ -4464,7 +4775,7 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
4464 | {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 }, | 4775 | {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 }, |
4465 | {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 }, | 4776 | {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 }, |
4466 | {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF }, | 4777 | {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF }, |
4467 | {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 }, | 4778 | {USB_DEVICE(0x8020, 0xef04), .driver_info = BRIDGE_OVFX2 }, |
4468 | {} | 4779 | {} |
4469 | }; | 4780 | }; |
4470 | 4781 | ||
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 88ef03f6235b..0edf93973b1c 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c | |||
@@ -1243,34 +1243,26 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, | |||
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | /* get stream parameters (framerate) */ | 1245 | /* get stream parameters (framerate) */ |
1246 | static int sd_get_streamparm(struct gspca_dev *gspca_dev, | 1246 | static void sd_get_streamparm(struct gspca_dev *gspca_dev, |
1247 | struct v4l2_streamparm *parm) | 1247 | struct v4l2_streamparm *parm) |
1248 | { | 1248 | { |
1249 | struct v4l2_captureparm *cp = &parm->parm.capture; | 1249 | struct v4l2_captureparm *cp = &parm->parm.capture; |
1250 | struct v4l2_fract *tpf = &cp->timeperframe; | 1250 | struct v4l2_fract *tpf = &cp->timeperframe; |
1251 | struct sd *sd = (struct sd *) gspca_dev; | 1251 | struct sd *sd = (struct sd *) gspca_dev; |
1252 | 1252 | ||
1253 | if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1254 | return -EINVAL; | ||
1255 | |||
1256 | cp->capability |= V4L2_CAP_TIMEPERFRAME; | 1253 | cp->capability |= V4L2_CAP_TIMEPERFRAME; |
1257 | tpf->numerator = 1; | 1254 | tpf->numerator = 1; |
1258 | tpf->denominator = sd->frame_rate; | 1255 | tpf->denominator = sd->frame_rate; |
1259 | |||
1260 | return 0; | ||
1261 | } | 1256 | } |
1262 | 1257 | ||
1263 | /* set stream parameters (framerate) */ | 1258 | /* set stream parameters (framerate) */ |
1264 | static int sd_set_streamparm(struct gspca_dev *gspca_dev, | 1259 | static void sd_set_streamparm(struct gspca_dev *gspca_dev, |
1265 | struct v4l2_streamparm *parm) | 1260 | struct v4l2_streamparm *parm) |
1266 | { | 1261 | { |
1267 | struct v4l2_captureparm *cp = &parm->parm.capture; | 1262 | struct v4l2_captureparm *cp = &parm->parm.capture; |
1268 | struct v4l2_fract *tpf = &cp->timeperframe; | 1263 | struct v4l2_fract *tpf = &cp->timeperframe; |
1269 | struct sd *sd = (struct sd *) gspca_dev; | 1264 | struct sd *sd = (struct sd *) gspca_dev; |
1270 | 1265 | ||
1271 | if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1272 | return -EINVAL; | ||
1273 | |||
1274 | /* Set requested framerate */ | 1266 | /* Set requested framerate */ |
1275 | sd->frame_rate = tpf->denominator / tpf->numerator; | 1267 | sd->frame_rate = tpf->denominator / tpf->numerator; |
1276 | if (gspca_dev->streaming) | 1268 | if (gspca_dev->streaming) |
@@ -1279,8 +1271,6 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev, | |||
1279 | /* Return the actual framerate */ | 1271 | /* Return the actual framerate */ |
1280 | tpf->numerator = 1; | 1272 | tpf->numerator = 1; |
1281 | tpf->denominator = sd->frame_rate; | 1273 | tpf->denominator = sd->frame_rate; |
1282 | |||
1283 | return 0; | ||
1284 | } | 1274 | } |
1285 | 1275 | ||
1286 | /* sub-driver description */ | 1276 | /* sub-driver description */ |
diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c index e831f0d280ea..c5244b4b4777 100644 --- a/drivers/media/video/gspca/ov534_9.c +++ b/drivers/media/video/gspca/ov534_9.c | |||
@@ -945,7 +945,6 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
945 | u8 val; | 945 | u8 val; |
946 | 946 | ||
947 | /*fixme: should adjust agc/awb/aec by different controls */ | 947 | /*fixme: should adjust agc/awb/aec by different controls */ |
948 | val = sd->autogain; | ||
949 | val = sccb_read(gspca_dev, 0x13); /* com8 */ | 948 | val = sccb_read(gspca_dev, 0x13); /* com8 */ |
950 | sccb_write(gspca_dev, 0xff, 0x00); | 949 | sccb_write(gspca_dev, 0xff, 0x00); |
951 | if (sd->autogain) | 950 | if (sd->autogain) |
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 15e97fa4c337..96f9986305b4 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c | |||
@@ -162,7 +162,7 @@ static const __u8 pac207_sensor_init[][8] = { | |||
162 | {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0x84}, | 162 | {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0x84}, |
163 | {0x49, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30}, | 163 | {0x49, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30}, |
164 | {0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00}, | 164 | {0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00}, |
165 | {0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00}, | 165 | {0x32, 0x00, 0x96, 0x00, 0xa2, 0x02, 0xaf, 0x00}, |
166 | }; | 166 | }; |
167 | 167 | ||
168 | static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, | 168 | static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, |
@@ -228,7 +228,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
228 | 228 | ||
229 | idreg[0] = pac207_read_reg(gspca_dev, 0x0000); | 229 | idreg[0] = pac207_read_reg(gspca_dev, 0x0000); |
230 | idreg[1] = pac207_read_reg(gspca_dev, 0x0001); | 230 | idreg[1] = pac207_read_reg(gspca_dev, 0x0001); |
231 | idreg[0] = ((idreg[0] & 0x0F) << 4) | ((idreg[1] & 0xf0) >> 4); | 231 | idreg[0] = ((idreg[0] & 0x0f) << 4) | ((idreg[1] & 0xf0) >> 4); |
232 | idreg[1] = idreg[1] & 0x0f; | 232 | idreg[1] = idreg[1] & 0x0f; |
233 | PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X", | 233 | PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X", |
234 | idreg[0], idreg[1]); | 234 | idreg[0], idreg[1]); |
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index 55fbea7381b0..2700975abce5 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c | |||
@@ -393,7 +393,7 @@ static const __u8 page3_7302[] = { | |||
393 | 393 | ||
394 | static void reg_w_buf(struct gspca_dev *gspca_dev, | 394 | static void reg_w_buf(struct gspca_dev *gspca_dev, |
395 | __u8 index, | 395 | __u8 index, |
396 | const char *buffer, int len) | 396 | const u8 *buffer, int len) |
397 | { | 397 | { |
398 | int ret; | 398 | int ret; |
399 | 399 | ||
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 7657b43b3203..6820f5d58b19 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c | |||
@@ -261,7 +261,7 @@ static const __u8 page4_7311[] = { | |||
261 | 261 | ||
262 | static void reg_w_buf(struct gspca_dev *gspca_dev, | 262 | static void reg_w_buf(struct gspca_dev *gspca_dev, |
263 | __u8 index, | 263 | __u8 index, |
264 | const char *buffer, int len) | 264 | const u8 *buffer, int len) |
265 | { | 265 | { |
266 | int ret; | 266 | int ret; |
267 | 267 | ||
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index 6b155ae3a746..cb08d00d0a31 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c | |||
@@ -33,6 +33,14 @@ MODULE_LICENSE("GPL"); | |||
33 | 33 | ||
34 | #define MODULE_NAME "sn9c20x" | 34 | #define MODULE_NAME "sn9c20x" |
35 | 35 | ||
36 | /* | ||
37 | * Pixel format private data | ||
38 | */ | ||
39 | #define SCALE_MASK 0x0f | ||
40 | #define SCALE_160x120 0 | ||
41 | #define SCALE_320x240 1 | ||
42 | #define SCALE_640x480 2 | ||
43 | #define SCALE_1280x1024 3 | ||
36 | #define MODE_RAW 0x10 | 44 | #define MODE_RAW 0x10 |
37 | #define MODE_JPEG 0x20 | 45 | #define MODE_JPEG 0x20 |
38 | #define MODE_SXGA 0x80 | 46 | #define MODE_SXGA 0x80 |
@@ -348,47 +356,47 @@ static const struct v4l2_pix_format vga_mode[] = { | |||
348 | .bytesperline = 160, | 356 | .bytesperline = 160, |
349 | .sizeimage = 160 * 120 * 4 / 8 + 590, | 357 | .sizeimage = 160 * 120 * 4 / 8 + 590, |
350 | .colorspace = V4L2_COLORSPACE_JPEG, | 358 | .colorspace = V4L2_COLORSPACE_JPEG, |
351 | .priv = 0 | MODE_JPEG}, | 359 | .priv = SCALE_160x120 | MODE_JPEG}, |
352 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 360 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
353 | .bytesperline = 160, | 361 | .bytesperline = 160, |
354 | .sizeimage = 160 * 120, | 362 | .sizeimage = 160 * 120, |
355 | .colorspace = V4L2_COLORSPACE_SRGB, | 363 | .colorspace = V4L2_COLORSPACE_SRGB, |
356 | .priv = 0 | MODE_RAW}, | 364 | .priv = SCALE_160x120 | MODE_RAW}, |
357 | {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | 365 | {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, |
358 | .bytesperline = 160, | 366 | .bytesperline = 160, |
359 | .sizeimage = 240 * 120, | 367 | .sizeimage = 240 * 120, |
360 | .colorspace = V4L2_COLORSPACE_SRGB, | 368 | .colorspace = V4L2_COLORSPACE_SRGB, |
361 | .priv = 0}, | 369 | .priv = SCALE_160x120}, |
362 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 370 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
363 | .bytesperline = 320, | 371 | .bytesperline = 320, |
364 | .sizeimage = 320 * 240 * 3 / 8 + 590, | 372 | .sizeimage = 320 * 240 * 3 / 8 + 590, |
365 | .colorspace = V4L2_COLORSPACE_JPEG, | 373 | .colorspace = V4L2_COLORSPACE_JPEG, |
366 | .priv = 1 | MODE_JPEG}, | 374 | .priv = SCALE_320x240 | MODE_JPEG}, |
367 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 375 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
368 | .bytesperline = 320, | 376 | .bytesperline = 320, |
369 | .sizeimage = 320 * 240 , | 377 | .sizeimage = 320 * 240 , |
370 | .colorspace = V4L2_COLORSPACE_SRGB, | 378 | .colorspace = V4L2_COLORSPACE_SRGB, |
371 | .priv = 1 | MODE_RAW}, | 379 | .priv = SCALE_320x240 | MODE_RAW}, |
372 | {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | 380 | {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, |
373 | .bytesperline = 320, | 381 | .bytesperline = 320, |
374 | .sizeimage = 480 * 240 , | 382 | .sizeimage = 480 * 240 , |
375 | .colorspace = V4L2_COLORSPACE_SRGB, | 383 | .colorspace = V4L2_COLORSPACE_SRGB, |
376 | .priv = 1}, | 384 | .priv = SCALE_320x240}, |
377 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 385 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
378 | .bytesperline = 640, | 386 | .bytesperline = 640, |
379 | .sizeimage = 640 * 480 * 3 / 8 + 590, | 387 | .sizeimage = 640 * 480 * 3 / 8 + 590, |
380 | .colorspace = V4L2_COLORSPACE_JPEG, | 388 | .colorspace = V4L2_COLORSPACE_JPEG, |
381 | .priv = 2 | MODE_JPEG}, | 389 | .priv = SCALE_640x480 | MODE_JPEG}, |
382 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 390 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
383 | .bytesperline = 640, | 391 | .bytesperline = 640, |
384 | .sizeimage = 640 * 480, | 392 | .sizeimage = 640 * 480, |
385 | .colorspace = V4L2_COLORSPACE_SRGB, | 393 | .colorspace = V4L2_COLORSPACE_SRGB, |
386 | .priv = 2 | MODE_RAW}, | 394 | .priv = SCALE_640x480 | MODE_RAW}, |
387 | {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | 395 | {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, |
388 | .bytesperline = 640, | 396 | .bytesperline = 640, |
389 | .sizeimage = 960 * 480, | 397 | .sizeimage = 960 * 480, |
390 | .colorspace = V4L2_COLORSPACE_SRGB, | 398 | .colorspace = V4L2_COLORSPACE_SRGB, |
391 | .priv = 2}, | 399 | .priv = SCALE_640x480}, |
392 | }; | 400 | }; |
393 | 401 | ||
394 | static const struct v4l2_pix_format sxga_mode[] = { | 402 | static const struct v4l2_pix_format sxga_mode[] = { |
@@ -396,52 +404,75 @@ static const struct v4l2_pix_format sxga_mode[] = { | |||
396 | .bytesperline = 160, | 404 | .bytesperline = 160, |
397 | .sizeimage = 160 * 120 * 4 / 8 + 590, | 405 | .sizeimage = 160 * 120 * 4 / 8 + 590, |
398 | .colorspace = V4L2_COLORSPACE_JPEG, | 406 | .colorspace = V4L2_COLORSPACE_JPEG, |
399 | .priv = 0 | MODE_JPEG}, | 407 | .priv = SCALE_160x120 | MODE_JPEG}, |
400 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 408 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
401 | .bytesperline = 160, | 409 | .bytesperline = 160, |
402 | .sizeimage = 160 * 120, | 410 | .sizeimage = 160 * 120, |
403 | .colorspace = V4L2_COLORSPACE_SRGB, | 411 | .colorspace = V4L2_COLORSPACE_SRGB, |
404 | .priv = 0 | MODE_RAW}, | 412 | .priv = SCALE_160x120 | MODE_RAW}, |
405 | {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | 413 | {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, |
406 | .bytesperline = 160, | 414 | .bytesperline = 160, |
407 | .sizeimage = 240 * 120, | 415 | .sizeimage = 240 * 120, |
408 | .colorspace = V4L2_COLORSPACE_SRGB, | 416 | .colorspace = V4L2_COLORSPACE_SRGB, |
409 | .priv = 0}, | 417 | .priv = SCALE_160x120}, |
410 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 418 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
411 | .bytesperline = 320, | 419 | .bytesperline = 320, |
412 | .sizeimage = 320 * 240 * 3 / 8 + 590, | 420 | .sizeimage = 320 * 240 * 3 / 8 + 590, |
413 | .colorspace = V4L2_COLORSPACE_JPEG, | 421 | .colorspace = V4L2_COLORSPACE_JPEG, |
414 | .priv = 1 | MODE_JPEG}, | 422 | .priv = SCALE_320x240 | MODE_JPEG}, |
415 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 423 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
416 | .bytesperline = 320, | 424 | .bytesperline = 320, |
417 | .sizeimage = 320 * 240 , | 425 | .sizeimage = 320 * 240 , |
418 | .colorspace = V4L2_COLORSPACE_SRGB, | 426 | .colorspace = V4L2_COLORSPACE_SRGB, |
419 | .priv = 1 | MODE_RAW}, | 427 | .priv = SCALE_320x240 | MODE_RAW}, |
420 | {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | 428 | {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, |
421 | .bytesperline = 320, | 429 | .bytesperline = 320, |
422 | .sizeimage = 480 * 240 , | 430 | .sizeimage = 480 * 240 , |
423 | .colorspace = V4L2_COLORSPACE_SRGB, | 431 | .colorspace = V4L2_COLORSPACE_SRGB, |
424 | .priv = 1}, | 432 | .priv = SCALE_320x240}, |
425 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 433 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
426 | .bytesperline = 640, | 434 | .bytesperline = 640, |
427 | .sizeimage = 640 * 480 * 3 / 8 + 590, | 435 | .sizeimage = 640 * 480 * 3 / 8 + 590, |
428 | .colorspace = V4L2_COLORSPACE_JPEG, | 436 | .colorspace = V4L2_COLORSPACE_JPEG, |
429 | .priv = 2 | MODE_JPEG}, | 437 | .priv = SCALE_640x480 | MODE_JPEG}, |
430 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 438 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
431 | .bytesperline = 640, | 439 | .bytesperline = 640, |
432 | .sizeimage = 640 * 480, | 440 | .sizeimage = 640 * 480, |
433 | .colorspace = V4L2_COLORSPACE_SRGB, | 441 | .colorspace = V4L2_COLORSPACE_SRGB, |
434 | .priv = 2 | MODE_RAW}, | 442 | .priv = SCALE_640x480 | MODE_RAW}, |
435 | {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | 443 | {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, |
436 | .bytesperline = 640, | 444 | .bytesperline = 640, |
437 | .sizeimage = 960 * 480, | 445 | .sizeimage = 960 * 480, |
438 | .colorspace = V4L2_COLORSPACE_SRGB, | 446 | .colorspace = V4L2_COLORSPACE_SRGB, |
439 | .priv = 2}, | 447 | .priv = SCALE_640x480}, |
440 | {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 448 | {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
441 | .bytesperline = 1280, | 449 | .bytesperline = 1280, |
442 | .sizeimage = 1280 * 1024, | 450 | .sizeimage = 1280 * 1024, |
443 | .colorspace = V4L2_COLORSPACE_SRGB, | 451 | .colorspace = V4L2_COLORSPACE_SRGB, |
444 | .priv = 3 | MODE_RAW | MODE_SXGA}, | 452 | .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA}, |
453 | }; | ||
454 | |||
455 | static const struct v4l2_pix_format mono_mode[] = { | ||
456 | {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, | ||
457 | .bytesperline = 160, | ||
458 | .sizeimage = 160 * 120, | ||
459 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
460 | .priv = SCALE_160x120 | MODE_RAW}, | ||
461 | {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, | ||
462 | .bytesperline = 320, | ||
463 | .sizeimage = 320 * 240 , | ||
464 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
465 | .priv = SCALE_320x240 | MODE_RAW}, | ||
466 | {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, | ||
467 | .bytesperline = 640, | ||
468 | .sizeimage = 640 * 480, | ||
469 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
470 | .priv = SCALE_640x480 | MODE_RAW}, | ||
471 | {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, | ||
472 | .bytesperline = 1280, | ||
473 | .sizeimage = 1280 * 1024, | ||
474 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
475 | .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA}, | ||
445 | }; | 476 | }; |
446 | 477 | ||
447 | static const s16 hsv_red_x[] = { | 478 | static const s16 hsv_red_x[] = { |
@@ -1029,16 +1060,19 @@ static struct i2c_reg_u16 mt9v011_init[] = { | |||
1029 | }; | 1060 | }; |
1030 | 1061 | ||
1031 | static struct i2c_reg_u16 mt9m001_init[] = { | 1062 | static struct i2c_reg_u16 mt9m001_init[] = { |
1032 | {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e}, | 1063 | {0x0d, 0x0001}, |
1033 | {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501}, | 1064 | {0x0d, 0x0000}, |
1034 | {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002}, | 1065 | {0x04, 0x0500}, /* hres = 1280 */ |
1035 | {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000}, | 1066 | {0x03, 0x0400}, /* vres = 1024 */ |
1036 | {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000}, | 1067 | {0x20, 0x1100}, |
1037 | {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000}, | 1068 | {0x06, 0x0010}, |
1038 | {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2}, | 1069 | {0x2b, 0x0024}, |
1039 | {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003}, | 1070 | {0x2e, 0x0024}, |
1040 | {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a}, | 1071 | {0x35, 0x0024}, |
1041 | {0x2e, 0x0029}, {0x07, 0x0002}, | 1072 | {0x2d, 0x0020}, |
1073 | {0x2c, 0x0020}, | ||
1074 | {0x09, 0x0ad4}, | ||
1075 | {0x35, 0x0057}, | ||
1042 | }; | 1076 | }; |
1043 | 1077 | ||
1044 | static struct i2c_reg_u16 mt9m111_init[] = { | 1078 | static struct i2c_reg_u16 mt9m111_init[] = { |
@@ -1224,8 +1258,17 @@ static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) | |||
1224 | static int ov9650_init_sensor(struct gspca_dev *gspca_dev) | 1258 | static int ov9650_init_sensor(struct gspca_dev *gspca_dev) |
1225 | { | 1259 | { |
1226 | int i; | 1260 | int i; |
1261 | u16 id; | ||
1227 | struct sd *sd = (struct sd *) gspca_dev; | 1262 | struct sd *sd = (struct sd *) gspca_dev; |
1228 | 1263 | ||
1264 | if (i2c_r2(gspca_dev, 0x1c, &id) < 0) | ||
1265 | return -EINVAL; | ||
1266 | |||
1267 | if (id != 0x7fa2) { | ||
1268 | err("sensor id for ov9650 doesn't match (0x%04x)", id); | ||
1269 | return -ENODEV; | ||
1270 | } | ||
1271 | |||
1229 | for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) { | 1272 | for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) { |
1230 | if (i2c_w1(gspca_dev, ov9650_init[i].reg, | 1273 | if (i2c_w1(gspca_dev, ov9650_init[i].reg, |
1231 | ov9650_init[i].val) < 0) { | 1274 | ov9650_init[i].val) < 0) { |
@@ -1425,6 +1468,25 @@ static int mt9m001_init_sensor(struct gspca_dev *gspca_dev) | |||
1425 | { | 1468 | { |
1426 | struct sd *sd = (struct sd *) gspca_dev; | 1469 | struct sd *sd = (struct sd *) gspca_dev; |
1427 | int i; | 1470 | int i; |
1471 | u16 id; | ||
1472 | |||
1473 | if (i2c_r2(gspca_dev, 0x00, &id) < 0) | ||
1474 | return -EINVAL; | ||
1475 | |||
1476 | /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ | ||
1477 | switch (id) { | ||
1478 | case 0x8411: | ||
1479 | case 0x8421: | ||
1480 | info("MT9M001 color sensor detected"); | ||
1481 | break; | ||
1482 | case 0x8431: | ||
1483 | info("MT9M001 mono sensor detected"); | ||
1484 | break; | ||
1485 | default: | ||
1486 | err("No MT9M001 chip detected, ID = %x\n", id); | ||
1487 | return -ENODEV; | ||
1488 | } | ||
1489 | |||
1428 | for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) { | 1490 | for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) { |
1429 | if (i2c_w2(gspca_dev, mt9m001_init[i].reg, | 1491 | if (i2c_w2(gspca_dev, mt9m001_init[i].reg, |
1430 | mt9m001_init[i].val) < 0) { | 1492 | mt9m001_init[i].val) < 0) { |
@@ -1434,8 +1496,8 @@ static int mt9m001_init_sensor(struct gspca_dev *gspca_dev) | |||
1434 | } | 1496 | } |
1435 | /* disable hflip and vflip */ | 1497 | /* disable hflip and vflip */ |
1436 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); | 1498 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); |
1437 | sd->hstart = 2; | 1499 | sd->hstart = 1; |
1438 | sd->vstart = 2; | 1500 | sd->vstart = 1; |
1439 | return 0; | 1501 | return 0; |
1440 | } | 1502 | } |
1441 | 1503 | ||
@@ -1977,6 +2039,10 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1977 | cam->cam_mode = sxga_mode; | 2039 | cam->cam_mode = sxga_mode; |
1978 | cam->nmodes = ARRAY_SIZE(sxga_mode); | 2040 | cam->nmodes = ARRAY_SIZE(sxga_mode); |
1979 | break; | 2041 | break; |
2042 | case SENSOR_MT9M001: | ||
2043 | cam->cam_mode = mono_mode; | ||
2044 | cam->nmodes = ARRAY_SIZE(mono_mode); | ||
2045 | break; | ||
1980 | default: | 2046 | default: |
1981 | cam->cam_mode = vga_mode; | 2047 | cam->cam_mode = vga_mode; |
1982 | cam->nmodes = ARRAY_SIZE(vga_mode); | 2048 | cam->nmodes = ARRAY_SIZE(vga_mode); |
@@ -2075,7 +2141,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
2075 | case SENSOR_MT9M001: | 2141 | case SENSOR_MT9M001: |
2076 | if (mt9m001_init_sensor(gspca_dev) < 0) | 2142 | if (mt9m001_init_sensor(gspca_dev) < 0) |
2077 | return -ENODEV; | 2143 | return -ENODEV; |
2078 | info("MT9M001 sensor detected"); | ||
2079 | break; | 2144 | break; |
2080 | case SENSOR_HV7131R: | 2145 | case SENSOR_HV7131R: |
2081 | if (hv7131r_init_sensor(gspca_dev) < 0) | 2146 | if (hv7131r_init_sensor(gspca_dev) < 0) |
@@ -2173,22 +2238,22 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2173 | else if (mode & MODE_JPEG) | 2238 | else if (mode & MODE_JPEG) |
2174 | fmt = 0x2c; | 2239 | fmt = 0x2c; |
2175 | else | 2240 | else |
2176 | fmt = 0x2f; | 2241 | fmt = 0x2f; /* YUV 420 */ |
2177 | 2242 | ||
2178 | switch (mode & 0x0f) { | 2243 | switch (mode & SCALE_MASK) { |
2179 | case 3: | 2244 | case SCALE_1280x1024: |
2180 | scale = 0xc0; | 2245 | scale = 0xc0; |
2181 | info("Set 1280x1024"); | 2246 | info("Set 1280x1024"); |
2182 | break; | 2247 | break; |
2183 | case 2: | 2248 | case SCALE_640x480: |
2184 | scale = 0x80; | 2249 | scale = 0x80; |
2185 | info("Set 640x480"); | 2250 | info("Set 640x480"); |
2186 | break; | 2251 | break; |
2187 | case 1: | 2252 | case SCALE_320x240: |
2188 | scale = 0x90; | 2253 | scale = 0x90; |
2189 | info("Set 320x240"); | 2254 | info("Set 320x240"); |
2190 | break; | 2255 | break; |
2191 | case 0: | 2256 | case SCALE_160x120: |
2192 | scale = 0xa0; | 2257 | scale = 0xa0; |
2193 | info("Set 160x120"); | 2258 | info("Set 160x120"); |
2194 | break; | 2259 | break; |
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 706f96f92654..73504a3f87b7 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -56,6 +56,8 @@ struct sd { | |||
56 | int prev_avg_lum; | 56 | int prev_avg_lum; |
57 | int exp_too_low_cnt; | 57 | int exp_too_low_cnt; |
58 | int exp_too_high_cnt; | 58 | int exp_too_high_cnt; |
59 | int header_read; | ||
60 | u8 header[12]; /* Header without sof marker */ | ||
59 | 61 | ||
60 | unsigned short exposure; | 62 | unsigned short exposure; |
61 | unsigned char gain; | 63 | unsigned char gain; |
@@ -71,14 +73,15 @@ struct sd { | |||
71 | #define BRIDGE_103 1 | 73 | #define BRIDGE_103 1 |
72 | 74 | ||
73 | __u8 sensor; /* Type of image sensor chip */ | 75 | __u8 sensor; /* Type of image sensor chip */ |
74 | #define SENSOR_HV7131R 0 | 76 | #define SENSOR_HV7131D 0 |
75 | #define SENSOR_OV6650 1 | 77 | #define SENSOR_HV7131R 1 |
76 | #define SENSOR_OV7630 2 | 78 | #define SENSOR_OV6650 2 |
77 | #define SENSOR_PAS106 3 | 79 | #define SENSOR_OV7630 3 |
78 | #define SENSOR_PAS202 4 | 80 | #define SENSOR_PAS106 4 |
79 | #define SENSOR_TAS5110C 5 | 81 | #define SENSOR_PAS202 5 |
80 | #define SENSOR_TAS5110D 6 | 82 | #define SENSOR_TAS5110C 6 |
81 | #define SENSOR_TAS5130CXX 7 | 83 | #define SENSOR_TAS5110D 7 |
84 | #define SENSOR_TAS5130CXX 8 | ||
82 | __u8 reg11; | 85 | __u8 reg11; |
83 | }; | 86 | }; |
84 | 87 | ||
@@ -303,14 +306,29 @@ static const struct v4l2_pix_format sif_mode[] = { | |||
303 | .priv = 0}, | 306 | .priv = 0}, |
304 | }; | 307 | }; |
305 | 308 | ||
306 | static const __u8 initHv7131[] = { | 309 | static const __u8 initHv7131d[] = { |
310 | 0x04, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, | ||
311 | 0x00, 0x00, | ||
312 | 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, | ||
313 | 0x28, 0x1e, 0x60, 0x8e, 0x42, | ||
314 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c | ||
315 | }; | ||
316 | static const __u8 hv7131d_sensor_init[][8] = { | ||
317 | {0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17}, | ||
318 | {0xa0, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x17}, | ||
319 | {0xa0, 0x11, 0x28, 0x00, 0x00, 0x00, 0x00, 0x17}, | ||
320 | {0xa0, 0x11, 0x30, 0x30, 0x00, 0x00, 0x00, 0x17}, /* reset level */ | ||
321 | {0xa0, 0x11, 0x34, 0x02, 0x00, 0x00, 0x00, 0x17}, /* pixel bias volt */ | ||
322 | }; | ||
323 | |||
324 | static const __u8 initHv7131r[] = { | ||
307 | 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, | 325 | 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, |
308 | 0x00, 0x00, | 326 | 0x00, 0x00, |
309 | 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, | 327 | 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, |
310 | 0x28, 0x1e, 0x60, 0x8a, 0x20, | 328 | 0x28, 0x1e, 0x60, 0x8a, 0x20, |
311 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c | 329 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c |
312 | }; | 330 | }; |
313 | static const __u8 hv7131_sensor_init[][8] = { | 331 | static const __u8 hv7131r_sensor_init[][8] = { |
314 | {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10}, | 332 | {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10}, |
315 | {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10}, | 333 | {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10}, |
316 | {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10}, | 334 | {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10}, |
@@ -340,7 +358,7 @@ static const __u8 ov6650_sensor_init[][8] = { | |||
340 | * but blue wont be there. Avoid this data ... */ | 358 | * but blue wont be there. Avoid this data ... */ |
341 | {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */ | 359 | {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */ |
342 | {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, | 360 | {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, |
343 | {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10}, | 361 | {0xa0, 0x60, 0x30, 0x3d, 0x0a, 0xd8, 0xa4, 0x10}, |
344 | /* Enable rgb brightness control */ | 362 | /* Enable rgb brightness control */ |
345 | {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10}, | 363 | {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10}, |
346 | /* HDG: Note windows uses the line below, which sets both register 0x60 | 364 | /* HDG: Note windows uses the line below, which sets both register 0x60 |
@@ -505,7 +523,7 @@ static const __u8 pas202_sensor_init[][8] = { | |||
505 | {0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10}, | 523 | {0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10}, |
506 | {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10}, | 524 | {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10}, |
507 | {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10}, | 525 | {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10}, |
508 | {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x01, 0x32, 0x10}, | 526 | {0xd0, 0x40, 0x0c, 0x00, 0x0c, 0x01, 0x32, 0x10}, |
509 | {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10}, | 527 | {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10}, |
510 | {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10}, | 528 | {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10}, |
511 | {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10}, | 529 | {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10}, |
@@ -551,7 +569,8 @@ static const __u8 tas5130_sensor_init[][8] = { | |||
551 | }; | 569 | }; |
552 | 570 | ||
553 | static struct sensor_data sensor_data[] = { | 571 | static struct sensor_data sensor_data[] = { |
554 | SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), | 572 | SENS(initHv7131d, NULL, hv7131d_sensor_init, NULL, NULL, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0), |
573 | SENS(initHv7131r, NULL, hv7131r_sensor_init, NULL, NULL, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), | ||
555 | SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), | 574 | SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), |
556 | SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, | 575 | SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, |
557 | F_GAIN, 0, 0x21), | 576 | F_GAIN, 0, 0x21), |
@@ -701,7 +720,18 @@ static void setsensorgain(struct gspca_dev *gspca_dev) | |||
701 | unsigned char gain = sd->gain; | 720 | unsigned char gain = sd->gain; |
702 | 721 | ||
703 | switch (sd->sensor) { | 722 | switch (sd->sensor) { |
723 | case SENSOR_HV7131D: { | ||
724 | __u8 i2c[] = | ||
725 | {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17}; | ||
704 | 726 | ||
727 | i2c[3] = 0x3f - (sd->gain / 4); | ||
728 | i2c[4] = 0x3f - (sd->gain / 4); | ||
729 | i2c[5] = 0x3f - (sd->gain / 4); | ||
730 | |||
731 | if (i2c_w(gspca_dev, i2c) < 0) | ||
732 | goto err; | ||
733 | break; | ||
734 | } | ||
705 | case SENSOR_TAS5110C: | 735 | case SENSOR_TAS5110C: |
706 | case SENSOR_TAS5110D: { | 736 | case SENSOR_TAS5110D: { |
707 | __u8 i2c[] = | 737 | __u8 i2c[] = |
@@ -788,6 +818,23 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
788 | struct sd *sd = (struct sd *) gspca_dev; | 818 | struct sd *sd = (struct sd *) gspca_dev; |
789 | 819 | ||
790 | switch (sd->sensor) { | 820 | switch (sd->sensor) { |
821 | case SENSOR_HV7131D: { | ||
822 | /* Note the datasheet wrongly says line mode exposure uses reg | ||
823 | 0x26 and 0x27, testing has shown 0x25 + 0x26 */ | ||
824 | __u8 i2c[] = {0xc0, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x17}; | ||
825 | /* The HV7131D's exposure goes from 0 - 65535, we scale our | ||
826 | exposure of 0-1023 to 0-6138. There are 2 reasons for this: | ||
827 | 1) This puts our exposure knee of 200 at approx the point | ||
828 | where the framerate starts dropping | ||
829 | 2) At 6138 the framerate has already dropped to 2 fps, | ||
830 | going any lower makes little sense */ | ||
831 | __u16 reg = sd->exposure * 6; | ||
832 | i2c[3] = reg >> 8; | ||
833 | i2c[4] = reg & 0xff; | ||
834 | if (i2c_w(gspca_dev, i2c) != 0) | ||
835 | goto err; | ||
836 | break; | ||
837 | } | ||
791 | case SENSOR_TAS5110C: | 838 | case SENSOR_TAS5110C: |
792 | case SENSOR_TAS5110D: { | 839 | case SENSOR_TAS5110D: { |
793 | /* register 19's high nibble contains the sn9c10x clock divider | 840 | /* register 19's high nibble contains the sn9c10x clock divider |
@@ -1177,13 +1224,10 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
1177 | sd_init(gspca_dev); | 1224 | sd_init(gspca_dev); |
1178 | } | 1225 | } |
1179 | 1226 | ||
1180 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1227 | static u8* find_sof(struct gspca_dev *gspca_dev, u8 *data, int len) |
1181 | u8 *data, /* isoc packet */ | ||
1182 | int len) /* iso packet length */ | ||
1183 | { | 1228 | { |
1184 | int i; | ||
1185 | struct sd *sd = (struct sd *) gspca_dev; | 1229 | struct sd *sd = (struct sd *) gspca_dev; |
1186 | struct cam *cam = &gspca_dev->cam; | 1230 | int i, header_size = (sd->bridge == BRIDGE_103) ? 18 : 12; |
1187 | 1231 | ||
1188 | /* frames start with: | 1232 | /* frames start with: |
1189 | * ff ff 00 c4 c4 96 synchro | 1233 | * ff ff 00 c4 c4 96 synchro |
@@ -1194,58 +1238,84 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1194 | * ll mm brightness sum outside auto exposure | 1238 | * ll mm brightness sum outside auto exposure |
1195 | * (xx xx xx xx xx) audio values for snc103 | 1239 | * (xx xx xx xx xx) audio values for snc103 |
1196 | */ | 1240 | */ |
1197 | if (len > 6 && len < 24) { | 1241 | for (i = 0; i < len; i++) { |
1198 | for (i = 0; i < len - 6; i++) { | 1242 | switch (sd->header_read) { |
1199 | if (data[0 + i] == 0xff | 1243 | case 0: |
1200 | && data[1 + i] == 0xff | 1244 | if (data[i] == 0xff) |
1201 | && data[2 + i] == 0x00 | 1245 | sd->header_read++; |
1202 | && data[3 + i] == 0xc4 | 1246 | break; |
1203 | && data[4 + i] == 0xc4 | 1247 | case 1: |
1204 | && data[5 + i] == 0x96) { /* start of frame */ | 1248 | if (data[i] == 0xff) |
1205 | int lum = -1; | 1249 | sd->header_read++; |
1206 | int pkt_type = LAST_PACKET; | 1250 | else |
1207 | int fr_h_sz = (sd->bridge == BRIDGE_103) ? | 1251 | sd->header_read = 0; |
1208 | 18 : 12; | 1252 | break; |
1209 | 1253 | case 2: | |
1210 | if (len - i < fr_h_sz) { | 1254 | if (data[i] == 0x00) |
1211 | PDEBUG(D_STREAM, "packet too short to" | 1255 | sd->header_read++; |
1212 | " get avg brightness"); | 1256 | else if (data[i] != 0xff) |
1213 | } else if (sd->bridge == BRIDGE_103) { | 1257 | sd->header_read = 0; |
1214 | lum = data[i + 9] + | 1258 | break; |
1215 | (data[i + 10] << 8); | 1259 | case 3: |
1216 | } else { | 1260 | if (data[i] == 0xc4) |
1217 | lum = data[i + 8] + (data[i + 9] << 8); | 1261 | sd->header_read++; |
1218 | } | 1262 | else if (data[i] == 0xff) |
1219 | /* When exposure changes midway a frame we | 1263 | sd->header_read = 1; |
1220 | get a lum of 0 in this case drop 2 frames | 1264 | else |
1221 | as the frames directly after an exposure | 1265 | sd->header_read = 0; |
1222 | change have an unstable image. Sometimes lum | 1266 | break; |
1223 | *really* is 0 (cam used in low light with | 1267 | case 4: |
1224 | low exposure setting), so do not drop frames | 1268 | if (data[i] == 0xc4) |
1225 | if the previous lum was 0 too. */ | 1269 | sd->header_read++; |
1226 | if (lum == 0 && sd->prev_avg_lum != 0) { | 1270 | else if (data[i] == 0xff) |
1227 | lum = -1; | 1271 | sd->header_read = 1; |
1228 | sd->frames_to_drop = 2; | 1272 | else |
1229 | sd->prev_avg_lum = 0; | 1273 | sd->header_read = 0; |
1230 | } else | 1274 | break; |
1231 | sd->prev_avg_lum = lum; | 1275 | case 5: |
1232 | atomic_set(&sd->avg_lum, lum); | 1276 | if (data[i] == 0x96) |
1233 | 1277 | sd->header_read++; | |
1234 | if (sd->frames_to_drop) { | 1278 | else if (data[i] == 0xff) |
1235 | sd->frames_to_drop--; | 1279 | sd->header_read = 1; |
1236 | pkt_type = DISCARD_PACKET; | 1280 | else |
1237 | } | 1281 | sd->header_read = 0; |
1238 | 1282 | break; | |
1239 | gspca_frame_add(gspca_dev, pkt_type, | 1283 | default: |
1240 | NULL, 0); | 1284 | sd->header[sd->header_read - 6] = data[i]; |
1241 | data += i + fr_h_sz; | 1285 | sd->header_read++; |
1242 | len -= i + fr_h_sz; | 1286 | if (sd->header_read == header_size) { |
1243 | gspca_frame_add(gspca_dev, FIRST_PACKET, | 1287 | sd->header_read = 0; |
1244 | data, len); | 1288 | return data + i + 1; |
1245 | return; | ||
1246 | } | 1289 | } |
1247 | } | 1290 | } |
1248 | } | 1291 | } |
1292 | return NULL; | ||
1293 | } | ||
1294 | |||
1295 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
1296 | u8 *data, /* isoc packet */ | ||
1297 | int len) /* iso packet length */ | ||
1298 | { | ||
1299 | int fr_h_sz = 0, lum_offset = 0, len_after_sof = 0; | ||
1300 | struct sd *sd = (struct sd *) gspca_dev; | ||
1301 | struct cam *cam = &gspca_dev->cam; | ||
1302 | u8 *sof; | ||
1303 | |||
1304 | sof = find_sof(gspca_dev, data, len); | ||
1305 | if (sof) { | ||
1306 | if (sd->bridge == BRIDGE_103) { | ||
1307 | fr_h_sz = 18; | ||
1308 | lum_offset = 3; | ||
1309 | } else { | ||
1310 | fr_h_sz = 12; | ||
1311 | lum_offset = 2; | ||
1312 | } | ||
1313 | |||
1314 | len_after_sof = len - (sof - data); | ||
1315 | len = (sof - data) - fr_h_sz; | ||
1316 | if (len < 0) | ||
1317 | len = 0; | ||
1318 | } | ||
1249 | 1319 | ||
1250 | if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) { | 1320 | if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) { |
1251 | /* In raw mode we sometimes get some garbage after the frame | 1321 | /* In raw mode we sometimes get some garbage after the frame |
@@ -1259,6 +1329,33 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1259 | } | 1329 | } |
1260 | 1330 | ||
1261 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 1331 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
1332 | |||
1333 | if (sof) { | ||
1334 | int lum = sd->header[lum_offset] + | ||
1335 | (sd->header[lum_offset + 1] << 8); | ||
1336 | |||
1337 | /* When exposure changes midway a frame we | ||
1338 | get a lum of 0 in this case drop 2 frames | ||
1339 | as the frames directly after an exposure | ||
1340 | change have an unstable image. Sometimes lum | ||
1341 | *really* is 0 (cam used in low light with | ||
1342 | low exposure setting), so do not drop frames | ||
1343 | if the previous lum was 0 too. */ | ||
1344 | if (lum == 0 && sd->prev_avg_lum != 0) { | ||
1345 | lum = -1; | ||
1346 | sd->frames_to_drop = 2; | ||
1347 | sd->prev_avg_lum = 0; | ||
1348 | } else | ||
1349 | sd->prev_avg_lum = lum; | ||
1350 | atomic_set(&sd->avg_lum, lum); | ||
1351 | |||
1352 | if (sd->frames_to_drop) | ||
1353 | sd->frames_to_drop--; | ||
1354 | else | ||
1355 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); | ||
1356 | |||
1357 | gspca_frame_add(gspca_dev, FIRST_PACKET, sof, len_after_sof); | ||
1358 | } | ||
1262 | } | 1359 | } |
1263 | 1360 | ||
1264 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 1361 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) |
@@ -1431,9 +1528,7 @@ static const struct sd_desc sd_desc = { | |||
1431 | static const struct usb_device_id device_table[] __devinitconst = { | 1528 | static const struct usb_device_id device_table[] __devinitconst = { |
1432 | {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */ | 1529 | {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */ |
1433 | {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */ | 1530 | {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */ |
1434 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | ||
1435 | {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */ | 1531 | {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */ |
1436 | #endif | ||
1437 | {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)}, | 1532 | {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)}, |
1438 | {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, | 1533 | {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, |
1439 | {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)}, | 1534 | {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)}, |
@@ -1444,9 +1539,12 @@ static const struct usb_device_id device_table[] __devinitconst = { | |||
1444 | #endif | 1539 | #endif |
1445 | {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)}, | 1540 | {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)}, |
1446 | {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, | 1541 | {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, |
1542 | {USB_DEVICE(0x0c45, 0x602a), SB(HV7131D, 102)}, | ||
1543 | /* {USB_DEVICE(0x0c45, 0x602b), SB(MI0343, 102)}, */ | ||
1447 | {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, | 1544 | {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, |
1448 | {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, | 1545 | {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, |
1449 | {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, | 1546 | {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, |
1547 | /* {USB_DEVICE(0x0c45, 0x602b), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */ | ||
1450 | {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)}, | 1548 | {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)}, |
1451 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | 1549 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE |
1452 | {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)}, | 1550 | {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)}, |
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index e23de57e2c73..2d0bb17a30a2 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -1598,22 +1598,22 @@ static void i2c_w_seq(struct gspca_dev *gspca_dev, | |||
1598 | } | 1598 | } |
1599 | } | 1599 | } |
1600 | 1600 | ||
1601 | /* check the ID of the hv7131 sensor */ | ||
1602 | /* this sequence is needed because it activates the sensor */ | ||
1601 | static void hv7131r_probe(struct gspca_dev *gspca_dev) | 1603 | static void hv7131r_probe(struct gspca_dev *gspca_dev) |
1602 | { | 1604 | { |
1603 | i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ | 1605 | i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ |
1604 | msleep(10); | 1606 | msleep(10); |
1605 | reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */ | 1607 | reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */ |
1606 | msleep(10); | 1608 | msleep(10); |
1607 | i2c_r(gspca_dev, 0, 5); /* read sensor id */ | 1609 | i2c_r(gspca_dev, 0, 5); /* read sensor id */ |
1608 | if (gspca_dev->usb_buf[0] == 0x02 | 1610 | if (gspca_dev->usb_buf[0] == 0x02 /* chip ID (02 is R) */ |
1609 | && gspca_dev->usb_buf[1] == 0x09 | 1611 | && gspca_dev->usb_buf[1] == 0x09 |
1610 | && gspca_dev->usb_buf[2] == 0x01 | 1612 | && gspca_dev->usb_buf[2] == 0x01) { |
1611 | && gspca_dev->usb_buf[3] == 0x00 | 1613 | PDEBUG(D_PROBE, "Sensor HV7131R found"); |
1612 | && gspca_dev->usb_buf[4] == 0x00) { | ||
1613 | PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found"); | ||
1614 | return; | 1614 | return; |
1615 | } | 1615 | } |
1616 | PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found", | 1616 | warn("Erroneous HV7131R ID 0x%02x 0x%02x 0x%02x", |
1617 | gspca_dev->usb_buf[0], gspca_dev->usb_buf[1], | 1617 | gspca_dev->usb_buf[0], gspca_dev->usb_buf[1], |
1618 | gspca_dev->usb_buf[2]); | 1618 | gspca_dev->usb_buf[2]); |
1619 | } | 1619 | } |
@@ -2533,7 +2533,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2533 | init = om6802_sensor_param1; | 2533 | init = om6802_sensor_param1; |
2534 | if (!mode) { /* if 640x480 */ | 2534 | if (!mode) { /* if 640x480 */ |
2535 | reg17 &= ~MCK_SIZE_MASK; | 2535 | reg17 &= ~MCK_SIZE_MASK; |
2536 | reg17 |= 0x01; /* clock / 4 */ | 2536 | reg17 |= 0x04; /* clock / 4 */ |
2537 | } | 2537 | } |
2538 | break; | 2538 | break; |
2539 | case SENSOR_OV7630: | 2539 | case SENSOR_OV7630: |
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index ad73f4812c05..3a162c6d5466 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c | |||
@@ -597,7 +597,7 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
597 | else if (sd->gain < 128) | 597 | else if (sd->gain < 128) |
598 | gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40; | 598 | gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40; |
599 | else | 599 | else |
600 | gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xC0; | 600 | gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xc0; |
601 | 601 | ||
602 | gspca_dev->usb_buf[1] = 0; | 602 | gspca_dev->usb_buf[1] = 0; |
603 | reg_w_buf(gspca_dev, 0x8335, 2); | 603 | reg_w_buf(gspca_dev, 0x8335, 2); |
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c index c2e88b5303cb..8ba199543856 100644 --- a/drivers/media/video/gspca/sq905c.c +++ b/drivers/media/video/gspca/sq905c.c | |||
@@ -301,6 +301,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
301 | static const __devinitdata struct usb_device_id device_table[] = { | 301 | static const __devinitdata struct usb_device_id device_table[] = { |
302 | {USB_DEVICE(0x2770, 0x905c)}, | 302 | {USB_DEVICE(0x2770, 0x905c)}, |
303 | {USB_DEVICE(0x2770, 0x9050)}, | 303 | {USB_DEVICE(0x2770, 0x9050)}, |
304 | {USB_DEVICE(0x2770, 0x9051)}, | ||
304 | {USB_DEVICE(0x2770, 0x9052)}, | 305 | {USB_DEVICE(0x2770, 0x9052)}, |
305 | {USB_DEVICE(0x2770, 0x913d)}, | 306 | {USB_DEVICE(0x2770, 0x913d)}, |
306 | {} | 307 | {} |
diff --git a/drivers/media/video/gspca/sq930x.c b/drivers/media/video/gspca/sq930x.c index 3e4b0b94c700..a4a98811b9e3 100644 --- a/drivers/media/video/gspca/sq930x.c +++ b/drivers/media/video/gspca/sq930x.c | |||
@@ -687,10 +687,19 @@ static void cmos_probe(struct gspca_dev *gspca_dev) | |||
687 | if (gspca_dev->usb_buf[0] != 0) | 687 | if (gspca_dev->usb_buf[0] != 0) |
688 | break; | 688 | break; |
689 | } | 689 | } |
690 | if (i >= ARRAY_SIZE(probe_order)) | 690 | if (i >= ARRAY_SIZE(probe_order)) { |
691 | err("Unknown sensor"); | 691 | err("Unknown sensor"); |
692 | else | 692 | gspca_dev->usb_err = -EINVAL; |
693 | sd->sensor = probe_order[i]; | 693 | return; |
694 | } | ||
695 | sd->sensor = probe_order[i]; | ||
696 | switch (sd->sensor) { | ||
697 | case SENSOR_OV7660: | ||
698 | case SENSOR_OV9630: | ||
699 | err("Sensor %s not yet treated", sensor_tb[sd->sensor].name); | ||
700 | gspca_dev->usb_err = -EINVAL; | ||
701 | break; | ||
702 | } | ||
694 | } | 703 | } |
695 | 704 | ||
696 | static void mt9v111_init(struct gspca_dev *gspca_dev) | 705 | static void mt9v111_init(struct gspca_dev *gspca_dev) |
@@ -867,6 +876,9 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
867 | */ | 876 | */ |
868 | 877 | ||
869 | reg_r(gspca_dev, SQ930_CTRL_GET_DEV_INFO, 8); | 878 | reg_r(gspca_dev, SQ930_CTRL_GET_DEV_INFO, 8); |
879 | if (gspca_dev->usb_err < 0) | ||
880 | return gspca_dev->usb_err; | ||
881 | |||
870 | /* it returns: | 882 | /* it returns: |
871 | * 03 00 12 93 0b f6 c9 00 live! ultra | 883 | * 03 00 12 93 0b f6 c9 00 live! ultra |
872 | * 03 00 07 93 0b f6 ca 00 live! ultra for notebook | 884 | * 03 00 07 93 0b f6 ca 00 live! ultra for notebook |
@@ -900,15 +912,15 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
900 | if (sd->sensor == SENSOR_MI0360) { | 912 | if (sd->sensor == SENSOR_MI0360) { |
901 | 913 | ||
902 | /* no sensor probe for icam tracer */ | 914 | /* no sensor probe for icam tracer */ |
903 | if (gspca_dev->usb_buf[5] == 0xf6) /* if CMOS */ | 915 | if (gspca_dev->usb_buf[5] == 0xf6) /* if ccd */ |
904 | sd->sensor = SENSOR_ICX098BQ; | 916 | sd->sensor = SENSOR_ICX098BQ; |
905 | else | 917 | else |
906 | cmos_probe(gspca_dev); | 918 | cmos_probe(gspca_dev); |
907 | } | 919 | } |
908 | 920 | if (gspca_dev->usb_err >= 0) { | |
909 | PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name); | 921 | PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name); |
910 | 922 | global_init(sd, 1); | |
911 | global_init(sd, 1); | 923 | } |
912 | return gspca_dev->usb_err; | 924 | return gspca_dev->usb_err; |
913 | } | 925 | } |
914 | 926 | ||
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c index 086de44a6e57..28ea4175b80e 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx.c | |||
@@ -263,7 +263,21 @@ static int stv06xx_init(struct gspca_dev *gspca_dev) | |||
263 | static int stv06xx_start(struct gspca_dev *gspca_dev) | 263 | static int stv06xx_start(struct gspca_dev *gspca_dev) |
264 | { | 264 | { |
265 | struct sd *sd = (struct sd *) gspca_dev; | 265 | struct sd *sd = (struct sd *) gspca_dev; |
266 | int err; | 266 | struct usb_host_interface *alt; |
267 | struct usb_interface *intf; | ||
268 | int err, packet_size; | ||
269 | |||
270 | intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); | ||
271 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); | ||
272 | if (!alt) { | ||
273 | PDEBUG(D_ERR, "Couldn't get altsetting"); | ||
274 | return -EIO; | ||
275 | } | ||
276 | |||
277 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | ||
278 | err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size); | ||
279 | if (err < 0) | ||
280 | return err; | ||
267 | 281 | ||
268 | /* Prepare the sensor for start */ | 282 | /* Prepare the sensor for start */ |
269 | err = sd->sensor->start(sd); | 283 | err = sd->sensor->start(sd); |
@@ -282,6 +296,43 @@ out: | |||
282 | return (err < 0) ? err : 0; | 296 | return (err < 0) ? err : 0; |
283 | } | 297 | } |
284 | 298 | ||
299 | static int stv06xx_isoc_init(struct gspca_dev *gspca_dev) | ||
300 | { | ||
301 | struct usb_host_interface *alt; | ||
302 | struct sd *sd = (struct sd *) gspca_dev; | ||
303 | |||
304 | /* Start isoc bandwidth "negotiation" at max isoc bandwidth */ | ||
305 | alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; | ||
306 | alt->endpoint[0].desc.wMaxPacketSize = | ||
307 | cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static int stv06xx_isoc_nego(struct gspca_dev *gspca_dev) | ||
313 | { | ||
314 | int ret, packet_size, min_packet_size; | ||
315 | struct usb_host_interface *alt; | ||
316 | struct sd *sd = (struct sd *) gspca_dev; | ||
317 | |||
318 | alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; | ||
319 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | ||
320 | min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode]; | ||
321 | if (packet_size <= min_packet_size) | ||
322 | return -EIO; | ||
323 | |||
324 | packet_size -= 100; | ||
325 | if (packet_size < min_packet_size) | ||
326 | packet_size = min_packet_size; | ||
327 | alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size); | ||
328 | |||
329 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); | ||
330 | if (ret < 0) | ||
331 | PDEBUG(D_ERR|D_STREAM, "set alt 1 err %d", ret); | ||
332 | |||
333 | return ret; | ||
334 | } | ||
335 | |||
285 | static void stv06xx_stopN(struct gspca_dev *gspca_dev) | 336 | static void stv06xx_stopN(struct gspca_dev *gspca_dev) |
286 | { | 337 | { |
287 | int err; | 338 | int err; |
@@ -349,7 +400,7 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev, | |||
349 | } | 400 | } |
350 | 401 | ||
351 | /* First byte seem to be 02=data 2nd byte is unknown??? */ | 402 | /* First byte seem to be 02=data 2nd byte is unknown??? */ |
352 | if (sd->bridge == BRIDGE_ST6422 && (id & 0xFF00) == 0x0200) | 403 | if (sd->bridge == BRIDGE_ST6422 && (id & 0xff00) == 0x0200) |
353 | goto frame_data; | 404 | goto frame_data; |
354 | 405 | ||
355 | switch (id) { | 406 | switch (id) { |
@@ -462,6 +513,8 @@ static const struct sd_desc sd_desc = { | |||
462 | .start = stv06xx_start, | 513 | .start = stv06xx_start, |
463 | .stopN = stv06xx_stopN, | 514 | .stopN = stv06xx_stopN, |
464 | .pkt_scan = stv06xx_pkt_scan, | 515 | .pkt_scan = stv06xx_pkt_scan, |
516 | .isoc_init = stv06xx_isoc_init, | ||
517 | .isoc_nego = stv06xx_isoc_nego, | ||
465 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 518 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
466 | .int_pkt_scan = sd_int_pkt_scan, | 519 | .int_pkt_scan = sd_int_pkt_scan, |
467 | #endif | 520 | #endif |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h index cf3d0ccc1121..b538dce96f78 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h | |||
@@ -146,6 +146,11 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = { | |||
146 | .i2c_addr = (0x55 << 1), | 146 | .i2c_addr = (0x55 << 1), |
147 | .i2c_len = 1, | 147 | .i2c_len = 1, |
148 | 148 | ||
149 | /* FIXME (see if we can lower min_packet_size, needs testing, and also | ||
150 | adjusting framerate when the bandwidth gets lower) */ | ||
151 | .min_packet_size = { 847 }, | ||
152 | .max_packet_size = { 847 }, | ||
153 | |||
149 | .init = hdcs_init, | 154 | .init = hdcs_init, |
150 | .probe = hdcs_probe_1x00, | 155 | .probe = hdcs_probe_1x00, |
151 | .start = hdcs_start, | 156 | .start = hdcs_start, |
@@ -160,6 +165,11 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = { | |||
160 | .i2c_addr = (0x55 << 1), | 165 | .i2c_addr = (0x55 << 1), |
161 | .i2c_len = 1, | 166 | .i2c_len = 1, |
162 | 167 | ||
168 | /* FIXME (see if we can lower min_packet_size, needs testing, and also | ||
169 | adjusting framerate when the bandwidthm gets lower) */ | ||
170 | .min_packet_size = { 847 }, | ||
171 | .max_packet_size = { 847 }, | ||
172 | |||
163 | .init = hdcs_init, | 173 | .init = hdcs_init, |
164 | .probe = hdcs_probe_1020, | 174 | .probe = hdcs_probe_1020, |
165 | .start = hdcs_start, | 175 | .start = hdcs_start, |
@@ -177,7 +187,6 @@ static const u16 stv_bridge_init[][2] = { | |||
177 | {STV_REG04, 0x07}, | 187 | {STV_REG04, 0x07}, |
178 | 188 | ||
179 | {STV_SCAN_RATE, 0x20}, | 189 | {STV_SCAN_RATE, 0x20}, |
180 | {STV_ISO_SIZE_L, 847}, | ||
181 | {STV_Y_CTRL, 0x01}, | 190 | {STV_Y_CTRL, 0x01}, |
182 | {STV_X_CTRL, 0x0a} | 191 | {STV_X_CTRL, 0x0a} |
183 | }; | 192 | }; |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c index 285221e6b390..ac47b4c94388 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c | |||
@@ -208,11 +208,24 @@ static int pb0100_probe(struct sd *sd) | |||
208 | 208 | ||
209 | static int pb0100_start(struct sd *sd) | 209 | static int pb0100_start(struct sd *sd) |
210 | { | 210 | { |
211 | int err; | 211 | int err, packet_size, max_packet_size; |
212 | struct usb_host_interface *alt; | ||
213 | struct usb_interface *intf; | ||
212 | struct cam *cam = &sd->gspca_dev.cam; | 214 | struct cam *cam = &sd->gspca_dev.cam; |
213 | s32 *sensor_settings = sd->sensor_priv; | 215 | s32 *sensor_settings = sd->sensor_priv; |
214 | u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv; | 216 | u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv; |
215 | 217 | ||
218 | intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); | ||
219 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); | ||
220 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | ||
221 | |||
222 | /* If we don't have enough bandwidth use a lower framerate */ | ||
223 | max_packet_size = sd->sensor->max_packet_size[sd->gspca_dev.curr_mode]; | ||
224 | if (packet_size < max_packet_size) | ||
225 | stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1)); | ||
226 | else | ||
227 | stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(5)|BIT(3)|BIT(1)); | ||
228 | |||
216 | /* Setup sensor window */ | 229 | /* Setup sensor window */ |
217 | if (mode & PB0100_CROP_TO_VGA) { | 230 | if (mode & PB0100_CROP_TO_VGA) { |
218 | stv06xx_write_sensor(sd, PB_RSTART, 30); | 231 | stv06xx_write_sensor(sd, PB_RSTART, 30); |
@@ -328,9 +341,6 @@ static int pb0100_init(struct sd *sd) | |||
328 | stv06xx_write_bridge(sd, STV_REG03, 0x45); | 341 | stv06xx_write_bridge(sd, STV_REG03, 0x45); |
329 | stv06xx_write_bridge(sd, STV_REG04, 0x07); | 342 | stv06xx_write_bridge(sd, STV_REG04, 0x07); |
330 | 343 | ||
331 | /* ISO-Size (0x27b: 635... why? - HDCS uses 847) */ | ||
332 | stv06xx_write_bridge(sd, STV_ISO_SIZE_L, 847); | ||
333 | |||
334 | /* Scan/timing for the sensor */ | 344 | /* Scan/timing for the sensor */ |
335 | stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1)); | 345 | stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1)); |
336 | stv06xx_write_sensor(sd, PB_CFILLIN, 14); | 346 | stv06xx_write_sensor(sd, PB_CFILLIN, 14); |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h index 4de4fa5ebc57..757de246dc75 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h | |||
@@ -138,6 +138,9 @@ const struct stv06xx_sensor stv06xx_sensor_pb0100 = { | |||
138 | .i2c_addr = 0xba, | 138 | .i2c_addr = 0xba, |
139 | .i2c_len = 2, | 139 | .i2c_len = 2, |
140 | 140 | ||
141 | .min_packet_size = { 635, 847 }, | ||
142 | .max_packet_size = { 847, 923 }, | ||
143 | |||
141 | .init = pb0100_init, | 144 | .init = pb0100_init, |
142 | .probe = pb0100_probe, | 145 | .probe = pb0100_probe, |
143 | .start = pb0100_start, | 146 | .start = pb0100_start, |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h index 934b9cebc1ab..fb229d8ded58 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h | |||
@@ -53,6 +53,10 @@ struct stv06xx_sensor { | |||
53 | /* length of an i2c word */ | 53 | /* length of an i2c word */ |
54 | u8 i2c_len; | 54 | u8 i2c_len; |
55 | 55 | ||
56 | /* Isoc packet size (per mode) */ | ||
57 | int min_packet_size[4]; | ||
58 | int max_packet_size[4]; | ||
59 | |||
56 | /* Probes if the sensor is connected */ | 60 | /* Probes if the sensor is connected */ |
57 | int (*probe)(struct sd *sd); | 61 | int (*probe)(struct sd *sd); |
58 | 62 | ||
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c index 3af53264a364..8a456de4970a 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c | |||
@@ -28,6 +28,20 @@ | |||
28 | 28 | ||
29 | #include "stv06xx_st6422.h" | 29 | #include "stv06xx_st6422.h" |
30 | 30 | ||
31 | /* controls */ | ||
32 | enum e_ctrl { | ||
33 | BRIGHTNESS, | ||
34 | CONTRAST, | ||
35 | GAIN, | ||
36 | EXPOSURE, | ||
37 | NCTRLS /* number of controls */ | ||
38 | }; | ||
39 | |||
40 | /* sensor settings */ | ||
41 | struct st6422_settings { | ||
42 | struct gspca_ctrl ctrls[NCTRLS]; | ||
43 | }; | ||
44 | |||
31 | static struct v4l2_pix_format st6422_mode[] = { | 45 | static struct v4l2_pix_format st6422_mode[] = { |
32 | /* Note we actually get 124 lines of data, of which we skip the 4st | 46 | /* Note we actually get 124 lines of data, of which we skip the 4st |
33 | 4 as they are garbage */ | 47 | 4 as they are garbage */ |
@@ -57,9 +71,14 @@ static struct v4l2_pix_format st6422_mode[] = { | |||
57 | }, | 71 | }, |
58 | }; | 72 | }; |
59 | 73 | ||
60 | static const struct ctrl st6422_ctrl[] = { | 74 | /* V4L2 controls supported by the driver */ |
61 | #define BRIGHTNESS_IDX 0 | 75 | static void st6422_set_brightness(struct gspca_dev *gspca_dev); |
62 | { | 76 | static void st6422_set_contrast(struct gspca_dev *gspca_dev); |
77 | static void st6422_set_gain(struct gspca_dev *gspca_dev); | ||
78 | static void st6422_set_exposure(struct gspca_dev *gspca_dev); | ||
79 | |||
80 | static const struct ctrl st6422_ctrl[NCTRLS] = { | ||
81 | [BRIGHTNESS] = { | ||
63 | { | 82 | { |
64 | .id = V4L2_CID_BRIGHTNESS, | 83 | .id = V4L2_CID_BRIGHTNESS, |
65 | .type = V4L2_CTRL_TYPE_INTEGER, | 84 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -69,11 +88,9 @@ static const struct ctrl st6422_ctrl[] = { | |||
69 | .step = 1, | 88 | .step = 1, |
70 | .default_value = 3 | 89 | .default_value = 3 |
71 | }, | 90 | }, |
72 | .set = st6422_set_brightness, | 91 | .set_control = st6422_set_brightness |
73 | .get = st6422_get_brightness | ||
74 | }, | 92 | }, |
75 | #define CONTRAST_IDX 1 | 93 | [CONTRAST] = { |
76 | { | ||
77 | { | 94 | { |
78 | .id = V4L2_CID_CONTRAST, | 95 | .id = V4L2_CID_CONTRAST, |
79 | .type = V4L2_CTRL_TYPE_INTEGER, | 96 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -83,11 +100,9 @@ static const struct ctrl st6422_ctrl[] = { | |||
83 | .step = 1, | 100 | .step = 1, |
84 | .default_value = 11 | 101 | .default_value = 11 |
85 | }, | 102 | }, |
86 | .set = st6422_set_contrast, | 103 | .set_control = st6422_set_contrast |
87 | .get = st6422_get_contrast | ||
88 | }, | 104 | }, |
89 | #define GAIN_IDX 2 | 105 | [GAIN] = { |
90 | { | ||
91 | { | 106 | { |
92 | .id = V4L2_CID_GAIN, | 107 | .id = V4L2_CID_GAIN, |
93 | .type = V4L2_CTRL_TYPE_INTEGER, | 108 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -97,49 +112,43 @@ static const struct ctrl st6422_ctrl[] = { | |||
97 | .step = 1, | 112 | .step = 1, |
98 | .default_value = 64 | 113 | .default_value = 64 |
99 | }, | 114 | }, |
100 | .set = st6422_set_gain, | 115 | .set_control = st6422_set_gain |
101 | .get = st6422_get_gain | ||
102 | }, | 116 | }, |
103 | #define EXPOSURE_IDX 3 | 117 | [EXPOSURE] = { |
104 | { | ||
105 | { | 118 | { |
106 | .id = V4L2_CID_EXPOSURE, | 119 | .id = V4L2_CID_EXPOSURE, |
107 | .type = V4L2_CTRL_TYPE_INTEGER, | 120 | .type = V4L2_CTRL_TYPE_INTEGER, |
108 | .name = "Exposure", | 121 | .name = "Exposure", |
109 | .minimum = 0, | 122 | .minimum = 0, |
110 | .maximum = 1023, | 123 | #define EXPOSURE_MAX 1023 |
124 | .maximum = EXPOSURE_MAX, | ||
111 | .step = 1, | 125 | .step = 1, |
112 | .default_value = 256 | 126 | .default_value = 256 |
113 | }, | 127 | }, |
114 | .set = st6422_set_exposure, | 128 | .set_control = st6422_set_exposure |
115 | .get = st6422_get_exposure | ||
116 | }, | 129 | }, |
117 | }; | 130 | }; |
118 | 131 | ||
119 | static int st6422_probe(struct sd *sd) | 132 | static int st6422_probe(struct sd *sd) |
120 | { | 133 | { |
121 | int i; | 134 | struct st6422_settings *sensor_settings; |
122 | s32 *sensor_settings; | ||
123 | 135 | ||
124 | if (sd->bridge != BRIDGE_ST6422) | 136 | if (sd->bridge != BRIDGE_ST6422) |
125 | return -ENODEV; | 137 | return -ENODEV; |
126 | 138 | ||
127 | info("st6422 sensor detected"); | 139 | info("st6422 sensor detected"); |
128 | 140 | ||
129 | sensor_settings = kmalloc(ARRAY_SIZE(st6422_ctrl) * sizeof(s32), | 141 | sensor_settings = kmalloc(sizeof *sensor_settings, GFP_KERNEL); |
130 | GFP_KERNEL); | ||
131 | if (!sensor_settings) | 142 | if (!sensor_settings) |
132 | return -ENOMEM; | 143 | return -ENOMEM; |
133 | 144 | ||
134 | sd->gspca_dev.cam.cam_mode = st6422_mode; | 145 | sd->gspca_dev.cam.cam_mode = st6422_mode; |
135 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode); | 146 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode); |
147 | sd->gspca_dev.cam.ctrls = sensor_settings->ctrls; | ||
136 | sd->desc.ctrls = st6422_ctrl; | 148 | sd->desc.ctrls = st6422_ctrl; |
137 | sd->desc.nctrls = ARRAY_SIZE(st6422_ctrl); | 149 | sd->desc.nctrls = ARRAY_SIZE(st6422_ctrl); |
138 | sd->sensor_priv = sensor_settings; | 150 | sd->sensor_priv = sensor_settings; |
139 | 151 | ||
140 | for (i = 0; i < sd->desc.nctrls; i++) | ||
141 | sensor_settings[i] = st6422_ctrl[i].qctrl.default_value; | ||
142 | |||
143 | return 0; | 152 | return 0; |
144 | } | 153 | } |
145 | 154 | ||
@@ -151,11 +160,11 @@ static int st6422_init(struct sd *sd) | |||
151 | { STV_ISO_ENABLE, 0x00 }, /* disable capture */ | 160 | { STV_ISO_ENABLE, 0x00 }, /* disable capture */ |
152 | { 0x1436, 0x00 }, | 161 | { 0x1436, 0x00 }, |
153 | { 0x1432, 0x03 }, /* 0x00-0x1F brightness */ | 162 | { 0x1432, 0x03 }, /* 0x00-0x1F brightness */ |
154 | { 0x143a, 0xF9 }, /* 0x00-0x0F contrast */ | 163 | { 0x143a, 0xf9 }, /* 0x00-0x0F contrast */ |
155 | { 0x0509, 0x38 }, /* R */ | 164 | { 0x0509, 0x38 }, /* R */ |
156 | { 0x050a, 0x38 }, /* G */ | 165 | { 0x050a, 0x38 }, /* G */ |
157 | { 0x050b, 0x38 }, /* B */ | 166 | { 0x050b, 0x38 }, /* B */ |
158 | { 0x050c, 0x2A }, | 167 | { 0x050c, 0x2a }, |
159 | { 0x050d, 0x01 }, | 168 | { 0x050d, 0x01 }, |
160 | 169 | ||
161 | 170 | ||
@@ -213,7 +222,6 @@ static int st6422_init(struct sd *sd) | |||
213 | { 0x150e, 0x8e }, | 222 | { 0x150e, 0x8e }, |
214 | { 0x150f, 0x37 }, | 223 | { 0x150f, 0x37 }, |
215 | { 0x15c0, 0x00 }, | 224 | { 0x15c0, 0x00 }, |
216 | { 0x15c1, 1023 }, /* 160x120, ISOC_PACKET_SIZE */ | ||
217 | { 0x15c3, 0x08 }, /* 0x04/0x14 ... test pictures ??? */ | 225 | { 0x15c3, 0x08 }, /* 0x04/0x14 ... test pictures ??? */ |
218 | 226 | ||
219 | 227 | ||
@@ -235,91 +243,92 @@ static void st6422_disconnect(struct sd *sd) | |||
235 | kfree(sd->sensor_priv); | 243 | kfree(sd->sensor_priv); |
236 | } | 244 | } |
237 | 245 | ||
238 | static int st6422_start(struct sd *sd) | 246 | static int setbrightness(struct sd *sd) |
239 | { | 247 | { |
240 | int err, packet_size; | 248 | struct st6422_settings *sensor_settings = sd->sensor_priv; |
241 | struct cam *cam = &sd->gspca_dev.cam; | ||
242 | s32 *sensor_settings = sd->sensor_priv; | ||
243 | struct usb_host_interface *alt; | ||
244 | struct usb_interface *intf; | ||
245 | |||
246 | intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); | ||
247 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); | ||
248 | if (!alt) { | ||
249 | err("Couldn't get altsetting"); | ||
250 | return -EIO; | ||
251 | } | ||
252 | 249 | ||
253 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | 250 | /* val goes from 0 -> 31 */ |
254 | err = stv06xx_write_bridge(sd, 0x15c1, packet_size); | 251 | return stv06xx_write_bridge(sd, 0x1432, |
255 | if (err < 0) | 252 | sensor_settings->ctrls[BRIGHTNESS].val); |
256 | return err; | 253 | } |
257 | 254 | ||
258 | if (cam->cam_mode[sd->gspca_dev.curr_mode].priv) | 255 | static int setcontrast(struct sd *sd) |
259 | err = stv06xx_write_bridge(sd, 0x1505, 0x0f); | 256 | { |
260 | else | 257 | struct st6422_settings *sensor_settings = sd->sensor_priv; |
261 | err = stv06xx_write_bridge(sd, 0x1505, 0x02); | 258 | |
262 | if (err < 0) | 259 | /* Val goes from 0 -> 15 */ |
263 | return err; | 260 | return stv06xx_write_bridge(sd, 0x143a, |
261 | sensor_settings->ctrls[CONTRAST].val | 0xf0); | ||
262 | } | ||
263 | |||
264 | static int setgain(struct sd *sd) | ||
265 | { | ||
266 | struct st6422_settings *sensor_settings = sd->sensor_priv; | ||
267 | u8 gain; | ||
268 | int err; | ||
269 | |||
270 | gain = sensor_settings->ctrls[GAIN].val; | ||
264 | 271 | ||
265 | err = st6422_set_brightness(&sd->gspca_dev, | 272 | /* Set red, green, blue, gain */ |
266 | sensor_settings[BRIGHTNESS_IDX]); | 273 | err = stv06xx_write_bridge(sd, 0x0509, gain); |
267 | if (err < 0) | 274 | if (err < 0) |
268 | return err; | 275 | return err; |
269 | 276 | ||
270 | err = st6422_set_contrast(&sd->gspca_dev, | 277 | err = stv06xx_write_bridge(sd, 0x050a, gain); |
271 | sensor_settings[CONTRAST_IDX]); | ||
272 | if (err < 0) | 278 | if (err < 0) |
273 | return err; | 279 | return err; |
274 | 280 | ||
275 | err = st6422_set_exposure(&sd->gspca_dev, | 281 | err = stv06xx_write_bridge(sd, 0x050b, gain); |
276 | sensor_settings[EXPOSURE_IDX]); | ||
277 | if (err < 0) | 282 | if (err < 0) |
278 | return err; | 283 | return err; |
279 | 284 | ||
280 | err = st6422_set_gain(&sd->gspca_dev, | 285 | /* 2 mystery writes */ |
281 | sensor_settings[GAIN_IDX]); | 286 | err = stv06xx_write_bridge(sd, 0x050c, 0x2a); |
282 | if (err < 0) | 287 | if (err < 0) |
283 | return err; | 288 | return err; |
284 | 289 | ||
285 | PDEBUG(D_STREAM, "Starting stream"); | 290 | return stv06xx_write_bridge(sd, 0x050d, 0x01); |
286 | |||
287 | return 0; | ||
288 | } | 291 | } |
289 | 292 | ||
290 | static int st6422_stop(struct sd *sd) | 293 | static int setexposure(struct sd *sd) |
291 | { | 294 | { |
292 | PDEBUG(D_STREAM, "Halting stream"); | 295 | struct st6422_settings *sensor_settings = sd->sensor_priv; |
293 | 296 | u16 expo; | |
294 | return 0; | 297 | int err; |
295 | } | ||
296 | |||
297 | static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
298 | { | ||
299 | struct sd *sd = (struct sd *) gspca_dev; | ||
300 | s32 *sensor_settings = sd->sensor_priv; | ||
301 | |||
302 | *val = sensor_settings[BRIGHTNESS_IDX]; | ||
303 | 298 | ||
304 | PDEBUG(D_V4L2, "Read brightness %d", *val); | 299 | expo = sensor_settings->ctrls[EXPOSURE].val; |
300 | err = stv06xx_write_bridge(sd, 0x143d, expo & 0xff); | ||
301 | if (err < 0) | ||
302 | return err; | ||
305 | 303 | ||
306 | return 0; | 304 | return stv06xx_write_bridge(sd, 0x143e, expo >> 8); |
307 | } | 305 | } |
308 | 306 | ||
309 | static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | 307 | static int st6422_start(struct sd *sd) |
310 | { | 308 | { |
311 | int err; | 309 | int err; |
312 | struct sd *sd = (struct sd *) gspca_dev; | 310 | struct cam *cam = &sd->gspca_dev.cam; |
313 | s32 *sensor_settings = sd->sensor_priv; | ||
314 | 311 | ||
315 | sensor_settings[BRIGHTNESS_IDX] = val; | 312 | if (cam->cam_mode[sd->gspca_dev.curr_mode].priv) |
313 | err = stv06xx_write_bridge(sd, 0x1505, 0x0f); | ||
314 | else | ||
315 | err = stv06xx_write_bridge(sd, 0x1505, 0x02); | ||
316 | if (err < 0) | ||
317 | return err; | ||
316 | 318 | ||
317 | if (!gspca_dev->streaming) | 319 | err = setbrightness(sd); |
318 | return 0; | 320 | if (err < 0) |
321 | return err; | ||
319 | 322 | ||
320 | /* val goes from 0 -> 31 */ | 323 | err = setcontrast(sd); |
321 | PDEBUG(D_V4L2, "Set brightness to %d", val); | 324 | if (err < 0) |
322 | err = stv06xx_write_bridge(sd, 0x1432, val); | 325 | return err; |
326 | |||
327 | err = setexposure(sd); | ||
328 | if (err < 0) | ||
329 | return err; | ||
330 | |||
331 | err = setgain(sd); | ||
323 | if (err < 0) | 332 | if (err < 0) |
324 | return err; | 333 | return err; |
325 | 334 | ||
@@ -328,125 +337,65 @@ static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | |||
328 | return (err < 0) ? err : 0; | 337 | return (err < 0) ? err : 0; |
329 | } | 338 | } |
330 | 339 | ||
331 | static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val) | 340 | static int st6422_stop(struct sd *sd) |
332 | { | 341 | { |
333 | struct sd *sd = (struct sd *) gspca_dev; | 342 | PDEBUG(D_STREAM, "Halting stream"); |
334 | s32 *sensor_settings = sd->sensor_priv; | ||
335 | |||
336 | *val = sensor_settings[CONTRAST_IDX]; | ||
337 | |||
338 | PDEBUG(D_V4L2, "Read contrast %d", *val); | ||
339 | 343 | ||
340 | return 0; | 344 | return 0; |
341 | } | 345 | } |
342 | 346 | ||
343 | static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val) | 347 | static void st6422_set_brightness(struct gspca_dev *gspca_dev) |
344 | { | 348 | { |
345 | int err; | 349 | int err; |
346 | struct sd *sd = (struct sd *) gspca_dev; | 350 | struct sd *sd = (struct sd *) gspca_dev; |
347 | s32 *sensor_settings = sd->sensor_priv; | ||
348 | |||
349 | sensor_settings[CONTRAST_IDX] = val; | ||
350 | 351 | ||
351 | if (!gspca_dev->streaming) | 352 | err = setbrightness(sd); |
352 | return 0; | ||
353 | |||
354 | /* Val goes from 0 -> 15 */ | ||
355 | PDEBUG(D_V4L2, "Set contrast to %d\n", val); | ||
356 | err = stv06xx_write_bridge(sd, 0x143a, 0xf0 | val); | ||
357 | if (err < 0) | ||
358 | return err; | ||
359 | 353 | ||
360 | /* commit settings */ | 354 | /* commit settings */ |
361 | err = stv06xx_write_bridge(sd, 0x143f, 0x01); | 355 | if (err >= 0) |
362 | return (err < 0) ? err : 0; | 356 | err = stv06xx_write_bridge(sd, 0x143f, 0x01); |
363 | } | ||
364 | |||
365 | static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | ||
366 | { | ||
367 | struct sd *sd = (struct sd *) gspca_dev; | ||
368 | s32 *sensor_settings = sd->sensor_priv; | ||
369 | |||
370 | *val = sensor_settings[GAIN_IDX]; | ||
371 | |||
372 | PDEBUG(D_V4L2, "Read gain %d", *val); | ||
373 | 357 | ||
374 | return 0; | 358 | gspca_dev->usb_err = err; |
375 | } | 359 | } |
376 | 360 | ||
377 | static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 361 | static void st6422_set_contrast(struct gspca_dev *gspca_dev) |
378 | { | 362 | { |
379 | int err; | 363 | int err; |
380 | struct sd *sd = (struct sd *) gspca_dev; | 364 | struct sd *sd = (struct sd *) gspca_dev; |
381 | s32 *sensor_settings = sd->sensor_priv; | ||
382 | |||
383 | sensor_settings[GAIN_IDX] = val; | ||
384 | |||
385 | if (!gspca_dev->streaming) | ||
386 | return 0; | ||
387 | |||
388 | PDEBUG(D_V4L2, "Set gain to %d", val); | ||
389 | 365 | ||
390 | /* Set red, green, blue, gain */ | 366 | err = setcontrast(sd); |
391 | err = stv06xx_write_bridge(sd, 0x0509, val); | ||
392 | if (err < 0) | ||
393 | return err; | ||
394 | |||
395 | err = stv06xx_write_bridge(sd, 0x050a, val); | ||
396 | if (err < 0) | ||
397 | return err; | ||
398 | |||
399 | err = stv06xx_write_bridge(sd, 0x050b, val); | ||
400 | if (err < 0) | ||
401 | return err; | ||
402 | |||
403 | /* 2 mystery writes */ | ||
404 | err = stv06xx_write_bridge(sd, 0x050c, 0x2a); | ||
405 | if (err < 0) | ||
406 | return err; | ||
407 | |||
408 | err = stv06xx_write_bridge(sd, 0x050d, 0x01); | ||
409 | if (err < 0) | ||
410 | return err; | ||
411 | 367 | ||
412 | /* commit settings */ | 368 | /* commit settings */ |
413 | err = stv06xx_write_bridge(sd, 0x143f, 0x01); | 369 | if (err >= 0) |
414 | return (err < 0) ? err : 0; | 370 | err = stv06xx_write_bridge(sd, 0x143f, 0x01); |
371 | |||
372 | gspca_dev->usb_err = err; | ||
415 | } | 373 | } |
416 | 374 | ||
417 | static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 375 | static void st6422_set_gain(struct gspca_dev *gspca_dev) |
418 | { | 376 | { |
377 | int err; | ||
419 | struct sd *sd = (struct sd *) gspca_dev; | 378 | struct sd *sd = (struct sd *) gspca_dev; |
420 | s32 *sensor_settings = sd->sensor_priv; | ||
421 | 379 | ||
422 | *val = sensor_settings[EXPOSURE_IDX]; | 380 | err = setgain(sd); |
423 | 381 | ||
424 | PDEBUG(D_V4L2, "Read exposure %d", *val); | 382 | /* commit settings */ |
383 | if (err >= 0) | ||
384 | err = stv06xx_write_bridge(sd, 0x143f, 0x01); | ||
425 | 385 | ||
426 | return 0; | 386 | gspca_dev->usb_err = err; |
427 | } | 387 | } |
428 | 388 | ||
429 | static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 389 | static void st6422_set_exposure(struct gspca_dev *gspca_dev) |
430 | { | 390 | { |
431 | int err; | 391 | int err; |
432 | struct sd *sd = (struct sd *) gspca_dev; | 392 | struct sd *sd = (struct sd *) gspca_dev; |
433 | s32 *sensor_settings = sd->sensor_priv; | ||
434 | |||
435 | sensor_settings[EXPOSURE_IDX] = val; | ||
436 | 393 | ||
437 | if (!gspca_dev->streaming) | 394 | err = setexposure(sd); |
438 | return 0; | ||
439 | |||
440 | PDEBUG(D_V4L2, "Set exposure to %d\n", val); | ||
441 | err = stv06xx_write_bridge(sd, 0x143d, val & 0xff); | ||
442 | if (err < 0) | ||
443 | return err; | ||
444 | |||
445 | err = stv06xx_write_bridge(sd, 0x143e, val >> 8); | ||
446 | if (err < 0) | ||
447 | return err; | ||
448 | 395 | ||
449 | /* commit settings */ | 396 | /* commit settings */ |
450 | err = stv06xx_write_bridge(sd, 0x143f, 0x01); | 397 | if (err >= 0) |
451 | return (err < 0) ? err : 0; | 398 | err = stv06xx_write_bridge(sd, 0x143f, 0x01); |
399 | |||
400 | gspca_dev->usb_err = err; | ||
452 | } | 401 | } |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h index b2d45fe50522..d7498e06432b 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h | |||
@@ -37,18 +37,11 @@ static int st6422_init(struct sd *sd); | |||
37 | static int st6422_stop(struct sd *sd); | 37 | static int st6422_stop(struct sd *sd); |
38 | static void st6422_disconnect(struct sd *sd); | 38 | static void st6422_disconnect(struct sd *sd); |
39 | 39 | ||
40 | /* V4L2 controls supported by the driver */ | ||
41 | static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
42 | static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | ||
43 | static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
44 | static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val); | ||
45 | static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
46 | static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
47 | static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
48 | static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
49 | |||
50 | const struct stv06xx_sensor stv06xx_sensor_st6422 = { | 40 | const struct stv06xx_sensor stv06xx_sensor_st6422 = { |
51 | .name = "ST6422", | 41 | .name = "ST6422", |
42 | /* No known way to lower framerate in case of less bandwidth */ | ||
43 | .min_packet_size = { 300, 847 }, | ||
44 | .max_packet_size = { 300, 847 }, | ||
52 | .init = st6422_init, | 45 | .init = st6422_init, |
53 | .probe = st6422_probe, | 46 | .probe = st6422_probe, |
54 | .start = st6422_start, | 47 | .start = st6422_start, |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h index b3b5508473bc..7fe3587f5f71 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h | |||
@@ -197,6 +197,10 @@ const struct stv06xx_sensor stv06xx_sensor_vv6410 = { | |||
197 | .i2c_flush = 5, | 197 | .i2c_flush = 5, |
198 | .i2c_addr = 0x20, | 198 | .i2c_addr = 0x20, |
199 | .i2c_len = 1, | 199 | .i2c_len = 1, |
200 | /* FIXME (see if we can lower packet_size-s, needs testing, and also | ||
201 | adjusting framerate when the bandwidth gets lower) */ | ||
202 | .min_packet_size = { 1023 }, | ||
203 | .max_packet_size = { 1023 }, | ||
200 | .init = vv6410_init, | 204 | .init = vv6410_init, |
201 | .probe = vv6410_probe, | 205 | .probe = vv6410_probe, |
202 | .start = vv6410_start, | 206 | .start = vv6410_start, |
@@ -220,10 +224,6 @@ static const u8 x1536[] = { /* 0x1536 - 0x153b */ | |||
220 | 0x02, 0x00, 0x60, 0x01, 0x20, 0x01 | 224 | 0x02, 0x00, 0x60, 0x01, 0x20, 0x01 |
221 | }; | 225 | }; |
222 | 226 | ||
223 | static const u8 x15c1[] = { /* 0x15c1 - 0x15c2 */ | ||
224 | 0xff, 0x03 /* Output word 0x03ff = 1023 (ISO size) */ | ||
225 | }; | ||
226 | |||
227 | static const struct stv_init stv_bridge_init[] = { | 227 | static const struct stv_init stv_bridge_init[] = { |
228 | /* This reg is written twice. Some kind of reset? */ | 228 | /* This reg is written twice. Some kind of reset? */ |
229 | {NULL, 0x1620, 0x80}, | 229 | {NULL, 0x1620, 0x80}, |
@@ -232,7 +232,6 @@ static const struct stv_init stv_bridge_init[] = { | |||
232 | {NULL, 0x1423, 0x04}, | 232 | {NULL, 0x1423, 0x04}, |
233 | {x1500, 0x1500, ARRAY_SIZE(x1500)}, | 233 | {x1500, 0x1500, ARRAY_SIZE(x1500)}, |
234 | {x1536, 0x1536, ARRAY_SIZE(x1536)}, | 234 | {x1536, 0x1536, ARRAY_SIZE(x1536)}, |
235 | {x15c1, 0x15c1, ARRAY_SIZE(x15c1)} | ||
236 | }; | 235 | }; |
237 | 236 | ||
238 | static const u8 vv6410_sensor_init[][2] = { | 237 | static const u8 vv6410_sensor_init[][2] = { |
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index b45f4d0f3997..8f0c33116e0d 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c | |||
@@ -487,7 +487,7 @@ static const u8 gamma_table[GAMMA_MAX][17] = { | |||
487 | {0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f, /* 3 */ | 487 | {0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f, /* 3 */ |
488 | 0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6, | 488 | 0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6, |
489 | 0xff}, | 489 | 0xff}, |
490 | {0x00, 0x04, 0x0B, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */ | 490 | {0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */ |
491 | 0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9, | 491 | 0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9, |
492 | 0xff}, | 492 | 0xff}, |
493 | {0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58, /* 5 */ | 493 | {0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58, /* 5 */ |
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index d9e3c6050781..38c22f0a4263 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c | |||
@@ -132,7 +132,7 @@ static const struct v4l2_pix_format sif_mode[] = { | |||
132 | #define R36_PID 0x36 | 132 | #define R36_PID 0x36 |
133 | #define R37_PIDH 0x37 | 133 | #define R37_PIDH 0x37 |
134 | #define R39_Test1 0x39 /* GPIO */ | 134 | #define R39_Test1 0x39 /* GPIO */ |
135 | #define R3B_Test3 0x3B /* GPIO */ | 135 | #define R3B_Test3 0x3b /* GPIO */ |
136 | #define R83_AD_IDH 0x83 | 136 | #define R83_AD_IDH 0x83 |
137 | #define R91_AD_SLOPEREG 0x91 | 137 | #define R91_AD_SLOPEREG 0x91 |
138 | #define R94_AD_BITCONTROL 0x94 | 138 | #define R94_AD_BITCONTROL 0x94 |
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 38a6efe1a5f9..9b2ae1b6cc75 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c | |||
@@ -47,24 +47,29 @@ struct sd { | |||
47 | u8 image_offset; | 47 | u8 image_offset; |
48 | 48 | ||
49 | u8 bridge; | 49 | u8 bridge; |
50 | #define BRIDGE_VC0321 0 | ||
51 | #define BRIDGE_VC0323 1 | ||
52 | u8 sensor; | 50 | u8 sensor; |
53 | #define SENSOR_HV7131R 0 | ||
54 | #define SENSOR_MI0360 1 | ||
55 | #define SENSOR_MI1310_SOC 2 | ||
56 | #define SENSOR_MI1320 3 | ||
57 | #define SENSOR_MI1320_SOC 4 | ||
58 | #define SENSOR_OV7660 5 | ||
59 | #define SENSOR_OV7670 6 | ||
60 | #define SENSOR_PO1200 7 | ||
61 | #define SENSOR_PO3130NC 8 | ||
62 | #define SENSOR_POxxxx 9 | ||
63 | u8 flags; | 51 | u8 flags; |
64 | #define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */ | 52 | #define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */ |
65 | #define FL_HFLIP 0x02 /* mirrored by default */ | 53 | #define FL_HFLIP 0x02 /* mirrored by default */ |
66 | #define FL_VFLIP 0x04 /* vertical flipped by default */ | 54 | #define FL_VFLIP 0x04 /* vertical flipped by default */ |
67 | }; | 55 | }; |
56 | enum bridges { | ||
57 | BRIDGE_VC0321, | ||
58 | BRIDGE_VC0323, | ||
59 | }; | ||
60 | enum sensors { | ||
61 | SENSOR_HV7131R, | ||
62 | SENSOR_MI0360, | ||
63 | SENSOR_MI1310_SOC, | ||
64 | SENSOR_MI1320, | ||
65 | SENSOR_MI1320_SOC, | ||
66 | SENSOR_OV7660, | ||
67 | SENSOR_OV7670, | ||
68 | SENSOR_PO1200, | ||
69 | SENSOR_PO3130NC, | ||
70 | SENSOR_POxxxx, | ||
71 | NSENSORS | ||
72 | }; | ||
68 | 73 | ||
69 | /* V4L2 controls supported by the driver */ | 74 | /* V4L2 controls supported by the driver */ |
70 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | 75 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); |
@@ -260,56 +265,56 @@ static const struct ctrl sd_ctrls[] = { | |||
260 | }; | 265 | }; |
261 | 266 | ||
262 | /* table of the disabled controls */ | 267 | /* table of the disabled controls */ |
263 | static u32 ctrl_dis[] = { | 268 | static u32 ctrl_dis[NSENSORS] = { |
264 | /* SENSOR_HV7131R 0 */ | 269 | [SENSOR_HV7131R] = |
265 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | 270 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) |
266 | | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX) | 271 | | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX) |
267 | | (1 << SHARPNESS_IDX) | 272 | | (1 << SHARPNESS_IDX) |
268 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | 273 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) |
269 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | 274 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), |
270 | /* SENSOR_MI0360 1 */ | 275 | [SENSOR_MI0360] = |
271 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | 276 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) |
272 | | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX) | 277 | | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX) |
273 | | (1 << SHARPNESS_IDX) | 278 | | (1 << SHARPNESS_IDX) |
274 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | 279 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) |
275 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | 280 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), |
276 | /* SENSOR_MI1310_SOC 2 */ | 281 | [SENSOR_MI1310_SOC] = |
277 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | 282 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) |
278 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) | 283 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) |
279 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | 284 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) |
280 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | 285 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), |
281 | /* SENSOR_MI1320 3 */ | 286 | [SENSOR_MI1320] = |
282 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | 287 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) |
283 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) | 288 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) |
284 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | 289 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) |
285 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | 290 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), |
286 | /* SENSOR_MI1320_SOC 4 */ | 291 | [SENSOR_MI1320_SOC] = |
287 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | 292 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) |
288 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) | 293 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) |
289 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | 294 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) |
290 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | 295 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), |
291 | /* SENSOR_OV7660 5 */ | 296 | [SENSOR_OV7660] = |
292 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | 297 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) |
293 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) | 298 | | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX) |
294 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | 299 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) |
295 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | 300 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), |
296 | /* SENSOR_OV7670 6 */ | 301 | [SENSOR_OV7670] = |
297 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | 302 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) |
298 | | (1 << SHARPNESS_IDX) | 303 | | (1 << SHARPNESS_IDX) |
299 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | 304 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) |
300 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | 305 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), |
301 | /* SENSOR_PO1200 7 */ | 306 | [SENSOR_PO1200] = |
302 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | 307 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) |
303 | | (1 << LIGHTFREQ_IDX) | 308 | | (1 << LIGHTFREQ_IDX) |
304 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | 309 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) |
305 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | 310 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), |
306 | /* SENSOR_PO3130NC 8 */ | 311 | [SENSOR_PO3130NC] = |
307 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) | 312 | (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX) |
308 | | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX) | 313 | | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX) |
309 | | (1 << SHARPNESS_IDX) | 314 | | (1 << SHARPNESS_IDX) |
310 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) | 315 | | (1 << GAIN_IDX) | (1 << EXPOSURE_IDX) |
311 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), | 316 | | (1 << AUTOGAIN_IDX) | (1 << BACKLIGHT_IDX), |
312 | /* SENSOR_POxxxx 9 */ | 317 | [SENSOR_POxxxx] = |
313 | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX), | 318 | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX), |
314 | }; | 319 | }; |
315 | 320 | ||
@@ -3420,17 +3425,18 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3420 | struct sd *sd = (struct sd *) gspca_dev; | 3425 | struct sd *sd = (struct sd *) gspca_dev; |
3421 | struct cam *cam; | 3426 | struct cam *cam; |
3422 | int sensor; | 3427 | int sensor; |
3423 | static u8 npkt[] = { /* number of packets per ISOC message */ | 3428 | /* number of packets per ISOC message */ |
3424 | 64, /* HV7131R 0 */ | 3429 | static u8 npkt[NSENSORS] = { |
3425 | 32, /* MI0360 1 */ | 3430 | [SENSOR_HV7131R] = 64, |
3426 | 32, /* MI1310_SOC 2 */ | 3431 | [SENSOR_MI0360] = 32, |
3427 | 64, /* MI1320 3 */ | 3432 | [SENSOR_MI1310_SOC] = 32, |
3428 | 128, /* MI1320_SOC 4 */ | 3433 | [SENSOR_MI1320] = 64, |
3429 | 32, /* OV7660 5 */ | 3434 | [SENSOR_MI1320_SOC] = 128, |
3430 | 64, /* OV7670 6 */ | 3435 | [SENSOR_OV7660] = 32, |
3431 | 128, /* PO1200 7 */ | 3436 | [SENSOR_OV7670] = 64, |
3432 | 128, /* PO3130NC 8 */ | 3437 | [SENSOR_PO1200] = 128, |
3433 | 128, /* POxxxx 9 */ | 3438 | [SENSOR_PO3130NC] = 128, |
3439 | [SENSOR_POxxxx] = 128, | ||
3434 | }; | 3440 | }; |
3435 | 3441 | ||
3436 | if (sd->sensor != SENSOR_POxxxx) | 3442 | if (sd->sensor != SENSOR_POxxxx) |
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c index 4066ac8c45a0..4a9e622e5e1b 100644 --- a/drivers/media/video/gspca/w996Xcf.c +++ b/drivers/media/video/gspca/w996Xcf.c | |||
@@ -59,18 +59,21 @@ static const struct v4l2_pix_format w9968cf_vga_mode[] = { | |||
59 | .colorspace = V4L2_COLORSPACE_JPEG}, | 59 | .colorspace = V4L2_COLORSPACE_JPEG}, |
60 | }; | 60 | }; |
61 | 61 | ||
62 | static int reg_w(struct sd *sd, __u16 index, __u16 value); | 62 | static void reg_w(struct sd *sd, u16 index, u16 value); |
63 | 63 | ||
64 | /*-------------------------------------------------------------------------- | 64 | /*-------------------------------------------------------------------------- |
65 | Write 64-bit data to the fast serial bus registers. | 65 | Write 64-bit data to the fast serial bus registers. |
66 | Return 0 on success, -1 otherwise. | 66 | Return 0 on success, -1 otherwise. |
67 | --------------------------------------------------------------------------*/ | 67 | --------------------------------------------------------------------------*/ |
68 | static int w9968cf_write_fsb(struct sd *sd, u16* data) | 68 | static void w9968cf_write_fsb(struct sd *sd, u16* data) |
69 | { | 69 | { |
70 | struct usb_device *udev = sd->gspca_dev.dev; | 70 | struct usb_device *udev = sd->gspca_dev.dev; |
71 | u16 value; | 71 | u16 value; |
72 | int ret; | 72 | int ret; |
73 | 73 | ||
74 | if (sd->gspca_dev.usb_err < 0) | ||
75 | return; | ||
76 | |||
74 | value = *data++; | 77 | value = *data++; |
75 | memcpy(sd->gspca_dev.usb_buf, data, 6); | 78 | memcpy(sd->gspca_dev.usb_buf, data, 6); |
76 | 79 | ||
@@ -79,20 +82,21 @@ static int w9968cf_write_fsb(struct sd *sd, u16* data) | |||
79 | value, 0x06, sd->gspca_dev.usb_buf, 6, 500); | 82 | value, 0x06, sd->gspca_dev.usb_buf, 6, 500); |
80 | if (ret < 0) { | 83 | if (ret < 0) { |
81 | err("Write FSB registers failed (%d)", ret); | 84 | err("Write FSB registers failed (%d)", ret); |
82 | return ret; | 85 | sd->gspca_dev.usb_err = ret; |
83 | } | 86 | } |
84 | |||
85 | return 0; | ||
86 | } | 87 | } |
87 | 88 | ||
88 | /*-------------------------------------------------------------------------- | 89 | /*-------------------------------------------------------------------------- |
89 | Write data to the serial bus control register. | 90 | Write data to the serial bus control register. |
90 | Return 0 on success, a negative number otherwise. | 91 | Return 0 on success, a negative number otherwise. |
91 | --------------------------------------------------------------------------*/ | 92 | --------------------------------------------------------------------------*/ |
92 | static int w9968cf_write_sb(struct sd *sd, u16 value) | 93 | static void w9968cf_write_sb(struct sd *sd, u16 value) |
93 | { | 94 | { |
94 | int ret; | 95 | int ret; |
95 | 96 | ||
97 | if (sd->gspca_dev.usb_err < 0) | ||
98 | return; | ||
99 | |||
96 | /* We don't use reg_w here, as that would cause all writes when | 100 | /* We don't use reg_w here, as that would cause all writes when |
97 | bitbanging i2c to be logged, making the logs impossible to read */ | 101 | bitbanging i2c to be logged, making the logs impossible to read */ |
98 | ret = usb_control_msg(sd->gspca_dev.dev, | 102 | ret = usb_control_msg(sd->gspca_dev.dev, |
@@ -105,10 +109,8 @@ static int w9968cf_write_sb(struct sd *sd, u16 value) | |||
105 | 109 | ||
106 | if (ret < 0) { | 110 | if (ret < 0) { |
107 | err("Write SB reg [01] %04x failed", value); | 111 | err("Write SB reg [01] %04x failed", value); |
108 | return ret; | 112 | sd->gspca_dev.usb_err = ret; |
109 | } | 113 | } |
110 | |||
111 | return 0; | ||
112 | } | 114 | } |
113 | 115 | ||
114 | /*-------------------------------------------------------------------------- | 116 | /*-------------------------------------------------------------------------- |
@@ -119,6 +121,9 @@ static int w9968cf_read_sb(struct sd *sd) | |||
119 | { | 121 | { |
120 | int ret; | 122 | int ret; |
121 | 123 | ||
124 | if (sd->gspca_dev.usb_err < 0) | ||
125 | return -1; | ||
126 | |||
122 | /* We don't use reg_r here, as the w9968cf is special and has 16 | 127 | /* We don't use reg_r here, as the w9968cf is special and has 16 |
123 | bit registers instead of 8 bit */ | 128 | bit registers instead of 8 bit */ |
124 | ret = usb_control_msg(sd->gspca_dev.dev, | 129 | ret = usb_control_msg(sd->gspca_dev.dev, |
@@ -126,11 +131,13 @@ static int w9968cf_read_sb(struct sd *sd) | |||
126 | 1, | 131 | 1, |
127 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 132 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
128 | 0, 0x01, sd->gspca_dev.usb_buf, 2, 500); | 133 | 0, 0x01, sd->gspca_dev.usb_buf, 2, 500); |
129 | if (ret >= 0) | 134 | if (ret >= 0) { |
130 | ret = sd->gspca_dev.usb_buf[0] | | 135 | ret = sd->gspca_dev.usb_buf[0] | |
131 | (sd->gspca_dev.usb_buf[1] << 8); | 136 | (sd->gspca_dev.usb_buf[1] << 8); |
132 | else | 137 | } else { |
133 | err("Read SB reg [01] failed"); | 138 | err("Read SB reg [01] failed"); |
139 | sd->gspca_dev.usb_err = ret; | ||
140 | } | ||
134 | 141 | ||
135 | udelay(W9968CF_I2C_BUS_DELAY); | 142 | udelay(W9968CF_I2C_BUS_DELAY); |
136 | 143 | ||
@@ -142,22 +149,20 @@ static int w9968cf_read_sb(struct sd *sd) | |||
142 | This function is called by w9968cf_start_transfer(). | 149 | This function is called by w9968cf_start_transfer(). |
143 | Return 0 on success, a negative number otherwise. | 150 | Return 0 on success, a negative number otherwise. |
144 | --------------------------------------------------------------------------*/ | 151 | --------------------------------------------------------------------------*/ |
145 | static int w9968cf_upload_quantizationtables(struct sd *sd) | 152 | static void w9968cf_upload_quantizationtables(struct sd *sd) |
146 | { | 153 | { |
147 | u16 a, b; | 154 | u16 a, b; |
148 | int ret = 0, i, j; | 155 | int i, j; |
149 | 156 | ||
150 | ret += reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */ | 157 | reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */ |
151 | 158 | ||
152 | for (i = 0, j = 0; i < 32; i++, j += 2) { | 159 | for (i = 0, j = 0; i < 32; i++, j += 2) { |
153 | a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8); | 160 | a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j + 1]) << 8); |
154 | b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8); | 161 | b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j + 1]) << 8); |
155 | ret += reg_w(sd, 0x40+i, a); | 162 | reg_w(sd, 0x40 + i, a); |
156 | ret += reg_w(sd, 0x60+i, b); | 163 | reg_w(sd, 0x60 + i, b); |
157 | } | 164 | } |
158 | ret += reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */ | 165 | reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */ |
159 | |||
160 | return ret; | ||
161 | } | 166 | } |
162 | 167 | ||
163 | /**************************************************************************** | 168 | /**************************************************************************** |
@@ -168,50 +173,39 @@ static int w9968cf_upload_quantizationtables(struct sd *sd) | |||
168 | * i2c_adap_read_byte() * | 173 | * i2c_adap_read_byte() * |
169 | ****************************************************************************/ | 174 | ****************************************************************************/ |
170 | 175 | ||
171 | static int w9968cf_smbus_start(struct sd *sd) | 176 | static void w9968cf_smbus_start(struct sd *sd) |
172 | { | 177 | { |
173 | int ret = 0; | 178 | w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */ |
174 | 179 | w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */ | |
175 | ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */ | ||
176 | ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */ | ||
177 | |||
178 | return ret; | ||
179 | } | 180 | } |
180 | 181 | ||
181 | static int w9968cf_smbus_stop(struct sd *sd) | 182 | static void w9968cf_smbus_stop(struct sd *sd) |
182 | { | 183 | { |
183 | int ret = 0; | 184 | w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */ |
184 | 185 | w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */ | |
185 | ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */ | 186 | w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ |
186 | ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */ | ||
187 | ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ | ||
188 | |||
189 | return ret; | ||
190 | } | 187 | } |
191 | 188 | ||
192 | static int w9968cf_smbus_write_byte(struct sd *sd, u8 v) | 189 | static void w9968cf_smbus_write_byte(struct sd *sd, u8 v) |
193 | { | 190 | { |
194 | u8 bit; | 191 | u8 bit; |
195 | int ret = 0, sda; | 192 | int sda; |
196 | 193 | ||
197 | for (bit = 0 ; bit < 8 ; bit++) { | 194 | for (bit = 0 ; bit < 8 ; bit++) { |
198 | sda = (v & 0x80) ? 2 : 0; | 195 | sda = (v & 0x80) ? 2 : 0; |
199 | v <<= 1; | 196 | v <<= 1; |
200 | /* SDE=1, SDA=sda, SCL=0 */ | 197 | /* SDE=1, SDA=sda, SCL=0 */ |
201 | ret += w9968cf_write_sb(sd, 0x10 | sda); | 198 | w9968cf_write_sb(sd, 0x10 | sda); |
202 | /* SDE=1, SDA=sda, SCL=1 */ | 199 | /* SDE=1, SDA=sda, SCL=1 */ |
203 | ret += w9968cf_write_sb(sd, 0x11 | sda); | 200 | w9968cf_write_sb(sd, 0x11 | sda); |
204 | /* SDE=1, SDA=sda, SCL=0 */ | 201 | /* SDE=1, SDA=sda, SCL=0 */ |
205 | ret += w9968cf_write_sb(sd, 0x10 | sda); | 202 | w9968cf_write_sb(sd, 0x10 | sda); |
206 | } | 203 | } |
207 | |||
208 | return ret; | ||
209 | } | 204 | } |
210 | 205 | ||
211 | static int w9968cf_smbus_read_byte(struct sd *sd, u8* v) | 206 | static void w9968cf_smbus_read_byte(struct sd *sd, u8 *v) |
212 | { | 207 | { |
213 | u8 bit; | 208 | u8 bit; |
214 | int ret = 0; | ||
215 | 209 | ||
216 | /* No need to ensure SDA is high as we are always called after | 210 | /* No need to ensure SDA is high as we are always called after |
217 | read_ack which ends with SDA high */ | 211 | read_ack which ends with SDA high */ |
@@ -219,51 +213,40 @@ static int w9968cf_smbus_read_byte(struct sd *sd, u8* v) | |||
219 | for (bit = 0 ; bit < 8 ; bit++) { | 213 | for (bit = 0 ; bit < 8 ; bit++) { |
220 | *v <<= 1; | 214 | *v <<= 1; |
221 | /* SDE=1, SDA=1, SCL=1 */ | 215 | /* SDE=1, SDA=1, SCL=1 */ |
222 | ret += w9968cf_write_sb(sd, 0x0013); | 216 | w9968cf_write_sb(sd, 0x0013); |
223 | *v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0; | 217 | *v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0; |
224 | /* SDE=1, SDA=1, SCL=0 */ | 218 | /* SDE=1, SDA=1, SCL=0 */ |
225 | ret += w9968cf_write_sb(sd, 0x0012); | 219 | w9968cf_write_sb(sd, 0x0012); |
226 | } | 220 | } |
227 | |||
228 | return ret; | ||
229 | } | 221 | } |
230 | 222 | ||
231 | static int w9968cf_smbus_write_nack(struct sd *sd) | 223 | static void w9968cf_smbus_write_nack(struct sd *sd) |
232 | { | 224 | { |
233 | int ret = 0; | ||
234 | |||
235 | /* No need to ensure SDA is high as we are always called after | 225 | /* No need to ensure SDA is high as we are always called after |
236 | read_byte which ends with SDA high */ | 226 | read_byte which ends with SDA high */ |
237 | ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ | 227 | w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ |
238 | ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ | 228 | w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ |
239 | |||
240 | return ret; | ||
241 | } | 229 | } |
242 | 230 | ||
243 | static int w9968cf_smbus_read_ack(struct sd *sd) | 231 | static void w9968cf_smbus_read_ack(struct sd *sd) |
244 | { | 232 | { |
245 | int ret = 0, sda; | 233 | int sda; |
246 | 234 | ||
247 | /* Ensure SDA is high before raising clock to avoid a spurious stop */ | 235 | /* Ensure SDA is high before raising clock to avoid a spurious stop */ |
248 | ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ | 236 | w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ |
249 | ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ | 237 | w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ |
250 | sda = w9968cf_read_sb(sd); | 238 | sda = w9968cf_read_sb(sd); |
251 | ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ | 239 | w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ |
252 | if (sda < 0) | 240 | if (sda >= 0 && (sda & 0x08)) { |
253 | ret += sda; | ||
254 | else if (sda & 0x08) { | ||
255 | PDEBUG(D_USBI, "Did not receive i2c ACK"); | 241 | PDEBUG(D_USBI, "Did not receive i2c ACK"); |
256 | ret += -1; | 242 | sd->gspca_dev.usb_err = -EIO; |
257 | } | 243 | } |
258 | |||
259 | return ret; | ||
260 | } | 244 | } |
261 | 245 | ||
262 | /* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */ | 246 | /* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */ |
263 | static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value) | 247 | static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value) |
264 | { | 248 | { |
265 | u16* data = (u16 *)sd->gspca_dev.usb_buf; | 249 | u16* data = (u16 *)sd->gspca_dev.usb_buf; |
266 | int ret = 0; | ||
267 | 250 | ||
268 | data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0); | 251 | data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0); |
269 | data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0; | 252 | data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0; |
@@ -276,7 +259,7 @@ static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value) | |||
276 | data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0); | 259 | data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0); |
277 | data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0; | 260 | data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0; |
278 | 261 | ||
279 | ret += w9968cf_write_fsb(sd, data); | 262 | w9968cf_write_fsb(sd, data); |
280 | 263 | ||
281 | data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0); | 264 | data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0); |
282 | data[0] |= (reg & 0x40) ? 0x0540 : 0x0; | 265 | data[0] |= (reg & 0x40) ? 0x0540 : 0x0; |
@@ -290,7 +273,7 @@ static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value) | |||
290 | data[2] |= (reg & 0x01) ? 0x5400 : 0x0; | 273 | data[2] |= (reg & 0x01) ? 0x5400 : 0x0; |
291 | data[3] = 0x001d; | 274 | data[3] = 0x001d; |
292 | 275 | ||
293 | ret += w9968cf_write_fsb(sd, data); | 276 | w9968cf_write_fsb(sd, data); |
294 | 277 | ||
295 | data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0); | 278 | data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0); |
296 | data[0] |= (value & 0x40) ? 0x0540 : 0x0; | 279 | data[0] |= (value & 0x40) ? 0x0540 : 0x0; |
@@ -304,14 +287,9 @@ static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value) | |||
304 | data[2] |= (value & 0x01) ? 0x5400 : 0x0; | 287 | data[2] |= (value & 0x01) ? 0x5400 : 0x0; |
305 | data[3] = 0xfe1d; | 288 | data[3] = 0xfe1d; |
306 | 289 | ||
307 | ret += w9968cf_write_fsb(sd, data); | 290 | w9968cf_write_fsb(sd, data); |
308 | 291 | ||
309 | if (!ret) | 292 | PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); |
310 | PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); | ||
311 | else | ||
312 | PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg); | ||
313 | |||
314 | return ret; | ||
315 | } | 293 | } |
316 | 294 | ||
317 | /* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */ | 295 | /* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */ |
@@ -321,28 +299,28 @@ static int w9968cf_i2c_r(struct sd *sd, u8 reg) | |||
321 | u8 value; | 299 | u8 value; |
322 | 300 | ||
323 | /* Fast serial bus data control disable */ | 301 | /* Fast serial bus data control disable */ |
324 | ret += w9968cf_write_sb(sd, 0x0013); /* don't change ! */ | 302 | w9968cf_write_sb(sd, 0x0013); /* don't change ! */ |
325 | 303 | ||
326 | ret += w9968cf_smbus_start(sd); | 304 | w9968cf_smbus_start(sd); |
327 | ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr); | 305 | w9968cf_smbus_write_byte(sd, sd->sensor_addr); |
328 | ret += w9968cf_smbus_read_ack(sd); | 306 | w9968cf_smbus_read_ack(sd); |
329 | ret += w9968cf_smbus_write_byte(sd, reg); | 307 | w9968cf_smbus_write_byte(sd, reg); |
330 | ret += w9968cf_smbus_read_ack(sd); | 308 | w9968cf_smbus_read_ack(sd); |
331 | ret += w9968cf_smbus_stop(sd); | 309 | w9968cf_smbus_stop(sd); |
332 | ret += w9968cf_smbus_start(sd); | 310 | w9968cf_smbus_start(sd); |
333 | ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1); | 311 | w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1); |
334 | ret += w9968cf_smbus_read_ack(sd); | 312 | w9968cf_smbus_read_ack(sd); |
335 | ret += w9968cf_smbus_read_byte(sd, &value); | 313 | w9968cf_smbus_read_byte(sd, &value); |
336 | /* signal we don't want to read anymore, the v4l1 driver used to | 314 | /* signal we don't want to read anymore, the v4l1 driver used to |
337 | send an ack here which is very wrong! (and then fixed | 315 | send an ack here which is very wrong! (and then fixed |
338 | the issues this gave by retrying reads) */ | 316 | the issues this gave by retrying reads) */ |
339 | ret += w9968cf_smbus_write_nack(sd); | 317 | w9968cf_smbus_write_nack(sd); |
340 | ret += w9968cf_smbus_stop(sd); | 318 | w9968cf_smbus_stop(sd); |
341 | 319 | ||
342 | /* Fast serial bus data control re-enable */ | 320 | /* Fast serial bus data control re-enable */ |
343 | ret += w9968cf_write_sb(sd, 0x0030); | 321 | w9968cf_write_sb(sd, 0x0030); |
344 | 322 | ||
345 | if (!ret) { | 323 | if (sd->gspca_dev.usb_err >= 0) { |
346 | ret = value; | 324 | ret = value; |
347 | PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); | 325 | PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); |
348 | } else | 326 | } else |
@@ -351,79 +329,68 @@ static int w9968cf_i2c_r(struct sd *sd, u8 reg) | |||
351 | return ret; | 329 | return ret; |
352 | } | 330 | } |
353 | 331 | ||
354 | |||
355 | /*-------------------------------------------------------------------------- | 332 | /*-------------------------------------------------------------------------- |
356 | Turn on the LED on some webcams. A beep should be heard too. | 333 | Turn on the LED on some webcams. A beep should be heard too. |
357 | Return 0 on success, a negative number otherwise. | 334 | Return 0 on success, a negative number otherwise. |
358 | --------------------------------------------------------------------------*/ | 335 | --------------------------------------------------------------------------*/ |
359 | static int w9968cf_configure(struct sd *sd) | 336 | static void w9968cf_configure(struct sd *sd) |
360 | { | 337 | { |
361 | int ret = 0; | 338 | reg_w(sd, 0x00, 0xff00); /* power-down */ |
362 | 339 | reg_w(sd, 0x00, 0xbf17); /* reset everything */ | |
363 | ret += reg_w(sd, 0x00, 0xff00); /* power-down */ | 340 | reg_w(sd, 0x00, 0xbf10); /* normal operation */ |
364 | ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */ | 341 | reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */ |
365 | ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */ | 342 | reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */ |
366 | ret += reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */ | 343 | reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */ |
367 | ret += reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */ | 344 | reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */ |
368 | ret += reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */ | ||
369 | ret += reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */ | ||
370 | |||
371 | if (ret) | ||
372 | PDEBUG(D_ERR, "Couldn't turn on the LED"); | ||
373 | 345 | ||
374 | sd->stopped = 1; | 346 | sd->stopped = 1; |
375 | |||
376 | return ret; | ||
377 | } | 347 | } |
378 | 348 | ||
379 | static int w9968cf_init(struct sd *sd) | 349 | static void w9968cf_init(struct sd *sd) |
380 | { | 350 | { |
381 | int ret = 0; | ||
382 | unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2), | 351 | unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2), |
383 | y0 = 0x0000, | 352 | y0 = 0x0000, |
384 | u0 = y0 + hw_bufsize/2, | 353 | u0 = y0 + hw_bufsize / 2, |
385 | v0 = u0 + hw_bufsize/4, | 354 | v0 = u0 + hw_bufsize / 4, |
386 | y1 = v0 + hw_bufsize/4, | 355 | y1 = v0 + hw_bufsize / 4, |
387 | u1 = y1 + hw_bufsize/2, | 356 | u1 = y1 + hw_bufsize / 2, |
388 | v1 = u1 + hw_bufsize/4; | 357 | v1 = u1 + hw_bufsize / 4; |
389 | 358 | ||
390 | ret += reg_w(sd, 0x00, 0xff00); /* power off */ | 359 | reg_w(sd, 0x00, 0xff00); /* power off */ |
391 | ret += reg_w(sd, 0x00, 0xbf10); /* power on */ | 360 | reg_w(sd, 0x00, 0xbf10); /* power on */ |
392 | 361 | ||
393 | ret += reg_w(sd, 0x03, 0x405d); /* DRAM timings */ | 362 | reg_w(sd, 0x03, 0x405d); /* DRAM timings */ |
394 | ret += reg_w(sd, 0x04, 0x0030); /* SDRAM timings */ | 363 | reg_w(sd, 0x04, 0x0030); /* SDRAM timings */ |
395 | 364 | ||
396 | ret += reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */ | 365 | reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */ |
397 | ret += reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */ | 366 | reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */ |
398 | ret += reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */ | 367 | reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */ |
399 | ret += reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */ | 368 | reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */ |
400 | ret += reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */ | 369 | reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */ |
401 | ret += reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */ | 370 | reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */ |
402 | 371 | ||
403 | ret += reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */ | 372 | reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */ |
404 | ret += reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */ | 373 | reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */ |
405 | ret += reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */ | 374 | reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */ |
406 | ret += reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */ | 375 | reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */ |
407 | ret += reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */ | 376 | reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */ |
408 | ret += reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */ | 377 | reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */ |
409 | 378 | ||
410 | ret += reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */ | 379 | reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */ |
411 | ret += reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */ | 380 | reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */ |
412 | 381 | ||
413 | ret += reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */ | 382 | reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */ |
414 | ret += reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */ | 383 | reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */ |
415 | 384 | ||
416 | ret += reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */ | 385 | reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */ |
417 | ret += reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/ | 386 | reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/ |
418 | ret += reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */ | 387 | reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */ |
419 | ret += reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */ | 388 | reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */ |
420 | |||
421 | return ret; | ||
422 | } | 389 | } |
423 | 390 | ||
424 | static int w9968cf_set_crop_window(struct sd *sd) | 391 | static void w9968cf_set_crop_window(struct sd *sd) |
425 | { | 392 | { |
426 | int ret = 0, start_cropx, start_cropy, x, y, fw, fh, cw, ch, | 393 | int start_cropx, start_cropy, x, y, fw, fh, cw, ch, |
427 | max_width, max_height; | 394 | max_width, max_height; |
428 | 395 | ||
429 | if (sd->sif) { | 396 | if (sd->sif) { |
@@ -456,8 +423,8 @@ static int w9968cf_set_crop_window(struct sd *sd) | |||
456 | fw = SC(sd->gspca_dev.width) / max_width; | 423 | fw = SC(sd->gspca_dev.width) / max_width; |
457 | fh = SC(sd->gspca_dev.height) / max_height; | 424 | fh = SC(sd->gspca_dev.height) / max_height; |
458 | 425 | ||
459 | cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width)/fh; | 426 | cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width) / fh; |
460 | ch = (fw >= fh) ? SC(sd->gspca_dev.height)/fw : max_height; | 427 | ch = (fw >= fh) ? SC(sd->gspca_dev.height) / fw : max_height; |
461 | 428 | ||
462 | sd->sensor_width = max_width; | 429 | sd->sensor_width = max_width; |
463 | sd->sensor_height = max_height; | 430 | sd->sensor_height = max_height; |
@@ -465,42 +432,40 @@ static int w9968cf_set_crop_window(struct sd *sd) | |||
465 | x = (max_width - cw) / 2; | 432 | x = (max_width - cw) / 2; |
466 | y = (max_height - ch) / 2; | 433 | y = (max_height - ch) / 2; |
467 | 434 | ||
468 | ret += reg_w(sd, 0x10, start_cropx + x); | 435 | reg_w(sd, 0x10, start_cropx + x); |
469 | ret += reg_w(sd, 0x11, start_cropy + y); | 436 | reg_w(sd, 0x11, start_cropy + y); |
470 | ret += reg_w(sd, 0x12, start_cropx + x + cw); | 437 | reg_w(sd, 0x12, start_cropx + x + cw); |
471 | ret += reg_w(sd, 0x13, start_cropy + y + ch); | 438 | reg_w(sd, 0x13, start_cropy + y + ch); |
472 | |||
473 | return ret; | ||
474 | } | 439 | } |
475 | 440 | ||
476 | static int w9968cf_mode_init_regs(struct sd *sd) | 441 | static void w9968cf_mode_init_regs(struct sd *sd) |
477 | { | 442 | { |
478 | int ret = 0, val, vs_polarity, hs_polarity; | 443 | int val, vs_polarity, hs_polarity; |
479 | 444 | ||
480 | ret += w9968cf_set_crop_window(sd); | 445 | w9968cf_set_crop_window(sd); |
481 | 446 | ||
482 | ret += reg_w(sd, 0x14, sd->gspca_dev.width); | 447 | reg_w(sd, 0x14, sd->gspca_dev.width); |
483 | ret += reg_w(sd, 0x15, sd->gspca_dev.height); | 448 | reg_w(sd, 0x15, sd->gspca_dev.height); |
484 | 449 | ||
485 | /* JPEG width & height */ | 450 | /* JPEG width & height */ |
486 | ret += reg_w(sd, 0x30, sd->gspca_dev.width); | 451 | reg_w(sd, 0x30, sd->gspca_dev.width); |
487 | ret += reg_w(sd, 0x31, sd->gspca_dev.height); | 452 | reg_w(sd, 0x31, sd->gspca_dev.height); |
488 | 453 | ||
489 | /* Y & UV frame buffer strides (in WORD) */ | 454 | /* Y & UV frame buffer strides (in WORD) */ |
490 | if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == | 455 | if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == |
491 | V4L2_PIX_FMT_JPEG) { | 456 | V4L2_PIX_FMT_JPEG) { |
492 | ret += reg_w(sd, 0x2c, sd->gspca_dev.width/2); | 457 | reg_w(sd, 0x2c, sd->gspca_dev.width / 2); |
493 | ret += reg_w(sd, 0x2d, sd->gspca_dev.width/4); | 458 | reg_w(sd, 0x2d, sd->gspca_dev.width / 4); |
494 | } else | 459 | } else |
495 | ret += reg_w(sd, 0x2c, sd->gspca_dev.width); | 460 | reg_w(sd, 0x2c, sd->gspca_dev.width); |
496 | 461 | ||
497 | ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */ | 462 | reg_w(sd, 0x00, 0xbf17); /* reset everything */ |
498 | ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */ | 463 | reg_w(sd, 0x00, 0xbf10); /* normal operation */ |
499 | 464 | ||
500 | /* Transfer size in WORDS (for UYVY format only) */ | 465 | /* Transfer size in WORDS (for UYVY format only) */ |
501 | val = sd->gspca_dev.width * sd->gspca_dev.height; | 466 | val = sd->gspca_dev.width * sd->gspca_dev.height; |
502 | ret += reg_w(sd, 0x3d, val & 0xffff); /* low bits */ | 467 | reg_w(sd, 0x3d, val & 0xffff); /* low bits */ |
503 | ret += reg_w(sd, 0x3e, val >> 16); /* high bits */ | 468 | reg_w(sd, 0x3e, val >> 16); /* high bits */ |
504 | 469 | ||
505 | if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == | 470 | if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == |
506 | V4L2_PIX_FMT_JPEG) { | 471 | V4L2_PIX_FMT_JPEG) { |
@@ -508,7 +473,7 @@ static int w9968cf_mode_init_regs(struct sd *sd) | |||
508 | jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height, | 473 | jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height, |
509 | sd->gspca_dev.width, 0x22); /* JPEG 420 */ | 474 | sd->gspca_dev.width, 0x22); /* JPEG 420 */ |
510 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 475 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
511 | ret += w9968cf_upload_quantizationtables(sd); | 476 | w9968cf_upload_quantizationtables(sd); |
512 | } | 477 | } |
513 | 478 | ||
514 | /* Video Capture Control Register */ | 479 | /* Video Capture Control Register */ |
@@ -540,19 +505,15 @@ static int w9968cf_mode_init_regs(struct sd *sd) | |||
540 | 505 | ||
541 | val |= 0x8000; /* capt. enable */ | 506 | val |= 0x8000; /* capt. enable */ |
542 | 507 | ||
543 | ret += reg_w(sd, 0x16, val); | 508 | reg_w(sd, 0x16, val); |
544 | 509 | ||
545 | sd->gspca_dev.empty_packet = 0; | 510 | sd->gspca_dev.empty_packet = 0; |
546 | |||
547 | return ret; | ||
548 | } | 511 | } |
549 | 512 | ||
550 | static void w9968cf_stop0(struct sd *sd) | 513 | static void w9968cf_stop0(struct sd *sd) |
551 | { | 514 | { |
552 | if (sd->gspca_dev.present) { | 515 | reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */ |
553 | reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */ | 516 | reg_w(sd, 0x16, 0x0000); /* stop video capture */ |
554 | reg_w(sd, 0x16, 0x0000); /* stop video capture */ | ||
555 | } | ||
556 | } | 517 | } |
557 | 518 | ||
558 | /* The w9968cf docs say that a 0 sized packet means EOF (and also SOF | 519 | /* The w9968cf docs say that a 0 sized packet means EOF (and also SOF |
diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c index 8715577bc2d8..5b5039a02031 100644 --- a/drivers/media/video/gspca/xirlink_cit.c +++ b/drivers/media/video/gspca/xirlink_cit.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #define MODULE_NAME "xirlink-cit" | 30 | #define MODULE_NAME "xirlink-cit" |
31 | 31 | ||
32 | #include <linux/input.h> | ||
32 | #include "gspca.h" | 33 | #include "gspca.h" |
33 | 34 | ||
34 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | 35 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); |
@@ -58,6 +59,7 @@ struct sd { | |||
58 | #define CIT_MODEL4 4 | 59 | #define CIT_MODEL4 4 |
59 | #define CIT_IBM_NETCAM_PRO 5 | 60 | #define CIT_IBM_NETCAM_PRO 5 |
60 | u8 input_index; | 61 | u8 input_index; |
62 | u8 button_state; | ||
61 | u8 stop_on_control_change; | 63 | u8 stop_on_control_change; |
62 | u8 sof_read; | 64 | u8 sof_read; |
63 | u8 sof_len; | 65 | u8 sof_len; |
@@ -185,60 +187,60 @@ static const struct ctrl sd_ctrls[] = { | |||
185 | static const struct v4l2_pix_format cif_yuv_mode[] = { | 187 | static const struct v4l2_pix_format cif_yuv_mode[] = { |
186 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 188 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
187 | .bytesperline = 176, | 189 | .bytesperline = 176, |
188 | .sizeimage = 176 * 144 * 3 / 2, | 190 | .sizeimage = 176 * 144 * 3 / 2 + 4, |
189 | .colorspace = V4L2_COLORSPACE_SRGB}, | 191 | .colorspace = V4L2_COLORSPACE_SRGB}, |
190 | {352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 192 | {352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
191 | .bytesperline = 352, | 193 | .bytesperline = 352, |
192 | .sizeimage = 352 * 288 * 3 / 2, | 194 | .sizeimage = 352 * 288 * 3 / 2 + 4, |
193 | .colorspace = V4L2_COLORSPACE_SRGB}, | 195 | .colorspace = V4L2_COLORSPACE_SRGB}, |
194 | }; | 196 | }; |
195 | 197 | ||
196 | static const struct v4l2_pix_format vga_yuv_mode[] = { | 198 | static const struct v4l2_pix_format vga_yuv_mode[] = { |
197 | {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 199 | {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
198 | .bytesperline = 160, | 200 | .bytesperline = 160, |
199 | .sizeimage = 160 * 120 * 3 / 2, | 201 | .sizeimage = 160 * 120 * 3 / 2 + 4, |
200 | .colorspace = V4L2_COLORSPACE_SRGB}, | 202 | .colorspace = V4L2_COLORSPACE_SRGB}, |
201 | {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 203 | {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
202 | .bytesperline = 320, | 204 | .bytesperline = 320, |
203 | .sizeimage = 320 * 240 * 3 / 2, | 205 | .sizeimage = 320 * 240 * 3 / 2 + 4, |
204 | .colorspace = V4L2_COLORSPACE_SRGB}, | 206 | .colorspace = V4L2_COLORSPACE_SRGB}, |
205 | {640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 207 | {640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
206 | .bytesperline = 640, | 208 | .bytesperline = 640, |
207 | .sizeimage = 640 * 480 * 3 / 2, | 209 | .sizeimage = 640 * 480 * 3 / 2 + 4, |
208 | .colorspace = V4L2_COLORSPACE_SRGB}, | 210 | .colorspace = V4L2_COLORSPACE_SRGB}, |
209 | }; | 211 | }; |
210 | 212 | ||
211 | static const struct v4l2_pix_format model0_mode[] = { | 213 | static const struct v4l2_pix_format model0_mode[] = { |
212 | {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 214 | {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
213 | .bytesperline = 160, | 215 | .bytesperline = 160, |
214 | .sizeimage = 160 * 120 * 3 / 2, | 216 | .sizeimage = 160 * 120 * 3 / 2 + 4, |
215 | .colorspace = V4L2_COLORSPACE_SRGB}, | 217 | .colorspace = V4L2_COLORSPACE_SRGB}, |
216 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 218 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
217 | .bytesperline = 176, | 219 | .bytesperline = 176, |
218 | .sizeimage = 176 * 144 * 3 / 2, | 220 | .sizeimage = 176 * 144 * 3 / 2 + 4, |
219 | .colorspace = V4L2_COLORSPACE_SRGB}, | 221 | .colorspace = V4L2_COLORSPACE_SRGB}, |
220 | {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 222 | {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
221 | .bytesperline = 320, | 223 | .bytesperline = 320, |
222 | .sizeimage = 320 * 240 * 3 / 2, | 224 | .sizeimage = 320 * 240 * 3 / 2 + 4, |
223 | .colorspace = V4L2_COLORSPACE_SRGB}, | 225 | .colorspace = V4L2_COLORSPACE_SRGB}, |
224 | }; | 226 | }; |
225 | 227 | ||
226 | static const struct v4l2_pix_format model2_mode[] = { | 228 | static const struct v4l2_pix_format model2_mode[] = { |
227 | {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 229 | {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
228 | .bytesperline = 160, | 230 | .bytesperline = 160, |
229 | .sizeimage = 160 * 120 * 3 / 2, | 231 | .sizeimage = 160 * 120 * 3 / 2 + 4, |
230 | .colorspace = V4L2_COLORSPACE_SRGB}, | 232 | .colorspace = V4L2_COLORSPACE_SRGB}, |
231 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 233 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
232 | .bytesperline = 176, | 234 | .bytesperline = 176, |
233 | .sizeimage = 176 * 144 * 3 / 2, | 235 | .sizeimage = 176 * 144 * 3 / 2 + 4, |
234 | .colorspace = V4L2_COLORSPACE_SRGB}, | 236 | .colorspace = V4L2_COLORSPACE_SRGB}, |
235 | {320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, | 237 | {320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, |
236 | .bytesperline = 320, | 238 | .bytesperline = 320, |
237 | .sizeimage = 320 * 240, | 239 | .sizeimage = 320 * 240 + 4, |
238 | .colorspace = V4L2_COLORSPACE_SRGB}, | 240 | .colorspace = V4L2_COLORSPACE_SRGB}, |
239 | {352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, | 241 | {352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, |
240 | .bytesperline = 352, | 242 | .bytesperline = 352, |
241 | .sizeimage = 352 * 288, | 243 | .sizeimage = 352 * 288 + 4, |
242 | .colorspace = V4L2_COLORSPACE_SRGB}, | 244 | .colorspace = V4L2_COLORSPACE_SRGB}, |
243 | }; | 245 | }; |
244 | 246 | ||
@@ -804,7 +806,7 @@ static int cit_write_reg(struct gspca_dev *gspca_dev, u16 value, u16 index) | |||
804 | return 0; | 806 | return 0; |
805 | } | 807 | } |
806 | 808 | ||
807 | static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index) | 809 | static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index, int verbose) |
808 | { | 810 | { |
809 | struct usb_device *udev = gspca_dev->dev; | 811 | struct usb_device *udev = gspca_dev->dev; |
810 | __u8 *buf = gspca_dev->usb_buf; | 812 | __u8 *buf = gspca_dev->usb_buf; |
@@ -819,10 +821,8 @@ static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index) | |||
819 | return res; | 821 | return res; |
820 | } | 822 | } |
821 | 823 | ||
822 | PDEBUG(D_PROBE, | 824 | if (verbose) |
823 | "Register %04x value: %02x %02x %02x %02x %02x %02x %02x %02x", | 825 | PDEBUG(D_PROBE, "Register %04x value: %02x", index, buf[0]); |
824 | index, | ||
825 | buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); | ||
826 | 826 | ||
827 | return 0; | 827 | return 0; |
828 | } | 828 | } |
@@ -907,7 +907,7 @@ static void cit_Packet_Format1(struct gspca_dev *gspca_dev, u16 fkey, u16 val) | |||
907 | cit_send_x_00_05(gspca_dev, 0x0089); | 907 | cit_send_x_00_05(gspca_dev, 0x0089); |
908 | cit_send_x_00(gspca_dev, fkey); | 908 | cit_send_x_00(gspca_dev, fkey); |
909 | cit_send_00_04_06(gspca_dev); | 909 | cit_send_00_04_06(gspca_dev); |
910 | cit_read_reg(gspca_dev, 0x0126); | 910 | cit_read_reg(gspca_dev, 0x0126, 0); |
911 | cit_send_FF_04_02(gspca_dev); | 911 | cit_send_FF_04_02(gspca_dev); |
912 | } | 912 | } |
913 | 913 | ||
@@ -1074,12 +1074,12 @@ static int cit_init_model0(struct gspca_dev *gspca_dev) | |||
1074 | 1074 | ||
1075 | static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev) | 1075 | static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev) |
1076 | { | 1076 | { |
1077 | cit_read_reg(gspca_dev, 0x128); | 1077 | cit_read_reg(gspca_dev, 0x128, 1); |
1078 | cit_write_reg(gspca_dev, 0x0003, 0x0133); | 1078 | cit_write_reg(gspca_dev, 0x0003, 0x0133); |
1079 | cit_write_reg(gspca_dev, 0x0000, 0x0117); | 1079 | cit_write_reg(gspca_dev, 0x0000, 0x0117); |
1080 | cit_write_reg(gspca_dev, 0x0008, 0x0123); | 1080 | cit_write_reg(gspca_dev, 0x0008, 0x0123); |
1081 | cit_write_reg(gspca_dev, 0x0000, 0x0100); | 1081 | cit_write_reg(gspca_dev, 0x0000, 0x0100); |
1082 | cit_read_reg(gspca_dev, 0x0116); | 1082 | cit_read_reg(gspca_dev, 0x0116, 0); |
1083 | cit_write_reg(gspca_dev, 0x0060, 0x0116); | 1083 | cit_write_reg(gspca_dev, 0x0060, 0x0116); |
1084 | cit_write_reg(gspca_dev, 0x0002, 0x0112); | 1084 | cit_write_reg(gspca_dev, 0x0002, 0x0112); |
1085 | cit_write_reg(gspca_dev, 0x0000, 0x0133); | 1085 | cit_write_reg(gspca_dev, 0x0000, 0x0133); |
@@ -1098,7 +1098,7 @@ static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev) | |||
1098 | cit_write_reg(gspca_dev, 0x00ff, 0x0130); | 1098 | cit_write_reg(gspca_dev, 0x00ff, 0x0130); |
1099 | cit_write_reg(gspca_dev, 0xcd41, 0x0124); | 1099 | cit_write_reg(gspca_dev, 0xcd41, 0x0124); |
1100 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); | 1100 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); |
1101 | cit_read_reg(gspca_dev, 0x0126); | 1101 | cit_read_reg(gspca_dev, 0x0126, 1); |
1102 | 1102 | ||
1103 | cit_model3_Packet1(gspca_dev, 0x0000, 0x0000); | 1103 | cit_model3_Packet1(gspca_dev, 0x0000, 0x0000); |
1104 | cit_model3_Packet1(gspca_dev, 0x0000, 0x0001); | 1104 | cit_model3_Packet1(gspca_dev, 0x0000, 0x0001); |
@@ -1557,18 +1557,20 @@ static int cit_restart_stream(struct gspca_dev *gspca_dev) | |||
1557 | switch (sd->model) { | 1557 | switch (sd->model) { |
1558 | case CIT_MODEL0: | 1558 | case CIT_MODEL0: |
1559 | case CIT_MODEL1: | 1559 | case CIT_MODEL1: |
1560 | case CIT_MODEL3: | ||
1561 | case CIT_IBM_NETCAM_PRO: | ||
1562 | cit_write_reg(gspca_dev, 0x0001, 0x0114); | 1560 | cit_write_reg(gspca_dev, 0x0001, 0x0114); |
1563 | /* Fall through */ | 1561 | /* Fall through */ |
1564 | case CIT_MODEL2: | 1562 | case CIT_MODEL2: |
1565 | case CIT_MODEL4: | 1563 | case CIT_MODEL4: |
1566 | cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */ | 1564 | cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */ |
1567 | usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe); | 1565 | usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe); |
1568 | /* This happens repeatedly while streaming with the ibm netcam | 1566 | break; |
1569 | pro and the ibmcam driver did it for model3 after changing | 1567 | case CIT_MODEL3: |
1570 | settings, but it does not seem to have any effect. */ | 1568 | case CIT_IBM_NETCAM_PRO: |
1571 | /* cit_write_reg(gspca_dev, 0x0001, 0x0113); */ | 1569 | cit_write_reg(gspca_dev, 0x0001, 0x0114); |
1570 | cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */ | ||
1571 | usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe); | ||
1572 | /* Clear button events from while we were not streaming */ | ||
1573 | cit_write_reg(gspca_dev, 0x0001, 0x0113); | ||
1572 | break; | 1574 | break; |
1573 | } | 1575 | } |
1574 | 1576 | ||
@@ -1680,23 +1682,23 @@ static int cit_start_model1(struct gspca_dev *gspca_dev) | |||
1680 | if (clock_div < 0) | 1682 | if (clock_div < 0) |
1681 | return clock_div; | 1683 | return clock_div; |
1682 | 1684 | ||
1683 | cit_read_reg(gspca_dev, 0x0128); | 1685 | cit_read_reg(gspca_dev, 0x0128, 1); |
1684 | cit_read_reg(gspca_dev, 0x0100); | 1686 | cit_read_reg(gspca_dev, 0x0100, 0); |
1685 | cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */ | 1687 | cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */ |
1686 | cit_read_reg(gspca_dev, 0x0100); | 1688 | cit_read_reg(gspca_dev, 0x0100, 0); |
1687 | cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */ | 1689 | cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */ |
1688 | cit_read_reg(gspca_dev, 0x0100); | 1690 | cit_read_reg(gspca_dev, 0x0100, 0); |
1689 | cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */ | 1691 | cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */ |
1690 | cit_write_reg(gspca_dev, 0x01, 0x0108); | 1692 | cit_write_reg(gspca_dev, 0x01, 0x0108); |
1691 | 1693 | ||
1692 | cit_write_reg(gspca_dev, 0x03, 0x0112); | 1694 | cit_write_reg(gspca_dev, 0x03, 0x0112); |
1693 | cit_read_reg(gspca_dev, 0x0115); | 1695 | cit_read_reg(gspca_dev, 0x0115, 0); |
1694 | cit_write_reg(gspca_dev, 0x06, 0x0115); | 1696 | cit_write_reg(gspca_dev, 0x06, 0x0115); |
1695 | cit_read_reg(gspca_dev, 0x0116); | 1697 | cit_read_reg(gspca_dev, 0x0116, 0); |
1696 | cit_write_reg(gspca_dev, 0x44, 0x0116); | 1698 | cit_write_reg(gspca_dev, 0x44, 0x0116); |
1697 | cit_read_reg(gspca_dev, 0x0116); | 1699 | cit_read_reg(gspca_dev, 0x0116, 0); |
1698 | cit_write_reg(gspca_dev, 0x40, 0x0116); | 1700 | cit_write_reg(gspca_dev, 0x40, 0x0116); |
1699 | cit_read_reg(gspca_dev, 0x0115); | 1701 | cit_read_reg(gspca_dev, 0x0115, 0); |
1700 | cit_write_reg(gspca_dev, 0x0e, 0x0115); | 1702 | cit_write_reg(gspca_dev, 0x0e, 0x0115); |
1701 | cit_write_reg(gspca_dev, 0x19, 0x012c); | 1703 | cit_write_reg(gspca_dev, 0x19, 0x012c); |
1702 | 1704 | ||
@@ -1878,7 +1880,7 @@ static int cit_start_model2(struct gspca_dev *gspca_dev) | |||
1878 | int clock_div = 0; | 1880 | int clock_div = 0; |
1879 | 1881 | ||
1880 | cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */ | 1882 | cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */ |
1881 | cit_read_reg(gspca_dev, 0x0116); | 1883 | cit_read_reg(gspca_dev, 0x0116, 0); |
1882 | cit_write_reg(gspca_dev, 0x0060, 0x0116); | 1884 | cit_write_reg(gspca_dev, 0x0060, 0x0116); |
1883 | cit_write_reg(gspca_dev, 0x0002, 0x0112); | 1885 | cit_write_reg(gspca_dev, 0x0002, 0x0112); |
1884 | cit_write_reg(gspca_dev, 0x00bc, 0x012c); | 1886 | cit_write_reg(gspca_dev, 0x00bc, 0x012c); |
@@ -2070,10 +2072,10 @@ static int cit_start_model3(struct gspca_dev *gspca_dev) | |||
2070 | 2072 | ||
2071 | /* HDG not in ibmcam driver, added to see if it helps with | 2073 | /* HDG not in ibmcam driver, added to see if it helps with |
2072 | auto-detecting between model3 and ibm netcamera pro */ | 2074 | auto-detecting between model3 and ibm netcamera pro */ |
2073 | cit_read_reg(gspca_dev, 0x128); | 2075 | cit_read_reg(gspca_dev, 0x128, 1); |
2074 | 2076 | ||
2075 | cit_write_reg(gspca_dev, 0x0000, 0x0100); | 2077 | cit_write_reg(gspca_dev, 0x0000, 0x0100); |
2076 | cit_read_reg(gspca_dev, 0x0116); | 2078 | cit_read_reg(gspca_dev, 0x0116, 0); |
2077 | cit_write_reg(gspca_dev, 0x0060, 0x0116); | 2079 | cit_write_reg(gspca_dev, 0x0060, 0x0116); |
2078 | cit_write_reg(gspca_dev, 0x0002, 0x0112); | 2080 | cit_write_reg(gspca_dev, 0x0002, 0x0112); |
2079 | cit_write_reg(gspca_dev, 0x0000, 0x0123); | 2081 | cit_write_reg(gspca_dev, 0x0000, 0x0123); |
@@ -2083,7 +2085,7 @@ static int cit_start_model3(struct gspca_dev *gspca_dev) | |||
2083 | cit_write_reg(gspca_dev, 0x0060, 0x0116); | 2085 | cit_write_reg(gspca_dev, 0x0060, 0x0116); |
2084 | cit_write_reg(gspca_dev, 0x0002, 0x0115); | 2086 | cit_write_reg(gspca_dev, 0x0002, 0x0115); |
2085 | cit_write_reg(gspca_dev, 0x0003, 0x0115); | 2087 | cit_write_reg(gspca_dev, 0x0003, 0x0115); |
2086 | cit_read_reg(gspca_dev, 0x0115); | 2088 | cit_read_reg(gspca_dev, 0x0115, 0); |
2087 | cit_write_reg(gspca_dev, 0x000b, 0x0115); | 2089 | cit_write_reg(gspca_dev, 0x000b, 0x0115); |
2088 | 2090 | ||
2089 | /* TESTME HDG not in ibmcam driver, added to see if it helps with | 2091 | /* TESTME HDG not in ibmcam driver, added to see if it helps with |
@@ -2096,7 +2098,7 @@ static int cit_start_model3(struct gspca_dev *gspca_dev) | |||
2096 | cit_write_reg(gspca_dev, 0x00ff, 0x0130); | 2098 | cit_write_reg(gspca_dev, 0x00ff, 0x0130); |
2097 | cit_write_reg(gspca_dev, 0xcd41, 0x0124); | 2099 | cit_write_reg(gspca_dev, 0xcd41, 0x0124); |
2098 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); | 2100 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); |
2099 | cit_read_reg(gspca_dev, 0x0126); | 2101 | cit_read_reg(gspca_dev, 0x0126, 1); |
2100 | } | 2102 | } |
2101 | 2103 | ||
2102 | cit_model3_Packet1(gspca_dev, 0x000a, 0x0040); | 2104 | cit_model3_Packet1(gspca_dev, 0x000a, 0x0040); |
@@ -2293,7 +2295,7 @@ static int cit_start_model3(struct gspca_dev *gspca_dev) | |||
2293 | if (rca_input) { | 2295 | if (rca_input) { |
2294 | for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) { | 2296 | for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) { |
2295 | if (rca_initdata[i][0]) | 2297 | if (rca_initdata[i][0]) |
2296 | cit_read_reg(gspca_dev, rca_initdata[i][2]); | 2298 | cit_read_reg(gspca_dev, rca_initdata[i][2], 0); |
2297 | else | 2299 | else |
2298 | cit_write_reg(gspca_dev, rca_initdata[i][1], | 2300 | cit_write_reg(gspca_dev, rca_initdata[i][1], |
2299 | rca_initdata[i][2]); | 2301 | rca_initdata[i][2]); |
@@ -2712,7 +2714,7 @@ static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev) | |||
2712 | if (rca_input) { | 2714 | if (rca_input) { |
2713 | for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) { | 2715 | for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) { |
2714 | if (rca_initdata[i][0]) | 2716 | if (rca_initdata[i][0]) |
2715 | cit_read_reg(gspca_dev, rca_initdata[i][2]); | 2717 | cit_read_reg(gspca_dev, rca_initdata[i][2], 0); |
2716 | else | 2718 | else |
2717 | cit_write_reg(gspca_dev, rca_initdata[i][1], | 2719 | cit_write_reg(gspca_dev, rca_initdata[i][1], |
2718 | rca_initdata[i][2]); | 2720 | rca_initdata[i][2]); |
@@ -2769,16 +2771,55 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2769 | return 0; | 2771 | return 0; |
2770 | } | 2772 | } |
2771 | 2773 | ||
2774 | static int sd_isoc_init(struct gspca_dev *gspca_dev) | ||
2775 | { | ||
2776 | struct usb_host_interface *alt; | ||
2777 | int max_packet_size; | ||
2778 | |||
2779 | switch (gspca_dev->width) { | ||
2780 | case 160: | ||
2781 | max_packet_size = 450; | ||
2782 | break; | ||
2783 | case 176: | ||
2784 | max_packet_size = 600; | ||
2785 | break; | ||
2786 | default: | ||
2787 | max_packet_size = 1022; | ||
2788 | break; | ||
2789 | } | ||
2790 | |||
2791 | /* Start isoc bandwidth "negotiation" at max isoc bandwidth */ | ||
2792 | alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; | ||
2793 | alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size); | ||
2794 | |||
2795 | return 0; | ||
2796 | } | ||
2797 | |||
2772 | static int sd_isoc_nego(struct gspca_dev *gspca_dev) | 2798 | static int sd_isoc_nego(struct gspca_dev *gspca_dev) |
2773 | { | 2799 | { |
2774 | int ret, packet_size; | 2800 | int ret, packet_size, min_packet_size; |
2775 | struct usb_host_interface *alt; | 2801 | struct usb_host_interface *alt; |
2776 | 2802 | ||
2803 | switch (gspca_dev->width) { | ||
2804 | case 160: | ||
2805 | min_packet_size = 200; | ||
2806 | break; | ||
2807 | case 176: | ||
2808 | min_packet_size = 266; | ||
2809 | break; | ||
2810 | default: | ||
2811 | min_packet_size = 400; | ||
2812 | break; | ||
2813 | } | ||
2814 | |||
2777 | alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; | 2815 | alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; |
2778 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | 2816 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); |
2779 | packet_size -= 100; | 2817 | if (packet_size <= min_packet_size) |
2780 | if (packet_size < 300) | ||
2781 | return -EIO; | 2818 | return -EIO; |
2819 | |||
2820 | packet_size -= 100; | ||
2821 | if (packet_size < min_packet_size) | ||
2822 | packet_size = min_packet_size; | ||
2782 | alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size); | 2823 | alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size); |
2783 | 2824 | ||
2784 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); | 2825 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); |
@@ -2796,15 +2837,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
2796 | static void sd_stop0(struct gspca_dev *gspca_dev) | 2837 | static void sd_stop0(struct gspca_dev *gspca_dev) |
2797 | { | 2838 | { |
2798 | struct sd *sd = (struct sd *) gspca_dev; | 2839 | struct sd *sd = (struct sd *) gspca_dev; |
2799 | struct usb_host_interface *alt; | ||
2800 | 2840 | ||
2801 | /* We cannot use gspca_dev->present here as that is not set when | 2841 | /* We cannot use gspca_dev->present here as that is not set when |
2802 | sd_init gets called and we get called from sd_init */ | 2842 | sd_init gets called and we get called from sd_init */ |
2803 | if (!gspca_dev->dev) | 2843 | if (!gspca_dev->dev) |
2804 | return; | 2844 | return; |
2805 | 2845 | ||
2806 | alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; | ||
2807 | |||
2808 | switch (sd->model) { | 2846 | switch (sd->model) { |
2809 | case CIT_MODEL0: | 2847 | case CIT_MODEL0: |
2810 | /* HDG windows does this, but it causes the cams autogain to | 2848 | /* HDG windows does this, but it causes the cams autogain to |
@@ -2815,7 +2853,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
2815 | break; | 2853 | break; |
2816 | case CIT_MODEL1: | 2854 | case CIT_MODEL1: |
2817 | cit_send_FF_04_02(gspca_dev); | 2855 | cit_send_FF_04_02(gspca_dev); |
2818 | cit_read_reg(gspca_dev, 0x0100); | 2856 | cit_read_reg(gspca_dev, 0x0100, 0); |
2819 | cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */ | 2857 | cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */ |
2820 | break; | 2858 | break; |
2821 | case CIT_MODEL2: | 2859 | case CIT_MODEL2: |
@@ -2834,9 +2872,9 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
2834 | case CIT_MODEL3: | 2872 | case CIT_MODEL3: |
2835 | cit_write_reg(gspca_dev, 0x0006, 0x012c); | 2873 | cit_write_reg(gspca_dev, 0x0006, 0x012c); |
2836 | cit_model3_Packet1(gspca_dev, 0x0046, 0x0000); | 2874 | cit_model3_Packet1(gspca_dev, 0x0046, 0x0000); |
2837 | cit_read_reg(gspca_dev, 0x0116); | 2875 | cit_read_reg(gspca_dev, 0x0116, 0); |
2838 | cit_write_reg(gspca_dev, 0x0064, 0x0116); | 2876 | cit_write_reg(gspca_dev, 0x0064, 0x0116); |
2839 | cit_read_reg(gspca_dev, 0x0115); | 2877 | cit_read_reg(gspca_dev, 0x0115, 0); |
2840 | cit_write_reg(gspca_dev, 0x0003, 0x0115); | 2878 | cit_write_reg(gspca_dev, 0x0003, 0x0115); |
2841 | cit_write_reg(gspca_dev, 0x0008, 0x0123); | 2879 | cit_write_reg(gspca_dev, 0x0008, 0x0123); |
2842 | cit_write_reg(gspca_dev, 0x0000, 0x0117); | 2880 | cit_write_reg(gspca_dev, 0x0000, 0x0117); |
@@ -2859,12 +2897,17 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
2859 | restarting the stream after this */ | 2897 | restarting the stream after this */ |
2860 | /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */ | 2898 | /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */ |
2861 | cit_write_reg(gspca_dev, 0x00c0, 0x0100); | 2899 | cit_write_reg(gspca_dev, 0x00c0, 0x0100); |
2862 | |||
2863 | /* Start isoc bandwidth "negotiation" at max isoc bandwith | ||
2864 | next stream start */ | ||
2865 | alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(1022); | ||
2866 | break; | 2900 | break; |
2867 | } | 2901 | } |
2902 | |||
2903 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | ||
2904 | /* If the last button state is pressed, release it now! */ | ||
2905 | if (sd->button_state) { | ||
2906 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); | ||
2907 | input_sync(gspca_dev->input_dev); | ||
2908 | sd->button_state = 0; | ||
2909 | } | ||
2910 | #endif | ||
2868 | } | 2911 | } |
2869 | 2912 | ||
2870 | static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len) | 2913 | static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len) |
@@ -3158,6 +3201,38 @@ static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
3158 | return 0; | 3201 | return 0; |
3159 | } | 3202 | } |
3160 | 3203 | ||
3204 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | ||
3205 | static void cit_check_button(struct gspca_dev *gspca_dev) | ||
3206 | { | ||
3207 | int new_button_state; | ||
3208 | struct sd *sd = (struct sd *)gspca_dev; | ||
3209 | |||
3210 | switch (sd->model) { | ||
3211 | case CIT_MODEL3: | ||
3212 | case CIT_IBM_NETCAM_PRO: | ||
3213 | break; | ||
3214 | default: /* TEST ME unknown if this works on other models too */ | ||
3215 | return; | ||
3216 | } | ||
3217 | |||
3218 | /* Read the button state */ | ||
3219 | cit_read_reg(gspca_dev, 0x0113, 0); | ||
3220 | new_button_state = !gspca_dev->usb_buf[0]; | ||
3221 | |||
3222 | /* Tell the cam we've seen the button press, notice that this | ||
3223 | is a nop (iow the cam keeps reporting pressed) until the | ||
3224 | button is actually released. */ | ||
3225 | if (new_button_state) | ||
3226 | cit_write_reg(gspca_dev, 0x01, 0x0113); | ||
3227 | |||
3228 | if (sd->button_state != new_button_state) { | ||
3229 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, | ||
3230 | new_button_state); | ||
3231 | input_sync(gspca_dev->input_dev); | ||
3232 | sd->button_state = new_button_state; | ||
3233 | } | ||
3234 | } | ||
3235 | #endif | ||
3161 | 3236 | ||
3162 | /* sub-driver description */ | 3237 | /* sub-driver description */ |
3163 | static const struct sd_desc sd_desc = { | 3238 | static const struct sd_desc sd_desc = { |
@@ -3170,6 +3245,10 @@ static const struct sd_desc sd_desc = { | |||
3170 | .stopN = sd_stopN, | 3245 | .stopN = sd_stopN, |
3171 | .stop0 = sd_stop0, | 3246 | .stop0 = sd_stop0, |
3172 | .pkt_scan = sd_pkt_scan, | 3247 | .pkt_scan = sd_pkt_scan, |
3248 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | ||
3249 | .dq_callback = cit_check_button, | ||
3250 | .other_input = 1, | ||
3251 | #endif | ||
3173 | }; | 3252 | }; |
3174 | 3253 | ||
3175 | static const struct sd_desc sd_desc_isoc_nego = { | 3254 | static const struct sd_desc sd_desc_isoc_nego = { |
@@ -3179,10 +3258,15 @@ static const struct sd_desc sd_desc_isoc_nego = { | |||
3179 | .config = sd_config, | 3258 | .config = sd_config, |
3180 | .init = sd_init, | 3259 | .init = sd_init, |
3181 | .start = sd_start, | 3260 | .start = sd_start, |
3261 | .isoc_init = sd_isoc_init, | ||
3182 | .isoc_nego = sd_isoc_nego, | 3262 | .isoc_nego = sd_isoc_nego, |
3183 | .stopN = sd_stopN, | 3263 | .stopN = sd_stopN, |
3184 | .stop0 = sd_stop0, | 3264 | .stop0 = sd_stop0, |
3185 | .pkt_scan = sd_pkt_scan, | 3265 | .pkt_scan = sd_pkt_scan, |
3266 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | ||
3267 | .dq_callback = cit_check_button, | ||
3268 | .other_input = 1, | ||
3269 | #endif | ||
3186 | }; | 3270 | }; |
3187 | 3271 | ||
3188 | /* -- module initialisation -- */ | 3272 | /* -- module initialisation -- */ |
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index c7e1970ca284..14b85d483163 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -35,16 +35,23 @@ static int force_sensor = -1; | |||
35 | #define QUANT_VAL 1 /* quantization table */ | 35 | #define QUANT_VAL 1 /* quantization table */ |
36 | #include "zc3xx-reg.h" | 36 | #include "zc3xx-reg.h" |
37 | 37 | ||
38 | /* controls */ | ||
39 | enum e_ctrl { | ||
40 | BRIGHTNESS, | ||
41 | CONTRAST, | ||
42 | GAMMA, | ||
43 | AUTOGAIN, | ||
44 | LIGHTFREQ, | ||
45 | SHARPNESS, | ||
46 | NCTRLS /* number of controls */ | ||
47 | }; | ||
48 | |||
38 | /* specific webcam descriptor */ | 49 | /* specific webcam descriptor */ |
39 | struct sd { | 50 | struct sd { |
40 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 51 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
41 | 52 | ||
42 | u8 brightness; | 53 | struct gspca_ctrl ctrls[NCTRLS]; |
43 | u8 contrast; | 54 | |
44 | u8 gamma; | ||
45 | u8 autogain; | ||
46 | u8 lightfreq; | ||
47 | u8 sharpness; | ||
48 | u8 quality; /* image quality */ | 55 | u8 quality; /* image quality */ |
49 | #define QUALITY_MIN 50 | 56 | #define QUALITY_MIN 50 |
50 | #define QUALITY_MAX 80 | 57 | #define QUALITY_MAX 80 |
@@ -64,6 +71,7 @@ enum sensors { | |||
64 | SENSOR_ADCM2700, | 71 | SENSOR_ADCM2700, |
65 | SENSOR_CS2102, | 72 | SENSOR_CS2102, |
66 | SENSOR_CS2102K, | 73 | SENSOR_CS2102K, |
74 | SENSOR_GC0303, | ||
67 | SENSOR_GC0305, | 75 | SENSOR_GC0305, |
68 | SENSOR_HDCS2020b, | 76 | SENSOR_HDCS2020b, |
69 | SENSOR_HV7131B, | 77 | SENSOR_HV7131B, |
@@ -79,26 +87,17 @@ enum sensors { | |||
79 | SENSOR_PB0330, | 87 | SENSOR_PB0330, |
80 | SENSOR_PO2030, | 88 | SENSOR_PO2030, |
81 | SENSOR_TAS5130C, | 89 | SENSOR_TAS5130C, |
82 | SENSOR_TAS5130C_VF0250, | ||
83 | SENSOR_MAX | 90 | SENSOR_MAX |
84 | }; | 91 | }; |
85 | 92 | ||
86 | /* V4L2 controls supported by the driver */ | 93 | /* V4L2 controls supported by the driver */ |
87 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | 94 | static void setcontrast(struct gspca_dev *gspca_dev); |
88 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | 95 | static void setautogain(struct gspca_dev *gspca_dev); |
89 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | 96 | static void setlightfreq(struct gspca_dev *gspca_dev); |
90 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 97 | static void setsharpness(struct gspca_dev *gspca_dev); |
91 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | 98 | |
92 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | 99 | static const struct ctrl sd_ctrls[NCTRLS] = { |
93 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); | 100 | [BRIGHTNESS] = { |
94 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); | ||
95 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
96 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
97 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
98 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
99 | |||
100 | static const struct ctrl sd_ctrls[] = { | ||
101 | { | ||
102 | { | 101 | { |
103 | .id = V4L2_CID_BRIGHTNESS, | 102 | .id = V4L2_CID_BRIGHTNESS, |
104 | .type = V4L2_CTRL_TYPE_INTEGER, | 103 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -106,13 +105,11 @@ static const struct ctrl sd_ctrls[] = { | |||
106 | .minimum = 0, | 105 | .minimum = 0, |
107 | .maximum = 255, | 106 | .maximum = 255, |
108 | .step = 1, | 107 | .step = 1, |
109 | #define BRIGHTNESS_DEF 128 | 108 | .default_value = 128, |
110 | .default_value = BRIGHTNESS_DEF, | ||
111 | }, | 109 | }, |
112 | .set = sd_setbrightness, | 110 | .set_control = setcontrast |
113 | .get = sd_getbrightness, | ||
114 | }, | 111 | }, |
115 | { | 112 | [CONTRAST] = { |
116 | { | 113 | { |
117 | .id = V4L2_CID_CONTRAST, | 114 | .id = V4L2_CID_CONTRAST, |
118 | .type = V4L2_CTRL_TYPE_INTEGER, | 115 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -120,13 +117,11 @@ static const struct ctrl sd_ctrls[] = { | |||
120 | .minimum = 0, | 117 | .minimum = 0, |
121 | .maximum = 255, | 118 | .maximum = 255, |
122 | .step = 1, | 119 | .step = 1, |
123 | #define CONTRAST_DEF 128 | 120 | .default_value = 128, |
124 | .default_value = CONTRAST_DEF, | ||
125 | }, | 121 | }, |
126 | .set = sd_setcontrast, | 122 | .set_control = setcontrast |
127 | .get = sd_getcontrast, | ||
128 | }, | 123 | }, |
129 | { | 124 | [GAMMA] = { |
130 | { | 125 | { |
131 | .id = V4L2_CID_GAMMA, | 126 | .id = V4L2_CID_GAMMA, |
132 | .type = V4L2_CTRL_TYPE_INTEGER, | 127 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -136,10 +131,9 @@ static const struct ctrl sd_ctrls[] = { | |||
136 | .step = 1, | 131 | .step = 1, |
137 | .default_value = 4, | 132 | .default_value = 4, |
138 | }, | 133 | }, |
139 | .set = sd_setgamma, | 134 | .set_control = setcontrast |
140 | .get = sd_getgamma, | ||
141 | }, | 135 | }, |
142 | { | 136 | [AUTOGAIN] = { |
143 | { | 137 | { |
144 | .id = V4L2_CID_AUTOGAIN, | 138 | .id = V4L2_CID_AUTOGAIN, |
145 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 139 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -147,14 +141,11 @@ static const struct ctrl sd_ctrls[] = { | |||
147 | .minimum = 0, | 141 | .minimum = 0, |
148 | .maximum = 1, | 142 | .maximum = 1, |
149 | .step = 1, | 143 | .step = 1, |
150 | #define AUTOGAIN_DEF 1 | 144 | .default_value = 1, |
151 | .default_value = AUTOGAIN_DEF, | ||
152 | }, | 145 | }, |
153 | .set = sd_setautogain, | 146 | .set_control = setautogain |
154 | .get = sd_getautogain, | ||
155 | }, | 147 | }, |
156 | #define LIGHTFREQ_IDX 4 | 148 | [LIGHTFREQ] = { |
157 | { | ||
158 | { | 149 | { |
159 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | 150 | .id = V4L2_CID_POWER_LINE_FREQUENCY, |
160 | .type = V4L2_CTRL_TYPE_MENU, | 151 | .type = V4L2_CTRL_TYPE_MENU, |
@@ -162,13 +153,11 @@ static const struct ctrl sd_ctrls[] = { | |||
162 | .minimum = 0, | 153 | .minimum = 0, |
163 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | 154 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ |
164 | .step = 1, | 155 | .step = 1, |
165 | #define FREQ_DEF 0 | 156 | .default_value = 0, |
166 | .default_value = FREQ_DEF, | ||
167 | }, | 157 | }, |
168 | .set = sd_setfreq, | 158 | .set_control = setlightfreq |
169 | .get = sd_getfreq, | ||
170 | }, | 159 | }, |
171 | { | 160 | [SHARPNESS] = { |
172 | { | 161 | { |
173 | .id = V4L2_CID_SHARPNESS, | 162 | .id = V4L2_CID_SHARPNESS, |
174 | .type = V4L2_CTRL_TYPE_INTEGER, | 163 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -176,11 +165,9 @@ static const struct ctrl sd_ctrls[] = { | |||
176 | .minimum = 0, | 165 | .minimum = 0, |
177 | .maximum = 3, | 166 | .maximum = 3, |
178 | .step = 1, | 167 | .step = 1, |
179 | #define SHARPNESS_DEF 2 | 168 | .default_value = 2, |
180 | .default_value = SHARPNESS_DEF, | ||
181 | }, | 169 | }, |
182 | .set = sd_setsharpness, | 170 | .set_control = setsharpness |
183 | .get = sd_getsharpness, | ||
184 | }, | 171 | }, |
185 | }; | 172 | }; |
186 | 173 | ||
@@ -4499,7 +4486,7 @@ static const struct usb_action mt9v111_3_Initial[] = { | |||
4499 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | 4486 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, |
4500 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | 4487 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, |
4501 | {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, | 4488 | {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, |
4502 | {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, | 4489 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, |
4503 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | 4490 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, |
4504 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | 4491 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, |
4505 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | 4492 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, |
@@ -5406,7 +5393,7 @@ static const struct usb_action tas5130c_NoFlikerScale[] = { | |||
5406 | {} | 5393 | {} |
5407 | }; | 5394 | }; |
5408 | 5395 | ||
5409 | static const struct usb_action tas5130c_vf0250_InitialScale[] = { | 5396 | static const struct usb_action gc0303_InitialScale[] = { |
5410 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ | 5397 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ |
5411 | {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ | 5398 | {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ |
5412 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ | 5399 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ |
@@ -5473,7 +5460,7 @@ static const struct usb_action tas5130c_vf0250_InitialScale[] = { | |||
5473 | {} | 5460 | {} |
5474 | }; | 5461 | }; |
5475 | 5462 | ||
5476 | static const struct usb_action tas5130c_vf0250_Initial[] = { | 5463 | static const struct usb_action gc0303_Initial[] = { |
5477 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ | 5464 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ |
5478 | {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ | 5465 | {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ |
5479 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ | 5466 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ |
@@ -5538,7 +5525,7 @@ static const struct usb_action tas5130c_vf0250_Initial[] = { | |||
5538 | {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ | 5525 | {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ |
5539 | {} | 5526 | {} |
5540 | }; | 5527 | }; |
5541 | static const struct usb_action tas5130c_vf0250_50HZScale[] = { | 5528 | static const struct usb_action gc0303_50HZScale[] = { |
5542 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 5529 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
5543 | {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ | 5530 | {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ |
5544 | {0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */ | 5531 | {0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */ |
@@ -5562,7 +5549,7 @@ static const struct usb_action tas5130c_vf0250_50HZScale[] = { | |||
5562 | {} | 5549 | {} |
5563 | }; | 5550 | }; |
5564 | 5551 | ||
5565 | static const struct usb_action tas5130c_vf0250_50HZ[] = { | 5552 | static const struct usb_action gc0303_50HZ[] = { |
5566 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 5553 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
5567 | {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */ | 5554 | {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */ |
5568 | {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */ | 5555 | {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */ |
@@ -5586,7 +5573,7 @@ static const struct usb_action tas5130c_vf0250_50HZ[] = { | |||
5586 | {} | 5573 | {} |
5587 | }; | 5574 | }; |
5588 | 5575 | ||
5589 | static const struct usb_action tas5130c_vf0250_60HZScale[] = { | 5576 | static const struct usb_action gc0303_60HZScale[] = { |
5590 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 5577 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
5591 | {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ | 5578 | {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ |
5592 | {0xaa, 0x84, 0x0062}, /* 00,84,62,aa */ | 5579 | {0xaa, 0x84, 0x0062}, /* 00,84,62,aa */ |
@@ -5610,7 +5597,7 @@ static const struct usb_action tas5130c_vf0250_60HZScale[] = { | |||
5610 | {} | 5597 | {} |
5611 | }; | 5598 | }; |
5612 | 5599 | ||
5613 | static const struct usb_action tas5130c_vf0250_60HZ[] = { | 5600 | static const struct usb_action gc0303_60HZ[] = { |
5614 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 5601 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
5615 | {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ | 5602 | {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ |
5616 | {0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */ | 5603 | {0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */ |
@@ -5634,7 +5621,7 @@ static const struct usb_action tas5130c_vf0250_60HZ[] = { | |||
5634 | {} | 5621 | {} |
5635 | }; | 5622 | }; |
5636 | 5623 | ||
5637 | static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = { | 5624 | static const struct usb_action gc0303_NoFlikerScale[] = { |
5638 | {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ | 5625 | {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ |
5639 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 5626 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
5640 | {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ | 5627 | {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ |
@@ -5656,7 +5643,7 @@ static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = { | |||
5656 | {} | 5643 | {} |
5657 | }; | 5644 | }; |
5658 | 5645 | ||
5659 | static const struct usb_action tas5130c_vf0250_NoFliker[] = { | 5646 | static const struct usb_action gc0303_NoFliker[] = { |
5660 | {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ | 5647 | {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ |
5661 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 5648 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
5662 | {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ | 5649 | {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ |
@@ -5833,12 +5820,13 @@ static void setmatrix(struct gspca_dev *gspca_dev) | |||
5833 | {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; | 5820 | {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; |
5834 | static const u8 tas5130c_matrix[9] = | 5821 | static const u8 tas5130c_matrix[9] = |
5835 | {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68}; | 5822 | {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68}; |
5836 | static const u8 vf0250_matrix[9] = | 5823 | static const u8 gc0303_matrix[9] = |
5837 | {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; | 5824 | {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; |
5838 | static const u8 *matrix_tb[SENSOR_MAX] = { | 5825 | static const u8 *matrix_tb[SENSOR_MAX] = { |
5839 | [SENSOR_ADCM2700] = adcm2700_matrix, | 5826 | [SENSOR_ADCM2700] = adcm2700_matrix, |
5840 | [SENSOR_CS2102] = ov7620_matrix, | 5827 | [SENSOR_CS2102] = ov7620_matrix, |
5841 | [SENSOR_CS2102K] = NULL, | 5828 | [SENSOR_CS2102K] = NULL, |
5829 | [SENSOR_GC0303] = gc0303_matrix, | ||
5842 | [SENSOR_GC0305] = gc0305_matrix, | 5830 | [SENSOR_GC0305] = gc0305_matrix, |
5843 | [SENSOR_HDCS2020b] = NULL, | 5831 | [SENSOR_HDCS2020b] = NULL, |
5844 | [SENSOR_HV7131B] = NULL, | 5832 | [SENSOR_HV7131B] = NULL, |
@@ -5854,7 +5842,6 @@ static void setmatrix(struct gspca_dev *gspca_dev) | |||
5854 | [SENSOR_PB0330] = gc0305_matrix, | 5842 | [SENSOR_PB0330] = gc0305_matrix, |
5855 | [SENSOR_PO2030] = po2030_matrix, | 5843 | [SENSOR_PO2030] = po2030_matrix, |
5856 | [SENSOR_TAS5130C] = tas5130c_matrix, | 5844 | [SENSOR_TAS5130C] = tas5130c_matrix, |
5857 | [SENSOR_TAS5130C_VF0250] = vf0250_matrix, | ||
5858 | }; | 5845 | }; |
5859 | 5846 | ||
5860 | matrix = matrix_tb[sd->sensor]; | 5847 | matrix = matrix_tb[sd->sensor]; |
@@ -5875,7 +5862,7 @@ static void setsharpness(struct gspca_dev *gspca_dev) | |||
5875 | {0x10, 0x1e} | 5862 | {0x10, 0x1e} |
5876 | }; | 5863 | }; |
5877 | 5864 | ||
5878 | sharpness = sd->sharpness; | 5865 | sharpness = sd->ctrls[SHARPNESS].val; |
5879 | reg_w(gspca_dev, sharpness_tb[sharpness][0], 0x01c6); | 5866 | reg_w(gspca_dev, sharpness_tb[sharpness][0], 0x01c6); |
5880 | reg_r(gspca_dev, 0x01c8); | 5867 | reg_r(gspca_dev, 0x01c8); |
5881 | reg_r(gspca_dev, 0x01c9); | 5868 | reg_r(gspca_dev, 0x01c9); |
@@ -5910,10 +5897,10 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
5910 | 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}, | 5897 | 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}, |
5911 | }; | 5898 | }; |
5912 | 5899 | ||
5913 | Tgamma = gamma_tb[sd->gamma - 1]; | 5900 | Tgamma = gamma_tb[sd->ctrls[GAMMA].val - 1]; |
5914 | 5901 | ||
5915 | contrast = ((int) sd->contrast - 128); /* -128 / 127 */ | 5902 | contrast = ((int) sd->ctrls[CONTRAST].val - 128); /* -128 / 127 */ |
5916 | brightness = ((int) sd->brightness - 128); /* -128 / 92 */ | 5903 | brightness = ((int) sd->ctrls[BRIGHTNESS].val - 128); /* -128 / 92 */ |
5917 | adj = 0; | 5904 | adj = 0; |
5918 | gp1 = gp2 = 0; | 5905 | gp1 = gp2 = 0; |
5919 | for (i = 0; i < 16; i++) { | 5906 | for (i = 0; i < 16; i++) { |
@@ -5994,6 +5981,10 @@ static void setlightfreq(struct gspca_dev *gspca_dev) | |||
5994 | {cs2102_NoFliker, cs2102_NoFlikerScale, | 5981 | {cs2102_NoFliker, cs2102_NoFlikerScale, |
5995 | NULL, NULL, /* currently disabled */ | 5982 | NULL, NULL, /* currently disabled */ |
5996 | NULL, NULL}, | 5983 | NULL, NULL}, |
5984 | [SENSOR_GC0303] = | ||
5985 | {gc0303_NoFliker, gc0303_NoFlikerScale, | ||
5986 | gc0303_50HZ, gc0303_50HZScale, | ||
5987 | gc0303_60HZ, gc0303_60HZScale}, | ||
5997 | [SENSOR_GC0305] = | 5988 | [SENSOR_GC0305] = |
5998 | {gc0305_NoFliker, gc0305_NoFliker, | 5989 | {gc0305_NoFliker, gc0305_NoFliker, |
5999 | gc0305_50HZ, gc0305_50HZ, | 5990 | gc0305_50HZ, gc0305_50HZ, |
@@ -6054,14 +6045,10 @@ static void setlightfreq(struct gspca_dev *gspca_dev) | |||
6054 | {tas5130c_NoFliker, tas5130c_NoFlikerScale, | 6045 | {tas5130c_NoFliker, tas5130c_NoFlikerScale, |
6055 | tas5130c_50HZ, tas5130c_50HZScale, | 6046 | tas5130c_50HZ, tas5130c_50HZScale, |
6056 | tas5130c_60HZ, tas5130c_60HZScale}, | 6047 | tas5130c_60HZ, tas5130c_60HZScale}, |
6057 | [SENSOR_TAS5130C_VF0250] = | ||
6058 | {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale, | ||
6059 | tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, | ||
6060 | tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale}, | ||
6061 | }; | 6048 | }; |
6062 | 6049 | ||
6063 | i = sd->lightfreq * 2; | 6050 | i = sd->ctrls[LIGHTFREQ].val * 2; |
6064 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | 6051 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; |
6065 | if (mode) | 6052 | if (mode) |
6066 | i++; /* 320x240 */ | 6053 | i++; /* 320x240 */ |
6067 | zc3_freq = freq_tb[sd->sensor][i]; | 6054 | zc3_freq = freq_tb[sd->sensor][i]; |
@@ -6070,14 +6057,14 @@ static void setlightfreq(struct gspca_dev *gspca_dev) | |||
6070 | usb_exchange(gspca_dev, zc3_freq); | 6057 | usb_exchange(gspca_dev, zc3_freq); |
6071 | switch (sd->sensor) { | 6058 | switch (sd->sensor) { |
6072 | case SENSOR_GC0305: | 6059 | case SENSOR_GC0305: |
6073 | if (mode /* if 320x240 */ | 6060 | if (mode /* if 320x240 */ |
6074 | && sd->lightfreq == 1) /* and 50Hz */ | 6061 | && sd->ctrls[LIGHTFREQ].val == 1) /* and 50Hz */ |
6075 | reg_w(gspca_dev, 0x85, 0x018d); | 6062 | reg_w(gspca_dev, 0x85, 0x018d); |
6076 | /* win: 0x80, 0x018d */ | 6063 | /* win: 0x80, 0x018d */ |
6077 | break; | 6064 | break; |
6078 | case SENSOR_OV7620: | 6065 | case SENSOR_OV7620: |
6079 | if (!mode) { /* if 640x480 */ | 6066 | if (!mode) { /* if 640x480 */ |
6080 | if (sd->lightfreq != 0) /* and 50 or 60 Hz */ | 6067 | if (sd->ctrls[LIGHTFREQ].val != 0) /* and filter */ |
6081 | reg_w(gspca_dev, 0x40, 0x0002); | 6068 | reg_w(gspca_dev, 0x40, 0x0002); |
6082 | else | 6069 | else |
6083 | reg_w(gspca_dev, 0x44, 0x0002); | 6070 | reg_w(gspca_dev, 0x44, 0x0002); |
@@ -6094,7 +6081,7 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
6094 | struct sd *sd = (struct sd *) gspca_dev; | 6081 | struct sd *sd = (struct sd *) gspca_dev; |
6095 | u8 autoval; | 6082 | u8 autoval; |
6096 | 6083 | ||
6097 | if (sd->autogain) | 6084 | if (sd->ctrls[AUTOGAIN].val) |
6098 | autoval = 0x42; | 6085 | autoval = 0x42; |
6099 | else | 6086 | else |
6100 | autoval = 0x02; | 6087 | autoval = 0x02; |
@@ -6330,8 +6317,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) | |||
6330 | retword = i2c_read(gspca_dev, 0x00); | 6317 | retword = i2c_read(gspca_dev, 0x00); |
6331 | if (retword != 0) { | 6318 | if (retword != 0) { |
6332 | PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword); | 6319 | PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword); |
6333 | if (retword == 0x0011) /* VF0250 */ | 6320 | if (retword == 0x0011) /* gc0303 */ |
6334 | return 0x0250; | 6321 | return 0x0303; |
6335 | if (retword == 0x0029) /* gc0305 */ | 6322 | if (retword == 0x0029) /* gc0305 */ |
6336 | send_unknown(gspca_dev, SENSOR_GC0305); | 6323 | send_unknown(gspca_dev, SENSOR_GC0305); |
6337 | return retword; | 6324 | return retword; |
@@ -6392,7 +6379,7 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev) | |||
6392 | switch (sd->sensor) { | 6379 | switch (sd->sensor) { |
6393 | case SENSOR_MC501CB: | 6380 | case SENSOR_MC501CB: |
6394 | return -1; /* don't probe */ | 6381 | return -1; /* don't probe */ |
6395 | case SENSOR_TAS5130C_VF0250: | 6382 | case SENSOR_GC0303: |
6396 | /* may probe but with no write in reg 0x0010 */ | 6383 | /* may probe but with no write in reg 0x0010 */ |
6397 | return -1; /* don't probe */ | 6384 | return -1; /* don't probe */ |
6398 | case SENSOR_PAS106: | 6385 | case SENSOR_PAS106: |
@@ -6421,11 +6408,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
6421 | /* define some sensors from the vendor/product */ | 6408 | /* define some sensors from the vendor/product */ |
6422 | sd->sensor = id->driver_info; | 6409 | sd->sensor = id->driver_info; |
6423 | 6410 | ||
6424 | sd->sharpness = SHARPNESS_DEF; | 6411 | gspca_dev->cam.ctrls = sd->ctrls; |
6425 | sd->brightness = BRIGHTNESS_DEF; | ||
6426 | sd->contrast = CONTRAST_DEF; | ||
6427 | sd->autogain = AUTOGAIN_DEF; | ||
6428 | sd->lightfreq = FREQ_DEF; | ||
6429 | sd->quality = QUALITY_DEF; | 6412 | sd->quality = QUALITY_DEF; |
6430 | 6413 | ||
6431 | return 0; | 6414 | return 0; |
@@ -6441,6 +6424,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
6441 | [SENSOR_ADCM2700] = 4, | 6424 | [SENSOR_ADCM2700] = 4, |
6442 | [SENSOR_CS2102] = 4, | 6425 | [SENSOR_CS2102] = 4, |
6443 | [SENSOR_CS2102K] = 5, | 6426 | [SENSOR_CS2102K] = 5, |
6427 | [SENSOR_GC0303] = 3, | ||
6444 | [SENSOR_GC0305] = 4, | 6428 | [SENSOR_GC0305] = 4, |
6445 | [SENSOR_HDCS2020b] = 4, | 6429 | [SENSOR_HDCS2020b] = 4, |
6446 | [SENSOR_HV7131B] = 4, | 6430 | [SENSOR_HV7131B] = 4, |
@@ -6456,12 +6440,12 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
6456 | [SENSOR_PB0330] = 4, | 6440 | [SENSOR_PB0330] = 4, |
6457 | [SENSOR_PO2030] = 4, | 6441 | [SENSOR_PO2030] = 4, |
6458 | [SENSOR_TAS5130C] = 3, | 6442 | [SENSOR_TAS5130C] = 3, |
6459 | [SENSOR_TAS5130C_VF0250] = 3, | ||
6460 | }; | 6443 | }; |
6461 | static const u8 mode_tb[SENSOR_MAX] = { | 6444 | static const u8 mode_tb[SENSOR_MAX] = { |
6462 | [SENSOR_ADCM2700] = 2, | 6445 | [SENSOR_ADCM2700] = 2, |
6463 | [SENSOR_CS2102] = 1, | 6446 | [SENSOR_CS2102] = 1, |
6464 | [SENSOR_CS2102K] = 1, | 6447 | [SENSOR_CS2102K] = 1, |
6448 | [SENSOR_GC0303] = 1, | ||
6465 | [SENSOR_GC0305] = 1, | 6449 | [SENSOR_GC0305] = 1, |
6466 | [SENSOR_HDCS2020b] = 1, | 6450 | [SENSOR_HDCS2020b] = 1, |
6467 | [SENSOR_HV7131B] = 1, | 6451 | [SENSOR_HV7131B] = 1, |
@@ -6477,7 +6461,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
6477 | [SENSOR_PB0330] = 1, | 6461 | [SENSOR_PB0330] = 1, |
6478 | [SENSOR_PO2030] = 1, | 6462 | [SENSOR_PO2030] = 1, |
6479 | [SENSOR_TAS5130C] = 1, | 6463 | [SENSOR_TAS5130C] = 1, |
6480 | [SENSOR_TAS5130C_VF0250] = 1, | ||
6481 | }; | 6464 | }; |
6482 | 6465 | ||
6483 | sensor = zcxx_probeSensor(gspca_dev); | 6466 | sensor = zcxx_probeSensor(gspca_dev); |
@@ -6493,8 +6476,8 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
6493 | case SENSOR_MC501CB: | 6476 | case SENSOR_MC501CB: |
6494 | PDEBUG(D_PROBE, "Sensor MC501CB"); | 6477 | PDEBUG(D_PROBE, "Sensor MC501CB"); |
6495 | break; | 6478 | break; |
6496 | case SENSOR_TAS5130C_VF0250: | 6479 | case SENSOR_GC0303: |
6497 | PDEBUG(D_PROBE, "Sensor Tas5130 (VF0250)"); | 6480 | PDEBUG(D_PROBE, "Sensor GC0303"); |
6498 | break; | 6481 | break; |
6499 | default: | 6482 | default: |
6500 | warn("Unknown sensor - set to TAS5130C"); | 6483 | warn("Unknown sensor - set to TAS5130C"); |
@@ -6581,14 +6564,14 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
6581 | PDEBUG(D_PROBE, "Find Sensor GC0305"); | 6564 | PDEBUG(D_PROBE, "Find Sensor GC0305"); |
6582 | sd->sensor = SENSOR_GC0305; | 6565 | sd->sensor = SENSOR_GC0305; |
6583 | break; | 6566 | break; |
6584 | case 0x0250: | 6567 | case 0x0303: |
6585 | PDEBUG(D_PROBE, "Sensor Tas5130 (VF0250)"); | 6568 | PDEBUG(D_PROBE, "Sensor GC0303"); |
6586 | sd->sensor = SENSOR_TAS5130C_VF0250; | 6569 | sd->sensor = SENSOR_GC0303; |
6587 | break; | 6570 | break; |
6588 | case 0x2030: | 6571 | case 0x2030: |
6589 | PDEBUG(D_PROBE, "Find Sensor PO2030"); | 6572 | PDEBUG(D_PROBE, "Find Sensor PO2030"); |
6590 | sd->sensor = SENSOR_PO2030; | 6573 | sd->sensor = SENSOR_PO2030; |
6591 | sd->sharpness = 0; /* from win traces */ | 6574 | sd->ctrls[SHARPNESS].def = 0; /* from win traces */ |
6592 | break; | 6575 | break; |
6593 | case 0x7620: | 6576 | case 0x7620: |
6594 | PDEBUG(D_PROBE, "Find Sensor OV7620"); | 6577 | PDEBUG(D_PROBE, "Find Sensor OV7620"); |
@@ -6629,11 +6612,12 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
6629 | cam->nmodes = ARRAY_SIZE(broken_vga_mode); | 6612 | cam->nmodes = ARRAY_SIZE(broken_vga_mode); |
6630 | break; | 6613 | break; |
6631 | } | 6614 | } |
6632 | sd->gamma = gamma[sd->sensor]; | 6615 | |
6616 | sd->ctrls[GAMMA].def = gamma[sd->sensor]; | ||
6633 | 6617 | ||
6634 | switch (sd->sensor) { | 6618 | switch (sd->sensor) { |
6635 | case SENSOR_OV7630C: | 6619 | case SENSOR_OV7630C: |
6636 | gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX); | 6620 | gspca_dev->ctrl_dis = (1 << LIGHTFREQ); |
6637 | break; | 6621 | break; |
6638 | } | 6622 | } |
6639 | 6623 | ||
@@ -6653,6 +6637,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
6653 | {cs2102_Initial, cs2102_InitialScale}, | 6637 | {cs2102_Initial, cs2102_InitialScale}, |
6654 | [SENSOR_CS2102K] = | 6638 | [SENSOR_CS2102K] = |
6655 | {cs2102K_Initial, cs2102K_InitialScale}, | 6639 | {cs2102K_Initial, cs2102K_InitialScale}, |
6640 | [SENSOR_GC0303] = | ||
6641 | {gc0303_Initial, gc0303_InitialScale}, | ||
6656 | [SENSOR_GC0305] = | 6642 | [SENSOR_GC0305] = |
6657 | {gc0305_Initial, gc0305_InitialScale}, | 6643 | {gc0305_Initial, gc0305_InitialScale}, |
6658 | [SENSOR_HDCS2020b] = | 6644 | [SENSOR_HDCS2020b] = |
@@ -6683,8 +6669,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
6683 | {po2030_Initial, po2030_InitialScale}, | 6669 | {po2030_Initial, po2030_InitialScale}, |
6684 | [SENSOR_TAS5130C] = | 6670 | [SENSOR_TAS5130C] = |
6685 | {tas5130c_Initial, tas5130c_InitialScale}, | 6671 | {tas5130c_Initial, tas5130c_InitialScale}, |
6686 | [SENSOR_TAS5130C_VF0250] = | ||
6687 | {tas5130c_vf0250_Initial, tas5130c_vf0250_InitialScale}, | ||
6688 | }; | 6672 | }; |
6689 | 6673 | ||
6690 | /* create the JPEG header */ | 6674 | /* create the JPEG header */ |
@@ -6709,7 +6693,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
6709 | case SENSOR_OV7620: | 6693 | case SENSOR_OV7620: |
6710 | case SENSOR_PO2030: | 6694 | case SENSOR_PO2030: |
6711 | case SENSOR_TAS5130C: | 6695 | case SENSOR_TAS5130C: |
6712 | case SENSOR_TAS5130C_VF0250: | 6696 | case SENSOR_GC0303: |
6713 | /* msleep(100); * ?? */ | 6697 | /* msleep(100); * ?? */ |
6714 | reg_r(gspca_dev, 0x0002); /* --> 0x40 */ | 6698 | reg_r(gspca_dev, 0x0002); /* --> 0x40 */ |
6715 | reg_w(gspca_dev, 0x09, 0x01ad); /* (from win traces) */ | 6699 | reg_w(gspca_dev, 0x09, 0x01ad); /* (from win traces) */ |
@@ -6843,114 +6827,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
6843 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 6827 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
6844 | } | 6828 | } |
6845 | 6829 | ||
6846 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
6847 | { | ||
6848 | struct sd *sd = (struct sd *) gspca_dev; | ||
6849 | |||
6850 | sd->brightness = val; | ||
6851 | if (gspca_dev->streaming) | ||
6852 | setcontrast(gspca_dev); | ||
6853 | return gspca_dev->usb_err; | ||
6854 | } | ||
6855 | |||
6856 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
6857 | { | ||
6858 | struct sd *sd = (struct sd *) gspca_dev; | ||
6859 | |||
6860 | *val = sd->brightness; | ||
6861 | return 0; | ||
6862 | } | ||
6863 | |||
6864 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
6865 | { | ||
6866 | struct sd *sd = (struct sd *) gspca_dev; | ||
6867 | |||
6868 | sd->contrast = val; | ||
6869 | if (gspca_dev->streaming) | ||
6870 | setcontrast(gspca_dev); | ||
6871 | return gspca_dev->usb_err; | ||
6872 | } | ||
6873 | |||
6874 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
6875 | { | ||
6876 | struct sd *sd = (struct sd *) gspca_dev; | ||
6877 | |||
6878 | *val = sd->contrast; | ||
6879 | return 0; | ||
6880 | } | ||
6881 | |||
6882 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
6883 | { | ||
6884 | struct sd *sd = (struct sd *) gspca_dev; | ||
6885 | |||
6886 | sd->autogain = val; | ||
6887 | if (gspca_dev->streaming) | ||
6888 | setautogain(gspca_dev); | ||
6889 | return gspca_dev->usb_err; | ||
6890 | } | ||
6891 | |||
6892 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
6893 | { | ||
6894 | struct sd *sd = (struct sd *) gspca_dev; | ||
6895 | |||
6896 | *val = sd->autogain; | ||
6897 | return 0; | ||
6898 | } | ||
6899 | |||
6900 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) | ||
6901 | { | ||
6902 | struct sd *sd = (struct sd *) gspca_dev; | ||
6903 | |||
6904 | sd->gamma = val; | ||
6905 | if (gspca_dev->streaming) | ||
6906 | setcontrast(gspca_dev); | ||
6907 | return gspca_dev->usb_err; | ||
6908 | } | ||
6909 | |||
6910 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) | ||
6911 | { | ||
6912 | struct sd *sd = (struct sd *) gspca_dev; | ||
6913 | |||
6914 | *val = sd->gamma; | ||
6915 | return 0; | ||
6916 | } | ||
6917 | |||
6918 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
6919 | { | ||
6920 | struct sd *sd = (struct sd *) gspca_dev; | ||
6921 | |||
6922 | sd->lightfreq = val; | ||
6923 | if (gspca_dev->streaming) | ||
6924 | setlightfreq(gspca_dev); | ||
6925 | return gspca_dev->usb_err; | ||
6926 | } | ||
6927 | |||
6928 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
6929 | { | ||
6930 | struct sd *sd = (struct sd *) gspca_dev; | ||
6931 | |||
6932 | *val = sd->lightfreq; | ||
6933 | return 0; | ||
6934 | } | ||
6935 | |||
6936 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
6937 | { | ||
6938 | struct sd *sd = (struct sd *) gspca_dev; | ||
6939 | |||
6940 | sd->sharpness = val; | ||
6941 | if (gspca_dev->streaming) | ||
6942 | setsharpness(gspca_dev); | ||
6943 | return gspca_dev->usb_err; | ||
6944 | } | ||
6945 | |||
6946 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
6947 | { | ||
6948 | struct sd *sd = (struct sd *) gspca_dev; | ||
6949 | |||
6950 | *val = sd->sharpness; | ||
6951 | return 0; | ||
6952 | } | ||
6953 | |||
6954 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 6830 | static int sd_querymenu(struct gspca_dev *gspca_dev, |
6955 | struct v4l2_querymenu *menu) | 6831 | struct v4l2_querymenu *menu) |
6956 | { | 6832 | { |
@@ -7045,8 +6921,8 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
7045 | {USB_DEVICE(0x041e, 0x4035), .driver_info = SENSOR_PAS106}, | 6921 | {USB_DEVICE(0x041e, 0x4035), .driver_info = SENSOR_PAS106}, |
7046 | {USB_DEVICE(0x041e, 0x4036)}, | 6922 | {USB_DEVICE(0x041e, 0x4036)}, |
7047 | {USB_DEVICE(0x041e, 0x403a)}, | 6923 | {USB_DEVICE(0x041e, 0x403a)}, |
7048 | {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_TAS5130C_VF0250}, | 6924 | {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_GC0303}, |
7049 | {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_TAS5130C_VF0250}, | 6925 | {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_GC0303}, |
7050 | {USB_DEVICE(0x0458, 0x7007)}, | 6926 | {USB_DEVICE(0x0458, 0x7007)}, |
7051 | {USB_DEVICE(0x0458, 0x700c)}, | 6927 | {USB_DEVICE(0x0458, 0x700c)}, |
7052 | {USB_DEVICE(0x0458, 0x700f)}, | 6928 | {USB_DEVICE(0x0458, 0x700f)}, |
@@ -7066,8 +6942,8 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
7066 | {USB_DEVICE(0x046d, 0x08af)}, | 6942 | {USB_DEVICE(0x046d, 0x08af)}, |
7067 | {USB_DEVICE(0x046d, 0x08b9)}, | 6943 | {USB_DEVICE(0x046d, 0x08b9)}, |
7068 | {USB_DEVICE(0x046d, 0x08d7)}, | 6944 | {USB_DEVICE(0x046d, 0x08d7)}, |
7069 | {USB_DEVICE(0x046d, 0x08d9)}, | ||
7070 | {USB_DEVICE(0x046d, 0x08d8)}, | 6945 | {USB_DEVICE(0x046d, 0x08d8)}, |
6946 | {USB_DEVICE(0x046d, 0x08d9)}, | ||
7071 | {USB_DEVICE(0x046d, 0x08da)}, | 6947 | {USB_DEVICE(0x046d, 0x08da)}, |
7072 | {USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB}, | 6948 | {USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB}, |
7073 | {USB_DEVICE(0x0471, 0x0325), .driver_info = SENSOR_PAS106}, | 6949 | {USB_DEVICE(0x0471, 0x0325), .driver_info = SENSOR_PAS106}, |
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c index b70d6afc9fec..f7d1ee55185a 100644 --- a/drivers/media/video/hdpvr/hdpvr-core.c +++ b/drivers/media/video/hdpvr/hdpvr-core.c | |||
@@ -385,6 +385,11 @@ static int hdpvr_probe(struct usb_interface *interface, | |||
385 | v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n"); | 385 | v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n"); |
386 | goto error; | 386 | goto error; |
387 | } | 387 | } |
388 | |||
389 | /* until i2c is working properly */ | ||
390 | retval = 0; /* hdpvr_register_i2c_ir(dev); */ | ||
391 | if (retval < 0) | ||
392 | v4l2_err(&dev->v4l2_dev, "registering i2c IR devices failed\n"); | ||
388 | #endif /* CONFIG_I2C */ | 393 | #endif /* CONFIG_I2C */ |
389 | 394 | ||
390 | /* let the user know what node this device is now attached to */ | 395 | /* let the user know what node this device is now attached to */ |
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c index 409de11096d4..24966aa02a70 100644 --- a/drivers/media/video/hdpvr/hdpvr-i2c.c +++ b/drivers/media/video/hdpvr/hdpvr-i2c.c | |||
@@ -4,6 +4,9 @@ | |||
4 | * | 4 | * |
5 | * Copyright (C) 2008 Janne Grunau (j@jannau.net) | 5 | * Copyright (C) 2008 Janne Grunau (j@jannau.net) |
6 | * | 6 | * |
7 | * IR device registration code is | ||
8 | * Copyright (C) 2010 Andy Walls <awalls@md.metrocast.net> | ||
9 | * | ||
7 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License as | 11 | * modify it under the terms of the GNU General Public License as |
9 | * published by the Free Software Foundation, version 2. | 12 | * published by the Free Software Foundation, version 2. |
@@ -22,6 +25,56 @@ | |||
22 | #define REQTYPE_I2C_WRITE 0xb0 | 25 | #define REQTYPE_I2C_WRITE 0xb0 |
23 | #define REQTYPE_I2C_WRITE_STATT 0xd0 | 26 | #define REQTYPE_I2C_WRITE_STATT 0xd0 |
24 | 27 | ||
28 | #define Z8F0811_IR_TX_I2C_ADDR 0x70 | ||
29 | #define Z8F0811_IR_RX_I2C_ADDR 0x71 | ||
30 | |||
31 | static const u8 ir_i2c_addrs[] = { | ||
32 | Z8F0811_IR_TX_I2C_ADDR, | ||
33 | Z8F0811_IR_RX_I2C_ADDR, | ||
34 | }; | ||
35 | |||
36 | static const char * const ir_devicenames[] = { | ||
37 | "ir_tx_z8f0811_hdpvr", | ||
38 | "ir_rx_z8f0811_hdpvr", | ||
39 | }; | ||
40 | |||
41 | static int hdpvr_new_i2c_ir(struct hdpvr_device *dev, struct i2c_adapter *adap, | ||
42 | const char *type, u8 addr) | ||
43 | { | ||
44 | struct i2c_board_info info; | ||
45 | struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data; | ||
46 | unsigned short addr_list[2] = { addr, I2C_CLIENT_END }; | ||
47 | |||
48 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
49 | strlcpy(info.type, type, I2C_NAME_SIZE); | ||
50 | |||
51 | /* Our default information for ir-kbd-i2c.c to use */ | ||
52 | switch (addr) { | ||
53 | case Z8F0811_IR_RX_I2C_ADDR: | ||
54 | init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; | ||
55 | init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; | ||
56 | init_data->type = RC_TYPE_RC5; | ||
57 | init_data->name = "HD PVR"; | ||
58 | info.platform_data = init_data; | ||
59 | break; | ||
60 | } | ||
61 | |||
62 | return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ? | ||
63 | -1 : 0; | ||
64 | } | ||
65 | |||
66 | int hdpvr_register_i2c_ir(struct hdpvr_device *dev) | ||
67 | { | ||
68 | int i; | ||
69 | int ret = 0; | ||
70 | |||
71 | for (i = 0; i < ARRAY_SIZE(ir_i2c_addrs); i++) | ||
72 | ret += hdpvr_new_i2c_ir(dev, dev->i2c_adapter, | ||
73 | ir_devicenames[i], ir_i2c_addrs[i]); | ||
74 | |||
75 | return ret; | ||
76 | } | ||
77 | |||
25 | static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr, | 78 | static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr, |
26 | char *data, int len) | 79 | char *data, int len) |
27 | { | 80 | { |
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h index 5efc963f9164..37f1e4c7675d 100644 --- a/drivers/media/video/hdpvr/hdpvr.h +++ b/drivers/media/video/hdpvr/hdpvr.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/videodev2.h> | 16 | #include <linux/videodev2.h> |
17 | 17 | ||
18 | #include <media/v4l2-device.h> | 18 | #include <media/v4l2-device.h> |
19 | #include <media/ir-kbd-i2c.h> | ||
19 | 20 | ||
20 | #define HDPVR_MAJOR_VERSION 0 | 21 | #define HDPVR_MAJOR_VERSION 0 |
21 | #define HDPVR_MINOR_VERSION 2 | 22 | #define HDPVR_MINOR_VERSION 2 |
@@ -109,6 +110,9 @@ struct hdpvr_device { | |||
109 | /* I2C lock */ | 110 | /* I2C lock */ |
110 | struct mutex i2c_mutex; | 111 | struct mutex i2c_mutex; |
111 | 112 | ||
113 | /* For passing data to ir-kbd-i2c */ | ||
114 | struct IR_i2c_init_data ir_i2c_init_data; | ||
115 | |||
112 | /* usb control transfer buffer and lock */ | 116 | /* usb control transfer buffer and lock */ |
113 | struct mutex usbc_mutex; | 117 | struct mutex usbc_mutex; |
114 | u8 *usbc_buf; | 118 | u8 *usbc_buf; |
@@ -306,6 +310,8 @@ int hdpvr_cancel_queue(struct hdpvr_device *dev); | |||
306 | /* i2c adapter registration */ | 310 | /* i2c adapter registration */ |
307 | int hdpvr_register_i2c_adapter(struct hdpvr_device *dev); | 311 | int hdpvr_register_i2c_adapter(struct hdpvr_device *dev); |
308 | 312 | ||
313 | int hdpvr_register_i2c_ir(struct hdpvr_device *dev); | ||
314 | |||
309 | /*========================================================================*/ | 315 | /*========================================================================*/ |
310 | /* buffer management */ | 316 | /* buffer management */ |
311 | int hdpvr_free_buffers(struct hdpvr_device *dev); | 317 | int hdpvr_free_buffers(struct hdpvr_device *dev); |
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c index 7ae96367b3ab..cdf8b191f710 100644 --- a/drivers/media/video/hexium_gemini.c +++ b/drivers/media/video/hexium_gemini.c | |||
@@ -37,15 +37,15 @@ static int hexium_num; | |||
37 | 37 | ||
38 | #define HEXIUM_INPUTS 9 | 38 | #define HEXIUM_INPUTS 9 |
39 | static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = { | 39 | static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = { |
40 | { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 40 | { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
41 | { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 41 | { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
42 | { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 42 | { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
43 | { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 43 | { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
44 | { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 44 | { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
45 | { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 45 | { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
46 | { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 46 | { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
47 | { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 47 | { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
48 | { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 48 | { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
49 | }; | 49 | }; |
50 | 50 | ||
51 | #define HEXIUM_AUDIOS 0 | 51 | #define HEXIUM_AUDIOS 0 |
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c index b72d0f0b8310..6ad7e1c8b922 100644 --- a/drivers/media/video/hexium_orion.c +++ b/drivers/media/video/hexium_orion.c | |||
@@ -38,15 +38,15 @@ static int hexium_num; | |||
38 | 38 | ||
39 | #define HEXIUM_INPUTS 9 | 39 | #define HEXIUM_INPUTS 9 |
40 | static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = { | 40 | static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = { |
41 | { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 41 | { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
42 | { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 42 | { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
43 | { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 43 | { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
44 | { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 44 | { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
45 | { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 45 | { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
46 | { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 46 | { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
47 | { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 47 | { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
48 | { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 48 | { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
49 | { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 49 | { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | #define HEXIUM_AUDIOS 0 | 52 | #define HEXIUM_AUDIOS 0 |
diff --git a/drivers/media/video/imx074.c b/drivers/media/video/imx074.c index 27b5dfdfbb93..1a1169115716 100644 --- a/drivers/media/video/imx074.c +++ b/drivers/media/video/imx074.c | |||
@@ -467,7 +467,6 @@ static int imx074_remove(struct i2c_client *client) | |||
467 | icd->ops = NULL; | 467 | icd->ops = NULL; |
468 | if (icl->free_bus) | 468 | if (icl->free_bus) |
469 | icl->free_bus(icl); | 469 | icl->free_bus(icl); |
470 | client->driver = NULL; | ||
471 | kfree(priv); | 470 | kfree(priv); |
472 | 471 | ||
473 | return 0; | 472 | return 0; |
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index ce4a75375909..c87b6bc45555 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include <linux/i2c.h> | 46 | #include <linux/i2c.h> |
47 | #include <linux/workqueue.h> | 47 | #include <linux/workqueue.h> |
48 | 48 | ||
49 | #include <media/ir-core.h> | 49 | #include <media/rc-core.h> |
50 | #include <media/ir-kbd-i2c.h> | 50 | #include <media/ir-kbd-i2c.h> |
51 | 51 | ||
52 | /* ----------------------------------------------------------------------- */ | 52 | /* ----------------------------------------------------------------------- */ |
@@ -252,7 +252,7 @@ static void ir_key_poll(struct IR_i2c *ir) | |||
252 | } | 252 | } |
253 | 253 | ||
254 | if (rc) | 254 | if (rc) |
255 | ir_keydown(ir->input, ir_key, 0); | 255 | rc_keydown(ir->rc, ir_key, 0); |
256 | } | 256 | } |
257 | 257 | ||
258 | static void ir_work(struct work_struct *work) | 258 | static void ir_work(struct work_struct *work) |
@@ -269,22 +269,18 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
269 | { | 269 | { |
270 | char *ir_codes = NULL; | 270 | char *ir_codes = NULL; |
271 | const char *name = NULL; | 271 | const char *name = NULL; |
272 | u64 ir_type = 0; | 272 | u64 rc_type = RC_TYPE_UNKNOWN; |
273 | struct IR_i2c *ir; | 273 | struct IR_i2c *ir; |
274 | struct input_dev *input_dev; | 274 | struct rc_dev *rc = NULL; |
275 | struct i2c_adapter *adap = client->adapter; | 275 | struct i2c_adapter *adap = client->adapter; |
276 | unsigned short addr = client->addr; | 276 | unsigned short addr = client->addr; |
277 | int err; | 277 | int err; |
278 | 278 | ||
279 | ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); | 279 | ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL); |
280 | input_dev = input_allocate_device(); | 280 | if (!ir) |
281 | if (!ir || !input_dev) { | 281 | return -ENOMEM; |
282 | err = -ENOMEM; | ||
283 | goto err_out_free; | ||
284 | } | ||
285 | 282 | ||
286 | ir->c = client; | 283 | ir->c = client; |
287 | ir->input = input_dev; | ||
288 | ir->polling_interval = DEFAULT_POLLING_INTERVAL; | 284 | ir->polling_interval = DEFAULT_POLLING_INTERVAL; |
289 | i2c_set_clientdata(client, ir); | 285 | i2c_set_clientdata(client, ir); |
290 | 286 | ||
@@ -292,7 +288,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
292 | case 0x64: | 288 | case 0x64: |
293 | name = "Pixelview"; | 289 | name = "Pixelview"; |
294 | ir->get_key = get_key_pixelview; | 290 | ir->get_key = get_key_pixelview; |
295 | ir_type = IR_TYPE_OTHER; | 291 | rc_type = RC_TYPE_OTHER; |
296 | ir_codes = RC_MAP_EMPTY; | 292 | ir_codes = RC_MAP_EMPTY; |
297 | break; | 293 | break; |
298 | case 0x18: | 294 | case 0x18: |
@@ -300,7 +296,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
300 | case 0x1a: | 296 | case 0x1a: |
301 | name = "Hauppauge"; | 297 | name = "Hauppauge"; |
302 | ir->get_key = get_key_haup; | 298 | ir->get_key = get_key_haup; |
303 | ir_type = IR_TYPE_RC5; | 299 | rc_type = RC_TYPE_RC5; |
304 | if (hauppauge == 1) { | 300 | if (hauppauge == 1) { |
305 | ir_codes = RC_MAP_HAUPPAUGE_NEW; | 301 | ir_codes = RC_MAP_HAUPPAUGE_NEW; |
306 | } else { | 302 | } else { |
@@ -310,19 +306,19 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
310 | case 0x30: | 306 | case 0x30: |
311 | name = "KNC One"; | 307 | name = "KNC One"; |
312 | ir->get_key = get_key_knc1; | 308 | ir->get_key = get_key_knc1; |
313 | ir_type = IR_TYPE_OTHER; | 309 | rc_type = RC_TYPE_OTHER; |
314 | ir_codes = RC_MAP_EMPTY; | 310 | ir_codes = RC_MAP_EMPTY; |
315 | break; | 311 | break; |
316 | case 0x6b: | 312 | case 0x6b: |
317 | name = "FusionHDTV"; | 313 | name = "FusionHDTV"; |
318 | ir->get_key = get_key_fusionhdtv; | 314 | ir->get_key = get_key_fusionhdtv; |
319 | ir_type = IR_TYPE_RC5; | 315 | rc_type = RC_TYPE_RC5; |
320 | ir_codes = RC_MAP_FUSIONHDTV_MCE; | 316 | ir_codes = RC_MAP_FUSIONHDTV_MCE; |
321 | break; | 317 | break; |
322 | case 0x40: | 318 | case 0x40: |
323 | name = "AVerMedia Cardbus remote"; | 319 | name = "AVerMedia Cardbus remote"; |
324 | ir->get_key = get_key_avermedia_cardbus; | 320 | ir->get_key = get_key_avermedia_cardbus; |
325 | ir_type = IR_TYPE_OTHER; | 321 | rc_type = RC_TYPE_OTHER; |
326 | ir_codes = RC_MAP_AVERMEDIA_CARDBUS; | 322 | ir_codes = RC_MAP_AVERMEDIA_CARDBUS; |
327 | break; | 323 | break; |
328 | } | 324 | } |
@@ -333,9 +329,11 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
333 | client->dev.platform_data; | 329 | client->dev.platform_data; |
334 | 330 | ||
335 | ir_codes = init_data->ir_codes; | 331 | ir_codes = init_data->ir_codes; |
332 | rc = init_data->rc_dev; | ||
333 | |||
336 | name = init_data->name; | 334 | name = init_data->name; |
337 | if (init_data->type) | 335 | if (init_data->type) |
338 | ir_type = init_data->type; | 336 | rc_type = init_data->type; |
339 | 337 | ||
340 | if (init_data->polling_interval) | 338 | if (init_data->polling_interval) |
341 | ir->polling_interval = init_data->polling_interval; | 339 | ir->polling_interval = init_data->polling_interval; |
@@ -366,8 +364,21 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
366 | } | 364 | } |
367 | } | 365 | } |
368 | 366 | ||
367 | if (!rc) { | ||
368 | /* | ||
369 | * If platform_data doesn't specify rc_dev, initilize it | ||
370 | * internally | ||
371 | */ | ||
372 | rc = rc_allocate_device(); | ||
373 | if (!rc) { | ||
374 | err = -ENOMEM; | ||
375 | goto err_out_free; | ||
376 | } | ||
377 | } | ||
378 | ir->rc = rc; | ||
379 | |||
369 | /* Make sure we are all setup before going on */ | 380 | /* Make sure we are all setup before going on */ |
370 | if (!name || !ir->get_key || !ir_type || !ir_codes) { | 381 | if (!name || !ir->get_key || !rc_type || !ir_codes) { |
371 | dprintk(1, ": Unsupported device at address 0x%02x\n", | 382 | dprintk(1, ": Unsupported device at address 0x%02x\n", |
372 | addr); | 383 | addr); |
373 | err = -ENODEV; | 384 | err = -ENODEV; |
@@ -382,18 +393,28 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
382 | dev_name(&adap->dev), | 393 | dev_name(&adap->dev), |
383 | dev_name(&client->dev)); | 394 | dev_name(&client->dev)); |
384 | 395 | ||
385 | /* init + register input device */ | 396 | /* |
386 | ir->ir_type = ir_type; | 397 | * Initialize input_dev fields |
387 | input_dev->id.bustype = BUS_I2C; | 398 | * It doesn't make sense to allow overriding them via platform_data |
388 | input_dev->name = ir->name; | 399 | */ |
389 | input_dev->phys = ir->phys; | 400 | rc->input_id.bustype = BUS_I2C; |
401 | rc->input_phys = ir->phys; | ||
402 | rc->input_name = ir->name; | ||
403 | |||
404 | /* | ||
405 | * Initialize the other fields of rc_dev | ||
406 | */ | ||
407 | rc->map_name = ir->ir_codes; | ||
408 | rc->allowed_protos = rc_type; | ||
409 | if (!rc->driver_name) | ||
410 | rc->driver_name = MODULE_NAME; | ||
390 | 411 | ||
391 | err = ir_input_register(ir->input, ir->ir_codes, NULL, MODULE_NAME); | 412 | err = rc_register_device(rc); |
392 | if (err) | 413 | if (err) |
393 | goto err_out_free; | 414 | goto err_out_free; |
394 | 415 | ||
395 | printk(MODULE_NAME ": %s detected at %s [%s]\n", | 416 | printk(MODULE_NAME ": %s detected at %s [%s]\n", |
396 | ir->input->name, ir->input->phys, adap->name); | 417 | ir->name, ir->phys, adap->name); |
397 | 418 | ||
398 | /* start polling via eventd */ | 419 | /* start polling via eventd */ |
399 | INIT_DELAYED_WORK(&ir->work, ir_work); | 420 | INIT_DELAYED_WORK(&ir->work, ir_work); |
@@ -402,6 +423,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
402 | return 0; | 423 | return 0; |
403 | 424 | ||
404 | err_out_free: | 425 | err_out_free: |
426 | /* Only frees rc if it were allocated internally */ | ||
427 | rc_free_device(rc); | ||
405 | kfree(ir); | 428 | kfree(ir); |
406 | return err; | 429 | return err; |
407 | } | 430 | } |
@@ -414,7 +437,7 @@ static int ir_remove(struct i2c_client *client) | |||
414 | cancel_delayed_work_sync(&ir->work); | 437 | cancel_delayed_work_sync(&ir->work); |
415 | 438 | ||
416 | /* unregister device */ | 439 | /* unregister device */ |
417 | ir_input_unregister(ir->input); | 440 | rc_unregister_device(ir->rc); |
418 | 441 | ||
419 | /* free memory */ | 442 | /* free memory */ |
420 | kfree(ir); | 443 | kfree(ir); |
@@ -426,6 +449,7 @@ static const struct i2c_device_id ir_kbd_id[] = { | |||
426 | { "ir_video", 0 }, | 449 | { "ir_video", 0 }, |
427 | /* IR device specific entries should be added here */ | 450 | /* IR device specific entries should be added here */ |
428 | { "ir_rx_z8f0811_haup", 0 }, | 451 | { "ir_rx_z8f0811_haup", 0 }, |
452 | { "ir_rx_z8f0811_hdpvr", 0 }, | ||
429 | { } | 453 | { } |
430 | }; | 454 | }; |
431 | 455 | ||
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig index be4af1fa557e..89f65914cc8e 100644 --- a/drivers/media/video/ivtv/Kconfig +++ b/drivers/media/video/ivtv/Kconfig | |||
@@ -1,9 +1,8 @@ | |||
1 | config VIDEO_IVTV | 1 | config VIDEO_IVTV |
2 | tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" | 2 | tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" |
3 | depends on VIDEO_V4L2 && PCI && I2C | 3 | depends on VIDEO_V4L2 && PCI && I2C |
4 | depends on INPUT # due to VIDEO_IR | ||
5 | select I2C_ALGOBIT | 4 | select I2C_ALGOBIT |
6 | depends on VIDEO_IR | 5 | depends on RC_CORE |
7 | select VIDEO_TUNER | 6 | select VIDEO_TUNER |
8 | select VIDEO_TVEEPROM | 7 | select VIDEO_TVEEPROM |
9 | select VIDEO_CX2341X | 8 | select VIDEO_CX2341X |
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c index 87afbbee2063..145e4749a69d 100644 --- a/drivers/media/video/ivtv/ivtv-cards.c +++ b/drivers/media/video/ivtv/ivtv-cards.c | |||
@@ -405,7 +405,8 @@ static const struct ivtv_card ivtv_card_avc2410 = { | |||
405 | .hw_audio_ctrl = IVTV_HW_MSP34XX, | 405 | .hw_audio_ctrl = IVTV_HW_MSP34XX, |
406 | .hw_muxer = IVTV_HW_CS53L32A, | 406 | .hw_muxer = IVTV_HW_CS53L32A, |
407 | .hw_all = IVTV_HW_MSP34XX | IVTV_HW_CS53L32A | | 407 | .hw_all = IVTV_HW_MSP34XX | IVTV_HW_CS53L32A | |
408 | IVTV_HW_SAA7115 | IVTV_HW_TUNER, | 408 | IVTV_HW_SAA7115 | IVTV_HW_TUNER | |
409 | IVTV_HW_I2C_IR_RX_ADAPTEC, | ||
409 | .video_inputs = { | 410 | .video_inputs = { |
410 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 }, | 411 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 }, |
411 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, | 412 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, |
@@ -1313,7 +1314,6 @@ int ivtv_get_input(struct ivtv *itv, u16 index, struct v4l2_input *input) | |||
1313 | "Composite 3" | 1314 | "Composite 3" |
1314 | }; | 1315 | }; |
1315 | 1316 | ||
1316 | memset(input, 0, sizeof(*input)); | ||
1317 | if (index >= itv->nof_inputs) | 1317 | if (index >= itv->nof_inputs) |
1318 | return -EINVAL; | 1318 | return -EINVAL; |
1319 | input->index = index; | 1319 | input->index = index; |
@@ -1331,7 +1331,6 @@ int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output) | |||
1331 | { | 1331 | { |
1332 | const struct ivtv_card_output *card_output = itv->card->video_outputs + index; | 1332 | const struct ivtv_card_output *card_output = itv->card->video_outputs + index; |
1333 | 1333 | ||
1334 | memset(output, 0, sizeof(*output)); | ||
1335 | if (index >= itv->card->nof_outputs) | 1334 | if (index >= itv->card->nof_outputs) |
1336 | return -EINVAL; | 1335 | return -EINVAL; |
1337 | output->index = index; | 1336 | output->index = index; |
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h index 78eca992e1fd..e6f5c02981f1 100644 --- a/drivers/media/video/ivtv/ivtv-cards.h +++ b/drivers/media/video/ivtv/ivtv-cards.h | |||
@@ -111,6 +111,7 @@ | |||
111 | #define IVTV_HW_I2C_IR_RX_HAUP_INT (1 << 18) | 111 | #define IVTV_HW_I2C_IR_RX_HAUP_INT (1 << 18) |
112 | #define IVTV_HW_Z8F0811_IR_TX_HAUP (1 << 19) | 112 | #define IVTV_HW_Z8F0811_IR_TX_HAUP (1 << 19) |
113 | #define IVTV_HW_Z8F0811_IR_RX_HAUP (1 << 20) | 113 | #define IVTV_HW_Z8F0811_IR_RX_HAUP (1 << 20) |
114 | #define IVTV_HW_I2C_IR_RX_ADAPTEC (1 << 21) | ||
114 | 115 | ||
115 | #define IVTV_HW_Z8F0811_IR_HAUP (IVTV_HW_Z8F0811_IR_RX_HAUP | \ | 116 | #define IVTV_HW_Z8F0811_IR_HAUP (IVTV_HW_Z8F0811_IR_RX_HAUP | \ |
116 | IVTV_HW_Z8F0811_IR_TX_HAUP) | 117 | IVTV_HW_Z8F0811_IR_TX_HAUP) |
@@ -120,7 +121,8 @@ | |||
120 | #define IVTV_HW_IR_RX_ANY (IVTV_HW_I2C_IR_RX_AVER | \ | 121 | #define IVTV_HW_IR_RX_ANY (IVTV_HW_I2C_IR_RX_AVER | \ |
121 | IVTV_HW_I2C_IR_RX_HAUP_EXT | \ | 122 | IVTV_HW_I2C_IR_RX_HAUP_EXT | \ |
122 | IVTV_HW_I2C_IR_RX_HAUP_INT | \ | 123 | IVTV_HW_I2C_IR_RX_HAUP_INT | \ |
123 | IVTV_HW_Z8F0811_IR_RX_HAUP) | 124 | IVTV_HW_Z8F0811_IR_RX_HAUP | \ |
125 | IVTV_HW_I2C_IR_RX_ADAPTEC) | ||
124 | 126 | ||
125 | #define IVTV_HW_IR_TX_ANY (IVTV_HW_Z8F0811_IR_TX_HAUP) | 127 | #define IVTV_HW_IR_TX_ANY (IVTV_HW_Z8F0811_IR_TX_HAUP) |
126 | 128 | ||
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index e421d15b0f5c..39946420b301 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -1029,8 +1029,13 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, | |||
1029 | itv->enc_mem = ioremap_nocache(itv->base_addr + IVTV_ENCODER_OFFSET, | 1029 | itv->enc_mem = ioremap_nocache(itv->base_addr + IVTV_ENCODER_OFFSET, |
1030 | IVTV_ENCODER_SIZE); | 1030 | IVTV_ENCODER_SIZE); |
1031 | if (!itv->enc_mem) { | 1031 | if (!itv->enc_mem) { |
1032 | IVTV_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n"); | 1032 | IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 " |
1033 | IVTV_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n"); | 1033 | "encoder memory\n"); |
1034 | IVTV_ERR("Each capture card with a CX23415/6 needs 8 MB of " | ||
1035 | "vmalloc address space for this window\n"); | ||
1036 | IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n"); | ||
1037 | IVTV_ERR("Use the vmalloc= kernel command line option to set " | ||
1038 | "VmallocTotal to a larger value\n"); | ||
1034 | retval = -ENOMEM; | 1039 | retval = -ENOMEM; |
1035 | goto free_mem; | 1040 | goto free_mem; |
1036 | } | 1041 | } |
@@ -1041,8 +1046,14 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, | |||
1041 | itv->dec_mem = ioremap_nocache(itv->base_addr + IVTV_DECODER_OFFSET, | 1046 | itv->dec_mem = ioremap_nocache(itv->base_addr + IVTV_DECODER_OFFSET, |
1042 | IVTV_DECODER_SIZE); | 1047 | IVTV_DECODER_SIZE); |
1043 | if (!itv->dec_mem) { | 1048 | if (!itv->dec_mem) { |
1044 | IVTV_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n"); | 1049 | IVTV_ERR("ioremap failed. Can't get a window into " |
1045 | IVTV_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n"); | 1050 | "CX23415 decoder memory\n"); |
1051 | IVTV_ERR("Each capture card with a CX23415 needs 8 MB " | ||
1052 | "of vmalloc address space for this window\n"); | ||
1053 | IVTV_ERR("Check the output of 'grep Vmalloc " | ||
1054 | "/proc/meminfo'\n"); | ||
1055 | IVTV_ERR("Use the vmalloc= kernel command line option " | ||
1056 | "to set VmallocTotal to a larger value\n"); | ||
1046 | retval = -ENOMEM; | 1057 | retval = -ENOMEM; |
1047 | goto free_mem; | 1058 | goto free_mem; |
1048 | } | 1059 | } |
@@ -1057,8 +1068,13 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, | |||
1057 | itv->reg_mem = | 1068 | itv->reg_mem = |
1058 | ioremap_nocache(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); | 1069 | ioremap_nocache(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); |
1059 | if (!itv->reg_mem) { | 1070 | if (!itv->reg_mem) { |
1060 | IVTV_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n"); | 1071 | IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 " |
1061 | IVTV_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n"); | 1072 | "register space\n"); |
1073 | IVTV_ERR("Each capture card with a CX23415/6 needs 64 kB of " | ||
1074 | "vmalloc address space for this window\n"); | ||
1075 | IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n"); | ||
1076 | IVTV_ERR("Use the vmalloc= kernel command line option to set " | ||
1077 | "VmallocTotal to a larger value\n"); | ||
1062 | retval = -ENOMEM; | 1078 | retval = -ENOMEM; |
1063 | goto free_io; | 1079 | goto free_io; |
1064 | } | 1080 | } |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index d727485da886..c57a58523ca8 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -570,8 +570,8 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c | |||
570 | int elems = count / sizeof(struct v4l2_sliced_vbi_data); | 570 | int elems = count / sizeof(struct v4l2_sliced_vbi_data); |
571 | 571 | ||
572 | set_bit(IVTV_F_S_APPL_IO, &s->s_flags); | 572 | set_bit(IVTV_F_S_APPL_IO, &s->s_flags); |
573 | ivtv_write_vbi(itv, (const struct v4l2_sliced_vbi_data *)user_buf, elems); | 573 | return ivtv_write_vbi_from_user(itv, |
574 | return elems * sizeof(struct v4l2_sliced_vbi_data); | 574 | (const struct v4l2_sliced_vbi_data __user *)user_buf, elems); |
575 | } | 575 | } |
576 | 576 | ||
577 | mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV; | 577 | mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV; |
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index 665191c9b407..e103b8fc7452 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c | |||
@@ -94,6 +94,7 @@ | |||
94 | #define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18 | 94 | #define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18 |
95 | #define IVTV_Z8F0811_IR_TX_I2C_ADDR 0x70 | 95 | #define IVTV_Z8F0811_IR_TX_I2C_ADDR 0x70 |
96 | #define IVTV_Z8F0811_IR_RX_I2C_ADDR 0x71 | 96 | #define IVTV_Z8F0811_IR_RX_I2C_ADDR 0x71 |
97 | #define IVTV_ADAPTEC_IR_ADDR 0x6b | ||
97 | 98 | ||
98 | /* This array should match the IVTV_HW_ defines */ | 99 | /* This array should match the IVTV_HW_ defines */ |
99 | static const u8 hw_addrs[] = { | 100 | static const u8 hw_addrs[] = { |
@@ -118,6 +119,7 @@ static const u8 hw_addrs[] = { | |||
118 | IVTV_HAUP_INT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_INT */ | 119 | IVTV_HAUP_INT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_INT */ |
119 | IVTV_Z8F0811_IR_TX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_TX_HAUP */ | 120 | IVTV_Z8F0811_IR_TX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_TX_HAUP */ |
120 | IVTV_Z8F0811_IR_RX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_RX_HAUP */ | 121 | IVTV_Z8F0811_IR_RX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_RX_HAUP */ |
122 | IVTV_ADAPTEC_IR_ADDR, /* IVTV_HW_I2C_IR_RX_ADAPTEC */ | ||
121 | }; | 123 | }; |
122 | 124 | ||
123 | /* This array should match the IVTV_HW_ defines */ | 125 | /* This array should match the IVTV_HW_ defines */ |
@@ -143,8 +145,34 @@ static const char * const hw_devicenames[] = { | |||
143 | "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_INT */ | 145 | "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_INT */ |
144 | "ir_tx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_TX_HAUP */ | 146 | "ir_tx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_TX_HAUP */ |
145 | "ir_rx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_RX_HAUP */ | 147 | "ir_rx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_RX_HAUP */ |
148 | "ir_video", /* IVTV_HW_I2C_IR_RX_ADAPTEC */ | ||
146 | }; | 149 | }; |
147 | 150 | ||
151 | static int get_key_adaptec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
152 | { | ||
153 | unsigned char keybuf[4]; | ||
154 | |||
155 | keybuf[0] = 0x00; | ||
156 | i2c_master_send(ir->c, keybuf, 1); | ||
157 | /* poll IR chip */ | ||
158 | if (i2c_master_recv(ir->c, keybuf, sizeof(keybuf)) != sizeof(keybuf)) { | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | /* key pressed ? */ | ||
163 | if (keybuf[2] == 0xff) | ||
164 | return 0; | ||
165 | |||
166 | /* remove repeat bit */ | ||
167 | keybuf[2] &= 0x7f; | ||
168 | keybuf[3] |= 0x80; | ||
169 | |||
170 | *ir_key = keybuf[3] | keybuf[2] << 8 | keybuf[1] << 16 |keybuf[0] << 24; | ||
171 | *ir_raw = *ir_key; | ||
172 | |||
173 | return 1; | ||
174 | } | ||
175 | |||
148 | static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) | 176 | static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) |
149 | { | 177 | { |
150 | struct i2c_board_info info; | 178 | struct i2c_board_info info; |
@@ -172,7 +200,7 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) | |||
172 | init_data->ir_codes = RC_MAP_AVERMEDIA_CARDBUS; | 200 | init_data->ir_codes = RC_MAP_AVERMEDIA_CARDBUS; |
173 | init_data->internal_get_key_func = | 201 | init_data->internal_get_key_func = |
174 | IR_KBD_GET_KEY_AVERMEDIA_CARDBUS; | 202 | IR_KBD_GET_KEY_AVERMEDIA_CARDBUS; |
175 | init_data->type = IR_TYPE_OTHER; | 203 | init_data->type = RC_TYPE_OTHER; |
176 | init_data->name = "AVerMedia AVerTV card"; | 204 | init_data->name = "AVerMedia AVerTV card"; |
177 | break; | 205 | break; |
178 | case IVTV_HW_I2C_IR_RX_HAUP_EXT: | 206 | case IVTV_HW_I2C_IR_RX_HAUP_EXT: |
@@ -180,15 +208,22 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) | |||
180 | /* Default to old black remote */ | 208 | /* Default to old black remote */ |
181 | init_data->ir_codes = RC_MAP_RC5_TV; | 209 | init_data->ir_codes = RC_MAP_RC5_TV; |
182 | init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; | 210 | init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; |
183 | init_data->type = IR_TYPE_RC5; | 211 | init_data->type = RC_TYPE_RC5; |
184 | init_data->name = itv->card_name; | 212 | init_data->name = itv->card_name; |
185 | break; | 213 | break; |
186 | case IVTV_HW_Z8F0811_IR_RX_HAUP: | 214 | case IVTV_HW_Z8F0811_IR_RX_HAUP: |
187 | /* Default to grey remote */ | 215 | /* Default to grey remote */ |
188 | init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; | 216 | init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; |
189 | init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; | 217 | init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; |
190 | init_data->type = IR_TYPE_RC5; | 218 | init_data->type = RC_TYPE_RC5; |
219 | init_data->name = itv->card_name; | ||
220 | break; | ||
221 | case IVTV_HW_I2C_IR_RX_ADAPTEC: | ||
222 | init_data->get_key = get_key_adaptec; | ||
191 | init_data->name = itv->card_name; | 223 | init_data->name = itv->card_name; |
224 | /* FIXME: The protocol and RC_MAP needs to be corrected */ | ||
225 | init_data->ir_codes = RC_MAP_EMPTY; | ||
226 | init_data->type = RC_TYPE_UNKNOWN; | ||
192 | break; | 227 | break; |
193 | } | 228 | } |
194 | 229 | ||
@@ -218,8 +253,6 @@ struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv) | |||
218 | const unsigned short addr_list[] = { | 253 | const unsigned short addr_list[] = { |
219 | 0x1a, /* Hauppauge IR external - collides with WM8739 */ | 254 | 0x1a, /* Hauppauge IR external - collides with WM8739 */ |
220 | 0x18, /* Hauppauge IR internal */ | 255 | 0x18, /* Hauppauge IR internal */ |
221 | 0x71, /* Hauppauge IR (PVR150) */ | ||
222 | 0x6b, /* Adaptec IR */ | ||
223 | I2C_CLIENT_END | 256 | I2C_CLIENT_END |
224 | }; | 257 | }; |
225 | 258 | ||
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c index e1c347e5ebd8..2dfa957b0fd5 100644 --- a/drivers/media/video/ivtv/ivtv-vbi.c +++ b/drivers/media/video/ivtv/ivtv-vbi.c | |||
@@ -92,54 +92,97 @@ static int odd_parity(u8 c) | |||
92 | return c & 1; | 92 | return c & 1; |
93 | } | 93 | } |
94 | 94 | ||
95 | void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t cnt) | 95 | static void ivtv_write_vbi_line(struct ivtv *itv, |
96 | const struct v4l2_sliced_vbi_data *d, | ||
97 | struct vbi_cc *cc, int *found_cc) | ||
96 | { | 98 | { |
97 | struct vbi_info *vi = &itv->vbi; | 99 | struct vbi_info *vi = &itv->vbi; |
98 | struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } }; | ||
99 | int found_cc = 0; | ||
100 | size_t i; | ||
101 | |||
102 | for (i = 0; i < cnt; i++) { | ||
103 | const struct v4l2_sliced_vbi_data *d = sliced + i; | ||
104 | 100 | ||
105 | if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) { | 101 | if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) { |
106 | if (d->field) { | 102 | if (d->field) { |
107 | cc.even[0] = d->data[0]; | 103 | cc->even[0] = d->data[0]; |
108 | cc.even[1] = d->data[1]; | 104 | cc->even[1] = d->data[1]; |
109 | } else { | 105 | } else { |
110 | cc.odd[0] = d->data[0]; | 106 | cc->odd[0] = d->data[0]; |
111 | cc.odd[1] = d->data[1]; | 107 | cc->odd[1] = d->data[1]; |
112 | } | ||
113 | found_cc = 1; | ||
114 | } | 108 | } |
115 | else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) { | 109 | *found_cc = 1; |
116 | struct vbi_vps vps; | 110 | } else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) { |
117 | 111 | struct vbi_vps vps; | |
118 | vps.data[0] = d->data[2]; | 112 | |
119 | vps.data[1] = d->data[8]; | 113 | vps.data[0] = d->data[2]; |
120 | vps.data[2] = d->data[9]; | 114 | vps.data[1] = d->data[8]; |
121 | vps.data[3] = d->data[10]; | 115 | vps.data[2] = d->data[9]; |
122 | vps.data[4] = d->data[11]; | 116 | vps.data[3] = d->data[10]; |
123 | if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) { | 117 | vps.data[4] = d->data[11]; |
124 | vi->vps_payload = vps; | 118 | if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) { |
125 | set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags); | 119 | vi->vps_payload = vps; |
126 | } | 120 | set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags); |
127 | } | 121 | } |
128 | else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) { | 122 | } else if (d->id == V4L2_SLICED_WSS_625 && |
129 | int wss = d->data[0] | d->data[1] << 8; | 123 | d->line == 23 && d->field == 0) { |
124 | int wss = d->data[0] | d->data[1] << 8; | ||
130 | 125 | ||
131 | if (vi->wss_payload != wss) { | 126 | if (vi->wss_payload != wss) { |
132 | vi->wss_payload = wss; | 127 | vi->wss_payload = wss; |
133 | set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags); | 128 | set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags); |
134 | } | ||
135 | } | 129 | } |
136 | } | 130 | } |
137 | if (found_cc && vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) { | 131 | } |
138 | vi->cc_payload[vi->cc_payload_idx++] = cc; | 132 | |
133 | static void ivtv_write_vbi_cc_lines(struct ivtv *itv, const struct vbi_cc *cc) | ||
134 | { | ||
135 | struct vbi_info *vi = &itv->vbi; | ||
136 | |||
137 | if (vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) { | ||
138 | memcpy(&vi->cc_payload[vi->cc_payload_idx], cc, | ||
139 | sizeof(struct vbi_cc)); | ||
140 | vi->cc_payload_idx++; | ||
139 | set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags); | 141 | set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags); |
140 | } | 142 | } |
141 | } | 143 | } |
142 | 144 | ||
145 | static void ivtv_write_vbi(struct ivtv *itv, | ||
146 | const struct v4l2_sliced_vbi_data *sliced, | ||
147 | size_t cnt) | ||
148 | { | ||
149 | struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } }; | ||
150 | int found_cc = 0; | ||
151 | size_t i; | ||
152 | |||
153 | for (i = 0; i < cnt; i++) | ||
154 | ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc); | ||
155 | |||
156 | if (found_cc) | ||
157 | ivtv_write_vbi_cc_lines(itv, &cc); | ||
158 | } | ||
159 | |||
160 | ssize_t | ||
161 | ivtv_write_vbi_from_user(struct ivtv *itv, | ||
162 | const struct v4l2_sliced_vbi_data __user *sliced, | ||
163 | size_t cnt) | ||
164 | { | ||
165 | struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } }; | ||
166 | int found_cc = 0; | ||
167 | size_t i; | ||
168 | struct v4l2_sliced_vbi_data d; | ||
169 | ssize_t ret = cnt * sizeof(struct v4l2_sliced_vbi_data); | ||
170 | |||
171 | for (i = 0; i < cnt; i++) { | ||
172 | if (copy_from_user(&d, sliced + i, | ||
173 | sizeof(struct v4l2_sliced_vbi_data))) { | ||
174 | ret = -EFAULT; | ||
175 | break; | ||
176 | } | ||
177 | ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc); | ||
178 | } | ||
179 | |||
180 | if (found_cc) | ||
181 | ivtv_write_vbi_cc_lines(itv, &cc); | ||
182 | |||
183 | return ret; | ||
184 | } | ||
185 | |||
143 | static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp) | 186 | static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp) |
144 | { | 187 | { |
145 | int line = 0; | 188 | int line = 0; |
diff --git a/drivers/media/video/ivtv/ivtv-vbi.h b/drivers/media/video/ivtv/ivtv-vbi.h index 970567b9194d..166dd0b75d0f 100644 --- a/drivers/media/video/ivtv/ivtv-vbi.h +++ b/drivers/media/video/ivtv/ivtv-vbi.h | |||
@@ -20,7 +20,10 @@ | |||
20 | #ifndef IVTV_VBI_H | 20 | #ifndef IVTV_VBI_H |
21 | #define IVTV_VBI_H | 21 | #define IVTV_VBI_H |
22 | 22 | ||
23 | void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t count); | 23 | ssize_t |
24 | ivtv_write_vbi_from_user(struct ivtv *itv, | ||
25 | const struct v4l2_sliced_vbi_data __user *sliced, | ||
26 | size_t count); | ||
24 | void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf, | 27 | void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf, |
25 | u64 pts_stamp, int streamtype); | 28 | u64 pts_stamp, int streamtype); |
26 | int ivtv_used_line(struct ivtv *itv, int line, int field); | 29 | int ivtv_used_line(struct ivtv *itv, int line, int field); |
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index 3b19f5b25a72..c179041d91f8 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c | |||
@@ -524,7 +524,6 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) | |||
524 | { | 524 | { |
525 | struct m2mtest_q_data *q_data; | 525 | struct m2mtest_q_data *q_data; |
526 | struct videobuf_queue *vq; | 526 | struct videobuf_queue *vq; |
527 | int ret = 0; | ||
528 | 527 | ||
529 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); | 528 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); |
530 | if (!vq) | 529 | if (!vq) |
@@ -534,12 +533,9 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) | |||
534 | if (!q_data) | 533 | if (!q_data) |
535 | return -EINVAL; | 534 | return -EINVAL; |
536 | 535 | ||
537 | mutex_lock(&vq->vb_lock); | ||
538 | |||
539 | if (videobuf_queue_is_busy(vq)) { | 536 | if (videobuf_queue_is_busy(vq)) { |
540 | v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__); | 537 | v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__); |
541 | ret = -EBUSY; | 538 | return -EBUSY; |
542 | goto out; | ||
543 | } | 539 | } |
544 | 540 | ||
545 | q_data->fmt = find_format(f); | 541 | q_data->fmt = find_format(f); |
@@ -553,9 +549,7 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) | |||
553 | "Setting format for type %d, wxh: %dx%d, fmt: %d\n", | 549 | "Setting format for type %d, wxh: %dx%d, fmt: %d\n", |
554 | f->type, q_data->width, q_data->height, q_data->fmt->fourcc); | 550 | f->type, q_data->width, q_data->height, q_data->fmt->fourcc); |
555 | 551 | ||
556 | out: | 552 | return 0; |
557 | mutex_unlock(&vq->vb_lock); | ||
558 | return ret; | ||
559 | } | 553 | } |
560 | 554 | ||
561 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | 555 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, |
@@ -845,10 +839,12 @@ static void queue_init(void *priv, struct videobuf_queue *vq, | |||
845 | enum v4l2_buf_type type) | 839 | enum v4l2_buf_type type) |
846 | { | 840 | { |
847 | struct m2mtest_ctx *ctx = priv; | 841 | struct m2mtest_ctx *ctx = priv; |
842 | struct m2mtest_dev *dev = ctx->dev; | ||
848 | 843 | ||
849 | videobuf_queue_vmalloc_init(vq, &m2mtest_qops, ctx->dev->v4l2_dev.dev, | 844 | videobuf_queue_vmalloc_init(vq, &m2mtest_qops, dev->v4l2_dev.dev, |
850 | &ctx->dev->irqlock, type, V4L2_FIELD_NONE, | 845 | &dev->irqlock, type, V4L2_FIELD_NONE, |
851 | sizeof(struct m2mtest_buffer), priv, NULL); | 846 | sizeof(struct m2mtest_buffer), priv, |
847 | &dev->dev_mutex); | ||
852 | } | 848 | } |
853 | 849 | ||
854 | 850 | ||
@@ -920,7 +916,7 @@ static const struct v4l2_file_operations m2mtest_fops = { | |||
920 | .open = m2mtest_open, | 916 | .open = m2mtest_open, |
921 | .release = m2mtest_release, | 917 | .release = m2mtest_release, |
922 | .poll = m2mtest_poll, | 918 | .poll = m2mtest_poll, |
923 | .ioctl = video_ioctl2, | 919 | .unlocked_ioctl = video_ioctl2, |
924 | .mmap = m2mtest_mmap, | 920 | .mmap = m2mtest_mmap, |
925 | }; | 921 | }; |
926 | 922 | ||
@@ -965,6 +961,7 @@ static int m2mtest_probe(struct platform_device *pdev) | |||
965 | } | 961 | } |
966 | 962 | ||
967 | *vfd = m2mtest_videodev; | 963 | *vfd = m2mtest_videodev; |
964 | vfd->lock = &dev->dev_mutex; | ||
968 | 965 | ||
969 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | 966 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); |
970 | if (ret) { | 967 | if (ret) { |
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index fcb4cd941853..f7fc88d240e6 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c | |||
@@ -798,7 +798,6 @@ static int mt9m001_remove(struct i2c_client *client) | |||
798 | 798 | ||
799 | icd->ops = NULL; | 799 | icd->ops = NULL; |
800 | mt9m001_video_remove(icd); | 800 | mt9m001_video_remove(icd); |
801 | client->driver = NULL; | ||
802 | kfree(mt9m001); | 801 | kfree(mt9m001); |
803 | 802 | ||
804 | return 0; | 803 | return 0; |
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 525a16e73285..53fa2a7bf156 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c | |||
@@ -1092,7 +1092,6 @@ static int mt9m111_remove(struct i2c_client *client) | |||
1092 | struct soc_camera_device *icd = client->dev.platform_data; | 1092 | struct soc_camera_device *icd = client->dev.platform_data; |
1093 | 1093 | ||
1094 | icd->ops = NULL; | 1094 | icd->ops = NULL; |
1095 | client->driver = NULL; | ||
1096 | kfree(mt9m111); | 1095 | kfree(mt9m111); |
1097 | 1096 | ||
1098 | return 0; | 1097 | return 0; |
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 9bd44a816ea1..7ce279c3751d 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c | |||
@@ -896,7 +896,6 @@ static int mt9t031_remove(struct i2c_client *client) | |||
896 | 896 | ||
897 | if (icd) | 897 | if (icd) |
898 | icd->ops = NULL; | 898 | icd->ops = NULL; |
899 | client->driver = NULL; | ||
900 | kfree(mt9t031); | 899 | kfree(mt9t031); |
901 | 900 | ||
902 | return 0; | 901 | return 0; |
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index b96171cc79f9..6a784c87e5ff 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c | |||
@@ -930,7 +930,6 @@ static int mt9v022_remove(struct i2c_client *client) | |||
930 | 930 | ||
931 | icd->ops = NULL; | 931 | icd->ops = NULL; |
932 | mt9v022_video_remove(icd); | 932 | mt9v022_video_remove(icd); |
933 | client->driver = NULL; | ||
934 | kfree(mt9v022); | 933 | kfree(mt9v022); |
935 | 934 | ||
936 | return 0; | 935 | return 0; |
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 5e486a88ad7c..bc0c23a1009c 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -382,10 +382,9 @@ static void mx1_camera_init_videobuf(struct videobuf_queue *q, | |||
382 | struct mx1_camera_dev *pcdev = ici->priv; | 382 | struct mx1_camera_dev *pcdev = ici->priv; |
383 | 383 | ||
384 | videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, icd->dev.parent, | 384 | videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, icd->dev.parent, |
385 | &pcdev->lock, | 385 | &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, |
386 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 386 | V4L2_FIELD_NONE, |
387 | V4L2_FIELD_NONE, | 387 | sizeof(struct mx1_buffer), icd, &icd->video_lock); |
388 | sizeof(struct mx1_buffer), icd, NULL); | ||
389 | } | 388 | } |
390 | 389 | ||
391 | static int mclk_get_divisor(struct mx1_camera_dev *pcdev) | 390 | static int mclk_get_divisor(struct mx1_camera_dev *pcdev) |
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 13565cba237d..4eab1c620318 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c | |||
@@ -683,7 +683,8 @@ static void mx2_camera_init_videobuf(struct videobuf_queue *q, | |||
683 | 683 | ||
684 | videobuf_queue_dma_contig_init(q, &mx2_videobuf_ops, pcdev->dev, | 684 | videobuf_queue_dma_contig_init(q, &mx2_videobuf_ops, pcdev->dev, |
685 | &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, | 685 | &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, |
686 | V4L2_FIELD_NONE, sizeof(struct mx2_buffer), icd, NULL); | 686 | V4L2_FIELD_NONE, sizeof(struct mx2_buffer), |
687 | icd, &icd->video_lock); | ||
687 | } | 688 | } |
688 | 689 | ||
689 | #define MX2_BUS_FLAGS (SOCAM_DATAWIDTH_8 | \ | 690 | #define MX2_BUS_FLAGS (SOCAM_DATAWIDTH_8 | \ |
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index aa871c2936b3..b9cb4a436959 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c | |||
@@ -443,7 +443,7 @@ static void mx3_camera_init_videobuf(struct videobuf_queue *q, | |||
443 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 443 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
444 | V4L2_FIELD_NONE, | 444 | V4L2_FIELD_NONE, |
445 | sizeof(struct mx3_camera_buffer), icd, | 445 | sizeof(struct mx3_camera_buffer), icd, |
446 | NULL); | 446 | &icd->video_lock); |
447 | } | 447 | } |
448 | 448 | ||
449 | /* First part of ipu_csi_init_interface() */ | 449 | /* First part of ipu_csi_init_interface() */ |
@@ -1186,13 +1186,12 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev) | |||
1186 | goto egetres; | 1186 | goto egetres; |
1187 | } | 1187 | } |
1188 | 1188 | ||
1189 | mx3_cam = vmalloc(sizeof(*mx3_cam)); | 1189 | mx3_cam = vzalloc(sizeof(*mx3_cam)); |
1190 | if (!mx3_cam) { | 1190 | if (!mx3_cam) { |
1191 | dev_err(&pdev->dev, "Could not allocate mx3 camera object\n"); | 1191 | dev_err(&pdev->dev, "Could not allocate mx3 camera object\n"); |
1192 | err = -ENOMEM; | 1192 | err = -ENOMEM; |
1193 | goto ealloc; | 1193 | goto ealloc; |
1194 | } | 1194 | } |
1195 | memset(mx3_cam, 0, sizeof(*mx3_cam)); | ||
1196 | 1195 | ||
1197 | mx3_cam->clk = clk_get(&pdev->dev, NULL); | 1196 | mx3_cam->clk = clk_get(&pdev->dev, NULL); |
1198 | if (IS_ERR(mx3_cam->clk)) { | 1197 | if (IS_ERR(mx3_cam->clk)) { |
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index 4e8fd965f151..e8846a09b026 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c | |||
@@ -59,10 +59,10 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | |||
59 | enum { TUNER, AUX1, AUX3, AUX3_YC }; | 59 | enum { TUNER, AUX1, AUX3, AUX3_YC }; |
60 | 60 | ||
61 | static struct v4l2_input mxb_inputs[MXB_INPUTS] = { | 61 | static struct v4l2_input mxb_inputs[MXB_INPUTS] = { |
62 | { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 62 | { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
63 | { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 63 | { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
64 | { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 64 | { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
65 | { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, | 65 | { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | /* this array holds the information, which port of the saa7146 each | 68 | /* this array holds the information, which port of the saa7146 each |
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 15f8793e325b..83de97ad971e 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c | |||
@@ -2230,7 +2230,6 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout) | |||
2230 | 2230 | ||
2231 | strlcpy(vfd->name, VOUT_NAME, sizeof(vfd->name)); | 2231 | strlcpy(vfd->name, VOUT_NAME, sizeof(vfd->name)); |
2232 | 2232 | ||
2233 | /* need to register for a VID_HARDWARE_* ID in videodev.h */ | ||
2234 | vfd->fops = &omap_vout_fops; | 2233 | vfd->fops = &omap_vout_fops; |
2235 | vfd->v4l2_dev = &vout->vid_dev->v4l2_dev; | 2234 | vfd->v4l2_dev = &vout->vid_dev->v4l2_dev; |
2236 | mutex_init(&vout->lock); | 2235 | mutex_init(&vout->lock); |
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c index cbfd07f2d9da..0a2fb2bfdbfb 100644 --- a/drivers/media/video/omap1_camera.c +++ b/drivers/media/video/omap1_camera.c | |||
@@ -1365,12 +1365,12 @@ static void omap1_cam_init_videobuf(struct videobuf_queue *q, | |||
1365 | videobuf_queue_dma_contig_init(q, &omap1_videobuf_ops, | 1365 | videobuf_queue_dma_contig_init(q, &omap1_videobuf_ops, |
1366 | icd->dev.parent, &pcdev->lock, | 1366 | icd->dev.parent, &pcdev->lock, |
1367 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | 1367 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, |
1368 | sizeof(struct omap1_cam_buf), icd, NULL); | 1368 | sizeof(struct omap1_cam_buf), icd, &icd->video_lock); |
1369 | else | 1369 | else |
1370 | videobuf_queue_sg_init(q, &omap1_videobuf_ops, | 1370 | videobuf_queue_sg_init(q, &omap1_videobuf_ops, |
1371 | icd->dev.parent, &pcdev->lock, | 1371 | icd->dev.parent, &pcdev->lock, |
1372 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | 1372 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, |
1373 | sizeof(struct omap1_cam_buf), icd, NULL); | 1373 | sizeof(struct omap1_cam_buf), icd, &icd->video_lock); |
1374 | 1374 | ||
1375 | /* use videobuf mode (auto)selected with the module parameter */ | 1375 | /* use videobuf mode (auto)selected with the module parameter */ |
1376 | pcdev->vb_mode = sg_mode ? OMAP1_CAM_DMA_SG : OMAP1_CAM_DMA_CONTIG; | 1376 | pcdev->vb_mode = sg_mode ? OMAP1_CAM_DMA_SG : OMAP1_CAM_DMA_CONTIG; |
diff --git a/drivers/media/video/ov2640.c b/drivers/media/video/ov2640.c new file mode 100644 index 000000000000..0cea0cf36679 --- /dev/null +++ b/drivers/media/video/ov2640.c | |||
@@ -0,0 +1,1205 @@ | |||
1 | /* | ||
2 | * ov2640 Camera Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Alberto Panizzo <maramaopercheseimorto@gmail.com> | ||
5 | * | ||
6 | * Based on ov772x, ov9640 drivers and previous non merged implementations. | ||
7 | * | ||
8 | * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. | ||
9 | * Copyright (C) 2006, OmniVision | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/init.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/videodev2.h> | ||
22 | #include <media/v4l2-chip-ident.h> | ||
23 | #include <media/v4l2-subdev.h> | ||
24 | #include <media/soc_camera.h> | ||
25 | #include <media/soc_mediabus.h> | ||
26 | |||
27 | #define VAL_SET(x, mask, rshift, lshift) \ | ||
28 | ((((x) >> rshift) & mask) << lshift) | ||
29 | /* | ||
30 | * DSP registers | ||
31 | * register offset for BANK_SEL == BANK_SEL_DSP | ||
32 | */ | ||
33 | #define R_BYPASS 0x05 /* Bypass DSP */ | ||
34 | #define R_BYPASS_DSP_BYPAS 0x01 /* Bypass DSP, sensor out directly */ | ||
35 | #define R_BYPASS_USE_DSP 0x00 /* Use the internal DSP */ | ||
36 | #define QS 0x44 /* Quantization Scale Factor */ | ||
37 | #define CTRLI 0x50 | ||
38 | #define CTRLI_LP_DP 0x80 | ||
39 | #define CTRLI_ROUND 0x40 | ||
40 | #define CTRLI_V_DIV_SET(x) VAL_SET(x, 0x3, 0, 3) | ||
41 | #define CTRLI_H_DIV_SET(x) VAL_SET(x, 0x3, 0, 0) | ||
42 | #define HSIZE 0x51 /* H_SIZE[7:0] (real/4) */ | ||
43 | #define HSIZE_SET(x) VAL_SET(x, 0xFF, 2, 0) | ||
44 | #define VSIZE 0x52 /* V_SIZE[7:0] (real/4) */ | ||
45 | #define VSIZE_SET(x) VAL_SET(x, 0xFF, 2, 0) | ||
46 | #define XOFFL 0x53 /* OFFSET_X[7:0] */ | ||
47 | #define XOFFL_SET(x) VAL_SET(x, 0xFF, 0, 0) | ||
48 | #define YOFFL 0x54 /* OFFSET_Y[7:0] */ | ||
49 | #define YOFFL_SET(x) VAL_SET(x, 0xFF, 0, 0) | ||
50 | #define VHYX 0x55 /* Offset and size completion */ | ||
51 | #define VHYX_VSIZE_SET(x) VAL_SET(x, 0x1, (8+2), 7) | ||
52 | #define VHYX_HSIZE_SET(x) VAL_SET(x, 0x1, (8+2), 3) | ||
53 | #define VHYX_YOFF_SET(x) VAL_SET(x, 0x3, 8, 4) | ||
54 | #define VHYX_XOFF_SET(x) VAL_SET(x, 0x3, 8, 0) | ||
55 | #define DPRP 0x56 | ||
56 | #define TEST 0x57 /* Horizontal size completion */ | ||
57 | #define TEST_HSIZE_SET(x) VAL_SET(x, 0x1, (9+2), 7) | ||
58 | #define ZMOW 0x5A /* Zoom: Out Width OUTW[7:0] (real/4) */ | ||
59 | #define ZMOW_OUTW_SET(x) VAL_SET(x, 0xFF, 2, 0) | ||
60 | #define ZMOH 0x5B /* Zoom: Out Height OUTH[7:0] (real/4) */ | ||
61 | #define ZMOH_OUTH_SET(x) VAL_SET(x, 0xFF, 2, 0) | ||
62 | #define ZMHH 0x5C /* Zoom: Speed and H&W completion */ | ||
63 | #define ZMHH_ZSPEED_SET(x) VAL_SET(x, 0x0F, 0, 4) | ||
64 | #define ZMHH_OUTH_SET(x) VAL_SET(x, 0x1, (8+2), 2) | ||
65 | #define ZMHH_OUTW_SET(x) VAL_SET(x, 0x3, (8+2), 0) | ||
66 | #define BPADDR 0x7C /* SDE Indirect Register Access: Address */ | ||
67 | #define BPDATA 0x7D /* SDE Indirect Register Access: Data */ | ||
68 | #define CTRL2 0x86 /* DSP Module enable 2 */ | ||
69 | #define CTRL2_DCW_EN 0x20 | ||
70 | #define CTRL2_SDE_EN 0x10 | ||
71 | #define CTRL2_UV_ADJ_EN 0x08 | ||
72 | #define CTRL2_UV_AVG_EN 0x04 | ||
73 | #define CTRL2_CMX_EN 0x01 | ||
74 | #define CTRL3 0x87 /* DSP Module enable 3 */ | ||
75 | #define CTRL3_BPC_EN 0x80 | ||
76 | #define CTRL3_WPC_EN 0x40 | ||
77 | #define SIZEL 0x8C /* Image Size Completion */ | ||
78 | #define SIZEL_HSIZE8_11_SET(x) VAL_SET(x, 0x1, 11, 6) | ||
79 | #define SIZEL_HSIZE8_SET(x) VAL_SET(x, 0x7, 0, 3) | ||
80 | #define SIZEL_VSIZE8_SET(x) VAL_SET(x, 0x7, 0, 0) | ||
81 | #define HSIZE8 0xC0 /* Image Horizontal Size HSIZE[10:3] */ | ||
82 | #define HSIZE8_SET(x) VAL_SET(x, 0xFF, 3, 0) | ||
83 | #define VSIZE8 0xC1 /* Image Vertical Size VSIZE[10:3] */ | ||
84 | #define VSIZE8_SET(x) VAL_SET(x, 0xFF, 3, 0) | ||
85 | #define CTRL0 0xC2 /* DSP Module enable 0 */ | ||
86 | #define CTRL0_AEC_EN 0x80 | ||
87 | #define CTRL0_AEC_SEL 0x40 | ||
88 | #define CTRL0_STAT_SEL 0x20 | ||
89 | #define CTRL0_VFIRST 0x10 | ||
90 | #define CTRL0_YUV422 0x08 | ||
91 | #define CTRL0_YUV_EN 0x04 | ||
92 | #define CTRL0_RGB_EN 0x02 | ||
93 | #define CTRL0_RAW_EN 0x01 | ||
94 | #define CTRL1 0xC3 /* DSP Module enable 1 */ | ||
95 | #define CTRL1_CIP 0x80 | ||
96 | #define CTRL1_DMY 0x40 | ||
97 | #define CTRL1_RAW_GMA 0x20 | ||
98 | #define CTRL1_DG 0x10 | ||
99 | #define CTRL1_AWB 0x08 | ||
100 | #define CTRL1_AWB_GAIN 0x04 | ||
101 | #define CTRL1_LENC 0x02 | ||
102 | #define CTRL1_PRE 0x01 | ||
103 | #define R_DVP_SP 0xD3 /* DVP output speed control */ | ||
104 | #define R_DVP_SP_AUTO_MODE 0x80 | ||
105 | #define R_DVP_SP_DVP_MASK 0x3F /* DVP PCLK = sysclk (48)/[6:0] (YUV0); | ||
106 | * = sysclk (48)/(2*[6:0]) (RAW);*/ | ||
107 | #define IMAGE_MODE 0xDA /* Image Output Format Select */ | ||
108 | #define IMAGE_MODE_Y8_DVP_EN 0x40 | ||
109 | #define IMAGE_MODE_JPEG_EN 0x10 | ||
110 | #define IMAGE_MODE_YUV422 0x00 | ||
111 | #define IMAGE_MODE_RAW10 0x04 /* (DVP) */ | ||
112 | #define IMAGE_MODE_RGB565 0x08 | ||
113 | #define IMAGE_MODE_HREF_VSYNC 0x02 /* HREF timing select in DVP JPEG output | ||
114 | * mode (0 for HREF is same as sensor) */ | ||
115 | #define IMAGE_MODE_LBYTE_FIRST 0x01 /* Byte swap enable for DVP | ||
116 | * 1: Low byte first UYVY (C2[4] =0) | ||
117 | * VYUY (C2[4] =1) | ||
118 | * 0: High byte first YUYV (C2[4]=0) | ||
119 | * YVYU (C2[4] = 1) */ | ||
120 | #define RESET 0xE0 /* Reset */ | ||
121 | #define RESET_MICROC 0x40 | ||
122 | #define RESET_SCCB 0x20 | ||
123 | #define RESET_JPEG 0x10 | ||
124 | #define RESET_DVP 0x04 | ||
125 | #define RESET_IPU 0x02 | ||
126 | #define RESET_CIF 0x01 | ||
127 | #define REGED 0xED /* Register ED */ | ||
128 | #define REGED_CLK_OUT_DIS 0x10 | ||
129 | #define MS_SP 0xF0 /* SCCB Master Speed */ | ||
130 | #define SS_ID 0xF7 /* SCCB Slave ID */ | ||
131 | #define SS_CTRL 0xF8 /* SCCB Slave Control */ | ||
132 | #define SS_CTRL_ADD_AUTO_INC 0x20 | ||
133 | #define SS_CTRL_EN 0x08 | ||
134 | #define SS_CTRL_DELAY_CLK 0x04 | ||
135 | #define SS_CTRL_ACC_EN 0x02 | ||
136 | #define SS_CTRL_SEN_PASS_THR 0x01 | ||
137 | #define MC_BIST 0xF9 /* Microcontroller misc register */ | ||
138 | #define MC_BIST_RESET 0x80 /* Microcontroller Reset */ | ||
139 | #define MC_BIST_BOOT_ROM_SEL 0x40 | ||
140 | #define MC_BIST_12KB_SEL 0x20 | ||
141 | #define MC_BIST_12KB_MASK 0x30 | ||
142 | #define MC_BIST_512KB_SEL 0x08 | ||
143 | #define MC_BIST_512KB_MASK 0x0C | ||
144 | #define MC_BIST_BUSY_BIT_R 0x02 | ||
145 | #define MC_BIST_MC_RES_ONE_SH_W 0x02 | ||
146 | #define MC_BIST_LAUNCH 0x01 | ||
147 | #define BANK_SEL 0xFF /* Register Bank Select */ | ||
148 | #define BANK_SEL_DSP 0x00 | ||
149 | #define BANK_SEL_SENS 0x01 | ||
150 | |||
151 | /* | ||
152 | * Sensor registers | ||
153 | * register offset for BANK_SEL == BANK_SEL_SENS | ||
154 | */ | ||
155 | #define GAIN 0x00 /* AGC - Gain control gain setting */ | ||
156 | #define COM1 0x03 /* Common control 1 */ | ||
157 | #define COM1_1_DUMMY_FR 0x40 | ||
158 | #define COM1_3_DUMMY_FR 0x80 | ||
159 | #define COM1_7_DUMMY_FR 0xC0 | ||
160 | #define COM1_VWIN_LSB_UXGA 0x0F | ||
161 | #define COM1_VWIN_LSB_SVGA 0x0A | ||
162 | #define COM1_VWIN_LSB_CIF 0x06 | ||
163 | #define REG04 0x04 /* Register 04 */ | ||
164 | #define REG04_DEF 0x20 /* Always set */ | ||
165 | #define REG04_HFLIP_IMG 0x80 /* Horizontal mirror image ON/OFF */ | ||
166 | #define REG04_VFLIP_IMG 0x40 /* Vertical flip image ON/OFF */ | ||
167 | #define REG04_VREF_EN 0x10 | ||
168 | #define REG04_HREF_EN 0x08 | ||
169 | #define REG04_AEC_SET(x) VAL_SET(x, 0x3, 0, 0) | ||
170 | #define REG08 0x08 /* Frame Exposure One-pin Control Pre-charge Row Num */ | ||
171 | #define COM2 0x09 /* Common control 2 */ | ||
172 | #define COM2_SOFT_SLEEP_MODE 0x10 /* Soft sleep mode */ | ||
173 | /* Output drive capability */ | ||
174 | #define COM2_OCAP_Nx_SET(N) (((N) - 1) & 0x03) /* N = [1x .. 4x] */ | ||
175 | #define PID 0x0A /* Product ID Number MSB */ | ||
176 | #define VER 0x0B /* Product ID Number LSB */ | ||
177 | #define COM3 0x0C /* Common control 3 */ | ||
178 | #define COM3_BAND_50H 0x04 /* 0 For Banding at 60H */ | ||
179 | #define COM3_BAND_AUTO 0x02 /* Auto Banding */ | ||
180 | #define COM3_SING_FR_SNAPSH 0x01 /* 0 For enable live video output after the | ||
181 | * snapshot sequence*/ | ||
182 | #define AEC 0x10 /* AEC[9:2] Exposure Value */ | ||
183 | #define CLKRC 0x11 /* Internal clock */ | ||
184 | #define CLKRC_EN 0x80 | ||
185 | #define CLKRC_DIV_SET(x) (((x) - 1) & 0x1F) /* CLK = XVCLK/(x) */ | ||
186 | #define COM7 0x12 /* Common control 7 */ | ||
187 | #define COM7_SRST 0x80 /* Initiates system reset. All registers are | ||
188 | * set to factory default values after which | ||
189 | * the chip resumes normal operation */ | ||
190 | #define COM7_RES_UXGA 0x00 /* Resolution selectors for UXGA */ | ||
191 | #define COM7_RES_SVGA 0x40 /* SVGA */ | ||
192 | #define COM7_RES_CIF 0x20 /* CIF */ | ||
193 | #define COM7_ZOOM_EN 0x04 /* Enable Zoom mode */ | ||
194 | #define COM7_COLOR_BAR_TEST 0x02 /* Enable Color Bar Test Pattern */ | ||
195 | #define COM8 0x13 /* Common control 8 */ | ||
196 | #define COM8_DEF 0xC0 /* Banding filter ON/OFF */ | ||
197 | #define COM8_BNDF_EN 0x20 /* Banding filter ON/OFF */ | ||
198 | #define COM8_AGC_EN 0x04 /* AGC Auto/Manual control selection */ | ||
199 | #define COM8_AEC_EN 0x01 /* Auto/Manual Exposure control */ | ||
200 | #define COM9 0x14 /* Common control 9 | ||
201 | * Automatic gain ceiling - maximum AGC value [7:5]*/ | ||
202 | #define COM9_AGC_GAIN_2x 0x00 /* 000 : 2x */ | ||
203 | #define COM9_AGC_GAIN_4x 0x20 /* 001 : 4x */ | ||
204 | #define COM9_AGC_GAIN_8x 0x40 /* 010 : 8x */ | ||
205 | #define COM9_AGC_GAIN_16x 0x60 /* 011 : 16x */ | ||
206 | #define COM9_AGC_GAIN_32x 0x80 /* 100 : 32x */ | ||
207 | #define COM9_AGC_GAIN_64x 0xA0 /* 101 : 64x */ | ||
208 | #define COM9_AGC_GAIN_128x 0xC0 /* 110 : 128x */ | ||
209 | #define COM10 0x15 /* Common control 10 */ | ||
210 | #define COM10_PCLK_HREF 0x20 /* PCLK output qualified by HREF */ | ||
211 | #define COM10_PCLK_RISE 0x10 /* Data is updated at the rising edge of | ||
212 | * PCLK (user can latch data at the next | ||
213 | * falling edge of PCLK). | ||
214 | * 0 otherwise. */ | ||
215 | #define COM10_HREF_INV 0x08 /* Invert HREF polarity: | ||
216 | * HREF negative for valid data*/ | ||
217 | #define COM10_VSINC_INV 0x02 /* Invert VSYNC polarity */ | ||
218 | #define HSTART 0x17 /* Horizontal Window start MSB 8 bit */ | ||
219 | #define HEND 0x18 /* Horizontal Window end MSB 8 bit */ | ||
220 | #define VSTART 0x19 /* Vertical Window start MSB 8 bit */ | ||
221 | #define VEND 0x1A /* Vertical Window end MSB 8 bit */ | ||
222 | #define MIDH 0x1C /* Manufacturer ID byte - high */ | ||
223 | #define MIDL 0x1D /* Manufacturer ID byte - low */ | ||
224 | #define AEW 0x24 /* AGC/AEC - Stable operating region (upper limit) */ | ||
225 | #define AEB 0x25 /* AGC/AEC - Stable operating region (lower limit) */ | ||
226 | #define VV 0x26 /* AGC/AEC Fast mode operating region */ | ||
227 | #define VV_HIGH_TH_SET(x) VAL_SET(x, 0xF, 0, 4) | ||
228 | #define VV_LOW_TH_SET(x) VAL_SET(x, 0xF, 0, 0) | ||
229 | #define REG2A 0x2A /* Dummy pixel insert MSB */ | ||
230 | #define FRARL 0x2B /* Dummy pixel insert LSB */ | ||
231 | #define ADDVFL 0x2D /* LSB of insert dummy lines in Vertical direction */ | ||
232 | #define ADDVFH 0x2E /* MSB of insert dummy lines in Vertical direction */ | ||
233 | #define YAVG 0x2F /* Y/G Channel Average value */ | ||
234 | #define REG32 0x32 /* Common Control 32 */ | ||
235 | #define REG32_PCLK_DIV_2 0x80 /* PCLK freq divided by 2 */ | ||
236 | #define REG32_PCLK_DIV_4 0xC0 /* PCLK freq divided by 4 */ | ||
237 | #define ARCOM2 0x34 /* Zoom: Horizontal start point */ | ||
238 | #define REG45 0x45 /* Register 45 */ | ||
239 | #define FLL 0x46 /* Frame Length Adjustment LSBs */ | ||
240 | #define FLH 0x47 /* Frame Length Adjustment MSBs */ | ||
241 | #define COM19 0x48 /* Zoom: Vertical start point */ | ||
242 | #define ZOOMS 0x49 /* Zoom: Vertical start point */ | ||
243 | #define COM22 0x4B /* Flash light control */ | ||
244 | #define COM25 0x4E /* For Banding operations */ | ||
245 | #define BD50 0x4F /* 50Hz Banding AEC 8 LSBs */ | ||
246 | #define BD60 0x50 /* 60Hz Banding AEC 8 LSBs */ | ||
247 | #define REG5D 0x5D /* AVGsel[7:0], 16-zone average weight option */ | ||
248 | #define REG5E 0x5E /* AVGsel[15:8], 16-zone average weight option */ | ||
249 | #define REG5F 0x5F /* AVGsel[23:16], 16-zone average weight option */ | ||
250 | #define REG60 0x60 /* AVGsel[31:24], 16-zone average weight option */ | ||
251 | #define HISTO_LOW 0x61 /* Histogram Algorithm Low Level */ | ||
252 | #define HISTO_HIGH 0x62 /* Histogram Algorithm High Level */ | ||
253 | |||
254 | /* | ||
255 | * ID | ||
256 | */ | ||
257 | #define MANUFACTURER_ID 0x7FA2 | ||
258 | #define PID_OV2640 0x2642 | ||
259 | #define VERSION(pid, ver) ((pid << 8) | (ver & 0xFF)) | ||
260 | |||
261 | /* | ||
262 | * Struct | ||
263 | */ | ||
264 | struct regval_list { | ||
265 | u8 reg_num; | ||
266 | u8 value; | ||
267 | }; | ||
268 | |||
269 | /* Supported resolutions */ | ||
270 | enum ov2640_width { | ||
271 | W_QCIF = 176, | ||
272 | W_QVGA = 320, | ||
273 | W_CIF = 352, | ||
274 | W_VGA = 640, | ||
275 | W_SVGA = 800, | ||
276 | W_XGA = 1024, | ||
277 | W_SXGA = 1280, | ||
278 | W_UXGA = 1600, | ||
279 | }; | ||
280 | |||
281 | enum ov2640_height { | ||
282 | H_QCIF = 144, | ||
283 | H_QVGA = 240, | ||
284 | H_CIF = 288, | ||
285 | H_VGA = 480, | ||
286 | H_SVGA = 600, | ||
287 | H_XGA = 768, | ||
288 | H_SXGA = 1024, | ||
289 | H_UXGA = 1200, | ||
290 | }; | ||
291 | |||
292 | struct ov2640_win_size { | ||
293 | char *name; | ||
294 | enum ov2640_width width; | ||
295 | enum ov2640_height height; | ||
296 | const struct regval_list *regs; | ||
297 | }; | ||
298 | |||
299 | |||
300 | struct ov2640_priv { | ||
301 | struct v4l2_subdev subdev; | ||
302 | struct ov2640_camera_info *info; | ||
303 | enum v4l2_mbus_pixelcode cfmt_code; | ||
304 | const struct ov2640_win_size *win; | ||
305 | int model; | ||
306 | u16 flag_vflip:1; | ||
307 | u16 flag_hflip:1; | ||
308 | }; | ||
309 | |||
310 | /* | ||
311 | * Registers settings | ||
312 | */ | ||
313 | |||
314 | #define ENDMARKER { 0xff, 0xff } | ||
315 | |||
316 | static const struct regval_list ov2640_init_regs[] = { | ||
317 | { BANK_SEL, BANK_SEL_DSP }, | ||
318 | { 0x2c, 0xff }, | ||
319 | { 0x2e, 0xdf }, | ||
320 | { BANK_SEL, BANK_SEL_SENS }, | ||
321 | { 0x3c, 0x32 }, | ||
322 | { CLKRC, CLKRC_DIV_SET(1) }, | ||
323 | { COM2, COM2_OCAP_Nx_SET(3) }, | ||
324 | { REG04, REG04_DEF | REG04_HREF_EN }, | ||
325 | { COM8, COM8_DEF | COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN }, | ||
326 | { COM9, COM9_AGC_GAIN_8x | 0x08}, | ||
327 | { 0x2c, 0x0c }, | ||
328 | { 0x33, 0x78 }, | ||
329 | { 0x3a, 0x33 }, | ||
330 | { 0x3b, 0xfb }, | ||
331 | { 0x3e, 0x00 }, | ||
332 | { 0x43, 0x11 }, | ||
333 | { 0x16, 0x10 }, | ||
334 | { 0x39, 0x02 }, | ||
335 | { 0x35, 0x88 }, | ||
336 | { 0x22, 0x0a }, | ||
337 | { 0x37, 0x40 }, | ||
338 | { 0x23, 0x00 }, | ||
339 | { ARCOM2, 0xa0 }, | ||
340 | { 0x06, 0x02 }, | ||
341 | { 0x06, 0x88 }, | ||
342 | { 0x07, 0xc0 }, | ||
343 | { 0x0d, 0xb7 }, | ||
344 | { 0x0e, 0x01 }, | ||
345 | { 0x4c, 0x00 }, | ||
346 | { 0x4a, 0x81 }, | ||
347 | { 0x21, 0x99 }, | ||
348 | { AEW, 0x40 }, | ||
349 | { AEB, 0x38 }, | ||
350 | { VV, VV_HIGH_TH_SET(0x08) | VV_LOW_TH_SET(0x02) }, | ||
351 | { 0x5c, 0x00 }, | ||
352 | { 0x63, 0x00 }, | ||
353 | { FLL, 0x22 }, | ||
354 | { COM3, 0x38 | COM3_BAND_AUTO }, | ||
355 | { REG5D, 0x55 }, | ||
356 | { REG5E, 0x7d }, | ||
357 | { REG5F, 0x7d }, | ||
358 | { REG60, 0x55 }, | ||
359 | { HISTO_LOW, 0x70 }, | ||
360 | { HISTO_HIGH, 0x80 }, | ||
361 | { 0x7c, 0x05 }, | ||
362 | { 0x20, 0x80 }, | ||
363 | { 0x28, 0x30 }, | ||
364 | { 0x6c, 0x00 }, | ||
365 | { 0x6d, 0x80 }, | ||
366 | { 0x6e, 0x00 }, | ||
367 | { 0x70, 0x02 }, | ||
368 | { 0x71, 0x94 }, | ||
369 | { 0x73, 0xc1 }, | ||
370 | { 0x3d, 0x34 }, | ||
371 | { COM7, COM7_RES_UXGA | COM7_ZOOM_EN }, | ||
372 | { 0x5a, 0x57 }, | ||
373 | { BD50, 0xbb }, | ||
374 | { BD60, 0x9c }, | ||
375 | { BANK_SEL, BANK_SEL_DSP }, | ||
376 | { 0xe5, 0x7f }, | ||
377 | { MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL }, | ||
378 | { 0x41, 0x24 }, | ||
379 | { RESET, RESET_JPEG | RESET_DVP }, | ||
380 | { 0x76, 0xff }, | ||
381 | { 0x33, 0xa0 }, | ||
382 | { 0x42, 0x20 }, | ||
383 | { 0x43, 0x18 }, | ||
384 | { 0x4c, 0x00 }, | ||
385 | { CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10 }, | ||
386 | { 0x88, 0x3f }, | ||
387 | { 0xd7, 0x03 }, | ||
388 | { 0xd9, 0x10 }, | ||
389 | { R_DVP_SP , R_DVP_SP_AUTO_MODE | 0x2 }, | ||
390 | { 0xc8, 0x08 }, | ||
391 | { 0xc9, 0x80 }, | ||
392 | { BPADDR, 0x00 }, | ||
393 | { BPDATA, 0x00 }, | ||
394 | { BPADDR, 0x03 }, | ||
395 | { BPDATA, 0x48 }, | ||
396 | { BPDATA, 0x48 }, | ||
397 | { BPADDR, 0x08 }, | ||
398 | { BPDATA, 0x20 }, | ||
399 | { BPDATA, 0x10 }, | ||
400 | { BPDATA, 0x0e }, | ||
401 | { 0x90, 0x00 }, | ||
402 | { 0x91, 0x0e }, | ||
403 | { 0x91, 0x1a }, | ||
404 | { 0x91, 0x31 }, | ||
405 | { 0x91, 0x5a }, | ||
406 | { 0x91, 0x69 }, | ||
407 | { 0x91, 0x75 }, | ||
408 | { 0x91, 0x7e }, | ||
409 | { 0x91, 0x88 }, | ||
410 | { 0x91, 0x8f }, | ||
411 | { 0x91, 0x96 }, | ||
412 | { 0x91, 0xa3 }, | ||
413 | { 0x91, 0xaf }, | ||
414 | { 0x91, 0xc4 }, | ||
415 | { 0x91, 0xd7 }, | ||
416 | { 0x91, 0xe8 }, | ||
417 | { 0x91, 0x20 }, | ||
418 | { 0x92, 0x00 }, | ||
419 | { 0x93, 0x06 }, | ||
420 | { 0x93, 0xe3 }, | ||
421 | { 0x93, 0x03 }, | ||
422 | { 0x93, 0x03 }, | ||
423 | { 0x93, 0x00 }, | ||
424 | { 0x93, 0x02 }, | ||
425 | { 0x93, 0x00 }, | ||
426 | { 0x93, 0x00 }, | ||
427 | { 0x93, 0x00 }, | ||
428 | { 0x93, 0x00 }, | ||
429 | { 0x93, 0x00 }, | ||
430 | { 0x93, 0x00 }, | ||
431 | { 0x93, 0x00 }, | ||
432 | { 0x96, 0x00 }, | ||
433 | { 0x97, 0x08 }, | ||
434 | { 0x97, 0x19 }, | ||
435 | { 0x97, 0x02 }, | ||
436 | { 0x97, 0x0c }, | ||
437 | { 0x97, 0x24 }, | ||
438 | { 0x97, 0x30 }, | ||
439 | { 0x97, 0x28 }, | ||
440 | { 0x97, 0x26 }, | ||
441 | { 0x97, 0x02 }, | ||
442 | { 0x97, 0x98 }, | ||
443 | { 0x97, 0x80 }, | ||
444 | { 0x97, 0x00 }, | ||
445 | { 0x97, 0x00 }, | ||
446 | { 0xa4, 0x00 }, | ||
447 | { 0xa8, 0x00 }, | ||
448 | { 0xc5, 0x11 }, | ||
449 | { 0xc6, 0x51 }, | ||
450 | { 0xbf, 0x80 }, | ||
451 | { 0xc7, 0x10 }, | ||
452 | { 0xb6, 0x66 }, | ||
453 | { 0xb8, 0xA5 }, | ||
454 | { 0xb7, 0x64 }, | ||
455 | { 0xb9, 0x7C }, | ||
456 | { 0xb3, 0xaf }, | ||
457 | { 0xb4, 0x97 }, | ||
458 | { 0xb5, 0xFF }, | ||
459 | { 0xb0, 0xC5 }, | ||
460 | { 0xb1, 0x94 }, | ||
461 | { 0xb2, 0x0f }, | ||
462 | { 0xc4, 0x5c }, | ||
463 | { 0xa6, 0x00 }, | ||
464 | { 0xa7, 0x20 }, | ||
465 | { 0xa7, 0xd8 }, | ||
466 | { 0xa7, 0x1b }, | ||
467 | { 0xa7, 0x31 }, | ||
468 | { 0xa7, 0x00 }, | ||
469 | { 0xa7, 0x18 }, | ||
470 | { 0xa7, 0x20 }, | ||
471 | { 0xa7, 0xd8 }, | ||
472 | { 0xa7, 0x19 }, | ||
473 | { 0xa7, 0x31 }, | ||
474 | { 0xa7, 0x00 }, | ||
475 | { 0xa7, 0x18 }, | ||
476 | { 0xa7, 0x20 }, | ||
477 | { 0xa7, 0xd8 }, | ||
478 | { 0xa7, 0x19 }, | ||
479 | { 0xa7, 0x31 }, | ||
480 | { 0xa7, 0x00 }, | ||
481 | { 0xa7, 0x18 }, | ||
482 | { 0x7f, 0x00 }, | ||
483 | { 0xe5, 0x1f }, | ||
484 | { 0xe1, 0x77 }, | ||
485 | { 0xdd, 0x7f }, | ||
486 | { CTRL0, CTRL0_YUV422 | CTRL0_YUV_EN | CTRL0_RGB_EN }, | ||
487 | ENDMARKER, | ||
488 | }; | ||
489 | |||
490 | /* | ||
491 | * Register settings for window size | ||
492 | * The preamble, setup the internal DSP to input an UXGA (1600x1200) image. | ||
493 | * Then the different zooming configurations will setup the output image size. | ||
494 | */ | ||
495 | static const struct regval_list ov2640_size_change_preamble_regs[] = { | ||
496 | { BANK_SEL, BANK_SEL_DSP }, | ||
497 | { RESET, RESET_DVP }, | ||
498 | { HSIZE8, HSIZE8_SET(W_UXGA) }, | ||
499 | { VSIZE8, VSIZE8_SET(H_UXGA) }, | ||
500 | { CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN | | ||
501 | CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN }, | ||
502 | { HSIZE, HSIZE_SET(W_UXGA) }, | ||
503 | { VSIZE, VSIZE_SET(H_UXGA) }, | ||
504 | { XOFFL, XOFFL_SET(0) }, | ||
505 | { YOFFL, YOFFL_SET(0) }, | ||
506 | { VHYX, VHYX_HSIZE_SET(W_UXGA) | VHYX_VSIZE_SET(H_UXGA) | | ||
507 | VHYX_XOFF_SET(0) | VHYX_YOFF_SET(0)}, | ||
508 | { TEST, TEST_HSIZE_SET(W_UXGA) }, | ||
509 | ENDMARKER, | ||
510 | }; | ||
511 | |||
512 | #define PER_SIZE_REG_SEQ(x, y, v_div, h_div, pclk_div) \ | ||
513 | { CTRLI, CTRLI_LP_DP | CTRLI_V_DIV_SET(v_div) | \ | ||
514 | CTRLI_H_DIV_SET(h_div)}, \ | ||
515 | { ZMOW, ZMOW_OUTW_SET(x) }, \ | ||
516 | { ZMOH, ZMOH_OUTH_SET(y) }, \ | ||
517 | { ZMHH, ZMHH_OUTW_SET(x) | ZMHH_OUTH_SET(y) }, \ | ||
518 | { R_DVP_SP, pclk_div }, \ | ||
519 | { RESET, 0x00} | ||
520 | |||
521 | static const struct regval_list ov2640_qcif_regs[] = { | ||
522 | PER_SIZE_REG_SEQ(W_QCIF, H_QCIF, 3, 3, 4), | ||
523 | ENDMARKER, | ||
524 | }; | ||
525 | |||
526 | static const struct regval_list ov2640_qvga_regs[] = { | ||
527 | PER_SIZE_REG_SEQ(W_QVGA, H_QVGA, 2, 2, 4), | ||
528 | ENDMARKER, | ||
529 | }; | ||
530 | |||
531 | static const struct regval_list ov2640_cif_regs[] = { | ||
532 | PER_SIZE_REG_SEQ(W_CIF, H_CIF, 2, 2, 8), | ||
533 | ENDMARKER, | ||
534 | }; | ||
535 | |||
536 | static const struct regval_list ov2640_vga_regs[] = { | ||
537 | PER_SIZE_REG_SEQ(W_VGA, H_VGA, 0, 0, 2), | ||
538 | ENDMARKER, | ||
539 | }; | ||
540 | |||
541 | static const struct regval_list ov2640_svga_regs[] = { | ||
542 | PER_SIZE_REG_SEQ(W_SVGA, H_SVGA, 1, 1, 2), | ||
543 | ENDMARKER, | ||
544 | }; | ||
545 | |||
546 | static const struct regval_list ov2640_xga_regs[] = { | ||
547 | PER_SIZE_REG_SEQ(W_XGA, H_XGA, 0, 0, 2), | ||
548 | { CTRLI, 0x00}, | ||
549 | ENDMARKER, | ||
550 | }; | ||
551 | |||
552 | static const struct regval_list ov2640_sxga_regs[] = { | ||
553 | PER_SIZE_REG_SEQ(W_SXGA, H_SXGA, 0, 0, 2), | ||
554 | { CTRLI, 0x00}, | ||
555 | { R_DVP_SP, 2 | R_DVP_SP_AUTO_MODE }, | ||
556 | ENDMARKER, | ||
557 | }; | ||
558 | |||
559 | static const struct regval_list ov2640_uxga_regs[] = { | ||
560 | PER_SIZE_REG_SEQ(W_UXGA, H_UXGA, 0, 0, 0), | ||
561 | { CTRLI, 0x00}, | ||
562 | { R_DVP_SP, 0 | R_DVP_SP_AUTO_MODE }, | ||
563 | ENDMARKER, | ||
564 | }; | ||
565 | |||
566 | #define OV2640_SIZE(n, w, h, r) \ | ||
567 | {.name = n, .width = w , .height = h, .regs = r } | ||
568 | |||
569 | static const struct ov2640_win_size ov2640_supported_win_sizes[] = { | ||
570 | OV2640_SIZE("QCIF", W_QCIF, H_QCIF, ov2640_qcif_regs), | ||
571 | OV2640_SIZE("QVGA", W_QVGA, H_QVGA, ov2640_qvga_regs), | ||
572 | OV2640_SIZE("CIF", W_CIF, H_CIF, ov2640_cif_regs), | ||
573 | OV2640_SIZE("VGA", W_VGA, H_VGA, ov2640_vga_regs), | ||
574 | OV2640_SIZE("SVGA", W_SVGA, H_SVGA, ov2640_svga_regs), | ||
575 | OV2640_SIZE("XGA", W_XGA, H_XGA, ov2640_xga_regs), | ||
576 | OV2640_SIZE("SXGA", W_SXGA, H_SXGA, ov2640_sxga_regs), | ||
577 | OV2640_SIZE("UXGA", W_UXGA, H_UXGA, ov2640_uxga_regs), | ||
578 | }; | ||
579 | |||
580 | /* | ||
581 | * Register settings for pixel formats | ||
582 | */ | ||
583 | static const struct regval_list ov2640_format_change_preamble_regs[] = { | ||
584 | { BANK_SEL, BANK_SEL_DSP }, | ||
585 | { R_BYPASS, R_BYPASS_USE_DSP }, | ||
586 | ENDMARKER, | ||
587 | }; | ||
588 | |||
589 | static const struct regval_list ov2640_yuv422_regs[] = { | ||
590 | { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_YUV422 }, | ||
591 | { 0xD7, 0x01 }, | ||
592 | { 0x33, 0xa0 }, | ||
593 | { 0xe1, 0x67 }, | ||
594 | { RESET, 0x00 }, | ||
595 | { R_BYPASS, R_BYPASS_USE_DSP }, | ||
596 | ENDMARKER, | ||
597 | }; | ||
598 | |||
599 | static const struct regval_list ov2640_rgb565_regs[] = { | ||
600 | { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_RGB565 }, | ||
601 | { 0xd7, 0x03 }, | ||
602 | { RESET, 0x00 }, | ||
603 | { R_BYPASS, R_BYPASS_USE_DSP }, | ||
604 | ENDMARKER, | ||
605 | }; | ||
606 | |||
607 | static enum v4l2_mbus_pixelcode ov2640_codes[] = { | ||
608 | V4L2_MBUS_FMT_UYVY8_2X8, | ||
609 | V4L2_MBUS_FMT_RGB565_2X8_LE, | ||
610 | }; | ||
611 | |||
612 | /* | ||
613 | * Supported controls | ||
614 | */ | ||
615 | static const struct v4l2_queryctrl ov2640_controls[] = { | ||
616 | { | ||
617 | .id = V4L2_CID_VFLIP, | ||
618 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
619 | .name = "Flip Vertically", | ||
620 | .minimum = 0, | ||
621 | .maximum = 1, | ||
622 | .step = 1, | ||
623 | .default_value = 0, | ||
624 | }, { | ||
625 | .id = V4L2_CID_HFLIP, | ||
626 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
627 | .name = "Flip Horizontally", | ||
628 | .minimum = 0, | ||
629 | .maximum = 1, | ||
630 | .step = 1, | ||
631 | .default_value = 0, | ||
632 | }, | ||
633 | }; | ||
634 | |||
635 | /* | ||
636 | * General functions | ||
637 | */ | ||
638 | static struct ov2640_priv *to_ov2640(const struct i2c_client *client) | ||
639 | { | ||
640 | return container_of(i2c_get_clientdata(client), struct ov2640_priv, | ||
641 | subdev); | ||
642 | } | ||
643 | |||
644 | static int ov2640_write_array(struct i2c_client *client, | ||
645 | const struct regval_list *vals) | ||
646 | { | ||
647 | int ret; | ||
648 | |||
649 | while ((vals->reg_num != 0xff) || (vals->value != 0xff)) { | ||
650 | ret = i2c_smbus_write_byte_data(client, | ||
651 | vals->reg_num, vals->value); | ||
652 | dev_vdbg(&client->dev, "array: 0x%02x, 0x%02x", | ||
653 | vals->reg_num, vals->value); | ||
654 | |||
655 | if (ret < 0) | ||
656 | return ret; | ||
657 | vals++; | ||
658 | } | ||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | static int ov2640_mask_set(struct i2c_client *client, | ||
663 | u8 reg, u8 mask, u8 set) | ||
664 | { | ||
665 | s32 val = i2c_smbus_read_byte_data(client, reg); | ||
666 | if (val < 0) | ||
667 | return val; | ||
668 | |||
669 | val &= ~mask; | ||
670 | val |= set & mask; | ||
671 | |||
672 | dev_vdbg(&client->dev, "masks: 0x%02x, 0x%02x", reg, val); | ||
673 | |||
674 | return i2c_smbus_write_byte_data(client, reg, val); | ||
675 | } | ||
676 | |||
677 | static int ov2640_reset(struct i2c_client *client) | ||
678 | { | ||
679 | int ret; | ||
680 | const struct regval_list reset_seq[] = { | ||
681 | {BANK_SEL, BANK_SEL_SENS}, | ||
682 | {COM7, COM7_SRST}, | ||
683 | ENDMARKER, | ||
684 | }; | ||
685 | |||
686 | ret = ov2640_write_array(client, reset_seq); | ||
687 | if (ret) | ||
688 | goto err; | ||
689 | |||
690 | msleep(5); | ||
691 | err: | ||
692 | dev_dbg(&client->dev, "%s: (ret %d)", __func__, ret); | ||
693 | return ret; | ||
694 | } | ||
695 | |||
696 | /* | ||
697 | * soc_camera_ops functions | ||
698 | */ | ||
699 | static int ov2640_s_stream(struct v4l2_subdev *sd, int enable) | ||
700 | { | ||
701 | return 0; | ||
702 | } | ||
703 | |||
704 | static int ov2640_set_bus_param(struct soc_camera_device *icd, | ||
705 | unsigned long flags) | ||
706 | { | ||
707 | struct soc_camera_link *icl = to_soc_camera_link(icd); | ||
708 | unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK; | ||
709 | |||
710 | /* Only one width bit may be set */ | ||
711 | if (!is_power_of_2(width_flag)) | ||
712 | return -EINVAL; | ||
713 | |||
714 | if (icl->set_bus_param) | ||
715 | return icl->set_bus_param(icl, width_flag); | ||
716 | |||
717 | /* | ||
718 | * Without board specific bus width settings we support only the | ||
719 | * sensors native bus width witch are tested working | ||
720 | */ | ||
721 | if (width_flag & (SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8)) | ||
722 | return 0; | ||
723 | |||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | static unsigned long ov2640_query_bus_param(struct soc_camera_device *icd) | ||
728 | { | ||
729 | struct soc_camera_link *icl = to_soc_camera_link(icd); | ||
730 | unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | | ||
731 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | | ||
732 | SOCAM_DATA_ACTIVE_HIGH; | ||
733 | |||
734 | if (icl->query_bus_param) | ||
735 | flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK; | ||
736 | else | ||
737 | flags |= SOCAM_DATAWIDTH_10; | ||
738 | |||
739 | return soc_camera_apply_sensor_flags(icl, flags); | ||
740 | } | ||
741 | |||
742 | static int ov2640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
743 | { | ||
744 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
745 | struct ov2640_priv *priv = to_ov2640(client); | ||
746 | |||
747 | switch (ctrl->id) { | ||
748 | case V4L2_CID_VFLIP: | ||
749 | ctrl->value = priv->flag_vflip; | ||
750 | break; | ||
751 | case V4L2_CID_HFLIP: | ||
752 | ctrl->value = priv->flag_hflip; | ||
753 | break; | ||
754 | } | ||
755 | return 0; | ||
756 | } | ||
757 | |||
758 | static int ov2640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
759 | { | ||
760 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
761 | struct ov2640_priv *priv = to_ov2640(client); | ||
762 | int ret = 0; | ||
763 | u8 val; | ||
764 | |||
765 | switch (ctrl->id) { | ||
766 | case V4L2_CID_VFLIP: | ||
767 | val = ctrl->value ? REG04_VFLIP_IMG : 0x00; | ||
768 | priv->flag_vflip = ctrl->value ? 1 : 0; | ||
769 | ret = ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val); | ||
770 | break; | ||
771 | case V4L2_CID_HFLIP: | ||
772 | val = ctrl->value ? REG04_HFLIP_IMG : 0x00; | ||
773 | priv->flag_hflip = ctrl->value ? 1 : 0; | ||
774 | ret = ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val); | ||
775 | break; | ||
776 | } | ||
777 | |||
778 | return ret; | ||
779 | } | ||
780 | |||
781 | static int ov2640_g_chip_ident(struct v4l2_subdev *sd, | ||
782 | struct v4l2_dbg_chip_ident *id) | ||
783 | { | ||
784 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
785 | struct ov2640_priv *priv = to_ov2640(client); | ||
786 | |||
787 | id->ident = priv->model; | ||
788 | id->revision = 0; | ||
789 | |||
790 | return 0; | ||
791 | } | ||
792 | |||
793 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
794 | static int ov2640_g_register(struct v4l2_subdev *sd, | ||
795 | struct v4l2_dbg_register *reg) | ||
796 | { | ||
797 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
798 | int ret; | ||
799 | |||
800 | reg->size = 1; | ||
801 | if (reg->reg > 0xff) | ||
802 | return -EINVAL; | ||
803 | |||
804 | ret = i2c_smbus_read_byte_data(client, reg->reg); | ||
805 | if (ret < 0) | ||
806 | return ret; | ||
807 | |||
808 | reg->val = ret; | ||
809 | |||
810 | return 0; | ||
811 | } | ||
812 | |||
813 | static int ov2640_s_register(struct v4l2_subdev *sd, | ||
814 | struct v4l2_dbg_register *reg) | ||
815 | { | ||
816 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
817 | |||
818 | if (reg->reg > 0xff || | ||
819 | reg->val > 0xff) | ||
820 | return -EINVAL; | ||
821 | |||
822 | return i2c_smbus_write_byte_data(client, reg->reg, reg->val); | ||
823 | } | ||
824 | #endif | ||
825 | |||
826 | /* Select the nearest higher resolution for capture */ | ||
827 | static const struct ov2640_win_size *ov2640_select_win(u32 *width, u32 *height) | ||
828 | { | ||
829 | int i, default_size = ARRAY_SIZE(ov2640_supported_win_sizes) - 1; | ||
830 | |||
831 | for (i = 0; i < ARRAY_SIZE(ov2640_supported_win_sizes); i++) { | ||
832 | if (ov2640_supported_win_sizes[i].width >= *width && | ||
833 | ov2640_supported_win_sizes[i].height >= *height) { | ||
834 | *width = ov2640_supported_win_sizes[i].width; | ||
835 | *height = ov2640_supported_win_sizes[i].height; | ||
836 | return &ov2640_supported_win_sizes[i]; | ||
837 | } | ||
838 | } | ||
839 | |||
840 | *width = ov2640_supported_win_sizes[default_size].width; | ||
841 | *height = ov2640_supported_win_sizes[default_size].height; | ||
842 | return &ov2640_supported_win_sizes[default_size]; | ||
843 | } | ||
844 | |||
845 | static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height, | ||
846 | enum v4l2_mbus_pixelcode code) | ||
847 | { | ||
848 | struct ov2640_priv *priv = to_ov2640(client); | ||
849 | const struct regval_list *selected_cfmt_regs; | ||
850 | int ret; | ||
851 | |||
852 | /* select win */ | ||
853 | priv->win = ov2640_select_win(width, height); | ||
854 | |||
855 | /* select format */ | ||
856 | priv->cfmt_code = 0; | ||
857 | switch (code) { | ||
858 | case V4L2_MBUS_FMT_RGB565_2X8_LE: | ||
859 | dev_dbg(&client->dev, "%s: Selected cfmt RGB565", __func__); | ||
860 | selected_cfmt_regs = ov2640_rgb565_regs; | ||
861 | break; | ||
862 | default: | ||
863 | case V4L2_MBUS_FMT_UYVY8_2X8: | ||
864 | dev_dbg(&client->dev, "%s: Selected cfmt YUV422", __func__); | ||
865 | selected_cfmt_regs = ov2640_yuv422_regs; | ||
866 | } | ||
867 | |||
868 | /* reset hardware */ | ||
869 | ov2640_reset(client); | ||
870 | |||
871 | /* initialize the sensor with default data */ | ||
872 | dev_dbg(&client->dev, "%s: Init default", __func__); | ||
873 | ret = ov2640_write_array(client, ov2640_init_regs); | ||
874 | if (ret < 0) | ||
875 | goto err; | ||
876 | |||
877 | /* select preamble */ | ||
878 | dev_dbg(&client->dev, "%s: Set size to %s", __func__, priv->win->name); | ||
879 | ret = ov2640_write_array(client, ov2640_size_change_preamble_regs); | ||
880 | if (ret < 0) | ||
881 | goto err; | ||
882 | |||
883 | /* set size win */ | ||
884 | ret = ov2640_write_array(client, priv->win->regs); | ||
885 | if (ret < 0) | ||
886 | goto err; | ||
887 | |||
888 | /* cfmt preamble */ | ||
889 | dev_dbg(&client->dev, "%s: Set cfmt", __func__); | ||
890 | ret = ov2640_write_array(client, ov2640_format_change_preamble_regs); | ||
891 | if (ret < 0) | ||
892 | goto err; | ||
893 | |||
894 | /* set cfmt */ | ||
895 | ret = ov2640_write_array(client, selected_cfmt_regs); | ||
896 | if (ret < 0) | ||
897 | goto err; | ||
898 | |||
899 | priv->cfmt_code = code; | ||
900 | *width = priv->win->width; | ||
901 | *height = priv->win->height; | ||
902 | |||
903 | return 0; | ||
904 | |||
905 | err: | ||
906 | dev_err(&client->dev, "%s: Error %d", __func__, ret); | ||
907 | ov2640_reset(client); | ||
908 | priv->win = NULL; | ||
909 | |||
910 | return ret; | ||
911 | } | ||
912 | |||
913 | static int ov2640_g_fmt(struct v4l2_subdev *sd, | ||
914 | struct v4l2_mbus_framefmt *mf) | ||
915 | { | ||
916 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
917 | struct ov2640_priv *priv = to_ov2640(client); | ||
918 | |||
919 | if (!priv->win) { | ||
920 | u32 width = W_SVGA, height = H_SVGA; | ||
921 | int ret = ov2640_set_params(client, &width, &height, | ||
922 | V4L2_MBUS_FMT_UYVY8_2X8); | ||
923 | if (ret < 0) | ||
924 | return ret; | ||
925 | } | ||
926 | |||
927 | mf->width = priv->win->width; | ||
928 | mf->height = priv->win->height; | ||
929 | mf->code = priv->cfmt_code; | ||
930 | |||
931 | switch (mf->code) { | ||
932 | case V4L2_MBUS_FMT_RGB565_2X8_LE: | ||
933 | mf->colorspace = V4L2_COLORSPACE_SRGB; | ||
934 | break; | ||
935 | default: | ||
936 | case V4L2_MBUS_FMT_UYVY8_2X8: | ||
937 | mf->colorspace = V4L2_COLORSPACE_JPEG; | ||
938 | } | ||
939 | mf->field = V4L2_FIELD_NONE; | ||
940 | |||
941 | return 0; | ||
942 | } | ||
943 | |||
944 | static int ov2640_s_fmt(struct v4l2_subdev *sd, | ||
945 | struct v4l2_mbus_framefmt *mf) | ||
946 | { | ||
947 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
948 | int ret; | ||
949 | |||
950 | |||
951 | switch (mf->code) { | ||
952 | case V4L2_MBUS_FMT_RGB565_2X8_LE: | ||
953 | mf->colorspace = V4L2_COLORSPACE_SRGB; | ||
954 | break; | ||
955 | default: | ||
956 | mf->code = V4L2_MBUS_FMT_UYVY8_2X8; | ||
957 | case V4L2_MBUS_FMT_UYVY8_2X8: | ||
958 | mf->colorspace = V4L2_COLORSPACE_JPEG; | ||
959 | } | ||
960 | |||
961 | ret = ov2640_set_params(client, &mf->width, &mf->height, mf->code); | ||
962 | |||
963 | return ret; | ||
964 | } | ||
965 | |||
966 | static int ov2640_try_fmt(struct v4l2_subdev *sd, | ||
967 | struct v4l2_mbus_framefmt *mf) | ||
968 | { | ||
969 | const struct ov2640_win_size *win; | ||
970 | |||
971 | /* | ||
972 | * select suitable win | ||
973 | */ | ||
974 | win = ov2640_select_win(&mf->width, &mf->height); | ||
975 | |||
976 | mf->field = V4L2_FIELD_NONE; | ||
977 | |||
978 | switch (mf->code) { | ||
979 | case V4L2_MBUS_FMT_RGB565_2X8_LE: | ||
980 | mf->colorspace = V4L2_COLORSPACE_SRGB; | ||
981 | break; | ||
982 | default: | ||
983 | mf->code = V4L2_MBUS_FMT_UYVY8_2X8; | ||
984 | case V4L2_MBUS_FMT_UYVY8_2X8: | ||
985 | mf->colorspace = V4L2_COLORSPACE_JPEG; | ||
986 | } | ||
987 | |||
988 | return 0; | ||
989 | } | ||
990 | |||
991 | static int ov2640_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | ||
992 | enum v4l2_mbus_pixelcode *code) | ||
993 | { | ||
994 | if (index >= ARRAY_SIZE(ov2640_codes)) | ||
995 | return -EINVAL; | ||
996 | |||
997 | *code = ov2640_codes[index]; | ||
998 | return 0; | ||
999 | } | ||
1000 | |||
1001 | static int ov2640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | ||
1002 | { | ||
1003 | a->c.left = 0; | ||
1004 | a->c.top = 0; | ||
1005 | a->c.width = W_UXGA; | ||
1006 | a->c.height = H_UXGA; | ||
1007 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1008 | |||
1009 | return 0; | ||
1010 | } | ||
1011 | |||
1012 | static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | ||
1013 | { | ||
1014 | a->bounds.left = 0; | ||
1015 | a->bounds.top = 0; | ||
1016 | a->bounds.width = W_UXGA; | ||
1017 | a->bounds.height = H_UXGA; | ||
1018 | a->defrect = a->bounds; | ||
1019 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1020 | a->pixelaspect.numerator = 1; | ||
1021 | a->pixelaspect.denominator = 1; | ||
1022 | |||
1023 | return 0; | ||
1024 | } | ||
1025 | |||
1026 | static int ov2640_video_probe(struct soc_camera_device *icd, | ||
1027 | struct i2c_client *client) | ||
1028 | { | ||
1029 | struct ov2640_priv *priv = to_ov2640(client); | ||
1030 | u8 pid, ver, midh, midl; | ||
1031 | const char *devname; | ||
1032 | int ret; | ||
1033 | |||
1034 | /* | ||
1035 | * we must have a parent by now. And it cannot be a wrong one. | ||
1036 | * So this entire test is completely redundant. | ||
1037 | */ | ||
1038 | if (!icd->dev.parent || | ||
1039 | to_soc_camera_host(icd->dev.parent)->nr != icd->iface) { | ||
1040 | dev_err(&client->dev, "Parent missing or invalid!\n"); | ||
1041 | ret = -ENODEV; | ||
1042 | goto err; | ||
1043 | } | ||
1044 | |||
1045 | /* | ||
1046 | * check and show product ID and manufacturer ID | ||
1047 | */ | ||
1048 | i2c_smbus_write_byte_data(client, BANK_SEL, BANK_SEL_SENS); | ||
1049 | pid = i2c_smbus_read_byte_data(client, PID); | ||
1050 | ver = i2c_smbus_read_byte_data(client, VER); | ||
1051 | midh = i2c_smbus_read_byte_data(client, MIDH); | ||
1052 | midl = i2c_smbus_read_byte_data(client, MIDL); | ||
1053 | |||
1054 | switch (VERSION(pid, ver)) { | ||
1055 | case PID_OV2640: | ||
1056 | devname = "ov2640"; | ||
1057 | priv->model = V4L2_IDENT_OV2640; | ||
1058 | break; | ||
1059 | default: | ||
1060 | dev_err(&client->dev, | ||
1061 | "Product ID error %x:%x\n", pid, ver); | ||
1062 | ret = -ENODEV; | ||
1063 | goto err; | ||
1064 | } | ||
1065 | |||
1066 | dev_info(&client->dev, | ||
1067 | "%s Product ID %0x:%0x Manufacturer ID %x:%x\n", | ||
1068 | devname, pid, ver, midh, midl); | ||
1069 | |||
1070 | return 0; | ||
1071 | |||
1072 | err: | ||
1073 | return ret; | ||
1074 | } | ||
1075 | |||
1076 | static struct soc_camera_ops ov2640_ops = { | ||
1077 | .set_bus_param = ov2640_set_bus_param, | ||
1078 | .query_bus_param = ov2640_query_bus_param, | ||
1079 | .controls = ov2640_controls, | ||
1080 | .num_controls = ARRAY_SIZE(ov2640_controls), | ||
1081 | }; | ||
1082 | |||
1083 | static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = { | ||
1084 | .g_ctrl = ov2640_g_ctrl, | ||
1085 | .s_ctrl = ov2640_s_ctrl, | ||
1086 | .g_chip_ident = ov2640_g_chip_ident, | ||
1087 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1088 | .g_register = ov2640_g_register, | ||
1089 | .s_register = ov2640_s_register, | ||
1090 | #endif | ||
1091 | }; | ||
1092 | |||
1093 | static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = { | ||
1094 | .s_stream = ov2640_s_stream, | ||
1095 | .g_mbus_fmt = ov2640_g_fmt, | ||
1096 | .s_mbus_fmt = ov2640_s_fmt, | ||
1097 | .try_mbus_fmt = ov2640_try_fmt, | ||
1098 | .cropcap = ov2640_cropcap, | ||
1099 | .g_crop = ov2640_g_crop, | ||
1100 | .enum_mbus_fmt = ov2640_enum_fmt, | ||
1101 | }; | ||
1102 | |||
1103 | static struct v4l2_subdev_ops ov2640_subdev_ops = { | ||
1104 | .core = &ov2640_subdev_core_ops, | ||
1105 | .video = &ov2640_subdev_video_ops, | ||
1106 | }; | ||
1107 | |||
1108 | /* | ||
1109 | * i2c_driver functions | ||
1110 | */ | ||
1111 | static int ov2640_probe(struct i2c_client *client, | ||
1112 | const struct i2c_device_id *did) | ||
1113 | { | ||
1114 | struct ov2640_priv *priv; | ||
1115 | struct soc_camera_device *icd = client->dev.platform_data; | ||
1116 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | ||
1117 | struct soc_camera_link *icl; | ||
1118 | int ret; | ||
1119 | |||
1120 | if (!icd) { | ||
1121 | dev_err(&adapter->dev, "OV2640: missing soc-camera data!\n"); | ||
1122 | return -EINVAL; | ||
1123 | } | ||
1124 | |||
1125 | icl = to_soc_camera_link(icd); | ||
1126 | if (!icl) { | ||
1127 | dev_err(&adapter->dev, | ||
1128 | "OV2640: Missing platform_data for driver\n"); | ||
1129 | return -EINVAL; | ||
1130 | } | ||
1131 | |||
1132 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
1133 | dev_err(&adapter->dev, | ||
1134 | "OV2640: I2C-Adapter doesn't support SMBUS\n"); | ||
1135 | return -EIO; | ||
1136 | } | ||
1137 | |||
1138 | priv = kzalloc(sizeof(struct ov2640_priv), GFP_KERNEL); | ||
1139 | if (!priv) { | ||
1140 | dev_err(&adapter->dev, | ||
1141 | "Failed to allocate memory for private data!\n"); | ||
1142 | return -ENOMEM; | ||
1143 | } | ||
1144 | |||
1145 | priv->info = icl->priv; | ||
1146 | |||
1147 | v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops); | ||
1148 | |||
1149 | icd->ops = &ov2640_ops; | ||
1150 | |||
1151 | ret = ov2640_video_probe(icd, client); | ||
1152 | if (ret) { | ||
1153 | icd->ops = NULL; | ||
1154 | kfree(priv); | ||
1155 | } else { | ||
1156 | dev_info(&adapter->dev, "OV2640 Probed\n"); | ||
1157 | } | ||
1158 | |||
1159 | return ret; | ||
1160 | } | ||
1161 | |||
1162 | static int ov2640_remove(struct i2c_client *client) | ||
1163 | { | ||
1164 | struct ov2640_priv *priv = to_ov2640(client); | ||
1165 | struct soc_camera_device *icd = client->dev.platform_data; | ||
1166 | |||
1167 | icd->ops = NULL; | ||
1168 | kfree(priv); | ||
1169 | return 0; | ||
1170 | } | ||
1171 | |||
1172 | static const struct i2c_device_id ov2640_id[] = { | ||
1173 | { "ov2640", 0 }, | ||
1174 | { } | ||
1175 | }; | ||
1176 | MODULE_DEVICE_TABLE(i2c, ov2640_id); | ||
1177 | |||
1178 | static struct i2c_driver ov2640_i2c_driver = { | ||
1179 | .driver = { | ||
1180 | .name = "ov2640", | ||
1181 | }, | ||
1182 | .probe = ov2640_probe, | ||
1183 | .remove = ov2640_remove, | ||
1184 | .id_table = ov2640_id, | ||
1185 | }; | ||
1186 | |||
1187 | /* | ||
1188 | * Module functions | ||
1189 | */ | ||
1190 | static int __init ov2640_module_init(void) | ||
1191 | { | ||
1192 | return i2c_add_driver(&ov2640_i2c_driver); | ||
1193 | } | ||
1194 | |||
1195 | static void __exit ov2640_module_exit(void) | ||
1196 | { | ||
1197 | i2c_del_driver(&ov2640_i2c_driver); | ||
1198 | } | ||
1199 | |||
1200 | module_init(ov2640_module_init); | ||
1201 | module_exit(ov2640_module_exit); | ||
1202 | |||
1203 | MODULE_DESCRIPTION("SoC Camera driver for Omni Vision 2640 sensor"); | ||
1204 | MODULE_AUTHOR("Alberto Panizzo"); | ||
1205 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index a84b770352f9..48895ef863ff 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c | |||
@@ -600,7 +600,7 @@ static int ov772x_reset(struct i2c_client *client) | |||
600 | static int ov772x_s_stream(struct v4l2_subdev *sd, int enable) | 600 | static int ov772x_s_stream(struct v4l2_subdev *sd, int enable) |
601 | { | 601 | { |
602 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 602 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
603 | struct ov772x_priv *priv = to_ov772x(client); | 603 | struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev); |
604 | 604 | ||
605 | if (!enable) { | 605 | if (!enable) { |
606 | ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE); | 606 | ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE); |
@@ -645,8 +645,7 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd) | |||
645 | 645 | ||
646 | static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 646 | static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
647 | { | 647 | { |
648 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 648 | struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev); |
649 | struct ov772x_priv *priv = to_ov772x(client); | ||
650 | 649 | ||
651 | switch (ctrl->id) { | 650 | switch (ctrl->id) { |
652 | case V4L2_CID_VFLIP: | 651 | case V4L2_CID_VFLIP: |
@@ -665,7 +664,7 @@ static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
665 | static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 664 | static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
666 | { | 665 | { |
667 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 666 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
668 | struct ov772x_priv *priv = to_ov772x(client); | 667 | struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev); |
669 | int ret = 0; | 668 | int ret = 0; |
670 | u8 val; | 669 | u8 val; |
671 | 670 | ||
@@ -715,8 +714,7 @@ static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
715 | static int ov772x_g_chip_ident(struct v4l2_subdev *sd, | 714 | static int ov772x_g_chip_ident(struct v4l2_subdev *sd, |
716 | struct v4l2_dbg_chip_ident *id) | 715 | struct v4l2_dbg_chip_ident *id) |
717 | { | 716 | { |
718 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 717 | struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev); |
719 | struct ov772x_priv *priv = to_ov772x(client); | ||
720 | 718 | ||
721 | id->ident = priv->model; | 719 | id->ident = priv->model; |
722 | id->revision = 0; | 720 | id->revision = 0; |
@@ -955,7 +953,7 @@ static int ov772x_g_fmt(struct v4l2_subdev *sd, | |||
955 | struct v4l2_mbus_framefmt *mf) | 953 | struct v4l2_mbus_framefmt *mf) |
956 | { | 954 | { |
957 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 955 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
958 | struct ov772x_priv *priv = to_ov772x(client); | 956 | struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev); |
959 | 957 | ||
960 | if (!priv->win || !priv->cfmt) { | 958 | if (!priv->win || !priv->cfmt) { |
961 | u32 width = VGA_WIDTH, height = VGA_HEIGHT; | 959 | u32 width = VGA_WIDTH, height = VGA_HEIGHT; |
@@ -978,7 +976,7 @@ static int ov772x_s_fmt(struct v4l2_subdev *sd, | |||
978 | struct v4l2_mbus_framefmt *mf) | 976 | struct v4l2_mbus_framefmt *mf) |
979 | { | 977 | { |
980 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 978 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
981 | struct ov772x_priv *priv = to_ov772x(client); | 979 | struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev); |
982 | int ret = ov772x_set_params(client, &mf->width, &mf->height, | 980 | int ret = ov772x_set_params(client, &mf->width, &mf->height, |
983 | mf->code); | 981 | mf->code); |
984 | 982 | ||
@@ -991,8 +989,7 @@ static int ov772x_s_fmt(struct v4l2_subdev *sd, | |||
991 | static int ov772x_try_fmt(struct v4l2_subdev *sd, | 989 | static int ov772x_try_fmt(struct v4l2_subdev *sd, |
992 | struct v4l2_mbus_framefmt *mf) | 990 | struct v4l2_mbus_framefmt *mf) |
993 | { | 991 | { |
994 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 992 | struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev); |
995 | struct ov772x_priv *priv = to_ov772x(client); | ||
996 | const struct ov772x_win_size *win; | 993 | const struct ov772x_win_size *win; |
997 | int i; | 994 | int i; |
998 | 995 | ||
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c index 99e9e1d3c83b..53d88a2ab920 100644 --- a/drivers/media/video/ov9640.c +++ b/drivers/media/video/ov9640.c | |||
@@ -31,6 +31,8 @@ | |||
31 | 31 | ||
32 | #include "ov9640.h" | 32 | #include "ov9640.h" |
33 | 33 | ||
34 | #define to_ov9640_sensor(sd) container_of(sd, struct ov9640_priv, subdev) | ||
35 | |||
34 | /* default register setup */ | 36 | /* default register setup */ |
35 | static const struct ov9640_reg ov9640_regs_dflt[] = { | 37 | static const struct ov9640_reg ov9640_regs_dflt[] = { |
36 | { OV9640_COM5, OV9640_COM5_SYSCLK | OV9640_COM5_LONGEXP }, | 38 | { OV9640_COM5, OV9640_COM5_SYSCLK | OV9640_COM5_LONGEXP }, |
@@ -308,9 +310,7 @@ static unsigned long ov9640_query_bus_param(struct soc_camera_device *icd) | |||
308 | /* Get status of additional camera capabilities */ | 310 | /* Get status of additional camera capabilities */ |
309 | static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 311 | static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
310 | { | 312 | { |
311 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 313 | struct ov9640_priv *priv = to_ov9640_sensor(sd); |
312 | struct ov9640_priv *priv = container_of(i2c_get_clientdata(client), | ||
313 | struct ov9640_priv, subdev); | ||
314 | 314 | ||
315 | switch (ctrl->id) { | 315 | switch (ctrl->id) { |
316 | case V4L2_CID_VFLIP: | 316 | case V4L2_CID_VFLIP: |
@@ -327,8 +327,7 @@ static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
327 | static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 327 | static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
328 | { | 328 | { |
329 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 329 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
330 | struct ov9640_priv *priv = container_of(i2c_get_clientdata(client), | 330 | struct ov9640_priv *priv = to_ov9640_sensor(sd); |
331 | struct ov9640_priv, subdev); | ||
332 | 331 | ||
333 | int ret = 0; | 332 | int ret = 0; |
334 | 333 | ||
@@ -360,9 +359,7 @@ static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
360 | static int ov9640_g_chip_ident(struct v4l2_subdev *sd, | 359 | static int ov9640_g_chip_ident(struct v4l2_subdev *sd, |
361 | struct v4l2_dbg_chip_ident *id) | 360 | struct v4l2_dbg_chip_ident *id) |
362 | { | 361 | { |
363 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 362 | struct ov9640_priv *priv = to_ov9640_sensor(sd); |
364 | struct ov9640_priv *priv = container_of(i2c_get_clientdata(client), | ||
365 | struct ov9640_priv, subdev); | ||
366 | 363 | ||
367 | id->ident = priv->model; | 364 | id->ident = priv->model; |
368 | id->revision = priv->revision; | 365 | id->revision = priv->revision; |
@@ -654,7 +651,8 @@ static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
654 | static int ov9640_video_probe(struct soc_camera_device *icd, | 651 | static int ov9640_video_probe(struct soc_camera_device *icd, |
655 | struct i2c_client *client) | 652 | struct i2c_client *client) |
656 | { | 653 | { |
657 | struct ov9640_priv *priv = i2c_get_clientdata(client); | 654 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
655 | struct ov9640_priv *priv = to_ov9640_sensor(sd); | ||
658 | u8 pid, ver, midh, midl; | 656 | u8 pid, ver, midh, midl; |
659 | const char *devname; | 657 | const char *devname; |
660 | int ret = 0; | 658 | int ret = 0; |
@@ -791,7 +789,8 @@ static int ov9640_probe(struct i2c_client *client, | |||
791 | 789 | ||
792 | static int ov9640_remove(struct i2c_client *client) | 790 | static int ov9640_remove(struct i2c_client *client) |
793 | { | 791 | { |
794 | struct ov9640_priv *priv = i2c_get_clientdata(client); | 792 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
793 | struct ov9640_priv *priv = to_ov9640_sensor(sd); | ||
795 | 794 | ||
796 | kfree(priv); | 795 | kfree(priv); |
797 | return 0; | 796 | return 0; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c index 55ea914c7fcd..7d5a7139a45a 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c | |||
@@ -203,7 +203,7 @@ int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val, | |||
203 | *blen = 0; | 203 | *blen = 0; |
204 | LOCK_TAKE(cptr->hdw->big_lock); do { | 204 | LOCK_TAKE(cptr->hdw->big_lock); do { |
205 | if (cptr->info->type == pvr2_ctl_enum) { | 205 | if (cptr->info->type == pvr2_ctl_enum) { |
206 | const char **names; | 206 | const char * const *names; |
207 | names = cptr->info->def.type_enum.value_names; | 207 | names = cptr->info->def.type_enum.value_names; |
208 | if (pvr2_ctrl_range_check(cptr,val) == 0) { | 208 | if (pvr2_ctrl_range_check(cptr,val) == 0) { |
209 | if (names[val]) { | 209 | if (names[val]) { |
@@ -367,7 +367,7 @@ static const char *boolNames[] = { | |||
367 | 367 | ||
368 | static int parse_token(const char *ptr,unsigned int len, | 368 | static int parse_token(const char *ptr,unsigned int len, |
369 | int *valptr, | 369 | int *valptr, |
370 | const char **names,unsigned int namecnt) | 370 | const char * const *names, unsigned int namecnt) |
371 | { | 371 | { |
372 | char buf[33]; | 372 | char buf[33]; |
373 | unsigned int slen; | 373 | unsigned int slen; |
@@ -559,7 +559,7 @@ int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr, | |||
559 | *len = scnprintf(buf,maxlen,"%s",val ? "true" : "false"); | 559 | *len = scnprintf(buf,maxlen,"%s",val ? "true" : "false"); |
560 | ret = 0; | 560 | ret = 0; |
561 | } else if (cptr->info->type == pvr2_ctl_enum) { | 561 | } else if (cptr->info->type == pvr2_ctl_enum) { |
562 | const char **names; | 562 | const char * const *names; |
563 | names = cptr->info->def.type_enum.value_names; | 563 | names = cptr->info->def.type_enum.value_names; |
564 | if ((val >= 0) && | 564 | if ((val >= 0) && |
565 | (val < cptr->info->def.type_enum.count)) { | 565 | (val < cptr->info->def.type_enum.count)) { |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index cb4057bb07a0..ac94a8bf883e 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | |||
@@ -115,7 +115,7 @@ struct pvr2_ctl_info { | |||
115 | } type_int; | 115 | } type_int; |
116 | struct { /* enumerated control */ | 116 | struct { /* enumerated control */ |
117 | unsigned int count; /* enum value count */ | 117 | unsigned int count; /* enum value count */ |
118 | const char **value_names; /* symbol names */ | 118 | const char * const *value_names; /* symbol names */ |
119 | } type_enum; | 119 | } type_enum; |
120 | struct { /* bitmask control */ | 120 | struct { /* bitmask control */ |
121 | unsigned int valid_bits; /* bits in use */ | 121 | unsigned int valid_bits; /* bits in use */ |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 3d7e5aab547f..281806b2df62 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | |||
@@ -647,7 +647,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp, | |||
647 | if (ret) { | 647 | if (ret) { |
648 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | 648 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
649 | "device_register failed"); | 649 | "device_register failed"); |
650 | kfree(class_dev); | 650 | put_device(class_dev); |
651 | return; | 651 | return; |
652 | } | 652 | } |
653 | 653 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index aaafa0398fd5..58617fc656c2 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |||
@@ -852,8 +852,8 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
852 | #endif | 852 | #endif |
853 | 853 | ||
854 | default : | 854 | default : |
855 | ret = v4l_compat_translate_ioctl(file, cmd, | 855 | ret = -EINVAL; |
856 | arg, pvr2_v4l2_do_ioctl); | 856 | break; |
857 | } | 857 | } |
858 | 858 | ||
859 | pvr2_hdw_commit_ctl(hdw); | 859 | pvr2_hdw_commit_ctl(hdw); |
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 6b8fbddc0747..1593f8deb810 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c | |||
@@ -1386,11 +1386,16 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | |||
1386 | { | 1386 | { |
1387 | ARG_DEF(int, qual) | 1387 | ARG_DEF(int, qual) |
1388 | 1388 | ||
1389 | if (pdev->iso_init) { | ||
1390 | ret = -EBUSY; | ||
1391 | break; | ||
1392 | } | ||
1393 | |||
1389 | ARG_IN(qual) | 1394 | ARG_IN(qual) |
1390 | if (ARGR(qual) < 0 || ARGR(qual) > 3) | 1395 | if (ARGR(qual) < 0 || ARGR(qual) > 3) |
1391 | ret = -EINVAL; | 1396 | ret = -EINVAL; |
1392 | else | 1397 | else |
1393 | ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot); | 1398 | ret = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot); |
1394 | if (ret >= 0) | 1399 | if (ret >= 0) |
1395 | pdev->vcompression = ARGR(qual); | 1400 | pdev->vcompression = ARGR(qual); |
1396 | break; | 1401 | break; |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index f3dc89da4c4e..bd1519a4ecb4 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -287,14 +287,13 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) | |||
287 | /* create frame buffers, and make circular ring */ | 287 | /* create frame buffers, and make circular ring */ |
288 | for (i = 0; i < default_fbufs; i++) { | 288 | for (i = 0; i < default_fbufs; i++) { |
289 | if (pdev->fbuf[i].data == NULL) { | 289 | if (pdev->fbuf[i].data == NULL) { |
290 | kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */ | 290 | kbuf = vzalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */ |
291 | if (kbuf == NULL) { | 291 | if (kbuf == NULL) { |
292 | PWC_ERROR("Failed to allocate frame buffer %d.\n", i); | 292 | PWC_ERROR("Failed to allocate frame buffer %d.\n", i); |
293 | return -ENOMEM; | 293 | return -ENOMEM; |
294 | } | 294 | } |
295 | PWC_DEBUG_MEMORY("Allocated frame buffer %d at %p.\n", i, kbuf); | 295 | PWC_DEBUG_MEMORY("Allocated frame buffer %d at %p.\n", i, kbuf); |
296 | pdev->fbuf[i].data = kbuf; | 296 | pdev->fbuf[i].data = kbuf; |
297 | memset(kbuf, 0, PWC_FRAME_SIZE); | ||
298 | } | 297 | } |
299 | } | 298 | } |
300 | 299 | ||
@@ -899,10 +898,13 @@ int pwc_isoc_init(struct pwc_device *pdev) | |||
899 | /* link */ | 898 | /* link */ |
900 | for (i = 0; i < MAX_ISO_BUFS; i++) { | 899 | for (i = 0; i < MAX_ISO_BUFS; i++) { |
901 | ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL); | 900 | ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL); |
902 | if (ret) | 901 | if (ret) { |
903 | PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); | 902 | PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); |
904 | else | 903 | pdev->iso_init = 1; |
905 | PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb); | 904 | pwc_isoc_cleanup(pdev); |
905 | return ret; | ||
906 | } | ||
907 | PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb); | ||
906 | } | 908 | } |
907 | 909 | ||
908 | /* All is done... */ | 910 | /* All is done... */ |
@@ -958,7 +960,7 @@ void pwc_isoc_cleanup(struct pwc_device *pdev) | |||
958 | /* Stop camera, but only if we are sure the camera is still there (unplug | 960 | /* Stop camera, but only if we are sure the camera is still there (unplug |
959 | is signalled by EPIPE) | 961 | is signalled by EPIPE) |
960 | */ | 962 | */ |
961 | if (pdev->error_status && pdev->error_status != EPIPE) { | 963 | if (pdev->error_status != EPIPE) { |
962 | PWC_DEBUG_OPEN("Setting alternate interface 0.\n"); | 964 | PWC_DEBUG_OPEN("Setting alternate interface 0.\n"); |
963 | usb_set_interface(pdev->udev, 0, 0); | 965 | usb_set_interface(pdev->udev, 0, 0); |
964 | } | 966 | } |
@@ -967,36 +969,6 @@ void pwc_isoc_cleanup(struct pwc_device *pdev) | |||
967 | PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); | 969 | PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); |
968 | } | 970 | } |
969 | 971 | ||
970 | int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot) | ||
971 | { | ||
972 | int ret, start; | ||
973 | |||
974 | /* Stop isoc stuff */ | ||
975 | pwc_isoc_cleanup(pdev); | ||
976 | /* Reset parameters */ | ||
977 | pwc_reset_buffers(pdev); | ||
978 | /* Try to set video mode... */ | ||
979 | start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot); | ||
980 | if (ret) { | ||
981 | PWC_DEBUG_FLOW("pwc_set_video_mode attempt 1 failed.\n"); | ||
982 | /* That failed... restore old mode (we know that worked) */ | ||
983 | start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); | ||
984 | if (start) { | ||
985 | PWC_DEBUG_FLOW("pwc_set_video_mode attempt 2 failed.\n"); | ||
986 | } | ||
987 | } | ||
988 | if (start == 0) | ||
989 | { | ||
990 | if (pwc_isoc_init(pdev) < 0) | ||
991 | { | ||
992 | PWC_WARNING("Failed to restart ISOC transfers in pwc_try_video_mode.\n"); | ||
993 | ret = -EAGAIN; /* let's try again, who knows if it works a second time */ | ||
994 | } | ||
995 | } | ||
996 | pdev->drop_frames++; /* try to avoid garbage during switch */ | ||
997 | return ret; /* Return original error code */ | ||
998 | } | ||
999 | |||
1000 | /********* | 972 | /********* |
1001 | * sysfs | 973 | * sysfs |
1002 | *********/ | 974 | *********/ |
@@ -1176,7 +1148,7 @@ static int pwc_video_open(struct file *file) | |||
1176 | /* Set some defaults */ | 1148 | /* Set some defaults */ |
1177 | pdev->vsnapshot = 0; | 1149 | pdev->vsnapshot = 0; |
1178 | 1150 | ||
1179 | /* Start iso pipe for video; first try the last used video size | 1151 | /* Set video size, first try the last used video size |
1180 | (or the default one); if that fails try QCIF/10 or QSIF/10; | 1152 | (or the default one); if that fails try QCIF/10 or QSIF/10; |
1181 | it that fails too, give up. | 1153 | it that fails too, give up. |
1182 | */ | 1154 | */ |
@@ -1203,15 +1175,6 @@ static int pwc_video_open(struct file *file) | |||
1203 | return i; | 1175 | return i; |
1204 | } | 1176 | } |
1205 | 1177 | ||
1206 | i = pwc_isoc_init(pdev); | ||
1207 | if (i) { | ||
1208 | PWC_DEBUG_OPEN("Failed to init ISOC stuff = %d.\n", i); | ||
1209 | pwc_isoc_cleanup(pdev); | ||
1210 | pwc_free_buffers(pdev); | ||
1211 | mutex_unlock(&pdev->modlock); | ||
1212 | return i; | ||
1213 | } | ||
1214 | |||
1215 | /* Initialize the webcam to sane value */ | 1178 | /* Initialize the webcam to sane value */ |
1216 | pwc_set_brightness(pdev, 0x7fff); | 1179 | pwc_set_brightness(pdev, 0x7fff); |
1217 | pwc_set_agc(pdev, 1, 0); | 1180 | pwc_set_agc(pdev, 1, 0); |
@@ -1326,6 +1289,11 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf, | |||
1326 | goto err_out; | 1289 | goto err_out; |
1327 | } | 1290 | } |
1328 | 1291 | ||
1292 | /* Start the stream (if not already started) */ | ||
1293 | rv = pwc_isoc_init(pdev); | ||
1294 | if (rv) | ||
1295 | goto err_out; | ||
1296 | |||
1329 | /* In case we're doing partial reads, we don't have to wait for a frame */ | 1297 | /* In case we're doing partial reads, we don't have to wait for a frame */ |
1330 | if (pdev->image_read_pos == 0) { | 1298 | if (pdev->image_read_pos == 0) { |
1331 | /* Do wait queueing according to the (doc)book */ | 1299 | /* Do wait queueing according to the (doc)book */ |
@@ -1395,6 +1363,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait) | |||
1395 | { | 1363 | { |
1396 | struct video_device *vdev = file->private_data; | 1364 | struct video_device *vdev = file->private_data; |
1397 | struct pwc_device *pdev; | 1365 | struct pwc_device *pdev; |
1366 | int ret; | ||
1398 | 1367 | ||
1399 | if (vdev == NULL) | 1368 | if (vdev == NULL) |
1400 | return -EFAULT; | 1369 | return -EFAULT; |
@@ -1402,6 +1371,13 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait) | |||
1402 | if (pdev == NULL) | 1371 | if (pdev == NULL) |
1403 | return -EFAULT; | 1372 | return -EFAULT; |
1404 | 1373 | ||
1374 | /* Start the stream (if not already started) */ | ||
1375 | mutex_lock(&pdev->modlock); | ||
1376 | ret = pwc_isoc_init(pdev); | ||
1377 | mutex_unlock(&pdev->modlock); | ||
1378 | if (ret) | ||
1379 | return ret; | ||
1380 | |||
1405 | poll_wait(file, &pdev->frameq, wait); | 1381 | poll_wait(file, &pdev->frameq, wait); |
1406 | if (pdev->error_status) | 1382 | if (pdev->error_status) |
1407 | return POLLERR; | 1383 | return POLLERR; |
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 7061a03f5cf1..8ca4d22b4384 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c | |||
@@ -309,7 +309,10 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) | |||
309 | pixelformat != V4L2_PIX_FMT_PWC2) | 309 | pixelformat != V4L2_PIX_FMT_PWC2) |
310 | return -EINVAL; | 310 | return -EINVAL; |
311 | 311 | ||
312 | PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d " | 312 | if (pdev->iso_init) |
313 | return -EBUSY; | ||
314 | |||
315 | PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d " | ||
313 | "compression=%d snapshot=%d format=%c%c%c%c\n", | 316 | "compression=%d snapshot=%d format=%c%c%c%c\n", |
314 | f->fmt.pix.width, f->fmt.pix.height, fps, | 317 | f->fmt.pix.width, f->fmt.pix.height, fps, |
315 | compression, snapshot, | 318 | compression, snapshot, |
@@ -318,14 +321,14 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) | |||
318 | (pixelformat>>16)&255, | 321 | (pixelformat>>16)&255, |
319 | (pixelformat>>24)&255); | 322 | (pixelformat>>24)&255); |
320 | 323 | ||
321 | ret = pwc_try_video_mode(pdev, | 324 | ret = pwc_set_video_mode(pdev, |
322 | f->fmt.pix.width, | 325 | f->fmt.pix.width, |
323 | f->fmt.pix.height, | 326 | f->fmt.pix.height, |
324 | fps, | 327 | fps, |
325 | compression, | 328 | compression, |
326 | snapshot); | 329 | snapshot); |
327 | 330 | ||
328 | PWC_DEBUG_IOCTL("pwc_try_video_mode(), return=%d\n", ret); | 331 | PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret); |
329 | 332 | ||
330 | if (ret) | 333 | if (ret) |
331 | return ret; | 334 | return ret; |
@@ -359,23 +362,6 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
359 | 362 | ||
360 | 363 | ||
361 | switch (cmd) { | 364 | switch (cmd) { |
362 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
363 | /* mmap() functions */ | ||
364 | case VIDIOCGMBUF: | ||
365 | { | ||
366 | /* Tell the user program how much memory is needed for a mmap() */ | ||
367 | struct video_mbuf *vm = arg; | ||
368 | int i; | ||
369 | |||
370 | memset(vm, 0, sizeof(*vm)); | ||
371 | vm->size = pwc_mbufs * pdev->len_per_image; | ||
372 | vm->frames = pwc_mbufs; /* double buffering should be enough for most applications */ | ||
373 | for (i = 0; i < pwc_mbufs; i++) | ||
374 | vm->offsets[i] = i * pdev->len_per_image; | ||
375 | break; | ||
376 | } | ||
377 | #endif | ||
378 | |||
379 | /* V4L2 Layer */ | 365 | /* V4L2 Layer */ |
380 | case VIDIOC_QUERYCAP: | 366 | case VIDIOC_QUERYCAP: |
381 | { | 367 | { |
@@ -882,9 +868,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
882 | 868 | ||
883 | case VIDIOC_STREAMON: | 869 | case VIDIOC_STREAMON: |
884 | { | 870 | { |
885 | /* WARNING: pwc_try_video_mode() called pwc_isoc_init */ | 871 | return pwc_isoc_init(pdev); |
886 | pwc_isoc_init(pdev); | ||
887 | return 0; | ||
888 | } | 872 | } |
889 | 873 | ||
890 | case VIDIOC_STREAMOFF: | 874 | case VIDIOC_STREAMOFF: |
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 36a9c83b5f5d..16bbc6df9b07 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
@@ -275,7 +275,6 @@ extern int pwc_trace; | |||
275 | extern int pwc_mbufs; | 275 | extern int pwc_mbufs; |
276 | 276 | ||
277 | /** functions in pwc-if.c */ | 277 | /** functions in pwc-if.c */ |
278 | int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot); | ||
279 | int pwc_handle_frame(struct pwc_device *pdev); | 278 | int pwc_handle_frame(struct pwc_device *pdev); |
280 | void pwc_next_image(struct pwc_device *pdev); | 279 | void pwc_next_image(struct pwc_device *pdev); |
281 | int pwc_isoc_init(struct pwc_device *pdev); | 280 | int pwc_isoc_init(struct pwc_device *pdev); |
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index c143ed0a5270..02686771740d 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c | |||
@@ -852,7 +852,7 @@ static void pxa_camera_init_videobuf(struct videobuf_queue *q, | |||
852 | */ | 852 | */ |
853 | videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock, | 853 | videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock, |
854 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | 854 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, |
855 | sizeof(struct pxa_buffer), icd, NULL); | 855 | sizeof(struct pxa_buffer), icd, &icd->video_lock); |
856 | } | 856 | } |
857 | 857 | ||
858 | static u32 mclk_get_divisor(struct platform_device *pdev, | 858 | static u32 mclk_get_divisor(struct platform_device *pdev, |
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c index d2fa2d43ff19..57e11b6f19fb 100644 --- a/drivers/media/video/rj54n1cb0c.c +++ b/drivers/media/video/rj54n1cb0c.c | |||
@@ -1460,7 +1460,6 @@ static int rj54n1_remove(struct i2c_client *client) | |||
1460 | icd->ops = NULL; | 1460 | icd->ops = NULL; |
1461 | if (icl->free_bus) | 1461 | if (icl->free_bus) |
1462 | icl->free_bus(icl); | 1462 | icl->free_bus(icl); |
1463 | client->driver = NULL; | ||
1464 | kfree(rj54n1); | 1463 | kfree(rj54n1); |
1465 | 1464 | ||
1466 | return 0; | 1465 | return 0; |
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index a845753665c1..b63f8cafa671 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c | |||
@@ -268,7 +268,7 @@ struct s2255_dev { | |||
268 | struct v4l2_device v4l2_dev; | 268 | struct v4l2_device v4l2_dev; |
269 | atomic_t num_channels; | 269 | atomic_t num_channels; |
270 | int frames; | 270 | int frames; |
271 | struct mutex lock; | 271 | struct mutex lock; /* channels[].vdev.lock */ |
272 | struct mutex open_lock; | 272 | struct mutex open_lock; |
273 | struct usb_device *udev; | 273 | struct usb_device *udev; |
274 | struct usb_interface *interface; | 274 | struct usb_interface *interface; |
@@ -780,20 +780,14 @@ static struct videobuf_queue_ops s2255_video_qops = { | |||
780 | 780 | ||
781 | static int res_get(struct s2255_fh *fh) | 781 | static int res_get(struct s2255_fh *fh) |
782 | { | 782 | { |
783 | struct s2255_dev *dev = fh->dev; | ||
784 | /* is it free? */ | ||
785 | struct s2255_channel *channel = fh->channel; | 783 | struct s2255_channel *channel = fh->channel; |
786 | mutex_lock(&dev->lock); | 784 | /* is it free? */ |
787 | if (channel->resources) { | 785 | if (channel->resources) |
788 | /* no, someone else uses it */ | 786 | return 0; /* no, someone else uses it */ |
789 | mutex_unlock(&dev->lock); | ||
790 | return 0; | ||
791 | } | ||
792 | /* it's free, grab it */ | 787 | /* it's free, grab it */ |
793 | channel->resources = 1; | 788 | channel->resources = 1; |
794 | fh->resources = 1; | 789 | fh->resources = 1; |
795 | dprintk(1, "s2255: res: get\n"); | 790 | dprintk(1, "s2255: res: get\n"); |
796 | mutex_unlock(&dev->lock); | ||
797 | return 1; | 791 | return 1; |
798 | } | 792 | } |
799 | 793 | ||
@@ -811,11 +805,8 @@ static int res_check(struct s2255_fh *fh) | |||
811 | static void res_free(struct s2255_fh *fh) | 805 | static void res_free(struct s2255_fh *fh) |
812 | { | 806 | { |
813 | struct s2255_channel *channel = fh->channel; | 807 | struct s2255_channel *channel = fh->channel; |
814 | struct s2255_dev *dev = fh->dev; | ||
815 | mutex_lock(&dev->lock); | ||
816 | channel->resources = 0; | 808 | channel->resources = 0; |
817 | fh->resources = 0; | 809 | fh->resources = 0; |
818 | mutex_unlock(&dev->lock); | ||
819 | dprintk(1, "res: put\n"); | 810 | dprintk(1, "res: put\n"); |
820 | } | 811 | } |
821 | 812 | ||
@@ -1106,15 +1097,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) | |||
1106 | return rc; | 1097 | return rc; |
1107 | } | 1098 | } |
1108 | 1099 | ||
1109 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1110 | static int vidioc_cgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | ||
1111 | { | ||
1112 | struct s2255_fh *fh = priv; | ||
1113 | |||
1114 | return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); | ||
1115 | } | ||
1116 | #endif | ||
1117 | |||
1118 | /* write to the configuration pipe, synchronously */ | 1100 | /* write to the configuration pipe, synchronously */ |
1119 | static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf, | 1101 | static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf, |
1120 | int size) | 1102 | int size) |
@@ -1218,7 +1200,6 @@ static int s2255_set_mode(struct s2255_channel *channel, | |||
1218 | __le32 *buffer; | 1200 | __le32 *buffer; |
1219 | unsigned long chn_rev; | 1201 | unsigned long chn_rev; |
1220 | struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); | 1202 | struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); |
1221 | mutex_lock(&dev->lock); | ||
1222 | chn_rev = G_chnmap[channel->idx]; | 1203 | chn_rev = G_chnmap[channel->idx]; |
1223 | dprintk(3, "%s channel: %d\n", __func__, channel->idx); | 1204 | dprintk(3, "%s channel: %d\n", __func__, channel->idx); |
1224 | /* if JPEG, set the quality */ | 1205 | /* if JPEG, set the quality */ |
@@ -1235,7 +1216,6 @@ static int s2255_set_mode(struct s2255_channel *channel, | |||
1235 | buffer = kzalloc(512, GFP_KERNEL); | 1216 | buffer = kzalloc(512, GFP_KERNEL); |
1236 | if (buffer == NULL) { | 1217 | if (buffer == NULL) { |
1237 | dev_err(&dev->udev->dev, "out of mem\n"); | 1218 | dev_err(&dev->udev->dev, "out of mem\n"); |
1238 | mutex_unlock(&dev->lock); | ||
1239 | return -ENOMEM; | 1219 | return -ENOMEM; |
1240 | } | 1220 | } |
1241 | /* set the mode */ | 1221 | /* set the mode */ |
@@ -1260,7 +1240,6 @@ static int s2255_set_mode(struct s2255_channel *channel, | |||
1260 | } | 1240 | } |
1261 | /* clear the restart flag */ | 1241 | /* clear the restart flag */ |
1262 | channel->mode.restart = 0; | 1242 | channel->mode.restart = 0; |
1263 | mutex_unlock(&dev->lock); | ||
1264 | dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res); | 1243 | dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res); |
1265 | return res; | 1244 | return res; |
1266 | } | 1245 | } |
@@ -1271,13 +1250,11 @@ static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus) | |||
1271 | __le32 *buffer; | 1250 | __le32 *buffer; |
1272 | u32 chn_rev; | 1251 | u32 chn_rev; |
1273 | struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); | 1252 | struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); |
1274 | mutex_lock(&dev->lock); | ||
1275 | chn_rev = G_chnmap[channel->idx]; | 1253 | chn_rev = G_chnmap[channel->idx]; |
1276 | dprintk(4, "%s chan %d\n", __func__, channel->idx); | 1254 | dprintk(4, "%s chan %d\n", __func__, channel->idx); |
1277 | buffer = kzalloc(512, GFP_KERNEL); | 1255 | buffer = kzalloc(512, GFP_KERNEL); |
1278 | if (buffer == NULL) { | 1256 | if (buffer == NULL) { |
1279 | dev_err(&dev->udev->dev, "out of mem\n"); | 1257 | dev_err(&dev->udev->dev, "out of mem\n"); |
1280 | mutex_unlock(&dev->lock); | ||
1281 | return -ENOMEM; | 1258 | return -ENOMEM; |
1282 | } | 1259 | } |
1283 | /* form the get vid status command */ | 1260 | /* form the get vid status command */ |
@@ -1297,7 +1274,6 @@ static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus) | |||
1297 | } | 1274 | } |
1298 | *pstatus = channel->vidstatus; | 1275 | *pstatus = channel->vidstatus; |
1299 | dprintk(4, "%s, vid status %d\n", __func__, *pstatus); | 1276 | dprintk(4, "%s, vid status %d\n", __func__, *pstatus); |
1300 | mutex_unlock(&dev->lock); | ||
1301 | return res; | 1277 | return res; |
1302 | } | 1278 | } |
1303 | 1279 | ||
@@ -1816,7 +1792,8 @@ static int s2255_open(struct file *file) | |||
1816 | NULL, &dev->slock, | 1792 | NULL, &dev->slock, |
1817 | fh->type, | 1793 | fh->type, |
1818 | V4L2_FIELD_INTERLACED, | 1794 | V4L2_FIELD_INTERLACED, |
1819 | sizeof(struct s2255_buffer), fh, NULL); | 1795 | sizeof(struct s2255_buffer), |
1796 | fh, vdev->lock); | ||
1820 | return 0; | 1797 | return 0; |
1821 | } | 1798 | } |
1822 | 1799 | ||
@@ -1899,7 +1876,7 @@ static const struct v4l2_file_operations s2255_fops_v4l = { | |||
1899 | .open = s2255_open, | 1876 | .open = s2255_open, |
1900 | .release = s2255_release, | 1877 | .release = s2255_release, |
1901 | .poll = s2255_poll, | 1878 | .poll = s2255_poll, |
1902 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ | 1879 | .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */ |
1903 | .mmap = s2255_mmap_v4l, | 1880 | .mmap = s2255_mmap_v4l, |
1904 | }; | 1881 | }; |
1905 | 1882 | ||
@@ -1923,9 +1900,6 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { | |||
1923 | .vidioc_s_ctrl = vidioc_s_ctrl, | 1900 | .vidioc_s_ctrl = vidioc_s_ctrl, |
1924 | .vidioc_streamon = vidioc_streamon, | 1901 | .vidioc_streamon = vidioc_streamon, |
1925 | .vidioc_streamoff = vidioc_streamoff, | 1902 | .vidioc_streamoff = vidioc_streamoff, |
1926 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1927 | .vidiocgmbuf = vidioc_cgmbuf, | ||
1928 | #endif | ||
1929 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, | 1903 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, |
1930 | .vidioc_g_jpegcomp = vidioc_g_jpegcomp, | 1904 | .vidioc_g_jpegcomp = vidioc_g_jpegcomp, |
1931 | .vidioc_s_parm = vidioc_s_parm, | 1905 | .vidioc_s_parm = vidioc_s_parm, |
@@ -1969,6 +1943,7 @@ static int s2255_probe_v4l(struct s2255_dev *dev) | |||
1969 | channel->vidq.dev = dev; | 1943 | channel->vidq.dev = dev; |
1970 | /* register 4 video devices */ | 1944 | /* register 4 video devices */ |
1971 | channel->vdev = template; | 1945 | channel->vdev = template; |
1946 | channel->vdev.lock = &dev->lock; | ||
1972 | channel->vdev.v4l2_dev = &dev->v4l2_dev; | 1947 | channel->vdev.v4l2_dev = &dev->v4l2_dev; |
1973 | video_set_drvdata(&channel->vdev, channel); | 1948 | video_set_drvdata(&channel->vdev, channel); |
1974 | if (video_nr == -1) | 1949 | if (video_nr == -1) |
@@ -2675,7 +2650,9 @@ static void s2255_disconnect(struct usb_interface *interface) | |||
2675 | struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface)); | 2650 | struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface)); |
2676 | int i; | 2651 | int i; |
2677 | int channels = atomic_read(&dev->num_channels); | 2652 | int channels = atomic_read(&dev->num_channels); |
2653 | mutex_lock(&dev->lock); | ||
2678 | v4l2_device_disconnect(&dev->v4l2_dev); | 2654 | v4l2_device_disconnect(&dev->v4l2_dev); |
2655 | mutex_unlock(&dev->lock); | ||
2679 | /*see comments in the uvc_driver.c usb disconnect function */ | 2656 | /*see comments in the uvc_driver.c usb disconnect function */ |
2680 | atomic_inc(&dev->num_channels); | 2657 | atomic_inc(&dev->num_channels); |
2681 | /* unregister each video device. */ | 2658 | /* unregister each video device. */ |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index bb99f2d805d3..817aa66627f6 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -543,7 +543,7 @@ static void fimc_dma_run(void *priv) | |||
543 | unsigned long flags; | 543 | unsigned long flags; |
544 | u32 ret; | 544 | u32 ret; |
545 | 545 | ||
546 | if (WARN(!ctx, "null hardware context")) | 546 | if (WARN(!ctx, "null hardware context\n")) |
547 | return; | 547 | return; |
548 | 548 | ||
549 | fimc = ctx->fimc_dev; | 549 | fimc = ctx->fimc_dev; |
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c index 984c0feb2a4e..99a2ac16f9e5 100644 --- a/drivers/media/video/saa6588.c +++ b/drivers/media/video/saa6588.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/wait.h> | 31 | #include <linux/wait.h> |
32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
33 | 33 | ||
34 | #include <media/rds.h> | 34 | #include <media/saa6588.h> |
35 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
36 | #include <media/v4l2-chip-ident.h> | 36 | #include <media/v4l2-chip-ident.h> |
37 | 37 | ||
@@ -181,7 +181,7 @@ static int block_to_user_buf(struct saa6588 *s, unsigned char __user *user_buf) | |||
181 | return 1; | 181 | return 1; |
182 | } | 182 | } |
183 | 183 | ||
184 | static void read_from_buf(struct saa6588 *s, struct rds_command *a) | 184 | static void read_from_buf(struct saa6588 *s, struct saa6588_command *a) |
185 | { | 185 | { |
186 | unsigned long flags; | 186 | unsigned long flags; |
187 | 187 | ||
@@ -392,25 +392,25 @@ static void saa6588_configure(struct saa6588 *s) | |||
392 | static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) | 392 | static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) |
393 | { | 393 | { |
394 | struct saa6588 *s = to_saa6588(sd); | 394 | struct saa6588 *s = to_saa6588(sd); |
395 | struct rds_command *a = arg; | 395 | struct saa6588_command *a = arg; |
396 | 396 | ||
397 | switch (cmd) { | 397 | switch (cmd) { |
398 | /* --- open() for /dev/radio --- */ | 398 | /* --- open() for /dev/radio --- */ |
399 | case RDS_CMD_OPEN: | 399 | case SAA6588_CMD_OPEN: |
400 | a->result = 0; /* return error if chip doesn't work ??? */ | 400 | a->result = 0; /* return error if chip doesn't work ??? */ |
401 | break; | 401 | break; |
402 | /* --- close() for /dev/radio --- */ | 402 | /* --- close() for /dev/radio --- */ |
403 | case RDS_CMD_CLOSE: | 403 | case SAA6588_CMD_CLOSE: |
404 | s->data_available_for_read = 1; | 404 | s->data_available_for_read = 1; |
405 | wake_up_interruptible(&s->read_queue); | 405 | wake_up_interruptible(&s->read_queue); |
406 | a->result = 0; | 406 | a->result = 0; |
407 | break; | 407 | break; |
408 | /* --- read() for /dev/radio --- */ | 408 | /* --- read() for /dev/radio --- */ |
409 | case RDS_CMD_READ: | 409 | case SAA6588_CMD_READ: |
410 | read_from_buf(s, a); | 410 | read_from_buf(s, a); |
411 | break; | 411 | break; |
412 | /* --- poll() for /dev/radio --- */ | 412 | /* --- poll() for /dev/radio --- */ |
413 | case RDS_CMD_POLL: | 413 | case SAA6588_CMD_POLL: |
414 | a->result = 0; | 414 | a->result = 0; |
415 | if (s->data_available_for_read) { | 415 | if (s->data_available_for_read) { |
416 | a->result |= POLLIN | POLLRDNORM; | 416 | a->result |= POLLIN | POLLRDNORM; |
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index 301c62b88cad..f35459d1f42f 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c | |||
@@ -1348,8 +1348,17 @@ static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) | |||
1348 | int reg1e; | 1348 | int reg1e; |
1349 | 1349 | ||
1350 | *std = V4L2_STD_ALL; | 1350 | *std = V4L2_STD_ALL; |
1351 | if (state->ident != V4L2_IDENT_SAA7115) | 1351 | if (state->ident != V4L2_IDENT_SAA7115) { |
1352 | int reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC); | ||
1353 | |||
1354 | if (reg1f & 0x20) | ||
1355 | *std = V4L2_STD_525_60; | ||
1356 | else | ||
1357 | *std = V4L2_STD_625_50; | ||
1358 | |||
1352 | return 0; | 1359 | return 0; |
1360 | } | ||
1361 | |||
1353 | reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC); | 1362 | reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC); |
1354 | 1363 | ||
1355 | switch (reg1e & 0x03) { | 1364 | switch (reg1e & 0x03) { |
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig index 3fe71be41a1f..380f1b28cfcc 100644 --- a/drivers/media/video/saa7134/Kconfig +++ b/drivers/media/video/saa7134/Kconfig | |||
@@ -26,7 +26,7 @@ config VIDEO_SAA7134_ALSA | |||
26 | 26 | ||
27 | config VIDEO_SAA7134_RC | 27 | config VIDEO_SAA7134_RC |
28 | bool "Philips SAA7134 Remote Controller support" | 28 | bool "Philips SAA7134 Remote Controller support" |
29 | depends on VIDEO_IR | 29 | depends on RC_CORE |
30 | depends on VIDEO_SAA7134 | 30 | depends on VIDEO_SAA7134 |
31 | default y | 31 | default y |
32 | ---help--- | 32 | ---help--- |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 1d4d0a49ea52..e7aa588c6c5a 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -5176,6 +5176,58 @@ struct saa7134_board saa7134_boards[] = { | |||
5176 | .amux = 2, | 5176 | .amux = 2, |
5177 | }, | 5177 | }, |
5178 | }, | 5178 | }, |
5179 | [SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG] = { | ||
5180 | .name = "Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid", | ||
5181 | .audio_clock = 0x00187de7, | ||
5182 | #if 0 | ||
5183 | /* | ||
5184 | * FIXME: Analog mode doesn't work, if digital is enabled. The proper | ||
5185 | * fix is to use tda8290 driver, but Kworld seems to use an | ||
5186 | * unsupported version of tda8295. | ||
5187 | */ | ||
5188 | .tuner_type = TUNER_NXP_TDA18271, /* TUNER_PHILIPS_TDA8290 */ | ||
5189 | .tuner_addr = 0x60, | ||
5190 | #else | ||
5191 | .tuner_type = UNSET, | ||
5192 | .tuner_addr = ADDR_UNSET, | ||
5193 | #endif | ||
5194 | .radio_type = UNSET, | ||
5195 | .radio_addr = ADDR_UNSET, | ||
5196 | .gpiomask = 0x8e054000, | ||
5197 | .mpeg = SAA7134_MPEG_DVB, | ||
5198 | .ts_type = SAA7134_MPEG_TS_PARALLEL, | ||
5199 | .inputs = { { | ||
5200 | .name = name_tv, | ||
5201 | .vmux = 1, | ||
5202 | .amux = TV, | ||
5203 | .tv = 1, | ||
5204 | #if 0 /* FIXME */ | ||
5205 | }, { | ||
5206 | .name = name_comp1, | ||
5207 | .vmux = 3, | ||
5208 | .amux = LINE1, | ||
5209 | .gpio = 0x200, | ||
5210 | }, { | ||
5211 | .name = name_svideo, | ||
5212 | .vmux = 8, | ||
5213 | .amux = LINE1, | ||
5214 | .gpio = 0x200, | ||
5215 | #endif | ||
5216 | } }, | ||
5217 | #if 0 | ||
5218 | .radio = { | ||
5219 | .name = name_radio, | ||
5220 | .vmux = 1, | ||
5221 | .amux = LINE1, | ||
5222 | .gpio = 0x100, | ||
5223 | }, | ||
5224 | #endif | ||
5225 | .mute = { | ||
5226 | .name = name_mute, | ||
5227 | .vmux = 0, | ||
5228 | .amux = TV, | ||
5229 | }, | ||
5230 | }, | ||
5179 | [SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS] = { | 5231 | [SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS] = { |
5180 | .name = "Avermedia AVerTV GO 007 FM Plus", | 5232 | .name = "Avermedia AVerTV GO 007 FM Plus", |
5181 | .audio_clock = 0x00187de7, | 5233 | .audio_clock = 0x00187de7, |
@@ -5486,6 +5538,37 @@ struct saa7134_board saa7134_boards[] = { | |||
5486 | .amux = LINE2, | 5538 | .amux = LINE2, |
5487 | } }, | 5539 | } }, |
5488 | }, | 5540 | }, |
5541 | [SAA7134_BOARD_VIDEOMATE_M1F] = { | ||
5542 | /* Pavel Osnova <pvosnova@gmail.com> */ | ||
5543 | .name = "Compro VideoMate Vista M1F", | ||
5544 | .audio_clock = 0x00187de7, | ||
5545 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
5546 | .radio_type = TUNER_TEA5767, | ||
5547 | .tuner_addr = ADDR_UNSET, | ||
5548 | .radio_addr = 0x60, | ||
5549 | .inputs = { { | ||
5550 | .name = name_tv, | ||
5551 | .vmux = 1, | ||
5552 | .amux = TV, | ||
5553 | .tv = 1, | ||
5554 | }, { | ||
5555 | .name = name_comp1, | ||
5556 | .vmux = 3, | ||
5557 | .amux = LINE2, | ||
5558 | }, { | ||
5559 | .name = name_svideo, | ||
5560 | .vmux = 8, | ||
5561 | .amux = LINE2, | ||
5562 | } }, | ||
5563 | .radio = { | ||
5564 | .name = name_radio, | ||
5565 | .amux = LINE1, | ||
5566 | }, | ||
5567 | .mute = { | ||
5568 | .name = name_mute, | ||
5569 | .amux = TV, | ||
5570 | }, | ||
5571 | }, | ||
5489 | 5572 | ||
5490 | }; | 5573 | }; |
5491 | 5574 | ||
@@ -6615,6 +6698,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
6615 | }, { | 6698 | }, { |
6616 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6699 | .vendor = PCI_VENDOR_ID_PHILIPS, |
6617 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6700 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
6701 | .subvendor = 0x17de, | ||
6702 | .subdevice = 0xb136, | ||
6703 | .driver_data = SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG, | ||
6704 | }, { | ||
6705 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
6706 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
6618 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | 6707 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ |
6619 | .subdevice = 0xf31d, | 6708 | .subdevice = 0xf31d, |
6620 | .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS, | 6709 | .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS, |
@@ -6673,6 +6762,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
6673 | .subdevice = 0x7090, | 6762 | .subdevice = 0x7090, |
6674 | .driver_data = SAA7134_BOARD_BEHOLD_A7, | 6763 | .driver_data = SAA7134_BOARD_BEHOLD_A7, |
6675 | }, { | 6764 | }, { |
6765 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
6766 | .device = PCI_DEVICE_ID_PHILIPS_SAA7135, | ||
6767 | .subvendor = 0x185b, | ||
6768 | .subdevice = 0xc900, | ||
6769 | .driver_data = SAA7134_BOARD_VIDEOMATE_M1F, | ||
6770 | }, { | ||
6676 | /* --- boards without eeprom + subsystem ID --- */ | 6771 | /* --- boards without eeprom + subsystem ID --- */ |
6677 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6772 | .vendor = PCI_VENDOR_ID_PHILIPS, |
6678 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 6773 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
@@ -6831,6 +6926,23 @@ static inline int saa7134_tda18271_hvr11x0_toggle_agc(struct saa7134_dev *dev, | |||
6831 | return 0; | 6926 | return 0; |
6832 | } | 6927 | } |
6833 | 6928 | ||
6929 | static inline int saa7134_kworld_sbtvd_toggle_agc(struct saa7134_dev *dev, | ||
6930 | enum tda18271_mode mode) | ||
6931 | { | ||
6932 | /* toggle AGC switch through GPIO 27 */ | ||
6933 | switch (mode) { | ||
6934 | case TDA18271_ANALOG: | ||
6935 | saa7134_set_gpio(dev, 27, 0); | ||
6936 | break; | ||
6937 | case TDA18271_DIGITAL: | ||
6938 | saa7134_set_gpio(dev, 27, 1); | ||
6939 | break; | ||
6940 | default: | ||
6941 | return -EINVAL; | ||
6942 | } | ||
6943 | return 0; | ||
6944 | } | ||
6945 | |||
6834 | static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev, | 6946 | static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev, |
6835 | int command, int arg) | 6947 | int command, int arg) |
6836 | { | 6948 | { |
@@ -6843,6 +6955,9 @@ static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev, | |||
6843 | case SAA7134_BOARD_HAUPPAUGE_HVR1120: | 6955 | case SAA7134_BOARD_HAUPPAUGE_HVR1120: |
6844 | ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg); | 6956 | ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg); |
6845 | break; | 6957 | break; |
6958 | case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: | ||
6959 | ret = saa7134_kworld_sbtvd_toggle_agc(dev, arg); | ||
6960 | break; | ||
6846 | default: | 6961 | default: |
6847 | break; | 6962 | break; |
6848 | } | 6963 | } |
@@ -6863,6 +6978,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev, | |||
6863 | case SAA7134_BOARD_HAUPPAUGE_HVR1150: | 6978 | case SAA7134_BOARD_HAUPPAUGE_HVR1150: |
6864 | case SAA7134_BOARD_HAUPPAUGE_HVR1120: | 6979 | case SAA7134_BOARD_HAUPPAUGE_HVR1120: |
6865 | case SAA7134_BOARD_AVERMEDIA_M733A: | 6980 | case SAA7134_BOARD_AVERMEDIA_M733A: |
6981 | case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: | ||
6866 | /* tda8290 + tda18271 */ | 6982 | /* tda8290 + tda18271 */ |
6867 | ret = saa7134_tda8290_18271_callback(dev, command, arg); | 6983 | ret = saa7134_tda8290_18271_callback(dev, command, arg); |
6868 | break; | 6984 | break; |
@@ -6967,6 +7083,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
6967 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: | 7083 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: |
6968 | case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: | 7084 | case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: |
6969 | case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: | 7085 | case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: |
7086 | case SAA7134_BOARD_VIDEOMATE_M1F: | ||
6970 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | 7087 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: |
6971 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: | 7088 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: |
6972 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: | 7089 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: |
@@ -7541,6 +7658,37 @@ int saa7134_board_init2(struct saa7134_dev *dev) | |||
7541 | dev->name); | 7658 | dev->name); |
7542 | break; | 7659 | break; |
7543 | } | 7660 | } |
7661 | case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: | ||
7662 | { | ||
7663 | struct i2c_msg msg = { .addr = 0x4b, .flags = 0 }; | ||
7664 | int i; | ||
7665 | static u8 buffer[][2] = { | ||
7666 | {0x30, 0x31}, | ||
7667 | {0xff, 0x00}, | ||
7668 | {0x41, 0x03}, | ||
7669 | {0x41, 0x1a}, | ||
7670 | {0xff, 0x02}, | ||
7671 | {0x34, 0x00}, | ||
7672 | {0x45, 0x97}, | ||
7673 | {0x45, 0xc1}, | ||
7674 | }; | ||
7675 | saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000); | ||
7676 | saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x4000); | ||
7677 | |||
7678 | /* | ||
7679 | * FIXME: identify what device is at addr 0x4b and what means | ||
7680 | * this initialization | ||
7681 | */ | ||
7682 | for (i = 0; i < ARRAY_SIZE(buffer); i++) { | ||
7683 | msg.buf = &buffer[i][0]; | ||
7684 | msg.len = ARRAY_SIZE(buffer[0]); | ||
7685 | if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) | ||
7686 | printk(KERN_WARNING | ||
7687 | "%s: Unable to enable tuner(%i).\n", | ||
7688 | dev->name, i); | ||
7689 | } | ||
7690 | break; | ||
7691 | } | ||
7544 | } /* switch() */ | 7692 | } /* switch() */ |
7545 | 7693 | ||
7546 | /* initialize tuner */ | 7694 | /* initialize tuner */ |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index beb95e21d109..3315a48a848b 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include "tda18271.h" | 52 | #include "tda18271.h" |
53 | #include "lgdt3305.h" | 53 | #include "lgdt3305.h" |
54 | #include "tda8290.h" | 54 | #include "tda8290.h" |
55 | #include "mb86a20s.h" | ||
55 | 56 | ||
56 | #include "zl10353.h" | 57 | #include "zl10353.h" |
57 | 58 | ||
@@ -228,6 +229,20 @@ static struct mt352_config avermedia_xc3028_mt352_dev = { | |||
228 | .demod_init = mt352_avermedia_xc3028_init, | 229 | .demod_init = mt352_avermedia_xc3028_init, |
229 | }; | 230 | }; |
230 | 231 | ||
232 | static struct tda18271_std_map mb86a20s_tda18271_std_map = { | ||
233 | .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4, | ||
234 | .if_lvl = 7, .rfagc_top = 0x37, }, | ||
235 | }; | ||
236 | |||
237 | static struct tda18271_config kworld_tda18271_config = { | ||
238 | .std_map = &mb86a20s_tda18271_std_map, | ||
239 | .gate = TDA18271_GATE_DIGITAL, | ||
240 | }; | ||
241 | |||
242 | static const struct mb86a20s_config kworld_mb86a20s_config = { | ||
243 | .demod_address = 0x10, | ||
244 | }; | ||
245 | |||
231 | /* ================================================================== | 246 | /* ================================================================== |
232 | * tda1004x based DVB-T cards, helper functions | 247 | * tda1004x based DVB-T cards, helper functions |
233 | */ | 248 | */ |
@@ -608,6 +623,37 @@ static struct tda827x_config tda827x_cfg_2_sw42 = { | |||
608 | 623 | ||
609 | /* ------------------------------------------------------------------ */ | 624 | /* ------------------------------------------------------------------ */ |
610 | 625 | ||
626 | static int __kworld_sbtvd_i2c_gate_ctrl(struct saa7134_dev *dev, int enable) | ||
627 | { | ||
628 | unsigned char initmsg[] = {0x45, 0x97}; | ||
629 | unsigned char msg_enable[] = {0x45, 0xc1}; | ||
630 | unsigned char msg_disable[] = {0x45, 0x81}; | ||
631 | struct i2c_msg msg = {.addr = 0x4b, .flags = 0, .buf = initmsg, .len = 2}; | ||
632 | |||
633 | if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) { | ||
634 | wprintk("could not access the I2C gate\n"); | ||
635 | return -EIO; | ||
636 | } | ||
637 | if (enable) | ||
638 | msg.buf = msg_enable; | ||
639 | else | ||
640 | msg.buf = msg_disable; | ||
641 | if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) { | ||
642 | wprintk("could not access the I2C gate\n"); | ||
643 | return -EIO; | ||
644 | } | ||
645 | msleep(20); | ||
646 | return 0; | ||
647 | } | ||
648 | static int kworld_sbtvd_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
649 | { | ||
650 | struct saa7134_dev *dev = fe->dvb->priv; | ||
651 | |||
652 | return __kworld_sbtvd_i2c_gate_ctrl(dev, enable); | ||
653 | } | ||
654 | |||
655 | /* ------------------------------------------------------------------ */ | ||
656 | |||
611 | static struct tda1004x_config tda827x_lifeview_config = { | 657 | static struct tda1004x_config tda827x_lifeview_config = { |
612 | .demod_address = 0x08, | 658 | .demod_address = 0x08, |
613 | .invert = 1, | 659 | .invert = 1, |
@@ -1613,6 +1659,29 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1613 | &dtv1000s_tda18271_config); | 1659 | &dtv1000s_tda18271_config); |
1614 | } | 1660 | } |
1615 | break; | 1661 | break; |
1662 | case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: | ||
1663 | __kworld_sbtvd_i2c_gate_ctrl(dev, 0); | ||
1664 | saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x14000); | ||
1665 | saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x14000); | ||
1666 | msleep(20); | ||
1667 | saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x54000); | ||
1668 | saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x54000); | ||
1669 | msleep(20); | ||
1670 | fe0->dvb.frontend = dvb_attach(mb86a20s_attach, | ||
1671 | &kworld_mb86a20s_config, | ||
1672 | &dev->i2c_adap); | ||
1673 | __kworld_sbtvd_i2c_gate_ctrl(dev, 1); | ||
1674 | if (fe0->dvb.frontend != NULL) { | ||
1675 | dvb_attach(tda18271_attach, fe0->dvb.frontend, | ||
1676 | 0x60, &dev->i2c_adap, | ||
1677 | &kworld_tda18271_config); | ||
1678 | /* | ||
1679 | * Only after success, it can initialize the gate, otherwise | ||
1680 | * an OOPS will hit, due to kfree(fe0->dvb.frontend) | ||
1681 | */ | ||
1682 | fe0->dvb.frontend->ops.i2c_gate_ctrl = kworld_sbtvd_i2c_gate_ctrl; | ||
1683 | } | ||
1684 | break; | ||
1616 | default: | 1685 | default: |
1617 | wprintk("Huh? unknown DVB card?\n"); | 1686 | wprintk("Huh? unknown DVB card?\n"); |
1618 | break; | 1687 | break; |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 46d31dfca7a3..dc646e65edb7 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/input.h> | ||
26 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
27 | 26 | ||
28 | #include "saa7134-reg.h" | 27 | #include "saa7134-reg.h" |
@@ -42,41 +41,19 @@ static int pinnacle_remote; | |||
42 | module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */ | 41 | module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */ |
43 | MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)"); | 42 | MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)"); |
44 | 43 | ||
45 | static int ir_rc5_remote_gap = 885; | ||
46 | module_param(ir_rc5_remote_gap, int, 0644); | ||
47 | static int ir_rc5_key_timeout = 115; | ||
48 | module_param(ir_rc5_key_timeout, int, 0644); | ||
49 | |||
50 | static int repeat_delay = 500; | ||
51 | module_param(repeat_delay, int, 0644); | ||
52 | MODULE_PARM_DESC(repeat_delay, "delay before key repeat started"); | ||
53 | static int repeat_period = 33; | ||
54 | module_param(repeat_period, int, 0644); | ||
55 | MODULE_PARM_DESC(repeat_period, "repeat period between " | ||
56 | "keypresses when key is down"); | ||
57 | |||
58 | static unsigned int disable_other_ir; | ||
59 | module_param(disable_other_ir, int, 0644); | ||
60 | MODULE_PARM_DESC(disable_other_ir, "disable full codes of " | ||
61 | "alternative remotes from other manufacturers"); | ||
62 | |||
63 | #define dprintk(fmt, arg...) if (ir_debug) \ | 44 | #define dprintk(fmt, arg...) if (ir_debug) \ |
64 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) | 45 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) |
65 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ | 46 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ |
66 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg) | 47 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg) |
67 | 48 | ||
68 | /* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */ | 49 | /* Helper function for raw decoding at GPIO16 or GPIO18 */ |
69 | static int saa7134_rc5_irq(struct saa7134_dev *dev); | ||
70 | static int saa7134_nec_irq(struct saa7134_dev *dev); | ||
71 | static int saa7134_raw_decode_irq(struct saa7134_dev *dev); | 50 | static int saa7134_raw_decode_irq(struct saa7134_dev *dev); |
72 | static void nec_task(unsigned long data); | ||
73 | static void saa7134_nec_timer(unsigned long data); | ||
74 | 51 | ||
75 | /* -------------------- GPIO generic keycode builder -------------------- */ | 52 | /* -------------------- GPIO generic keycode builder -------------------- */ |
76 | 53 | ||
77 | static int build_key(struct saa7134_dev *dev) | 54 | static int build_key(struct saa7134_dev *dev) |
78 | { | 55 | { |
79 | struct card_ir *ir = dev->remote; | 56 | struct saa7134_card_ir *ir = dev->remote; |
80 | u32 gpio, data; | 57 | u32 gpio, data; |
81 | 58 | ||
82 | /* here comes the additional handshake steps for some cards */ | 59 | /* here comes the additional handshake steps for some cards */ |
@@ -104,25 +81,25 @@ static int build_key(struct saa7134_dev *dev) | |||
104 | switch (dev->board) { | 81 | switch (dev->board) { |
105 | case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: | 82 | case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: |
106 | if (data == ir->mask_keycode) | 83 | if (data == ir->mask_keycode) |
107 | ir_input_nokey(ir->dev, &ir->ir); | 84 | rc_keyup(ir->dev); |
108 | else | 85 | else |
109 | ir_input_keydown(ir->dev, &ir->ir, data); | 86 | rc_keydown_notimeout(ir->dev, data, 0); |
110 | return 0; | 87 | return 0; |
111 | } | 88 | } |
112 | 89 | ||
113 | if (ir->polling) { | 90 | if (ir->polling) { |
114 | if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || | 91 | if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || |
115 | (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { | 92 | (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { |
116 | ir_input_keydown(ir->dev, &ir->ir, data); | 93 | rc_keydown_notimeout(ir->dev, data, 0); |
117 | } else { | 94 | } else { |
118 | ir_input_nokey(ir->dev, &ir->ir); | 95 | rc_keyup(ir->dev); |
119 | } | 96 | } |
120 | } | 97 | } |
121 | else { /* IRQ driven mode - handle key press and release in one go */ | 98 | else { /* IRQ driven mode - handle key press and release in one go */ |
122 | if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || | 99 | if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || |
123 | (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { | 100 | (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { |
124 | ir_input_keydown(ir->dev, &ir->ir, data); | 101 | rc_keydown_notimeout(ir->dev, data, 0); |
125 | ir_input_nokey(ir->dev, &ir->ir); | 102 | rc_keyup(ir->dev); |
126 | } | 103 | } |
127 | } | 104 | } |
128 | 105 | ||
@@ -300,22 +277,12 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
300 | i2cdprintk("read error\n"); | 277 | i2cdprintk("read error\n"); |
301 | return -EIO; | 278 | return -EIO; |
302 | } | 279 | } |
303 | /* IR of this card normally decode signals NEC-standard from | ||
304 | * - Sven IHOO MT 5.1R remote. xxyye718 | ||
305 | * - Sven DVD HD-10xx remote. xxyyf708 | ||
306 | * - BBK ... | ||
307 | * - mayby others | ||
308 | * So, skip not our, if disable full codes mode. | ||
309 | */ | ||
310 | if (data[10] != 0x6b && data[11] != 0x86 && disable_other_ir) | ||
311 | return 0; | ||
312 | 280 | ||
313 | /* Wrong data decode fix */ | ||
314 | if (data[9] != (unsigned char)(~data[8])) | 281 | if (data[9] != (unsigned char)(~data[8])) |
315 | return 0; | 282 | return 0; |
316 | 283 | ||
317 | *ir_key = data[9]; | 284 | *ir_raw = ((data[10] << 16) | (data[11] << 8) | (data[9] << 0)); |
318 | *ir_raw = data[9]; | 285 | *ir_key = *ir_raw; |
319 | 286 | ||
320 | return 1; | 287 | return 1; |
321 | } | 288 | } |
@@ -400,7 +367,7 @@ static int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
400 | 367 | ||
401 | void saa7134_input_irq(struct saa7134_dev *dev) | 368 | void saa7134_input_irq(struct saa7134_dev *dev) |
402 | { | 369 | { |
403 | struct card_ir *ir; | 370 | struct saa7134_card_ir *ir; |
404 | 371 | ||
405 | if (!dev || !dev->remote) | 372 | if (!dev || !dev->remote) |
406 | return; | 373 | return; |
@@ -409,12 +376,8 @@ void saa7134_input_irq(struct saa7134_dev *dev) | |||
409 | if (!ir->running) | 376 | if (!ir->running) |
410 | return; | 377 | return; |
411 | 378 | ||
412 | if (ir->nec_gpio) { | 379 | if (!ir->polling && !ir->raw_decode) { |
413 | saa7134_nec_irq(dev); | ||
414 | } else if (!ir->polling && !ir->rc5_gpio && !ir->raw_decode) { | ||
415 | build_key(dev); | 380 | build_key(dev); |
416 | } else if (ir->rc5_gpio) { | ||
417 | saa7134_rc5_irq(dev); | ||
418 | } else if (ir->raw_decode) { | 381 | } else if (ir->raw_decode) { |
419 | saa7134_raw_decode_irq(dev); | 382 | saa7134_raw_decode_irq(dev); |
420 | } | 383 | } |
@@ -423,7 +386,7 @@ void saa7134_input_irq(struct saa7134_dev *dev) | |||
423 | static void saa7134_input_timer(unsigned long data) | 386 | static void saa7134_input_timer(unsigned long data) |
424 | { | 387 | { |
425 | struct saa7134_dev *dev = (struct saa7134_dev *)data; | 388 | struct saa7134_dev *dev = (struct saa7134_dev *)data; |
426 | struct card_ir *ir = dev->remote; | 389 | struct saa7134_card_ir *ir = dev->remote; |
427 | 390 | ||
428 | build_key(dev); | 391 | build_key(dev); |
429 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); | 392 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); |
@@ -432,57 +395,37 @@ static void saa7134_input_timer(unsigned long data) | |||
432 | static void ir_raw_decode_timer_end(unsigned long data) | 395 | static void ir_raw_decode_timer_end(unsigned long data) |
433 | { | 396 | { |
434 | struct saa7134_dev *dev = (struct saa7134_dev *)data; | 397 | struct saa7134_dev *dev = (struct saa7134_dev *)data; |
435 | struct card_ir *ir = dev->remote; | 398 | struct saa7134_card_ir *ir = dev->remote; |
436 | 399 | ||
437 | ir_raw_event_handle(dev->remote->dev); | 400 | ir_raw_event_handle(dev->remote->dev); |
438 | 401 | ||
439 | ir->active = 0; | 402 | ir->active = false; |
440 | } | 403 | } |
441 | 404 | ||
442 | static int __saa7134_ir_start(void *priv) | 405 | static int __saa7134_ir_start(void *priv) |
443 | { | 406 | { |
444 | struct saa7134_dev *dev = priv; | 407 | struct saa7134_dev *dev = priv; |
445 | struct card_ir *ir; | 408 | struct saa7134_card_ir *ir; |
446 | 409 | ||
447 | if (!dev) | 410 | if (!dev || !dev->remote) |
448 | return -EINVAL; | 411 | return -EINVAL; |
449 | 412 | ||
450 | ir = dev->remote; | 413 | ir = dev->remote; |
451 | if (!ir) | ||
452 | return -EINVAL; | ||
453 | |||
454 | if (ir->running) | 414 | if (ir->running) |
455 | return 0; | 415 | return 0; |
456 | 416 | ||
457 | ir->running = 1; | 417 | ir->running = true; |
418 | ir->active = false; | ||
419 | |||
458 | if (ir->polling) { | 420 | if (ir->polling) { |
459 | setup_timer(&ir->timer, saa7134_input_timer, | 421 | setup_timer(&ir->timer, saa7134_input_timer, |
460 | (unsigned long)dev); | 422 | (unsigned long)dev); |
461 | ir->timer.expires = jiffies + HZ; | 423 | ir->timer.expires = jiffies + HZ; |
462 | add_timer(&ir->timer); | 424 | add_timer(&ir->timer); |
463 | } else if (ir->rc5_gpio) { | ||
464 | /* set timer_end for code completion */ | ||
465 | init_timer(&ir->timer_end); | ||
466 | ir->timer_end.function = ir_rc5_timer_end; | ||
467 | ir->timer_end.data = (unsigned long)ir; | ||
468 | init_timer(&ir->timer_keyup); | ||
469 | ir->timer_keyup.function = ir_rc5_timer_keyup; | ||
470 | ir->timer_keyup.data = (unsigned long)ir; | ||
471 | ir->shift_by = 2; | ||
472 | ir->start = 0x2; | ||
473 | ir->addr = 0x17; | ||
474 | ir->rc5_key_timeout = ir_rc5_key_timeout; | ||
475 | ir->rc5_remote_gap = ir_rc5_remote_gap; | ||
476 | } else if (ir->nec_gpio) { | ||
477 | setup_timer(&ir->timer_keyup, saa7134_nec_timer, | ||
478 | (unsigned long)dev); | ||
479 | tasklet_init(&ir->tlet, nec_task, (unsigned long)dev); | ||
480 | } else if (ir->raw_decode) { | 425 | } else if (ir->raw_decode) { |
481 | /* set timer_end for code completion */ | 426 | /* set timer_end for code completion */ |
482 | init_timer(&ir->timer_end); | 427 | setup_timer(&ir->timer, ir_raw_decode_timer_end, |
483 | ir->timer_end.function = ir_raw_decode_timer_end; | 428 | (unsigned long)dev); |
484 | ir->timer_end.data = (unsigned long)dev; | ||
485 | ir->active = 0; | ||
486 | } | 429 | } |
487 | 430 | ||
488 | return 0; | 431 | return 0; |
@@ -491,29 +434,20 @@ static int __saa7134_ir_start(void *priv) | |||
491 | static void __saa7134_ir_stop(void *priv) | 434 | static void __saa7134_ir_stop(void *priv) |
492 | { | 435 | { |
493 | struct saa7134_dev *dev = priv; | 436 | struct saa7134_dev *dev = priv; |
494 | struct card_ir *ir; | 437 | struct saa7134_card_ir *ir; |
495 | 438 | ||
496 | if (!dev) | 439 | if (!dev || !dev->remote) |
497 | return; | 440 | return; |
498 | 441 | ||
499 | ir = dev->remote; | 442 | ir = dev->remote; |
500 | if (!ir) | ||
501 | return; | ||
502 | |||
503 | if (!ir->running) | 443 | if (!ir->running) |
504 | return; | 444 | return; |
505 | if (dev->remote->polling) | ||
506 | del_timer_sync(&dev->remote->timer); | ||
507 | else if (ir->rc5_gpio) | ||
508 | del_timer_sync(&ir->timer_end); | ||
509 | else if (ir->nec_gpio) | ||
510 | tasklet_kill(&ir->tlet); | ||
511 | else if (ir->raw_decode) { | ||
512 | del_timer_sync(&ir->timer_end); | ||
513 | ir->active = 0; | ||
514 | } | ||
515 | 445 | ||
516 | ir->running = 0; | 446 | if (ir->polling || ir->raw_decode) |
447 | del_timer_sync(&ir->timer); | ||
448 | |||
449 | ir->active = false; | ||
450 | ir->running = false; | ||
517 | 451 | ||
518 | return; | 452 | return; |
519 | } | 453 | } |
@@ -532,71 +466,33 @@ void saa7134_ir_stop(struct saa7134_dev *dev) | |||
532 | __saa7134_ir_stop(dev); | 466 | __saa7134_ir_stop(dev); |
533 | } | 467 | } |
534 | 468 | ||
535 | static int saa7134_ir_open(void *priv) | 469 | static int saa7134_ir_open(struct rc_dev *rc) |
536 | { | 470 | { |
537 | struct saa7134_dev *dev = priv; | 471 | struct saa7134_dev *dev = rc->priv; |
538 | 472 | ||
539 | dev->remote->users++; | 473 | dev->remote->users++; |
540 | return __saa7134_ir_start(dev); | 474 | return __saa7134_ir_start(dev); |
541 | } | 475 | } |
542 | 476 | ||
543 | static void saa7134_ir_close(void *priv) | 477 | static void saa7134_ir_close(struct rc_dev *rc) |
544 | { | 478 | { |
545 | struct saa7134_dev *dev = priv; | 479 | struct saa7134_dev *dev = rc->priv; |
546 | 480 | ||
547 | dev->remote->users--; | 481 | dev->remote->users--; |
548 | if (!dev->remote->users) | 482 | if (!dev->remote->users) |
549 | __saa7134_ir_stop(dev); | 483 | __saa7134_ir_stop(dev); |
550 | } | 484 | } |
551 | 485 | ||
552 | |||
553 | static int saa7134_ir_change_protocol(void *priv, u64 ir_type) | ||
554 | { | ||
555 | struct saa7134_dev *dev = priv; | ||
556 | struct card_ir *ir = dev->remote; | ||
557 | u32 nec_gpio, rc5_gpio; | ||
558 | |||
559 | if (ir_type == IR_TYPE_RC5) { | ||
560 | dprintk("Changing protocol to RC5\n"); | ||
561 | nec_gpio = 0; | ||
562 | rc5_gpio = 1; | ||
563 | } else if (ir_type == IR_TYPE_NEC) { | ||
564 | dprintk("Changing protocol to NEC\n"); | ||
565 | nec_gpio = 1; | ||
566 | rc5_gpio = 0; | ||
567 | } else { | ||
568 | dprintk("IR protocol type %ud is not supported\n", | ||
569 | (unsigned)ir_type); | ||
570 | return -EINVAL; | ||
571 | } | ||
572 | |||
573 | if (ir->running) { | ||
574 | saa7134_ir_stop(dev); | ||
575 | ir->nec_gpio = nec_gpio; | ||
576 | ir->rc5_gpio = rc5_gpio; | ||
577 | saa7134_ir_start(dev); | ||
578 | } else { | ||
579 | ir->nec_gpio = nec_gpio; | ||
580 | ir->rc5_gpio = rc5_gpio; | ||
581 | } | ||
582 | |||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | int saa7134_input_init1(struct saa7134_dev *dev) | 486 | int saa7134_input_init1(struct saa7134_dev *dev) |
587 | { | 487 | { |
588 | struct card_ir *ir; | 488 | struct saa7134_card_ir *ir; |
589 | struct input_dev *input_dev; | 489 | struct rc_dev *rc; |
590 | char *ir_codes = NULL; | 490 | char *ir_codes = NULL; |
591 | u32 mask_keycode = 0; | 491 | u32 mask_keycode = 0; |
592 | u32 mask_keydown = 0; | 492 | u32 mask_keydown = 0; |
593 | u32 mask_keyup = 0; | 493 | u32 mask_keyup = 0; |
594 | int polling = 0; | 494 | unsigned polling = 0; |
595 | int rc5_gpio = 0; | 495 | bool raw_decode = false; |
596 | int nec_gpio = 0; | ||
597 | int raw_decode = 0; | ||
598 | int allow_protocol_change = 0; | ||
599 | u64 ir_type = IR_TYPE_OTHER; | ||
600 | int err; | 496 | int err; |
601 | 497 | ||
602 | if (dev->has_remote != SAA7134_REMOTE_GPIO) | 498 | if (dev->has_remote != SAA7134_REMOTE_GPIO) |
@@ -661,14 +557,14 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
661 | mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */ | 557 | mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */ |
662 | mask_keyup = 0x0040000; | 558 | mask_keyup = 0x0040000; |
663 | mask_keycode = 0xffff; | 559 | mask_keycode = 0xffff; |
664 | raw_decode = 1; | 560 | raw_decode = true; |
665 | break; | 561 | break; |
666 | case SAA7134_BOARD_AVERMEDIA_M733A: | 562 | case SAA7134_BOARD_AVERMEDIA_M733A: |
667 | ir_codes = RC_MAP_AVERMEDIA_M733A_RM_K6; | 563 | ir_codes = RC_MAP_AVERMEDIA_M733A_RM_K6; |
668 | mask_keydown = 0x0040000; | 564 | mask_keydown = 0x0040000; |
669 | mask_keyup = 0x0040000; | 565 | mask_keyup = 0x0040000; |
670 | mask_keycode = 0xffff; | 566 | mask_keycode = 0xffff; |
671 | raw_decode = 1; | 567 | raw_decode = true; |
672 | break; | 568 | break; |
673 | case SAA7134_BOARD_AVERMEDIA_777: | 569 | case SAA7134_BOARD_AVERMEDIA_777: |
674 | case SAA7134_BOARD_AVERMEDIA_A16AR: | 570 | case SAA7134_BOARD_AVERMEDIA_A16AR: |
@@ -775,7 +671,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
775 | mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */ | 671 | mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */ |
776 | mask_keyup = 0x0040000; | 672 | mask_keyup = 0x0040000; |
777 | mask_keycode = 0xffff; | 673 | mask_keycode = 0xffff; |
778 | raw_decode = 1; | 674 | raw_decode = true; |
779 | break; | 675 | break; |
780 | case SAA7134_BOARD_ENCORE_ENLTV: | 676 | case SAA7134_BOARD_ENCORE_ENLTV: |
781 | case SAA7134_BOARD_ENCORE_ENLTV_FM: | 677 | case SAA7134_BOARD_ENCORE_ENLTV_FM: |
@@ -786,9 +682,10 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
786 | break; | 682 | break; |
787 | case SAA7134_BOARD_ENCORE_ENLTV_FM53: | 683 | case SAA7134_BOARD_ENCORE_ENLTV_FM53: |
788 | ir_codes = RC_MAP_ENCORE_ENLTV_FM53; | 684 | ir_codes = RC_MAP_ENCORE_ENLTV_FM53; |
789 | mask_keydown = 0x0040000; | 685 | mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */ |
790 | mask_keycode = 0x00007f; | 686 | mask_keyup = 0x0040000; |
791 | nec_gpio = 1; | 687 | mask_keycode = 0xffff; |
688 | raw_decode = true; | ||
792 | break; | 689 | break; |
793 | case SAA7134_BOARD_10MOONSTVMASTER3: | 690 | case SAA7134_BOARD_10MOONSTVMASTER3: |
794 | ir_codes = RC_MAP_ENCORE_ENLTV; | 691 | ir_codes = RC_MAP_ENCORE_ENLTV; |
@@ -824,6 +721,11 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
824 | mask_keyup = 0x020000; | 721 | mask_keyup = 0x020000; |
825 | polling = 50; /* ms */ | 722 | polling = 50; /* ms */ |
826 | break; | 723 | break; |
724 | case SAA7134_BOARD_VIDEOMATE_M1F: | ||
725 | ir_codes = RC_MAP_VIDEOMATE_M1F; | ||
726 | mask_keycode = 0x0ff00; | ||
727 | mask_keyup = 0x040000; | ||
728 | break; | ||
827 | } | 729 | } |
828 | if (NULL == ir_codes) { | 730 | if (NULL == ir_codes) { |
829 | printk("%s: Oops: IR config error [card=%d]\n", | 731 | printk("%s: Oops: IR config error [card=%d]\n", |
@@ -832,24 +734,20 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
832 | } | 734 | } |
833 | 735 | ||
834 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | 736 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); |
835 | input_dev = input_allocate_device(); | 737 | rc = rc_allocate_device(); |
836 | if (!ir || !input_dev) { | 738 | if (!ir || !rc) { |
837 | err = -ENOMEM; | 739 | err = -ENOMEM; |
838 | goto err_out_free; | 740 | goto err_out_free; |
839 | } | 741 | } |
840 | 742 | ||
841 | ir->dev = input_dev; | 743 | ir->dev = rc; |
842 | dev->remote = ir; | 744 | dev->remote = ir; |
843 | 745 | ||
844 | ir->running = 0; | ||
845 | |||
846 | /* init hardware-specific stuff */ | 746 | /* init hardware-specific stuff */ |
847 | ir->mask_keycode = mask_keycode; | 747 | ir->mask_keycode = mask_keycode; |
848 | ir->mask_keydown = mask_keydown; | 748 | ir->mask_keydown = mask_keydown; |
849 | ir->mask_keyup = mask_keyup; | 749 | ir->mask_keyup = mask_keyup; |
850 | ir->polling = polling; | 750 | ir->polling = polling; |
851 | ir->rc5_gpio = rc5_gpio; | ||
852 | ir->nec_gpio = nec_gpio; | ||
853 | ir->raw_decode = raw_decode; | 751 | ir->raw_decode = raw_decode; |
854 | 752 | ||
855 | /* init input device */ | 753 | /* init input device */ |
@@ -858,47 +756,35 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
858 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", | 756 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", |
859 | pci_name(dev->pci)); | 757 | pci_name(dev->pci)); |
860 | 758 | ||
861 | 759 | rc->priv = dev; | |
862 | ir->props.priv = dev; | 760 | rc->open = saa7134_ir_open; |
863 | ir->props.open = saa7134_ir_open; | 761 | rc->close = saa7134_ir_close; |
864 | ir->props.close = saa7134_ir_close; | ||
865 | |||
866 | if (raw_decode) | 762 | if (raw_decode) |
867 | ir->props.driver_type = RC_DRIVER_IR_RAW; | 763 | rc->driver_type = RC_DRIVER_IR_RAW; |
868 | |||
869 | if (!raw_decode && allow_protocol_change) { | ||
870 | ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; | ||
871 | ir->props.change_protocol = saa7134_ir_change_protocol; | ||
872 | } | ||
873 | |||
874 | err = ir_input_init(input_dev, &ir->ir, ir_type); | ||
875 | if (err < 0) | ||
876 | goto err_out_free; | ||
877 | 764 | ||
878 | input_dev->name = ir->name; | 765 | rc->input_name = ir->name; |
879 | input_dev->phys = ir->phys; | 766 | rc->input_phys = ir->phys; |
880 | input_dev->id.bustype = BUS_PCI; | 767 | rc->input_id.bustype = BUS_PCI; |
881 | input_dev->id.version = 1; | 768 | rc->input_id.version = 1; |
882 | if (dev->pci->subsystem_vendor) { | 769 | if (dev->pci->subsystem_vendor) { |
883 | input_dev->id.vendor = dev->pci->subsystem_vendor; | 770 | rc->input_id.vendor = dev->pci->subsystem_vendor; |
884 | input_dev->id.product = dev->pci->subsystem_device; | 771 | rc->input_id.product = dev->pci->subsystem_device; |
885 | } else { | 772 | } else { |
886 | input_dev->id.vendor = dev->pci->vendor; | 773 | rc->input_id.vendor = dev->pci->vendor; |
887 | input_dev->id.product = dev->pci->device; | 774 | rc->input_id.product = dev->pci->device; |
888 | } | 775 | } |
889 | input_dev->dev.parent = &dev->pci->dev; | 776 | rc->dev.parent = &dev->pci->dev; |
777 | rc->map_name = ir_codes; | ||
778 | rc->driver_name = MODULE_NAME; | ||
890 | 779 | ||
891 | err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME); | 780 | err = rc_register_device(rc); |
892 | if (err) | 781 | if (err) |
893 | goto err_out_free; | 782 | goto err_out_free; |
894 | 783 | ||
895 | /* the remote isn't as bouncy as a keyboard */ | ||
896 | ir->dev->rep[REP_DELAY] = repeat_delay; | ||
897 | ir->dev->rep[REP_PERIOD] = repeat_period; | ||
898 | |||
899 | return 0; | 784 | return 0; |
900 | 785 | ||
901 | err_out_free: | 786 | err_out_free: |
787 | rc_free_device(rc); | ||
902 | dev->remote = NULL; | 788 | dev->remote = NULL; |
903 | kfree(ir); | 789 | kfree(ir); |
904 | return err; | 790 | return err; |
@@ -910,7 +796,7 @@ void saa7134_input_fini(struct saa7134_dev *dev) | |||
910 | return; | 796 | return; |
911 | 797 | ||
912 | saa7134_ir_stop(dev); | 798 | saa7134_ir_stop(dev); |
913 | ir_input_unregister(dev->remote->dev); | 799 | rc_unregister_device(dev->remote->dev); |
914 | kfree(dev->remote); | 800 | kfree(dev->remote); |
915 | dev->remote = NULL; | 801 | dev->remote = NULL; |
916 | } | 802 | } |
@@ -918,14 +804,12 @@ void saa7134_input_fini(struct saa7134_dev *dev) | |||
918 | void saa7134_probe_i2c_ir(struct saa7134_dev *dev) | 804 | void saa7134_probe_i2c_ir(struct saa7134_dev *dev) |
919 | { | 805 | { |
920 | struct i2c_board_info info; | 806 | struct i2c_board_info info; |
921 | |||
922 | struct i2c_msg msg_msi = { | 807 | struct i2c_msg msg_msi = { |
923 | .addr = 0x50, | 808 | .addr = 0x50, |
924 | .flags = I2C_M_RD, | 809 | .flags = I2C_M_RD, |
925 | .len = 0, | 810 | .len = 0, |
926 | .buf = NULL, | 811 | .buf = NULL, |
927 | }; | 812 | }; |
928 | |||
929 | int rc; | 813 | int rc; |
930 | 814 | ||
931 | if (disable_ir) { | 815 | if (disable_ir) { |
@@ -972,7 +856,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) | |||
972 | an existing device. Weird... | 856 | an existing device. Weird... |
973 | REVISIT: might no longer be needed */ | 857 | REVISIT: might no longer be needed */ |
974 | rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1); | 858 | rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1); |
975 | dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n", | 859 | dprintk("probe 0x%02x @ %s: %s\n", |
976 | msg_msi.addr, dev->i2c_adap.name, | 860 | msg_msi.addr, dev->i2c_adap.name, |
977 | (1 == rc) ? "yes" : "no"); | 861 | (1 == rc) ? "yes" : "no"); |
978 | break; | 862 | break; |
@@ -1000,7 +884,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) | |||
1000 | dev->init_data.name = "BeholdTV"; | 884 | dev->init_data.name = "BeholdTV"; |
1001 | dev->init_data.get_key = get_key_beholdm6xx; | 885 | dev->init_data.get_key = get_key_beholdm6xx; |
1002 | dev->init_data.ir_codes = RC_MAP_BEHOLD; | 886 | dev->init_data.ir_codes = RC_MAP_BEHOLD; |
1003 | dev->init_data.type = IR_TYPE_NEC; | 887 | dev->init_data.type = RC_TYPE_NEC; |
1004 | info.addr = 0x2d; | 888 | info.addr = 0x2d; |
1005 | break; | 889 | break; |
1006 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: | 890 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: |
@@ -1025,8 +909,8 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) | |||
1025 | 909 | ||
1026 | static int saa7134_raw_decode_irq(struct saa7134_dev *dev) | 910 | static int saa7134_raw_decode_irq(struct saa7134_dev *dev) |
1027 | { | 911 | { |
1028 | struct card_ir *ir = dev->remote; | 912 | struct saa7134_card_ir *ir = dev->remote; |
1029 | unsigned long timeout; | 913 | unsigned long timeout; |
1030 | int space; | 914 | int space; |
1031 | 915 | ||
1032 | /* Generate initial event */ | 916 | /* Generate initial event */ |
@@ -1035,7 +919,6 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev) | |||
1035 | space = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown; | 919 | space = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown; |
1036 | ir_raw_event_store_edge(dev->remote->dev, space ? IR_SPACE : IR_PULSE); | 920 | ir_raw_event_store_edge(dev->remote->dev, space ? IR_SPACE : IR_PULSE); |
1037 | 921 | ||
1038 | |||
1039 | /* | 922 | /* |
1040 | * Wait 15 ms from the start of the first IR event before processing | 923 | * Wait 15 ms from the start of the first IR event before processing |
1041 | * the event. This time is enough for NEC protocol. May need adjustments | 924 | * the event. This time is enough for NEC protocol. May need adjustments |
@@ -1043,173 +926,9 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev) | |||
1043 | */ | 926 | */ |
1044 | if (!ir->active) { | 927 | if (!ir->active) { |
1045 | timeout = jiffies + jiffies_to_msecs(15); | 928 | timeout = jiffies + jiffies_to_msecs(15); |
1046 | mod_timer(&ir->timer_end, timeout); | 929 | mod_timer(&ir->timer, timeout); |
1047 | ir->active = 1; | 930 | ir->active = true; |
1048 | } | 931 | } |
1049 | 932 | ||
1050 | return 1; | 933 | return 1; |
1051 | } | 934 | } |
1052 | |||
1053 | static int saa7134_rc5_irq(struct saa7134_dev *dev) | ||
1054 | { | ||
1055 | struct card_ir *ir = dev->remote; | ||
1056 | struct timeval tv; | ||
1057 | u32 gap; | ||
1058 | unsigned long current_jiffies, timeout; | ||
1059 | |||
1060 | /* get time of bit */ | ||
1061 | current_jiffies = jiffies; | ||
1062 | do_gettimeofday(&tv); | ||
1063 | |||
1064 | /* avoid overflow with gap >1s */ | ||
1065 | if (tv.tv_sec - ir->base_time.tv_sec > 1) { | ||
1066 | gap = 200000; | ||
1067 | } else { | ||
1068 | gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + | ||
1069 | tv.tv_usec - ir->base_time.tv_usec; | ||
1070 | } | ||
1071 | |||
1072 | /* active code => add bit */ | ||
1073 | if (ir->active) { | ||
1074 | /* only if in the code (otherwise spurious IRQ or timer | ||
1075 | late) */ | ||
1076 | if (ir->last_bit < 28) { | ||
1077 | ir->last_bit = (gap - ir_rc5_remote_gap / 2) / | ||
1078 | ir_rc5_remote_gap; | ||
1079 | ir->code |= 1 << ir->last_bit; | ||
1080 | } | ||
1081 | /* starting new code */ | ||
1082 | } else { | ||
1083 | ir->active = 1; | ||
1084 | ir->code = 0; | ||
1085 | ir->base_time = tv; | ||
1086 | ir->last_bit = 0; | ||
1087 | |||
1088 | timeout = current_jiffies + (500 + 30 * HZ) / 1000; | ||
1089 | mod_timer(&ir->timer_end, timeout); | ||
1090 | } | ||
1091 | |||
1092 | return 1; | ||
1093 | } | ||
1094 | |||
1095 | /* On NEC protocol, One has 2.25 ms, and zero has 1.125 ms | ||
1096 | The first pulse (start) has 9 + 4.5 ms | ||
1097 | */ | ||
1098 | |||
1099 | static void saa7134_nec_timer(unsigned long data) | ||
1100 | { | ||
1101 | struct saa7134_dev *dev = (struct saa7134_dev *) data; | ||
1102 | struct card_ir *ir = dev->remote; | ||
1103 | |||
1104 | dprintk("Cancel key repeat\n"); | ||
1105 | |||
1106 | ir_input_nokey(ir->dev, &ir->ir); | ||
1107 | } | ||
1108 | |||
1109 | static void nec_task(unsigned long data) | ||
1110 | { | ||
1111 | struct saa7134_dev *dev = (struct saa7134_dev *) data; | ||
1112 | struct card_ir *ir; | ||
1113 | struct timeval tv; | ||
1114 | int count, pulse, oldpulse, gap; | ||
1115 | u32 ircode = 0, not_code = 0; | ||
1116 | int ngap = 0; | ||
1117 | |||
1118 | if (!data) { | ||
1119 | printk(KERN_ERR "saa713x/ir: Can't recover dev struct\n"); | ||
1120 | /* GPIO will be kept disabled */ | ||
1121 | return; | ||
1122 | } | ||
1123 | |||
1124 | ir = dev->remote; | ||
1125 | |||
1126 | /* rising SAA7134_GPIO_GPRESCAN reads the status */ | ||
1127 | saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
1128 | saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
1129 | |||
1130 | oldpulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown; | ||
1131 | pulse = oldpulse; | ||
1132 | |||
1133 | do_gettimeofday(&tv); | ||
1134 | ir->base_time = tv; | ||
1135 | |||
1136 | /* Decode NEC pulsecode. This code can take up to 76.5 ms to run. | ||
1137 | Unfortunately, using IRQ to decode pulse didn't work, since it uses | ||
1138 | a pulse train of 38KHz. This means one pulse on each 52 us | ||
1139 | */ | ||
1140 | do { | ||
1141 | /* Wait until the end of pulse/space or 5 ms */ | ||
1142 | for (count = 0; count < 500; count++) { | ||
1143 | udelay(10); | ||
1144 | /* rising SAA7134_GPIO_GPRESCAN reads the status */ | ||
1145 | saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
1146 | saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
1147 | pulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) | ||
1148 | & ir->mask_keydown; | ||
1149 | if (pulse != oldpulse) | ||
1150 | break; | ||
1151 | } | ||
1152 | |||
1153 | do_gettimeofday(&tv); | ||
1154 | gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + | ||
1155 | tv.tv_usec - ir->base_time.tv_usec; | ||
1156 | |||
1157 | if (!pulse) { | ||
1158 | /* Bit 0 has 560 us, while bit 1 has 1120 us. | ||
1159 | Do something only if bit == 1 | ||
1160 | */ | ||
1161 | if (ngap && (gap > 560 + 280)) { | ||
1162 | unsigned int shift = ngap - 1; | ||
1163 | |||
1164 | /* Address first, then command */ | ||
1165 | if (shift < 8) { | ||
1166 | shift += 8; | ||
1167 | ircode |= 1 << shift; | ||
1168 | } else if (shift < 16) { | ||
1169 | not_code |= 1 << shift; | ||
1170 | } else if (shift < 24) { | ||
1171 | shift -= 16; | ||
1172 | ircode |= 1 << shift; | ||
1173 | } else { | ||
1174 | shift -= 24; | ||
1175 | not_code |= 1 << shift; | ||
1176 | } | ||
1177 | } | ||
1178 | ngap++; | ||
1179 | } | ||
1180 | |||
1181 | |||
1182 | ir->base_time = tv; | ||
1183 | |||
1184 | /* TIMEOUT - Long pulse */ | ||
1185 | if (gap >= 5000) | ||
1186 | break; | ||
1187 | oldpulse = pulse; | ||
1188 | } while (ngap < 32); | ||
1189 | |||
1190 | if (ngap == 32) { | ||
1191 | /* FIXME: should check if not_code == ~ircode */ | ||
1192 | ir->code = ir_extract_bits(ircode, ir->mask_keycode); | ||
1193 | |||
1194 | dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n", | ||
1195 | ir->code, ircode, not_code); | ||
1196 | |||
1197 | ir_input_keydown(ir->dev, &ir->ir, ir->code); | ||
1198 | } else | ||
1199 | dprintk("Repeat last key\n"); | ||
1200 | |||
1201 | /* Keep repeating the last key */ | ||
1202 | mod_timer(&ir->timer_keyup, jiffies + msecs_to_jiffies(150)); | ||
1203 | |||
1204 | saa_setl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P); | ||
1205 | } | ||
1206 | |||
1207 | static int saa7134_nec_irq(struct saa7134_dev *dev) | ||
1208 | { | ||
1209 | struct card_ir *ir = dev->remote; | ||
1210 | |||
1211 | saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P); | ||
1212 | tasklet_schedule(&ir->tlet); | ||
1213 | |||
1214 | return 1; | ||
1215 | } | ||
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index 3e7d2fd1688f..57e646bb48b3 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c | |||
@@ -550,16 +550,16 @@ static int tvaudio_thread(void *data) | |||
550 | } else if (0 != dev->last_carrier) { | 550 | } else if (0 != dev->last_carrier) { |
551 | /* no carrier -- try last detected one as fallback */ | 551 | /* no carrier -- try last detected one as fallback */ |
552 | carrier = dev->last_carrier; | 552 | carrier = dev->last_carrier; |
553 | dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, " | 553 | dprintk("audio carrier scan failed, " |
554 | "using %d.%03d MHz [last detected]\n", | 554 | "using %d.%03d MHz [last detected]\n", |
555 | dev->name, carrier/1000, carrier%1000); | 555 | carrier/1000, carrier%1000); |
556 | 556 | ||
557 | } else { | 557 | } else { |
558 | /* no carrier + no fallback -- use default */ | 558 | /* no carrier + no fallback -- use default */ |
559 | carrier = default_carrier; | 559 | carrier = default_carrier; |
560 | dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, " | 560 | dprintk("audio carrier scan failed, " |
561 | "using %d.%03d MHz [default]\n", | 561 | "using %d.%03d MHz [default]\n", |
562 | dev->name, carrier/1000, carrier%1000); | 562 | carrier/1000, carrier%1000); |
563 | } | 563 | } |
564 | tvaudio_setcarrier(dev,carrier,carrier); | 564 | tvaudio_setcarrier(dev,carrier,carrier); |
565 | dev->automute = 0; | 565 | dev->automute = 0; |
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index f0b1573137f4..776ba2dd7f9f 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include "saa7134-reg.h" | 30 | #include "saa7134-reg.h" |
31 | #include "saa7134.h" | 31 | #include "saa7134.h" |
32 | #include <media/v4l2-common.h> | 32 | #include <media/v4l2-common.h> |
33 | #include <media/rds.h> | 33 | #include <media/saa6588.h> |
34 | 34 | ||
35 | /* ------------------------------------------------------------------ */ | 35 | /* ------------------------------------------------------------------ */ |
36 | 36 | ||
@@ -1459,7 +1459,7 @@ static int video_release(struct file *file) | |||
1459 | { | 1459 | { |
1460 | struct saa7134_fh *fh = file->private_data; | 1460 | struct saa7134_fh *fh = file->private_data; |
1461 | struct saa7134_dev *dev = fh->dev; | 1461 | struct saa7134_dev *dev = fh->dev; |
1462 | struct rds_command cmd; | 1462 | struct saa6588_command cmd; |
1463 | unsigned long flags; | 1463 | unsigned long flags; |
1464 | 1464 | ||
1465 | /* turn off overlay */ | 1465 | /* turn off overlay */ |
@@ -1494,7 +1494,7 @@ static int video_release(struct file *file) | |||
1494 | 1494 | ||
1495 | saa_call_all(dev, core, s_power, 0); | 1495 | saa_call_all(dev, core, s_power, 0); |
1496 | if (fh->radio) | 1496 | if (fh->radio) |
1497 | saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd); | 1497 | saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd); |
1498 | 1498 | ||
1499 | /* free stuff */ | 1499 | /* free stuff */ |
1500 | videobuf_mmap_free(&fh->cap); | 1500 | videobuf_mmap_free(&fh->cap); |
@@ -1520,14 +1520,14 @@ static ssize_t radio_read(struct file *file, char __user *data, | |||
1520 | { | 1520 | { |
1521 | struct saa7134_fh *fh = file->private_data; | 1521 | struct saa7134_fh *fh = file->private_data; |
1522 | struct saa7134_dev *dev = fh->dev; | 1522 | struct saa7134_dev *dev = fh->dev; |
1523 | struct rds_command cmd; | 1523 | struct saa6588_command cmd; |
1524 | 1524 | ||
1525 | cmd.block_count = count/3; | 1525 | cmd.block_count = count/3; |
1526 | cmd.buffer = data; | 1526 | cmd.buffer = data; |
1527 | cmd.instance = file; | 1527 | cmd.instance = file; |
1528 | cmd.result = -ENODEV; | 1528 | cmd.result = -ENODEV; |
1529 | 1529 | ||
1530 | saa_call_all(dev, core, ioctl, RDS_CMD_READ, &cmd); | 1530 | saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd); |
1531 | 1531 | ||
1532 | return cmd.result; | 1532 | return cmd.result; |
1533 | } | 1533 | } |
@@ -1536,12 +1536,12 @@ static unsigned int radio_poll(struct file *file, poll_table *wait) | |||
1536 | { | 1536 | { |
1537 | struct saa7134_fh *fh = file->private_data; | 1537 | struct saa7134_fh *fh = file->private_data; |
1538 | struct saa7134_dev *dev = fh->dev; | 1538 | struct saa7134_dev *dev = fh->dev; |
1539 | struct rds_command cmd; | 1539 | struct saa6588_command cmd; |
1540 | 1540 | ||
1541 | cmd.instance = file; | 1541 | cmd.instance = file; |
1542 | cmd.event_list = wait; | 1542 | cmd.event_list = wait; |
1543 | cmd.result = -ENODEV; | 1543 | cmd.result = -ENODEV; |
1544 | saa_call_all(dev, core, ioctl, RDS_CMD_POLL, &cmd); | 1544 | saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd); |
1545 | 1545 | ||
1546 | return cmd.result; | 1546 | return cmd.result; |
1547 | } | 1547 | } |
@@ -1748,7 +1748,6 @@ static int saa7134_enum_input(struct file *file, void *priv, | |||
1748 | return -EINVAL; | 1748 | return -EINVAL; |
1749 | if (NULL == card_in(dev, i->index).name) | 1749 | if (NULL == card_in(dev, i->index).name) |
1750 | return -EINVAL; | 1750 | return -EINVAL; |
1751 | memset(i, 0, sizeof(*i)); | ||
1752 | i->index = n; | 1751 | i->index = n; |
1753 | i->type = V4L2_INPUT_TYPE_CAMERA; | 1752 | i->type = V4L2_INPUT_TYPE_CAMERA; |
1754 | strcpy(i->name, card_in(dev, n).name); | 1753 | strcpy(i->name, card_in(dev, n).name); |
@@ -2211,14 +2210,6 @@ static int saa7134_overlay(struct file *file, void *f, unsigned int on) | |||
2211 | return 0; | 2210 | return 0; |
2212 | } | 2211 | } |
2213 | 2212 | ||
2214 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
2215 | static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | ||
2216 | { | ||
2217 | struct saa7134_fh *fh = file->private_data; | ||
2218 | return videobuf_cgmbuf(saa7134_queue(fh), mbuf, 8); | ||
2219 | } | ||
2220 | #endif | ||
2221 | |||
2222 | static int saa7134_reqbufs(struct file *file, void *priv, | 2213 | static int saa7134_reqbufs(struct file *file, void *priv, |
2223 | struct v4l2_requestbuffers *p) | 2214 | struct v4l2_requestbuffers *p) |
2224 | { | 2215 | { |
@@ -2456,9 +2447,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
2456 | .vidioc_streamoff = saa7134_streamoff, | 2447 | .vidioc_streamoff = saa7134_streamoff, |
2457 | .vidioc_g_tuner = saa7134_g_tuner, | 2448 | .vidioc_g_tuner = saa7134_g_tuner, |
2458 | .vidioc_s_tuner = saa7134_s_tuner, | 2449 | .vidioc_s_tuner = saa7134_s_tuner, |
2459 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
2460 | .vidiocgmbuf = vidiocgmbuf, | ||
2461 | #endif | ||
2462 | .vidioc_g_crop = saa7134_g_crop, | 2450 | .vidioc_g_crop = saa7134_g_crop, |
2463 | .vidioc_s_crop = saa7134_s_crop, | 2451 | .vidioc_s_crop = saa7134_s_crop, |
2464 | .vidioc_g_fbuf = saa7134_g_fbuf, | 2452 | .vidioc_g_fbuf = saa7134_g_fbuf, |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index d3b6a196e5dc..5b0a347b0b8f 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <media/v4l2-ioctl.h> | 37 | #include <media/v4l2-ioctl.h> |
38 | #include <media/v4l2-device.h> | 38 | #include <media/v4l2-device.h> |
39 | #include <media/tuner.h> | 39 | #include <media/tuner.h> |
40 | #include <media/ir-common.h> | 40 | #include <media/rc-core.h> |
41 | #include <media/ir-kbd-i2c.h> | 41 | #include <media/ir-kbd-i2c.h> |
42 | #include <media/videobuf-dma-sg.h> | 42 | #include <media/videobuf-dma-sg.h> |
43 | #include <sound/core.h> | 43 | #include <sound/core.h> |
@@ -119,6 +119,26 @@ struct saa7134_format { | |||
119 | unsigned int uvswap:1; | 119 | unsigned int uvswap:1; |
120 | }; | 120 | }; |
121 | 121 | ||
122 | struct saa7134_card_ir { | ||
123 | struct rc_dev *dev; | ||
124 | |||
125 | char name[32]; | ||
126 | char phys[32]; | ||
127 | unsigned users; | ||
128 | |||
129 | u32 polling; | ||
130 | u32 last_gpio; | ||
131 | u32 mask_keycode, mask_keydown, mask_keyup; | ||
132 | |||
133 | bool running; | ||
134 | bool active; | ||
135 | |||
136 | struct timer_list timer; | ||
137 | |||
138 | /* IR core raw decoding */ | ||
139 | u32 raw_decode; | ||
140 | }; | ||
141 | |||
122 | /* ----------------------------------------------------------- */ | 142 | /* ----------------------------------------------------------- */ |
123 | /* card configuration */ | 143 | /* card configuration */ |
124 | 144 | ||
@@ -305,6 +325,8 @@ struct saa7134_format { | |||
305 | #define SAA7134_BOARD_BEHOLD_A7 179 | 325 | #define SAA7134_BOARD_BEHOLD_A7 179 |
306 | #define SAA7134_BOARD_AVERMEDIA_M733A 180 | 326 | #define SAA7134_BOARD_AVERMEDIA_M733A 180 |
307 | #define SAA7134_BOARD_TECHNOTREND_BUDGET_T3000 181 | 327 | #define SAA7134_BOARD_TECHNOTREND_BUDGET_T3000 181 |
328 | #define SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG 182 | ||
329 | #define SAA7134_BOARD_VIDEOMATE_M1F 183 | ||
308 | 330 | ||
309 | #define SAA7134_MAXBOARDS 32 | 331 | #define SAA7134_MAXBOARDS 32 |
310 | #define SAA7134_INPUT_MAX 8 | 332 | #define SAA7134_INPUT_MAX 8 |
@@ -529,7 +551,7 @@ struct saa7134_dev { | |||
529 | 551 | ||
530 | /* infrared remote */ | 552 | /* infrared remote */ |
531 | int has_remote; | 553 | int has_remote; |
532 | struct card_ir *remote; | 554 | struct saa7134_card_ir *remote; |
533 | 555 | ||
534 | /* pci i/o */ | 556 | /* pci i/o */ |
535 | char name[32]; | 557 | char name[32]; |
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c index ad3bc4154176..bd86d970f4c2 100644 --- a/drivers/media/video/saa7164/saa7164-api.c +++ b/drivers/media/video/saa7164/saa7164-api.c | |||
@@ -40,9 +40,8 @@ int saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i) | |||
40 | 40 | ||
41 | ret = saa7164_cmd_send(dev, 0, GET_CUR, | 41 | ret = saa7164_cmd_send(dev, 0, GET_CUR, |
42 | GET_FW_STATUS_CONTROL, sizeof(struct tmFwInfoStruct), i); | 42 | GET_FW_STATUS_CONTROL, sizeof(struct tmFwInfoStruct), i); |
43 | if (ret != SAA_OK) { | 43 | if (ret != SAA_OK) |
44 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 44 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); |
45 | } | ||
46 | 45 | ||
47 | printk(KERN_INFO "saa7164[%d]-CPU: %d percent", dev->nr, i->CPULoad); | 46 | printk(KERN_INFO "saa7164[%d]-CPU: %d percent", dev->nr, i->CPULoad); |
48 | 47 | ||
@@ -63,14 +62,15 @@ int saa7164_api_collect_debug(struct saa7164_dev *dev) | |||
63 | 62 | ||
64 | ret = saa7164_cmd_send(dev, 0, GET_CUR, | 63 | ret = saa7164_cmd_send(dev, 0, GET_CUR, |
65 | GET_DEBUG_DATA_CONTROL, sizeof(d), &d); | 64 | GET_DEBUG_DATA_CONTROL, sizeof(d), &d); |
66 | if (ret != SAA_OK) { | 65 | if (ret != SAA_OK) |
67 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 66 | printk(KERN_ERR "%s() error, ret = 0x%x\n", |
68 | } | 67 | __func__, ret); |
69 | 68 | ||
70 | if (d.dwResult != SAA_OK) | 69 | if (d.dwResult != SAA_OK) |
71 | break; | 70 | break; |
72 | 71 | ||
73 | printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr, d.ucDebugData); | 72 | printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr, |
73 | d.ucDebugData); | ||
74 | } | 74 | } |
75 | 75 | ||
76 | return 0; | 76 | return 0; |
@@ -86,9 +86,9 @@ int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level) | |||
86 | /* Retrieve current state */ | 86 | /* Retrieve current state */ |
87 | ret = saa7164_cmd_send(dev, 0, GET_CUR, | 87 | ret = saa7164_cmd_send(dev, 0, GET_CUR, |
88 | SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl); | 88 | SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl); |
89 | if (ret != SAA_OK) { | 89 | if (ret != SAA_OK) |
90 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 90 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); |
91 | } | 91 | |
92 | dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel); | 92 | dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel); |
93 | 93 | ||
94 | lvl.dwDebugLevel = level; | 94 | lvl.dwDebugLevel = level; |
@@ -96,9 +96,8 @@ int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level) | |||
96 | /* set new state */ | 96 | /* set new state */ |
97 | ret = saa7164_cmd_send(dev, 0, SET_CUR, | 97 | ret = saa7164_cmd_send(dev, 0, SET_CUR, |
98 | SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl); | 98 | SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl); |
99 | if (ret != SAA_OK) { | 99 | if (ret != SAA_OK) |
100 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 100 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); |
101 | } | ||
102 | 101 | ||
103 | return ret; | 102 | return ret; |
104 | } | 103 | } |
@@ -152,8 +151,10 @@ int saa7164_api_set_vbi_format(struct saa7164_port *port) | |||
152 | dprintk(DBGLVL_API, "SET/COMMIT Verified\n"); | 151 | dprintk(DBGLVL_API, "SET/COMMIT Verified\n"); |
153 | 152 | ||
154 | dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint); | 153 | dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint); |
155 | dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n", rsp.bFormatIndex); | 154 | dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n", |
156 | dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n", rsp.bFrameIndex); | 155 | rsp.bFormatIndex); |
156 | dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n", | ||
157 | rsp.bFrameIndex); | ||
157 | } else | 158 | } else |
158 | printk(KERN_ERR "%s() compare failed\n", __func__); | 159 | printk(KERN_ERR "%s() compare failed\n", __func__); |
159 | } | 160 | } |
@@ -210,14 +211,17 @@ int saa7164_api_set_encoder(struct saa7164_port *port) | |||
210 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 211 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); |
211 | 212 | ||
212 | /* Establish video bitrates */ | 213 | /* Establish video bitrates */ |
213 | if (port->encoder_params.bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) | 214 | if (port->encoder_params.bitrate_mode == |
215 | V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) | ||
214 | vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_CONSTANT; | 216 | vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_CONSTANT; |
215 | else | 217 | else |
216 | vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK; | 218 | vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK; |
217 | vb.dwVideoBitRate = port->encoder_params.bitrate; | 219 | vb.dwVideoBitRate = port->encoder_params.bitrate; |
218 | vb.dwVideoBitRatePeak = port->encoder_params.bitrate_peak; | 220 | vb.dwVideoBitRatePeak = port->encoder_params.bitrate_peak; |
219 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, | 221 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, |
220 | EU_VIDEO_BIT_RATE_CONTROL, sizeof(struct tmComResEncVideoBitRate), &vb); | 222 | EU_VIDEO_BIT_RATE_CONTROL, |
223 | sizeof(struct tmComResEncVideoBitRate), | ||
224 | &vb); | ||
221 | if (ret != SAA_OK) | 225 | if (ret != SAA_OK) |
222 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 226 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); |
223 | 227 | ||
@@ -226,9 +230,12 @@ int saa7164_api_set_encoder(struct saa7164_port *port) | |||
226 | ab.dwAudioBitRate = 384000; | 230 | ab.dwAudioBitRate = 384000; |
227 | ab.dwAudioBitRatePeak = ab.dwAudioBitRate; | 231 | ab.dwAudioBitRatePeak = ab.dwAudioBitRate; |
228 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, | 232 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, |
229 | EU_AUDIO_BIT_RATE_CONTROL, sizeof(struct tmComResEncAudioBitRate), &ab); | 233 | EU_AUDIO_BIT_RATE_CONTROL, |
234 | sizeof(struct tmComResEncAudioBitRate), | ||
235 | &ab); | ||
230 | if (ret != SAA_OK) | 236 | if (ret != SAA_OK) |
231 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 237 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, |
238 | ret); | ||
232 | 239 | ||
233 | saa7164_api_set_aspect_ratio(port); | 240 | saa7164_api_set_aspect_ratio(port); |
234 | saa7164_api_set_gop_size(port); | 241 | saa7164_api_set_gop_size(port); |
@@ -244,7 +251,8 @@ int saa7164_api_get_encoder(struct saa7164_port *port) | |||
244 | struct tmComResEncVideoInputAspectRatio ar; | 251 | struct tmComResEncVideoInputAspectRatio ar; |
245 | int ret; | 252 | int ret; |
246 | 253 | ||
247 | dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, port->hwcfg.sourceid); | 254 | dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, |
255 | port->hwcfg.sourceid); | ||
248 | 256 | ||
249 | port->encoder_profile = 0; | 257 | port->encoder_profile = 0; |
250 | port->video_format = 0; | 258 | port->video_format = 0; |
@@ -257,7 +265,8 @@ int saa7164_api_get_encoder(struct saa7164_port *port) | |||
257 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 265 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); |
258 | 266 | ||
259 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, | 267 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, |
260 | EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8), &port->video_resolution); | 268 | EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8), |
269 | &port->video_resolution); | ||
261 | if (ret != SAA_OK) | 270 | if (ret != SAA_OK) |
262 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 271 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); |
263 | 272 | ||
@@ -294,13 +303,20 @@ int saa7164_api_get_encoder(struct saa7164_port *port) | |||
294 | dprintk(DBGLVL_ENC, "video_format = %d\n", port->video_format); | 303 | dprintk(DBGLVL_ENC, "video_format = %d\n", port->video_format); |
295 | dprintk(DBGLVL_ENC, "audio_format = %d\n", port->audio_format); | 304 | dprintk(DBGLVL_ENC, "audio_format = %d\n", port->audio_format); |
296 | dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution); | 305 | dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution); |
297 | dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n", v.ucVideoBitRateMode); | 306 | dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n", |
298 | dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n", v.dwVideoBitRate); | 307 | v.ucVideoBitRateMode); |
299 | dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n", v.dwVideoBitRatePeak); | 308 | dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n", |
300 | dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n", a.ucAudioBitRateMode); | 309 | v.dwVideoBitRate); |
301 | dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n", a.dwAudioBitRate); | 310 | dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n", |
302 | dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n", a.dwAudioBitRatePeak); | 311 | v.dwVideoBitRatePeak); |
303 | dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n", ar.width, ar.height); | 312 | dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n", |
313 | a.ucAudioBitRateMode); | ||
314 | dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n", | ||
315 | a.dwAudioBitRate); | ||
316 | dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n", | ||
317 | a.dwAudioBitRatePeak); | ||
318 | dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n", | ||
319 | ar.width, ar.height); | ||
304 | 320 | ||
305 | return ret; | 321 | return ret; |
306 | } | 322 | } |
@@ -439,7 +455,8 @@ int saa7164_api_set_videomux(struct saa7164_port *port) | |||
439 | 455 | ||
440 | /* Audio Mux */ | 456 | /* Audio Mux */ |
441 | ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR, | 457 | ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR, |
442 | SU_INPUT_SELECT_CONTROL, sizeof(u8), &inputs[port->mux_input - 1]); | 458 | SU_INPUT_SELECT_CONTROL, sizeof(u8), |
459 | &inputs[port->mux_input - 1]); | ||
443 | if (ret != SAA_OK) | 460 | if (ret != SAA_OK) |
444 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 461 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); |
445 | 462 | ||
@@ -492,7 +509,8 @@ int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level) | |||
492 | if (ret != SAA_OK) | 509 | if (ret != SAA_OK) |
493 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 510 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); |
494 | 511 | ||
495 | dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v); | 512 | dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, |
513 | level, min, max, v); | ||
496 | 514 | ||
497 | v = level; | 515 | v = level; |
498 | if (v < min) | 516 | if (v < min) |
@@ -517,7 +535,8 @@ int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level) | |||
517 | if (ret != SAA_OK) | 535 | if (ret != SAA_OK) |
518 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 536 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); |
519 | 537 | ||
520 | dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v); | 538 | dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, |
539 | level, min, max, v); | ||
521 | 540 | ||
522 | return ret; | 541 | return ret; |
523 | } | 542 | } |
@@ -539,7 +558,8 @@ int saa7164_api_set_audio_std(struct saa7164_port *port) | |||
539 | lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT; | 558 | lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT; |
540 | lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT; | 559 | lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT; |
541 | ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, | 560 | ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, |
542 | AUDIO_DEFAULT_CONTROL, sizeof(struct tmComResAudioDefaults), &lvl); | 561 | AUDIO_DEFAULT_CONTROL, sizeof(struct tmComResAudioDefaults), |
562 | &lvl); | ||
543 | if (ret != SAA_OK) | 563 | if (ret != SAA_OK) |
544 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 564 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); |
545 | 565 | ||
@@ -555,7 +575,8 @@ int saa7164_api_set_audio_std(struct saa7164_port *port) | |||
555 | ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR, | 575 | ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR, |
556 | TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio); | 576 | TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio); |
557 | if (ret != SAA_OK) | 577 | if (ret != SAA_OK) |
558 | printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n", __func__, ret); | 578 | printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n", |
579 | __func__, ret); | ||
559 | return ret; | 580 | return ret; |
560 | } | 581 | } |
561 | 582 | ||
@@ -575,7 +596,9 @@ int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect) | |||
575 | ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR, | 596 | ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR, |
576 | TU_STANDARD_AUTO_CONTROL, sizeof(p), &p); | 597 | TU_STANDARD_AUTO_CONTROL, sizeof(p), &p); |
577 | if (ret != SAA_OK) | 598 | if (ret != SAA_OK) |
578 | printk(KERN_ERR "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n", __func__, ret); | 599 | printk(KERN_ERR |
600 | "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n", | ||
601 | __func__, ret); | ||
579 | 602 | ||
580 | return ret; | 603 | return ret; |
581 | } | 604 | } |
@@ -646,9 +669,9 @@ int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val) | |||
646 | EXU_REGISTER_ACCESS_CONTROL, len, &buf); | 669 | EXU_REGISTER_ACCESS_CONTROL, len, &buf); |
647 | if (ret != SAA_OK) | 670 | if (ret != SAA_OK) |
648 | printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret); | 671 | printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret); |
649 | 672 | #if 0 | |
650 | //saa7164_dumphex16(dev, buf, 16); | 673 | saa7164_dumphex16(dev, buf, 16); |
651 | 674 | #endif | |
652 | return ret == SAA_OK ? 0 : -EIO; | 675 | return ret == SAA_OK ? 0 : -EIO; |
653 | } | 676 | } |
654 | 677 | ||
@@ -696,7 +719,8 @@ int saa7164_api_configure_dif(struct saa7164_port *port, u32 std) | |||
696 | } else { | 719 | } else { |
697 | /* Unknown standard, assume DTV */ | 720 | /* Unknown standard, assume DTV */ |
698 | dprintk(DBGLVL_API, " Unknown (assuming DTV)\n"); | 721 | dprintk(DBGLVL_API, " Unknown (assuming DTV)\n"); |
699 | saa7164_api_set_dif(port, 0x00, 0x80); /* Undefined Video Standard */ | 722 | /* Undefinded Video Standard */ |
723 | saa7164_api_set_dif(port, 0x00, 0x80); | ||
700 | agc_disable = 1; | 724 | agc_disable = 1; |
701 | } | 725 | } |
702 | 726 | ||
@@ -933,7 +957,7 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
933 | if (hdr->type != CS_INTERFACE) | 957 | if (hdr->type != CS_INTERFACE) |
934 | return SAA_ERR_NOT_SUPPORTED; | 958 | return SAA_ERR_NOT_SUPPORTED; |
935 | 959 | ||
936 | dprintk(DBGLVL_API, "@ 0x%x = \n", idx); | 960 | dprintk(DBGLVL_API, "@ 0x%x =\n", idx); |
937 | switch (hdr->subtype) { | 961 | switch (hdr->subtype) { |
938 | case GENERAL_REQUEST: | 962 | case GENERAL_REQUEST: |
939 | dprintk(DBGLVL_API, " GENERAL_REQUEST\n"); | 963 | dprintk(DBGLVL_API, " GENERAL_REQUEST\n"); |
@@ -1085,7 +1109,8 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
1085 | vbiport = &dev->ports[SAA7164_PORT_VBI2]; | 1109 | vbiport = &dev->ports[SAA7164_PORT_VBI2]; |
1086 | memcpy(&vbiport->hwcfg, vcoutputtermhdr, | 1110 | memcpy(&vbiport->hwcfg, vcoutputtermhdr, |
1087 | sizeof(*vcoutputtermhdr)); | 1111 | sizeof(*vcoutputtermhdr)); |
1088 | memcpy(&vbiport->vbi_fmt_ntsc, vbifmt, sizeof(*vbifmt)); | 1112 | memcpy(&vbiport->vbi_fmt_ntsc, vbifmt, |
1113 | sizeof(*vbifmt)); | ||
1089 | saa7164_api_configure_port_vbi(dev, | 1114 | saa7164_api_configure_port_vbi(dev, |
1090 | vbiport); | 1115 | vbiport); |
1091 | break; | 1116 | break; |
@@ -1134,7 +1159,9 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
1134 | encport = &dev->ports[SAA7164_PORT_ENC2]; | 1159 | encport = &dev->ports[SAA7164_PORT_ENC2]; |
1135 | memcpy(&encport->tunerunit, tunerunithdr, | 1160 | memcpy(&encport->tunerunit, tunerunithdr, |
1136 | sizeof(struct tmComResTunerDescrHeader)); | 1161 | sizeof(struct tmComResTunerDescrHeader)); |
1137 | dprintk(DBGLVL_API, " (becomes dev->enc[%d] tuner)\n", encport->nr); | 1162 | dprintk(DBGLVL_API, |
1163 | " (becomes dev->enc[%d] tuner)\n", | ||
1164 | encport->nr); | ||
1138 | } | 1165 | } |
1139 | break; | 1166 | break; |
1140 | case VC_SELECTOR_UNIT: | 1167 | case VC_SELECTOR_UNIT: |
@@ -1163,7 +1190,8 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
1163 | encport = &dev->ports[SAA7164_PORT_ENC2]; | 1190 | encport = &dev->ports[SAA7164_PORT_ENC2]; |
1164 | memcpy(&encport->vidproc, pdh, | 1191 | memcpy(&encport->vidproc, pdh, |
1165 | sizeof(struct tmComResProcDescrHeader)); | 1192 | sizeof(struct tmComResProcDescrHeader)); |
1166 | dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr); | 1193 | dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", |
1194 | encport->nr); | ||
1167 | } | 1195 | } |
1168 | break; | 1196 | break; |
1169 | case FEATURE_UNIT: | 1197 | case FEATURE_UNIT: |
@@ -1181,15 +1209,18 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
1181 | encport = &dev->ports[SAA7164_PORT_ENC2]; | 1209 | encport = &dev->ports[SAA7164_PORT_ENC2]; |
1182 | memcpy(&encport->audfeat, afd, | 1210 | memcpy(&encport->audfeat, afd, |
1183 | sizeof(struct tmComResAFeatureDescrHeader)); | 1211 | sizeof(struct tmComResAFeatureDescrHeader)); |
1184 | dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr); | 1212 | dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", |
1213 | encport->nr); | ||
1185 | break; | 1214 | break; |
1186 | case ENCODER_UNIT: | 1215 | case ENCODER_UNIT: |
1187 | edh = (struct tmComResEncoderDescrHeader *)(buf + idx); | 1216 | edh = (struct tmComResEncoderDescrHeader *)(buf + idx); |
1188 | dprintk(DBGLVL_API, " ENCODER_UNIT\n"); | 1217 | dprintk(DBGLVL_API, " ENCODER_UNIT\n"); |
1189 | dprintk(DBGLVL_API, " subtype = 0x%x\n", edh->subtype); | 1218 | dprintk(DBGLVL_API, " subtype = 0x%x\n", edh->subtype); |
1190 | dprintk(DBGLVL_API, " unitid = 0x%x\n", edh->unitid); | 1219 | dprintk(DBGLVL_API, " unitid = 0x%x\n", edh->unitid); |
1191 | dprintk(DBGLVL_API, " vsourceid = 0x%x\n", edh->vsourceid); | 1220 | dprintk(DBGLVL_API, " vsourceid = 0x%x\n", |
1192 | dprintk(DBGLVL_API, " asourceid = 0x%x\n", edh->asourceid); | 1221 | edh->vsourceid); |
1222 | dprintk(DBGLVL_API, " asourceid = 0x%x\n", | ||
1223 | edh->asourceid); | ||
1193 | dprintk(DBGLVL_API, " iunit = 0x%x\n", edh->iunit); | 1224 | dprintk(DBGLVL_API, " iunit = 0x%x\n", edh->iunit); |
1194 | if (edh->iunit == edh->unitid) { | 1225 | if (edh->iunit == edh->unitid) { |
1195 | if (currpath == 1) | 1226 | if (currpath == 1) |
@@ -1198,7 +1229,9 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
1198 | encport = &dev->ports[SAA7164_PORT_ENC2]; | 1229 | encport = &dev->ports[SAA7164_PORT_ENC2]; |
1199 | memcpy(&encport->encunit, edh, | 1230 | memcpy(&encport->encunit, edh, |
1200 | sizeof(struct tmComResEncoderDescrHeader)); | 1231 | sizeof(struct tmComResEncoderDescrHeader)); |
1201 | dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr); | 1232 | dprintk(DBGLVL_API, |
1233 | " (becomes dev->enc[%d])\n", | ||
1234 | encport->nr); | ||
1202 | } | 1235 | } |
1203 | break; | 1236 | break; |
1204 | case EXTENSION_UNIT: | 1237 | case EXTENSION_UNIT: |
@@ -1262,7 +1295,9 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
1262 | encport = &dev->ports[SAA7164_PORT_ENC2]; | 1295 | encport = &dev->ports[SAA7164_PORT_ENC2]; |
1263 | memcpy(&encport->ifunit, exthdr, | 1296 | memcpy(&encport->ifunit, exthdr, |
1264 | sizeof(struct tmComResExtDevDescrHeader)); | 1297 | sizeof(struct tmComResExtDevDescrHeader)); |
1265 | dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr); | 1298 | dprintk(DBGLVL_API, |
1299 | " (becomes dev->enc[%d])\n", | ||
1300 | encport->nr); | ||
1266 | } | 1301 | } |
1267 | break; | 1302 | break; |
1268 | case PVC_INFRARED_UNIT: | 1303 | case PVC_INFRARED_UNIT: |
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c index 7230912acc7d..ddd25211c9e8 100644 --- a/drivers/media/video/saa7164/saa7164-buffer.c +++ b/drivers/media/video/saa7164/saa7164-buffer.c | |||
@@ -24,46 +24,46 @@ | |||
24 | #include "saa7164.h" | 24 | #include "saa7164.h" |
25 | 25 | ||
26 | /* The PCI address space for buffer handling looks like this: | 26 | /* The PCI address space for buffer handling looks like this: |
27 | 27 | * | |
28 | +-u32 wide-------------+ | 28 | * +-u32 wide-------------+ |
29 | | + | 29 | * | + |
30 | +-u64 wide------------------------------------+ | 30 | * +-u64 wide------------------------------------+ |
31 | + + | 31 | * + + |
32 | +----------------------+ | 32 | * +----------------------+ |
33 | | CurrentBufferPtr + Pointer to current PCI buffer >-+ | 33 | * | CurrentBufferPtr + Pointer to current PCI buffer >-+ |
34 | +----------------------+ | | 34 | * +----------------------+ | |
35 | | Unused + | | 35 | * | Unused + | |
36 | +----------------------+ | | 36 | * +----------------------+ | |
37 | | Pitch + = 188 (bytes) | | 37 | * | Pitch + = 188 (bytes) | |
38 | +----------------------+ | | 38 | * +----------------------+ | |
39 | | PCI buffer size + = pitch * number of lines (312) | | 39 | * | PCI buffer size + = pitch * number of lines (312) | |
40 | +----------------------+ | | 40 | * +----------------------+ | |
41 | |0| Buf0 Write Offset + | | 41 | * |0| Buf0 Write Offset + | |
42 | +----------------------+ v | 42 | * +----------------------+ v |
43 | |1| Buf1 Write Offset + | | 43 | * |1| Buf1 Write Offset + | |
44 | +----------------------+ | | 44 | * +----------------------+ | |
45 | |2| Buf2 Write Offset + | | 45 | * |2| Buf2 Write Offset + | |
46 | +----------------------+ | | 46 | * +----------------------+ | |
47 | |3| Buf3 Write Offset + | | 47 | * |3| Buf3 Write Offset + | |
48 | +----------------------+ | | 48 | * +----------------------+ | |
49 | ... More write offsets | | 49 | * ... More write offsets | |
50 | +---------------------------------------------+ | | 50 | * +---------------------------------------------+ | |
51 | +0| set of ptrs to PCI pagetables + | | 51 | * +0| set of ptrs to PCI pagetables + | |
52 | +---------------------------------------------+ | | 52 | * +---------------------------------------------+ | |
53 | +1| set of ptrs to PCI pagetables + <--------+ | 53 | * +1| set of ptrs to PCI pagetables + <--------+ |
54 | +---------------------------------------------+ | 54 | * +---------------------------------------------+ |
55 | +2| set of ptrs to PCI pagetables + | 55 | * +2| set of ptrs to PCI pagetables + |
56 | +---------------------------------------------+ | 56 | * +---------------------------------------------+ |
57 | +3| set of ptrs to PCI pagetables + >--+ | 57 | * +3| set of ptrs to PCI pagetables + >--+ |
58 | +---------------------------------------------+ | | 58 | * +---------------------------------------------+ | |
59 | ... More buffer pointers | +----------------+ | 59 | * ... More buffer pointers | +----------------+ |
60 | +->| pt[0] TS data | | 60 | * +->| pt[0] TS data | |
61 | | +----------------+ | 61 | * | +----------------+ |
62 | | | 62 | * | |
63 | | +----------------+ | 63 | * | +----------------+ |
64 | +->| pt[1] TS data | | 64 | * +->| pt[1] TS data | |
65 | | +----------------+ | 65 | * | +----------------+ |
66 | | etc | 66 | * | etc |
67 | */ | 67 | */ |
68 | 68 | ||
69 | void saa7164_buffer_display(struct saa7164_buffer *buf) | 69 | void saa7164_buffer_display(struct saa7164_buffer *buf) |
@@ -283,7 +283,8 @@ int saa7164_buffer_cfg_port(struct saa7164_port *port) | |||
283 | return 0; | 283 | return 0; |
284 | } | 284 | } |
285 | 285 | ||
286 | struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev, u32 len) | 286 | struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev, |
287 | u32 len) | ||
287 | { | 288 | { |
288 | struct saa7164_user_buffer *buf; | 289 | struct saa7164_user_buffer *buf; |
289 | 290 | ||
@@ -313,12 +314,9 @@ void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf) | |||
313 | if (!buf) | 314 | if (!buf) |
314 | return; | 315 | return; |
315 | 316 | ||
316 | if (buf->data) { | 317 | kfree(buf->data); |
317 | kfree(buf->data); | 318 | buf->data = 0; |
318 | buf->data = 0; | ||
319 | } | ||
320 | 319 | ||
321 | if (buf) | 320 | kfree(buf); |
322 | kfree(buf); | ||
323 | } | 321 | } |
324 | 322 | ||
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c index 30d5283da41e..b2b0d97101d0 100644 --- a/drivers/media/video/saa7164/saa7164-bus.c +++ b/drivers/media/video/saa7164/saa7164-bus.c | |||
@@ -43,7 +43,8 @@ int saa7164_bus_setup(struct saa7164_dev *dev) | |||
43 | 43 | ||
44 | b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE; | 44 | b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE; |
45 | 45 | ||
46 | b->m_dwSetWritePos = ((u32)dev->intfdesc.BARLocation) + (2 * sizeof(u64)); | 46 | b->m_dwSetWritePos = ((u32)dev->intfdesc.BARLocation) + |
47 | (2 * sizeof(u64)); | ||
47 | b->m_dwSetReadPos = b->m_dwSetWritePos + (1 * sizeof(u32)); | 48 | b->m_dwSetReadPos = b->m_dwSetWritePos + (1 * sizeof(u32)); |
48 | 49 | ||
49 | b->m_dwGetWritePos = b->m_dwSetWritePos + (2 * sizeof(u32)); | 50 | b->m_dwGetWritePos = b->m_dwSetWritePos + (2 * sizeof(u32)); |
@@ -105,7 +106,8 @@ void saa7164_bus_verify(struct saa7164_dev *dev) | |||
105 | } | 106 | } |
106 | } | 107 | } |
107 | 108 | ||
108 | void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m, void *buf) | 109 | void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m, |
110 | void *buf) | ||
109 | { | 111 | { |
110 | dprintk(DBGLVL_BUS, "Dumping msg structure:\n"); | 112 | dprintk(DBGLVL_BUS, "Dumping msg structure:\n"); |
111 | dprintk(DBGLVL_BUS, " .id = %d\n", m->id); | 113 | dprintk(DBGLVL_BUS, " .id = %d\n", m->id); |
@@ -129,7 +131,8 @@ void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m, void * | |||
129 | * SAA_OK The function executed successfully. | 131 | * SAA_OK The function executed successfully. |
130 | * < 0 One or more members are not initialized. | 132 | * < 0 One or more members are not initialized. |
131 | */ | 133 | */ |
132 | int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf) | 134 | int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, |
135 | void *buf) | ||
133 | { | 136 | { |
134 | struct tmComResBusInfo *bus = &dev->bus; | 137 | struct tmComResBusInfo *bus = &dev->bus; |
135 | u32 bytes_to_write, free_write_space, timeout, curr_srp, curr_swp; | 138 | u32 bytes_to_write, free_write_space, timeout, curr_srp, curr_swp; |
@@ -294,14 +297,15 @@ out: | |||
294 | /* | 297 | /* |
295 | * Receive a command or a response from the bus. The implementation does not | 298 | * Receive a command or a response from the bus. The implementation does not |
296 | * know if it is a command or a response it simply dequeues the data, | 299 | * know if it is a command or a response it simply dequeues the data, |
297 | * depending on the bus information given in the struct tmComResBusInfo structure. | 300 | * depending on the bus information given in the struct tmComResBusInfo |
301 | * structure. | ||
298 | * | 302 | * |
299 | * Return Value: | 303 | * Return Value: |
300 | * 0 The function executed successfully. | 304 | * 0 The function executed successfully. |
301 | * < 0 One or more members are not initialized. | 305 | * < 0 One or more members are not initialized. |
302 | */ | 306 | */ |
303 | int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf, | 307 | int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, |
304 | int peekonly) | 308 | void *buf, int peekonly) |
305 | { | 309 | { |
306 | struct tmComResBusInfo *bus = &dev->bus; | 310 | struct tmComResBusInfo *bus = &dev->bus; |
307 | u32 bytes_to_read, write_distance, curr_grp, curr_gwp, | 311 | u32 bytes_to_read, write_distance, curr_grp, curr_gwp, |
diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c index 4cb634e952a6..69822a4e7275 100644 --- a/drivers/media/video/saa7164/saa7164-cards.c +++ b/drivers/media/video/saa7164/saa7164-cards.c | |||
@@ -482,7 +482,7 @@ void saa7164_gpio_setup(struct saa7164_dev *dev) | |||
482 | saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2); | 482 | saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2); |
483 | saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3); | 483 | saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3); |
484 | 484 | ||
485 | msleep(10); | 485 | msleep(20); |
486 | 486 | ||
487 | saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2); | 487 | saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2); |
488 | saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3); | 488 | saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3); |
diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c index 301a9e302f45..a97ae17b36c2 100644 --- a/drivers/media/video/saa7164/saa7164-cmd.c +++ b/drivers/media/video/saa7164/saa7164-cmd.c | |||
@@ -122,8 +122,8 @@ int saa7164_irq_dequeue(struct saa7164_dev *dev) | |||
122 | return ret; | 122 | return ret; |
123 | } | 123 | } |
124 | 124 | ||
125 | /* It's unlikely to have more than 4 or 5 pending messages, ensure we exit | 125 | /* It's unlikely to have more than 4 or 5 pending messages, |
126 | * at some point regardles. | 126 | * ensure we exit at some point regardless. |
127 | */ | 127 | */ |
128 | } while (i++ < 32); | 128 | } while (i++ < 32); |
129 | 129 | ||
@@ -186,7 +186,8 @@ int saa7164_cmd_dequeue(struct saa7164_dev *dev) | |||
186 | return SAA_OK; | 186 | return SAA_OK; |
187 | } | 187 | } |
188 | 188 | ||
189 | int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf) | 189 | int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo *msg, |
190 | void *buf) | ||
190 | { | 191 | { |
191 | struct tmComResBusInfo *bus = &dev->bus; | 192 | struct tmComResBusInfo *bus = &dev->bus; |
192 | u8 cmd_sent; | 193 | u8 cmd_sent; |
@@ -292,7 +293,8 @@ int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno) | |||
292 | * We typically are signalled in < 50ms but it can | 293 | * We typically are signalled in < 50ms but it can |
293 | * take MUCH longer. | 294 | * take MUCH longer. |
294 | */ | 295 | */ |
295 | wait_event_timeout(*q, dev->cmds[seqno].signalled, (HZ * waitsecs)); | 296 | wait_event_timeout(*q, dev->cmds[seqno].signalled, |
297 | (HZ * waitsecs)); | ||
296 | r = time_before(jiffies, stamp + (HZ * waitsecs)); | 298 | r = time_before(jiffies, stamp + (HZ * waitsecs)); |
297 | if (r) | 299 | if (r) |
298 | ret = SAA_OK; | 300 | ret = SAA_OK; |
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c index e1bac5051460..d6bf3f82cc34 100644 --- a/drivers/media/video/saa7164/saa7164-core.c +++ b/drivers/media/video/saa7164/saa7164-core.c | |||
@@ -40,12 +40,12 @@ MODULE_AUTHOR("Steven Toth <stoth@kernellabs.com>"); | |||
40 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
41 | 41 | ||
42 | /* | 42 | /* |
43 | 1 Basic | 43 | * 1 Basic |
44 | 2 | 44 | * 2 |
45 | 4 i2c | 45 | * 4 i2c |
46 | 8 api | 46 | * 8 api |
47 | 16 cmd | 47 | * 16 cmd |
48 | 32 bus | 48 | * 32 bus |
49 | */ | 49 | */ |
50 | 50 | ||
51 | unsigned int saa_debug; | 51 | unsigned int saa_debug; |
@@ -82,7 +82,8 @@ MODULE_PARM_DESC(crc_checking, "enable crc sanity checking on buffers"); | |||
82 | 82 | ||
83 | unsigned int guard_checking = 1; | 83 | unsigned int guard_checking = 1; |
84 | module_param(guard_checking, int, 0644); | 84 | module_param(guard_checking, int, 0644); |
85 | MODULE_PARM_DESC(guard_checking, "enable dma sanity checking for buffer overruns"); | 85 | MODULE_PARM_DESC(guard_checking, |
86 | "enable dma sanity checking for buffer overruns"); | ||
86 | 87 | ||
87 | static unsigned int saa7164_devcount; | 88 | static unsigned int saa7164_devcount; |
88 | 89 | ||
@@ -123,7 +124,9 @@ static void saa7164_pack_verifier(struct saa7164_buffer *buf) | |||
123 | if ((*(p + i + 0) != 0x00) || (*(p + i + 1) != 0x00) || | 124 | if ((*(p + i + 0) != 0x00) || (*(p + i + 1) != 0x00) || |
124 | (*(p + i + 2) != 0x01) || (*(p + i + 3) != 0xBA)) { | 125 | (*(p + i + 2) != 0x01) || (*(p + i + 3) != 0xBA)) { |
125 | printk(KERN_ERR "No pack at 0x%x\n", i); | 126 | printk(KERN_ERR "No pack at 0x%x\n", i); |
126 | // saa7164_dumphex16FF(buf->port->dev, (p + i), 32); | 127 | #if 0 |
128 | saa7164_dumphex16FF(buf->port->dev, (p + i), 32); | ||
129 | #endif | ||
127 | } | 130 | } |
128 | } | 131 | } |
129 | } | 132 | } |
@@ -199,19 +202,16 @@ static void saa7164_histogram_reset(struct saa7164_histogram *hg, char *name) | |||
199 | strcpy(hg->name, name); | 202 | strcpy(hg->name, name); |
200 | 203 | ||
201 | /* First 30ms x 1ms */ | 204 | /* First 30ms x 1ms */ |
202 | for (i = 0; i < 30; i++) { | 205 | for (i = 0; i < 30; i++) |
203 | hg->counter1[0 + i].val = i; | 206 | hg->counter1[0 + i].val = i; |
204 | } | ||
205 | 207 | ||
206 | /* 30 - 200ms x 10ms */ | 208 | /* 30 - 200ms x 10ms */ |
207 | for (i = 0; i < 18; i++) { | 209 | for (i = 0; i < 18; i++) |
208 | hg->counter1[30 + i].val = 30 + (i * 10); | 210 | hg->counter1[30 + i].val = 30 + (i * 10); |
209 | } | ||
210 | 211 | ||
211 | /* 200 - 2000ms x 100ms */ | 212 | /* 200 - 2000ms x 100ms */ |
212 | for (i = 0; i < 15; i++) { | 213 | for (i = 0; i < 15; i++) |
213 | hg->counter1[48 + i].val = 200 + (i * 200); | 214 | hg->counter1[48 + i].val = 200 + (i * 200); |
214 | } | ||
215 | 215 | ||
216 | /* Catch all massive value (2secs) */ | 216 | /* Catch all massive value (2secs) */ |
217 | hg->counter1[55].val = 2000; | 217 | hg->counter1[55].val = 2000; |
@@ -315,7 +315,9 @@ static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr) | |||
315 | (*(p + buf->actual_size + 0x13) != 0xff)) { | 315 | (*(p + buf->actual_size + 0x13) != 0xff)) { |
316 | printk(KERN_ERR "%s() buf %p guard buffer breach\n", | 316 | printk(KERN_ERR "%s() buf %p guard buffer breach\n", |
317 | __func__, buf); | 317 | __func__, buf); |
318 | // saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64); | 318 | #if 0 |
319 | saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64); | ||
320 | #endif | ||
319 | } | 321 | } |
320 | } | 322 | } |
321 | 323 | ||
@@ -961,9 +963,7 @@ static int saa7164_port_init(struct saa7164_dev *dev, int portnr) | |||
961 | 963 | ||
962 | /* We need a deferred interrupt handler for cmd handling */ | 964 | /* We need a deferred interrupt handler for cmd handling */ |
963 | INIT_WORK(&port->workenc, saa7164_work_enchandler); | 965 | INIT_WORK(&port->workenc, saa7164_work_enchandler); |
964 | } | 966 | } else if ((portnr == SAA7164_PORT_VBI1) || (portnr == SAA7164_PORT_VBI2)) { |
965 | else | ||
966 | if ((portnr == SAA7164_PORT_VBI1) || (portnr == SAA7164_PORT_VBI2)) { | ||
967 | port->type = SAA7164_MPEG_VBI; | 967 | port->type = SAA7164_MPEG_VBI; |
968 | 968 | ||
969 | /* We need a deferred interrupt handler for cmd handling */ | 969 | /* We need a deferred interrupt handler for cmd handling */ |
@@ -1001,7 +1001,7 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) | |||
1001 | atomic_inc(&dev->refcount); | 1001 | atomic_inc(&dev->refcount); |
1002 | dev->nr = saa7164_devcount++; | 1002 | dev->nr = saa7164_devcount++; |
1003 | 1003 | ||
1004 | sprintf(dev->name, "saa7164[%d]", dev->nr); | 1004 | snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); |
1005 | 1005 | ||
1006 | mutex_lock(&devlist); | 1006 | mutex_lock(&devlist); |
1007 | list_add_tail(&dev->devlist, &saa7164_devlist); | 1007 | list_add_tail(&dev->devlist, &saa7164_devlist); |
@@ -1169,7 +1169,7 @@ static int saa7164_proc_open(struct inode *inode, struct file *filp) | |||
1169 | return single_open(filp, saa7164_proc_show, NULL); | 1169 | return single_open(filp, saa7164_proc_show, NULL); |
1170 | } | 1170 | } |
1171 | 1171 | ||
1172 | static struct file_operations saa7164_proc_fops = { | 1172 | static const struct file_operations saa7164_proc_fops = { |
1173 | .open = saa7164_proc_open, | 1173 | .open = saa7164_proc_open, |
1174 | .read = seq_read, | 1174 | .read = seq_read, |
1175 | .llseek = seq_lseek, | 1175 | .llseek = seq_lseek, |
diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c index cbb53d0ee979..1838408cd5cb 100644 --- a/drivers/media/video/saa7164/saa7164-encoder.c +++ b/drivers/media/video/saa7164/saa7164-encoder.c | |||
@@ -125,16 +125,22 @@ static int saa7164_encoder_buffers_alloc(struct saa7164_port *port) | |||
125 | 125 | ||
126 | dprintk(DBGLVL_ENC, "%s()\n", __func__); | 126 | dprintk(DBGLVL_ENC, "%s()\n", __func__); |
127 | 127 | ||
128 | if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) { | 128 | if (port->encoder_params.stream_type == |
129 | dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_PS\n", __func__); | 129 | V4L2_MPEG_STREAM_TYPE_MPEG2_PS) { |
130 | dprintk(DBGLVL_ENC, | ||
131 | "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_PS\n", | ||
132 | __func__); | ||
130 | params->samplesperline = 128; | 133 | params->samplesperline = 128; |
131 | params->numberoflines = 256; | 134 | params->numberoflines = 256; |
132 | params->pitch = 128; | 135 | params->pitch = 128; |
133 | params->numpagetables = 2 + | 136 | params->numpagetables = 2 + |
134 | ((SAA7164_PS_NUMBER_OF_LINES * 128) / PAGE_SIZE); | 137 | ((SAA7164_PS_NUMBER_OF_LINES * 128) / PAGE_SIZE); |
135 | } else | 138 | } else |
136 | if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) { | 139 | if (port->encoder_params.stream_type == |
137 | dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_TS\n", __func__); | 140 | V4L2_MPEG_STREAM_TYPE_MPEG2_TS) { |
141 | dprintk(DBGLVL_ENC, | ||
142 | "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_TS\n", | ||
143 | __func__); | ||
138 | params->samplesperline = 188; | 144 | params->samplesperline = 188; |
139 | params->numberoflines = 312; | 145 | params->numberoflines = 312; |
140 | params->pitch = 188; | 146 | params->pitch = 188; |
@@ -826,7 +832,8 @@ static int fill_queryctrl(struct saa7164_encoder_params *params, | |||
826 | return v4l2_ctrl_query_fill(c, 1, 255, 1, 15); | 832 | return v4l2_ctrl_query_fill(c, 1, 255, 1, 15); |
827 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | 833 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: |
828 | return v4l2_ctrl_query_fill(c, | 834 | return v4l2_ctrl_query_fill(c, |
829 | V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, | 835 | V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, |
836 | V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, | ||
830 | 1, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); | 837 | 1, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); |
831 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: | 838 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: |
832 | return v4l2_ctrl_query_fill(c, | 839 | return v4l2_ctrl_query_fill(c, |
@@ -1113,7 +1120,9 @@ struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port) | |||
1113 | if (crc_checking) { | 1120 | if (crc_checking) { |
1114 | crc = crc32(0, ubuf->data, ubuf->actual_size); | 1121 | crc = crc32(0, ubuf->data, ubuf->actual_size); |
1115 | if (crc != ubuf->crc) { | 1122 | if (crc != ubuf->crc) { |
1116 | printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__, | 1123 | printk(KERN_ERR |
1124 | "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", | ||
1125 | __func__, | ||
1117 | ubuf, ubuf->crc, crc); | 1126 | ubuf, ubuf->crc, crc); |
1118 | } | 1127 | } |
1119 | } | 1128 | } |
@@ -1201,9 +1210,8 @@ static ssize_t fops_read(struct file *file, char __user *buffer, | |||
1201 | buffer += cnt; | 1210 | buffer += cnt; |
1202 | ret += cnt; | 1211 | ret += cnt; |
1203 | 1212 | ||
1204 | if (ubuf->pos > ubuf->actual_size) { | 1213 | if (ubuf->pos > ubuf->actual_size) |
1205 | printk(KERN_ERR "read() pos > actual, huh?\n"); | 1214 | printk(KERN_ERR "read() pos > actual, huh?\n"); |
1206 | } | ||
1207 | 1215 | ||
1208 | if (ubuf->pos == ubuf->actual_size) { | 1216 | if (ubuf->pos == ubuf->actual_size) { |
1209 | 1217 | ||
@@ -1227,16 +1235,16 @@ static ssize_t fops_read(struct file *file, char __user *buffer, | |||
1227 | } | 1235 | } |
1228 | } | 1236 | } |
1229 | err: | 1237 | err: |
1230 | if (!ret && !ubuf) { | 1238 | if (!ret && !ubuf) |
1231 | ret = -EAGAIN; | 1239 | ret = -EAGAIN; |
1232 | } | ||
1233 | 1240 | ||
1234 | return ret; | 1241 | return ret; |
1235 | } | 1242 | } |
1236 | 1243 | ||
1237 | static unsigned int fops_poll(struct file *file, poll_table *wait) | 1244 | static unsigned int fops_poll(struct file *file, poll_table *wait) |
1238 | { | 1245 | { |
1239 | struct saa7164_encoder_fh *fh = (struct saa7164_encoder_fh *)file->private_data; | 1246 | struct saa7164_encoder_fh *fh = |
1247 | (struct saa7164_encoder_fh *)file->private_data; | ||
1240 | struct saa7164_port *port = fh->port; | 1248 | struct saa7164_port *port = fh->port; |
1241 | struct saa7164_user_buffer *ubuf; | 1249 | struct saa7164_user_buffer *ubuf; |
1242 | unsigned int mask = 0; | 1250 | unsigned int mask = 0; |
@@ -1249,9 +1257,8 @@ static unsigned int fops_poll(struct file *file, poll_table *wait) | |||
1249 | saa7164_histogram_update(&port->poll_interval, | 1257 | saa7164_histogram_update(&port->poll_interval, |
1250 | port->last_poll_msecs_diff); | 1258 | port->last_poll_msecs_diff); |
1251 | 1259 | ||
1252 | if (!video_is_registered(port->v4l_device)) { | 1260 | if (!video_is_registered(port->v4l_device)) |
1253 | return -EIO; | 1261 | return -EIO; |
1254 | } | ||
1255 | 1262 | ||
1256 | if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { | 1263 | if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { |
1257 | if (atomic_inc_return(&port->v4l_reader_count) == 1) { | 1264 | if (atomic_inc_return(&port->v4l_reader_count) == 1) { |
diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c index 484533c32bb1..ebed6f786a23 100644 --- a/drivers/media/video/saa7164/saa7164-fw.c +++ b/drivers/media/video/saa7164/saa7164-fw.c | |||
@@ -178,7 +178,7 @@ int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize, | |||
178 | goto out; | 178 | goto out; |
179 | } | 179 | } |
180 | 180 | ||
181 | msleep(10); | 181 | msleep(10); /* Checkpatch throws a < 20ms warning */ |
182 | if (timeout++ > 60) | 182 | if (timeout++ > 60) |
183 | break; | 183 | break; |
184 | } | 184 | } |
@@ -235,7 +235,7 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev) | |||
235 | while (err_flags != SAA_DEVICE_IMAGE_BOOTING) { | 235 | while (err_flags != SAA_DEVICE_IMAGE_BOOTING) { |
236 | dprintk(DBGLVL_FW, "%s() err_flags = %x\n", | 236 | dprintk(DBGLVL_FW, "%s() err_flags = %x\n", |
237 | __func__, err_flags); | 237 | __func__, err_flags); |
238 | msleep(10); | 238 | msleep(10); /* Checkpatch throws a < 20ms warning */ |
239 | 239 | ||
240 | if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) { | 240 | if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) { |
241 | printk(KERN_ERR "%s() firmware corrupt\n", | 241 | printk(KERN_ERR "%s() firmware corrupt\n", |
@@ -294,7 +294,7 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev) | |||
294 | while (err_flags != SAA_DEVICE_IMAGE_BOOTING) { | 294 | while (err_flags != SAA_DEVICE_IMAGE_BOOTING) { |
295 | dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n", | 295 | dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n", |
296 | __func__, err_flags); | 296 | __func__, err_flags); |
297 | msleep(10); | 297 | msleep(10); /* Checkpatch throws a < 20ms warning */ |
298 | 298 | ||
299 | if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) { | 299 | if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) { |
300 | printk(KERN_ERR | 300 | printk(KERN_ERR |
@@ -365,7 +365,7 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev) | |||
365 | 365 | ||
366 | first_timeout = SAA_DEVICE_TIMEOUT; | 366 | first_timeout = SAA_DEVICE_TIMEOUT; |
367 | while (first_timeout) { | 367 | while (first_timeout) { |
368 | msleep(10); | 368 | msleep(10); /* Checkpatch throws a < 20ms warning */ |
369 | 369 | ||
370 | version = | 370 | version = |
371 | saa7164_getcurrentfirmwareversion(dev); | 371 | saa7164_getcurrentfirmwareversion(dev); |
@@ -608,8 +608,6 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev) | |||
608 | ret = 0; | 608 | ret = 0; |
609 | 609 | ||
610 | out: | 610 | out: |
611 | if (fw) | 611 | release_firmware(fw); |
612 | release_firmware(fw); | ||
613 | |||
614 | return ret; | 612 | return ret; |
615 | } | 613 | } |
diff --git a/drivers/media/video/saa7164/saa7164-i2c.c b/drivers/media/video/saa7164/saa7164-i2c.c index b5167d33650a..26148f76cba2 100644 --- a/drivers/media/video/saa7164/saa7164-i2c.c +++ b/drivers/media/video/saa7164/saa7164-i2c.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/moduleparam.h> | 23 | #include <linux/moduleparam.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <asm/io.h> | 26 | #include <linux/io.h> |
27 | 27 | ||
28 | #include "saa7164.h" | 28 | #include "saa7164.h" |
29 | 29 | ||
@@ -65,7 +65,7 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) | |||
65 | } | 65 | } |
66 | return num; | 66 | return num; |
67 | 67 | ||
68 | err: | 68 | err: |
69 | return retval; | 69 | return retval; |
70 | } | 70 | } |
71 | 71 | ||
diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c index 323c7cdca37b..8abbe6d661e4 100644 --- a/drivers/media/video/saa7164/saa7164-vbi.c +++ b/drivers/media/video/saa7164/saa7164-vbi.c | |||
@@ -51,11 +51,15 @@ static void saa7164_vbi_configure(struct saa7164_port *port) | |||
51 | /* Set up the DIF (enable it) for analog mode by default */ | 51 | /* Set up the DIF (enable it) for analog mode by default */ |
52 | saa7164_api_initialize_dif(port); | 52 | saa7164_api_initialize_dif(port); |
53 | 53 | ||
54 | // /* Configure the correct video standard */ | 54 | /* Configure the correct video standard */ |
55 | // saa7164_api_configure_dif(port, port->encodernorm.id); | 55 | #if 0 |
56 | saa7164_api_configure_dif(port, port->encodernorm.id); | ||
57 | #endif | ||
56 | 58 | ||
57 | // /* Ensure the audio decoder is correct configured */ | 59 | #if 0 |
58 | // saa7164_api_set_audio_std(port); | 60 | /* Ensure the audio decoder is correct configured */ |
61 | saa7164_api_set_audio_std(port); | ||
62 | #endif | ||
59 | dprintk(DBGLVL_VBI, "%s() ends\n", __func__); | 63 | dprintk(DBGLVL_VBI, "%s() ends\n", __func__); |
60 | } | 64 | } |
61 | 65 | ||
@@ -919,8 +923,10 @@ static int saa7164_vbi_start_streaming(struct saa7164_port *port) | |||
919 | saa7164_vbi_buffers_alloc(port); | 923 | saa7164_vbi_buffers_alloc(port); |
920 | 924 | ||
921 | /* Configure the encoder with any cache values */ | 925 | /* Configure the encoder with any cache values */ |
922 | // saa7164_api_set_encoder(port); | 926 | #if 0 |
923 | // saa7164_api_get_encoder(port); | 927 | saa7164_api_set_encoder(port); |
928 | saa7164_api_get_encoder(port); | ||
929 | #endif | ||
924 | 930 | ||
925 | /* Place the empty buffers on the hardware */ | 931 | /* Place the empty buffers on the hardware */ |
926 | saa7164_buffer_cfg_port(port); | 932 | saa7164_buffer_cfg_port(port); |
@@ -1060,7 +1066,8 @@ struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port) | |||
1060 | if (crc_checking) { | 1066 | if (crc_checking) { |
1061 | crc = crc32(0, ubuf->data, ubuf->actual_size); | 1067 | crc = crc32(0, ubuf->data, ubuf->actual_size); |
1062 | if (crc != ubuf->crc) { | 1068 | if (crc != ubuf->crc) { |
1063 | printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__, | 1069 | printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", |
1070 | __func__, | ||
1064 | ubuf, ubuf->crc, crc); | 1071 | ubuf, ubuf->crc, crc); |
1065 | } | 1072 | } |
1066 | } | 1073 | } |
@@ -1148,9 +1155,8 @@ static ssize_t fops_read(struct file *file, char __user *buffer, | |||
1148 | buffer += cnt; | 1155 | buffer += cnt; |
1149 | ret += cnt; | 1156 | ret += cnt; |
1150 | 1157 | ||
1151 | if (ubuf->pos > ubuf->actual_size) { | 1158 | if (ubuf->pos > ubuf->actual_size) |
1152 | printk(KERN_ERR "read() pos > actual, huh?\n"); | 1159 | printk(KERN_ERR "read() pos > actual, huh?\n"); |
1153 | } | ||
1154 | 1160 | ||
1155 | if (ubuf->pos == ubuf->actual_size) { | 1161 | if (ubuf->pos == ubuf->actual_size) { |
1156 | 1162 | ||
@@ -1197,9 +1203,8 @@ static unsigned int fops_poll(struct file *file, poll_table *wait) | |||
1197 | saa7164_histogram_update(&port->poll_interval, | 1203 | saa7164_histogram_update(&port->poll_interval, |
1198 | port->last_poll_msecs_diff); | 1204 | port->last_poll_msecs_diff); |
1199 | 1205 | ||
1200 | if (!video_is_registered(port->v4l_device)) { | 1206 | if (!video_is_registered(port->v4l_device)) |
1201 | return -EIO; | 1207 | return -EIO; |
1202 | } | ||
1203 | 1208 | ||
1204 | if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { | 1209 | if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { |
1205 | if (atomic_inc_return(&port->v4l_reader_count) == 1) { | 1210 | if (atomic_inc_return(&port->v4l_reader_count) == 1) { |
@@ -1257,10 +1262,14 @@ static const struct v4l2_ioctl_ops vbi_ioctl_ops = { | |||
1257 | .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, | 1262 | .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, |
1258 | .vidioc_log_status = vidioc_log_status, | 1263 | .vidioc_log_status = vidioc_log_status, |
1259 | .vidioc_queryctrl = vidioc_queryctrl, | 1264 | .vidioc_queryctrl = vidioc_queryctrl, |
1260 | // .vidioc_g_chip_ident = saa7164_g_chip_ident, | 1265 | #if 0 |
1266 | .vidioc_g_chip_ident = saa7164_g_chip_ident, | ||
1267 | #endif | ||
1261 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1268 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1262 | // .vidioc_g_register = saa7164_g_register, | 1269 | #if 0 |
1263 | // .vidioc_s_register = saa7164_s_register, | 1270 | .vidioc_g_register = saa7164_g_register, |
1271 | .vidioc_s_register = saa7164_s_register, | ||
1272 | #endif | ||
1264 | #endif | 1273 | #endif |
1265 | .vidioc_g_fmt_vbi_cap = saa7164_vbi_fmt, | 1274 | .vidioc_g_fmt_vbi_cap = saa7164_vbi_fmt, |
1266 | .vidioc_try_fmt_vbi_cap = saa7164_vbi_fmt, | 1275 | .vidioc_try_fmt_vbi_cap = saa7164_vbi_fmt, |
diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h index 041ae8e20f68..16745d2fb349 100644 --- a/drivers/media/video/saa7164/saa7164.h +++ b/drivers/media/video/saa7164/saa7164.h | |||
@@ -113,7 +113,8 @@ | |||
113 | #define DBGLVL_THR 4096 | 113 | #define DBGLVL_THR 4096 |
114 | #define DBGLVL_CPU 8192 | 114 | #define DBGLVL_CPU 8192 |
115 | 115 | ||
116 | #define SAA7164_NORMS (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443) | 116 | #define SAA7164_NORMS \ |
117 | (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443) | ||
117 | 118 | ||
118 | enum port_t { | 119 | enum port_t { |
119 | SAA7164_MPEG_UNDEFINED = 0, | 120 | SAA7164_MPEG_UNDEFINED = 0, |
@@ -182,15 +183,11 @@ struct saa7164_subid { | |||
182 | 183 | ||
183 | struct saa7164_encoder_fh { | 184 | struct saa7164_encoder_fh { |
184 | struct saa7164_port *port; | 185 | struct saa7164_port *port; |
185 | // u32 freq; | ||
186 | // u32 tuner_type; | ||
187 | atomic_t v4l_reading; | 186 | atomic_t v4l_reading; |
188 | }; | 187 | }; |
189 | 188 | ||
190 | struct saa7164_vbi_fh { | 189 | struct saa7164_vbi_fh { |
191 | struct saa7164_port *port; | 190 | struct saa7164_port *port; |
192 | // u32 freq; | ||
193 | // u32 tuner_type; | ||
194 | atomic_t v4l_reading; | 191 | atomic_t v4l_reading; |
195 | }; | 192 | }; |
196 | 193 | ||
@@ -265,8 +262,6 @@ struct saa7164_ctrl { | |||
265 | struct saa7164_tvnorm { | 262 | struct saa7164_tvnorm { |
266 | char *name; | 263 | char *name; |
267 | v4l2_std_id id; | 264 | v4l2_std_id id; |
268 | // u32 cxiformat; | ||
269 | // u32 cxoformat; | ||
270 | }; | 265 | }; |
271 | 266 | ||
272 | struct saa7164_encoder_params { | 267 | struct saa7164_encoder_params { |
@@ -447,7 +442,7 @@ struct saa7164_dev { | |||
447 | int nr; | 442 | int nr; |
448 | int hwrevision; | 443 | int hwrevision; |
449 | u32 board; | 444 | u32 board; |
450 | char name[32]; | 445 | char name[16]; |
451 | 446 | ||
452 | /* firmware status */ | 447 | /* firmware status */ |
453 | struct saa7164_fw_status fw_status; | 448 | struct saa7164_fw_status fw_status; |
@@ -510,7 +505,8 @@ extern void saa7164_call_i2c_clients(struct saa7164_i2c *bus, | |||
510 | /* saa7164-bus.c */ | 505 | /* saa7164-bus.c */ |
511 | int saa7164_bus_setup(struct saa7164_dev *dev); | 506 | int saa7164_bus_setup(struct saa7164_dev *dev); |
512 | void saa7164_bus_dump(struct saa7164_dev *dev); | 507 | void saa7164_bus_dump(struct saa7164_dev *dev); |
513 | int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf); | 508 | int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, |
509 | void *buf); | ||
514 | int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, | 510 | int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, |
515 | void *buf, int peekonly); | 511 | void *buf, int peekonly); |
516 | 512 | ||
@@ -552,7 +548,8 @@ int saa7164_api_get_videomux(struct saa7164_port *port); | |||
552 | int saa7164_api_set_vbi_format(struct saa7164_port *port); | 548 | int saa7164_api_set_vbi_format(struct saa7164_port *port); |
553 | int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level); | 549 | int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level); |
554 | int saa7164_api_collect_debug(struct saa7164_dev *dev); | 550 | int saa7164_api_collect_debug(struct saa7164_dev *dev); |
555 | int saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i); | 551 | int saa7164_api_get_load_info(struct saa7164_dev *dev, |
552 | struct tmFwInfoStruct *i); | ||
556 | 553 | ||
557 | /* ----------------------------------------------------------- */ | 554 | /* ----------------------------------------------------------- */ |
558 | /* saa7164-cards.c */ | 555 | /* saa7164-cards.c */ |
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c deleted file mode 100644 index 41360d7c3e96..000000000000 --- a/drivers/media/video/se401.c +++ /dev/null | |||
@@ -1,1492 +0,0 @@ | |||
1 | /* | ||
2 | * Endpoints (formerly known as AOX) se401 USB Camera Driver | ||
3 | * | ||
4 | * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org) | ||
5 | * | ||
6 | * Still somewhat based on the Linux ov511 driver. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
15 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
16 | * for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software Foundation, | ||
20 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * | ||
23 | * Thanks to Endpoints Inc. (www.endpoints.com) for making documentation on | ||
24 | * their chipset available and supporting me while writing this driver. | ||
25 | * - Jeroen Vreeken | ||
26 | */ | ||
27 | |||
28 | static const char version[] = "0.24"; | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/vmalloc.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/pagemap.h> | ||
35 | #include <linux/usb.h> | ||
36 | #include "se401.h" | ||
37 | |||
38 | static int flickerless; | ||
39 | static int video_nr = -1; | ||
40 | |||
41 | static struct usb_device_id device_table[] = { | ||
42 | { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */ | ||
43 | { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */ | ||
44 | { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */ | ||
45 | { USB_DEVICE(0x047d, 0x5002) },/* Kensington 6701(5/7) */ | ||
46 | { USB_DEVICE(0x047d, 0x5003) },/* Kensington 67016 */ | ||
47 | { } | ||
48 | }; | ||
49 | |||
50 | MODULE_DEVICE_TABLE(usb, device_table); | ||
51 | |||
52 | MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>"); | ||
53 | MODULE_DESCRIPTION("SE401 USB Camera Driver"); | ||
54 | MODULE_LICENSE("GPL"); | ||
55 | module_param(flickerless, int, 0); | ||
56 | MODULE_PARM_DESC(flickerless, | ||
57 | "Net frequency to adjust exposure time to (0/50/60)"); | ||
58 | module_param(video_nr, int, 0); | ||
59 | |||
60 | static struct usb_driver se401_driver; | ||
61 | |||
62 | |||
63 | /********************************************************************** | ||
64 | * | ||
65 | * Memory management | ||
66 | * | ||
67 | **********************************************************************/ | ||
68 | static void *rvmalloc(unsigned long size) | ||
69 | { | ||
70 | void *mem; | ||
71 | unsigned long adr; | ||
72 | |||
73 | size = PAGE_ALIGN(size); | ||
74 | mem = vmalloc_32(size); | ||
75 | if (!mem) | ||
76 | return NULL; | ||
77 | |||
78 | memset(mem, 0, size); /* Clear the ram out, no junk to the user */ | ||
79 | adr = (unsigned long) mem; | ||
80 | while (size > 0) { | ||
81 | SetPageReserved(vmalloc_to_page((void *)adr)); | ||
82 | adr += PAGE_SIZE; | ||
83 | size -= PAGE_SIZE; | ||
84 | } | ||
85 | |||
86 | return mem; | ||
87 | } | ||
88 | |||
89 | static void rvfree(void *mem, unsigned long size) | ||
90 | { | ||
91 | unsigned long adr; | ||
92 | |||
93 | if (!mem) | ||
94 | return; | ||
95 | |||
96 | adr = (unsigned long) mem; | ||
97 | while ((long) size > 0) { | ||
98 | ClearPageReserved(vmalloc_to_page((void *)adr)); | ||
99 | adr += PAGE_SIZE; | ||
100 | size -= PAGE_SIZE; | ||
101 | } | ||
102 | vfree(mem); | ||
103 | } | ||
104 | |||
105 | |||
106 | |||
107 | /**************************************************************************** | ||
108 | * | ||
109 | * se401 register read/write functions | ||
110 | * | ||
111 | ***************************************************************************/ | ||
112 | |||
113 | static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req, | ||
114 | unsigned short value, unsigned char *cp, int size) | ||
115 | { | ||
116 | return usb_control_msg( | ||
117 | se401->dev, | ||
118 | set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0), | ||
119 | req, | ||
120 | (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
121 | value, | ||
122 | 0, | ||
123 | cp, | ||
124 | size, | ||
125 | 1000 | ||
126 | ); | ||
127 | } | ||
128 | |||
129 | static int se401_set_feature(struct usb_se401 *se401, unsigned short selector, | ||
130 | unsigned short param) | ||
131 | { | ||
132 | /* specs say that the selector (address) should go in the value field | ||
133 | and the param in index, but in the logs of the windows driver they do | ||
134 | this the other way around... | ||
135 | */ | ||
136 | return usb_control_msg( | ||
137 | se401->dev, | ||
138 | usb_sndctrlpipe(se401->dev, 0), | ||
139 | SE401_REQ_SET_EXT_FEATURE, | ||
140 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
141 | param, | ||
142 | selector, | ||
143 | NULL, | ||
144 | 0, | ||
145 | 1000 | ||
146 | ); | ||
147 | } | ||
148 | |||
149 | static unsigned short se401_get_feature(struct usb_se401 *se401, | ||
150 | unsigned short selector) | ||
151 | { | ||
152 | /* For 'set' the selecetor should be in index, not sure if the spec is | ||
153 | wrong here to.... | ||
154 | */ | ||
155 | unsigned char cp[2]; | ||
156 | usb_control_msg( | ||
157 | se401->dev, | ||
158 | usb_rcvctrlpipe(se401->dev, 0), | ||
159 | SE401_REQ_GET_EXT_FEATURE, | ||
160 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
161 | 0, | ||
162 | selector, | ||
163 | cp, | ||
164 | 2, | ||
165 | 1000 | ||
166 | ); | ||
167 | return cp[0]+cp[1]*256; | ||
168 | } | ||
169 | |||
170 | /**************************************************************************** | ||
171 | * | ||
172 | * Camera control | ||
173 | * | ||
174 | ***************************************************************************/ | ||
175 | |||
176 | |||
177 | static int se401_send_pict(struct usb_se401 *se401) | ||
178 | { | ||
179 | /* integration time low */ | ||
180 | se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l); | ||
181 | /* integration time mid */ | ||
182 | se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m); | ||
183 | /* integration time mid */ | ||
184 | se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h); | ||
185 | /* reset level value */ | ||
186 | se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel); | ||
187 | /* red color gain */ | ||
188 | se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain); | ||
189 | /* green color gain */ | ||
190 | se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain); | ||
191 | /* blue color gain */ | ||
192 | se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain); | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | static void se401_set_exposure(struct usb_se401 *se401, int brightness) | ||
198 | { | ||
199 | int integration = brightness << 5; | ||
200 | |||
201 | if (flickerless == 50) | ||
202 | integration = integration-integration % 106667; | ||
203 | if (flickerless == 60) | ||
204 | integration = integration-integration % 88889; | ||
205 | se401->brightness = integration >> 5; | ||
206 | se401->expose_h = (integration >> 16) & 0xff; | ||
207 | se401->expose_m = (integration >> 8) & 0xff; | ||
208 | se401->expose_l = integration & 0xff; | ||
209 | } | ||
210 | |||
211 | static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p) | ||
212 | { | ||
213 | p->brightness = se401->brightness; | ||
214 | if (se401->enhance) | ||
215 | p->whiteness = 32768; | ||
216 | else | ||
217 | p->whiteness = 0; | ||
218 | |||
219 | p->colour = 65535; | ||
220 | p->contrast = 65535; | ||
221 | p->hue = se401->rgain << 10; | ||
222 | p->palette = se401->palette; | ||
223 | p->depth = 3; /* rgb24 */ | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | |||
228 | static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p) | ||
229 | { | ||
230 | if (p->palette != VIDEO_PALETTE_RGB24) | ||
231 | return 1; | ||
232 | se401->palette = p->palette; | ||
233 | if (p->hue != se401->hue) { | ||
234 | se401->rgain = p->hue >> 10; | ||
235 | se401->bgain = 0x40-(p->hue >> 10); | ||
236 | se401->hue = p->hue; | ||
237 | } | ||
238 | if (p->brightness != se401->brightness) | ||
239 | se401_set_exposure(se401, p->brightness); | ||
240 | |||
241 | if (p->whiteness >= 32768) | ||
242 | se401->enhance = 1; | ||
243 | else | ||
244 | se401->enhance = 0; | ||
245 | se401_send_pict(se401); | ||
246 | se401_send_pict(se401); | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | Hyundai have some really nice docs about this and other sensor related | ||
252 | stuff on their homepage: www.hei.co.kr | ||
253 | */ | ||
254 | static void se401_auto_resetlevel(struct usb_se401 *se401) | ||
255 | { | ||
256 | unsigned int ahrc, alrc; | ||
257 | int oldreset = se401->resetlevel; | ||
258 | |||
259 | /* For some reason this normally read-only register doesn't get reset | ||
260 | to zero after reading them just once... | ||
261 | */ | ||
262 | se401_get_feature(se401, HV7131_REG_HIREFNOH); | ||
263 | se401_get_feature(se401, HV7131_REG_HIREFNOL); | ||
264 | se401_get_feature(se401, HV7131_REG_LOREFNOH); | ||
265 | se401_get_feature(se401, HV7131_REG_LOREFNOL); | ||
266 | ahrc = 256*se401_get_feature(se401, HV7131_REG_HIREFNOH) + | ||
267 | se401_get_feature(se401, HV7131_REG_HIREFNOL); | ||
268 | alrc = 256*se401_get_feature(se401, HV7131_REG_LOREFNOH) + | ||
269 | se401_get_feature(se401, HV7131_REG_LOREFNOL); | ||
270 | |||
271 | /* Not an exact science, but it seems to work pretty well... */ | ||
272 | if (alrc > 10) { | ||
273 | while (alrc >= 10 && se401->resetlevel < 63) { | ||
274 | se401->resetlevel++; | ||
275 | alrc /= 2; | ||
276 | } | ||
277 | } else if (ahrc > 20) { | ||
278 | while (ahrc >= 20 && se401->resetlevel > 0) { | ||
279 | se401->resetlevel--; | ||
280 | ahrc /= 2; | ||
281 | } | ||
282 | } | ||
283 | if (se401->resetlevel != oldreset) | ||
284 | se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel); | ||
285 | |||
286 | return; | ||
287 | } | ||
288 | |||
289 | /* irq handler for snapshot button */ | ||
290 | static void se401_button_irq(struct urb *urb) | ||
291 | { | ||
292 | struct usb_se401 *se401 = urb->context; | ||
293 | int status; | ||
294 | |||
295 | if (!se401->dev) { | ||
296 | dev_info(&urb->dev->dev, "device vapourished\n"); | ||
297 | return; | ||
298 | } | ||
299 | |||
300 | switch (urb->status) { | ||
301 | case 0: | ||
302 | /* success */ | ||
303 | break; | ||
304 | case -ECONNRESET: | ||
305 | case -ENOENT: | ||
306 | case -ESHUTDOWN: | ||
307 | /* this urb is terminated, clean up */ | ||
308 | dbg("%s - urb shutting down with status: %d", | ||
309 | __func__, urb->status); | ||
310 | return; | ||
311 | default: | ||
312 | dbg("%s - nonzero urb status received: %d", | ||
313 | __func__, urb->status); | ||
314 | goto exit; | ||
315 | } | ||
316 | |||
317 | if (urb->actual_length >= 2) | ||
318 | if (se401->button) | ||
319 | se401->buttonpressed = 1; | ||
320 | exit: | ||
321 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
322 | if (status) | ||
323 | err("%s - usb_submit_urb failed with result %d", | ||
324 | __func__, status); | ||
325 | } | ||
326 | |||
327 | static void se401_video_irq(struct urb *urb) | ||
328 | { | ||
329 | struct usb_se401 *se401 = urb->context; | ||
330 | int length = urb->actual_length; | ||
331 | |||
332 | /* ohoh... */ | ||
333 | if (!se401->streaming) | ||
334 | return; | ||
335 | |||
336 | if (!se401->dev) { | ||
337 | dev_info(&urb->dev->dev, "device vapourished\n"); | ||
338 | return; | ||
339 | } | ||
340 | |||
341 | /* 0 sized packets happen if we are to fast, but sometimes the camera | ||
342 | keeps sending them forever... | ||
343 | */ | ||
344 | if (length && !urb->status) { | ||
345 | se401->nullpackets = 0; | ||
346 | switch (se401->scratch[se401->scratch_next].state) { | ||
347 | case BUFFER_READY: | ||
348 | case BUFFER_BUSY: | ||
349 | se401->dropped++; | ||
350 | break; | ||
351 | case BUFFER_UNUSED: | ||
352 | memcpy(se401->scratch[se401->scratch_next].data, | ||
353 | (unsigned char *)urb->transfer_buffer, length); | ||
354 | se401->scratch[se401->scratch_next].state | ||
355 | = BUFFER_READY; | ||
356 | se401->scratch[se401->scratch_next].offset | ||
357 | = se401->bayeroffset; | ||
358 | se401->scratch[se401->scratch_next].length = length; | ||
359 | if (waitqueue_active(&se401->wq)) | ||
360 | wake_up_interruptible(&se401->wq); | ||
361 | se401->scratch_overflow = 0; | ||
362 | se401->scratch_next++; | ||
363 | if (se401->scratch_next >= SE401_NUMSCRATCH) | ||
364 | se401->scratch_next = 0; | ||
365 | break; | ||
366 | } | ||
367 | se401->bayeroffset += length; | ||
368 | if (se401->bayeroffset >= se401->cheight * se401->cwidth) | ||
369 | se401->bayeroffset = 0; | ||
370 | } else { | ||
371 | se401->nullpackets++; | ||
372 | if (se401->nullpackets > SE401_MAX_NULLPACKETS) | ||
373 | if (waitqueue_active(&se401->wq)) | ||
374 | wake_up_interruptible(&se401->wq); | ||
375 | } | ||
376 | |||
377 | /* Resubmit urb for new data */ | ||
378 | urb->status = 0; | ||
379 | urb->dev = se401->dev; | ||
380 | if (usb_submit_urb(urb, GFP_KERNEL)) | ||
381 | dev_info(&urb->dev->dev, "urb burned down\n"); | ||
382 | return; | ||
383 | } | ||
384 | |||
385 | static void se401_send_size(struct usb_se401 *se401, int width, int height) | ||
386 | { | ||
387 | int i = 0; | ||
388 | int mode = 0x03; /* No compression */ | ||
389 | int sendheight = height; | ||
390 | int sendwidth = width; | ||
391 | |||
392 | /* JangGu compression can only be used with the camera supported sizes, | ||
393 | but bayer seems to work with any size that fits on the sensor. | ||
394 | We check if we can use compression with the current size with either | ||
395 | 4 or 16 times subcapturing, if not we use uncompressed bayer data | ||
396 | but this will result in cutouts of the maximum size.... | ||
397 | */ | ||
398 | while (i < se401->sizes && !(se401->width[i] == width && | ||
399 | se401->height[i] == height)) | ||
400 | i++; | ||
401 | while (i < se401->sizes) { | ||
402 | if (se401->width[i] == width * 2 && | ||
403 | se401->height[i] == height * 2) { | ||
404 | sendheight = se401->height[i]; | ||
405 | sendwidth = se401->width[i]; | ||
406 | mode = 0x40; | ||
407 | } | ||
408 | if (se401->width[i] == width * 4 && | ||
409 | se401->height[i] == height * 4) { | ||
410 | sendheight = se401->height[i]; | ||
411 | sendwidth = se401->width[i]; | ||
412 | mode = 0x42; | ||
413 | } | ||
414 | i++; | ||
415 | } | ||
416 | |||
417 | se401_sndctrl(1, se401, SE401_REQ_SET_WIDTH, sendwidth, NULL, 0); | ||
418 | se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0); | ||
419 | se401_set_feature(se401, SE401_OPERATINGMODE, mode); | ||
420 | |||
421 | if (mode == 0x03) | ||
422 | se401->format = FMT_BAYER; | ||
423 | else | ||
424 | se401->format = FMT_JANGGU; | ||
425 | } | ||
426 | |||
427 | /* | ||
428 | In this function se401_send_pict is called several times, | ||
429 | for some reason (depending on the state of the sensor and the phase of | ||
430 | the moon :) doing this only in either place doesn't always work... | ||
431 | */ | ||
432 | static int se401_start_stream(struct usb_se401 *se401) | ||
433 | { | ||
434 | struct urb *urb; | ||
435 | int err = 0, i; | ||
436 | se401->streaming = 1; | ||
437 | |||
438 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); | ||
439 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); | ||
440 | |||
441 | /* Set picture settings */ | ||
442 | /* windowed + pix intg */ | ||
443 | se401_set_feature(se401, HV7131_REG_MODE_B, 0x05); | ||
444 | se401_send_pict(se401); | ||
445 | |||
446 | se401_send_size(se401, se401->cwidth, se401->cheight); | ||
447 | |||
448 | se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, | ||
449 | 0, NULL, 0); | ||
450 | |||
451 | /* Do some memory allocation */ | ||
452 | for (i = 0; i < SE401_NUMFRAMES; i++) { | ||
453 | se401->frame[i].data = se401->fbuf + i * se401->maxframesize; | ||
454 | se401->frame[i].curpix = 0; | ||
455 | } | ||
456 | for (i = 0; i < SE401_NUMSBUF; i++) { | ||
457 | se401->sbuf[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL); | ||
458 | if (!se401->sbuf[i].data) { | ||
459 | for (i = i - 1; i >= 0; i--) { | ||
460 | kfree(se401->sbuf[i].data); | ||
461 | se401->sbuf[i].data = NULL; | ||
462 | } | ||
463 | return -ENOMEM; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | se401->bayeroffset = 0; | ||
468 | se401->scratch_next = 0; | ||
469 | se401->scratch_use = 0; | ||
470 | se401->scratch_overflow = 0; | ||
471 | for (i = 0; i < SE401_NUMSCRATCH; i++) { | ||
472 | se401->scratch[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL); | ||
473 | if (!se401->scratch[i].data) { | ||
474 | for (i = i - 1; i >= 0; i--) { | ||
475 | kfree(se401->scratch[i].data); | ||
476 | se401->scratch[i].data = NULL; | ||
477 | } | ||
478 | goto nomem_sbuf; | ||
479 | } | ||
480 | se401->scratch[i].state = BUFFER_UNUSED; | ||
481 | } | ||
482 | |||
483 | for (i = 0; i < SE401_NUMSBUF; i++) { | ||
484 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
485 | if (!urb) { | ||
486 | for (i = i - 1; i >= 0; i--) { | ||
487 | usb_kill_urb(se401->urb[i]); | ||
488 | usb_free_urb(se401->urb[i]); | ||
489 | se401->urb[i] = NULL; | ||
490 | } | ||
491 | goto nomem_scratch; | ||
492 | } | ||
493 | |||
494 | usb_fill_bulk_urb(urb, se401->dev, | ||
495 | usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT), | ||
496 | se401->sbuf[i].data, SE401_PACKETSIZE, | ||
497 | se401_video_irq, | ||
498 | se401); | ||
499 | |||
500 | se401->urb[i] = urb; | ||
501 | |||
502 | err = usb_submit_urb(se401->urb[i], GFP_KERNEL); | ||
503 | if (err) | ||
504 | err("urb burned down"); | ||
505 | } | ||
506 | |||
507 | se401->framecount = 0; | ||
508 | |||
509 | return 0; | ||
510 | |||
511 | nomem_scratch: | ||
512 | for (i = 0; i < SE401_NUMSCRATCH; i++) { | ||
513 | kfree(se401->scratch[i].data); | ||
514 | se401->scratch[i].data = NULL; | ||
515 | } | ||
516 | nomem_sbuf: | ||
517 | for (i = 0; i < SE401_NUMSBUF; i++) { | ||
518 | kfree(se401->sbuf[i].data); | ||
519 | se401->sbuf[i].data = NULL; | ||
520 | } | ||
521 | return -ENOMEM; | ||
522 | } | ||
523 | |||
524 | static int se401_stop_stream(struct usb_se401 *se401) | ||
525 | { | ||
526 | int i; | ||
527 | |||
528 | if (!se401->streaming || !se401->dev) | ||
529 | return 1; | ||
530 | |||
531 | se401->streaming = 0; | ||
532 | |||
533 | se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0); | ||
534 | |||
535 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0); | ||
536 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0); | ||
537 | |||
538 | for (i = 0; i < SE401_NUMSBUF; i++) | ||
539 | if (se401->urb[i]) { | ||
540 | usb_kill_urb(se401->urb[i]); | ||
541 | usb_free_urb(se401->urb[i]); | ||
542 | se401->urb[i] = NULL; | ||
543 | kfree(se401->sbuf[i].data); | ||
544 | } | ||
545 | for (i = 0; i < SE401_NUMSCRATCH; i++) { | ||
546 | kfree(se401->scratch[i].data); | ||
547 | se401->scratch[i].data = NULL; | ||
548 | } | ||
549 | |||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | static int se401_set_size(struct usb_se401 *se401, int width, int height) | ||
554 | { | ||
555 | int wasstreaming = se401->streaming; | ||
556 | /* Check to see if we need to change */ | ||
557 | if (se401->cwidth == width && se401->cheight == height) | ||
558 | return 0; | ||
559 | |||
560 | /* Check for a valid mode */ | ||
561 | if (!width || !height) | ||
562 | return 1; | ||
563 | if ((width & 1) || (height & 1)) | ||
564 | return 1; | ||
565 | if (width > se401->width[se401->sizes-1]) | ||
566 | return 1; | ||
567 | if (height > se401->height[se401->sizes-1]) | ||
568 | return 1; | ||
569 | |||
570 | /* Stop a current stream and start it again at the new size */ | ||
571 | if (wasstreaming) | ||
572 | se401_stop_stream(se401); | ||
573 | se401->cwidth = width; | ||
574 | se401->cheight = height; | ||
575 | if (wasstreaming) | ||
576 | se401_start_stream(se401); | ||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | |||
581 | /**************************************************************************** | ||
582 | * | ||
583 | * Video Decoding | ||
584 | * | ||
585 | ***************************************************************************/ | ||
586 | |||
587 | /* | ||
588 | This shouldn't really be done in a v4l driver.... | ||
589 | But it does make the image look a lot more usable. | ||
590 | Basically it lifts the dark pixels more than the light pixels. | ||
591 | */ | ||
592 | static inline void enhance_picture(unsigned char *frame, int len) | ||
593 | { | ||
594 | while (len--) { | ||
595 | *frame = (((*frame^255)*(*frame^255))/255)^255; | ||
596 | frame++; | ||
597 | } | ||
598 | } | ||
599 | |||
600 | static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data) | ||
601 | { | ||
602 | struct se401_frame *frame = &se401->frame[se401->curframe]; | ||
603 | int linelength = se401->cwidth * 3; | ||
604 | |||
605 | if (frame->curlinepix >= linelength) { | ||
606 | frame->curlinepix = 0; | ||
607 | frame->curline += linelength; | ||
608 | } | ||
609 | |||
610 | /* First three are absolute, all others relative. | ||
611 | * Format is rgb from right to left (mirrorred image), | ||
612 | * we flip it to get bgr from left to right. */ | ||
613 | if (frame->curlinepix < 3) | ||
614 | *(frame->curline-frame->curlinepix) = 1 + data * 4; | ||
615 | else | ||
616 | *(frame->curline-frame->curlinepix) = | ||
617 | *(frame->curline-frame->curlinepix + 3) + data * 4; | ||
618 | frame->curlinepix++; | ||
619 | } | ||
620 | |||
621 | static inline void decode_JangGu_vlc(struct usb_se401 *se401, | ||
622 | unsigned char *data, int bit_exp, int packetlength) | ||
623 | { | ||
624 | int pos = 0; | ||
625 | int vlc_cod = 0; | ||
626 | int vlc_size = 0; | ||
627 | int vlc_data = 0; | ||
628 | int bit_cur; | ||
629 | int bit; | ||
630 | data += 4; | ||
631 | while (pos < packetlength) { | ||
632 | bit_cur = 8; | ||
633 | while (bit_cur && bit_exp) { | ||
634 | bit = ((*data) >> (bit_cur-1))&1; | ||
635 | if (!vlc_cod) { | ||
636 | if (bit) { | ||
637 | vlc_size++; | ||
638 | } else { | ||
639 | if (!vlc_size) | ||
640 | decode_JangGu_integrate(se401, 0); | ||
641 | else { | ||
642 | vlc_cod = 2; | ||
643 | vlc_data = 0; | ||
644 | } | ||
645 | } | ||
646 | } else { | ||
647 | if (vlc_cod == 2) { | ||
648 | if (!bit) | ||
649 | vlc_data = -(1 << vlc_size) + 1; | ||
650 | vlc_cod--; | ||
651 | } | ||
652 | vlc_size--; | ||
653 | vlc_data += bit << vlc_size; | ||
654 | if (!vlc_size) { | ||
655 | decode_JangGu_integrate(se401, vlc_data); | ||
656 | vlc_cod = 0; | ||
657 | } | ||
658 | } | ||
659 | bit_cur--; | ||
660 | bit_exp--; | ||
661 | } | ||
662 | pos++; | ||
663 | data++; | ||
664 | } | ||
665 | } | ||
666 | |||
667 | static inline void decode_JangGu(struct usb_se401 *se401, | ||
668 | struct se401_scratch *buffer) | ||
669 | { | ||
670 | unsigned char *data = buffer->data; | ||
671 | int len = buffer->length; | ||
672 | int bit_exp = 0, pix_exp = 0, frameinfo = 0, packetlength = 0, size; | ||
673 | int datapos = 0; | ||
674 | |||
675 | /* New image? */ | ||
676 | if (!se401->frame[se401->curframe].curpix) { | ||
677 | se401->frame[se401->curframe].curlinepix = 0; | ||
678 | se401->frame[se401->curframe].curline = | ||
679 | se401->frame[se401->curframe].data+ | ||
680 | se401->cwidth * 3 - 1; | ||
681 | if (se401->frame[se401->curframe].grabstate == FRAME_READY) | ||
682 | se401->frame[se401->curframe].grabstate = FRAME_GRABBING; | ||
683 | se401->vlcdatapos = 0; | ||
684 | } | ||
685 | while (datapos < len) { | ||
686 | size = 1024 - se401->vlcdatapos; | ||
687 | if (size+datapos > len) | ||
688 | size = len-datapos; | ||
689 | memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size); | ||
690 | se401->vlcdatapos += size; | ||
691 | packetlength = 0; | ||
692 | if (se401->vlcdatapos >= 4) { | ||
693 | bit_exp = se401->vlcdata[3] + (se401->vlcdata[2] << 8); | ||
694 | pix_exp = se401->vlcdata[1] + | ||
695 | ((se401->vlcdata[0] & 0x3f) << 8); | ||
696 | frameinfo = se401->vlcdata[0] & 0xc0; | ||
697 | packetlength = ((bit_exp + 47) >> 4) << 1; | ||
698 | if (packetlength > 1024) { | ||
699 | se401->vlcdatapos = 0; | ||
700 | datapos = len; | ||
701 | packetlength = 0; | ||
702 | se401->error++; | ||
703 | se401->frame[se401->curframe].curpix = 0; | ||
704 | } | ||
705 | } | ||
706 | if (packetlength && se401->vlcdatapos >= packetlength) { | ||
707 | decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, | ||
708 | packetlength); | ||
709 | se401->frame[se401->curframe].curpix += pix_exp * 3; | ||
710 | datapos += size-(se401->vlcdatapos-packetlength); | ||
711 | se401->vlcdatapos = 0; | ||
712 | if (se401->frame[se401->curframe].curpix >= se401->cwidth * se401->cheight * 3) { | ||
713 | if (se401->frame[se401->curframe].curpix == se401->cwidth * se401->cheight * 3) { | ||
714 | if (se401->frame[se401->curframe].grabstate == FRAME_GRABBING) { | ||
715 | se401->frame[se401->curframe].grabstate = FRAME_DONE; | ||
716 | se401->framecount++; | ||
717 | se401->readcount++; | ||
718 | } | ||
719 | if (se401->frame[(se401->curframe + 1) & (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) | ||
720 | se401->curframe = (se401->curframe + 1) & (SE401_NUMFRAMES - 1); | ||
721 | } else | ||
722 | se401->error++; | ||
723 | se401->frame[se401->curframe].curpix = 0; | ||
724 | datapos = len; | ||
725 | } | ||
726 | } else | ||
727 | datapos += size; | ||
728 | } | ||
729 | } | ||
730 | |||
731 | static inline void decode_bayer(struct usb_se401 *se401, | ||
732 | struct se401_scratch *buffer) | ||
733 | { | ||
734 | unsigned char *data = buffer->data; | ||
735 | int len = buffer->length; | ||
736 | int offset = buffer->offset; | ||
737 | int datasize = se401->cwidth * se401->cheight; | ||
738 | struct se401_frame *frame = &se401->frame[se401->curframe]; | ||
739 | unsigned char *framedata = frame->data, *curline, *nextline; | ||
740 | int width = se401->cwidth; | ||
741 | int blineoffset = 0, bline; | ||
742 | int linelength = width * 3, i; | ||
743 | |||
744 | |||
745 | if (frame->curpix == 0) { | ||
746 | if (frame->grabstate == FRAME_READY) | ||
747 | frame->grabstate = FRAME_GRABBING; | ||
748 | |||
749 | frame->curline = framedata + linelength; | ||
750 | frame->curlinepix = 0; | ||
751 | } | ||
752 | |||
753 | if (offset != frame->curpix) { | ||
754 | /* Regard frame as lost :( */ | ||
755 | frame->curpix = 0; | ||
756 | se401->error++; | ||
757 | return; | ||
758 | } | ||
759 | |||
760 | /* Check if we have to much data */ | ||
761 | if (frame->curpix + len > datasize) | ||
762 | len = datasize-frame->curpix; | ||
763 | |||
764 | if (se401->cheight % 4) | ||
765 | blineoffset = 1; | ||
766 | bline = frame->curpix / se401->cwidth+blineoffset; | ||
767 | |||
768 | curline = frame->curline; | ||
769 | nextline = curline + linelength; | ||
770 | if (nextline >= framedata+datasize * 3) | ||
771 | nextline = curline; | ||
772 | while (len) { | ||
773 | if (frame->curlinepix >= width) { | ||
774 | frame->curlinepix -= width; | ||
775 | bline = frame->curpix / width + blineoffset; | ||
776 | curline += linelength*2; | ||
777 | nextline += linelength*2; | ||
778 | if (curline >= framedata+datasize * 3) { | ||
779 | frame->curlinepix++; | ||
780 | curline -= 3; | ||
781 | nextline -= 3; | ||
782 | len--; | ||
783 | data++; | ||
784 | frame->curpix++; | ||
785 | } | ||
786 | if (nextline >= framedata+datasize*3) | ||
787 | nextline = curline; | ||
788 | } | ||
789 | if (bline & 1) { | ||
790 | if (frame->curlinepix & 1) { | ||
791 | *(curline + 2) = *data; | ||
792 | *(curline - 1) = *data; | ||
793 | *(nextline + 2) = *data; | ||
794 | *(nextline - 1) = *data; | ||
795 | } else { | ||
796 | *(curline + 1) = | ||
797 | (*(curline + 1) + *data) / 2; | ||
798 | *(curline-2) = | ||
799 | (*(curline - 2) + *data) / 2; | ||
800 | *(nextline + 1) = *data; | ||
801 | *(nextline - 2) = *data; | ||
802 | } | ||
803 | } else { | ||
804 | if (frame->curlinepix & 1) { | ||
805 | *(curline + 1) = | ||
806 | (*(curline + 1) + *data) / 2; | ||
807 | *(curline - 2) = | ||
808 | (*(curline - 2) + *data) / 2; | ||
809 | *(nextline + 1) = *data; | ||
810 | *(nextline - 2) = *data; | ||
811 | } else { | ||
812 | *curline = *data; | ||
813 | *(curline - 3) = *data; | ||
814 | *nextline = *data; | ||
815 | *(nextline - 3) = *data; | ||
816 | } | ||
817 | } | ||
818 | frame->curlinepix++; | ||
819 | curline -= 3; | ||
820 | nextline -= 3; | ||
821 | len--; | ||
822 | data++; | ||
823 | frame->curpix++; | ||
824 | } | ||
825 | frame->curline = curline; | ||
826 | |||
827 | if (frame->curpix >= datasize) { | ||
828 | /* Fix the top line */ | ||
829 | framedata += linelength; | ||
830 | for (i = 0; i < linelength; i++) { | ||
831 | framedata--; | ||
832 | *framedata = *(framedata + linelength); | ||
833 | } | ||
834 | /* Fix the left side (green is already present) */ | ||
835 | for (i = 0; i < se401->cheight; i++) { | ||
836 | *framedata = *(framedata + 3); | ||
837 | *(framedata + 1) = *(framedata + 4); | ||
838 | *(framedata + 2) = *(framedata + 5); | ||
839 | framedata += linelength; | ||
840 | } | ||
841 | frame->curpix = 0; | ||
842 | frame->grabstate = FRAME_DONE; | ||
843 | se401->framecount++; | ||
844 | se401->readcount++; | ||
845 | if (se401->frame[(se401->curframe + 1) & | ||
846 | (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) { | ||
847 | se401->curframe = (se401->curframe+1) & | ||
848 | (SE401_NUMFRAMES-1); | ||
849 | } | ||
850 | } | ||
851 | } | ||
852 | |||
853 | static int se401_newframe(struct usb_se401 *se401, int framenr) | ||
854 | { | ||
855 | DECLARE_WAITQUEUE(wait, current); | ||
856 | int errors = 0; | ||
857 | |||
858 | while (se401->streaming && | ||
859 | (se401->frame[framenr].grabstate == FRAME_READY || | ||
860 | se401->frame[framenr].grabstate == FRAME_GRABBING)) { | ||
861 | if (!se401->frame[framenr].curpix) | ||
862 | errors++; | ||
863 | |||
864 | wait_interruptible( | ||
865 | se401->scratch[se401->scratch_use].state != BUFFER_READY, | ||
866 | &se401->wq, &wait); | ||
867 | if (se401->nullpackets > SE401_MAX_NULLPACKETS) { | ||
868 | se401->nullpackets = 0; | ||
869 | dev_info(&se401->dev->dev, | ||
870 | "too many null length packets, restarting capture\n"); | ||
871 | se401_stop_stream(se401); | ||
872 | se401_start_stream(se401); | ||
873 | } else { | ||
874 | if (se401->scratch[se401->scratch_use].state != | ||
875 | BUFFER_READY) { | ||
876 | se401->frame[framenr].grabstate = FRAME_ERROR; | ||
877 | return -EIO; | ||
878 | } | ||
879 | se401->scratch[se401->scratch_use].state = BUFFER_BUSY; | ||
880 | if (se401->format == FMT_JANGGU) | ||
881 | decode_JangGu(se401, | ||
882 | &se401->scratch[se401->scratch_use]); | ||
883 | else | ||
884 | decode_bayer(se401, | ||
885 | &se401->scratch[se401->scratch_use]); | ||
886 | |||
887 | se401->scratch[se401->scratch_use].state = | ||
888 | BUFFER_UNUSED; | ||
889 | se401->scratch_use++; | ||
890 | if (se401->scratch_use >= SE401_NUMSCRATCH) | ||
891 | se401->scratch_use = 0; | ||
892 | if (errors > SE401_MAX_ERRORS) { | ||
893 | errors = 0; | ||
894 | dev_info(&se401->dev->dev, | ||
895 | "too many errors, restarting capture\n"); | ||
896 | se401_stop_stream(se401); | ||
897 | se401_start_stream(se401); | ||
898 | } | ||
899 | } | ||
900 | } | ||
901 | |||
902 | if (se401->frame[framenr].grabstate == FRAME_DONE) | ||
903 | if (se401->enhance) | ||
904 | enhance_picture(se401->frame[framenr].data, | ||
905 | se401->cheight * se401->cwidth * 3); | ||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | static void usb_se401_remove_disconnected(struct usb_se401 *se401) | ||
910 | { | ||
911 | int i; | ||
912 | |||
913 | se401->dev = NULL; | ||
914 | |||
915 | for (i = 0; i < SE401_NUMSBUF; i++) | ||
916 | if (se401->urb[i]) { | ||
917 | usb_kill_urb(se401->urb[i]); | ||
918 | usb_free_urb(se401->urb[i]); | ||
919 | se401->urb[i] = NULL; | ||
920 | kfree(se401->sbuf[i].data); | ||
921 | } | ||
922 | |||
923 | for (i = 0; i < SE401_NUMSCRATCH; i++) | ||
924 | kfree(se401->scratch[i].data); | ||
925 | |||
926 | if (se401->inturb) { | ||
927 | usb_kill_urb(se401->inturb); | ||
928 | usb_free_urb(se401->inturb); | ||
929 | } | ||
930 | dev_info(&se401->dev->dev, "%s disconnected", se401->camera_name); | ||
931 | |||
932 | /* Free the memory */ | ||
933 | kfree(se401->width); | ||
934 | kfree(se401->height); | ||
935 | kfree(se401); | ||
936 | } | ||
937 | |||
938 | |||
939 | |||
940 | /**************************************************************************** | ||
941 | * | ||
942 | * Video4Linux | ||
943 | * | ||
944 | ***************************************************************************/ | ||
945 | |||
946 | |||
947 | static int se401_open(struct file *file) | ||
948 | { | ||
949 | struct video_device *dev = video_devdata(file); | ||
950 | struct usb_se401 *se401 = (struct usb_se401 *)dev; | ||
951 | int err = 0; | ||
952 | |||
953 | mutex_lock(&se401->lock); | ||
954 | if (se401->user) { | ||
955 | mutex_unlock(&se401->lock); | ||
956 | return -EBUSY; | ||
957 | } | ||
958 | se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES); | ||
959 | if (se401->fbuf) | ||
960 | file->private_data = dev; | ||
961 | else | ||
962 | err = -ENOMEM; | ||
963 | se401->user = !err; | ||
964 | mutex_unlock(&se401->lock); | ||
965 | |||
966 | return err; | ||
967 | } | ||
968 | |||
969 | static int se401_close(struct file *file) | ||
970 | { | ||
971 | struct video_device *dev = file->private_data; | ||
972 | struct usb_se401 *se401 = (struct usb_se401 *)dev; | ||
973 | int i; | ||
974 | |||
975 | rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES); | ||
976 | if (se401->removed) { | ||
977 | dev_info(&se401->dev->dev, "device unregistered\n"); | ||
978 | usb_se401_remove_disconnected(se401); | ||
979 | } else { | ||
980 | for (i = 0; i < SE401_NUMFRAMES; i++) | ||
981 | se401->frame[i].grabstate = FRAME_UNUSED; | ||
982 | if (se401->streaming) | ||
983 | se401_stop_stream(se401); | ||
984 | se401->user = 0; | ||
985 | } | ||
986 | file->private_data = NULL; | ||
987 | return 0; | ||
988 | } | ||
989 | |||
990 | static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) | ||
991 | { | ||
992 | struct video_device *vdev = file->private_data; | ||
993 | struct usb_se401 *se401 = (struct usb_se401 *)vdev; | ||
994 | |||
995 | if (!se401->dev) | ||
996 | return -EIO; | ||
997 | |||
998 | switch (cmd) { | ||
999 | case VIDIOCGCAP: | ||
1000 | { | ||
1001 | struct video_capability *b = arg; | ||
1002 | strcpy(b->name, se401->camera_name); | ||
1003 | b->type = VID_TYPE_CAPTURE; | ||
1004 | b->channels = 1; | ||
1005 | b->audios = 0; | ||
1006 | b->maxwidth = se401->width[se401->sizes-1]; | ||
1007 | b->maxheight = se401->height[se401->sizes-1]; | ||
1008 | b->minwidth = se401->width[0]; | ||
1009 | b->minheight = se401->height[0]; | ||
1010 | return 0; | ||
1011 | } | ||
1012 | case VIDIOCGCHAN: | ||
1013 | { | ||
1014 | struct video_channel *v = arg; | ||
1015 | |||
1016 | if (v->channel != 0) | ||
1017 | return -EINVAL; | ||
1018 | v->flags = 0; | ||
1019 | v->tuners = 0; | ||
1020 | v->type = VIDEO_TYPE_CAMERA; | ||
1021 | strcpy(v->name, "Camera"); | ||
1022 | return 0; | ||
1023 | } | ||
1024 | case VIDIOCSCHAN: | ||
1025 | { | ||
1026 | struct video_channel *v = arg; | ||
1027 | |||
1028 | if (v->channel != 0) | ||
1029 | return -EINVAL; | ||
1030 | return 0; | ||
1031 | } | ||
1032 | case VIDIOCGPICT: | ||
1033 | { | ||
1034 | struct video_picture *p = arg; | ||
1035 | |||
1036 | se401_get_pict(se401, p); | ||
1037 | return 0; | ||
1038 | } | ||
1039 | case VIDIOCSPICT: | ||
1040 | { | ||
1041 | struct video_picture *p = arg; | ||
1042 | |||
1043 | if (se401_set_pict(se401, p)) | ||
1044 | return -EINVAL; | ||
1045 | return 0; | ||
1046 | } | ||
1047 | case VIDIOCSWIN: | ||
1048 | { | ||
1049 | struct video_window *vw = arg; | ||
1050 | |||
1051 | if (vw->flags) | ||
1052 | return -EINVAL; | ||
1053 | if (vw->clipcount) | ||
1054 | return -EINVAL; | ||
1055 | if (se401_set_size(se401, vw->width, vw->height)) | ||
1056 | return -EINVAL; | ||
1057 | return 0; | ||
1058 | } | ||
1059 | case VIDIOCGWIN: | ||
1060 | { | ||
1061 | struct video_window *vw = arg; | ||
1062 | |||
1063 | vw->x = 0; /* FIXME */ | ||
1064 | vw->y = 0; | ||
1065 | vw->chromakey = 0; | ||
1066 | vw->flags = 0; | ||
1067 | vw->clipcount = 0; | ||
1068 | vw->width = se401->cwidth; | ||
1069 | vw->height = se401->cheight; | ||
1070 | return 0; | ||
1071 | } | ||
1072 | case VIDIOCGMBUF: | ||
1073 | { | ||
1074 | struct video_mbuf *vm = arg; | ||
1075 | int i; | ||
1076 | |||
1077 | memset(vm, 0, sizeof(*vm)); | ||
1078 | vm->size = SE401_NUMFRAMES * se401->maxframesize; | ||
1079 | vm->frames = SE401_NUMFRAMES; | ||
1080 | for (i = 0; i < SE401_NUMFRAMES; i++) | ||
1081 | vm->offsets[i] = se401->maxframesize * i; | ||
1082 | return 0; | ||
1083 | } | ||
1084 | case VIDIOCMCAPTURE: | ||
1085 | { | ||
1086 | struct video_mmap *vm = arg; | ||
1087 | |||
1088 | if (vm->format != VIDEO_PALETTE_RGB24) | ||
1089 | return -EINVAL; | ||
1090 | if (vm->frame >= SE401_NUMFRAMES) | ||
1091 | return -EINVAL; | ||
1092 | if (se401->frame[vm->frame].grabstate != FRAME_UNUSED) | ||
1093 | return -EBUSY; | ||
1094 | |||
1095 | /* Is this according to the v4l spec??? */ | ||
1096 | if (se401_set_size(se401, vm->width, vm->height)) | ||
1097 | return -EINVAL; | ||
1098 | se401->frame[vm->frame].grabstate = FRAME_READY; | ||
1099 | |||
1100 | if (!se401->streaming) | ||
1101 | se401_start_stream(se401); | ||
1102 | |||
1103 | /* Set the picture properties */ | ||
1104 | if (se401->framecount == 0) | ||
1105 | se401_send_pict(se401); | ||
1106 | /* Calibrate the reset level after a few frames. */ | ||
1107 | if (se401->framecount % 20 == 1) | ||
1108 | se401_auto_resetlevel(se401); | ||
1109 | |||
1110 | return 0; | ||
1111 | } | ||
1112 | case VIDIOCSYNC: | ||
1113 | { | ||
1114 | int *frame = arg; | ||
1115 | int ret = 0; | ||
1116 | |||
1117 | if (*frame < 0 || *frame >= SE401_NUMFRAMES) | ||
1118 | return -EINVAL; | ||
1119 | |||
1120 | ret = se401_newframe(se401, *frame); | ||
1121 | se401->frame[*frame].grabstate = FRAME_UNUSED; | ||
1122 | return ret; | ||
1123 | } | ||
1124 | case VIDIOCGFBUF: | ||
1125 | { | ||
1126 | struct video_buffer *vb = arg; | ||
1127 | |||
1128 | memset(vb, 0, sizeof(*vb)); | ||
1129 | return 0; | ||
1130 | } | ||
1131 | case VIDIOCKEY: | ||
1132 | return 0; | ||
1133 | case VIDIOCCAPTURE: | ||
1134 | return -EINVAL; | ||
1135 | case VIDIOCSFBUF: | ||
1136 | return -EINVAL; | ||
1137 | case VIDIOCGTUNER: | ||
1138 | case VIDIOCSTUNER: | ||
1139 | return -EINVAL; | ||
1140 | case VIDIOCGFREQ: | ||
1141 | case VIDIOCSFREQ: | ||
1142 | return -EINVAL; | ||
1143 | case VIDIOCGAUDIO: | ||
1144 | case VIDIOCSAUDIO: | ||
1145 | return -EINVAL; | ||
1146 | default: | ||
1147 | return -ENOIOCTLCMD; | ||
1148 | } /* end switch */ | ||
1149 | |||
1150 | return 0; | ||
1151 | } | ||
1152 | |||
1153 | static long se401_ioctl(struct file *file, | ||
1154 | unsigned int cmd, unsigned long arg) | ||
1155 | { | ||
1156 | return video_usercopy(file, cmd, arg, se401_do_ioctl); | ||
1157 | } | ||
1158 | |||
1159 | static ssize_t se401_read(struct file *file, char __user *buf, | ||
1160 | size_t count, loff_t *ppos) | ||
1161 | { | ||
1162 | int realcount = count, ret = 0; | ||
1163 | struct video_device *dev = file->private_data; | ||
1164 | struct usb_se401 *se401 = (struct usb_se401 *)dev; | ||
1165 | |||
1166 | |||
1167 | if (se401->dev == NULL) | ||
1168 | return -EIO; | ||
1169 | if (realcount > se401->cwidth*se401->cheight*3) | ||
1170 | realcount = se401->cwidth*se401->cheight*3; | ||
1171 | |||
1172 | /* Shouldn't happen: */ | ||
1173 | if (se401->frame[0].grabstate == FRAME_GRABBING) | ||
1174 | return -EBUSY; | ||
1175 | se401->frame[0].grabstate = FRAME_READY; | ||
1176 | se401->frame[1].grabstate = FRAME_UNUSED; | ||
1177 | se401->curframe = 0; | ||
1178 | |||
1179 | if (!se401->streaming) | ||
1180 | se401_start_stream(se401); | ||
1181 | |||
1182 | /* Set the picture properties */ | ||
1183 | if (se401->framecount == 0) | ||
1184 | se401_send_pict(se401); | ||
1185 | /* Calibrate the reset level after a few frames. */ | ||
1186 | if (se401->framecount%20 == 1) | ||
1187 | se401_auto_resetlevel(se401); | ||
1188 | |||
1189 | ret = se401_newframe(se401, 0); | ||
1190 | |||
1191 | se401->frame[0].grabstate = FRAME_UNUSED; | ||
1192 | if (ret) | ||
1193 | return ret; | ||
1194 | if (copy_to_user(buf, se401->frame[0].data, realcount)) | ||
1195 | return -EFAULT; | ||
1196 | |||
1197 | return realcount; | ||
1198 | } | ||
1199 | |||
1200 | static int se401_mmap(struct file *file, struct vm_area_struct *vma) | ||
1201 | { | ||
1202 | struct video_device *dev = file->private_data; | ||
1203 | struct usb_se401 *se401 = (struct usb_se401 *)dev; | ||
1204 | unsigned long start = vma->vm_start; | ||
1205 | unsigned long size = vma->vm_end-vma->vm_start; | ||
1206 | unsigned long page, pos; | ||
1207 | |||
1208 | mutex_lock(&se401->lock); | ||
1209 | |||
1210 | if (se401->dev == NULL) { | ||
1211 | mutex_unlock(&se401->lock); | ||
1212 | return -EIO; | ||
1213 | } | ||
1214 | if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) | ||
1215 | & ~(PAGE_SIZE - 1))) { | ||
1216 | mutex_unlock(&se401->lock); | ||
1217 | return -EINVAL; | ||
1218 | } | ||
1219 | pos = (unsigned long)se401->fbuf; | ||
1220 | while (size > 0) { | ||
1221 | page = vmalloc_to_pfn((void *)pos); | ||
1222 | if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { | ||
1223 | mutex_unlock(&se401->lock); | ||
1224 | return -EAGAIN; | ||
1225 | } | ||
1226 | start += PAGE_SIZE; | ||
1227 | pos += PAGE_SIZE; | ||
1228 | if (size > PAGE_SIZE) | ||
1229 | size -= PAGE_SIZE; | ||
1230 | else | ||
1231 | size = 0; | ||
1232 | } | ||
1233 | mutex_unlock(&se401->lock); | ||
1234 | |||
1235 | return 0; | ||
1236 | } | ||
1237 | |||
1238 | static const struct v4l2_file_operations se401_fops = { | ||
1239 | .owner = THIS_MODULE, | ||
1240 | .open = se401_open, | ||
1241 | .release = se401_close, | ||
1242 | .read = se401_read, | ||
1243 | .mmap = se401_mmap, | ||
1244 | .ioctl = se401_ioctl, | ||
1245 | }; | ||
1246 | static struct video_device se401_template = { | ||
1247 | .name = "se401 USB camera", | ||
1248 | .fops = &se401_fops, | ||
1249 | .release = video_device_release_empty, | ||
1250 | }; | ||
1251 | |||
1252 | |||
1253 | |||
1254 | /***************************/ | ||
1255 | static int se401_init(struct usb_se401 *se401, int button) | ||
1256 | { | ||
1257 | int i = 0, rc; | ||
1258 | unsigned char cp[0x40]; | ||
1259 | char temp[200]; | ||
1260 | int slen; | ||
1261 | |||
1262 | /* led on */ | ||
1263 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); | ||
1264 | |||
1265 | /* get camera descriptor */ | ||
1266 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, | ||
1267 | cp, sizeof(cp)); | ||
1268 | if (cp[1] != 0x41) { | ||
1269 | err("Wrong descriptor type"); | ||
1270 | return 1; | ||
1271 | } | ||
1272 | slen = snprintf(temp, 200, "ExtraFeatures: %d", cp[3]); | ||
1273 | |||
1274 | se401->sizes = cp[4] + cp[5] * 256; | ||
1275 | se401->width = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); | ||
1276 | if (!se401->width) | ||
1277 | return 1; | ||
1278 | se401->height = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); | ||
1279 | if (!se401->height) { | ||
1280 | kfree(se401->width); | ||
1281 | return 1; | ||
1282 | } | ||
1283 | for (i = 0; i < se401->sizes; i++) { | ||
1284 | se401->width[i] = cp[6 + i * 4 + 0] + cp[6 + i*4 + 1] * 256; | ||
1285 | se401->height[i] = cp[6 + i * 4 + 2] + cp[6 + i * 4 + 3] * 256; | ||
1286 | } | ||
1287 | slen += snprintf(temp + slen, 200 - slen, " Sizes:"); | ||
1288 | for (i = 0; i < se401->sizes; i++) { | ||
1289 | slen += snprintf(temp + slen, 200 - slen, | ||
1290 | " %dx%d", se401->width[i], se401->height[i]); | ||
1291 | } | ||
1292 | dev_info(&se401->dev->dev, "%s\n", temp); | ||
1293 | se401->maxframesize = se401->width[se401->sizes-1] * | ||
1294 | se401->height[se401->sizes - 1] * 3; | ||
1295 | |||
1296 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp)); | ||
1297 | se401->cwidth = cp[0]+cp[1]*256; | ||
1298 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp)); | ||
1299 | se401->cheight = cp[0]+cp[1]*256; | ||
1300 | |||
1301 | if (!(cp[2] & SE401_FORMAT_BAYER)) { | ||
1302 | err("Bayer format not supported!"); | ||
1303 | return 1; | ||
1304 | } | ||
1305 | /* set output mode (BAYER) */ | ||
1306 | se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, | ||
1307 | SE401_FORMAT_BAYER, NULL, 0); | ||
1308 | |||
1309 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp)); | ||
1310 | se401->brightness = cp[0]+cp[1]*256; | ||
1311 | /* some default values */ | ||
1312 | se401->resetlevel = 0x2d; | ||
1313 | se401->rgain = 0x20; | ||
1314 | se401->ggain = 0x20; | ||
1315 | se401->bgain = 0x20; | ||
1316 | se401_set_exposure(se401, 20000); | ||
1317 | se401->palette = VIDEO_PALETTE_RGB24; | ||
1318 | se401->enhance = 1; | ||
1319 | se401->dropped = 0; | ||
1320 | se401->error = 0; | ||
1321 | se401->framecount = 0; | ||
1322 | se401->readcount = 0; | ||
1323 | |||
1324 | /* Start interrupt transfers for snapshot button */ | ||
1325 | if (button) { | ||
1326 | se401->inturb = usb_alloc_urb(0, GFP_KERNEL); | ||
1327 | if (!se401->inturb) { | ||
1328 | dev_info(&se401->dev->dev, | ||
1329 | "Allocation of inturb failed\n"); | ||
1330 | return 1; | ||
1331 | } | ||
1332 | usb_fill_int_urb(se401->inturb, se401->dev, | ||
1333 | usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT), | ||
1334 | &se401->button, sizeof(se401->button), | ||
1335 | se401_button_irq, | ||
1336 | se401, | ||
1337 | 8 | ||
1338 | ); | ||
1339 | if (usb_submit_urb(se401->inturb, GFP_KERNEL)) { | ||
1340 | dev_info(&se401->dev->dev, "int urb burned down\n"); | ||
1341 | return 1; | ||
1342 | } | ||
1343 | } else | ||
1344 | se401->inturb = NULL; | ||
1345 | |||
1346 | /* Flash the led */ | ||
1347 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); | ||
1348 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); | ||
1349 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0); | ||
1350 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0); | ||
1351 | |||
1352 | return 0; | ||
1353 | } | ||
1354 | |||
1355 | static int se401_probe(struct usb_interface *intf, | ||
1356 | const struct usb_device_id *id) | ||
1357 | { | ||
1358 | struct usb_device *dev = interface_to_usbdev(intf); | ||
1359 | struct usb_interface_descriptor *interface; | ||
1360 | struct usb_se401 *se401; | ||
1361 | char *camera_name = NULL; | ||
1362 | int button = 1; | ||
1363 | |||
1364 | /* We don't handle multi-config cameras */ | ||
1365 | if (dev->descriptor.bNumConfigurations != 1) | ||
1366 | return -ENODEV; | ||
1367 | |||
1368 | interface = &intf->cur_altsetting->desc; | ||
1369 | |||
1370 | /* Is it an se401? */ | ||
1371 | if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 && | ||
1372 | le16_to_cpu(dev->descriptor.idProduct) == 0x0004) { | ||
1373 | camera_name = "Endpoints/Aox SE401"; | ||
1374 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 && | ||
1375 | le16_to_cpu(dev->descriptor.idProduct) == 0x030b) { | ||
1376 | camera_name = "Philips PCVC665K"; | ||
1377 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && | ||
1378 | le16_to_cpu(dev->descriptor.idProduct) == 0x5001) { | ||
1379 | camera_name = "Kensington VideoCAM 67014"; | ||
1380 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && | ||
1381 | le16_to_cpu(dev->descriptor.idProduct) == 0x5002) { | ||
1382 | camera_name = "Kensington VideoCAM 6701(5/7)"; | ||
1383 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && | ||
1384 | le16_to_cpu(dev->descriptor.idProduct) == 0x5003) { | ||
1385 | camera_name = "Kensington VideoCAM 67016"; | ||
1386 | button = 0; | ||
1387 | } else | ||
1388 | return -ENODEV; | ||
1389 | |||
1390 | /* Checking vendor/product should be enough, but what the hell */ | ||
1391 | if (interface->bInterfaceClass != 0x00) | ||
1392 | return -ENODEV; | ||
1393 | if (interface->bInterfaceSubClass != 0x00) | ||
1394 | return -ENODEV; | ||
1395 | |||
1396 | /* We found one */ | ||
1397 | dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name); | ||
1398 | |||
1399 | se401 = kzalloc(sizeof(*se401), GFP_KERNEL); | ||
1400 | if (se401 == NULL) { | ||
1401 | err("couldn't kmalloc se401 struct"); | ||
1402 | return -ENOMEM; | ||
1403 | } | ||
1404 | |||
1405 | se401->dev = dev; | ||
1406 | se401->iface = interface->bInterfaceNumber; | ||
1407 | se401->camera_name = camera_name; | ||
1408 | |||
1409 | dev_info(&intf->dev, "firmware version: %02x\n", | ||
1410 | le16_to_cpu(dev->descriptor.bcdDevice) & 255); | ||
1411 | |||
1412 | if (se401_init(se401, button)) { | ||
1413 | kfree(se401); | ||
1414 | return -EIO; | ||
1415 | } | ||
1416 | |||
1417 | memcpy(&se401->vdev, &se401_template, sizeof(se401_template)); | ||
1418 | memcpy(se401->vdev.name, se401->camera_name, | ||
1419 | strlen(se401->camera_name)); | ||
1420 | init_waitqueue_head(&se401->wq); | ||
1421 | mutex_init(&se401->lock); | ||
1422 | wmb(); | ||
1423 | |||
1424 | if (video_register_device(&se401->vdev, | ||
1425 | VFL_TYPE_GRABBER, video_nr) < 0) { | ||
1426 | kfree(se401); | ||
1427 | err("video_register_device failed"); | ||
1428 | return -EIO; | ||
1429 | } | ||
1430 | dev_info(&intf->dev, "registered new video device: %s\n", | ||
1431 | video_device_node_name(&se401->vdev)); | ||
1432 | |||
1433 | usb_set_intfdata(intf, se401); | ||
1434 | return 0; | ||
1435 | } | ||
1436 | |||
1437 | static void se401_disconnect(struct usb_interface *intf) | ||
1438 | { | ||
1439 | struct usb_se401 *se401 = usb_get_intfdata(intf); | ||
1440 | |||
1441 | usb_set_intfdata(intf, NULL); | ||
1442 | if (se401) { | ||
1443 | video_unregister_device(&se401->vdev); | ||
1444 | if (!se401->user) | ||
1445 | usb_se401_remove_disconnected(se401); | ||
1446 | else { | ||
1447 | se401->frame[0].grabstate = FRAME_ERROR; | ||
1448 | se401->frame[0].grabstate = FRAME_ERROR; | ||
1449 | |||
1450 | se401->streaming = 0; | ||
1451 | |||
1452 | wake_up_interruptible(&se401->wq); | ||
1453 | se401->removed = 1; | ||
1454 | } | ||
1455 | } | ||
1456 | } | ||
1457 | |||
1458 | static struct usb_driver se401_driver = { | ||
1459 | .name = "se401", | ||
1460 | .id_table = device_table, | ||
1461 | .probe = se401_probe, | ||
1462 | .disconnect = se401_disconnect, | ||
1463 | }; | ||
1464 | |||
1465 | |||
1466 | |||
1467 | /**************************************************************************** | ||
1468 | * | ||
1469 | * Module routines | ||
1470 | * | ||
1471 | ***************************************************************************/ | ||
1472 | |||
1473 | static int __init usb_se401_init(void) | ||
1474 | { | ||
1475 | printk(KERN_INFO "SE401 usb camera driver version %s registering\n", | ||
1476 | version); | ||
1477 | if (flickerless) | ||
1478 | if (flickerless != 50 && flickerless != 60) { | ||
1479 | printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n"); | ||
1480 | return -1; | ||
1481 | } | ||
1482 | return usb_register(&se401_driver); | ||
1483 | } | ||
1484 | |||
1485 | static void __exit usb_se401_exit(void) | ||
1486 | { | ||
1487 | usb_deregister(&se401_driver); | ||
1488 | printk(KERN_INFO "SE401 driver deregistered\frame"); | ||
1489 | } | ||
1490 | |||
1491 | module_init(usb_se401_init); | ||
1492 | module_exit(usb_se401_exit); | ||
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h deleted file mode 100644 index bf7d2e9765b0..000000000000 --- a/drivers/media/video/se401.h +++ /dev/null | |||
@@ -1,236 +0,0 @@ | |||
1 | |||
2 | #ifndef __LINUX_se401_H | ||
3 | #define __LINUX_se401_H | ||
4 | |||
5 | #include <linux/uaccess.h> | ||
6 | #include <linux/videodev.h> | ||
7 | #include <media/v4l2-common.h> | ||
8 | #include <media/v4l2-ioctl.h> | ||
9 | #include <linux/mutex.h> | ||
10 | |||
11 | #define se401_DEBUG /* Turn on debug messages */ | ||
12 | |||
13 | #ifdef se401_DEBUG | ||
14 | # define PDEBUG(level, fmt, args...) \ | ||
15 | if (debug >= level) \ | ||
16 | info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args) | ||
17 | #else | ||
18 | # define PDEBUG(level, fmt, args...) do {} while (0) | ||
19 | #endif | ||
20 | |||
21 | /* An almost drop-in replacement for sleep_on_interruptible */ | ||
22 | #define wait_interruptible(test, queue, wait) \ | ||
23 | { \ | ||
24 | add_wait_queue(queue, wait); \ | ||
25 | set_current_state(TASK_INTERRUPTIBLE); \ | ||
26 | if (test) \ | ||
27 | schedule(); \ | ||
28 | remove_wait_queue(queue, wait); \ | ||
29 | set_current_state(TASK_RUNNING); \ | ||
30 | if (signal_pending(current)) \ | ||
31 | break; \ | ||
32 | } | ||
33 | |||
34 | #define SE401_REQ_GET_CAMERA_DESCRIPTOR 0x06 | ||
35 | #define SE401_REQ_START_CONTINUOUS_CAPTURE 0x41 | ||
36 | #define SE401_REQ_STOP_CONTINUOUS_CAPTURE 0x42 | ||
37 | #define SE401_REQ_CAPTURE_FRAME 0x43 | ||
38 | #define SE401_REQ_GET_BRT 0x44 | ||
39 | #define SE401_REQ_SET_BRT 0x45 | ||
40 | #define SE401_REQ_GET_WIDTH 0x4c | ||
41 | #define SE401_REQ_SET_WIDTH 0x4d | ||
42 | #define SE401_REQ_GET_HEIGHT 0x4e | ||
43 | #define SE401_REQ_SET_HEIGHT 0x4f | ||
44 | #define SE401_REQ_GET_OUTPUT_MODE 0x50 | ||
45 | #define SE401_REQ_SET_OUTPUT_MODE 0x51 | ||
46 | #define SE401_REQ_GET_EXT_FEATURE 0x52 | ||
47 | #define SE401_REQ_SET_EXT_FEATURE 0x53 | ||
48 | #define SE401_REQ_CAMERA_POWER 0x56 | ||
49 | #define SE401_REQ_LED_CONTROL 0x57 | ||
50 | #define SE401_REQ_BIOS 0xff | ||
51 | |||
52 | #define SE401_BIOS_READ 0x07 | ||
53 | |||
54 | #define SE401_FORMAT_BAYER 0x40 | ||
55 | |||
56 | /* Hyundai hv7131b registers | ||
57 | 7121 and 7141 should be the same (haven't really checked...) */ | ||
58 | /* Mode registers: */ | ||
59 | #define HV7131_REG_MODE_A 0x00 | ||
60 | #define HV7131_REG_MODE_B 0x01 | ||
61 | #define HV7131_REG_MODE_C 0x02 | ||
62 | /* Frame registers: */ | ||
63 | #define HV7131_REG_FRSU 0x10 | ||
64 | #define HV7131_REG_FRSL 0x11 | ||
65 | #define HV7131_REG_FCSU 0x12 | ||
66 | #define HV7131_REG_FCSL 0x13 | ||
67 | #define HV7131_REG_FWHU 0x14 | ||
68 | #define HV7131_REG_FWHL 0x15 | ||
69 | #define HV7131_REG_FWWU 0x16 | ||
70 | #define HV7131_REG_FWWL 0x17 | ||
71 | /* Timing registers: */ | ||
72 | #define HV7131_REG_THBU 0x20 | ||
73 | #define HV7131_REG_THBL 0x21 | ||
74 | #define HV7131_REG_TVBU 0x22 | ||
75 | #define HV7131_REG_TVBL 0x23 | ||
76 | #define HV7131_REG_TITU 0x25 | ||
77 | #define HV7131_REG_TITM 0x26 | ||
78 | #define HV7131_REG_TITL 0x27 | ||
79 | #define HV7131_REG_TMCD 0x28 | ||
80 | /* Adjust Registers: */ | ||
81 | #define HV7131_REG_ARLV 0x30 | ||
82 | #define HV7131_REG_ARCG 0x31 | ||
83 | #define HV7131_REG_AGCG 0x32 | ||
84 | #define HV7131_REG_ABCG 0x33 | ||
85 | #define HV7131_REG_APBV 0x34 | ||
86 | #define HV7131_REG_ASLP 0x54 | ||
87 | /* Offset Registers: */ | ||
88 | #define HV7131_REG_OFSR 0x50 | ||
89 | #define HV7131_REG_OFSG 0x51 | ||
90 | #define HV7131_REG_OFSB 0x52 | ||
91 | /* REset level statistics registers: */ | ||
92 | #define HV7131_REG_LOREFNOH 0x57 | ||
93 | #define HV7131_REG_LOREFNOL 0x58 | ||
94 | #define HV7131_REG_HIREFNOH 0x59 | ||
95 | #define HV7131_REG_HIREFNOL 0x5a | ||
96 | |||
97 | /* se401 registers */ | ||
98 | #define SE401_OPERATINGMODE 0x2000 | ||
99 | |||
100 | |||
101 | /* size of usb transfers */ | ||
102 | #define SE401_PACKETSIZE 4096 | ||
103 | /* number of queued bulk transfers to use, should be about 8 */ | ||
104 | #define SE401_NUMSBUF 1 | ||
105 | /* read the usb specs for this one :) */ | ||
106 | #define SE401_VIDEO_ENDPOINT 1 | ||
107 | #define SE401_BUTTON_ENDPOINT 2 | ||
108 | /* number of frames supported by the v4l part */ | ||
109 | #define SE401_NUMFRAMES 2 | ||
110 | /* scratch buffers for passing data to the decoders */ | ||
111 | #define SE401_NUMSCRATCH 32 | ||
112 | /* maximum amount of data in a JangGu packet */ | ||
113 | #define SE401_VLCDATALEN 1024 | ||
114 | /* number of nul sized packets to receive before kicking the camera */ | ||
115 | #define SE401_MAX_NULLPACKETS 4000 | ||
116 | /* number of decoding errors before kicking the camera */ | ||
117 | #define SE401_MAX_ERRORS 200 | ||
118 | |||
119 | struct usb_device; | ||
120 | |||
121 | struct se401_sbuf { | ||
122 | unsigned char *data; | ||
123 | }; | ||
124 | |||
125 | enum { | ||
126 | FRAME_UNUSED, /* Unused (no MCAPTURE) */ | ||
127 | FRAME_READY, /* Ready to start grabbing */ | ||
128 | FRAME_GRABBING, /* In the process of being grabbed into */ | ||
129 | FRAME_DONE, /* Finished grabbing, but not been synced yet */ | ||
130 | FRAME_ERROR, /* Something bad happened while processing */ | ||
131 | }; | ||
132 | |||
133 | enum { | ||
134 | FMT_BAYER, | ||
135 | FMT_JANGGU, | ||
136 | }; | ||
137 | |||
138 | enum { | ||
139 | BUFFER_UNUSED, | ||
140 | BUFFER_READY, | ||
141 | BUFFER_BUSY, | ||
142 | BUFFER_DONE, | ||
143 | }; | ||
144 | |||
145 | struct se401_scratch { | ||
146 | unsigned char *data; | ||
147 | volatile int state; | ||
148 | int offset; | ||
149 | int length; | ||
150 | }; | ||
151 | |||
152 | struct se401_frame { | ||
153 | unsigned char *data; /* Frame buffer */ | ||
154 | |||
155 | volatile int grabstate; /* State of grabbing */ | ||
156 | |||
157 | unsigned char *curline; | ||
158 | int curlinepix; | ||
159 | int curpix; | ||
160 | }; | ||
161 | |||
162 | struct usb_se401 { | ||
163 | struct video_device vdev; | ||
164 | |||
165 | /* Device structure */ | ||
166 | struct usb_device *dev; | ||
167 | |||
168 | unsigned char iface; | ||
169 | |||
170 | char *camera_name; | ||
171 | |||
172 | int change; | ||
173 | int brightness; | ||
174 | int hue; | ||
175 | int rgain; | ||
176 | int ggain; | ||
177 | int bgain; | ||
178 | int expose_h; | ||
179 | int expose_m; | ||
180 | int expose_l; | ||
181 | int resetlevel; | ||
182 | |||
183 | int enhance; | ||
184 | |||
185 | int format; | ||
186 | int sizes; | ||
187 | int *width; | ||
188 | int *height; | ||
189 | int cwidth; /* current width */ | ||
190 | int cheight; /* current height */ | ||
191 | int palette; | ||
192 | int maxframesize; | ||
193 | int cframesize; /* current framesize */ | ||
194 | |||
195 | struct mutex lock; | ||
196 | int user; /* user count for exclusive use */ | ||
197 | int removed; /* device disconnected */ | ||
198 | |||
199 | int streaming; /* Are we streaming video? */ | ||
200 | |||
201 | char *fbuf; /* Videodev buffer area */ | ||
202 | |||
203 | struct urb *urb[SE401_NUMSBUF]; | ||
204 | struct urb *inturb; | ||
205 | |||
206 | int button; | ||
207 | int buttonpressed; | ||
208 | |||
209 | int curframe; /* Current receiving frame */ | ||
210 | struct se401_frame frame[SE401_NUMFRAMES]; | ||
211 | int readcount; | ||
212 | int framecount; | ||
213 | int error; | ||
214 | int dropped; | ||
215 | |||
216 | int scratch_next; | ||
217 | int scratch_use; | ||
218 | int scratch_overflow; | ||
219 | struct se401_scratch scratch[SE401_NUMSCRATCH]; | ||
220 | |||
221 | /* Decoder specific data: */ | ||
222 | unsigned char vlcdata[SE401_VLCDATALEN]; | ||
223 | int vlcdatapos; | ||
224 | int bayeroffset; | ||
225 | |||
226 | struct se401_sbuf sbuf[SE401_NUMSBUF]; | ||
227 | |||
228 | wait_queue_head_t wq; /* Processes waiting */ | ||
229 | |||
230 | int nullpackets; | ||
231 | }; | ||
232 | |||
233 | |||
234 | |||
235 | #endif | ||
236 | |||
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 2486520582f2..954222bc3458 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -1786,7 +1786,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q, | |||
1786 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1786 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1787 | pcdev->field, | 1787 | pcdev->field, |
1788 | sizeof(struct sh_mobile_ceu_buffer), | 1788 | sizeof(struct sh_mobile_ceu_buffer), |
1789 | icd, NULL); | 1789 | icd, &icd->video_lock); |
1790 | } | 1790 | } |
1791 | 1791 | ||
1792 | static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd, | 1792 | static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd, |
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index f49fbfb7dc13..84984f64b234 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c | |||
@@ -2189,6 +2189,7 @@ sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg) | |||
2189 | memset(&i, 0, sizeof(i)); | 2189 | memset(&i, 0, sizeof(i)); |
2190 | strcpy(i.name, "Camera"); | 2190 | strcpy(i.name, "Camera"); |
2191 | i.type = V4L2_INPUT_TYPE_CAMERA; | 2191 | i.type = V4L2_INPUT_TYPE_CAMERA; |
2192 | i.capabilities = V4L2_IN_CAP_STD; | ||
2192 | 2193 | ||
2193 | if (copy_to_user(arg, &i, sizeof(i))) | 2194 | if (copy_to_user(arg, &i, sizeof(i))) |
2194 | return -EFAULT; | 2195 | return -EFAULT; |
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h index ccfa59c54552..41064c7b5ef8 100644 --- a/drivers/media/video/sn9c102/sn9c102_devtable.h +++ b/drivers/media/video/sn9c102/sn9c102_devtable.h | |||
@@ -43,9 +43,7 @@ static const struct usb_device_id sn9c102_id_table[] = { | |||
43 | #if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE | 43 | #if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE |
44 | { SN9C102_USB_DEVICE(0x0c45, 0x6001, BRIDGE_SN9C102), }, | 44 | { SN9C102_USB_DEVICE(0x0c45, 0x6001, BRIDGE_SN9C102), }, |
45 | { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), }, | 45 | { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), }, |
46 | #endif | ||
47 | { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), }, | 46 | { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), }, |
48 | #if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE | ||
49 | { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), }, | 47 | { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), }, |
50 | { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), }, | 48 | { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), }, |
51 | /* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */ | 49 | /* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */ |
@@ -56,8 +54,8 @@ static const struct usb_device_id sn9c102_id_table[] = { | |||
56 | #if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE | 54 | #if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE |
57 | { SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), }, | 55 | { SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), }, |
58 | { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), }, | 56 | { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), }, |
59 | #endif | ||
60 | { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), }, | 57 | { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), }, |
58 | #endif | ||
61 | { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), }, | 59 | { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), }, |
62 | #if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE | 60 | #if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE |
63 | { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), }, | 61 | { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), }, |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 052bd6dfa5a7..a66811b43710 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/regulator/consumer.h> | ||
27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
28 | #include <linux/pm_runtime.h> | 29 | #include <linux/pm_runtime.h> |
29 | #include <linux/vmalloc.h> | 30 | #include <linux/vmalloc.h> |
@@ -43,6 +44,51 @@ static LIST_HEAD(hosts); | |||
43 | static LIST_HEAD(devices); | 44 | static LIST_HEAD(devices); |
44 | static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */ | 45 | static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */ |
45 | 46 | ||
47 | static int soc_camera_power_set(struct soc_camera_device *icd, | ||
48 | struct soc_camera_link *icl, | ||
49 | int power_on) | ||
50 | { | ||
51 | int ret; | ||
52 | |||
53 | if (power_on) { | ||
54 | ret = regulator_bulk_enable(icl->num_regulators, | ||
55 | icl->regulators); | ||
56 | if (ret < 0) { | ||
57 | dev_err(&icd->dev, "Cannot enable regulators\n"); | ||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | if (icl->power) | ||
62 | ret = icl->power(icd->pdev, power_on); | ||
63 | if (ret < 0) { | ||
64 | dev_err(&icd->dev, | ||
65 | "Platform failed to power-on the camera.\n"); | ||
66 | |||
67 | regulator_bulk_disable(icl->num_regulators, | ||
68 | icl->regulators); | ||
69 | return ret; | ||
70 | } | ||
71 | } else { | ||
72 | ret = 0; | ||
73 | if (icl->power) | ||
74 | ret = icl->power(icd->pdev, 0); | ||
75 | if (ret < 0) { | ||
76 | dev_err(&icd->dev, | ||
77 | "Platform failed to power-off the camera.\n"); | ||
78 | return ret; | ||
79 | } | ||
80 | |||
81 | ret = regulator_bulk_disable(icl->num_regulators, | ||
82 | icl->regulators); | ||
83 | if (ret < 0) { | ||
84 | dev_err(&icd->dev, "Cannot disable regulators\n"); | ||
85 | return ret; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
46 | const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( | 92 | const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( |
47 | struct soc_camera_device *icd, unsigned int fourcc) | 93 | struct soc_camera_device *icd, unsigned int fourcc) |
48 | { | 94 | { |
@@ -352,12 +398,6 @@ static int soc_camera_open(struct file *file) | |||
352 | return -EINVAL; | 398 | return -EINVAL; |
353 | } | 399 | } |
354 | 400 | ||
355 | /* | ||
356 | * Protect against icd->ops->remove() until we module_get() both | ||
357 | * drivers. | ||
358 | */ | ||
359 | mutex_lock(&icd->video_lock); | ||
360 | |||
361 | icd->use_count++; | 401 | icd->use_count++; |
362 | 402 | ||
363 | /* Now we really have to activate the camera */ | 403 | /* Now we really have to activate the camera */ |
@@ -375,11 +415,9 @@ static int soc_camera_open(struct file *file) | |||
375 | }, | 415 | }, |
376 | }; | 416 | }; |
377 | 417 | ||
378 | if (icl->power) { | 418 | ret = soc_camera_power_set(icd, icl, 1); |
379 | ret = icl->power(icd->pdev, 1); | 419 | if (ret < 0) |
380 | if (ret < 0) | 420 | goto epower; |
381 | goto epower; | ||
382 | } | ||
383 | 421 | ||
384 | /* The camera could have been already on, try to reset */ | 422 | /* The camera could have been already on, try to reset */ |
385 | if (icl->reset) | 423 | if (icl->reset) |
@@ -412,8 +450,6 @@ static int soc_camera_open(struct file *file) | |||
412 | file->private_data = icd; | 450 | file->private_data = icd; |
413 | dev_dbg(&icd->dev, "camera device open\n"); | 451 | dev_dbg(&icd->dev, "camera device open\n"); |
414 | 452 | ||
415 | mutex_unlock(&icd->video_lock); | ||
416 | |||
417 | return 0; | 453 | return 0; |
418 | 454 | ||
419 | /* | 455 | /* |
@@ -425,11 +461,9 @@ esfmt: | |||
425 | eresume: | 461 | eresume: |
426 | ici->ops->remove(icd); | 462 | ici->ops->remove(icd); |
427 | eiciadd: | 463 | eiciadd: |
428 | if (icl->power) | 464 | soc_camera_power_set(icd, icl, 0); |
429 | icl->power(icd->pdev, 0); | ||
430 | epower: | 465 | epower: |
431 | icd->use_count--; | 466 | icd->use_count--; |
432 | mutex_unlock(&icd->video_lock); | ||
433 | module_put(ici->ops->owner); | 467 | module_put(ici->ops->owner); |
434 | 468 | ||
435 | return ret; | 469 | return ret; |
@@ -440,7 +474,6 @@ static int soc_camera_close(struct file *file) | |||
440 | struct soc_camera_device *icd = file->private_data; | 474 | struct soc_camera_device *icd = file->private_data; |
441 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 475 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
442 | 476 | ||
443 | mutex_lock(&icd->video_lock); | ||
444 | icd->use_count--; | 477 | icd->use_count--; |
445 | if (!icd->use_count) { | 478 | if (!icd->use_count) { |
446 | struct soc_camera_link *icl = to_soc_camera_link(icd); | 479 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
@@ -450,15 +483,12 @@ static int soc_camera_close(struct file *file) | |||
450 | 483 | ||
451 | ici->ops->remove(icd); | 484 | ici->ops->remove(icd); |
452 | 485 | ||
453 | if (icl->power) | 486 | soc_camera_power_set(icd, icl, 0); |
454 | icl->power(icd->pdev, 0); | ||
455 | } | 487 | } |
456 | 488 | ||
457 | if (icd->streamer == file) | 489 | if (icd->streamer == file) |
458 | icd->streamer = NULL; | 490 | icd->streamer = NULL; |
459 | 491 | ||
460 | mutex_unlock(&icd->video_lock); | ||
461 | |||
462 | module_put(ici->ops->owner); | 492 | module_put(ici->ops->owner); |
463 | 493 | ||
464 | dev_dbg(&icd->dev, "camera device close\n"); | 494 | dev_dbg(&icd->dev, "camera device close\n"); |
@@ -517,7 +547,7 @@ static struct v4l2_file_operations soc_camera_fops = { | |||
517 | .owner = THIS_MODULE, | 547 | .owner = THIS_MODULE, |
518 | .open = soc_camera_open, | 548 | .open = soc_camera_open, |
519 | .release = soc_camera_close, | 549 | .release = soc_camera_close, |
520 | .ioctl = video_ioctl2, | 550 | .unlocked_ioctl = video_ioctl2, |
521 | .read = soc_camera_read, | 551 | .read = soc_camera_read, |
522 | .mmap = soc_camera_mmap, | 552 | .mmap = soc_camera_mmap, |
523 | .poll = soc_camera_poll, | 553 | .poll = soc_camera_poll, |
@@ -534,12 +564,9 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, | |||
534 | if (icd->streamer && icd->streamer != file) | 564 | if (icd->streamer && icd->streamer != file) |
535 | return -EBUSY; | 565 | return -EBUSY; |
536 | 566 | ||
537 | mutex_lock(&icd->vb_vidq.vb_lock); | ||
538 | |||
539 | if (icd->vb_vidq.bufs[0]) { | 567 | if (icd->vb_vidq.bufs[0]) { |
540 | dev_err(&icd->dev, "S_FMT denied: queue initialised\n"); | 568 | dev_err(&icd->dev, "S_FMT denied: queue initialised\n"); |
541 | ret = -EBUSY; | 569 | return -EBUSY; |
542 | goto unlock; | ||
543 | } | 570 | } |
544 | 571 | ||
545 | ret = soc_camera_set_fmt(icd, f); | 572 | ret = soc_camera_set_fmt(icd, f); |
@@ -547,9 +574,6 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, | |||
547 | if (!ret && !icd->streamer) | 574 | if (!ret && !icd->streamer) |
548 | icd->streamer = file; | 575 | icd->streamer = file; |
549 | 576 | ||
550 | unlock: | ||
551 | mutex_unlock(&icd->vb_vidq.vb_lock); | ||
552 | |||
553 | return ret; | 577 | return ret; |
554 | } | 578 | } |
555 | 579 | ||
@@ -622,15 +646,11 @@ static int soc_camera_streamon(struct file *file, void *priv, | |||
622 | if (icd->streamer != file) | 646 | if (icd->streamer != file) |
623 | return -EBUSY; | 647 | return -EBUSY; |
624 | 648 | ||
625 | mutex_lock(&icd->video_lock); | ||
626 | |||
627 | v4l2_subdev_call(sd, video, s_stream, 1); | 649 | v4l2_subdev_call(sd, video, s_stream, 1); |
628 | 650 | ||
629 | /* This calls buf_queue from host driver's videobuf_queue_ops */ | 651 | /* This calls buf_queue from host driver's videobuf_queue_ops */ |
630 | ret = videobuf_streamon(&icd->vb_vidq); | 652 | ret = videobuf_streamon(&icd->vb_vidq); |
631 | 653 | ||
632 | mutex_unlock(&icd->video_lock); | ||
633 | |||
634 | return ret; | 654 | return ret; |
635 | } | 655 | } |
636 | 656 | ||
@@ -648,8 +668,6 @@ static int soc_camera_streamoff(struct file *file, void *priv, | |||
648 | if (icd->streamer != file) | 668 | if (icd->streamer != file) |
649 | return -EBUSY; | 669 | return -EBUSY; |
650 | 670 | ||
651 | mutex_lock(&icd->video_lock); | ||
652 | |||
653 | /* | 671 | /* |
654 | * This calls buf_release from host driver's videobuf_queue_ops for all | 672 | * This calls buf_release from host driver's videobuf_queue_ops for all |
655 | * remaining buffers. When the last buffer is freed, stop capture | 673 | * remaining buffers. When the last buffer is freed, stop capture |
@@ -658,8 +676,6 @@ static int soc_camera_streamoff(struct file *file, void *priv, | |||
658 | 676 | ||
659 | v4l2_subdev_call(sd, video, s_stream, 0); | 677 | v4l2_subdev_call(sd, video, s_stream, 0); |
660 | 678 | ||
661 | mutex_unlock(&icd->video_lock); | ||
662 | |||
663 | return 0; | 679 | return 0; |
664 | } | 680 | } |
665 | 681 | ||
@@ -748,9 +764,7 @@ static int soc_camera_g_crop(struct file *file, void *fh, | |||
748 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 764 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
749 | int ret; | 765 | int ret; |
750 | 766 | ||
751 | mutex_lock(&icd->vb_vidq.vb_lock); | ||
752 | ret = ici->ops->get_crop(icd, a); | 767 | ret = ici->ops->get_crop(icd, a); |
753 | mutex_unlock(&icd->vb_vidq.vb_lock); | ||
754 | 768 | ||
755 | return ret; | 769 | return ret; |
756 | } | 770 | } |
@@ -775,9 +789,6 @@ static int soc_camera_s_crop(struct file *file, void *fh, | |||
775 | dev_dbg(&icd->dev, "S_CROP(%ux%u@%u:%u)\n", | 789 | dev_dbg(&icd->dev, "S_CROP(%ux%u@%u:%u)\n", |
776 | rect->width, rect->height, rect->left, rect->top); | 790 | rect->width, rect->height, rect->left, rect->top); |
777 | 791 | ||
778 | /* Cropping is allowed during a running capture, guard consistency */ | ||
779 | mutex_lock(&icd->vb_vidq.vb_lock); | ||
780 | |||
781 | /* If get_crop fails, we'll let host and / or client drivers decide */ | 792 | /* If get_crop fails, we'll let host and / or client drivers decide */ |
782 | ret = ici->ops->get_crop(icd, ¤t_crop); | 793 | ret = ici->ops->get_crop(icd, ¤t_crop); |
783 | 794 | ||
@@ -795,8 +806,6 @@ static int soc_camera_s_crop(struct file *file, void *fh, | |||
795 | ret = ici->ops->set_crop(icd, a); | 806 | ret = ici->ops->set_crop(icd, a); |
796 | } | 807 | } |
797 | 808 | ||
798 | mutex_unlock(&icd->vb_vidq.vb_lock); | ||
799 | |||
800 | return ret; | 809 | return ret; |
801 | } | 810 | } |
802 | 811 | ||
@@ -941,14 +950,14 @@ static int soc_camera_probe(struct device *dev) | |||
941 | 950 | ||
942 | dev_info(dev, "Probing %s\n", dev_name(dev)); | 951 | dev_info(dev, "Probing %s\n", dev_name(dev)); |
943 | 952 | ||
944 | if (icl->power) { | 953 | ret = regulator_bulk_get(icd->pdev, icl->num_regulators, |
945 | ret = icl->power(icd->pdev, 1); | 954 | icl->regulators); |
946 | if (ret < 0) { | 955 | if (ret < 0) |
947 | dev_err(dev, | 956 | goto ereg; |
948 | "Platform failed to power-on the camera.\n"); | 957 | |
949 | goto epower; | 958 | ret = soc_camera_power_set(icd, icl, 1); |
950 | } | 959 | if (ret < 0) |
951 | } | 960 | goto epower; |
952 | 961 | ||
953 | /* The camera could have been already on, try to reset */ | 962 | /* The camera could have been already on, try to reset */ |
954 | if (icl->reset) | 963 | if (icl->reset) |
@@ -998,7 +1007,13 @@ static int soc_camera_probe(struct device *dev) | |||
998 | 1007 | ||
999 | icd->field = V4L2_FIELD_ANY; | 1008 | icd->field = V4L2_FIELD_ANY; |
1000 | 1009 | ||
1001 | /* ..._video_start() will create a device node, so we have to protect */ | 1010 | icd->vdev->lock = &icd->video_lock; |
1011 | |||
1012 | /* | ||
1013 | * ..._video_start() will create a device node, video_register_device() | ||
1014 | * itself is protected against concurrent open() calls, but we also have | ||
1015 | * to protect our data. | ||
1016 | */ | ||
1002 | mutex_lock(&icd->video_lock); | 1017 | mutex_lock(&icd->video_lock); |
1003 | 1018 | ||
1004 | ret = soc_camera_video_start(icd); | 1019 | ret = soc_camera_video_start(icd); |
@@ -1021,8 +1036,7 @@ static int soc_camera_probe(struct device *dev) | |||
1021 | 1036 | ||
1022 | ici->ops->remove(icd); | 1037 | ici->ops->remove(icd); |
1023 | 1038 | ||
1024 | if (icl->power) | 1039 | soc_camera_power_set(icd, icl, 0); |
1025 | icl->power(icd->pdev, 0); | ||
1026 | 1040 | ||
1027 | mutex_unlock(&icd->video_lock); | 1041 | mutex_unlock(&icd->video_lock); |
1028 | 1042 | ||
@@ -1044,9 +1058,10 @@ eadddev: | |||
1044 | evdc: | 1058 | evdc: |
1045 | ici->ops->remove(icd); | 1059 | ici->ops->remove(icd); |
1046 | eadd: | 1060 | eadd: |
1047 | if (icl->power) | 1061 | soc_camera_power_set(icd, icl, 0); |
1048 | icl->power(icd->pdev, 0); | ||
1049 | epower: | 1062 | epower: |
1063 | regulator_bulk_free(icl->num_regulators, icl->regulators); | ||
1064 | ereg: | ||
1050 | return ret; | 1065 | return ret; |
1051 | } | 1066 | } |
1052 | 1067 | ||
@@ -1063,10 +1078,8 @@ static int soc_camera_remove(struct device *dev) | |||
1063 | BUG_ON(!dev->parent); | 1078 | BUG_ON(!dev->parent); |
1064 | 1079 | ||
1065 | if (vdev) { | 1080 | if (vdev) { |
1066 | mutex_lock(&icd->video_lock); | ||
1067 | video_unregister_device(vdev); | 1081 | video_unregister_device(vdev); |
1068 | icd->vdev = NULL; | 1082 | icd->vdev = NULL; |
1069 | mutex_unlock(&icd->video_lock); | ||
1070 | } | 1083 | } |
1071 | 1084 | ||
1072 | if (icl->board_info) { | 1085 | if (icl->board_info) { |
@@ -1081,6 +1094,8 @@ static int soc_camera_remove(struct device *dev) | |||
1081 | } | 1094 | } |
1082 | soc_camera_free_user_formats(icd); | 1095 | soc_camera_free_user_formats(icd); |
1083 | 1096 | ||
1097 | regulator_bulk_free(icl->num_regulators, icl->regulators); | ||
1098 | |||
1084 | return 0; | 1099 | return 0; |
1085 | } | 1100 | } |
1086 | 1101 | ||
diff --git a/drivers/media/video/sr030pc30.c b/drivers/media/video/sr030pc30.c index c9dc67aba980..864696b7a006 100644 --- a/drivers/media/video/sr030pc30.c +++ b/drivers/media/video/sr030pc30.c | |||
@@ -735,7 +735,7 @@ static int sr030pc30_s_power(struct v4l2_subdev *sd, int on) | |||
735 | const struct sr030pc30_platform_data *pdata = info->pdata; | 735 | const struct sr030pc30_platform_data *pdata = info->pdata; |
736 | int ret; | 736 | int ret; |
737 | 737 | ||
738 | if (WARN(pdata == NULL, "No platform data!")) | 738 | if (WARN(pdata == NULL, "No platform data!\n")) |
739 | return -ENOMEM; | 739 | return -ENOMEM; |
740 | 740 | ||
741 | /* | 741 | /* |
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index b5afe5f841ce..d1a2cefbf55b 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c | |||
@@ -230,120 +230,6 @@ static int stk_initialise(struct stk_camera *dev) | |||
230 | return -1; | 230 | return -1; |
231 | } | 231 | } |
232 | 232 | ||
233 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
234 | |||
235 | /* sysfs functions */ | ||
236 | /*FIXME cleanup this */ | ||
237 | |||
238 | static ssize_t show_brightness(struct device *class, | ||
239 | struct device_attribute *attr, char *buf) | ||
240 | { | ||
241 | struct video_device *vdev = to_video_device(class); | ||
242 | struct stk_camera *dev = vdev_to_camera(vdev); | ||
243 | |||
244 | return sprintf(buf, "%X\n", dev->vsettings.brightness); | ||
245 | } | ||
246 | |||
247 | static ssize_t store_brightness(struct device *class, | ||
248 | struct device_attribute *attr, const char *buf, size_t count) | ||
249 | { | ||
250 | char *endp; | ||
251 | unsigned long value; | ||
252 | int ret; | ||
253 | |||
254 | struct video_device *vdev = to_video_device(class); | ||
255 | struct stk_camera *dev = vdev_to_camera(vdev); | ||
256 | |||
257 | value = simple_strtoul(buf, &endp, 16); | ||
258 | |||
259 | dev->vsettings.brightness = (int) value; | ||
260 | |||
261 | ret = stk_sensor_set_brightness(dev, value >> 8); | ||
262 | if (ret) | ||
263 | return ret; | ||
264 | else | ||
265 | return count; | ||
266 | } | ||
267 | |||
268 | static ssize_t show_hflip(struct device *class, | ||
269 | struct device_attribute *attr, char *buf) | ||
270 | { | ||
271 | struct video_device *vdev = to_video_device(class); | ||
272 | struct stk_camera *dev = vdev_to_camera(vdev); | ||
273 | |||
274 | return sprintf(buf, "%d\n", dev->vsettings.hflip); | ||
275 | } | ||
276 | |||
277 | static ssize_t store_hflip(struct device *class, | ||
278 | struct device_attribute *attr, const char *buf, size_t count) | ||
279 | { | ||
280 | struct video_device *vdev = to_video_device(class); | ||
281 | struct stk_camera *dev = vdev_to_camera(vdev); | ||
282 | |||
283 | if (strncmp(buf, "1", 1) == 0) | ||
284 | dev->vsettings.hflip = 1; | ||
285 | else if (strncmp(buf, "0", 1) == 0) | ||
286 | dev->vsettings.hflip = 0; | ||
287 | else | ||
288 | return -EINVAL; | ||
289 | |||
290 | return strlen(buf); | ||
291 | } | ||
292 | |||
293 | static ssize_t show_vflip(struct device *class, | ||
294 | struct device_attribute *attr, char *buf) | ||
295 | { | ||
296 | struct video_device *vdev = to_video_device(class); | ||
297 | struct stk_camera *dev = vdev_to_camera(vdev); | ||
298 | |||
299 | return sprintf(buf, "%d\n", dev->vsettings.vflip); | ||
300 | } | ||
301 | |||
302 | static ssize_t store_vflip(struct device *class, | ||
303 | struct device_attribute *attr, const char *buf, size_t count) | ||
304 | { | ||
305 | struct video_device *vdev = to_video_device(class); | ||
306 | struct stk_camera *dev = vdev_to_camera(vdev); | ||
307 | |||
308 | if (strncmp(buf, "1", 1) == 0) | ||
309 | dev->vsettings.vflip = 1; | ||
310 | else if (strncmp(buf, "0", 1) == 0) | ||
311 | dev->vsettings.vflip = 0; | ||
312 | else | ||
313 | return -EINVAL; | ||
314 | |||
315 | return strlen(buf); | ||
316 | } | ||
317 | |||
318 | static DEVICE_ATTR(brightness, S_IRUGO | S_IWUGO, | ||
319 | show_brightness, store_brightness); | ||
320 | static DEVICE_ATTR(hflip, S_IRUGO | S_IWUGO, show_hflip, store_hflip); | ||
321 | static DEVICE_ATTR(vflip, S_IRUGO | S_IWUGO, show_vflip, store_vflip); | ||
322 | |||
323 | static int stk_create_sysfs_files(struct video_device *vdev) | ||
324 | { | ||
325 | int ret; | ||
326 | |||
327 | ret = device_create_file(&vdev->dev, &dev_attr_brightness); | ||
328 | ret += device_create_file(&vdev->dev, &dev_attr_hflip); | ||
329 | ret += device_create_file(&vdev->dev, &dev_attr_vflip); | ||
330 | if (ret) | ||
331 | STK_WARNING("Could not create sysfs files\n"); | ||
332 | return ret; | ||
333 | } | ||
334 | |||
335 | static void stk_remove_sysfs_files(struct video_device *vdev) | ||
336 | { | ||
337 | device_remove_file(&vdev->dev, &dev_attr_brightness); | ||
338 | device_remove_file(&vdev->dev, &dev_attr_hflip); | ||
339 | device_remove_file(&vdev->dev, &dev_attr_vflip); | ||
340 | } | ||
341 | |||
342 | #else | ||
343 | #define stk_create_sysfs_files(a) | ||
344 | #define stk_remove_sysfs_files(a) | ||
345 | #endif | ||
346 | |||
347 | /* *********************************************** */ | 233 | /* *********************************************** */ |
348 | /* | 234 | /* |
349 | * This function is called as an URB transfert is complete (Isochronous pipe). | 235 | * This function is called as an URB transfert is complete (Isochronous pipe). |
@@ -878,7 +764,24 @@ static struct v4l2_queryctrl stk_controls[] = { | |||
878 | .step = 0x0100, | 764 | .step = 0x0100, |
879 | .default_value = 0x6000, | 765 | .default_value = 0x6000, |
880 | }, | 766 | }, |
881 | /*TODO: get more controls to work */ | 767 | { |
768 | .id = V4L2_CID_HFLIP, | ||
769 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
770 | .name = "Horizontal Flip", | ||
771 | .minimum = 0, | ||
772 | .maximum = 1, | ||
773 | .step = 1, | ||
774 | .default_value = 1, | ||
775 | }, | ||
776 | { | ||
777 | .id = V4L2_CID_VFLIP, | ||
778 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
779 | .name = "Vertical Flip", | ||
780 | .minimum = 0, | ||
781 | .maximum = 1, | ||
782 | .step = 1, | ||
783 | .default_value = 1, | ||
784 | }, | ||
882 | }; | 785 | }; |
883 | 786 | ||
884 | static int stk_vidioc_queryctrl(struct file *filp, | 787 | static int stk_vidioc_queryctrl(struct file *filp, |
@@ -906,6 +809,12 @@ static int stk_vidioc_g_ctrl(struct file *filp, | |||
906 | case V4L2_CID_BRIGHTNESS: | 809 | case V4L2_CID_BRIGHTNESS: |
907 | c->value = dev->vsettings.brightness; | 810 | c->value = dev->vsettings.brightness; |
908 | break; | 811 | break; |
812 | case V4L2_CID_HFLIP: | ||
813 | c->value = dev->vsettings.hflip; | ||
814 | break; | ||
815 | case V4L2_CID_VFLIP: | ||
816 | c->value = dev->vsettings.vflip; | ||
817 | break; | ||
909 | default: | 818 | default: |
910 | return -EINVAL; | 819 | return -EINVAL; |
911 | } | 820 | } |
@@ -920,6 +829,12 @@ static int stk_vidioc_s_ctrl(struct file *filp, | |||
920 | case V4L2_CID_BRIGHTNESS: | 829 | case V4L2_CID_BRIGHTNESS: |
921 | dev->vsettings.brightness = c->value; | 830 | dev->vsettings.brightness = c->value; |
922 | return stk_sensor_set_brightness(dev, c->value >> 8); | 831 | return stk_sensor_set_brightness(dev, c->value >> 8); |
832 | case V4L2_CID_HFLIP: | ||
833 | dev->vsettings.hflip = c->value; | ||
834 | return 0; | ||
835 | case V4L2_CID_VFLIP: | ||
836 | dev->vsettings.vflip = c->value; | ||
837 | return 0; | ||
923 | default: | 838 | default: |
924 | return -EINVAL; | 839 | return -EINVAL; |
925 | } | 840 | } |
@@ -1394,8 +1309,6 @@ static int stk_camera_probe(struct usb_interface *interface, | |||
1394 | goto error; | 1309 | goto error; |
1395 | } | 1310 | } |
1396 | 1311 | ||
1397 | stk_create_sysfs_files(&dev->vdev); | ||
1398 | |||
1399 | return 0; | 1312 | return 0; |
1400 | 1313 | ||
1401 | error: | 1314 | error: |
@@ -1411,7 +1324,6 @@ static void stk_camera_disconnect(struct usb_interface *interface) | |||
1411 | unset_present(dev); | 1324 | unset_present(dev); |
1412 | 1325 | ||
1413 | wake_up_interruptible(&dev->wait_frame); | 1326 | wake_up_interruptible(&dev->wait_frame); |
1414 | stk_remove_sysfs_files(&dev->vdev); | ||
1415 | 1327 | ||
1416 | STK_INFO("Syntek USB2.0 Camera release resources device %s\n", | 1328 | STK_INFO("Syntek USB2.0 Camera release resources device %s\n", |
1417 | video_device_node_name(&dev->vdev)); | 1329 | video_device_node_name(&dev->vdev)); |
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index 3e99cea8e4dc..19621ed523ec 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c | |||
@@ -148,7 +148,7 @@ static int tea6415c_probe(struct i2c_client *client, | |||
148 | 148 | ||
149 | /* let's see whether this adapter can support what we need */ | 149 | /* let's see whether this adapter can support what we need */ |
150 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) | 150 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) |
151 | return 0; | 151 | return -EIO; |
152 | 152 | ||
153 | v4l_info(client, "chip found @ 0x%x (%s)\n", | 153 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
154 | client->addr << 1, client->adapter->name); | 154 | client->addr << 1, client->adapter->name); |
diff --git a/drivers/media/video/timblogiw.c b/drivers/media/video/timblogiw.c new file mode 100644 index 000000000000..fc611ebeb82c --- /dev/null +++ b/drivers/media/video/timblogiw.c | |||
@@ -0,0 +1,893 @@ | |||
1 | /* | ||
2 | * timblogiw.c timberdale FPGA LogiWin Video In driver | ||
3 | * Copyright (c) 2009-2010 Intel Corporation | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | |||
19 | /* Supports: | ||
20 | * Timberdale FPGA LogiWin Video In | ||
21 | */ | ||
22 | |||
23 | #include <linux/version.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/dmaengine.h> | ||
27 | #include <linux/scatterlist.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/list.h> | ||
30 | #include <linux/i2c.h> | ||
31 | #include <media/v4l2-ioctl.h> | ||
32 | #include <media/v4l2-device.h> | ||
33 | #include <media/videobuf-dma-contig.h> | ||
34 | #include <media/timb_video.h> | ||
35 | |||
36 | #define DRIVER_NAME "timb-video" | ||
37 | |||
38 | #define TIMBLOGIWIN_NAME "Timberdale Video-In" | ||
39 | #define TIMBLOGIW_VERSION_CODE 0x04 | ||
40 | |||
41 | #define TIMBLOGIW_LINES_PER_DESC 44 | ||
42 | #define TIMBLOGIW_MAX_VIDEO_MEM 16 | ||
43 | |||
44 | #define TIMBLOGIW_HAS_DECODER(lw) (lw->pdata.encoder.module_name) | ||
45 | |||
46 | |||
47 | struct timblogiw { | ||
48 | struct video_device video_dev; | ||
49 | struct v4l2_device v4l2_dev; /* mutual exclusion */ | ||
50 | struct mutex lock; | ||
51 | struct device *dev; | ||
52 | struct timb_video_platform_data pdata; | ||
53 | struct v4l2_subdev *sd_enc; /* encoder */ | ||
54 | bool opened; | ||
55 | }; | ||
56 | |||
57 | struct timblogiw_tvnorm { | ||
58 | v4l2_std_id std; | ||
59 | u16 width; | ||
60 | u16 height; | ||
61 | u8 fps; | ||
62 | }; | ||
63 | |||
64 | struct timblogiw_fh { | ||
65 | struct videobuf_queue vb_vidq; | ||
66 | struct timblogiw_tvnorm const *cur_norm; | ||
67 | struct list_head capture; | ||
68 | struct dma_chan *chan; | ||
69 | spinlock_t queue_lock; /* mutual exclusion */ | ||
70 | unsigned int frame_count; | ||
71 | }; | ||
72 | |||
73 | struct timblogiw_buffer { | ||
74 | /* common v4l buffer stuff -- must be first */ | ||
75 | struct videobuf_buffer vb; | ||
76 | struct scatterlist sg[16]; | ||
77 | dma_cookie_t cookie; | ||
78 | struct timblogiw_fh *fh; | ||
79 | }; | ||
80 | |||
81 | const struct timblogiw_tvnorm timblogiw_tvnorms[] = { | ||
82 | { | ||
83 | .std = V4L2_STD_PAL, | ||
84 | .width = 720, | ||
85 | .height = 576, | ||
86 | .fps = 25 | ||
87 | }, | ||
88 | { | ||
89 | .std = V4L2_STD_NTSC, | ||
90 | .width = 720, | ||
91 | .height = 480, | ||
92 | .fps = 30 | ||
93 | } | ||
94 | }; | ||
95 | |||
96 | static int timblogiw_bytes_per_line(const struct timblogiw_tvnorm *norm) | ||
97 | { | ||
98 | return norm->width * 2; | ||
99 | } | ||
100 | |||
101 | |||
102 | static int timblogiw_frame_size(const struct timblogiw_tvnorm *norm) | ||
103 | { | ||
104 | return norm->height * timblogiw_bytes_per_line(norm); | ||
105 | } | ||
106 | |||
107 | static const struct timblogiw_tvnorm *timblogiw_get_norm(const v4l2_std_id std) | ||
108 | { | ||
109 | int i; | ||
110 | for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++) | ||
111 | if (timblogiw_tvnorms[i].std & std) | ||
112 | return timblogiw_tvnorms + i; | ||
113 | |||
114 | /* default to first element */ | ||
115 | return timblogiw_tvnorms; | ||
116 | } | ||
117 | |||
118 | static void timblogiw_dma_cb(void *data) | ||
119 | { | ||
120 | struct timblogiw_buffer *buf = data; | ||
121 | struct timblogiw_fh *fh = buf->fh; | ||
122 | struct videobuf_buffer *vb = &buf->vb; | ||
123 | |||
124 | spin_lock(&fh->queue_lock); | ||
125 | |||
126 | /* mark the transfer done */ | ||
127 | buf->cookie = -1; | ||
128 | |||
129 | fh->frame_count++; | ||
130 | |||
131 | if (vb->state != VIDEOBUF_ERROR) { | ||
132 | list_del(&vb->queue); | ||
133 | do_gettimeofday(&vb->ts); | ||
134 | vb->field_count = fh->frame_count * 2; | ||
135 | vb->state = VIDEOBUF_DONE; | ||
136 | |||
137 | wake_up(&vb->done); | ||
138 | } | ||
139 | |||
140 | if (!list_empty(&fh->capture)) { | ||
141 | vb = list_entry(fh->capture.next, struct videobuf_buffer, | ||
142 | queue); | ||
143 | vb->state = VIDEOBUF_ACTIVE; | ||
144 | } | ||
145 | |||
146 | spin_unlock(&fh->queue_lock); | ||
147 | } | ||
148 | |||
149 | static bool timblogiw_dma_filter_fn(struct dma_chan *chan, void *filter_param) | ||
150 | { | ||
151 | return chan->chan_id == (uintptr_t)filter_param; | ||
152 | } | ||
153 | |||
154 | /* IOCTL functions */ | ||
155 | |||
156 | static int timblogiw_g_fmt(struct file *file, void *priv, | ||
157 | struct v4l2_format *format) | ||
158 | { | ||
159 | struct video_device *vdev = video_devdata(file); | ||
160 | struct timblogiw *lw = video_get_drvdata(vdev); | ||
161 | struct timblogiw_fh *fh = priv; | ||
162 | |||
163 | dev_dbg(&vdev->dev, "%s entry\n", __func__); | ||
164 | |||
165 | if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
166 | return -EINVAL; | ||
167 | |||
168 | mutex_lock(&lw->lock); | ||
169 | |||
170 | format->fmt.pix.width = fh->cur_norm->width; | ||
171 | format->fmt.pix.height = fh->cur_norm->height; | ||
172 | format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; | ||
173 | format->fmt.pix.bytesperline = timblogiw_bytes_per_line(fh->cur_norm); | ||
174 | format->fmt.pix.sizeimage = timblogiw_frame_size(fh->cur_norm); | ||
175 | format->fmt.pix.field = V4L2_FIELD_NONE; | ||
176 | |||
177 | mutex_unlock(&lw->lock); | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int timblogiw_try_fmt(struct file *file, void *priv, | ||
183 | struct v4l2_format *format) | ||
184 | { | ||
185 | struct video_device *vdev = video_devdata(file); | ||
186 | struct v4l2_pix_format *pix = &format->fmt.pix; | ||
187 | |||
188 | dev_dbg(&vdev->dev, | ||
189 | "%s - width=%d, height=%d, pixelformat=%d, field=%d\n" | ||
190 | "bytes per line %d, size image: %d, colorspace: %d\n", | ||
191 | __func__, | ||
192 | pix->width, pix->height, pix->pixelformat, pix->field, | ||
193 | pix->bytesperline, pix->sizeimage, pix->colorspace); | ||
194 | |||
195 | if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
196 | return -EINVAL; | ||
197 | |||
198 | if (pix->field != V4L2_FIELD_NONE) | ||
199 | return -EINVAL; | ||
200 | |||
201 | if (pix->pixelformat != V4L2_PIX_FMT_UYVY) | ||
202 | return -EINVAL; | ||
203 | |||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static int timblogiw_s_fmt(struct file *file, void *priv, | ||
208 | struct v4l2_format *format) | ||
209 | { | ||
210 | struct video_device *vdev = video_devdata(file); | ||
211 | struct timblogiw *lw = video_get_drvdata(vdev); | ||
212 | struct timblogiw_fh *fh = priv; | ||
213 | struct v4l2_pix_format *pix = &format->fmt.pix; | ||
214 | int err; | ||
215 | |||
216 | mutex_lock(&lw->lock); | ||
217 | |||
218 | err = timblogiw_try_fmt(file, priv, format); | ||
219 | if (err) | ||
220 | goto out; | ||
221 | |||
222 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { | ||
223 | dev_err(&vdev->dev, "%s queue busy\n", __func__); | ||
224 | err = -EBUSY; | ||
225 | goto out; | ||
226 | } | ||
227 | |||
228 | pix->width = fh->cur_norm->width; | ||
229 | pix->height = fh->cur_norm->height; | ||
230 | |||
231 | out: | ||
232 | mutex_unlock(&lw->lock); | ||
233 | return err; | ||
234 | } | ||
235 | |||
236 | static int timblogiw_querycap(struct file *file, void *priv, | ||
237 | struct v4l2_capability *cap) | ||
238 | { | ||
239 | struct video_device *vdev = video_devdata(file); | ||
240 | |||
241 | dev_dbg(&vdev->dev, "%s: Entry\n", __func__); | ||
242 | memset(cap, 0, sizeof(*cap)); | ||
243 | strncpy(cap->card, TIMBLOGIWIN_NAME, sizeof(cap->card)-1); | ||
244 | strncpy(cap->driver, DRIVER_NAME, sizeof(cap->driver) - 1); | ||
245 | strlcpy(cap->bus_info, vdev->name, sizeof(cap->bus_info)); | ||
246 | cap->version = TIMBLOGIW_VERSION_CODE; | ||
247 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | | ||
248 | V4L2_CAP_READWRITE; | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static int timblogiw_enum_fmt(struct file *file, void *priv, | ||
254 | struct v4l2_fmtdesc *fmt) | ||
255 | { | ||
256 | struct video_device *vdev = video_devdata(file); | ||
257 | |||
258 | dev_dbg(&vdev->dev, "%s, index: %d\n", __func__, fmt->index); | ||
259 | |||
260 | if (fmt->index != 0) | ||
261 | return -EINVAL; | ||
262 | memset(fmt, 0, sizeof(*fmt)); | ||
263 | fmt->index = 0; | ||
264 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
265 | strncpy(fmt->description, "4:2:2, packed, YUYV", | ||
266 | sizeof(fmt->description)-1); | ||
267 | fmt->pixelformat = V4L2_PIX_FMT_UYVY; | ||
268 | |||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | static int timblogiw_g_parm(struct file *file, void *priv, | ||
273 | struct v4l2_streamparm *sp) | ||
274 | { | ||
275 | struct timblogiw_fh *fh = priv; | ||
276 | struct v4l2_captureparm *cp = &sp->parm.capture; | ||
277 | |||
278 | cp->capability = V4L2_CAP_TIMEPERFRAME; | ||
279 | cp->timeperframe.numerator = 1; | ||
280 | cp->timeperframe.denominator = fh->cur_norm->fps; | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static int timblogiw_reqbufs(struct file *file, void *priv, | ||
286 | struct v4l2_requestbuffers *rb) | ||
287 | { | ||
288 | struct video_device *vdev = video_devdata(file); | ||
289 | struct timblogiw_fh *fh = priv; | ||
290 | |||
291 | dev_dbg(&vdev->dev, "%s: entry\n", __func__); | ||
292 | |||
293 | return videobuf_reqbufs(&fh->vb_vidq, rb); | ||
294 | } | ||
295 | |||
296 | static int timblogiw_querybuf(struct file *file, void *priv, | ||
297 | struct v4l2_buffer *b) | ||
298 | { | ||
299 | struct video_device *vdev = video_devdata(file); | ||
300 | struct timblogiw_fh *fh = priv; | ||
301 | |||
302 | dev_dbg(&vdev->dev, "%s: entry\n", __func__); | ||
303 | |||
304 | return videobuf_querybuf(&fh->vb_vidq, b); | ||
305 | } | ||
306 | |||
307 | static int timblogiw_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) | ||
308 | { | ||
309 | struct video_device *vdev = video_devdata(file); | ||
310 | struct timblogiw_fh *fh = priv; | ||
311 | |||
312 | dev_dbg(&vdev->dev, "%s: entry\n", __func__); | ||
313 | |||
314 | return videobuf_qbuf(&fh->vb_vidq, b); | ||
315 | } | ||
316 | |||
317 | static int timblogiw_dqbuf(struct file *file, void *priv, | ||
318 | struct v4l2_buffer *b) | ||
319 | { | ||
320 | struct video_device *vdev = video_devdata(file); | ||
321 | struct timblogiw_fh *fh = priv; | ||
322 | |||
323 | dev_dbg(&vdev->dev, "%s: entry\n", __func__); | ||
324 | |||
325 | return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); | ||
326 | } | ||
327 | |||
328 | static int timblogiw_g_std(struct file *file, void *priv, v4l2_std_id *std) | ||
329 | { | ||
330 | struct video_device *vdev = video_devdata(file); | ||
331 | struct timblogiw_fh *fh = priv; | ||
332 | |||
333 | dev_dbg(&vdev->dev, "%s: entry\n", __func__); | ||
334 | |||
335 | *std = fh->cur_norm->std; | ||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static int timblogiw_s_std(struct file *file, void *priv, v4l2_std_id *std) | ||
340 | { | ||
341 | struct video_device *vdev = video_devdata(file); | ||
342 | struct timblogiw *lw = video_get_drvdata(vdev); | ||
343 | struct timblogiw_fh *fh = priv; | ||
344 | int err = 0; | ||
345 | |||
346 | dev_dbg(&vdev->dev, "%s: entry\n", __func__); | ||
347 | |||
348 | mutex_lock(&lw->lock); | ||
349 | |||
350 | if (TIMBLOGIW_HAS_DECODER(lw)) | ||
351 | err = v4l2_subdev_call(lw->sd_enc, core, s_std, *std); | ||
352 | |||
353 | if (!err) | ||
354 | fh->cur_norm = timblogiw_get_norm(*std); | ||
355 | |||
356 | mutex_unlock(&lw->lock); | ||
357 | |||
358 | return err; | ||
359 | } | ||
360 | |||
361 | static int timblogiw_enuminput(struct file *file, void *priv, | ||
362 | struct v4l2_input *inp) | ||
363 | { | ||
364 | struct video_device *vdev = video_devdata(file); | ||
365 | int i; | ||
366 | |||
367 | dev_dbg(&vdev->dev, "%s: Entry\n", __func__); | ||
368 | |||
369 | if (inp->index != 0) | ||
370 | return -EINVAL; | ||
371 | |||
372 | inp->index = 0; | ||
373 | |||
374 | strncpy(inp->name, "Timb input 1", sizeof(inp->name) - 1); | ||
375 | inp->type = V4L2_INPUT_TYPE_CAMERA; | ||
376 | |||
377 | inp->std = 0; | ||
378 | for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++) | ||
379 | inp->std |= timblogiw_tvnorms[i].std; | ||
380 | |||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | static int timblogiw_g_input(struct file *file, void *priv, | ||
385 | unsigned int *input) | ||
386 | { | ||
387 | struct video_device *vdev = video_devdata(file); | ||
388 | |||
389 | dev_dbg(&vdev->dev, "%s: Entry\n", __func__); | ||
390 | |||
391 | *input = 0; | ||
392 | |||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | static int timblogiw_s_input(struct file *file, void *priv, unsigned int input) | ||
397 | { | ||
398 | struct video_device *vdev = video_devdata(file); | ||
399 | |||
400 | dev_dbg(&vdev->dev, "%s: Entry\n", __func__); | ||
401 | |||
402 | if (input != 0) | ||
403 | return -EINVAL; | ||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | static int timblogiw_streamon(struct file *file, void *priv, unsigned int type) | ||
408 | { | ||
409 | struct video_device *vdev = video_devdata(file); | ||
410 | struct timblogiw_fh *fh = priv; | ||
411 | |||
412 | dev_dbg(&vdev->dev, "%s: entry\n", __func__); | ||
413 | |||
414 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
415 | dev_dbg(&vdev->dev, "%s - No capture device\n", __func__); | ||
416 | return -EINVAL; | ||
417 | } | ||
418 | |||
419 | fh->frame_count = 0; | ||
420 | return videobuf_streamon(&fh->vb_vidq); | ||
421 | } | ||
422 | |||
423 | static int timblogiw_streamoff(struct file *file, void *priv, | ||
424 | unsigned int type) | ||
425 | { | ||
426 | struct video_device *vdev = video_devdata(file); | ||
427 | struct timblogiw_fh *fh = priv; | ||
428 | |||
429 | dev_dbg(&vdev->dev, "%s entry\n", __func__); | ||
430 | |||
431 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
432 | return -EINVAL; | ||
433 | |||
434 | return videobuf_streamoff(&fh->vb_vidq); | ||
435 | } | ||
436 | |||
437 | static int timblogiw_querystd(struct file *file, void *priv, v4l2_std_id *std) | ||
438 | { | ||
439 | struct video_device *vdev = video_devdata(file); | ||
440 | struct timblogiw *lw = video_get_drvdata(vdev); | ||
441 | struct timblogiw_fh *fh = priv; | ||
442 | |||
443 | dev_dbg(&vdev->dev, "%s entry\n", __func__); | ||
444 | |||
445 | if (TIMBLOGIW_HAS_DECODER(lw)) | ||
446 | return v4l2_subdev_call(lw->sd_enc, video, querystd, std); | ||
447 | else { | ||
448 | *std = fh->cur_norm->std; | ||
449 | return 0; | ||
450 | } | ||
451 | } | ||
452 | |||
453 | static int timblogiw_enum_framesizes(struct file *file, void *priv, | ||
454 | struct v4l2_frmsizeenum *fsize) | ||
455 | { | ||
456 | struct video_device *vdev = video_devdata(file); | ||
457 | struct timblogiw_fh *fh = priv; | ||
458 | |||
459 | dev_dbg(&vdev->dev, "%s - index: %d, format: %d\n", __func__, | ||
460 | fsize->index, fsize->pixel_format); | ||
461 | |||
462 | if ((fsize->index != 0) || | ||
463 | (fsize->pixel_format != V4L2_PIX_FMT_UYVY)) | ||
464 | return -EINVAL; | ||
465 | |||
466 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | ||
467 | fsize->discrete.width = fh->cur_norm->width; | ||
468 | fsize->discrete.height = fh->cur_norm->height; | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | /* Video buffer functions */ | ||
474 | |||
475 | static int buffer_setup(struct videobuf_queue *vq, unsigned int *count, | ||
476 | unsigned int *size) | ||
477 | { | ||
478 | struct timblogiw_fh *fh = vq->priv_data; | ||
479 | |||
480 | *size = timblogiw_frame_size(fh->cur_norm); | ||
481 | |||
482 | if (!*count) | ||
483 | *count = 32; | ||
484 | |||
485 | while (*size * *count > TIMBLOGIW_MAX_VIDEO_MEM * 1024 * 1024) | ||
486 | (*count)--; | ||
487 | |||
488 | return 0; | ||
489 | } | ||
490 | |||
491 | static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | ||
492 | enum v4l2_field field) | ||
493 | { | ||
494 | struct timblogiw_fh *fh = vq->priv_data; | ||
495 | struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer, | ||
496 | vb); | ||
497 | unsigned int data_size = timblogiw_frame_size(fh->cur_norm); | ||
498 | int err = 0; | ||
499 | |||
500 | if (vb->baddr && vb->bsize < data_size) | ||
501 | /* User provided buffer, but it is too small */ | ||
502 | return -ENOMEM; | ||
503 | |||
504 | vb->size = data_size; | ||
505 | vb->width = fh->cur_norm->width; | ||
506 | vb->height = fh->cur_norm->height; | ||
507 | vb->field = field; | ||
508 | |||
509 | if (vb->state == VIDEOBUF_NEEDS_INIT) { | ||
510 | int i; | ||
511 | unsigned int size; | ||
512 | unsigned int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC * | ||
513 | timblogiw_bytes_per_line(fh->cur_norm); | ||
514 | dma_addr_t addr; | ||
515 | |||
516 | sg_init_table(buf->sg, ARRAY_SIZE(buf->sg)); | ||
517 | |||
518 | err = videobuf_iolock(vq, vb, NULL); | ||
519 | if (err) | ||
520 | goto err; | ||
521 | |||
522 | addr = videobuf_to_dma_contig(vb); | ||
523 | for (i = 0, size = 0; size < data_size; i++) { | ||
524 | sg_dma_address(buf->sg + i) = addr + size; | ||
525 | size += bytes_per_desc; | ||
526 | sg_dma_len(buf->sg + i) = (size > data_size) ? | ||
527 | (bytes_per_desc - (size - data_size)) : | ||
528 | bytes_per_desc; | ||
529 | } | ||
530 | |||
531 | vb->state = VIDEOBUF_PREPARED; | ||
532 | buf->cookie = -1; | ||
533 | buf->fh = fh; | ||
534 | } | ||
535 | |||
536 | return 0; | ||
537 | |||
538 | err: | ||
539 | videobuf_dma_contig_free(vq, vb); | ||
540 | vb->state = VIDEOBUF_NEEDS_INIT; | ||
541 | return err; | ||
542 | } | ||
543 | |||
544 | static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | ||
545 | { | ||
546 | struct timblogiw_fh *fh = vq->priv_data; | ||
547 | struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer, | ||
548 | vb); | ||
549 | struct dma_async_tx_descriptor *desc; | ||
550 | int sg_elems; | ||
551 | int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC * | ||
552 | timblogiw_bytes_per_line(fh->cur_norm); | ||
553 | |||
554 | sg_elems = timblogiw_frame_size(fh->cur_norm) / bytes_per_desc; | ||
555 | sg_elems += | ||
556 | (timblogiw_frame_size(fh->cur_norm) % bytes_per_desc) ? 1 : 0; | ||
557 | |||
558 | if (list_empty(&fh->capture)) | ||
559 | vb->state = VIDEOBUF_ACTIVE; | ||
560 | else | ||
561 | vb->state = VIDEOBUF_QUEUED; | ||
562 | |||
563 | list_add_tail(&vb->queue, &fh->capture); | ||
564 | |||
565 | spin_unlock_irq(&fh->queue_lock); | ||
566 | |||
567 | desc = fh->chan->device->device_prep_slave_sg(fh->chan, | ||
568 | buf->sg, sg_elems, DMA_FROM_DEVICE, | ||
569 | DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP); | ||
570 | if (!desc) { | ||
571 | spin_lock_irq(&fh->queue_lock); | ||
572 | list_del_init(&vb->queue); | ||
573 | vb->state = VIDEOBUF_PREPARED; | ||
574 | return; | ||
575 | } | ||
576 | |||
577 | desc->callback_param = buf; | ||
578 | desc->callback = timblogiw_dma_cb; | ||
579 | |||
580 | buf->cookie = desc->tx_submit(desc); | ||
581 | |||
582 | spin_lock_irq(&fh->queue_lock); | ||
583 | } | ||
584 | |||
585 | static void buffer_release(struct videobuf_queue *vq, | ||
586 | struct videobuf_buffer *vb) | ||
587 | { | ||
588 | struct timblogiw_fh *fh = vq->priv_data; | ||
589 | struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer, | ||
590 | vb); | ||
591 | |||
592 | videobuf_waiton(vq, vb, 0, 0); | ||
593 | if (buf->cookie >= 0) | ||
594 | dma_sync_wait(fh->chan, buf->cookie); | ||
595 | |||
596 | videobuf_dma_contig_free(vq, vb); | ||
597 | vb->state = VIDEOBUF_NEEDS_INIT; | ||
598 | } | ||
599 | |||
600 | static struct videobuf_queue_ops timblogiw_video_qops = { | ||
601 | .buf_setup = buffer_setup, | ||
602 | .buf_prepare = buffer_prepare, | ||
603 | .buf_queue = buffer_queue, | ||
604 | .buf_release = buffer_release, | ||
605 | }; | ||
606 | |||
607 | /* Device Operations functions */ | ||
608 | |||
609 | static int timblogiw_open(struct file *file) | ||
610 | { | ||
611 | struct video_device *vdev = video_devdata(file); | ||
612 | struct timblogiw *lw = video_get_drvdata(vdev); | ||
613 | struct timblogiw_fh *fh; | ||
614 | v4l2_std_id std; | ||
615 | dma_cap_mask_t mask; | ||
616 | int err = 0; | ||
617 | |||
618 | dev_dbg(&vdev->dev, "%s: entry\n", __func__); | ||
619 | |||
620 | mutex_lock(&lw->lock); | ||
621 | if (lw->opened) { | ||
622 | err = -EBUSY; | ||
623 | goto out; | ||
624 | } | ||
625 | |||
626 | if (TIMBLOGIW_HAS_DECODER(lw) && !lw->sd_enc) { | ||
627 | struct i2c_adapter *adapt; | ||
628 | |||
629 | /* find the video decoder */ | ||
630 | adapt = i2c_get_adapter(lw->pdata.i2c_adapter); | ||
631 | if (!adapt) { | ||
632 | dev_err(&vdev->dev, "No I2C bus #%d\n", | ||
633 | lw->pdata.i2c_adapter); | ||
634 | err = -ENODEV; | ||
635 | goto out; | ||
636 | } | ||
637 | |||
638 | /* now find the encoder */ | ||
639 | lw->sd_enc = v4l2_i2c_new_subdev_board(&lw->v4l2_dev, adapt, | ||
640 | lw->pdata.encoder.info, NULL); | ||
641 | |||
642 | i2c_put_adapter(adapt); | ||
643 | |||
644 | if (!lw->sd_enc) { | ||
645 | dev_err(&vdev->dev, "Failed to get encoder: %s\n", | ||
646 | lw->pdata.encoder.module_name); | ||
647 | err = -ENODEV; | ||
648 | goto out; | ||
649 | } | ||
650 | } | ||
651 | |||
652 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | ||
653 | if (!fh) { | ||
654 | err = -ENOMEM; | ||
655 | goto out; | ||
656 | } | ||
657 | |||
658 | fh->cur_norm = timblogiw_tvnorms; | ||
659 | timblogiw_querystd(file, fh, &std); | ||
660 | fh->cur_norm = timblogiw_get_norm(std); | ||
661 | |||
662 | INIT_LIST_HEAD(&fh->capture); | ||
663 | spin_lock_init(&fh->queue_lock); | ||
664 | |||
665 | dma_cap_zero(mask); | ||
666 | dma_cap_set(DMA_SLAVE, mask); | ||
667 | dma_cap_set(DMA_PRIVATE, mask); | ||
668 | |||
669 | /* find the DMA channel */ | ||
670 | fh->chan = dma_request_channel(mask, timblogiw_dma_filter_fn, | ||
671 | (void *)(uintptr_t)lw->pdata.dma_channel); | ||
672 | if (!fh->chan) { | ||
673 | dev_err(&vdev->dev, "Failed to get DMA channel\n"); | ||
674 | kfree(fh); | ||
675 | err = -ENODEV; | ||
676 | goto out; | ||
677 | } | ||
678 | |||
679 | file->private_data = fh; | ||
680 | videobuf_queue_dma_contig_init(&fh->vb_vidq, | ||
681 | &timblogiw_video_qops, lw->dev, &fh->queue_lock, | ||
682 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | ||
683 | sizeof(struct timblogiw_buffer), fh, NULL); | ||
684 | |||
685 | lw->opened = true; | ||
686 | out: | ||
687 | mutex_unlock(&lw->lock); | ||
688 | |||
689 | return err; | ||
690 | } | ||
691 | |||
692 | static int timblogiw_close(struct file *file) | ||
693 | { | ||
694 | struct video_device *vdev = video_devdata(file); | ||
695 | struct timblogiw *lw = video_get_drvdata(vdev); | ||
696 | struct timblogiw_fh *fh = file->private_data; | ||
697 | |||
698 | dev_dbg(&vdev->dev, "%s: Entry\n", __func__); | ||
699 | |||
700 | videobuf_stop(&fh->vb_vidq); | ||
701 | videobuf_mmap_free(&fh->vb_vidq); | ||
702 | |||
703 | dma_release_channel(fh->chan); | ||
704 | |||
705 | kfree(fh); | ||
706 | |||
707 | mutex_lock(&lw->lock); | ||
708 | lw->opened = false; | ||
709 | mutex_unlock(&lw->lock); | ||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static ssize_t timblogiw_read(struct file *file, char __user *data, | ||
714 | size_t count, loff_t *ppos) | ||
715 | { | ||
716 | struct video_device *vdev = video_devdata(file); | ||
717 | struct timblogiw_fh *fh = file->private_data; | ||
718 | |||
719 | dev_dbg(&vdev->dev, "%s: entry\n", __func__); | ||
720 | |||
721 | return videobuf_read_stream(&fh->vb_vidq, data, count, ppos, 0, | ||
722 | file->f_flags & O_NONBLOCK); | ||
723 | } | ||
724 | |||
725 | static unsigned int timblogiw_poll(struct file *file, | ||
726 | struct poll_table_struct *wait) | ||
727 | { | ||
728 | struct video_device *vdev = video_devdata(file); | ||
729 | struct timblogiw_fh *fh = file->private_data; | ||
730 | |||
731 | dev_dbg(&vdev->dev, "%s: entry\n", __func__); | ||
732 | |||
733 | return videobuf_poll_stream(file, &fh->vb_vidq, wait); | ||
734 | } | ||
735 | |||
736 | static int timblogiw_mmap(struct file *file, struct vm_area_struct *vma) | ||
737 | { | ||
738 | struct video_device *vdev = video_devdata(file); | ||
739 | struct timblogiw_fh *fh = file->private_data; | ||
740 | |||
741 | dev_dbg(&vdev->dev, "%s: entry\n", __func__); | ||
742 | |||
743 | return videobuf_mmap_mapper(&fh->vb_vidq, vma); | ||
744 | } | ||
745 | |||
746 | /* Platform device functions */ | ||
747 | |||
748 | static __devinitconst struct v4l2_ioctl_ops timblogiw_ioctl_ops = { | ||
749 | .vidioc_querycap = timblogiw_querycap, | ||
750 | .vidioc_enum_fmt_vid_cap = timblogiw_enum_fmt, | ||
751 | .vidioc_g_fmt_vid_cap = timblogiw_g_fmt, | ||
752 | .vidioc_try_fmt_vid_cap = timblogiw_try_fmt, | ||
753 | .vidioc_s_fmt_vid_cap = timblogiw_s_fmt, | ||
754 | .vidioc_g_parm = timblogiw_g_parm, | ||
755 | .vidioc_reqbufs = timblogiw_reqbufs, | ||
756 | .vidioc_querybuf = timblogiw_querybuf, | ||
757 | .vidioc_qbuf = timblogiw_qbuf, | ||
758 | .vidioc_dqbuf = timblogiw_dqbuf, | ||
759 | .vidioc_g_std = timblogiw_g_std, | ||
760 | .vidioc_s_std = timblogiw_s_std, | ||
761 | .vidioc_enum_input = timblogiw_enuminput, | ||
762 | .vidioc_g_input = timblogiw_g_input, | ||
763 | .vidioc_s_input = timblogiw_s_input, | ||
764 | .vidioc_streamon = timblogiw_streamon, | ||
765 | .vidioc_streamoff = timblogiw_streamoff, | ||
766 | .vidioc_querystd = timblogiw_querystd, | ||
767 | .vidioc_enum_framesizes = timblogiw_enum_framesizes, | ||
768 | }; | ||
769 | |||
770 | static __devinitconst struct v4l2_file_operations timblogiw_fops = { | ||
771 | .owner = THIS_MODULE, | ||
772 | .open = timblogiw_open, | ||
773 | .release = timblogiw_close, | ||
774 | .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */ | ||
775 | .mmap = timblogiw_mmap, | ||
776 | .read = timblogiw_read, | ||
777 | .poll = timblogiw_poll, | ||
778 | }; | ||
779 | |||
780 | static __devinitconst struct video_device timblogiw_template = { | ||
781 | .name = TIMBLOGIWIN_NAME, | ||
782 | .fops = &timblogiw_fops, | ||
783 | .ioctl_ops = &timblogiw_ioctl_ops, | ||
784 | .release = video_device_release_empty, | ||
785 | .minor = -1, | ||
786 | .tvnorms = V4L2_STD_PAL | V4L2_STD_NTSC | ||
787 | }; | ||
788 | |||
789 | static int __devinit timblogiw_probe(struct platform_device *pdev) | ||
790 | { | ||
791 | int err; | ||
792 | struct timblogiw *lw = NULL; | ||
793 | struct timb_video_platform_data *pdata = pdev->dev.platform_data; | ||
794 | |||
795 | if (!pdata) { | ||
796 | dev_err(&pdev->dev, "No platform data\n"); | ||
797 | err = -EINVAL; | ||
798 | goto err; | ||
799 | } | ||
800 | |||
801 | if (!pdata->encoder.module_name) | ||
802 | dev_info(&pdev->dev, "Running without decoder\n"); | ||
803 | |||
804 | lw = kzalloc(sizeof(*lw), GFP_KERNEL); | ||
805 | if (!lw) { | ||
806 | err = -ENOMEM; | ||
807 | goto err; | ||
808 | } | ||
809 | |||
810 | if (pdev->dev.parent) | ||
811 | lw->dev = pdev->dev.parent; | ||
812 | else | ||
813 | lw->dev = &pdev->dev; | ||
814 | |||
815 | memcpy(&lw->pdata, pdata, sizeof(lw->pdata)); | ||
816 | |||
817 | mutex_init(&lw->lock); | ||
818 | |||
819 | lw->video_dev = timblogiw_template; | ||
820 | |||
821 | strlcpy(lw->v4l2_dev.name, DRIVER_NAME, sizeof(lw->v4l2_dev.name)); | ||
822 | err = v4l2_device_register(NULL, &lw->v4l2_dev); | ||
823 | if (err) | ||
824 | goto err_register; | ||
825 | |||
826 | lw->video_dev.v4l2_dev = &lw->v4l2_dev; | ||
827 | |||
828 | platform_set_drvdata(pdev, lw); | ||
829 | video_set_drvdata(&lw->video_dev, lw); | ||
830 | |||
831 | err = video_register_device(&lw->video_dev, VFL_TYPE_GRABBER, 0); | ||
832 | if (err) { | ||
833 | dev_err(&pdev->dev, "Error reg video: %d\n", err); | ||
834 | goto err_request; | ||
835 | } | ||
836 | |||
837 | |||
838 | return 0; | ||
839 | |||
840 | err_request: | ||
841 | platform_set_drvdata(pdev, NULL); | ||
842 | v4l2_device_unregister(&lw->v4l2_dev); | ||
843 | err_register: | ||
844 | kfree(lw); | ||
845 | err: | ||
846 | dev_err(&pdev->dev, "Failed to register: %d\n", err); | ||
847 | |||
848 | return err; | ||
849 | } | ||
850 | |||
851 | static int __devexit timblogiw_remove(struct platform_device *pdev) | ||
852 | { | ||
853 | struct timblogiw *lw = platform_get_drvdata(pdev); | ||
854 | |||
855 | video_unregister_device(&lw->video_dev); | ||
856 | |||
857 | v4l2_device_unregister(&lw->v4l2_dev); | ||
858 | |||
859 | kfree(lw); | ||
860 | |||
861 | platform_set_drvdata(pdev, NULL); | ||
862 | |||
863 | return 0; | ||
864 | } | ||
865 | |||
866 | static struct platform_driver timblogiw_platform_driver = { | ||
867 | .driver = { | ||
868 | .name = DRIVER_NAME, | ||
869 | .owner = THIS_MODULE, | ||
870 | }, | ||
871 | .probe = timblogiw_probe, | ||
872 | .remove = __devexit_p(timblogiw_remove), | ||
873 | }; | ||
874 | |||
875 | /* Module functions */ | ||
876 | |||
877 | static int __init timblogiw_init(void) | ||
878 | { | ||
879 | return platform_driver_register(&timblogiw_platform_driver); | ||
880 | } | ||
881 | |||
882 | static void __exit timblogiw_exit(void) | ||
883 | { | ||
884 | platform_driver_unregister(&timblogiw_platform_driver); | ||
885 | } | ||
886 | |||
887 | module_init(timblogiw_init); | ||
888 | module_exit(timblogiw_exit); | ||
889 | |||
890 | MODULE_DESCRIPTION(TIMBLOGIWIN_NAME); | ||
891 | MODULE_AUTHOR("Pelagicore AB <info@pelagicore.com>"); | ||
892 | MODULE_LICENSE("GPL v2"); | ||
893 | MODULE_ALIAS("platform:"DRIVER_NAME); | ||
diff --git a/drivers/media/video/tlg2300/Kconfig b/drivers/media/video/tlg2300/Kconfig index 1686ebfa6951..645d915267e6 100644 --- a/drivers/media/video/tlg2300/Kconfig +++ b/drivers/media/video/tlg2300/Kconfig | |||
@@ -1,9 +1,9 @@ | |||
1 | config VIDEO_TLG2300 | 1 | config VIDEO_TLG2300 |
2 | tristate "Telegent TLG2300 USB video capture support" | 2 | tristate "Telegent TLG2300 USB video capture support" |
3 | depends on VIDEO_DEV && I2C && INPUT && SND && DVB_CORE | 3 | depends on VIDEO_DEV && I2C && SND && DVB_CORE |
4 | select VIDEO_TUNER | 4 | select VIDEO_TUNER |
5 | select VIDEO_TVEEPROM | 5 | select VIDEO_TVEEPROM |
6 | depends on VIDEO_IR | 6 | depends on RC_CORE |
7 | select VIDEOBUF_VMALLOC | 7 | select VIDEOBUF_VMALLOC |
8 | select SND_PCM | 8 | select SND_PCM |
9 | select VIDEOBUF_DVB | 9 | select VIDEOBUF_DVB |
diff --git a/drivers/media/video/usbvideo/Kconfig b/drivers/media/video/usbvideo/Kconfig deleted file mode 100644 index dfa7fc68a657..000000000000 --- a/drivers/media/video/usbvideo/Kconfig +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | config VIDEO_USBVIDEO | ||
2 | tristate | ||
3 | |||
4 | config USB_VICAM | ||
5 | tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)" | ||
6 | depends on VIDEO_V4L1 && EXPERIMENTAL | ||
7 | select VIDEO_USBVIDEO | ||
8 | ---help--- | ||
9 | Say Y here if you have 3com homeconnect camera (vicam). | ||
10 | |||
11 | To compile this driver as a module, choose M here: the | ||
12 | module will be called vicam. | ||
13 | |||
14 | config USB_IBMCAM | ||
15 | tristate "USB IBM (Xirlink) C-it Camera support (DEPRECATED)" | ||
16 | depends on VIDEO_V4L1 | ||
17 | select VIDEO_USBVIDEO | ||
18 | ---help--- | ||
19 | This driver is DEPRECATED please use the gspca xirlink_cit module | ||
20 | instead. | ||
21 | |||
22 | Say Y here if you want to connect a IBM "C-It" camera, also known as | ||
23 | "Xirlink PC Camera" to your computer's USB port. | ||
24 | |||
25 | To compile this driver as a module, choose M here: the | ||
26 | module will be called ibmcam. | ||
27 | |||
28 | This camera has several configuration options which | ||
29 | can be specified when you load the module. Read | ||
30 | <file:Documentation/video4linux/ibmcam.txt> to learn more. | ||
31 | |||
32 | config USB_KONICAWC | ||
33 | tristate "USB Konica Webcam support (DEPRECATED)" | ||
34 | depends on VIDEO_V4L1 | ||
35 | select VIDEO_USBVIDEO | ||
36 | ---help--- | ||
37 | This driver is DEPRECATED (and known to crash) please use the | ||
38 | gspca konica module instead. | ||
39 | |||
40 | Say Y here if you want support for webcams based on a Konica | ||
41 | chipset. This is known to work with the Intel YC76 webcam. | ||
42 | |||
43 | To compile this driver as a module, choose M here: the | ||
44 | module will be called konicawc. | ||
45 | |||
diff --git a/drivers/media/video/usbvideo/Makefile b/drivers/media/video/usbvideo/Makefile deleted file mode 100644 index bb52eb8dc2f9..000000000000 --- a/drivers/media/video/usbvideo/Makefile +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | obj-$(CONFIG_VIDEO_USBVIDEO) += usbvideo.o | ||
2 | obj-$(CONFIG_USB_IBMCAM) += ibmcam.o ultracam.o | ||
3 | obj-$(CONFIG_USB_KONICAWC) += konicawc.o | ||
4 | obj-$(CONFIG_USB_VICAM) += vicam.o | ||
diff --git a/drivers/media/video/usbvideo/ibmcam.c b/drivers/media/video/usbvideo/ibmcam.c deleted file mode 100644 index b08549661781..000000000000 --- a/drivers/media/video/usbvideo/ibmcam.c +++ /dev/null | |||
@@ -1,3977 +0,0 @@ | |||
1 | /* | ||
2 | * USB IBM C-It Video Camera driver | ||
3 | * | ||
4 | * Supports Xirlink C-It Video Camera, IBM PC Camera, | ||
5 | * IBM NetCamera and Veo Stingray. | ||
6 | * | ||
7 | * This driver is based on earlier work of: | ||
8 | * | ||
9 | * (C) Copyright 1999 Johannes Erdfelt | ||
10 | * (C) Copyright 1999 Randy Dunlap | ||
11 | * | ||
12 | * 5/24/00 Removed optional (and unnecessary) locking of the driver while | ||
13 | * the device remains plugged in. Corrected race conditions in ibmcam_open | ||
14 | * and ibmcam_probe() routines using this as a guideline: | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/init.h> | ||
20 | |||
21 | #include "usbvideo.h" | ||
22 | |||
23 | #define IBMCAM_VENDOR_ID 0x0545 | ||
24 | #define IBMCAM_PRODUCT_ID 0x8080 | ||
25 | #define NETCAM_PRODUCT_ID 0x8002 /* IBM NetCamera, close to model 2 */ | ||
26 | #define VEO_800C_PRODUCT_ID 0x800C /* Veo Stingray, repackaged Model 2 */ | ||
27 | #define VEO_800D_PRODUCT_ID 0x800D /* Veo Stingray, repackaged Model 4 */ | ||
28 | |||
29 | #define MAX_IBMCAM 4 /* How many devices we allow to connect */ | ||
30 | #define USES_IBMCAM_PUTPIXEL 0 /* 0=Fast/oops 1=Slow/secure */ | ||
31 | |||
32 | /* Header signatures */ | ||
33 | |||
34 | /* Model 1 header: 00 FF 00 xx */ | ||
35 | #define HDRSIG_MODEL1_128x96 0x06 /* U Y V Y ... */ | ||
36 | #define HDRSIG_MODEL1_176x144 0x0e /* U Y V Y ... */ | ||
37 | #define HDRSIG_MODEL1_352x288 0x00 /* V Y U Y ... */ | ||
38 | |||
39 | #define IBMCAM_MODEL_1 1 /* XVP-501, 3 interfaces, rev. 0.02 */ | ||
40 | #define IBMCAM_MODEL_2 2 /* KSX-X9903, 2 interfaces, rev. 3.0a */ | ||
41 | #define IBMCAM_MODEL_3 3 /* KSX-X9902, 2 interfaces, rev. 3.01 */ | ||
42 | #define IBMCAM_MODEL_4 4 /* IBM NetCamera, 0545/8002/3.0a */ | ||
43 | |||
44 | /* Video sizes supported */ | ||
45 | #define VIDEOSIZE_128x96 VIDEOSIZE(128, 96) | ||
46 | #define VIDEOSIZE_176x144 VIDEOSIZE(176,144) | ||
47 | #define VIDEOSIZE_352x288 VIDEOSIZE(352,288) | ||
48 | #define VIDEOSIZE_320x240 VIDEOSIZE(320,240) | ||
49 | #define VIDEOSIZE_352x240 VIDEOSIZE(352,240) | ||
50 | #define VIDEOSIZE_640x480 VIDEOSIZE(640,480) | ||
51 | #define VIDEOSIZE_160x120 VIDEOSIZE(160,120) | ||
52 | |||
53 | /* Video sizes supported */ | ||
54 | enum { | ||
55 | SIZE_128x96 = 0, | ||
56 | SIZE_160x120, | ||
57 | SIZE_176x144, | ||
58 | SIZE_320x240, | ||
59 | SIZE_352x240, | ||
60 | SIZE_352x288, | ||
61 | SIZE_640x480, | ||
62 | /* Add/remove/rearrange items before this line */ | ||
63 | SIZE_LastItem | ||
64 | }; | ||
65 | |||
66 | /* | ||
67 | * This structure lives in uvd->user field. | ||
68 | */ | ||
69 | typedef struct { | ||
70 | int initialized; /* Had we already sent init sequence? */ | ||
71 | int camera_model; /* What type of IBM camera we got? */ | ||
72 | int has_hdr; | ||
73 | } ibmcam_t; | ||
74 | #define IBMCAM_T(uvd) ((ibmcam_t *)((uvd)->user_data)) | ||
75 | |||
76 | static struct usbvideo *cams; | ||
77 | |||
78 | static int debug; | ||
79 | |||
80 | static int flags; /* = FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */ | ||
81 | |||
82 | static const int min_canvasWidth = 8; | ||
83 | static const int min_canvasHeight = 4; | ||
84 | |||
85 | static int lighting = 1; /* Medium */ | ||
86 | |||
87 | #define SHARPNESS_MIN 0 | ||
88 | #define SHARPNESS_MAX 6 | ||
89 | static int sharpness = 4; /* Low noise, good details */ | ||
90 | |||
91 | #define FRAMERATE_MIN 0 | ||
92 | #define FRAMERATE_MAX 6 | ||
93 | static int framerate = -1; | ||
94 | |||
95 | static int size = SIZE_352x288; | ||
96 | |||
97 | /* | ||
98 | * Here we define several initialization variables. They may | ||
99 | * be used to automatically set color, hue, brightness and | ||
100 | * contrast to desired values. This is particularly useful in | ||
101 | * case of webcams (which have no controls and no on-screen | ||
102 | * output) and also when a client V4L software is used that | ||
103 | * does not have some of those controls. In any case it's | ||
104 | * good to have startup values as options. | ||
105 | * | ||
106 | * These values are all in [0..255] range. This simplifies | ||
107 | * operation. Note that actual values of V4L variables may | ||
108 | * be scaled up (as much as << 8). User can see that only | ||
109 | * on overlay output, however, or through a V4L client. | ||
110 | */ | ||
111 | static int init_brightness = 128; | ||
112 | static int init_contrast = 192; | ||
113 | static int init_color = 128; | ||
114 | static int init_hue = 128; | ||
115 | static int hue_correction = 128; | ||
116 | |||
117 | /* Settings for camera model 2 */ | ||
118 | static int init_model2_rg2 = -1; | ||
119 | static int init_model2_sat = -1; | ||
120 | static int init_model2_yb = -1; | ||
121 | |||
122 | /* 01.01.08 - Added for RCA video in support -LO */ | ||
123 | /* Settings for camera model 3 */ | ||
124 | static int init_model3_input; | ||
125 | |||
126 | module_param(debug, int, 0); | ||
127 | MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)"); | ||
128 | module_param(flags, int, 0); | ||
129 | MODULE_PARM_DESC(flags, "Bitfield: 0=VIDIOCSYNC, 1=B/W, 2=show hints, 3=show stats, 4=test pattern, 5=separate frames, 6=clean frames"); | ||
130 | module_param(framerate, int, 0); | ||
131 | MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)"); | ||
132 | module_param(lighting, int, 0); | ||
133 | MODULE_PARM_DESC(lighting, "Photosensitivity: 0=bright, 1=medium (default), 2=low light"); | ||
134 | module_param(sharpness, int, 0); | ||
135 | MODULE_PARM_DESC(sharpness, "Model1 noise reduction: 0=smooth, 6=sharp (default=4)"); | ||
136 | module_param(size, int, 0); | ||
137 | MODULE_PARM_DESC(size, "Image size: 0=128x96 1=160x120 2=176x144 3=320x240 4=352x240 5=352x288 6=640x480 (default=5)"); | ||
138 | module_param(init_brightness, int, 0); | ||
139 | MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)"); | ||
140 | module_param(init_contrast, int, 0); | ||
141 | MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)"); | ||
142 | module_param(init_color, int, 0); | ||
143 | MODULE_PARM_DESC(init_color, "Color preconfiguration: 0-255 (default=128)"); | ||
144 | module_param(init_hue, int, 0); | ||
145 | MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)"); | ||
146 | module_param(hue_correction, int, 0); | ||
147 | MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)"); | ||
148 | |||
149 | module_param(init_model2_rg2, int, 0); | ||
150 | MODULE_PARM_DESC(init_model2_rg2, "Model2 preconfiguration: 0-255 (default=47)"); | ||
151 | module_param(init_model2_sat, int, 0); | ||
152 | MODULE_PARM_DESC(init_model2_sat, "Model2 preconfiguration: 0-255 (default=52)"); | ||
153 | module_param(init_model2_yb, int, 0); | ||
154 | MODULE_PARM_DESC(init_model2_yb, "Model2 preconfiguration: 0-255 (default=160)"); | ||
155 | |||
156 | /* 01.01.08 - Added for RCA video in support -LO */ | ||
157 | module_param(init_model3_input, int, 0); | ||
158 | MODULE_PARM_DESC(init_model3_input, "Model3 input: 0=CCD 1=RCA"); | ||
159 | |||
160 | MODULE_AUTHOR ("Dmitri"); | ||
161 | MODULE_DESCRIPTION ("IBM/Xirlink C-it USB Camera Driver for Linux (c) 2000"); | ||
162 | MODULE_LICENSE("GPL"); | ||
163 | |||
164 | /* Still mysterious i2c commands */ | ||
165 | static const unsigned short unknown_88 = 0x0088; | ||
166 | static const unsigned short unknown_89 = 0x0089; | ||
167 | static const unsigned short bright_3x[3] = { 0x0031, 0x0032, 0x0033 }; | ||
168 | static const unsigned short contrast_14 = 0x0014; | ||
169 | static const unsigned short light_27 = 0x0027; | ||
170 | static const unsigned short sharp_13 = 0x0013; | ||
171 | |||
172 | /* i2c commands for Model 2 cameras */ | ||
173 | static const unsigned short mod2_brightness = 0x001a; /* $5b .. $ee; default=$5a */ | ||
174 | static const unsigned short mod2_set_framerate = 0x001c; /* 0 (fast).. $1F (slow) */ | ||
175 | static const unsigned short mod2_color_balance_rg2 = 0x001e; /* 0 (red) .. $7F (green) */ | ||
176 | static const unsigned short mod2_saturation = 0x0020; /* 0 (b/w) - $7F (full color) */ | ||
177 | static const unsigned short mod2_color_balance_yb = 0x0022; /* 0..$7F, $50 is about right */ | ||
178 | static const unsigned short mod2_hue = 0x0024; /* 0..$7F, $70 is about right */ | ||
179 | static const unsigned short mod2_sensitivity = 0x0028; /* 0 (min) .. $1F (max) */ | ||
180 | |||
181 | struct struct_initData { | ||
182 | unsigned char req; | ||
183 | unsigned short value; | ||
184 | unsigned short index; | ||
185 | }; | ||
186 | |||
187 | /* | ||
188 | * ibmcam_size_to_videosize() | ||
189 | * | ||
190 | * This procedure converts module option 'size' into the actual | ||
191 | * videosize_t that defines the image size in pixels. We need | ||
192 | * simplified 'size' because user wants a simple enumerated list | ||
193 | * of choices, not an infinite set of possibilities. | ||
194 | */ | ||
195 | static videosize_t ibmcam_size_to_videosize(int size) | ||
196 | { | ||
197 | videosize_t vs = VIDEOSIZE_352x288; | ||
198 | RESTRICT_TO_RANGE(size, 0, (SIZE_LastItem-1)); | ||
199 | switch (size) { | ||
200 | case SIZE_128x96: | ||
201 | vs = VIDEOSIZE_128x96; | ||
202 | break; | ||
203 | case SIZE_160x120: | ||
204 | vs = VIDEOSIZE_160x120; | ||
205 | break; | ||
206 | case SIZE_176x144: | ||
207 | vs = VIDEOSIZE_176x144; | ||
208 | break; | ||
209 | case SIZE_320x240: | ||
210 | vs = VIDEOSIZE_320x240; | ||
211 | break; | ||
212 | case SIZE_352x240: | ||
213 | vs = VIDEOSIZE_352x240; | ||
214 | break; | ||
215 | case SIZE_352x288: | ||
216 | vs = VIDEOSIZE_352x288; | ||
217 | break; | ||
218 | case SIZE_640x480: | ||
219 | vs = VIDEOSIZE_640x480; | ||
220 | break; | ||
221 | default: | ||
222 | err("size=%d. is not valid", size); | ||
223 | break; | ||
224 | } | ||
225 | return vs; | ||
226 | } | ||
227 | |||
228 | /* | ||
229 | * ibmcam_find_header() | ||
230 | * | ||
231 | * Locate one of supported header markers in the queue. | ||
232 | * Once found, remove all preceding bytes AND the marker (4 bytes) | ||
233 | * from the data pump queue. Whatever follows must be video lines. | ||
234 | * | ||
235 | * History: | ||
236 | * 1/21/00 Created. | ||
237 | */ | ||
238 | static enum ParseState ibmcam_find_header(struct uvd *uvd) /* FIXME: Add frame here */ | ||
239 | { | ||
240 | struct usbvideo_frame *frame; | ||
241 | ibmcam_t *icam; | ||
242 | |||
243 | if ((uvd->curframe) < 0 || (uvd->curframe >= USBVIDEO_NUMFRAMES)) { | ||
244 | err("ibmcam_find_header: Illegal frame %d.", uvd->curframe); | ||
245 | return scan_EndParse; | ||
246 | } | ||
247 | icam = IBMCAM_T(uvd); | ||
248 | assert(icam != NULL); | ||
249 | frame = &uvd->frame[uvd->curframe]; | ||
250 | icam->has_hdr = 0; | ||
251 | switch (icam->camera_model) { | ||
252 | case IBMCAM_MODEL_1: | ||
253 | { | ||
254 | const int marker_len = 4; | ||
255 | while (RingQueue_GetLength(&uvd->dp) >= marker_len) { | ||
256 | if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) && | ||
257 | (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF) && | ||
258 | (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00)) | ||
259 | { | ||
260 | #if 0 /* This code helps to detect new frame markers */ | ||
261 | dev_info(&uvd->dev->dev, | ||
262 | "Header sig: 00 FF 00 %02X\n", | ||
263 | RING_QUEUE_PEEK(&uvd->dp, 3)); | ||
264 | #endif | ||
265 | frame->header = RING_QUEUE_PEEK(&uvd->dp, 3); | ||
266 | if ((frame->header == HDRSIG_MODEL1_128x96) || | ||
267 | (frame->header == HDRSIG_MODEL1_176x144) || | ||
268 | (frame->header == HDRSIG_MODEL1_352x288)) | ||
269 | { | ||
270 | #if 0 | ||
271 | dev_info(&uvd->dev->dev, | ||
272 | "Header found.\n"); | ||
273 | #endif | ||
274 | RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len); | ||
275 | icam->has_hdr = 1; | ||
276 | break; | ||
277 | } | ||
278 | } | ||
279 | /* If we are still here then this doesn't look like a header */ | ||
280 | RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1); | ||
281 | } | ||
282 | break; | ||
283 | } | ||
284 | case IBMCAM_MODEL_2: | ||
285 | case IBMCAM_MODEL_4: | ||
286 | { | ||
287 | int marker_len = 0; | ||
288 | switch (uvd->videosize) { | ||
289 | case VIDEOSIZE_176x144: | ||
290 | marker_len = 10; | ||
291 | break; | ||
292 | default: | ||
293 | marker_len = 2; | ||
294 | break; | ||
295 | } | ||
296 | while (RingQueue_GetLength(&uvd->dp) >= marker_len) { | ||
297 | if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) && | ||
298 | (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF)) | ||
299 | { | ||
300 | #if 0 | ||
301 | dev_info(&uvd->dev->dev, "Header found.\n"); | ||
302 | #endif | ||
303 | RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len); | ||
304 | icam->has_hdr = 1; | ||
305 | frame->header = HDRSIG_MODEL1_176x144; | ||
306 | break; | ||
307 | } | ||
308 | /* If we are still here then this doesn't look like a header */ | ||
309 | RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1); | ||
310 | } | ||
311 | break; | ||
312 | } | ||
313 | case IBMCAM_MODEL_3: | ||
314 | { /* | ||
315 | * Headers: (one precedes every frame). nc=no compression, | ||
316 | * bq=best quality bf=best frame rate. | ||
317 | * | ||
318 | * 176x144: 00 FF 02 { 0A=nc CA=bq EA=bf } | ||
319 | * 320x240: 00 FF 02 { 08=nc 28=bq 68=bf } | ||
320 | * 640x480: 00 FF 03 { 08=nc 28=bq 68=bf } | ||
321 | * | ||
322 | * Bytes '00 FF' seem to indicate header. Other two bytes | ||
323 | * encode the frame type. This is a set of bit fields that | ||
324 | * encode image size, compression type etc. These fields | ||
325 | * do NOT contain frame number because all frames carry | ||
326 | * the same header. | ||
327 | */ | ||
328 | const int marker_len = 4; | ||
329 | while (RingQueue_GetLength(&uvd->dp) >= marker_len) { | ||
330 | if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) && | ||
331 | (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF) && | ||
332 | (RING_QUEUE_PEEK(&uvd->dp, 2) != 0xFF)) | ||
333 | { | ||
334 | /* | ||
335 | * Combine 2 bytes of frame type into one | ||
336 | * easy to use value | ||
337 | */ | ||
338 | unsigned long byte3, byte4; | ||
339 | |||
340 | byte3 = RING_QUEUE_PEEK(&uvd->dp, 2); | ||
341 | byte4 = RING_QUEUE_PEEK(&uvd->dp, 3); | ||
342 | frame->header = (byte3 << 8) | byte4; | ||
343 | #if 0 | ||
344 | dev_info(&uvd->dev->dev, "Header found.\n"); | ||
345 | #endif | ||
346 | RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len); | ||
347 | icam->has_hdr = 1; | ||
348 | break; | ||
349 | } | ||
350 | /* If we are still here then this doesn't look like a header */ | ||
351 | RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1); | ||
352 | } | ||
353 | break; | ||
354 | } | ||
355 | default: | ||
356 | break; | ||
357 | } | ||
358 | if (!icam->has_hdr) { | ||
359 | if (uvd->debug > 2) | ||
360 | dev_info(&uvd->dev->dev, | ||
361 | "Skipping frame, no header\n"); | ||
362 | return scan_EndParse; | ||
363 | } | ||
364 | |||
365 | /* Header found */ | ||
366 | icam->has_hdr = 1; | ||
367 | uvd->stats.header_count++; | ||
368 | frame->scanstate = ScanState_Lines; | ||
369 | frame->curline = 0; | ||
370 | |||
371 | if (flags & FLAGS_FORCE_TESTPATTERN) { | ||
372 | usbvideo_TestPattern(uvd, 1, 1); | ||
373 | return scan_NextFrame; | ||
374 | } | ||
375 | return scan_Continue; | ||
376 | } | ||
377 | |||
378 | /* | ||
379 | * ibmcam_parse_lines() | ||
380 | * | ||
381 | * Parse one line (interlaced) from the buffer, put | ||
382 | * decoded RGB value into the current frame buffer | ||
383 | * and add the written number of bytes (RGB) to | ||
384 | * the *pcopylen. | ||
385 | * | ||
386 | * History: | ||
387 | * 21-Jan-2000 Created. | ||
388 | * 12-Oct-2000 Reworked to reflect interlaced nature of the data. | ||
389 | */ | ||
390 | static enum ParseState ibmcam_parse_lines( | ||
391 | struct uvd *uvd, | ||
392 | struct usbvideo_frame *frame, | ||
393 | long *pcopylen) | ||
394 | { | ||
395 | unsigned char *f; | ||
396 | ibmcam_t *icam; | ||
397 | unsigned int len, scanLength, scanHeight, order_uv, order_yc; | ||
398 | int v4l_linesize; /* V4L line offset */ | ||
399 | const int hue_corr = (uvd->vpic.hue - 0x8000) >> 10; /* -32..+31 */ | ||
400 | const int hue2_corr = (hue_correction - 128) / 4; /* -32..+31 */ | ||
401 | const int ccm = 128; /* Color correction median - see below */ | ||
402 | int y, u, v, i, frame_done=0, color_corr; | ||
403 | static unsigned char lineBuffer[640*3]; | ||
404 | unsigned const char *chromaLine, *lumaLine; | ||
405 | |||
406 | assert(uvd != NULL); | ||
407 | assert(frame != NULL); | ||
408 | icam = IBMCAM_T(uvd); | ||
409 | assert(icam != NULL); | ||
410 | color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/ | ||
411 | RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1); | ||
412 | |||
413 | v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL; | ||
414 | |||
415 | if (IBMCAM_T(uvd)->camera_model == IBMCAM_MODEL_4) { | ||
416 | /* Model 4 frame markers do not carry image size identification */ | ||
417 | switch (uvd->videosize) { | ||
418 | case VIDEOSIZE_128x96: | ||
419 | case VIDEOSIZE_160x120: | ||
420 | case VIDEOSIZE_176x144: | ||
421 | scanLength = VIDEOSIZE_X(uvd->videosize); | ||
422 | scanHeight = VIDEOSIZE_Y(uvd->videosize); | ||
423 | break; | ||
424 | default: | ||
425 | err("ibmcam_parse_lines: Wrong mode."); | ||
426 | return scan_Out; | ||
427 | } | ||
428 | order_yc = 1; /* order_yc: true=Yc false=cY ('c'=either U or V) */ | ||
429 | order_uv = 1; /* Always true in this algorithm */ | ||
430 | } else { | ||
431 | switch (frame->header) { | ||
432 | case HDRSIG_MODEL1_128x96: | ||
433 | scanLength = 128; | ||
434 | scanHeight = 96; | ||
435 | order_uv = 1; /* U Y V Y ... */ | ||
436 | break; | ||
437 | case HDRSIG_MODEL1_176x144: | ||
438 | scanLength = 176; | ||
439 | scanHeight = 144; | ||
440 | order_uv = 1; /* U Y V Y ... */ | ||
441 | break; | ||
442 | case HDRSIG_MODEL1_352x288: | ||
443 | scanLength = 352; | ||
444 | scanHeight = 288; | ||
445 | order_uv = 0; /* Y V Y V ... */ | ||
446 | break; | ||
447 | default: | ||
448 | err("Unknown header signature 00 FF 00 %02lX", frame->header); | ||
449 | return scan_NextFrame; | ||
450 | } | ||
451 | /* order_yc: true=Yc false=cY ('c'=either U or V) */ | ||
452 | order_yc = (IBMCAM_T(uvd)->camera_model == IBMCAM_MODEL_2); | ||
453 | } | ||
454 | |||
455 | len = scanLength * 3; | ||
456 | assert(len <= sizeof(lineBuffer)); | ||
457 | |||
458 | /* | ||
459 | * Lines are organized this way: | ||
460 | * | ||
461 | * I420: | ||
462 | * ~~~~ | ||
463 | * <scanLength-> | ||
464 | * ___________________________________ | ||
465 | * |-----Y-----|---UVUVUV...UVUV-----| \ | ||
466 | * |-----------+---------------------| \ | ||
467 | * |<-- 176 -->|<------ 176*2 ------>| Total 72. lines (interlaced) | ||
468 | * |... ... | ... | / | ||
469 | * |<-- 352 -->|<------ 352*2 ------>| Total 144. lines (interlaced) | ||
470 | * |___________|_____________________| / | ||
471 | * \ \ | ||
472 | * lumaLine chromaLine | ||
473 | */ | ||
474 | |||
475 | /* Make sure there's enough data for the entire line */ | ||
476 | if (RingQueue_GetLength(&uvd->dp) < len) | ||
477 | return scan_Out; | ||
478 | |||
479 | /* Suck one line out of the ring queue */ | ||
480 | RingQueue_Dequeue(&uvd->dp, lineBuffer, len); | ||
481 | |||
482 | /* | ||
483 | * Make sure that our writing into output buffer | ||
484 | * will not exceed the buffer. Mind that we may write | ||
485 | * not into current output scanline but in several after | ||
486 | * it as well (if we enlarge image vertically.) | ||
487 | */ | ||
488 | if ((frame->curline + 2) >= VIDEOSIZE_Y(frame->request)) | ||
489 | return scan_NextFrame; | ||
490 | |||
491 | /* | ||
492 | * Now we are sure that entire line (representing all 'scanLength' | ||
493 | * pixels from the camera) is available in the buffer. We | ||
494 | * start copying the line left-aligned to the V4L buffer. | ||
495 | * If the camera line is shorter then we should pad the V4L | ||
496 | * buffer with something (black) to complete the line. | ||
497 | */ | ||
498 | assert(frame->data != NULL); | ||
499 | f = frame->data + (v4l_linesize * frame->curline); | ||
500 | |||
501 | /* | ||
502 | * To obtain chrominance data from the 'chromaLine' use this: | ||
503 | * v = chromaLine[0]; // 0-1:[0], 2-3:[4], 4-5:[8]... | ||
504 | * u = chromaLine[2]; // 0-1:[2], 2-3:[6], 4-5:[10]... | ||
505 | * | ||
506 | * Indices must be calculated this way: | ||
507 | * v_index = (i >> 1) << 2; | ||
508 | * u_index = (i >> 1) << 2 + 2; | ||
509 | * | ||
510 | * where 'i' is the column number [0..VIDEOSIZE_X(frame->request)-1] | ||
511 | */ | ||
512 | lumaLine = lineBuffer; | ||
513 | chromaLine = lineBuffer + scanLength; | ||
514 | for (i = 0; i < VIDEOSIZE_X(frame->request); i++) | ||
515 | { | ||
516 | unsigned char rv, gv, bv; /* RGB components */ | ||
517 | |||
518 | /* Check for various visual debugging hints (colorized pixels) */ | ||
519 | if ((flags & FLAGS_DISPLAY_HINTS) && (icam->has_hdr)) { | ||
520 | /* | ||
521 | * This is bad and should not happen. This means that | ||
522 | * we somehow overshoot the line and encountered new | ||
523 | * frame! Obviously our camera/V4L frame size is out | ||
524 | * of whack. This cyan dot will help you to figure | ||
525 | * out where exactly the new frame arrived. | ||
526 | */ | ||
527 | if (icam->has_hdr == 1) { | ||
528 | bv = 0; /* Yellow marker */ | ||
529 | gv = 0xFF; | ||
530 | rv = 0xFF; | ||
531 | } else { | ||
532 | bv = 0xFF; /* Cyan marker */ | ||
533 | gv = 0xFF; | ||
534 | rv = 0; | ||
535 | } | ||
536 | icam->has_hdr = 0; | ||
537 | goto make_pixel; | ||
538 | } | ||
539 | |||
540 | /* | ||
541 | * Check if we are still in range. We may be out of range if our | ||
542 | * V4L canvas is wider or taller than the camera "native" image. | ||
543 | * Then we quickly fill the remainder of the line with zeros to | ||
544 | * make black color and quit the horizontal scanning loop. | ||
545 | */ | ||
546 | if (((frame->curline + 2) >= scanHeight) || (i >= scanLength)) { | ||
547 | const int j = i * V4L_BYTES_PER_PIXEL; | ||
548 | #if USES_IBMCAM_PUTPIXEL | ||
549 | /* Refresh 'f' because we don't use it much with PUTPIXEL */ | ||
550 | f = frame->data + (v4l_linesize * frame->curline) + j; | ||
551 | #endif | ||
552 | memset(f, 0, v4l_linesize - j); | ||
553 | break; | ||
554 | } | ||
555 | |||
556 | y = lumaLine[i]; | ||
557 | if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */ | ||
558 | rv = gv = bv = y; | ||
559 | else { | ||
560 | int off_0, off_2; | ||
561 | |||
562 | off_0 = (i >> 1) << 2; | ||
563 | off_2 = off_0 + 2; | ||
564 | |||
565 | if (order_yc) { | ||
566 | off_0++; | ||
567 | off_2++; | ||
568 | } | ||
569 | if (!order_uv) { | ||
570 | off_0 += 2; | ||
571 | off_2 -= 2; | ||
572 | } | ||
573 | u = chromaLine[off_0] + hue_corr; | ||
574 | v = chromaLine[off_2] + hue2_corr; | ||
575 | |||
576 | /* Apply color correction */ | ||
577 | if (color_corr != 0) { | ||
578 | /* Magnify up to 2 times, reduce down to zero saturation */ | ||
579 | u = 128 + ((ccm + color_corr) * (u - 128)) / ccm; | ||
580 | v = 128 + ((ccm + color_corr) * (v - 128)) / ccm; | ||
581 | } | ||
582 | YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv); | ||
583 | } | ||
584 | |||
585 | make_pixel: | ||
586 | /* | ||
587 | * The purpose of creating the pixel here, in one, | ||
588 | * dedicated place is that we may need to make the | ||
589 | * pixel wider and taller than it actually is. This | ||
590 | * may be used if camera generates small frames for | ||
591 | * sake of frame rate (or any other reason.) | ||
592 | * | ||
593 | * The output data consists of B, G, R bytes | ||
594 | * (in this order). | ||
595 | */ | ||
596 | #if USES_IBMCAM_PUTPIXEL | ||
597 | RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv); | ||
598 | #else | ||
599 | *f++ = bv; | ||
600 | *f++ = gv; | ||
601 | *f++ = rv; | ||
602 | #endif | ||
603 | /* | ||
604 | * Typically we do not decide within a legitimate frame | ||
605 | * that we want to end the frame. However debugging code | ||
606 | * may detect marker of new frame within the data. Then | ||
607 | * this condition activates. The 'data' pointer is already | ||
608 | * pointing at the new marker, so we'd better leave it as is. | ||
609 | */ | ||
610 | if (frame_done) | ||
611 | break; /* End scanning of lines */ | ||
612 | } | ||
613 | /* | ||
614 | * Account for number of bytes that we wrote into output V4L frame. | ||
615 | * We do it here, after we are done with the scanline, because we | ||
616 | * may fill more than one output scanline if we do vertical | ||
617 | * enlargement. | ||
618 | */ | ||
619 | frame->curline += 2; | ||
620 | if (pcopylen != NULL) | ||
621 | *pcopylen += 2 * v4l_linesize; | ||
622 | frame->deinterlace = Deinterlace_FillOddLines; | ||
623 | |||
624 | if (frame_done || (frame->curline >= VIDEOSIZE_Y(frame->request))) | ||
625 | return scan_NextFrame; | ||
626 | else | ||
627 | return scan_Continue; | ||
628 | } | ||
629 | |||
630 | /* | ||
631 | * ibmcam_model2_320x240_parse_lines() | ||
632 | * | ||
633 | * This procedure deals with a weird RGB format that is produced by IBM | ||
634 | * camera model 2 in modes 320x240 and above; 'x' below is 159 or 175, | ||
635 | * depending on horizontal size of the picture: | ||
636 | * | ||
637 | * <--- 160 or 176 pairs of RA,RB bytes -----> | ||
638 | * *-----------------------------------------* \ | ||
639 | * | RA0 | RB0 | RA1 | RB1 | ... | RAx | RBx | \ This is pair of horizontal lines, | ||
640 | * |-----+-----+-----+-----+ ... +-----+-----| *- or one interlaced line, total | ||
641 | * | B0 | G0 | B1 | G1 | ... | Bx | Gx | / 120 or 144 such pairs which yield | ||
642 | * |=====+=====+=====+=====+ ... +=====+=====| / 240 or 288 lines after deinterlacing. | ||
643 | * | ||
644 | * Each group of FOUR bytes (RAi, RBi, Bi, Gi) where i=0..frame_width/2-1 | ||
645 | * defines ONE pixel. Therefore this format yields 176x144 "decoded" | ||
646 | * resolution at best. I do not know why camera sends such format - the | ||
647 | * previous model (1) just used interlaced I420 and everyone was happy. | ||
648 | * | ||
649 | * I do not know what is the difference between RAi and RBi bytes. Both | ||
650 | * seemingly represent R component, but slightly vary in value (so that | ||
651 | * the picture looks a bit colored if one or another is used). I use | ||
652 | * them both as R component in attempt to at least partially recover the | ||
653 | * lost resolution. | ||
654 | */ | ||
655 | static enum ParseState ibmcam_model2_320x240_parse_lines( | ||
656 | struct uvd *uvd, | ||
657 | struct usbvideo_frame *frame, | ||
658 | long *pcopylen) | ||
659 | { | ||
660 | unsigned char *f, *la, *lb; | ||
661 | unsigned int len; | ||
662 | int v4l_linesize; /* V4L line offset */ | ||
663 | int i, j, frame_done=0, color_corr; | ||
664 | int scanLength, scanHeight; | ||
665 | static unsigned char lineBuffer[352*2]; | ||
666 | |||
667 | switch (uvd->videosize) { | ||
668 | case VIDEOSIZE_320x240: | ||
669 | case VIDEOSIZE_352x240: | ||
670 | case VIDEOSIZE_352x288: | ||
671 | scanLength = VIDEOSIZE_X(uvd->videosize); | ||
672 | scanHeight = VIDEOSIZE_Y(uvd->videosize); | ||
673 | break; | ||
674 | default: | ||
675 | err("ibmcam_model2_320x240_parse_lines: Wrong mode."); | ||
676 | return scan_Out; | ||
677 | } | ||
678 | |||
679 | color_corr = (uvd->vpic.colour) >> 8; /* 0..+255 */ | ||
680 | v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL; | ||
681 | |||
682 | len = scanLength * 2; /* See explanation above */ | ||
683 | assert(len <= sizeof(lineBuffer)); | ||
684 | |||
685 | /* Make sure there's enough data for the entire line */ | ||
686 | if (RingQueue_GetLength(&uvd->dp) < len) | ||
687 | return scan_Out; | ||
688 | |||
689 | /* Suck one line out of the ring queue */ | ||
690 | RingQueue_Dequeue(&uvd->dp, lineBuffer, len); | ||
691 | |||
692 | /* | ||
693 | * Make sure that our writing into output buffer | ||
694 | * will not exceed the buffer. Mind that we may write | ||
695 | * not into current output scanline but in several after | ||
696 | * it as well (if we enlarge image vertically.) | ||
697 | */ | ||
698 | if ((frame->curline + 2) >= VIDEOSIZE_Y(frame->request)) | ||
699 | return scan_NextFrame; | ||
700 | |||
701 | la = lineBuffer; | ||
702 | lb = lineBuffer + scanLength; | ||
703 | |||
704 | /* | ||
705 | * Now we are sure that entire line (representing all | ||
706 | * VIDEOSIZE_X(frame->request) | ||
707 | * pixels from the camera) is available in the scratch buffer. We | ||
708 | * start copying the line left-aligned to the V4L buffer (which | ||
709 | * might be larger - not smaller, hopefully). If the camera | ||
710 | * line is shorter then we should pad the V4L buffer with something | ||
711 | * (black in this case) to complete the line. | ||
712 | */ | ||
713 | f = frame->data + (v4l_linesize * frame->curline); | ||
714 | |||
715 | /* Fill the 2-line strip */ | ||
716 | for (i = 0; i < VIDEOSIZE_X(frame->request); i++) { | ||
717 | int y, rv, gv, bv; /* RGB components */ | ||
718 | |||
719 | j = i & (~1); | ||
720 | |||
721 | /* Check for various visual debugging hints (colorized pixels) */ | ||
722 | if ((flags & FLAGS_DISPLAY_HINTS) && (IBMCAM_T(uvd)->has_hdr)) { | ||
723 | if (IBMCAM_T(uvd)->has_hdr == 1) { | ||
724 | bv = 0; /* Yellow marker */ | ||
725 | gv = 0xFF; | ||
726 | rv = 0xFF; | ||
727 | } else { | ||
728 | bv = 0xFF; /* Cyan marker */ | ||
729 | gv = 0xFF; | ||
730 | rv = 0; | ||
731 | } | ||
732 | IBMCAM_T(uvd)->has_hdr = 0; | ||
733 | goto make_pixel; | ||
734 | } | ||
735 | |||
736 | /* | ||
737 | * Check if we are still in range. We may be out of range if our | ||
738 | * V4L canvas is wider or taller than the camera "native" image. | ||
739 | * Then we quickly fill the remainder of the line with zeros to | ||
740 | * make black color and quit the horizontal scanning loop. | ||
741 | */ | ||
742 | if (((frame->curline + 2) >= scanHeight) || (i >= scanLength)) { | ||
743 | const int offset = i * V4L_BYTES_PER_PIXEL; | ||
744 | #if USES_IBMCAM_PUTPIXEL | ||
745 | /* Refresh 'f' because we don't use it much with PUTPIXEL */ | ||
746 | f = frame->data + (v4l_linesize * frame->curline) + offset; | ||
747 | #endif | ||
748 | memset(f, 0, v4l_linesize - offset); | ||
749 | break; | ||
750 | } | ||
751 | |||
752 | /* | ||
753 | * Here I use RA and RB components, one per physical pixel. | ||
754 | * This causes fine vertical grid on the picture but may improve | ||
755 | * horizontal resolution. If you prefer replicating, use this: | ||
756 | * rv = la[j + 0]; ... or ... rv = la[j + 1]; | ||
757 | * then the pixel will be replicated. | ||
758 | */ | ||
759 | rv = la[i]; | ||
760 | gv = lb[j + 1]; | ||
761 | bv = lb[j + 0]; | ||
762 | |||
763 | y = (rv + gv + bv) / 3; /* Brightness (badly calculated) */ | ||
764 | |||
765 | if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */ | ||
766 | rv = gv = bv = y; | ||
767 | else if (color_corr != 128) { | ||
768 | |||
769 | /* Calculate difference between color and brightness */ | ||
770 | rv -= y; | ||
771 | gv -= y; | ||
772 | bv -= y; | ||
773 | |||
774 | /* Scale differences */ | ||
775 | rv = (rv * color_corr) / 128; | ||
776 | gv = (gv * color_corr) / 128; | ||
777 | bv = (bv * color_corr) / 128; | ||
778 | |||
779 | /* Reapply brightness */ | ||
780 | rv += y; | ||
781 | gv += y; | ||
782 | bv += y; | ||
783 | |||
784 | /* Watch for overflows */ | ||
785 | RESTRICT_TO_RANGE(rv, 0, 255); | ||
786 | RESTRICT_TO_RANGE(gv, 0, 255); | ||
787 | RESTRICT_TO_RANGE(bv, 0, 255); | ||
788 | } | ||
789 | |||
790 | make_pixel: | ||
791 | RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv); | ||
792 | } | ||
793 | /* | ||
794 | * Account for number of bytes that we wrote into output V4L frame. | ||
795 | * We do it here, after we are done with the scanline, because we | ||
796 | * may fill more than one output scanline if we do vertical | ||
797 | * enlargement. | ||
798 | */ | ||
799 | frame->curline += 2; | ||
800 | *pcopylen += v4l_linesize * 2; | ||
801 | frame->deinterlace = Deinterlace_FillOddLines; | ||
802 | |||
803 | if (frame_done || (frame->curline >= VIDEOSIZE_Y(frame->request))) | ||
804 | return scan_NextFrame; | ||
805 | else | ||
806 | return scan_Continue; | ||
807 | } | ||
808 | |||
809 | /* | ||
810 | * ibmcam_model3_parse_lines() | ||
811 | * | ||
812 | * | Even lines | Odd Lines | | ||
813 | * -----------------------------------| | ||
814 | * |YYY........Y|UYVYUYVY.........UYVY| | ||
815 | * |YYY........Y|UYVYUYVY.........UYVY| | ||
816 | * |............|.....................| | ||
817 | * |YYY........Y|UYVYUYVY.........UYVY| | ||
818 | * |------------+---------------------| | ||
819 | * | ||
820 | * There is one (U, V) chroma pair for every four luma (Y) values. This | ||
821 | * function reads a pair of lines at a time and obtains missing chroma values | ||
822 | * from adjacent pixels. | ||
823 | */ | ||
824 | static enum ParseState ibmcam_model3_parse_lines( | ||
825 | struct uvd *uvd, | ||
826 | struct usbvideo_frame *frame, | ||
827 | long *pcopylen) | ||
828 | { | ||
829 | unsigned char *data; | ||
830 | const unsigned char *color; | ||
831 | unsigned int len; | ||
832 | int v4l_linesize; /* V4L line offset */ | ||
833 | const int hue_corr = (uvd->vpic.hue - 0x8000) >> 10; /* -32..+31 */ | ||
834 | const int hue2_corr = (hue_correction - 128) / 4; /* -32..+31 */ | ||
835 | const int ccm = 128; /* Color correction median - see below */ | ||
836 | int i, u, v, rw, data_w=0, data_h=0, color_corr; | ||
837 | static unsigned char lineBuffer[640*3]; | ||
838 | int line; | ||
839 | |||
840 | color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/ | ||
841 | RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1); | ||
842 | |||
843 | v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL; | ||
844 | |||
845 | /* The header tells us what sort of data is in this frame */ | ||
846 | switch (frame->header) { | ||
847 | /* | ||
848 | * Uncompressed modes (that are easy to decode). | ||
849 | */ | ||
850 | case 0x0308: | ||
851 | data_w = 640; | ||
852 | data_h = 480; | ||
853 | break; | ||
854 | case 0x0208: | ||
855 | data_w = 320; | ||
856 | data_h = 240; | ||
857 | break; | ||
858 | case 0x020A: | ||
859 | data_w = 160; | ||
860 | data_h = 120; | ||
861 | break; | ||
862 | /* | ||
863 | * Compressed modes (ViCE - that I don't know how to decode). | ||
864 | */ | ||
865 | case 0x0328: /* 640x480, best quality compression */ | ||
866 | case 0x0368: /* 640x480, best frame rate compression */ | ||
867 | case 0x0228: /* 320x240, best quality compression */ | ||
868 | case 0x0268: /* 320x240, best frame rate compression */ | ||
869 | case 0x02CA: /* 160x120, best quality compression */ | ||
870 | case 0x02EA: /* 160x120, best frame rate compression */ | ||
871 | /* Do nothing with this - not supported */ | ||
872 | err("Unsupported mode $%04lx", frame->header); | ||
873 | return scan_NextFrame; | ||
874 | default: | ||
875 | /* Catch unknown headers, may help in learning new headers */ | ||
876 | err("Strange frame->header=$%08lx", frame->header); | ||
877 | return scan_NextFrame; | ||
878 | } | ||
879 | |||
880 | /* | ||
881 | * Make sure that our writing into output buffer | ||
882 | * will not exceed the buffer. Note that we may write | ||
883 | * not into current output scanline but in several after | ||
884 | * it as well (if we enlarge image vertically.) | ||
885 | */ | ||
886 | if ((frame->curline + 1) >= data_h) { | ||
887 | if (uvd->debug >= 3) | ||
888 | dev_info(&uvd->dev->dev, | ||
889 | "Reached line %d. (frame is done)\n", | ||
890 | frame->curline); | ||
891 | return scan_NextFrame; | ||
892 | } | ||
893 | |||
894 | /* Make sure that lineBuffer can store two lines of data */ | ||
895 | len = 3 * data_w; /* <y-data> <uyvy-data> */ | ||
896 | assert(len <= sizeof(lineBuffer)); | ||
897 | |||
898 | /* Make sure there's enough data for two lines */ | ||
899 | if (RingQueue_GetLength(&uvd->dp) < len) | ||
900 | return scan_Out; | ||
901 | |||
902 | /* Suck two lines of data out of the ring queue */ | ||
903 | RingQueue_Dequeue(&uvd->dp, lineBuffer, len); | ||
904 | |||
905 | data = lineBuffer; | ||
906 | color = data + data_w; /* Point to where color planes begin */ | ||
907 | |||
908 | /* Bottom-to-top scanning */ | ||
909 | rw = (int)VIDEOSIZE_Y(frame->request) - (int)(frame->curline) - 1; | ||
910 | RESTRICT_TO_RANGE(rw, 0, VIDEOSIZE_Y(frame->request)-1); | ||
911 | |||
912 | /* Iterate over two lines. */ | ||
913 | for (line = 0; line < 2; line++) { | ||
914 | for (i = 0; i < VIDEOSIZE_X(frame->request); i++) { | ||
915 | int y; | ||
916 | int rv, gv, bv; /* RGB components */ | ||
917 | |||
918 | if (i >= data_w) { | ||
919 | RGB24_PUTPIXEL(frame, i, rw, 0, 0, 0); | ||
920 | continue; | ||
921 | } | ||
922 | |||
923 | /* first line is YYY...Y; second is UYVY...UYVY */ | ||
924 | y = data[(line == 0) ? i : (i*2 + 1)]; | ||
925 | |||
926 | /* Apply static color correction */ | ||
927 | u = color[(i/2)*4] + hue_corr; | ||
928 | v = color[(i/2)*4 + 2] + hue2_corr; | ||
929 | |||
930 | /* Apply color correction */ | ||
931 | if (color_corr != 0) { | ||
932 | /* Magnify up to 2 times, reduce down to zero saturation */ | ||
933 | u = 128 + ((ccm + color_corr) * (u - 128)) / ccm; | ||
934 | v = 128 + ((ccm + color_corr) * (v - 128)) / ccm; | ||
935 | } | ||
936 | |||
937 | |||
938 | YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv); | ||
939 | RGB24_PUTPIXEL(frame, i, rw, rv, gv, bv); /* No deinterlacing */ | ||
940 | } | ||
941 | |||
942 | /* Check for the end of requested data */ | ||
943 | if (rw == 0) | ||
944 | break; | ||
945 | |||
946 | /* Prepare for the second line */ | ||
947 | rw--; | ||
948 | data = lineBuffer + data_w; | ||
949 | } | ||
950 | frame->deinterlace = Deinterlace_None; | ||
951 | |||
952 | /* | ||
953 | * Account for number of bytes that we wrote into output V4L frame. | ||
954 | * We do it here, after we are done with the scanline, because we | ||
955 | * may fill more than one output scanline if we do vertical | ||
956 | * enlargement. | ||
957 | */ | ||
958 | frame->curline += 2; | ||
959 | *pcopylen += 2 * v4l_linesize; | ||
960 | |||
961 | if (frame->curline >= VIDEOSIZE_Y(frame->request)) { | ||
962 | if (uvd->debug >= 3) { | ||
963 | dev_info(&uvd->dev->dev, | ||
964 | "All requested lines (%ld.) done.\n", | ||
965 | VIDEOSIZE_Y(frame->request)); | ||
966 | } | ||
967 | return scan_NextFrame; | ||
968 | } else | ||
969 | return scan_Continue; | ||
970 | } | ||
971 | |||
972 | /* | ||
973 | * ibmcam_model4_128x96_parse_lines() | ||
974 | * | ||
975 | * This decoder is for one strange data format that is produced by Model 4 | ||
976 | * camera only in 128x96 mode. This is RGB format and here is its description. | ||
977 | * First of all, this is non-interlaced stream, meaning that all scan lines | ||
978 | * are present in the datastream. There are 96 consecutive blocks of data | ||
979 | * that describe all 96 lines of the image. Each block is 5*128 bytes long | ||
980 | * and carries R, G, B components. The format of the block is shown in the | ||
981 | * code below. First 128*2 bytes are interleaved R and G components. Then | ||
982 | * we have a gap (junk data) 64 bytes long. Then follow B and something | ||
983 | * else, also interleaved (this makes another 128*2 bytes). After that | ||
984 | * probably another 64 bytes of junk follow. | ||
985 | * | ||
986 | * History: | ||
987 | * 10-Feb-2001 Created. | ||
988 | */ | ||
989 | static enum ParseState ibmcam_model4_128x96_parse_lines( | ||
990 | struct uvd *uvd, | ||
991 | struct usbvideo_frame *frame, | ||
992 | long *pcopylen) | ||
993 | { | ||
994 | const unsigned char *data_rv, *data_gv, *data_bv; | ||
995 | unsigned int len; | ||
996 | int i, v4l_linesize; /* V4L line offset */ | ||
997 | const int data_w=128, data_h=96; | ||
998 | static unsigned char lineBuffer[128*5]; | ||
999 | |||
1000 | v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL; | ||
1001 | |||
1002 | /* | ||
1003 | * Make sure that our writing into output buffer | ||
1004 | * will not exceed the buffer. Note that we may write | ||
1005 | * not into current output scanline but in several after | ||
1006 | * it as well (if we enlarge image vertically.) | ||
1007 | */ | ||
1008 | if ((frame->curline + 1) >= data_h) { | ||
1009 | if (uvd->debug >= 3) | ||
1010 | dev_info(&uvd->dev->dev, | ||
1011 | "Reached line %d. (frame is done)\n", | ||
1012 | frame->curline); | ||
1013 | return scan_NextFrame; | ||
1014 | } | ||
1015 | |||
1016 | /* | ||
1017 | * RGRGRG .... RGRG_____________B?B?B? ... B?B?____________ | ||
1018 | * <---- 128*2 ---><---- 64 ---><--- 128*2 ---><--- 64 ---> | ||
1019 | */ | ||
1020 | |||
1021 | /* Make sure there's enough data for the entire line */ | ||
1022 | len = 5 * data_w; | ||
1023 | assert(len <= sizeof(lineBuffer)); | ||
1024 | |||
1025 | /* Make sure there's enough data for the entire line */ | ||
1026 | if (RingQueue_GetLength(&uvd->dp) < len) | ||
1027 | return scan_Out; | ||
1028 | |||
1029 | /* Suck one line out of the ring queue */ | ||
1030 | RingQueue_Dequeue(&uvd->dp, lineBuffer, len); | ||
1031 | |||
1032 | data_rv = lineBuffer; | ||
1033 | data_gv = lineBuffer + 1; | ||
1034 | data_bv = lineBuffer + data_w*2 + data_w/2; | ||
1035 | for (i = 0; i < VIDEOSIZE_X(frame->request); i++) { | ||
1036 | int rv, gv, bv; /* RGB components */ | ||
1037 | if (i < data_w) { | ||
1038 | const int j = i * 2; | ||
1039 | gv = data_rv[j]; | ||
1040 | rv = data_gv[j]; | ||
1041 | bv = data_bv[j]; | ||
1042 | if (flags & FLAGS_MONOCHROME) { | ||
1043 | unsigned long y; | ||
1044 | y = rv + gv + bv; | ||
1045 | y /= 3; | ||
1046 | if (y > 0xFF) | ||
1047 | y = 0xFF; | ||
1048 | rv = gv = bv = (unsigned char) y; | ||
1049 | } | ||
1050 | } else { | ||
1051 | rv = gv = bv = 0; | ||
1052 | } | ||
1053 | RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv); | ||
1054 | } | ||
1055 | frame->deinterlace = Deinterlace_None; | ||
1056 | frame->curline++; | ||
1057 | *pcopylen += v4l_linesize; | ||
1058 | |||
1059 | if (frame->curline >= VIDEOSIZE_Y(frame->request)) { | ||
1060 | if (uvd->debug >= 3) { | ||
1061 | dev_info(&uvd->dev->dev, | ||
1062 | "All requested lines (%ld.) done.\n", | ||
1063 | VIDEOSIZE_Y(frame->request)); | ||
1064 | } | ||
1065 | return scan_NextFrame; | ||
1066 | } else | ||
1067 | return scan_Continue; | ||
1068 | } | ||
1069 | |||
1070 | /* | ||
1071 | * ibmcam_ProcessIsocData() | ||
1072 | * | ||
1073 | * Generic routine to parse the ring queue data. It employs either | ||
1074 | * ibmcam_find_header() or ibmcam_parse_lines() to do most | ||
1075 | * of work. | ||
1076 | * | ||
1077 | * History: | ||
1078 | * 1/21/00 Created. | ||
1079 | */ | ||
1080 | static void ibmcam_ProcessIsocData(struct uvd *uvd, | ||
1081 | struct usbvideo_frame *frame) | ||
1082 | { | ||
1083 | enum ParseState newstate; | ||
1084 | long copylen = 0; | ||
1085 | int mod = IBMCAM_T(uvd)->camera_model; | ||
1086 | |||
1087 | while (1) { | ||
1088 | newstate = scan_Out; | ||
1089 | if (RingQueue_GetLength(&uvd->dp) > 0) { | ||
1090 | if (frame->scanstate == ScanState_Scanning) { | ||
1091 | newstate = ibmcam_find_header(uvd); | ||
1092 | } else if (frame->scanstate == ScanState_Lines) { | ||
1093 | if ((mod == IBMCAM_MODEL_2) && | ||
1094 | ((uvd->videosize == VIDEOSIZE_352x288) || | ||
1095 | (uvd->videosize == VIDEOSIZE_320x240) || | ||
1096 | (uvd->videosize == VIDEOSIZE_352x240))) | ||
1097 | { | ||
1098 | newstate = ibmcam_model2_320x240_parse_lines( | ||
1099 | uvd, frame, ©len); | ||
1100 | } else if (mod == IBMCAM_MODEL_4) { | ||
1101 | /* | ||
1102 | * Model 4 cameras (IBM NetCamera) use Model 2 decoder (RGB) | ||
1103 | * for 320x240 and above; 160x120 and 176x144 uses Model 1 | ||
1104 | * decoder (YUV), and 128x96 mode uses ??? | ||
1105 | */ | ||
1106 | if ((uvd->videosize == VIDEOSIZE_352x288) || | ||
1107 | (uvd->videosize == VIDEOSIZE_320x240) || | ||
1108 | (uvd->videosize == VIDEOSIZE_352x240)) | ||
1109 | { | ||
1110 | newstate = ibmcam_model2_320x240_parse_lines(uvd, frame, ©len); | ||
1111 | } else if (uvd->videosize == VIDEOSIZE_128x96) { | ||
1112 | newstate = ibmcam_model4_128x96_parse_lines(uvd, frame, ©len); | ||
1113 | } else { | ||
1114 | newstate = ibmcam_parse_lines(uvd, frame, ©len); | ||
1115 | } | ||
1116 | } else if (mod == IBMCAM_MODEL_3) { | ||
1117 | newstate = ibmcam_model3_parse_lines(uvd, frame, ©len); | ||
1118 | } else { | ||
1119 | newstate = ibmcam_parse_lines(uvd, frame, ©len); | ||
1120 | } | ||
1121 | } | ||
1122 | } | ||
1123 | if (newstate == scan_Continue) | ||
1124 | continue; | ||
1125 | else if ((newstate == scan_NextFrame) || (newstate == scan_Out)) | ||
1126 | break; | ||
1127 | else | ||
1128 | return; /* scan_EndParse */ | ||
1129 | } | ||
1130 | |||
1131 | if (newstate == scan_NextFrame) { | ||
1132 | frame->frameState = FrameState_Done; | ||
1133 | uvd->curframe = -1; | ||
1134 | uvd->stats.frame_num++; | ||
1135 | if ((mod == IBMCAM_MODEL_2) || (mod == IBMCAM_MODEL_4)) { | ||
1136 | /* Need software contrast adjustment for those cameras */ | ||
1137 | frame->flags |= USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST; | ||
1138 | } | ||
1139 | } | ||
1140 | |||
1141 | /* Update the frame's uncompressed length. */ | ||
1142 | frame->seqRead_Length += copylen; | ||
1143 | |||
1144 | #if 0 | ||
1145 | { | ||
1146 | static unsigned char j=0; | ||
1147 | memset(frame->data, j++, uvd->max_frame_size); | ||
1148 | frame->frameState = FrameState_Ready; | ||
1149 | } | ||
1150 | #endif | ||
1151 | } | ||
1152 | |||
1153 | /* | ||
1154 | * ibmcam_veio() | ||
1155 | * | ||
1156 | * History: | ||
1157 | * 1/27/00 Added check for dev == NULL; this happens if camera is unplugged. | ||
1158 | */ | ||
1159 | static int ibmcam_veio( | ||
1160 | struct uvd *uvd, | ||
1161 | unsigned char req, | ||
1162 | unsigned short value, | ||
1163 | unsigned short index) | ||
1164 | { | ||
1165 | static const char proc[] = "ibmcam_veio"; | ||
1166 | unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */; | ||
1167 | int i; | ||
1168 | |||
1169 | if (!CAMERA_IS_OPERATIONAL(uvd)) | ||
1170 | return 0; | ||
1171 | |||
1172 | if (req == 1) { | ||
1173 | i = usb_control_msg( | ||
1174 | uvd->dev, | ||
1175 | usb_rcvctrlpipe(uvd->dev, 0), | ||
1176 | req, | ||
1177 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, | ||
1178 | value, | ||
1179 | index, | ||
1180 | cp, | ||
1181 | sizeof(cp), | ||
1182 | 1000); | ||
1183 | #if 0 | ||
1184 | dev_info(&uvd->dev->dev, | ||
1185 | "USB => %02x%02x%02x%02x%02x%02x%02x%02x " | ||
1186 | "(req=$%02x val=$%04x ind=$%04x)\n", | ||
1187 | cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7], | ||
1188 | req, value, index); | ||
1189 | #endif | ||
1190 | } else { | ||
1191 | i = usb_control_msg( | ||
1192 | uvd->dev, | ||
1193 | usb_sndctrlpipe(uvd->dev, 0), | ||
1194 | req, | ||
1195 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, | ||
1196 | value, | ||
1197 | index, | ||
1198 | NULL, | ||
1199 | 0, | ||
1200 | 1000); | ||
1201 | } | ||
1202 | if (i < 0) { | ||
1203 | err("%s: ERROR=%d. Camera stopped; Reconnect or reload driver.", | ||
1204 | proc, i); | ||
1205 | uvd->last_error = i; | ||
1206 | } | ||
1207 | return i; | ||
1208 | } | ||
1209 | |||
1210 | /* | ||
1211 | * ibmcam_calculate_fps() | ||
1212 | * | ||
1213 | * This procedure roughly calculates the real frame rate based | ||
1214 | * on FPS code (framerate=NNN option). Actual FPS differs | ||
1215 | * slightly depending on lighting conditions, so that actual frame | ||
1216 | * rate is determined by the camera. Since I don't know how to ask | ||
1217 | * the camera what FPS is now I have to use the FPS code instead. | ||
1218 | * | ||
1219 | * The FPS code is in range [0..6], 0 is slowest, 6 is fastest. | ||
1220 | * Corresponding real FPS should be in range [3..30] frames per second. | ||
1221 | * The conversion formula is obvious: | ||
1222 | * | ||
1223 | * real_fps = 3 + (fps_code * 4.5) | ||
1224 | * | ||
1225 | * History: | ||
1226 | * 1/18/00 Created. | ||
1227 | */ | ||
1228 | static int ibmcam_calculate_fps(struct uvd *uvd) | ||
1229 | { | ||
1230 | return 3 + framerate*4 + framerate/2; | ||
1231 | } | ||
1232 | |||
1233 | /* | ||
1234 | * ibmcam_send_FF_04_02() | ||
1235 | * | ||
1236 | * This procedure sends magic 3-command prefix to the camera. | ||
1237 | * The purpose of this prefix is not known. | ||
1238 | * | ||
1239 | * History: | ||
1240 | * 1/2/00 Created. | ||
1241 | */ | ||
1242 | static void ibmcam_send_FF_04_02(struct uvd *uvd) | ||
1243 | { | ||
1244 | ibmcam_veio(uvd, 0, 0x00FF, 0x0127); | ||
1245 | ibmcam_veio(uvd, 0, 0x0004, 0x0124); | ||
1246 | ibmcam_veio(uvd, 0, 0x0002, 0x0124); | ||
1247 | } | ||
1248 | |||
1249 | static void ibmcam_send_00_04_06(struct uvd *uvd) | ||
1250 | { | ||
1251 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
1252 | ibmcam_veio(uvd, 0, 0x0004, 0x0124); | ||
1253 | ibmcam_veio(uvd, 0, 0x0006, 0x0124); | ||
1254 | } | ||
1255 | |||
1256 | static void ibmcam_send_x_00(struct uvd *uvd, unsigned short x) | ||
1257 | { | ||
1258 | ibmcam_veio(uvd, 0, x, 0x0127); | ||
1259 | ibmcam_veio(uvd, 0, 0x0000, 0x0124); | ||
1260 | } | ||
1261 | |||
1262 | static void ibmcam_send_x_00_05(struct uvd *uvd, unsigned short x) | ||
1263 | { | ||
1264 | ibmcam_send_x_00(uvd, x); | ||
1265 | ibmcam_veio(uvd, 0, 0x0005, 0x0124); | ||
1266 | } | ||
1267 | |||
1268 | static void ibmcam_send_x_00_05_02(struct uvd *uvd, unsigned short x) | ||
1269 | { | ||
1270 | ibmcam_veio(uvd, 0, x, 0x0127); | ||
1271 | ibmcam_veio(uvd, 0, 0x0000, 0x0124); | ||
1272 | ibmcam_veio(uvd, 0, 0x0005, 0x0124); | ||
1273 | ibmcam_veio(uvd, 0, 0x0002, 0x0124); | ||
1274 | } | ||
1275 | |||
1276 | static void ibmcam_send_x_01_00_05(struct uvd *uvd, unsigned short x) | ||
1277 | { | ||
1278 | ibmcam_veio(uvd, 0, x, 0x0127); | ||
1279 | ibmcam_veio(uvd, 0, 0x0001, 0x0124); | ||
1280 | ibmcam_veio(uvd, 0, 0x0000, 0x0124); | ||
1281 | ibmcam_veio(uvd, 0, 0x0005, 0x0124); | ||
1282 | } | ||
1283 | |||
1284 | static void ibmcam_send_x_00_05_02_01(struct uvd *uvd, unsigned short x) | ||
1285 | { | ||
1286 | ibmcam_veio(uvd, 0, x, 0x0127); | ||
1287 | ibmcam_veio(uvd, 0, 0x0000, 0x0124); | ||
1288 | ibmcam_veio(uvd, 0, 0x0005, 0x0124); | ||
1289 | ibmcam_veio(uvd, 0, 0x0002, 0x0124); | ||
1290 | ibmcam_veio(uvd, 0, 0x0001, 0x0124); | ||
1291 | } | ||
1292 | |||
1293 | static void ibmcam_send_x_00_05_02_08_01(struct uvd *uvd, unsigned short x) | ||
1294 | { | ||
1295 | ibmcam_veio(uvd, 0, x, 0x0127); | ||
1296 | ibmcam_veio(uvd, 0, 0x0000, 0x0124); | ||
1297 | ibmcam_veio(uvd, 0, 0x0005, 0x0124); | ||
1298 | ibmcam_veio(uvd, 0, 0x0002, 0x0124); | ||
1299 | ibmcam_veio(uvd, 0, 0x0008, 0x0124); | ||
1300 | ibmcam_veio(uvd, 0, 0x0001, 0x0124); | ||
1301 | } | ||
1302 | |||
1303 | static void ibmcam_Packet_Format1(struct uvd *uvd, unsigned char fkey, unsigned char val) | ||
1304 | { | ||
1305 | ibmcam_send_x_01_00_05(uvd, unknown_88); | ||
1306 | ibmcam_send_x_00_05(uvd, fkey); | ||
1307 | ibmcam_send_x_00_05_02_08_01(uvd, val); | ||
1308 | ibmcam_send_x_00_05(uvd, unknown_88); | ||
1309 | ibmcam_send_x_00_05_02_01(uvd, fkey); | ||
1310 | ibmcam_send_x_00_05(uvd, unknown_89); | ||
1311 | ibmcam_send_x_00(uvd, fkey); | ||
1312 | ibmcam_send_00_04_06(uvd); | ||
1313 | ibmcam_veio(uvd, 1, 0x0000, 0x0126); | ||
1314 | ibmcam_send_FF_04_02(uvd); | ||
1315 | } | ||
1316 | |||
1317 | static void ibmcam_PacketFormat2(struct uvd *uvd, unsigned char fkey, unsigned char val) | ||
1318 | { | ||
1319 | ibmcam_send_x_01_00_05 (uvd, unknown_88); | ||
1320 | ibmcam_send_x_00_05 (uvd, fkey); | ||
1321 | ibmcam_send_x_00_05_02 (uvd, val); | ||
1322 | } | ||
1323 | |||
1324 | static void ibmcam_model2_Packet2(struct uvd *uvd) | ||
1325 | { | ||
1326 | ibmcam_veio(uvd, 0, 0x00ff, 0x012d); | ||
1327 | ibmcam_veio(uvd, 0, 0xfea3, 0x0124); | ||
1328 | } | ||
1329 | |||
1330 | static void ibmcam_model2_Packet1(struct uvd *uvd, unsigned short v1, unsigned short v2) | ||
1331 | { | ||
1332 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
1333 | ibmcam_veio(uvd, 0, 0x00ff, 0x012e); | ||
1334 | ibmcam_veio(uvd, 0, v1, 0x012f); | ||
1335 | ibmcam_veio(uvd, 0, 0x00ff, 0x0130); | ||
1336 | ibmcam_veio(uvd, 0, 0xc719, 0x0124); | ||
1337 | ibmcam_veio(uvd, 0, v2, 0x0127); | ||
1338 | |||
1339 | ibmcam_model2_Packet2(uvd); | ||
1340 | } | ||
1341 | |||
1342 | /* | ||
1343 | * ibmcam_model3_Packet1() | ||
1344 | * | ||
1345 | * 00_0078_012d | ||
1346 | * 00_0097_012f | ||
1347 | * 00_d141_0124 | ||
1348 | * 00_0096_0127 | ||
1349 | * 00_fea8_0124 | ||
1350 | */ | ||
1351 | static void ibmcam_model3_Packet1(struct uvd *uvd, unsigned short v1, unsigned short v2) | ||
1352 | { | ||
1353 | ibmcam_veio(uvd, 0, 0x0078, 0x012d); | ||
1354 | ibmcam_veio(uvd, 0, v1, 0x012f); | ||
1355 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
1356 | ibmcam_veio(uvd, 0, v2, 0x0127); | ||
1357 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
1358 | } | ||
1359 | |||
1360 | static void ibmcam_model4_BrightnessPacket(struct uvd *uvd, int i) | ||
1361 | { | ||
1362 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
1363 | ibmcam_veio(uvd, 0, 0x0026, 0x012f); | ||
1364 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
1365 | ibmcam_veio(uvd, 0, i, 0x0127); | ||
1366 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
1367 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
1368 | ibmcam_veio(uvd, 0, 0x0038, 0x012d); | ||
1369 | ibmcam_veio(uvd, 0, 0x0004, 0x012f); | ||
1370 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
1371 | ibmcam_veio(uvd, 0, 0xfffa, 0x0124); | ||
1372 | } | ||
1373 | |||
1374 | /* | ||
1375 | * ibmcam_adjust_contrast() | ||
1376 | * | ||
1377 | * The contrast value changes from 0 (high contrast) to 15 (low contrast). | ||
1378 | * This is in reverse to usual order of things (such as TV controls), so | ||
1379 | * we reverse it again here. | ||
1380 | * | ||
1381 | * TODO: we probably don't need to send the setup 5 times... | ||
1382 | * | ||
1383 | * History: | ||
1384 | * 1/2/00 Created. | ||
1385 | */ | ||
1386 | static void ibmcam_adjust_contrast(struct uvd *uvd) | ||
1387 | { | ||
1388 | unsigned char a_contrast = uvd->vpic.contrast >> 12; | ||
1389 | unsigned char new_contrast; | ||
1390 | |||
1391 | if (a_contrast >= 16) | ||
1392 | a_contrast = 15; | ||
1393 | new_contrast = 15 - a_contrast; | ||
1394 | if (new_contrast == uvd->vpic_old.contrast) | ||
1395 | return; | ||
1396 | uvd->vpic_old.contrast = new_contrast; | ||
1397 | switch (IBMCAM_T(uvd)->camera_model) { | ||
1398 | case IBMCAM_MODEL_1: | ||
1399 | { | ||
1400 | const int ntries = 5; | ||
1401 | int i; | ||
1402 | for (i=0; i < ntries; i++) { | ||
1403 | ibmcam_Packet_Format1(uvd, contrast_14, new_contrast); | ||
1404 | ibmcam_send_FF_04_02(uvd); | ||
1405 | } | ||
1406 | break; | ||
1407 | } | ||
1408 | case IBMCAM_MODEL_2: | ||
1409 | case IBMCAM_MODEL_4: | ||
1410 | /* Models 2, 4 do not have this control; implemented in software. */ | ||
1411 | break; | ||
1412 | case IBMCAM_MODEL_3: | ||
1413 | { /* Preset hardware values */ | ||
1414 | static const struct { | ||
1415 | unsigned short cv1; | ||
1416 | unsigned short cv2; | ||
1417 | unsigned short cv3; | ||
1418 | } cv[7] = { | ||
1419 | { 0x05, 0x05, 0x0f }, /* Minimum */ | ||
1420 | { 0x04, 0x04, 0x16 }, | ||
1421 | { 0x02, 0x03, 0x16 }, | ||
1422 | { 0x02, 0x08, 0x16 }, | ||
1423 | { 0x01, 0x0c, 0x16 }, | ||
1424 | { 0x01, 0x0e, 0x16 }, | ||
1425 | { 0x01, 0x10, 0x16 } /* Maximum */ | ||
1426 | }; | ||
1427 | int i = a_contrast / 2; | ||
1428 | RESTRICT_TO_RANGE(i, 0, 6); | ||
1429 | ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */ | ||
1430 | ibmcam_model3_Packet1(uvd, 0x0067, cv[i].cv1); | ||
1431 | ibmcam_model3_Packet1(uvd, 0x005b, cv[i].cv2); | ||
1432 | ibmcam_model3_Packet1(uvd, 0x005c, cv[i].cv3); | ||
1433 | ibmcam_veio(uvd, 0, 0x0001, 0x0114); | ||
1434 | ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */ | ||
1435 | usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp)); | ||
1436 | break; | ||
1437 | } | ||
1438 | default: | ||
1439 | break; | ||
1440 | } | ||
1441 | } | ||
1442 | |||
1443 | /* | ||
1444 | * ibmcam_change_lighting_conditions() | ||
1445 | * | ||
1446 | * Camera model 1: | ||
1447 | * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low. | ||
1448 | * | ||
1449 | * Camera model 2: | ||
1450 | * We have 16 levels of lighting, 0 for bright light and up to 15 for | ||
1451 | * low light. But values above 5 or so are useless because camera is | ||
1452 | * not really capable to produce anything worth viewing at such light. | ||
1453 | * This setting may be altered only in certain camera state. | ||
1454 | * | ||
1455 | * Low lighting forces slower FPS. Lighting is set as a module parameter. | ||
1456 | * | ||
1457 | * History: | ||
1458 | * 1/5/00 Created. | ||
1459 | * 2/20/00 Added support for Model 2 cameras. | ||
1460 | */ | ||
1461 | static void ibmcam_change_lighting_conditions(struct uvd *uvd) | ||
1462 | { | ||
1463 | if (debug > 0) | ||
1464 | dev_info(&uvd->dev->dev, | ||
1465 | "%s: Set lighting to %hu.\n", __func__, lighting); | ||
1466 | |||
1467 | switch (IBMCAM_T(uvd)->camera_model) { | ||
1468 | case IBMCAM_MODEL_1: | ||
1469 | { | ||
1470 | const int ntries = 5; | ||
1471 | int i; | ||
1472 | for (i=0; i < ntries; i++) | ||
1473 | ibmcam_Packet_Format1(uvd, light_27, (unsigned short) lighting); | ||
1474 | break; | ||
1475 | } | ||
1476 | case IBMCAM_MODEL_2: | ||
1477 | #if 0 | ||
1478 | /* | ||
1479 | * This command apparently requires camera to be stopped. My | ||
1480 | * experiments showed that it -is- possible to alter the lighting | ||
1481 | * conditions setting "on the fly", but why bother? This setting does | ||
1482 | * not work reliably in all cases, so I decided simply to leave the | ||
1483 | * setting where Xirlink put it - in the camera setup phase. This code | ||
1484 | * is commented out because it does not work at -any- moment, so its | ||
1485 | * presence makes no sense. You may use it for experiments. | ||
1486 | */ | ||
1487 | ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop camera */ | ||
1488 | ibmcam_model2_Packet1(uvd, mod2_sensitivity, lighting); | ||
1489 | ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Start camera */ | ||
1490 | #endif | ||
1491 | break; | ||
1492 | case IBMCAM_MODEL_3: | ||
1493 | case IBMCAM_MODEL_4: | ||
1494 | default: | ||
1495 | break; | ||
1496 | } | ||
1497 | } | ||
1498 | |||
1499 | /* | ||
1500 | * ibmcam_set_sharpness() | ||
1501 | * | ||
1502 | * Cameras model 1 have internal smoothing feature. It is controlled by value in | ||
1503 | * range [0..6], where 0 is most smooth and 6 is most sharp (raw image, I guess). | ||
1504 | * Recommended value is 4. Cameras model 2 do not have this feature at all. | ||
1505 | */ | ||
1506 | static void ibmcam_set_sharpness(struct uvd *uvd) | ||
1507 | { | ||
1508 | switch (IBMCAM_T(uvd)->camera_model) { | ||
1509 | case IBMCAM_MODEL_1: | ||
1510 | { | ||
1511 | static const unsigned short sa[] = { 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a }; | ||
1512 | unsigned short i, sv; | ||
1513 | |||
1514 | RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX); | ||
1515 | if (debug > 0) | ||
1516 | dev_info(&uvd->dev->dev, "%s: Set sharpness to %hu.\n", | ||
1517 | __func__, sharpness); | ||
1518 | |||
1519 | sv = sa[sharpness - SHARPNESS_MIN]; | ||
1520 | for (i=0; i < 2; i++) { | ||
1521 | ibmcam_send_x_01_00_05 (uvd, unknown_88); | ||
1522 | ibmcam_send_x_00_05 (uvd, sharp_13); | ||
1523 | ibmcam_send_x_00_05_02 (uvd, sv); | ||
1524 | } | ||
1525 | break; | ||
1526 | } | ||
1527 | case IBMCAM_MODEL_2: | ||
1528 | case IBMCAM_MODEL_4: | ||
1529 | /* Models 2, 4 do not have this control */ | ||
1530 | break; | ||
1531 | case IBMCAM_MODEL_3: | ||
1532 | { /* | ||
1533 | * "Use a table of magic numbers. | ||
1534 | * This setting doesn't really change much. | ||
1535 | * But that's how Windows does it." | ||
1536 | */ | ||
1537 | static const struct { | ||
1538 | unsigned short sv1; | ||
1539 | unsigned short sv2; | ||
1540 | unsigned short sv3; | ||
1541 | unsigned short sv4; | ||
1542 | } sv[7] = { | ||
1543 | { 0x00, 0x00, 0x05, 0x14 }, /* Smoothest */ | ||
1544 | { 0x01, 0x04, 0x05, 0x14 }, | ||
1545 | { 0x02, 0x04, 0x05, 0x14 }, | ||
1546 | { 0x03, 0x04, 0x05, 0x14 }, | ||
1547 | { 0x03, 0x05, 0x05, 0x14 }, | ||
1548 | { 0x03, 0x06, 0x05, 0x14 }, | ||
1549 | { 0x03, 0x07, 0x05, 0x14 } /* Sharpest */ | ||
1550 | }; | ||
1551 | RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX); | ||
1552 | RESTRICT_TO_RANGE(sharpness, 0, 6); | ||
1553 | ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */ | ||
1554 | ibmcam_model3_Packet1(uvd, 0x0060, sv[sharpness].sv1); | ||
1555 | ibmcam_model3_Packet1(uvd, 0x0061, sv[sharpness].sv2); | ||
1556 | ibmcam_model3_Packet1(uvd, 0x0062, sv[sharpness].sv3); | ||
1557 | ibmcam_model3_Packet1(uvd, 0x0063, sv[sharpness].sv4); | ||
1558 | ibmcam_veio(uvd, 0, 0x0001, 0x0114); | ||
1559 | ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */ | ||
1560 | usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp)); | ||
1561 | ibmcam_veio(uvd, 0, 0x0001, 0x0113); | ||
1562 | break; | ||
1563 | } | ||
1564 | default: | ||
1565 | break; | ||
1566 | } | ||
1567 | } | ||
1568 | |||
1569 | /* | ||
1570 | * ibmcam_set_brightness() | ||
1571 | * | ||
1572 | * This procedure changes brightness of the picture. | ||
1573 | */ | ||
1574 | static void ibmcam_set_brightness(struct uvd *uvd) | ||
1575 | { | ||
1576 | static const unsigned short n = 1; | ||
1577 | |||
1578 | if (debug > 0) | ||
1579 | dev_info(&uvd->dev->dev, "%s: Set brightness to %hu.\n", | ||
1580 | __func__, uvd->vpic.brightness); | ||
1581 | |||
1582 | switch (IBMCAM_T(uvd)->camera_model) { | ||
1583 | case IBMCAM_MODEL_1: | ||
1584 | { | ||
1585 | unsigned short i, j, bv[3]; | ||
1586 | bv[0] = bv[1] = bv[2] = uvd->vpic.brightness >> 10; | ||
1587 | if (bv[0] == (uvd->vpic_old.brightness >> 10)) | ||
1588 | return; | ||
1589 | uvd->vpic_old.brightness = bv[0]; | ||
1590 | for (j=0; j < 3; j++) | ||
1591 | for (i=0; i < n; i++) | ||
1592 | ibmcam_Packet_Format1(uvd, bright_3x[j], bv[j]); | ||
1593 | break; | ||
1594 | } | ||
1595 | case IBMCAM_MODEL_2: | ||
1596 | { | ||
1597 | unsigned short i, j; | ||
1598 | i = uvd->vpic.brightness >> 12; /* 0 .. 15 */ | ||
1599 | j = 0x60 + i * ((0xee - 0x60) / 16); /* 0x60 .. 0xee or so */ | ||
1600 | if (uvd->vpic_old.brightness == j) | ||
1601 | break; | ||
1602 | uvd->vpic_old.brightness = j; | ||
1603 | ibmcam_model2_Packet1(uvd, mod2_brightness, j); | ||
1604 | break; | ||
1605 | } | ||
1606 | case IBMCAM_MODEL_3: | ||
1607 | { | ||
1608 | /* Model 3: Brightness range 'i' in [0x0C..0x3F] */ | ||
1609 | unsigned short i = | ||
1610 | 0x0C + (uvd->vpic.brightness / (0xFFFF / (0x3F - 0x0C + 1))); | ||
1611 | RESTRICT_TO_RANGE(i, 0x0C, 0x3F); | ||
1612 | if (uvd->vpic_old.brightness == i) | ||
1613 | break; | ||
1614 | uvd->vpic_old.brightness = i; | ||
1615 | ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */ | ||
1616 | ibmcam_model3_Packet1(uvd, 0x0036, i); | ||
1617 | ibmcam_veio(uvd, 0, 0x0001, 0x0114); | ||
1618 | ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */ | ||
1619 | usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp)); | ||
1620 | ibmcam_veio(uvd, 0, 0x0001, 0x0113); | ||
1621 | break; | ||
1622 | } | ||
1623 | case IBMCAM_MODEL_4: | ||
1624 | { | ||
1625 | /* Model 4: Brightness range 'i' in [0x04..0xb4] */ | ||
1626 | unsigned short i = 0x04 + (uvd->vpic.brightness / (0xFFFF / (0xb4 - 0x04 + 1))); | ||
1627 | RESTRICT_TO_RANGE(i, 0x04, 0xb4); | ||
1628 | if (uvd->vpic_old.brightness == i) | ||
1629 | break; | ||
1630 | uvd->vpic_old.brightness = i; | ||
1631 | ibmcam_model4_BrightnessPacket(uvd, i); | ||
1632 | break; | ||
1633 | } | ||
1634 | default: | ||
1635 | break; | ||
1636 | } | ||
1637 | } | ||
1638 | |||
1639 | static void ibmcam_set_hue(struct uvd *uvd) | ||
1640 | { | ||
1641 | switch (IBMCAM_T(uvd)->camera_model) { | ||
1642 | case IBMCAM_MODEL_2: | ||
1643 | { | ||
1644 | unsigned short hue = uvd->vpic.hue >> 9; /* 0 .. 7F */ | ||
1645 | if (uvd->vpic_old.hue == hue) | ||
1646 | return; | ||
1647 | uvd->vpic_old.hue = hue; | ||
1648 | ibmcam_model2_Packet1(uvd, mod2_hue, hue); | ||
1649 | /* ibmcam_model2_Packet1(uvd, mod2_saturation, sat); */ | ||
1650 | break; | ||
1651 | } | ||
1652 | case IBMCAM_MODEL_3: | ||
1653 | { | ||
1654 | #if 0 /* This seems not to work. No problem, will fix programmatically */ | ||
1655 | unsigned short hue = 0x05 + (uvd->vpic.hue / (0xFFFF / (0x37 - 0x05 + 1))); | ||
1656 | RESTRICT_TO_RANGE(hue, 0x05, 0x37); | ||
1657 | if (uvd->vpic_old.hue == hue) | ||
1658 | return; | ||
1659 | uvd->vpic_old.hue = hue; | ||
1660 | ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */ | ||
1661 | ibmcam_model3_Packet1(uvd, 0x007e, hue); | ||
1662 | ibmcam_veio(uvd, 0, 0x0001, 0x0114); | ||
1663 | ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */ | ||
1664 | usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp)); | ||
1665 | ibmcam_veio(uvd, 0, 0x0001, 0x0113); | ||
1666 | #endif | ||
1667 | break; | ||
1668 | } | ||
1669 | case IBMCAM_MODEL_4: | ||
1670 | { | ||
1671 | unsigned short r_gain, g_gain, b_gain, hue; | ||
1672 | |||
1673 | /* | ||
1674 | * I am not sure r/g/b_gain variables exactly control gain | ||
1675 | * of those channels. Most likely they subtly change some | ||
1676 | * very internal image processing settings in the camera. | ||
1677 | * In any case, here is what they do, and feel free to tweak: | ||
1678 | * | ||
1679 | * r_gain: seriously affects red gain | ||
1680 | * g_gain: seriously affects green gain | ||
1681 | * b_gain: seriously affects blue gain | ||
1682 | * hue: changes average color from violet (0) to red (0xFF) | ||
1683 | * | ||
1684 | * These settings are preset for a decent white balance in | ||
1685 | * 320x240, 352x288 modes. Low-res modes exhibit higher contrast | ||
1686 | * and therefore may need different values here. | ||
1687 | */ | ||
1688 | hue = 20 + (uvd->vpic.hue >> 9); | ||
1689 | switch (uvd->videosize) { | ||
1690 | case VIDEOSIZE_128x96: | ||
1691 | r_gain = 90; | ||
1692 | g_gain = 166; | ||
1693 | b_gain = 175; | ||
1694 | break; | ||
1695 | case VIDEOSIZE_160x120: | ||
1696 | r_gain = 70; | ||
1697 | g_gain = 166; | ||
1698 | b_gain = 185; | ||
1699 | break; | ||
1700 | case VIDEOSIZE_176x144: | ||
1701 | r_gain = 160; | ||
1702 | g_gain = 175; | ||
1703 | b_gain = 185; | ||
1704 | break; | ||
1705 | default: | ||
1706 | r_gain = 120; | ||
1707 | g_gain = 166; | ||
1708 | b_gain = 175; | ||
1709 | break; | ||
1710 | } | ||
1711 | RESTRICT_TO_RANGE(hue, 1, 0x7f); | ||
1712 | |||
1713 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
1714 | ibmcam_veio(uvd, 0, 0x001e, 0x012f); | ||
1715 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
1716 | ibmcam_veio(uvd, 0, g_gain, 0x0127); /* Green gain */ | ||
1717 | ibmcam_veio(uvd, 0, r_gain, 0x012e); /* Red gain */ | ||
1718 | ibmcam_veio(uvd, 0, b_gain, 0x0130); /* Blue gain */ | ||
1719 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
1720 | ibmcam_veio(uvd, 0, hue, 0x012d); /* Hue */ | ||
1721 | ibmcam_veio(uvd, 0, 0xf545, 0x0124); | ||
1722 | break; | ||
1723 | } | ||
1724 | default: | ||
1725 | break; | ||
1726 | } | ||
1727 | } | ||
1728 | |||
1729 | /* | ||
1730 | * ibmcam_adjust_picture() | ||
1731 | * | ||
1732 | * This procedure gets called from V4L interface to update picture settings. | ||
1733 | * Here we change brightness and contrast. | ||
1734 | */ | ||
1735 | static void ibmcam_adjust_picture(struct uvd *uvd) | ||
1736 | { | ||
1737 | ibmcam_adjust_contrast(uvd); | ||
1738 | ibmcam_set_brightness(uvd); | ||
1739 | ibmcam_set_hue(uvd); | ||
1740 | } | ||
1741 | |||
1742 | static int ibmcam_model1_setup(struct uvd *uvd) | ||
1743 | { | ||
1744 | const int ntries = 5; | ||
1745 | int i; | ||
1746 | |||
1747 | ibmcam_veio(uvd, 1, 0x00, 0x0128); | ||
1748 | ibmcam_veio(uvd, 1, 0x00, 0x0100); | ||
1749 | ibmcam_veio(uvd, 0, 0x01, 0x0100); /* LED On */ | ||
1750 | ibmcam_veio(uvd, 1, 0x00, 0x0100); | ||
1751 | ibmcam_veio(uvd, 0, 0x81, 0x0100); /* LED Off */ | ||
1752 | ibmcam_veio(uvd, 1, 0x00, 0x0100); | ||
1753 | ibmcam_veio(uvd, 0, 0x01, 0x0100); /* LED On */ | ||
1754 | ibmcam_veio(uvd, 0, 0x01, 0x0108); | ||
1755 | |||
1756 | ibmcam_veio(uvd, 0, 0x03, 0x0112); | ||
1757 | ibmcam_veio(uvd, 1, 0x00, 0x0115); | ||
1758 | ibmcam_veio(uvd, 0, 0x06, 0x0115); | ||
1759 | ibmcam_veio(uvd, 1, 0x00, 0x0116); | ||
1760 | ibmcam_veio(uvd, 0, 0x44, 0x0116); | ||
1761 | ibmcam_veio(uvd, 1, 0x00, 0x0116); | ||
1762 | ibmcam_veio(uvd, 0, 0x40, 0x0116); | ||
1763 | ibmcam_veio(uvd, 1, 0x00, 0x0115); | ||
1764 | ibmcam_veio(uvd, 0, 0x0e, 0x0115); | ||
1765 | ibmcam_veio(uvd, 0, 0x19, 0x012c); | ||
1766 | |||
1767 | ibmcam_Packet_Format1(uvd, 0x00, 0x1e); | ||
1768 | ibmcam_Packet_Format1(uvd, 0x39, 0x0d); | ||
1769 | ibmcam_Packet_Format1(uvd, 0x39, 0x09); | ||
1770 | ibmcam_Packet_Format1(uvd, 0x3b, 0x00); | ||
1771 | ibmcam_Packet_Format1(uvd, 0x28, 0x22); | ||
1772 | ibmcam_Packet_Format1(uvd, light_27, 0); | ||
1773 | ibmcam_Packet_Format1(uvd, 0x2b, 0x1f); | ||
1774 | ibmcam_Packet_Format1(uvd, 0x39, 0x08); | ||
1775 | |||
1776 | for (i=0; i < ntries; i++) | ||
1777 | ibmcam_Packet_Format1(uvd, 0x2c, 0x00); | ||
1778 | |||
1779 | for (i=0; i < ntries; i++) | ||
1780 | ibmcam_Packet_Format1(uvd, 0x30, 0x14); | ||
1781 | |||
1782 | ibmcam_PacketFormat2(uvd, 0x39, 0x02); | ||
1783 | ibmcam_PacketFormat2(uvd, 0x01, 0xe1); | ||
1784 | ibmcam_PacketFormat2(uvd, 0x02, 0xcd); | ||
1785 | ibmcam_PacketFormat2(uvd, 0x03, 0xcd); | ||
1786 | ibmcam_PacketFormat2(uvd, 0x04, 0xfa); | ||
1787 | ibmcam_PacketFormat2(uvd, 0x3f, 0xff); | ||
1788 | ibmcam_PacketFormat2(uvd, 0x39, 0x00); | ||
1789 | |||
1790 | ibmcam_PacketFormat2(uvd, 0x39, 0x02); | ||
1791 | ibmcam_PacketFormat2(uvd, 0x0a, 0x37); | ||
1792 | ibmcam_PacketFormat2(uvd, 0x0b, 0xb8); | ||
1793 | ibmcam_PacketFormat2(uvd, 0x0c, 0xf3); | ||
1794 | ibmcam_PacketFormat2(uvd, 0x0d, 0xe3); | ||
1795 | ibmcam_PacketFormat2(uvd, 0x0e, 0x0d); | ||
1796 | ibmcam_PacketFormat2(uvd, 0x0f, 0xf2); | ||
1797 | ibmcam_PacketFormat2(uvd, 0x10, 0xd5); | ||
1798 | ibmcam_PacketFormat2(uvd, 0x11, 0xba); | ||
1799 | ibmcam_PacketFormat2(uvd, 0x12, 0x53); | ||
1800 | ibmcam_PacketFormat2(uvd, 0x3f, 0xff); | ||
1801 | ibmcam_PacketFormat2(uvd, 0x39, 0x00); | ||
1802 | |||
1803 | ibmcam_PacketFormat2(uvd, 0x39, 0x02); | ||
1804 | ibmcam_PacketFormat2(uvd, 0x16, 0x00); | ||
1805 | ibmcam_PacketFormat2(uvd, 0x17, 0x28); | ||
1806 | ibmcam_PacketFormat2(uvd, 0x18, 0x7d); | ||
1807 | ibmcam_PacketFormat2(uvd, 0x19, 0xbe); | ||
1808 | ibmcam_PacketFormat2(uvd, 0x3f, 0xff); | ||
1809 | ibmcam_PacketFormat2(uvd, 0x39, 0x00); | ||
1810 | |||
1811 | for (i=0; i < ntries; i++) | ||
1812 | ibmcam_Packet_Format1(uvd, 0x00, 0x18); | ||
1813 | for (i=0; i < ntries; i++) | ||
1814 | ibmcam_Packet_Format1(uvd, 0x13, 0x18); | ||
1815 | for (i=0; i < ntries; i++) | ||
1816 | ibmcam_Packet_Format1(uvd, 0x14, 0x06); | ||
1817 | |||
1818 | /* This is default brightness */ | ||
1819 | for (i=0; i < ntries; i++) | ||
1820 | ibmcam_Packet_Format1(uvd, 0x31, 0x37); | ||
1821 | for (i=0; i < ntries; i++) | ||
1822 | ibmcam_Packet_Format1(uvd, 0x32, 0x46); | ||
1823 | for (i=0; i < ntries; i++) | ||
1824 | ibmcam_Packet_Format1(uvd, 0x33, 0x55); | ||
1825 | |||
1826 | ibmcam_Packet_Format1(uvd, 0x2e, 0x04); | ||
1827 | for (i=0; i < ntries; i++) | ||
1828 | ibmcam_Packet_Format1(uvd, 0x2d, 0x04); | ||
1829 | for (i=0; i < ntries; i++) | ||
1830 | ibmcam_Packet_Format1(uvd, 0x29, 0x80); | ||
1831 | ibmcam_Packet_Format1(uvd, 0x2c, 0x01); | ||
1832 | ibmcam_Packet_Format1(uvd, 0x30, 0x17); | ||
1833 | ibmcam_Packet_Format1(uvd, 0x39, 0x08); | ||
1834 | for (i=0; i < ntries; i++) | ||
1835 | ibmcam_Packet_Format1(uvd, 0x34, 0x00); | ||
1836 | |||
1837 | ibmcam_veio(uvd, 0, 0x00, 0x0101); | ||
1838 | ibmcam_veio(uvd, 0, 0x00, 0x010a); | ||
1839 | |||
1840 | switch (uvd->videosize) { | ||
1841 | case VIDEOSIZE_128x96: | ||
1842 | ibmcam_veio(uvd, 0, 0x80, 0x0103); | ||
1843 | ibmcam_veio(uvd, 0, 0x60, 0x0105); | ||
1844 | ibmcam_veio(uvd, 0, 0x0c, 0x010b); | ||
1845 | ibmcam_veio(uvd, 0, 0x04, 0x011b); /* Same everywhere */ | ||
1846 | ibmcam_veio(uvd, 0, 0x0b, 0x011d); | ||
1847 | ibmcam_veio(uvd, 0, 0x00, 0x011e); /* Same everywhere */ | ||
1848 | ibmcam_veio(uvd, 0, 0x00, 0x0129); | ||
1849 | break; | ||
1850 | case VIDEOSIZE_176x144: | ||
1851 | ibmcam_veio(uvd, 0, 0xb0, 0x0103); | ||
1852 | ibmcam_veio(uvd, 0, 0x8f, 0x0105); | ||
1853 | ibmcam_veio(uvd, 0, 0x06, 0x010b); | ||
1854 | ibmcam_veio(uvd, 0, 0x04, 0x011b); /* Same everywhere */ | ||
1855 | ibmcam_veio(uvd, 0, 0x0d, 0x011d); | ||
1856 | ibmcam_veio(uvd, 0, 0x00, 0x011e); /* Same everywhere */ | ||
1857 | ibmcam_veio(uvd, 0, 0x03, 0x0129); | ||
1858 | break; | ||
1859 | case VIDEOSIZE_352x288: | ||
1860 | ibmcam_veio(uvd, 0, 0xb0, 0x0103); | ||
1861 | ibmcam_veio(uvd, 0, 0x90, 0x0105); | ||
1862 | ibmcam_veio(uvd, 0, 0x02, 0x010b); | ||
1863 | ibmcam_veio(uvd, 0, 0x04, 0x011b); /* Same everywhere */ | ||
1864 | ibmcam_veio(uvd, 0, 0x05, 0x011d); | ||
1865 | ibmcam_veio(uvd, 0, 0x00, 0x011e); /* Same everywhere */ | ||
1866 | ibmcam_veio(uvd, 0, 0x00, 0x0129); | ||
1867 | break; | ||
1868 | } | ||
1869 | |||
1870 | ibmcam_veio(uvd, 0, 0xff, 0x012b); | ||
1871 | |||
1872 | /* This is another brightness - don't know why */ | ||
1873 | for (i=0; i < ntries; i++) | ||
1874 | ibmcam_Packet_Format1(uvd, 0x31, 0xc3); | ||
1875 | for (i=0; i < ntries; i++) | ||
1876 | ibmcam_Packet_Format1(uvd, 0x32, 0xd2); | ||
1877 | for (i=0; i < ntries; i++) | ||
1878 | ibmcam_Packet_Format1(uvd, 0x33, 0xe1); | ||
1879 | |||
1880 | /* Default contrast */ | ||
1881 | for (i=0; i < ntries; i++) | ||
1882 | ibmcam_Packet_Format1(uvd, contrast_14, 0x0a); | ||
1883 | |||
1884 | /* Default sharpness */ | ||
1885 | for (i=0; i < 2; i++) | ||
1886 | ibmcam_PacketFormat2(uvd, sharp_13, 0x1a); /* Level 4 FIXME */ | ||
1887 | |||
1888 | /* Default lighting conditions */ | ||
1889 | ibmcam_Packet_Format1(uvd, light_27, lighting); /* 0=Bright 2=Low */ | ||
1890 | |||
1891 | /* Assorted init */ | ||
1892 | |||
1893 | switch (uvd->videosize) { | ||
1894 | case VIDEOSIZE_128x96: | ||
1895 | ibmcam_Packet_Format1(uvd, 0x2b, 0x1e); | ||
1896 | ibmcam_veio(uvd, 0, 0xc9, 0x0119); /* Same everywhere */ | ||
1897 | ibmcam_veio(uvd, 0, 0x80, 0x0109); /* Same everywhere */ | ||
1898 | ibmcam_veio(uvd, 0, 0x36, 0x0102); | ||
1899 | ibmcam_veio(uvd, 0, 0x1a, 0x0104); | ||
1900 | ibmcam_veio(uvd, 0, 0x04, 0x011a); /* Same everywhere */ | ||
1901 | ibmcam_veio(uvd, 0, 0x2b, 0x011c); | ||
1902 | ibmcam_veio(uvd, 0, 0x23, 0x012a); /* Same everywhere */ | ||
1903 | #if 0 | ||
1904 | ibmcam_veio(uvd, 0, 0x00, 0x0106); | ||
1905 | ibmcam_veio(uvd, 0, 0x38, 0x0107); | ||
1906 | #else | ||
1907 | ibmcam_veio(uvd, 0, 0x02, 0x0106); | ||
1908 | ibmcam_veio(uvd, 0, 0x2a, 0x0107); | ||
1909 | #endif | ||
1910 | break; | ||
1911 | case VIDEOSIZE_176x144: | ||
1912 | ibmcam_Packet_Format1(uvd, 0x2b, 0x1e); | ||
1913 | ibmcam_veio(uvd, 0, 0xc9, 0x0119); /* Same everywhere */ | ||
1914 | ibmcam_veio(uvd, 0, 0x80, 0x0109); /* Same everywhere */ | ||
1915 | ibmcam_veio(uvd, 0, 0x04, 0x0102); | ||
1916 | ibmcam_veio(uvd, 0, 0x02, 0x0104); | ||
1917 | ibmcam_veio(uvd, 0, 0x04, 0x011a); /* Same everywhere */ | ||
1918 | ibmcam_veio(uvd, 0, 0x2b, 0x011c); | ||
1919 | ibmcam_veio(uvd, 0, 0x23, 0x012a); /* Same everywhere */ | ||
1920 | ibmcam_veio(uvd, 0, 0x01, 0x0106); | ||
1921 | ibmcam_veio(uvd, 0, 0xca, 0x0107); | ||
1922 | break; | ||
1923 | case VIDEOSIZE_352x288: | ||
1924 | ibmcam_Packet_Format1(uvd, 0x2b, 0x1f); | ||
1925 | ibmcam_veio(uvd, 0, 0xc9, 0x0119); /* Same everywhere */ | ||
1926 | ibmcam_veio(uvd, 0, 0x80, 0x0109); /* Same everywhere */ | ||
1927 | ibmcam_veio(uvd, 0, 0x08, 0x0102); | ||
1928 | ibmcam_veio(uvd, 0, 0x01, 0x0104); | ||
1929 | ibmcam_veio(uvd, 0, 0x04, 0x011a); /* Same everywhere */ | ||
1930 | ibmcam_veio(uvd, 0, 0x2f, 0x011c); | ||
1931 | ibmcam_veio(uvd, 0, 0x23, 0x012a); /* Same everywhere */ | ||
1932 | ibmcam_veio(uvd, 0, 0x03, 0x0106); | ||
1933 | ibmcam_veio(uvd, 0, 0xf6, 0x0107); | ||
1934 | break; | ||
1935 | } | ||
1936 | return (CAMERA_IS_OPERATIONAL(uvd) ? 0 : -EFAULT); | ||
1937 | } | ||
1938 | |||
1939 | static int ibmcam_model2_setup(struct uvd *uvd) | ||
1940 | { | ||
1941 | ibmcam_veio(uvd, 0, 0x0000, 0x0100); /* LED on */ | ||
1942 | ibmcam_veio(uvd, 1, 0x0000, 0x0116); | ||
1943 | ibmcam_veio(uvd, 0, 0x0060, 0x0116); | ||
1944 | ibmcam_veio(uvd, 0, 0x0002, 0x0112); | ||
1945 | ibmcam_veio(uvd, 0, 0x00bc, 0x012c); | ||
1946 | ibmcam_veio(uvd, 0, 0x0008, 0x012b); | ||
1947 | ibmcam_veio(uvd, 0, 0x0000, 0x0108); | ||
1948 | ibmcam_veio(uvd, 0, 0x0001, 0x0133); | ||
1949 | ibmcam_veio(uvd, 0, 0x0001, 0x0102); | ||
1950 | switch (uvd->videosize) { | ||
1951 | case VIDEOSIZE_176x144: | ||
1952 | ibmcam_veio(uvd, 0, 0x002c, 0x0103); /* All except 320x240 */ | ||
1953 | ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */ | ||
1954 | ibmcam_veio(uvd, 0, 0x0024, 0x0105); /* 176x144, 352x288 */ | ||
1955 | ibmcam_veio(uvd, 0, 0x00b9, 0x010a); /* Unique to this mode */ | ||
1956 | ibmcam_veio(uvd, 0, 0x0038, 0x0119); /* Unique to this mode */ | ||
1957 | ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */ | ||
1958 | ibmcam_veio(uvd, 0, 0x0090, 0x0107); /* Unique to every mode*/ | ||
1959 | break; | ||
1960 | case VIDEOSIZE_320x240: | ||
1961 | ibmcam_veio(uvd, 0, 0x0028, 0x0103); /* Unique to this mode */ | ||
1962 | ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */ | ||
1963 | ibmcam_veio(uvd, 0, 0x001e, 0x0105); /* 320x240, 352x240 */ | ||
1964 | ibmcam_veio(uvd, 0, 0x0039, 0x010a); /* All except 176x144 */ | ||
1965 | ibmcam_veio(uvd, 0, 0x0070, 0x0119); /* All except 176x144 */ | ||
1966 | ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */ | ||
1967 | ibmcam_veio(uvd, 0, 0x0098, 0x0107); /* Unique to every mode*/ | ||
1968 | break; | ||
1969 | case VIDEOSIZE_352x240: | ||
1970 | ibmcam_veio(uvd, 0, 0x002c, 0x0103); /* All except 320x240 */ | ||
1971 | ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */ | ||
1972 | ibmcam_veio(uvd, 0, 0x001e, 0x0105); /* 320x240, 352x240 */ | ||
1973 | ibmcam_veio(uvd, 0, 0x0039, 0x010a); /* All except 176x144 */ | ||
1974 | ibmcam_veio(uvd, 0, 0x0070, 0x0119); /* All except 176x144 */ | ||
1975 | ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */ | ||
1976 | ibmcam_veio(uvd, 0, 0x00da, 0x0107); /* Unique to every mode*/ | ||
1977 | break; | ||
1978 | case VIDEOSIZE_352x288: | ||
1979 | ibmcam_veio(uvd, 0, 0x002c, 0x0103); /* All except 320x240 */ | ||
1980 | ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */ | ||
1981 | ibmcam_veio(uvd, 0, 0x0024, 0x0105); /* 176x144, 352x288 */ | ||
1982 | ibmcam_veio(uvd, 0, 0x0039, 0x010a); /* All except 176x144 */ | ||
1983 | ibmcam_veio(uvd, 0, 0x0070, 0x0119); /* All except 176x144 */ | ||
1984 | ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */ | ||
1985 | ibmcam_veio(uvd, 0, 0x00fe, 0x0107); /* Unique to every mode*/ | ||
1986 | break; | ||
1987 | } | ||
1988 | return (CAMERA_IS_OPERATIONAL(uvd) ? 0 : -EFAULT); | ||
1989 | } | ||
1990 | |||
1991 | /* | ||
1992 | * ibmcam_model1_setup_after_video_if() | ||
1993 | * | ||
1994 | * This code adds finishing touches to the video data interface. | ||
1995 | * Here we configure the frame rate and turn on the LED. | ||
1996 | */ | ||
1997 | static void ibmcam_model1_setup_after_video_if(struct uvd *uvd) | ||
1998 | { | ||
1999 | unsigned short internal_frame_rate; | ||
2000 | |||
2001 | RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX); | ||
2002 | internal_frame_rate = FRAMERATE_MAX - framerate; /* 0=Fast 6=Slow */ | ||
2003 | ibmcam_veio(uvd, 0, 0x01, 0x0100); /* LED On */ | ||
2004 | ibmcam_veio(uvd, 0, internal_frame_rate, 0x0111); | ||
2005 | ibmcam_veio(uvd, 0, 0x01, 0x0114); | ||
2006 | ibmcam_veio(uvd, 0, 0xc0, 0x010c); | ||
2007 | } | ||
2008 | |||
2009 | static void ibmcam_model2_setup_after_video_if(struct uvd *uvd) | ||
2010 | { | ||
2011 | unsigned short setup_model2_rg2, setup_model2_sat, setup_model2_yb; | ||
2012 | |||
2013 | ibmcam_veio(uvd, 0, 0x0000, 0x0100); /* LED on */ | ||
2014 | |||
2015 | switch (uvd->videosize) { | ||
2016 | case VIDEOSIZE_176x144: | ||
2017 | ibmcam_veio(uvd, 0, 0x0050, 0x0111); | ||
2018 | ibmcam_veio(uvd, 0, 0x00d0, 0x0111); | ||
2019 | break; | ||
2020 | case VIDEOSIZE_320x240: | ||
2021 | case VIDEOSIZE_352x240: | ||
2022 | case VIDEOSIZE_352x288: | ||
2023 | ibmcam_veio(uvd, 0, 0x0040, 0x0111); | ||
2024 | ibmcam_veio(uvd, 0, 0x00c0, 0x0111); | ||
2025 | break; | ||
2026 | } | ||
2027 | ibmcam_veio(uvd, 0, 0x009b, 0x010f); | ||
2028 | ibmcam_veio(uvd, 0, 0x00bb, 0x010f); | ||
2029 | |||
2030 | /* | ||
2031 | * Hardware settings, may affect CMOS sensor; not user controls! | ||
2032 | * ------------------------------------------------------------- | ||
2033 | * 0x0004: no effect | ||
2034 | * 0x0006: hardware effect | ||
2035 | * 0x0008: no effect | ||
2036 | * 0x000a: stops video stream, probably important h/w setting | ||
2037 | * 0x000c: changes color in hardware manner (not user setting) | ||
2038 | * 0x0012: changes number of colors (does not affect speed) | ||
2039 | * 0x002a: no effect | ||
2040 | * 0x002c: hardware setting (related to scan lines) | ||
2041 | * 0x002e: stops video stream, probably important h/w setting | ||
2042 | */ | ||
2043 | ibmcam_model2_Packet1(uvd, 0x000a, 0x005c); | ||
2044 | ibmcam_model2_Packet1(uvd, 0x0004, 0x0000); | ||
2045 | ibmcam_model2_Packet1(uvd, 0x0006, 0x00fb); | ||
2046 | ibmcam_model2_Packet1(uvd, 0x0008, 0x0000); | ||
2047 | ibmcam_model2_Packet1(uvd, 0x000c, 0x0009); | ||
2048 | ibmcam_model2_Packet1(uvd, 0x0012, 0x000a); | ||
2049 | ibmcam_model2_Packet1(uvd, 0x002a, 0x0000); | ||
2050 | ibmcam_model2_Packet1(uvd, 0x002c, 0x0000); | ||
2051 | ibmcam_model2_Packet1(uvd, 0x002e, 0x0008); | ||
2052 | |||
2053 | /* | ||
2054 | * Function 0x0030 pops up all over the place. Apparently | ||
2055 | * it is a hardware control register, with every bit assigned to | ||
2056 | * do something. | ||
2057 | */ | ||
2058 | ibmcam_model2_Packet1(uvd, 0x0030, 0x0000); | ||
2059 | |||
2060 | /* | ||
2061 | * Magic control of CMOS sensor. Only lower values like | ||
2062 | * 0-3 work, and picture shifts left or right. Don't change. | ||
2063 | */ | ||
2064 | switch (uvd->videosize) { | ||
2065 | case VIDEOSIZE_176x144: | ||
2066 | ibmcam_model2_Packet1(uvd, 0x0014, 0x0002); | ||
2067 | ibmcam_model2_Packet1(uvd, 0x0016, 0x0002); /* Horizontal shift */ | ||
2068 | ibmcam_model2_Packet1(uvd, 0x0018, 0x004a); /* Another hardware setting */ | ||
2069 | break; | ||
2070 | case VIDEOSIZE_320x240: | ||
2071 | ibmcam_model2_Packet1(uvd, 0x0014, 0x0009); | ||
2072 | ibmcam_model2_Packet1(uvd, 0x0016, 0x0005); /* Horizontal shift */ | ||
2073 | ibmcam_model2_Packet1(uvd, 0x0018, 0x0044); /* Another hardware setting */ | ||
2074 | break; | ||
2075 | case VIDEOSIZE_352x240: | ||
2076 | /* This mode doesn't work as Windows programs it; changed to work */ | ||
2077 | ibmcam_model2_Packet1(uvd, 0x0014, 0x0009); /* Windows sets this to 8 */ | ||
2078 | ibmcam_model2_Packet1(uvd, 0x0016, 0x0003); /* Horizontal shift */ | ||
2079 | ibmcam_model2_Packet1(uvd, 0x0018, 0x0044); /* Windows sets this to 0x0045 */ | ||
2080 | break; | ||
2081 | case VIDEOSIZE_352x288: | ||
2082 | ibmcam_model2_Packet1(uvd, 0x0014, 0x0003); | ||
2083 | ibmcam_model2_Packet1(uvd, 0x0016, 0x0002); /* Horizontal shift */ | ||
2084 | ibmcam_model2_Packet1(uvd, 0x0018, 0x004a); /* Another hardware setting */ | ||
2085 | break; | ||
2086 | } | ||
2087 | |||
2088 | ibmcam_model2_Packet1(uvd, mod2_brightness, 0x005a); | ||
2089 | |||
2090 | /* | ||
2091 | * We have our own frame rate setting varying from 0 (slowest) to 6 (fastest). | ||
2092 | * The camera model 2 allows frame rate in range [0..0x1F] where 0 is also the | ||
2093 | * slowest setting. However for all practical reasons high settings make no | ||
2094 | * sense because USB is not fast enough to support high FPS. Be aware that | ||
2095 | * the picture datastream will be severely disrupted if you ask for | ||
2096 | * frame rate faster than allowed for the video size - see below: | ||
2097 | * | ||
2098 | * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz): | ||
2099 | * ----------------------------------------------------------------- | ||
2100 | * 176x144: [6..31] | ||
2101 | * 320x240: [8..31] | ||
2102 | * 352x240: [10..31] | ||
2103 | * 352x288: [16..31] I have to raise lower threshold for stability... | ||
2104 | * | ||
2105 | * As usual, slower FPS provides better sensitivity. | ||
2106 | */ | ||
2107 | { | ||
2108 | short hw_fps=31, i_framerate; | ||
2109 | |||
2110 | RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX); | ||
2111 | i_framerate = FRAMERATE_MAX - framerate + FRAMERATE_MIN; | ||
2112 | switch (uvd->videosize) { | ||
2113 | case VIDEOSIZE_176x144: | ||
2114 | hw_fps = 6 + i_framerate*4; | ||
2115 | break; | ||
2116 | case VIDEOSIZE_320x240: | ||
2117 | hw_fps = 8 + i_framerate*3; | ||
2118 | break; | ||
2119 | case VIDEOSIZE_352x240: | ||
2120 | hw_fps = 10 + i_framerate*2; | ||
2121 | break; | ||
2122 | case VIDEOSIZE_352x288: | ||
2123 | hw_fps = 28 + i_framerate/2; | ||
2124 | break; | ||
2125 | } | ||
2126 | if (uvd->debug > 0) | ||
2127 | dev_info(&uvd->dev->dev, "Framerate (hardware): %hd.\n", | ||
2128 | hw_fps); | ||
2129 | RESTRICT_TO_RANGE(hw_fps, 0, 31); | ||
2130 | ibmcam_model2_Packet1(uvd, mod2_set_framerate, hw_fps); | ||
2131 | } | ||
2132 | |||
2133 | /* | ||
2134 | * This setting does not visibly affect pictures; left it here | ||
2135 | * because it was present in Windows USB data stream. This function | ||
2136 | * does not allow arbitrary values and apparently is a bit mask, to | ||
2137 | * be activated only at appropriate time. Don't change it randomly! | ||
2138 | */ | ||
2139 | switch (uvd->videosize) { | ||
2140 | case VIDEOSIZE_176x144: | ||
2141 | ibmcam_model2_Packet1(uvd, 0x0026, 0x00c2); | ||
2142 | break; | ||
2143 | case VIDEOSIZE_320x240: | ||
2144 | ibmcam_model2_Packet1(uvd, 0x0026, 0x0044); | ||
2145 | break; | ||
2146 | case VIDEOSIZE_352x240: | ||
2147 | ibmcam_model2_Packet1(uvd, 0x0026, 0x0046); | ||
2148 | break; | ||
2149 | case VIDEOSIZE_352x288: | ||
2150 | ibmcam_model2_Packet1(uvd, 0x0026, 0x0048); | ||
2151 | break; | ||
2152 | } | ||
2153 | |||
2154 | ibmcam_model2_Packet1(uvd, mod2_sensitivity, lighting); | ||
2155 | |||
2156 | if (init_model2_rg2 >= 0) { | ||
2157 | RESTRICT_TO_RANGE(init_model2_rg2, 0, 255); | ||
2158 | setup_model2_rg2 = init_model2_rg2; | ||
2159 | } else | ||
2160 | setup_model2_rg2 = 0x002f; | ||
2161 | |||
2162 | if (init_model2_sat >= 0) { | ||
2163 | RESTRICT_TO_RANGE(init_model2_sat, 0, 255); | ||
2164 | setup_model2_sat = init_model2_sat; | ||
2165 | } else | ||
2166 | setup_model2_sat = 0x0034; | ||
2167 | |||
2168 | if (init_model2_yb >= 0) { | ||
2169 | RESTRICT_TO_RANGE(init_model2_yb, 0, 255); | ||
2170 | setup_model2_yb = init_model2_yb; | ||
2171 | } else | ||
2172 | setup_model2_yb = 0x00a0; | ||
2173 | |||
2174 | ibmcam_model2_Packet1(uvd, mod2_color_balance_rg2, setup_model2_rg2); | ||
2175 | ibmcam_model2_Packet1(uvd, mod2_saturation, setup_model2_sat); | ||
2176 | ibmcam_model2_Packet1(uvd, mod2_color_balance_yb, setup_model2_yb); | ||
2177 | ibmcam_model2_Packet1(uvd, mod2_hue, uvd->vpic.hue >> 9); /* 0 .. 7F */; | ||
2178 | |||
2179 | /* Hardware control command */ | ||
2180 | ibmcam_model2_Packet1(uvd, 0x0030, 0x0004); | ||
2181 | |||
2182 | ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go camera, go! */ | ||
2183 | usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp)); | ||
2184 | } | ||
2185 | |||
2186 | static void ibmcam_model4_setup_after_video_if(struct uvd *uvd) | ||
2187 | { | ||
2188 | switch (uvd->videosize) { | ||
2189 | case VIDEOSIZE_128x96: | ||
2190 | ibmcam_veio(uvd, 0, 0x0000, 0x0100); | ||
2191 | ibmcam_veio(uvd, 0, 0x00c0, 0x0111); | ||
2192 | ibmcam_veio(uvd, 0, 0x00bc, 0x012c); | ||
2193 | ibmcam_veio(uvd, 0, 0x0080, 0x012b); | ||
2194 | ibmcam_veio(uvd, 0, 0x0000, 0x0108); | ||
2195 | ibmcam_veio(uvd, 0, 0x0001, 0x0133); | ||
2196 | ibmcam_veio(uvd, 0, 0x009b, 0x010f); | ||
2197 | ibmcam_veio(uvd, 0, 0x00bb, 0x010f); | ||
2198 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2199 | ibmcam_veio(uvd, 0, 0x0038, 0x012f); | ||
2200 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2201 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2202 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2203 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2204 | ibmcam_veio(uvd, 0, 0x000a, 0x012f); | ||
2205 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2206 | ibmcam_veio(uvd, 0, 0x005c, 0x0127); | ||
2207 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2208 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2209 | ibmcam_veio(uvd, 0, 0x0004, 0x012f); | ||
2210 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2211 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2212 | ibmcam_veio(uvd, 0, 0x00fb, 0x012e); | ||
2213 | ibmcam_veio(uvd, 0, 0x0000, 0x0130); | ||
2214 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2215 | ibmcam_veio(uvd, 0, 0x00aa, 0x012f); | ||
2216 | ibmcam_veio(uvd, 0, 0xd055, 0x0124); | ||
2217 | ibmcam_veio(uvd, 0, 0x000c, 0x0127); | ||
2218 | ibmcam_veio(uvd, 0, 0x0009, 0x012e); | ||
2219 | ibmcam_veio(uvd, 0, 0xaa28, 0x0124); | ||
2220 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2221 | ibmcam_veio(uvd, 0, 0x0012, 0x012f); | ||
2222 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2223 | ibmcam_veio(uvd, 0, 0x0008, 0x0127); | ||
2224 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2225 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2226 | ibmcam_veio(uvd, 0, 0x002a, 0x012d); | ||
2227 | ibmcam_veio(uvd, 0, 0x0000, 0x012f); | ||
2228 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2229 | ibmcam_veio(uvd, 0, 0xfffa, 0x0124); | ||
2230 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2231 | ibmcam_veio(uvd, 0, 0x0034, 0x012f); | ||
2232 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2233 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2234 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2235 | ibmcam_veio(uvd, 0, 0x0070, 0x0119); | ||
2236 | ibmcam_veio(uvd, 0, 0x00d2, 0x0107); | ||
2237 | ibmcam_veio(uvd, 0, 0x0003, 0x0106); | ||
2238 | ibmcam_veio(uvd, 0, 0x005e, 0x0107); | ||
2239 | ibmcam_veio(uvd, 0, 0x0003, 0x0106); | ||
2240 | ibmcam_veio(uvd, 0, 0x00d0, 0x0111); | ||
2241 | ibmcam_veio(uvd, 0, 0x0039, 0x010a); | ||
2242 | ibmcam_veio(uvd, 0, 0x0001, 0x0102); | ||
2243 | ibmcam_veio(uvd, 0, 0x0028, 0x0103); | ||
2244 | ibmcam_veio(uvd, 0, 0x0000, 0x0104); | ||
2245 | ibmcam_veio(uvd, 0, 0x001e, 0x0105); | ||
2246 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2247 | ibmcam_veio(uvd, 0, 0x0016, 0x012f); | ||
2248 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2249 | ibmcam_veio(uvd, 0, 0x000a, 0x0127); | ||
2250 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2251 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2252 | ibmcam_veio(uvd, 0, 0x0014, 0x012d); | ||
2253 | ibmcam_veio(uvd, 0, 0x0008, 0x012f); | ||
2254 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2255 | ibmcam_veio(uvd, 0, 0x00aa, 0x012e); | ||
2256 | ibmcam_veio(uvd, 0, 0x001a, 0x0130); | ||
2257 | ibmcam_veio(uvd, 0, 0x8a0a, 0x0124); | ||
2258 | ibmcam_veio(uvd, 0, 0x005a, 0x012d); | ||
2259 | ibmcam_veio(uvd, 0, 0x9545, 0x0124); | ||
2260 | ibmcam_veio(uvd, 0, 0x00aa, 0x0127); | ||
2261 | ibmcam_veio(uvd, 0, 0x0018, 0x012e); | ||
2262 | ibmcam_veio(uvd, 0, 0x0043, 0x0130); | ||
2263 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2264 | ibmcam_veio(uvd, 0, 0x00aa, 0x012f); | ||
2265 | ibmcam_veio(uvd, 0, 0xd055, 0x0124); | ||
2266 | ibmcam_veio(uvd, 0, 0x001c, 0x0127); | ||
2267 | ibmcam_veio(uvd, 0, 0x00eb, 0x012e); | ||
2268 | ibmcam_veio(uvd, 0, 0xaa28, 0x0124); | ||
2269 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2270 | ibmcam_veio(uvd, 0, 0x0032, 0x012f); | ||
2271 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2272 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2273 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2274 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2275 | ibmcam_veio(uvd, 0, 0x0036, 0x012d); | ||
2276 | ibmcam_veio(uvd, 0, 0x0008, 0x012f); | ||
2277 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2278 | ibmcam_veio(uvd, 0, 0xfffa, 0x0124); | ||
2279 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2280 | ibmcam_veio(uvd, 0, 0x001e, 0x012f); | ||
2281 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2282 | ibmcam_veio(uvd, 0, 0x0017, 0x0127); | ||
2283 | ibmcam_veio(uvd, 0, 0x0013, 0x012e); | ||
2284 | ibmcam_veio(uvd, 0, 0x0031, 0x0130); | ||
2285 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2286 | ibmcam_veio(uvd, 0, 0x0017, 0x012d); | ||
2287 | ibmcam_veio(uvd, 0, 0x0078, 0x012f); | ||
2288 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2289 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2290 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2291 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2292 | ibmcam_veio(uvd, 0, 0x0038, 0x012f); | ||
2293 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2294 | ibmcam_veio(uvd, 0, 0x0004, 0x0127); | ||
2295 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2296 | ibmcam_veio(uvd, 0, 0x00c0, 0x010c); | ||
2297 | break; | ||
2298 | case VIDEOSIZE_160x120: | ||
2299 | ibmcam_veio(uvd, 0, 0x0000, 0x0100); | ||
2300 | ibmcam_veio(uvd, 0, 0x00c0, 0x0111); | ||
2301 | ibmcam_veio(uvd, 0, 0x00bc, 0x012c); | ||
2302 | ibmcam_veio(uvd, 0, 0x0080, 0x012b); | ||
2303 | ibmcam_veio(uvd, 0, 0x0000, 0x0108); | ||
2304 | ibmcam_veio(uvd, 0, 0x0001, 0x0133); | ||
2305 | ibmcam_veio(uvd, 0, 0x009b, 0x010f); | ||
2306 | ibmcam_veio(uvd, 0, 0x00bb, 0x010f); | ||
2307 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2308 | ibmcam_veio(uvd, 0, 0x0038, 0x012f); | ||
2309 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2310 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2311 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2312 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2313 | ibmcam_veio(uvd, 0, 0x000a, 0x012f); | ||
2314 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2315 | ibmcam_veio(uvd, 0, 0x005c, 0x0127); | ||
2316 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2317 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2318 | ibmcam_veio(uvd, 0, 0x0004, 0x012f); | ||
2319 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2320 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2321 | ibmcam_veio(uvd, 0, 0x00fb, 0x012e); | ||
2322 | ibmcam_veio(uvd, 0, 0x0000, 0x0130); | ||
2323 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2324 | ibmcam_veio(uvd, 0, 0x00aa, 0x012f); | ||
2325 | ibmcam_veio(uvd, 0, 0xd055, 0x0124); | ||
2326 | ibmcam_veio(uvd, 0, 0x000c, 0x0127); | ||
2327 | ibmcam_veio(uvd, 0, 0x0009, 0x012e); | ||
2328 | ibmcam_veio(uvd, 0, 0xaa28, 0x0124); | ||
2329 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2330 | ibmcam_veio(uvd, 0, 0x0012, 0x012f); | ||
2331 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2332 | ibmcam_veio(uvd, 0, 0x0008, 0x0127); | ||
2333 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2334 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2335 | ibmcam_veio(uvd, 0, 0x002a, 0x012d); | ||
2336 | ibmcam_veio(uvd, 0, 0x0000, 0x012f); | ||
2337 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2338 | ibmcam_veio(uvd, 0, 0xfffa, 0x0124); | ||
2339 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2340 | ibmcam_veio(uvd, 0, 0x0034, 0x012f); | ||
2341 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2342 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2343 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2344 | ibmcam_veio(uvd, 0, 0x0038, 0x0119); | ||
2345 | ibmcam_veio(uvd, 0, 0x00d8, 0x0107); | ||
2346 | ibmcam_veio(uvd, 0, 0x0002, 0x0106); | ||
2347 | ibmcam_veio(uvd, 0, 0x00d0, 0x0111); | ||
2348 | ibmcam_veio(uvd, 0, 0x00b9, 0x010a); | ||
2349 | ibmcam_veio(uvd, 0, 0x0001, 0x0102); | ||
2350 | ibmcam_veio(uvd, 0, 0x0028, 0x0103); | ||
2351 | ibmcam_veio(uvd, 0, 0x0000, 0x0104); | ||
2352 | ibmcam_veio(uvd, 0, 0x001e, 0x0105); | ||
2353 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2354 | ibmcam_veio(uvd, 0, 0x0016, 0x012f); | ||
2355 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2356 | ibmcam_veio(uvd, 0, 0x000b, 0x0127); | ||
2357 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2358 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2359 | ibmcam_veio(uvd, 0, 0x0014, 0x012d); | ||
2360 | ibmcam_veio(uvd, 0, 0x0008, 0x012f); | ||
2361 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2362 | ibmcam_veio(uvd, 0, 0x00aa, 0x012e); | ||
2363 | ibmcam_veio(uvd, 0, 0x001a, 0x0130); | ||
2364 | ibmcam_veio(uvd, 0, 0x8a0a, 0x0124); | ||
2365 | ibmcam_veio(uvd, 0, 0x005a, 0x012d); | ||
2366 | ibmcam_veio(uvd, 0, 0x9545, 0x0124); | ||
2367 | ibmcam_veio(uvd, 0, 0x00aa, 0x0127); | ||
2368 | ibmcam_veio(uvd, 0, 0x0018, 0x012e); | ||
2369 | ibmcam_veio(uvd, 0, 0x0043, 0x0130); | ||
2370 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2371 | ibmcam_veio(uvd, 0, 0x00aa, 0x012f); | ||
2372 | ibmcam_veio(uvd, 0, 0xd055, 0x0124); | ||
2373 | ibmcam_veio(uvd, 0, 0x001c, 0x0127); | ||
2374 | ibmcam_veio(uvd, 0, 0x00c7, 0x012e); | ||
2375 | ibmcam_veio(uvd, 0, 0xaa28, 0x0124); | ||
2376 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2377 | ibmcam_veio(uvd, 0, 0x0032, 0x012f); | ||
2378 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2379 | ibmcam_veio(uvd, 0, 0x0025, 0x0127); | ||
2380 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2381 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2382 | ibmcam_veio(uvd, 0, 0x0036, 0x012d); | ||
2383 | ibmcam_veio(uvd, 0, 0x0008, 0x012f); | ||
2384 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2385 | ibmcam_veio(uvd, 0, 0xfffa, 0x0124); | ||
2386 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2387 | ibmcam_veio(uvd, 0, 0x001e, 0x012f); | ||
2388 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2389 | ibmcam_veio(uvd, 0, 0x0048, 0x0127); | ||
2390 | ibmcam_veio(uvd, 0, 0x0035, 0x012e); | ||
2391 | ibmcam_veio(uvd, 0, 0x00d0, 0x0130); | ||
2392 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2393 | ibmcam_veio(uvd, 0, 0x0048, 0x012d); | ||
2394 | ibmcam_veio(uvd, 0, 0x0090, 0x012f); | ||
2395 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2396 | ibmcam_veio(uvd, 0, 0x0001, 0x0127); | ||
2397 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2398 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2399 | ibmcam_veio(uvd, 0, 0x0038, 0x012f); | ||
2400 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2401 | ibmcam_veio(uvd, 0, 0x0004, 0x0127); | ||
2402 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2403 | ibmcam_veio(uvd, 0, 0x00c0, 0x010c); | ||
2404 | break; | ||
2405 | case VIDEOSIZE_176x144: | ||
2406 | ibmcam_veio(uvd, 0, 0x0000, 0x0100); | ||
2407 | ibmcam_veio(uvd, 0, 0x00c0, 0x0111); | ||
2408 | ibmcam_veio(uvd, 0, 0x00bc, 0x012c); | ||
2409 | ibmcam_veio(uvd, 0, 0x0080, 0x012b); | ||
2410 | ibmcam_veio(uvd, 0, 0x0000, 0x0108); | ||
2411 | ibmcam_veio(uvd, 0, 0x0001, 0x0133); | ||
2412 | ibmcam_veio(uvd, 0, 0x009b, 0x010f); | ||
2413 | ibmcam_veio(uvd, 0, 0x00bb, 0x010f); | ||
2414 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2415 | ibmcam_veio(uvd, 0, 0x0038, 0x012f); | ||
2416 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2417 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2418 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2419 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2420 | ibmcam_veio(uvd, 0, 0x000a, 0x012f); | ||
2421 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2422 | ibmcam_veio(uvd, 0, 0x005c, 0x0127); | ||
2423 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2424 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2425 | ibmcam_veio(uvd, 0, 0x0004, 0x012f); | ||
2426 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2427 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2428 | ibmcam_veio(uvd, 0, 0x00fb, 0x012e); | ||
2429 | ibmcam_veio(uvd, 0, 0x0000, 0x0130); | ||
2430 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2431 | ibmcam_veio(uvd, 0, 0x00aa, 0x012f); | ||
2432 | ibmcam_veio(uvd, 0, 0xd055, 0x0124); | ||
2433 | ibmcam_veio(uvd, 0, 0x000c, 0x0127); | ||
2434 | ibmcam_veio(uvd, 0, 0x0009, 0x012e); | ||
2435 | ibmcam_veio(uvd, 0, 0xaa28, 0x0124); | ||
2436 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2437 | ibmcam_veio(uvd, 0, 0x0012, 0x012f); | ||
2438 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2439 | ibmcam_veio(uvd, 0, 0x0008, 0x0127); | ||
2440 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2441 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2442 | ibmcam_veio(uvd, 0, 0x002a, 0x012d); | ||
2443 | ibmcam_veio(uvd, 0, 0x0000, 0x012f); | ||
2444 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2445 | ibmcam_veio(uvd, 0, 0xfffa, 0x0124); | ||
2446 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2447 | ibmcam_veio(uvd, 0, 0x0034, 0x012f); | ||
2448 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2449 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2450 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2451 | ibmcam_veio(uvd, 0, 0x0038, 0x0119); | ||
2452 | ibmcam_veio(uvd, 0, 0x00d6, 0x0107); | ||
2453 | ibmcam_veio(uvd, 0, 0x0003, 0x0106); | ||
2454 | ibmcam_veio(uvd, 0, 0x0018, 0x0107); | ||
2455 | ibmcam_veio(uvd, 0, 0x0003, 0x0106); | ||
2456 | ibmcam_veio(uvd, 0, 0x00d0, 0x0111); | ||
2457 | ibmcam_veio(uvd, 0, 0x00b9, 0x010a); | ||
2458 | ibmcam_veio(uvd, 0, 0x0001, 0x0102); | ||
2459 | ibmcam_veio(uvd, 0, 0x002c, 0x0103); | ||
2460 | ibmcam_veio(uvd, 0, 0x0000, 0x0104); | ||
2461 | ibmcam_veio(uvd, 0, 0x0024, 0x0105); | ||
2462 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2463 | ibmcam_veio(uvd, 0, 0x0016, 0x012f); | ||
2464 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2465 | ibmcam_veio(uvd, 0, 0x0007, 0x0127); | ||
2466 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2467 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2468 | ibmcam_veio(uvd, 0, 0x0014, 0x012d); | ||
2469 | ibmcam_veio(uvd, 0, 0x0001, 0x012f); | ||
2470 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2471 | ibmcam_veio(uvd, 0, 0x00aa, 0x012e); | ||
2472 | ibmcam_veio(uvd, 0, 0x001a, 0x0130); | ||
2473 | ibmcam_veio(uvd, 0, 0x8a0a, 0x0124); | ||
2474 | ibmcam_veio(uvd, 0, 0x005e, 0x012d); | ||
2475 | ibmcam_veio(uvd, 0, 0x9545, 0x0124); | ||
2476 | ibmcam_veio(uvd, 0, 0x00aa, 0x0127); | ||
2477 | ibmcam_veio(uvd, 0, 0x0018, 0x012e); | ||
2478 | ibmcam_veio(uvd, 0, 0x0049, 0x0130); | ||
2479 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2480 | ibmcam_veio(uvd, 0, 0x00aa, 0x012f); | ||
2481 | ibmcam_veio(uvd, 0, 0xd055, 0x0124); | ||
2482 | ibmcam_veio(uvd, 0, 0x001c, 0x0127); | ||
2483 | ibmcam_veio(uvd, 0, 0x00c7, 0x012e); | ||
2484 | ibmcam_veio(uvd, 0, 0xaa28, 0x0124); | ||
2485 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2486 | ibmcam_veio(uvd, 0, 0x0032, 0x012f); | ||
2487 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2488 | ibmcam_veio(uvd, 0, 0x0028, 0x0127); | ||
2489 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2490 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2491 | ibmcam_veio(uvd, 0, 0x0036, 0x012d); | ||
2492 | ibmcam_veio(uvd, 0, 0x0008, 0x012f); | ||
2493 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2494 | ibmcam_veio(uvd, 0, 0xfffa, 0x0124); | ||
2495 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2496 | ibmcam_veio(uvd, 0, 0x001e, 0x012f); | ||
2497 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2498 | ibmcam_veio(uvd, 0, 0x0010, 0x0127); | ||
2499 | ibmcam_veio(uvd, 0, 0x0013, 0x012e); | ||
2500 | ibmcam_veio(uvd, 0, 0x002a, 0x0130); | ||
2501 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2502 | ibmcam_veio(uvd, 0, 0x0010, 0x012d); | ||
2503 | ibmcam_veio(uvd, 0, 0x006d, 0x012f); | ||
2504 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2505 | ibmcam_veio(uvd, 0, 0x0001, 0x0127); | ||
2506 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2507 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2508 | ibmcam_veio(uvd, 0, 0x0038, 0x012f); | ||
2509 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2510 | ibmcam_veio(uvd, 0, 0x0004, 0x0127); | ||
2511 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2512 | ibmcam_veio(uvd, 0, 0x00c0, 0x010c); | ||
2513 | break; | ||
2514 | case VIDEOSIZE_320x240: | ||
2515 | ibmcam_veio(uvd, 0, 0x0000, 0x0100); | ||
2516 | ibmcam_veio(uvd, 0, 0x00c0, 0x0111); | ||
2517 | ibmcam_veio(uvd, 0, 0x00bc, 0x012c); | ||
2518 | ibmcam_veio(uvd, 0, 0x0080, 0x012b); | ||
2519 | ibmcam_veio(uvd, 0, 0x0000, 0x0108); | ||
2520 | ibmcam_veio(uvd, 0, 0x0001, 0x0133); | ||
2521 | ibmcam_veio(uvd, 0, 0x009b, 0x010f); | ||
2522 | ibmcam_veio(uvd, 0, 0x00bb, 0x010f); | ||
2523 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2524 | ibmcam_veio(uvd, 0, 0x0038, 0x012f); | ||
2525 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2526 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2527 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2528 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2529 | ibmcam_veio(uvd, 0, 0x000a, 0x012f); | ||
2530 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2531 | ibmcam_veio(uvd, 0, 0x005c, 0x0127); | ||
2532 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2533 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2534 | ibmcam_veio(uvd, 0, 0x0004, 0x012f); | ||
2535 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2536 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2537 | ibmcam_veio(uvd, 0, 0x00fb, 0x012e); | ||
2538 | ibmcam_veio(uvd, 0, 0x0000, 0x0130); | ||
2539 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2540 | ibmcam_veio(uvd, 0, 0x00aa, 0x012f); | ||
2541 | ibmcam_veio(uvd, 0, 0xd055, 0x0124); | ||
2542 | ibmcam_veio(uvd, 0, 0x000c, 0x0127); | ||
2543 | ibmcam_veio(uvd, 0, 0x0009, 0x012e); | ||
2544 | ibmcam_veio(uvd, 0, 0xaa28, 0x0124); | ||
2545 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2546 | ibmcam_veio(uvd, 0, 0x0012, 0x012f); | ||
2547 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2548 | ibmcam_veio(uvd, 0, 0x0008, 0x0127); | ||
2549 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2550 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2551 | ibmcam_veio(uvd, 0, 0x002a, 0x012d); | ||
2552 | ibmcam_veio(uvd, 0, 0x0000, 0x012f); | ||
2553 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2554 | ibmcam_veio(uvd, 0, 0xfffa, 0x0124); | ||
2555 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2556 | ibmcam_veio(uvd, 0, 0x0034, 0x012f); | ||
2557 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2558 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2559 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2560 | ibmcam_veio(uvd, 0, 0x0070, 0x0119); | ||
2561 | ibmcam_veio(uvd, 0, 0x00d2, 0x0107); | ||
2562 | ibmcam_veio(uvd, 0, 0x0003, 0x0106); | ||
2563 | ibmcam_veio(uvd, 0, 0x005e, 0x0107); | ||
2564 | ibmcam_veio(uvd, 0, 0x0003, 0x0106); | ||
2565 | ibmcam_veio(uvd, 0, 0x00d0, 0x0111); | ||
2566 | ibmcam_veio(uvd, 0, 0x0039, 0x010a); | ||
2567 | ibmcam_veio(uvd, 0, 0x0001, 0x0102); | ||
2568 | ibmcam_veio(uvd, 0, 0x0028, 0x0103); | ||
2569 | ibmcam_veio(uvd, 0, 0x0000, 0x0104); | ||
2570 | ibmcam_veio(uvd, 0, 0x001e, 0x0105); | ||
2571 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2572 | ibmcam_veio(uvd, 0, 0x0016, 0x012f); | ||
2573 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2574 | ibmcam_veio(uvd, 0, 0x000a, 0x0127); | ||
2575 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2576 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2577 | ibmcam_veio(uvd, 0, 0x0014, 0x012d); | ||
2578 | ibmcam_veio(uvd, 0, 0x0008, 0x012f); | ||
2579 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2580 | ibmcam_veio(uvd, 0, 0x00aa, 0x012e); | ||
2581 | ibmcam_veio(uvd, 0, 0x001a, 0x0130); | ||
2582 | ibmcam_veio(uvd, 0, 0x8a0a, 0x0124); | ||
2583 | ibmcam_veio(uvd, 0, 0x005a, 0x012d); | ||
2584 | ibmcam_veio(uvd, 0, 0x9545, 0x0124); | ||
2585 | ibmcam_veio(uvd, 0, 0x00aa, 0x0127); | ||
2586 | ibmcam_veio(uvd, 0, 0x0018, 0x012e); | ||
2587 | ibmcam_veio(uvd, 0, 0x0043, 0x0130); | ||
2588 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2589 | ibmcam_veio(uvd, 0, 0x00aa, 0x012f); | ||
2590 | ibmcam_veio(uvd, 0, 0xd055, 0x0124); | ||
2591 | ibmcam_veio(uvd, 0, 0x001c, 0x0127); | ||
2592 | ibmcam_veio(uvd, 0, 0x00eb, 0x012e); | ||
2593 | ibmcam_veio(uvd, 0, 0xaa28, 0x0124); | ||
2594 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2595 | ibmcam_veio(uvd, 0, 0x0032, 0x012f); | ||
2596 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2597 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2598 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2599 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2600 | ibmcam_veio(uvd, 0, 0x0036, 0x012d); | ||
2601 | ibmcam_veio(uvd, 0, 0x0008, 0x012f); | ||
2602 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2603 | ibmcam_veio(uvd, 0, 0xfffa, 0x0124); | ||
2604 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2605 | ibmcam_veio(uvd, 0, 0x001e, 0x012f); | ||
2606 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2607 | ibmcam_veio(uvd, 0, 0x0017, 0x0127); | ||
2608 | ibmcam_veio(uvd, 0, 0x0013, 0x012e); | ||
2609 | ibmcam_veio(uvd, 0, 0x0031, 0x0130); | ||
2610 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2611 | ibmcam_veio(uvd, 0, 0x0017, 0x012d); | ||
2612 | ibmcam_veio(uvd, 0, 0x0078, 0x012f); | ||
2613 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2614 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2615 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2616 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2617 | ibmcam_veio(uvd, 0, 0x0038, 0x012f); | ||
2618 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2619 | ibmcam_veio(uvd, 0, 0x0004, 0x0127); | ||
2620 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2621 | ibmcam_veio(uvd, 0, 0x00c0, 0x010c); | ||
2622 | break; | ||
2623 | case VIDEOSIZE_352x288: | ||
2624 | ibmcam_veio(uvd, 0, 0x0000, 0x0100); | ||
2625 | ibmcam_veio(uvd, 0, 0x00c0, 0x0111); | ||
2626 | ibmcam_veio(uvd, 0, 0x00bc, 0x012c); | ||
2627 | ibmcam_veio(uvd, 0, 0x0080, 0x012b); | ||
2628 | ibmcam_veio(uvd, 0, 0x0000, 0x0108); | ||
2629 | ibmcam_veio(uvd, 0, 0x0001, 0x0133); | ||
2630 | ibmcam_veio(uvd, 0, 0x009b, 0x010f); | ||
2631 | ibmcam_veio(uvd, 0, 0x00bb, 0x010f); | ||
2632 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2633 | ibmcam_veio(uvd, 0, 0x0038, 0x012f); | ||
2634 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2635 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2636 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2637 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2638 | ibmcam_veio(uvd, 0, 0x000a, 0x012f); | ||
2639 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2640 | ibmcam_veio(uvd, 0, 0x005c, 0x0127); | ||
2641 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2642 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2643 | ibmcam_veio(uvd, 0, 0x0004, 0x012f); | ||
2644 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2645 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2646 | ibmcam_veio(uvd, 0, 0x00fb, 0x012e); | ||
2647 | ibmcam_veio(uvd, 0, 0x0000, 0x0130); | ||
2648 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2649 | ibmcam_veio(uvd, 0, 0x00aa, 0x012f); | ||
2650 | ibmcam_veio(uvd, 0, 0xd055, 0x0124); | ||
2651 | ibmcam_veio(uvd, 0, 0x000c, 0x0127); | ||
2652 | ibmcam_veio(uvd, 0, 0x0009, 0x012e); | ||
2653 | ibmcam_veio(uvd, 0, 0xaa28, 0x0124); | ||
2654 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2655 | ibmcam_veio(uvd, 0, 0x0012, 0x012f); | ||
2656 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2657 | ibmcam_veio(uvd, 0, 0x0008, 0x0127); | ||
2658 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2659 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2660 | ibmcam_veio(uvd, 0, 0x002a, 0x012d); | ||
2661 | ibmcam_veio(uvd, 0, 0x0000, 0x012f); | ||
2662 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2663 | ibmcam_veio(uvd, 0, 0xfffa, 0x0124); | ||
2664 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2665 | ibmcam_veio(uvd, 0, 0x0034, 0x012f); | ||
2666 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2667 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2668 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2669 | ibmcam_veio(uvd, 0, 0x0070, 0x0119); | ||
2670 | ibmcam_veio(uvd, 0, 0x00f2, 0x0107); | ||
2671 | ibmcam_veio(uvd, 0, 0x0003, 0x0106); | ||
2672 | ibmcam_veio(uvd, 0, 0x008c, 0x0107); | ||
2673 | ibmcam_veio(uvd, 0, 0x0003, 0x0106); | ||
2674 | ibmcam_veio(uvd, 0, 0x00c0, 0x0111); | ||
2675 | ibmcam_veio(uvd, 0, 0x0039, 0x010a); | ||
2676 | ibmcam_veio(uvd, 0, 0x0001, 0x0102); | ||
2677 | ibmcam_veio(uvd, 0, 0x002c, 0x0103); | ||
2678 | ibmcam_veio(uvd, 0, 0x0000, 0x0104); | ||
2679 | ibmcam_veio(uvd, 0, 0x0024, 0x0105); | ||
2680 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2681 | ibmcam_veio(uvd, 0, 0x0016, 0x012f); | ||
2682 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2683 | ibmcam_veio(uvd, 0, 0x0006, 0x0127); | ||
2684 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2685 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2686 | ibmcam_veio(uvd, 0, 0x0014, 0x012d); | ||
2687 | ibmcam_veio(uvd, 0, 0x0002, 0x012f); | ||
2688 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2689 | ibmcam_veio(uvd, 0, 0x00aa, 0x012e); | ||
2690 | ibmcam_veio(uvd, 0, 0x001a, 0x0130); | ||
2691 | ibmcam_veio(uvd, 0, 0x8a0a, 0x0124); | ||
2692 | ibmcam_veio(uvd, 0, 0x005e, 0x012d); | ||
2693 | ibmcam_veio(uvd, 0, 0x9545, 0x0124); | ||
2694 | ibmcam_veio(uvd, 0, 0x00aa, 0x0127); | ||
2695 | ibmcam_veio(uvd, 0, 0x0018, 0x012e); | ||
2696 | ibmcam_veio(uvd, 0, 0x0049, 0x0130); | ||
2697 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2698 | ibmcam_veio(uvd, 0, 0x00aa, 0x012f); | ||
2699 | ibmcam_veio(uvd, 0, 0xd055, 0x0124); | ||
2700 | ibmcam_veio(uvd, 0, 0x001c, 0x0127); | ||
2701 | ibmcam_veio(uvd, 0, 0x00cf, 0x012e); | ||
2702 | ibmcam_veio(uvd, 0, 0xaa28, 0x0124); | ||
2703 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2704 | ibmcam_veio(uvd, 0, 0x0032, 0x012f); | ||
2705 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2706 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2707 | ibmcam_veio(uvd, 0, 0x00aa, 0x0130); | ||
2708 | ibmcam_veio(uvd, 0, 0x82a8, 0x0124); | ||
2709 | ibmcam_veio(uvd, 0, 0x0036, 0x012d); | ||
2710 | ibmcam_veio(uvd, 0, 0x0008, 0x012f); | ||
2711 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2712 | ibmcam_veio(uvd, 0, 0xfffa, 0x0124); | ||
2713 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2714 | ibmcam_veio(uvd, 0, 0x001e, 0x012f); | ||
2715 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2716 | ibmcam_veio(uvd, 0, 0x0010, 0x0127); | ||
2717 | ibmcam_veio(uvd, 0, 0x0013, 0x012e); | ||
2718 | ibmcam_veio(uvd, 0, 0x0025, 0x0130); | ||
2719 | ibmcam_veio(uvd, 0, 0x8a28, 0x0124); | ||
2720 | ibmcam_veio(uvd, 0, 0x0010, 0x012d); | ||
2721 | ibmcam_veio(uvd, 0, 0x0048, 0x012f); | ||
2722 | ibmcam_veio(uvd, 0, 0xd145, 0x0124); | ||
2723 | ibmcam_veio(uvd, 0, 0x0000, 0x0127); | ||
2724 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2725 | ibmcam_veio(uvd, 0, 0x00aa, 0x012d); | ||
2726 | ibmcam_veio(uvd, 0, 0x0038, 0x012f); | ||
2727 | ibmcam_veio(uvd, 0, 0xd141, 0x0124); | ||
2728 | ibmcam_veio(uvd, 0, 0x0004, 0x0127); | ||
2729 | ibmcam_veio(uvd, 0, 0xfea8, 0x0124); | ||
2730 | ibmcam_veio(uvd, 0, 0x00c0, 0x010c); | ||
2731 | break; | ||
2732 | } | ||
2733 | usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp)); | ||
2734 | } | ||
2735 | |||
2736 | static void ibmcam_model3_setup_after_video_if(struct uvd *uvd) | ||
2737 | { | ||
2738 | int i; | ||
2739 | /* | ||
2740 | * 01.01.08 - Added for RCA video in support -LO | ||
2741 | * This struct is used to init the Model3 cam to use the RCA video in port | ||
2742 | * instead of the CCD sensor. | ||
2743 | */ | ||
2744 | static const struct struct_initData initData[] = { | ||
2745 | {0, 0x0000, 0x010c}, | ||
2746 | {0, 0x0006, 0x012c}, | ||
2747 | {0, 0x0078, 0x012d}, | ||
2748 | {0, 0x0046, 0x012f}, | ||
2749 | {0, 0xd141, 0x0124}, | ||
2750 | {0, 0x0000, 0x0127}, | ||
2751 | {0, 0xfea8, 0x0124}, | ||
2752 | {1, 0x0000, 0x0116}, | ||
2753 | {0, 0x0064, 0x0116}, | ||
2754 | {1, 0x0000, 0x0115}, | ||
2755 | {0, 0x0003, 0x0115}, | ||
2756 | {0, 0x0008, 0x0123}, | ||
2757 | {0, 0x0000, 0x0117}, | ||
2758 | {0, 0x0000, 0x0112}, | ||
2759 | {0, 0x0080, 0x0100}, | ||
2760 | {0, 0x0000, 0x0100}, | ||
2761 | {1, 0x0000, 0x0116}, | ||
2762 | {0, 0x0060, 0x0116}, | ||
2763 | {0, 0x0002, 0x0112}, | ||
2764 | {0, 0x0000, 0x0123}, | ||
2765 | {0, 0x0001, 0x0117}, | ||
2766 | {0, 0x0040, 0x0108}, | ||
2767 | {0, 0x0019, 0x012c}, | ||
2768 | {0, 0x0040, 0x0116}, | ||
2769 | {0, 0x000a, 0x0115}, | ||
2770 | {0, 0x000b, 0x0115}, | ||
2771 | {0, 0x0078, 0x012d}, | ||
2772 | {0, 0x0046, 0x012f}, | ||
2773 | {0, 0xd141, 0x0124}, | ||
2774 | {0, 0x0000, 0x0127}, | ||
2775 | {0, 0xfea8, 0x0124}, | ||
2776 | {0, 0x0064, 0x0116}, | ||
2777 | {0, 0x0000, 0x0115}, | ||
2778 | {0, 0x0001, 0x0115}, | ||
2779 | {0, 0xffff, 0x0124}, | ||
2780 | {0, 0xfff9, 0x0124}, | ||
2781 | {0, 0x0086, 0x0127}, | ||
2782 | {0, 0xfff8, 0x0124}, | ||
2783 | {0, 0xfffd, 0x0124}, | ||
2784 | {0, 0x00aa, 0x0127}, | ||
2785 | {0, 0xfff8, 0x0124}, | ||
2786 | {0, 0xfffd, 0x0124}, | ||
2787 | {0, 0x0000, 0x0127}, | ||
2788 | {0, 0xfff8, 0x0124}, | ||
2789 | {0, 0xfffd, 0x0124}, | ||
2790 | {0, 0xfffa, 0x0124}, | ||
2791 | {0, 0xffff, 0x0124}, | ||
2792 | {0, 0xfff9, 0x0124}, | ||
2793 | {0, 0x0086, 0x0127}, | ||
2794 | {0, 0xfff8, 0x0124}, | ||
2795 | {0, 0xfffd, 0x0124}, | ||
2796 | {0, 0x00f2, 0x0127}, | ||
2797 | {0, 0xfff8, 0x0124}, | ||
2798 | {0, 0xfffd, 0x0124}, | ||
2799 | {0, 0x000f, 0x0127}, | ||
2800 | {0, 0xfff8, 0x0124}, | ||
2801 | {0, 0xfffd, 0x0124}, | ||
2802 | {0, 0xfffa, 0x0124}, | ||
2803 | {0, 0xffff, 0x0124}, | ||
2804 | {0, 0xfff9, 0x0124}, | ||
2805 | {0, 0x0086, 0x0127}, | ||
2806 | {0, 0xfff8, 0x0124}, | ||
2807 | {0, 0xfffd, 0x0124}, | ||
2808 | {0, 0x00f8, 0x0127}, | ||
2809 | {0, 0xfff8, 0x0124}, | ||
2810 | {0, 0xfffd, 0x0124}, | ||
2811 | {0, 0x00fc, 0x0127}, | ||
2812 | {0, 0xfff8, 0x0124}, | ||
2813 | {0, 0xfffd, 0x0124}, | ||
2814 | {0, 0xfffa, 0x0124}, | ||
2815 | {0, 0xffff, 0x0124}, | ||
2816 | {0, 0xfff9, 0x0124}, | ||
2817 | {0, 0x0086, 0x0127}, | ||
2818 | {0, 0xfff8, 0x0124}, | ||
2819 | {0, 0xfffd, 0x0124}, | ||
2820 | {0, 0x00f9, 0x0127}, | ||
2821 | {0, 0xfff8, 0x0124}, | ||
2822 | {0, 0xfffd, 0x0124}, | ||
2823 | {0, 0x003c, 0x0127}, | ||
2824 | {0, 0xfff8, 0x0124}, | ||
2825 | {0, 0xfffd, 0x0124}, | ||
2826 | {0, 0xfffa, 0x0124}, | ||
2827 | {0, 0xffff, 0x0124}, | ||
2828 | {0, 0xfff9, 0x0124}, | ||
2829 | {0, 0x0086, 0x0127}, | ||
2830 | {0, 0xfff8, 0x0124}, | ||
2831 | {0, 0xfffd, 0x0124}, | ||
2832 | {0, 0x0027, 0x0127}, | ||
2833 | {0, 0xfff8, 0x0124}, | ||
2834 | {0, 0xfffd, 0x0124}, | ||
2835 | {0, 0x0019, 0x0127}, | ||
2836 | {0, 0xfff8, 0x0124}, | ||
2837 | {0, 0xfffd, 0x0124}, | ||
2838 | {0, 0xfffa, 0x0124}, | ||
2839 | {0, 0xfff9, 0x0124}, | ||
2840 | {0, 0x0086, 0x0127}, | ||
2841 | {0, 0xfff8, 0x0124}, | ||
2842 | {0, 0xfffd, 0x0124}, | ||
2843 | {0, 0x0037, 0x0127}, | ||
2844 | {0, 0xfff8, 0x0124}, | ||
2845 | {0, 0xfffd, 0x0124}, | ||
2846 | {0, 0x0000, 0x0127}, | ||
2847 | {0, 0xfff8, 0x0124}, | ||
2848 | {0, 0xfffd, 0x0124}, | ||
2849 | {0, 0x0021, 0x0127}, | ||
2850 | {0, 0xfff8, 0x0124}, | ||
2851 | {0, 0xfffd, 0x0124}, | ||
2852 | {0, 0xfffa, 0x0124}, | ||
2853 | {0, 0xfff9, 0x0124}, | ||
2854 | {0, 0x0086, 0x0127}, | ||
2855 | {0, 0xfff8, 0x0124}, | ||
2856 | {0, 0xfffd, 0x0124}, | ||
2857 | {0, 0x0038, 0x0127}, | ||
2858 | {0, 0xfff8, 0x0124}, | ||
2859 | {0, 0xfffd, 0x0124}, | ||
2860 | {0, 0x0006, 0x0127}, | ||
2861 | {0, 0xfff8, 0x0124}, | ||
2862 | {0, 0xfffd, 0x0124}, | ||
2863 | {0, 0x0045, 0x0127}, | ||
2864 | {0, 0xfff8, 0x0124}, | ||
2865 | {0, 0xfffd, 0x0124}, | ||
2866 | {0, 0xfffa, 0x0124}, | ||
2867 | {0, 0xfff9, 0x0124}, | ||
2868 | {0, 0x0086, 0x0127}, | ||
2869 | {0, 0xfff8, 0x0124}, | ||
2870 | {0, 0xfffd, 0x0124}, | ||
2871 | {0, 0x0037, 0x0127}, | ||
2872 | {0, 0xfff8, 0x0124}, | ||
2873 | {0, 0xfffd, 0x0124}, | ||
2874 | {0, 0x0001, 0x0127}, | ||
2875 | {0, 0xfff8, 0x0124}, | ||
2876 | {0, 0xfffd, 0x0124}, | ||
2877 | {0, 0x002a, 0x0127}, | ||
2878 | {0, 0xfff8, 0x0124}, | ||
2879 | {0, 0xfffd, 0x0124}, | ||
2880 | {0, 0xfffa, 0x0124}, | ||
2881 | {0, 0xfff9, 0x0124}, | ||
2882 | {0, 0x0086, 0x0127}, | ||
2883 | {0, 0xfff8, 0x0124}, | ||
2884 | {0, 0xfffd, 0x0124}, | ||
2885 | {0, 0x0038, 0x0127}, | ||
2886 | {0, 0xfff8, 0x0124}, | ||
2887 | {0, 0xfffd, 0x0124}, | ||
2888 | {0, 0x0000, 0x0127}, | ||
2889 | {0, 0xfff8, 0x0124}, | ||
2890 | {0, 0xfffd, 0x0124}, | ||
2891 | {0, 0x000e, 0x0127}, | ||
2892 | {0, 0xfff8, 0x0124}, | ||
2893 | {0, 0xfffd, 0x0124}, | ||
2894 | {0, 0xfffa, 0x0124}, | ||
2895 | {0, 0xfff9, 0x0124}, | ||
2896 | {0, 0x0086, 0x0127}, | ||
2897 | {0, 0xfff8, 0x0124}, | ||
2898 | {0, 0xfffd, 0x0124}, | ||
2899 | {0, 0x0037, 0x0127}, | ||
2900 | {0, 0xfff8, 0x0124}, | ||
2901 | {0, 0xfffd, 0x0124}, | ||
2902 | {0, 0x0001, 0x0127}, | ||
2903 | {0, 0xfff8, 0x0124}, | ||
2904 | {0, 0xfffd, 0x0124}, | ||
2905 | {0, 0x002b, 0x0127}, | ||
2906 | {0, 0xfff8, 0x0124}, | ||
2907 | {0, 0xfffd, 0x0124}, | ||
2908 | {0, 0xfffa, 0x0124}, | ||
2909 | {0, 0xfff9, 0x0124}, | ||
2910 | {0, 0x0086, 0x0127}, | ||
2911 | {0, 0xfff8, 0x0124}, | ||
2912 | {0, 0xfffd, 0x0124}, | ||
2913 | {0, 0x0038, 0x0127}, | ||
2914 | {0, 0xfff8, 0x0124}, | ||
2915 | {0, 0xfffd, 0x0124}, | ||
2916 | {0, 0x0001, 0x0127}, | ||
2917 | {0, 0xfff8, 0x0124}, | ||
2918 | {0, 0xfffd, 0x0124}, | ||
2919 | {0, 0x00f4, 0x0127}, | ||
2920 | {0, 0xfff8, 0x0124}, | ||
2921 | {0, 0xfffd, 0x0124}, | ||
2922 | {0, 0xfffa, 0x0124}, | ||
2923 | {0, 0xfff9, 0x0124}, | ||
2924 | {0, 0x0086, 0x0127}, | ||
2925 | {0, 0xfff8, 0x0124}, | ||
2926 | {0, 0xfffd, 0x0124}, | ||
2927 | {0, 0x0037, 0x0127}, | ||
2928 | {0, 0xfff8, 0x0124}, | ||
2929 | {0, 0xfffd, 0x0124}, | ||
2930 | {0, 0x0001, 0x0127}, | ||
2931 | {0, 0xfff8, 0x0124}, | ||
2932 | {0, 0xfffd, 0x0124}, | ||
2933 | {0, 0x002c, 0x0127}, | ||
2934 | {0, 0xfff8, 0x0124}, | ||
2935 | {0, 0xfffd, 0x0124}, | ||
2936 | {0, 0xfffa, 0x0124}, | ||
2937 | {0, 0xfff9, 0x0124}, | ||
2938 | {0, 0x0086, 0x0127}, | ||
2939 | {0, 0xfff8, 0x0124}, | ||
2940 | {0, 0xfffd, 0x0124}, | ||
2941 | {0, 0x0038, 0x0127}, | ||
2942 | {0, 0xfff8, 0x0124}, | ||
2943 | {0, 0xfffd, 0x0124}, | ||
2944 | {0, 0x0001, 0x0127}, | ||
2945 | {0, 0xfff8, 0x0124}, | ||
2946 | {0, 0xfffd, 0x0124}, | ||
2947 | {0, 0x0004, 0x0127}, | ||
2948 | {0, 0xfff8, 0x0124}, | ||
2949 | {0, 0xfffd, 0x0124}, | ||
2950 | {0, 0xfffa, 0x0124}, | ||
2951 | {0, 0xfff9, 0x0124}, | ||
2952 | {0, 0x0086, 0x0127}, | ||
2953 | {0, 0xfff8, 0x0124}, | ||
2954 | {0, 0xfffd, 0x0124}, | ||
2955 | {0, 0x0037, 0x0127}, | ||
2956 | {0, 0xfff8, 0x0124}, | ||
2957 | {0, 0xfffd, 0x0124}, | ||
2958 | {0, 0x0001, 0x0127}, | ||
2959 | {0, 0xfff8, 0x0124}, | ||
2960 | {0, 0xfffd, 0x0124}, | ||
2961 | {0, 0x002d, 0x0127}, | ||
2962 | {0, 0xfff8, 0x0124}, | ||
2963 | {0, 0xfffd, 0x0124}, | ||
2964 | {0, 0xfffa, 0x0124}, | ||
2965 | {0, 0xfff9, 0x0124}, | ||
2966 | {0, 0x0086, 0x0127}, | ||
2967 | {0, 0xfff8, 0x0124}, | ||
2968 | {0, 0xfffd, 0x0124}, | ||
2969 | {0, 0x0038, 0x0127}, | ||
2970 | {0, 0xfff8, 0x0124}, | ||
2971 | {0, 0xfffd, 0x0124}, | ||
2972 | {0, 0x0000, 0x0127}, | ||
2973 | {0, 0xfff8, 0x0124}, | ||
2974 | {0, 0xfffd, 0x0124}, | ||
2975 | {0, 0x0014, 0x0127}, | ||
2976 | {0, 0xfff8, 0x0124}, | ||
2977 | {0, 0xfffd, 0x0124}, | ||
2978 | {0, 0xfffa, 0x0124}, | ||
2979 | {0, 0xfff9, 0x0124}, | ||
2980 | {0, 0x0086, 0x0127}, | ||
2981 | {0, 0xfff8, 0x0124}, | ||
2982 | {0, 0xfffd, 0x0124}, | ||
2983 | {0, 0x0037, 0x0127}, | ||
2984 | {0, 0xfff8, 0x0124}, | ||
2985 | {0, 0xfffd, 0x0124}, | ||
2986 | {0, 0x0001, 0x0127}, | ||
2987 | {0, 0xfff8, 0x0124}, | ||
2988 | {0, 0xfffd, 0x0124}, | ||
2989 | {0, 0x002e, 0x0127}, | ||
2990 | {0, 0xfff8, 0x0124}, | ||
2991 | {0, 0xfffd, 0x0124}, | ||
2992 | {0, 0xfffa, 0x0124}, | ||
2993 | {0, 0xfff9, 0x0124}, | ||
2994 | {0, 0x0086, 0x0127}, | ||
2995 | {0, 0xfff8, 0x0124}, | ||
2996 | {0, 0xfffd, 0x0124}, | ||
2997 | {0, 0x0038, 0x0127}, | ||
2998 | {0, 0xfff8, 0x0124}, | ||
2999 | {0, 0xfffd, 0x0124}, | ||
3000 | {0, 0x0003, 0x0127}, | ||
3001 | {0, 0xfff8, 0x0124}, | ||
3002 | {0, 0xfffd, 0x0124}, | ||
3003 | {0, 0x0000, 0x0127}, | ||
3004 | {0, 0xfff8, 0x0124}, | ||
3005 | {0, 0xfffd, 0x0124}, | ||
3006 | {0, 0xfffa, 0x0124}, | ||
3007 | {0, 0xfff9, 0x0124}, | ||
3008 | {0, 0x0086, 0x0127}, | ||
3009 | {0, 0xfff8, 0x0124}, | ||
3010 | {0, 0xfffd, 0x0124}, | ||
3011 | {0, 0x0037, 0x0127}, | ||
3012 | {0, 0xfff8, 0x0124}, | ||
3013 | {0, 0xfffd, 0x0124}, | ||
3014 | {0, 0x0001, 0x0127}, | ||
3015 | {0, 0xfff8, 0x0124}, | ||
3016 | {0, 0xfffd, 0x0124}, | ||
3017 | {0, 0x002f, 0x0127}, | ||
3018 | {0, 0xfff8, 0x0124}, | ||
3019 | {0, 0xfffd, 0x0124}, | ||
3020 | {0, 0xfffa, 0x0124}, | ||
3021 | {0, 0xfff9, 0x0124}, | ||
3022 | {0, 0x0086, 0x0127}, | ||
3023 | {0, 0xfff8, 0x0124}, | ||
3024 | {0, 0xfffd, 0x0124}, | ||
3025 | {0, 0x0038, 0x0127}, | ||
3026 | {0, 0xfff8, 0x0124}, | ||
3027 | {0, 0xfffd, 0x0124}, | ||
3028 | {0, 0x0003, 0x0127}, | ||
3029 | {0, 0xfff8, 0x0124}, | ||
3030 | {0, 0xfffd, 0x0124}, | ||
3031 | {0, 0x0014, 0x0127}, | ||
3032 | {0, 0xfff8, 0x0124}, | ||
3033 | {0, 0xfffd, 0x0124}, | ||
3034 | {0, 0xfffa, 0x0124}, | ||
3035 | {0, 0xfff9, 0x0124}, | ||
3036 | {0, 0x0086, 0x0127}, | ||
3037 | {0, 0xfff8, 0x0124}, | ||
3038 | {0, 0xfffd, 0x0124}, | ||
3039 | {0, 0x0037, 0x0127}, | ||
3040 | {0, 0xfff8, 0x0124}, | ||
3041 | {0, 0xfffd, 0x0124}, | ||
3042 | {0, 0x0001, 0x0127}, | ||
3043 | {0, 0xfff8, 0x0124}, | ||
3044 | {0, 0xfffd, 0x0124}, | ||
3045 | {0, 0x0040, 0x0127}, | ||
3046 | {0, 0xfff8, 0x0124}, | ||
3047 | {0, 0xfffd, 0x0124}, | ||
3048 | {0, 0xfffa, 0x0124}, | ||
3049 | {0, 0xfff9, 0x0124}, | ||
3050 | {0, 0x0086, 0x0127}, | ||
3051 | {0, 0xfff8, 0x0124}, | ||
3052 | {0, 0xfffd, 0x0124}, | ||
3053 | {0, 0x0038, 0x0127}, | ||
3054 | {0, 0xfff8, 0x0124}, | ||
3055 | {0, 0xfffd, 0x0124}, | ||
3056 | {0, 0x0000, 0x0127}, | ||
3057 | {0, 0xfff8, 0x0124}, | ||
3058 | {0, 0xfffd, 0x0124}, | ||
3059 | {0, 0x0040, 0x0127}, | ||
3060 | {0, 0xfff8, 0x0124}, | ||
3061 | {0, 0xfffd, 0x0124}, | ||
3062 | {0, 0xfffa, 0x0124}, | ||
3063 | {0, 0xfff9, 0x0124}, | ||
3064 | {0, 0x0086, 0x0127}, | ||
3065 | {0, 0xfff8, 0x0124}, | ||
3066 | {0, 0xfffd, 0x0124}, | ||
3067 | {0, 0x0037, 0x0127}, | ||
3068 | {0, 0xfff8, 0x0124}, | ||
3069 | {0, 0xfffd, 0x0124}, | ||
3070 | {0, 0x0001, 0x0127}, | ||
3071 | {0, 0xfff8, 0x0124}, | ||
3072 | {0, 0xfffd, 0x0124}, | ||
3073 | {0, 0x0053, 0x0127}, | ||
3074 | {0, 0xfff8, 0x0124}, | ||
3075 | {0, 0xfffd, 0x0124}, | ||
3076 | {0, 0xfffa, 0x0124}, | ||
3077 | {0, 0xfff9, 0x0124}, | ||
3078 | {0, 0x0086, 0x0127}, | ||
3079 | {0, 0xfff8, 0x0124}, | ||
3080 | {0, 0xfffd, 0x0124}, | ||
3081 | {0, 0x0038, 0x0127}, | ||
3082 | {0, 0xfff8, 0x0124}, | ||
3083 | {0, 0xfffd, 0x0124}, | ||
3084 | {0, 0x0000, 0x0127}, | ||
3085 | {0, 0xfff8, 0x0124}, | ||
3086 | {0, 0xfffd, 0x0124}, | ||
3087 | {0, 0x0038, 0x0127}, | ||
3088 | {0, 0xfff8, 0x0124}, | ||
3089 | {0, 0xfffd, 0x0124}, | ||
3090 | {0, 0xfffa, 0x0124}, | ||
3091 | {0, 0x0000, 0x0101}, | ||
3092 | {0, 0x00a0, 0x0103}, | ||
3093 | {0, 0x0078, 0x0105}, | ||
3094 | {0, 0x0000, 0x010a}, | ||
3095 | {0, 0x0024, 0x010b}, | ||
3096 | {0, 0x0028, 0x0119}, | ||
3097 | {0, 0x0088, 0x011b}, | ||
3098 | {0, 0x0002, 0x011d}, | ||
3099 | {0, 0x0003, 0x011e}, | ||
3100 | {0, 0x0000, 0x0129}, | ||
3101 | {0, 0x00fc, 0x012b}, | ||
3102 | {0, 0x0008, 0x0102}, | ||
3103 | {0, 0x0000, 0x0104}, | ||
3104 | {0, 0x0008, 0x011a}, | ||
3105 | {0, 0x0028, 0x011c}, | ||
3106 | {0, 0x0021, 0x012a}, | ||
3107 | {0, 0x0000, 0x0118}, | ||
3108 | {0, 0x0000, 0x0132}, | ||
3109 | {0, 0x0000, 0x0109}, | ||
3110 | {0, 0xfff9, 0x0124}, | ||
3111 | {0, 0x0086, 0x0127}, | ||
3112 | {0, 0xfff8, 0x0124}, | ||
3113 | {0, 0xfffd, 0x0124}, | ||
3114 | {0, 0x0037, 0x0127}, | ||
3115 | {0, 0xfff8, 0x0124}, | ||
3116 | {0, 0xfffd, 0x0124}, | ||
3117 | {0, 0x0001, 0x0127}, | ||
3118 | {0, 0xfff8, 0x0124}, | ||
3119 | {0, 0xfffd, 0x0124}, | ||
3120 | {0, 0x0031, 0x0127}, | ||
3121 | {0, 0xfff8, 0x0124}, | ||
3122 | {0, 0xfffd, 0x0124}, | ||
3123 | {0, 0xfffa, 0x0124}, | ||
3124 | {0, 0xfff9, 0x0124}, | ||
3125 | {0, 0x0086, 0x0127}, | ||
3126 | {0, 0xfff8, 0x0124}, | ||
3127 | {0, 0xfffd, 0x0124}, | ||
3128 | {0, 0x0038, 0x0127}, | ||
3129 | {0, 0xfff8, 0x0124}, | ||
3130 | {0, 0xfffd, 0x0124}, | ||
3131 | {0, 0x0000, 0x0127}, | ||
3132 | {0, 0xfff8, 0x0124}, | ||
3133 | {0, 0xfffd, 0x0124}, | ||
3134 | {0, 0x0000, 0x0127}, | ||
3135 | {0, 0xfff8, 0x0124}, | ||
3136 | {0, 0xfffd, 0x0124}, | ||
3137 | {0, 0xfffa, 0x0124}, | ||
3138 | {0, 0xfff9, 0x0124}, | ||
3139 | {0, 0x0086, 0x0127}, | ||
3140 | {0, 0xfff8, 0x0124}, | ||
3141 | {0, 0xfffd, 0x0124}, | ||
3142 | {0, 0x0037, 0x0127}, | ||
3143 | {0, 0xfff8, 0x0124}, | ||
3144 | {0, 0xfffd, 0x0124}, | ||
3145 | {0, 0x0001, 0x0127}, | ||
3146 | {0, 0xfff8, 0x0124}, | ||
3147 | {0, 0xfffd, 0x0124}, | ||
3148 | {0, 0x0040, 0x0127}, | ||
3149 | {0, 0xfff8, 0x0124}, | ||
3150 | {0, 0xfffd, 0x0124}, | ||
3151 | {0, 0xfffa, 0x0124}, | ||
3152 | {0, 0xfff9, 0x0124}, | ||
3153 | {0, 0x0086, 0x0127}, | ||
3154 | {0, 0xfff8, 0x0124}, | ||
3155 | {0, 0xfffd, 0x0124}, | ||
3156 | {0, 0x0038, 0x0127}, | ||
3157 | {0, 0xfff8, 0x0124}, | ||
3158 | {0, 0xfffd, 0x0124}, | ||
3159 | {0, 0x0000, 0x0127}, | ||
3160 | {0, 0xfff8, 0x0124}, | ||
3161 | {0, 0xfffd, 0x0124}, | ||
3162 | {0, 0x0040, 0x0127}, | ||
3163 | {0, 0xfff8, 0x0124}, | ||
3164 | {0, 0xfffd, 0x0124}, | ||
3165 | {0, 0xfffa, 0x0124}, | ||
3166 | {0, 0xfff9, 0x0124}, | ||
3167 | {0, 0x0086, 0x0127}, | ||
3168 | {0, 0xfff8, 0x0124}, | ||
3169 | {0, 0xfffd, 0x0124}, | ||
3170 | {0, 0x0037, 0x0127}, | ||
3171 | {0, 0xfff8, 0x0124}, | ||
3172 | {0, 0xfffd, 0x0124}, | ||
3173 | {0, 0x0000, 0x0127}, | ||
3174 | {0, 0xfff8, 0x0124}, | ||
3175 | {0, 0xfffd, 0x0124}, | ||
3176 | {0, 0x00dc, 0x0127}, | ||
3177 | {0, 0xfff8, 0x0124}, | ||
3178 | {0, 0xfffd, 0x0124}, | ||
3179 | {0, 0xfffa, 0x0124}, | ||
3180 | {0, 0xfff9, 0x0124}, | ||
3181 | {0, 0x0086, 0x0127}, | ||
3182 | {0, 0xfff8, 0x0124}, | ||
3183 | {0, 0xfffd, 0x0124}, | ||
3184 | {0, 0x0038, 0x0127}, | ||
3185 | {0, 0xfff8, 0x0124}, | ||
3186 | {0, 0xfffd, 0x0124}, | ||
3187 | {0, 0x0000, 0x0127}, | ||
3188 | {0, 0xfff8, 0x0124}, | ||
3189 | {0, 0xfffd, 0x0124}, | ||
3190 | {0, 0x0000, 0x0127}, | ||
3191 | {0, 0xfff8, 0x0124}, | ||
3192 | {0, 0xfffd, 0x0124}, | ||
3193 | {0, 0xfffa, 0x0124}, | ||
3194 | {0, 0xfff9, 0x0124}, | ||
3195 | {0, 0x0086, 0x0127}, | ||
3196 | {0, 0xfff8, 0x0124}, | ||
3197 | {0, 0xfffd, 0x0124}, | ||
3198 | {0, 0x0037, 0x0127}, | ||
3199 | {0, 0xfff8, 0x0124}, | ||
3200 | {0, 0xfffd, 0x0124}, | ||
3201 | {0, 0x0001, 0x0127}, | ||
3202 | {0, 0xfff8, 0x0124}, | ||
3203 | {0, 0xfffd, 0x0124}, | ||
3204 | {0, 0x0032, 0x0127}, | ||
3205 | {0, 0xfff8, 0x0124}, | ||
3206 | {0, 0xfffd, 0x0124}, | ||
3207 | {0, 0xfffa, 0x0124}, | ||
3208 | {0, 0xfff9, 0x0124}, | ||
3209 | {0, 0x0086, 0x0127}, | ||
3210 | {0, 0xfff8, 0x0124}, | ||
3211 | {0, 0xfffd, 0x0124}, | ||
3212 | {0, 0x0038, 0x0127}, | ||
3213 | {0, 0xfff8, 0x0124}, | ||
3214 | {0, 0xfffd, 0x0124}, | ||
3215 | {0, 0x0001, 0x0127}, | ||
3216 | {0, 0xfff8, 0x0124}, | ||
3217 | {0, 0xfffd, 0x0124}, | ||
3218 | {0, 0x0020, 0x0127}, | ||
3219 | {0, 0xfff8, 0x0124}, | ||
3220 | {0, 0xfffd, 0x0124}, | ||
3221 | {0, 0xfffa, 0x0124}, | ||
3222 | {0, 0xfff9, 0x0124}, | ||
3223 | {0, 0x0086, 0x0127}, | ||
3224 | {0, 0xfff8, 0x0124}, | ||
3225 | {0, 0xfffd, 0x0124}, | ||
3226 | {0, 0x0037, 0x0127}, | ||
3227 | {0, 0xfff8, 0x0124}, | ||
3228 | {0, 0xfffd, 0x0124}, | ||
3229 | {0, 0x0001, 0x0127}, | ||
3230 | {0, 0xfff8, 0x0124}, | ||
3231 | {0, 0xfffd, 0x0124}, | ||
3232 | {0, 0x0040, 0x0127}, | ||
3233 | {0, 0xfff8, 0x0124}, | ||
3234 | {0, 0xfffd, 0x0124}, | ||
3235 | {0, 0xfffa, 0x0124}, | ||
3236 | {0, 0xfff9, 0x0124}, | ||
3237 | {0, 0x0086, 0x0127}, | ||
3238 | {0, 0xfff8, 0x0124}, | ||
3239 | {0, 0xfffd, 0x0124}, | ||
3240 | {0, 0x0038, 0x0127}, | ||
3241 | {0, 0xfff8, 0x0124}, | ||
3242 | {0, 0xfffd, 0x0124}, | ||
3243 | {0, 0x0000, 0x0127}, | ||
3244 | {0, 0xfff8, 0x0124}, | ||
3245 | {0, 0xfffd, 0x0124}, | ||
3246 | {0, 0x0040, 0x0127}, | ||
3247 | {0, 0xfff8, 0x0124}, | ||
3248 | {0, 0xfffd, 0x0124}, | ||
3249 | {0, 0xfffa, 0x0124}, | ||
3250 | {0, 0xfff9, 0x0124}, | ||
3251 | {0, 0x0086, 0x0127}, | ||
3252 | {0, 0xfff8, 0x0124}, | ||
3253 | {0, 0xfffd, 0x0124}, | ||
3254 | {0, 0x0037, 0x0127}, | ||
3255 | {0, 0xfff8, 0x0124}, | ||
3256 | {0, 0xfffd, 0x0124}, | ||
3257 | {0, 0x0000, 0x0127}, | ||
3258 | {0, 0xfff8, 0x0124}, | ||
3259 | {0, 0xfffd, 0x0124}, | ||
3260 | {0, 0x0030, 0x0127}, | ||
3261 | {0, 0xfff8, 0x0124}, | ||
3262 | {0, 0xfffd, 0x0124}, | ||
3263 | {0, 0xfffa, 0x0124}, | ||
3264 | {0, 0xfff9, 0x0124}, | ||
3265 | {0, 0x0086, 0x0127}, | ||
3266 | {0, 0xfff8, 0x0124}, | ||
3267 | {0, 0xfffd, 0x0124}, | ||
3268 | {0, 0x0038, 0x0127}, | ||
3269 | {0, 0xfff8, 0x0124}, | ||
3270 | {0, 0xfffd, 0x0124}, | ||
3271 | {0, 0x0008, 0x0127}, | ||
3272 | {0, 0xfff8, 0x0124}, | ||
3273 | {0, 0xfffd, 0x0124}, | ||
3274 | {0, 0x0000, 0x0127}, | ||
3275 | {0, 0xfff8, 0x0124}, | ||
3276 | {0, 0xfffd, 0x0124}, | ||
3277 | {0, 0xfffa, 0x0124}, | ||
3278 | {0, 0x0003, 0x0106}, | ||
3279 | {0, 0x0062, 0x0107}, | ||
3280 | {0, 0x0003, 0x0111}, | ||
3281 | }; | ||
3282 | #define NUM_INIT_DATA | ||
3283 | |||
3284 | unsigned short compression = 0; /* 0=none, 7=best frame rate */ | ||
3285 | int f_rate; /* 0=Fastest 7=slowest */ | ||
3286 | |||
3287 | if (IBMCAM_T(uvd)->initialized) | ||
3288 | return; | ||
3289 | |||
3290 | /* Internal frame rate is controlled by f_rate value */ | ||
3291 | f_rate = 7 - framerate; | ||
3292 | RESTRICT_TO_RANGE(f_rate, 0, 7); | ||
3293 | |||
3294 | ibmcam_veio(uvd, 0, 0x0000, 0x0100); | ||
3295 | ibmcam_veio(uvd, 1, 0x0000, 0x0116); | ||
3296 | ibmcam_veio(uvd, 0, 0x0060, 0x0116); | ||
3297 | ibmcam_veio(uvd, 0, 0x0002, 0x0112); | ||
3298 | ibmcam_veio(uvd, 0, 0x0000, 0x0123); | ||
3299 | ibmcam_veio(uvd, 0, 0x0001, 0x0117); | ||
3300 | ibmcam_veio(uvd, 0, 0x0040, 0x0108); | ||
3301 | ibmcam_veio(uvd, 0, 0x0019, 0x012c); | ||
3302 | ibmcam_veio(uvd, 0, 0x0060, 0x0116); | ||
3303 | ibmcam_veio(uvd, 0, 0x0002, 0x0115); | ||
3304 | ibmcam_veio(uvd, 0, 0x0003, 0x0115); | ||
3305 | ibmcam_veio(uvd, 1, 0x0000, 0x0115); | ||
3306 | ibmcam_veio(uvd, 0, 0x000b, 0x0115); | ||
3307 | ibmcam_model3_Packet1(uvd, 0x000a, 0x0040); | ||
3308 | ibmcam_model3_Packet1(uvd, 0x000b, 0x00f6); | ||
3309 | ibmcam_model3_Packet1(uvd, 0x000c, 0x0002); | ||
3310 | ibmcam_model3_Packet1(uvd, 0x000d, 0x0020); | ||
3311 | ibmcam_model3_Packet1(uvd, 0x000e, 0x0033); | ||
3312 | ibmcam_model3_Packet1(uvd, 0x000f, 0x0007); | ||
3313 | ibmcam_model3_Packet1(uvd, 0x0010, 0x0000); | ||
3314 | ibmcam_model3_Packet1(uvd, 0x0011, 0x0070); | ||
3315 | ibmcam_model3_Packet1(uvd, 0x0012, 0x0030); | ||
3316 | ibmcam_model3_Packet1(uvd, 0x0013, 0x0000); | ||
3317 | ibmcam_model3_Packet1(uvd, 0x0014, 0x0001); | ||
3318 | ibmcam_model3_Packet1(uvd, 0x0015, 0x0001); | ||
3319 | ibmcam_model3_Packet1(uvd, 0x0016, 0x0001); | ||
3320 | ibmcam_model3_Packet1(uvd, 0x0017, 0x0001); | ||
3321 | ibmcam_model3_Packet1(uvd, 0x0018, 0x0000); | ||
3322 | ibmcam_model3_Packet1(uvd, 0x001e, 0x00c3); | ||
3323 | ibmcam_model3_Packet1(uvd, 0x0020, 0x0000); | ||
3324 | ibmcam_model3_Packet1(uvd, 0x0028, 0x0010); | ||
3325 | ibmcam_model3_Packet1(uvd, 0x0029, 0x0054); | ||
3326 | ibmcam_model3_Packet1(uvd, 0x002a, 0x0013); | ||
3327 | ibmcam_model3_Packet1(uvd, 0x002b, 0x0007); | ||
3328 | ibmcam_model3_Packet1(uvd, 0x002d, 0x0028); | ||
3329 | ibmcam_model3_Packet1(uvd, 0x002e, 0x0000); | ||
3330 | ibmcam_model3_Packet1(uvd, 0x0031, 0x0000); | ||
3331 | ibmcam_model3_Packet1(uvd, 0x0032, 0x0000); | ||
3332 | ibmcam_model3_Packet1(uvd, 0x0033, 0x0000); | ||
3333 | ibmcam_model3_Packet1(uvd, 0x0034, 0x0000); | ||
3334 | ibmcam_model3_Packet1(uvd, 0x0035, 0x0038); | ||
3335 | ibmcam_model3_Packet1(uvd, 0x003a, 0x0001); | ||
3336 | ibmcam_model3_Packet1(uvd, 0x003c, 0x001e); | ||
3337 | ibmcam_model3_Packet1(uvd, 0x003f, 0x000a); | ||
3338 | ibmcam_model3_Packet1(uvd, 0x0041, 0x0000); | ||
3339 | ibmcam_model3_Packet1(uvd, 0x0046, 0x003f); | ||
3340 | ibmcam_model3_Packet1(uvd, 0x0047, 0x0000); | ||
3341 | ibmcam_model3_Packet1(uvd, 0x0050, 0x0005); | ||
3342 | ibmcam_model3_Packet1(uvd, 0x0052, 0x001a); | ||
3343 | ibmcam_model3_Packet1(uvd, 0x0053, 0x0003); | ||
3344 | ibmcam_model3_Packet1(uvd, 0x005a, 0x006b); | ||
3345 | ibmcam_model3_Packet1(uvd, 0x005d, 0x001e); | ||
3346 | ibmcam_model3_Packet1(uvd, 0x005e, 0x0030); | ||
3347 | ibmcam_model3_Packet1(uvd, 0x005f, 0x0041); | ||
3348 | ibmcam_model3_Packet1(uvd, 0x0064, 0x0008); | ||
3349 | ibmcam_model3_Packet1(uvd, 0x0065, 0x0015); | ||
3350 | ibmcam_model3_Packet1(uvd, 0x0068, 0x000f); | ||
3351 | ibmcam_model3_Packet1(uvd, 0x0079, 0x0000); | ||
3352 | ibmcam_model3_Packet1(uvd, 0x007a, 0x0000); | ||
3353 | ibmcam_model3_Packet1(uvd, 0x007c, 0x003f); | ||
3354 | ibmcam_model3_Packet1(uvd, 0x0082, 0x000f); | ||
3355 | ibmcam_model3_Packet1(uvd, 0x0085, 0x0000); | ||
3356 | ibmcam_model3_Packet1(uvd, 0x0099, 0x0000); | ||
3357 | ibmcam_model3_Packet1(uvd, 0x009b, 0x0023); | ||
3358 | ibmcam_model3_Packet1(uvd, 0x009c, 0x0022); | ||
3359 | ibmcam_model3_Packet1(uvd, 0x009d, 0x0096); | ||
3360 | ibmcam_model3_Packet1(uvd, 0x009e, 0x0096); | ||
3361 | ibmcam_model3_Packet1(uvd, 0x009f, 0x000a); | ||
3362 | |||
3363 | switch (uvd->videosize) { | ||
3364 | case VIDEOSIZE_160x120: | ||
3365 | ibmcam_veio(uvd, 0, 0x0000, 0x0101); /* Same on 176x144, 320x240 */ | ||
3366 | ibmcam_veio(uvd, 0, 0x00a0, 0x0103); /* Same on 176x144, 320x240 */ | ||
3367 | ibmcam_veio(uvd, 0, 0x0078, 0x0105); /* Same on 176x144, 320x240 */ | ||
3368 | ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */ | ||
3369 | ibmcam_veio(uvd, 0, 0x0024, 0x010b); /* Differs everywhere */ | ||
3370 | ibmcam_veio(uvd, 0, 0x00a9, 0x0119); | ||
3371 | ibmcam_veio(uvd, 0, 0x0016, 0x011b); | ||
3372 | ibmcam_veio(uvd, 0, 0x0002, 0x011d); /* Same on 176x144, 320x240 */ | ||
3373 | ibmcam_veio(uvd, 0, 0x0003, 0x011e); /* Same on 176x144, 640x480 */ | ||
3374 | ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */ | ||
3375 | ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */ | ||
3376 | ibmcam_veio(uvd, 0, 0x0018, 0x0102); | ||
3377 | ibmcam_veio(uvd, 0, 0x0004, 0x0104); | ||
3378 | ibmcam_veio(uvd, 0, 0x0004, 0x011a); | ||
3379 | ibmcam_veio(uvd, 0, 0x0028, 0x011c); | ||
3380 | ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */ | ||
3381 | ibmcam_veio(uvd, 0, 0x0000, 0x0118); | ||
3382 | ibmcam_veio(uvd, 0, 0x0000, 0x0132); | ||
3383 | ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */ | ||
3384 | ibmcam_veio(uvd, 0, compression, 0x0109); | ||
3385 | break; | ||
3386 | case VIDEOSIZE_320x240: | ||
3387 | ibmcam_veio(uvd, 0, 0x0000, 0x0101); /* Same on 176x144, 320x240 */ | ||
3388 | ibmcam_veio(uvd, 0, 0x00a0, 0x0103); /* Same on 176x144, 320x240 */ | ||
3389 | ibmcam_veio(uvd, 0, 0x0078, 0x0105); /* Same on 176x144, 320x240 */ | ||
3390 | ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */ | ||
3391 | ibmcam_veio(uvd, 0, 0x0028, 0x010b); /* Differs everywhere */ | ||
3392 | ibmcam_veio(uvd, 0, 0x0002, 0x011d); /* Same */ | ||
3393 | ibmcam_veio(uvd, 0, 0x0000, 0x011e); | ||
3394 | ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */ | ||
3395 | ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */ | ||
3396 | /* 4 commands from 160x120 skipped */ | ||
3397 | ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */ | ||
3398 | ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */ | ||
3399 | ibmcam_veio(uvd, 0, compression, 0x0109); | ||
3400 | ibmcam_veio(uvd, 0, 0x00d9, 0x0119); | ||
3401 | ibmcam_veio(uvd, 0, 0x0006, 0x011b); | ||
3402 | ibmcam_veio(uvd, 0, 0x0021, 0x0102); /* Same on 320x240, 640x480 */ | ||
3403 | ibmcam_veio(uvd, 0, 0x0010, 0x0104); | ||
3404 | ibmcam_veio(uvd, 0, 0x0004, 0x011a); | ||
3405 | ibmcam_veio(uvd, 0, 0x003f, 0x011c); | ||
3406 | ibmcam_veio(uvd, 0, 0x001c, 0x0118); | ||
3407 | ibmcam_veio(uvd, 0, 0x0000, 0x0132); | ||
3408 | break; | ||
3409 | case VIDEOSIZE_640x480: | ||
3410 | ibmcam_veio(uvd, 0, 0x00f0, 0x0105); | ||
3411 | ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */ | ||
3412 | ibmcam_veio(uvd, 0, 0x0038, 0x010b); /* Differs everywhere */ | ||
3413 | ibmcam_veio(uvd, 0, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */ | ||
3414 | ibmcam_veio(uvd, 0, 0x0006, 0x011b); /* Same on 320x240, 640x480 */ | ||
3415 | ibmcam_veio(uvd, 0, 0x0004, 0x011d); /* NC */ | ||
3416 | ibmcam_veio(uvd, 0, 0x0003, 0x011e); /* Same on 176x144, 640x480 */ | ||
3417 | ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */ | ||
3418 | ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */ | ||
3419 | ibmcam_veio(uvd, 0, 0x0021, 0x0102); /* Same on 320x240, 640x480 */ | ||
3420 | ibmcam_veio(uvd, 0, 0x0016, 0x0104); /* NC */ | ||
3421 | ibmcam_veio(uvd, 0, 0x0004, 0x011a); /* Same on 320x240, 640x480 */ | ||
3422 | ibmcam_veio(uvd, 0, 0x003f, 0x011c); /* Same on 320x240, 640x480 */ | ||
3423 | ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */ | ||
3424 | ibmcam_veio(uvd, 0, 0x001c, 0x0118); /* Same on 320x240, 640x480 */ | ||
3425 | ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */ | ||
3426 | ibmcam_veio(uvd, 0, compression, 0x0109); | ||
3427 | ibmcam_veio(uvd, 0, 0x0040, 0x0101); | ||
3428 | ibmcam_veio(uvd, 0, 0x0040, 0x0103); | ||
3429 | ibmcam_veio(uvd, 0, 0x0000, 0x0132); /* Same on 320x240, 640x480 */ | ||
3430 | break; | ||
3431 | } | ||
3432 | ibmcam_model3_Packet1(uvd, 0x007e, 0x000e); /* Hue */ | ||
3433 | ibmcam_model3_Packet1(uvd, 0x0036, 0x0011); /* Brightness */ | ||
3434 | ibmcam_model3_Packet1(uvd, 0x0060, 0x0002); /* Sharpness */ | ||
3435 | ibmcam_model3_Packet1(uvd, 0x0061, 0x0004); /* Sharpness */ | ||
3436 | ibmcam_model3_Packet1(uvd, 0x0062, 0x0005); /* Sharpness */ | ||
3437 | ibmcam_model3_Packet1(uvd, 0x0063, 0x0014); /* Sharpness */ | ||
3438 | ibmcam_model3_Packet1(uvd, 0x0096, 0x00a0); /* Red gain */ | ||
3439 | ibmcam_model3_Packet1(uvd, 0x0097, 0x0096); /* Blue gain */ | ||
3440 | ibmcam_model3_Packet1(uvd, 0x0067, 0x0001); /* Contrast */ | ||
3441 | ibmcam_model3_Packet1(uvd, 0x005b, 0x000c); /* Contrast */ | ||
3442 | ibmcam_model3_Packet1(uvd, 0x005c, 0x0016); /* Contrast */ | ||
3443 | ibmcam_model3_Packet1(uvd, 0x0098, 0x000b); | ||
3444 | ibmcam_model3_Packet1(uvd, 0x002c, 0x0003); /* Was 1, broke 640x480 */ | ||
3445 | ibmcam_model3_Packet1(uvd, 0x002f, 0x002a); | ||
3446 | ibmcam_model3_Packet1(uvd, 0x0030, 0x0029); | ||
3447 | ibmcam_model3_Packet1(uvd, 0x0037, 0x0002); | ||
3448 | ibmcam_model3_Packet1(uvd, 0x0038, 0x0059); | ||
3449 | ibmcam_model3_Packet1(uvd, 0x003d, 0x002e); | ||
3450 | ibmcam_model3_Packet1(uvd, 0x003e, 0x0028); | ||
3451 | ibmcam_model3_Packet1(uvd, 0x0078, 0x0005); | ||
3452 | ibmcam_model3_Packet1(uvd, 0x007b, 0x0011); | ||
3453 | ibmcam_model3_Packet1(uvd, 0x007d, 0x004b); | ||
3454 | ibmcam_model3_Packet1(uvd, 0x007f, 0x0022); | ||
3455 | ibmcam_model3_Packet1(uvd, 0x0080, 0x000c); | ||
3456 | ibmcam_model3_Packet1(uvd, 0x0081, 0x000b); | ||
3457 | ibmcam_model3_Packet1(uvd, 0x0083, 0x00fd); | ||
3458 | ibmcam_model3_Packet1(uvd, 0x0086, 0x000b); | ||
3459 | ibmcam_model3_Packet1(uvd, 0x0087, 0x000b); | ||
3460 | ibmcam_model3_Packet1(uvd, 0x007e, 0x000e); | ||
3461 | ibmcam_model3_Packet1(uvd, 0x0096, 0x00a0); /* Red gain */ | ||
3462 | ibmcam_model3_Packet1(uvd, 0x0097, 0x0096); /* Blue gain */ | ||
3463 | ibmcam_model3_Packet1(uvd, 0x0098, 0x000b); | ||
3464 | |||
3465 | switch (uvd->videosize) { | ||
3466 | case VIDEOSIZE_160x120: | ||
3467 | ibmcam_veio(uvd, 0, 0x0002, 0x0106); | ||
3468 | ibmcam_veio(uvd, 0, 0x0008, 0x0107); | ||
3469 | ibmcam_veio(uvd, 0, f_rate, 0x0111); /* Frame rate */ | ||
3470 | ibmcam_model3_Packet1(uvd, 0x001f, 0x0000); /* Same */ | ||
3471 | ibmcam_model3_Packet1(uvd, 0x0039, 0x001f); /* Same */ | ||
3472 | ibmcam_model3_Packet1(uvd, 0x003b, 0x003c); /* Same */ | ||
3473 | ibmcam_model3_Packet1(uvd, 0x0040, 0x000a); | ||
3474 | ibmcam_model3_Packet1(uvd, 0x0051, 0x000a); | ||
3475 | break; | ||
3476 | case VIDEOSIZE_320x240: | ||
3477 | ibmcam_veio(uvd, 0, 0x0003, 0x0106); | ||
3478 | ibmcam_veio(uvd, 0, 0x0062, 0x0107); | ||
3479 | ibmcam_veio(uvd, 0, f_rate, 0x0111); /* Frame rate */ | ||
3480 | ibmcam_model3_Packet1(uvd, 0x001f, 0x0000); /* Same */ | ||
3481 | ibmcam_model3_Packet1(uvd, 0x0039, 0x001f); /* Same */ | ||
3482 | ibmcam_model3_Packet1(uvd, 0x003b, 0x003c); /* Same */ | ||
3483 | ibmcam_model3_Packet1(uvd, 0x0040, 0x0008); | ||
3484 | ibmcam_model3_Packet1(uvd, 0x0051, 0x000b); | ||
3485 | break; | ||
3486 | case VIDEOSIZE_640x480: | ||
3487 | ibmcam_veio(uvd, 0, 0x0002, 0x0106); /* Adjustments */ | ||
3488 | ibmcam_veio(uvd, 0, 0x00b4, 0x0107); /* Adjustments */ | ||
3489 | ibmcam_veio(uvd, 0, f_rate, 0x0111); /* Frame rate */ | ||
3490 | ibmcam_model3_Packet1(uvd, 0x001f, 0x0002); /* !Same */ | ||
3491 | ibmcam_model3_Packet1(uvd, 0x0039, 0x003e); /* !Same */ | ||
3492 | ibmcam_model3_Packet1(uvd, 0x0040, 0x0008); | ||
3493 | ibmcam_model3_Packet1(uvd, 0x0051, 0x000a); | ||
3494 | break; | ||
3495 | } | ||
3496 | |||
3497 | /* 01.01.08 - Added for RCA video in support -LO */ | ||
3498 | if(init_model3_input) { | ||
3499 | if (debug > 0) | ||
3500 | dev_info(&uvd->dev->dev, "Setting input to RCA.\n"); | ||
3501 | for (i=0; i < ARRAY_SIZE(initData); i++) { | ||
3502 | ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index); | ||
3503 | } | ||
3504 | } | ||
3505 | |||
3506 | ibmcam_veio(uvd, 0, 0x0001, 0x0114); | ||
3507 | ibmcam_veio(uvd, 0, 0x00c0, 0x010c); | ||
3508 | usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp)); | ||
3509 | } | ||
3510 | |||
3511 | /* | ||
3512 | * ibmcam_video_stop() | ||
3513 | * | ||
3514 | * This code tells camera to stop streaming. The interface remains | ||
3515 | * configured and bandwidth - claimed. | ||
3516 | */ | ||
3517 | static void ibmcam_video_stop(struct uvd *uvd) | ||
3518 | { | ||
3519 | switch (IBMCAM_T(uvd)->camera_model) { | ||
3520 | case IBMCAM_MODEL_1: | ||
3521 | ibmcam_veio(uvd, 0, 0x00, 0x010c); | ||
3522 | ibmcam_veio(uvd, 0, 0x00, 0x010c); | ||
3523 | ibmcam_veio(uvd, 0, 0x01, 0x0114); | ||
3524 | ibmcam_veio(uvd, 0, 0xc0, 0x010c); | ||
3525 | ibmcam_veio(uvd, 0, 0x00, 0x010c); | ||
3526 | ibmcam_send_FF_04_02(uvd); | ||
3527 | ibmcam_veio(uvd, 1, 0x00, 0x0100); | ||
3528 | ibmcam_veio(uvd, 0, 0x81, 0x0100); /* LED Off */ | ||
3529 | break; | ||
3530 | case IBMCAM_MODEL_2: | ||
3531 | case IBMCAM_MODEL_4: | ||
3532 | ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop the camera */ | ||
3533 | |||
3534 | ibmcam_model2_Packet1(uvd, 0x0030, 0x0004); | ||
3535 | |||
3536 | ibmcam_veio(uvd, 0, 0x0080, 0x0100); /* LED Off */ | ||
3537 | ibmcam_veio(uvd, 0, 0x0020, 0x0111); | ||
3538 | ibmcam_veio(uvd, 0, 0x00a0, 0x0111); | ||
3539 | |||
3540 | ibmcam_model2_Packet1(uvd, 0x0030, 0x0002); | ||
3541 | |||
3542 | ibmcam_veio(uvd, 0, 0x0020, 0x0111); | ||
3543 | ibmcam_veio(uvd, 0, 0x0000, 0x0112); | ||
3544 | break; | ||
3545 | case IBMCAM_MODEL_3: | ||
3546 | #if 1 | ||
3547 | ibmcam_veio(uvd, 0, 0x0000, 0x010c); | ||
3548 | |||
3549 | /* Here we are supposed to select video interface alt. setting 0 */ | ||
3550 | ibmcam_veio(uvd, 0, 0x0006, 0x012c); | ||
3551 | |||
3552 | ibmcam_model3_Packet1(uvd, 0x0046, 0x0000); | ||
3553 | |||
3554 | ibmcam_veio(uvd, 1, 0x0000, 0x0116); | ||
3555 | ibmcam_veio(uvd, 0, 0x0064, 0x0116); | ||
3556 | ibmcam_veio(uvd, 1, 0x0000, 0x0115); | ||
3557 | ibmcam_veio(uvd, 0, 0x0003, 0x0115); | ||
3558 | ibmcam_veio(uvd, 0, 0x0008, 0x0123); | ||
3559 | ibmcam_veio(uvd, 0, 0x0000, 0x0117); | ||
3560 | ibmcam_veio(uvd, 0, 0x0000, 0x0112); | ||
3561 | ibmcam_veio(uvd, 0, 0x0080, 0x0100); | ||
3562 | IBMCAM_T(uvd)->initialized = 0; | ||
3563 | #endif | ||
3564 | break; | ||
3565 | } /* switch */ | ||
3566 | } | ||
3567 | |||
3568 | /* | ||
3569 | * ibmcam_reinit_iso() | ||
3570 | * | ||
3571 | * This procedure sends couple of commands to the camera and then | ||
3572 | * resets the video pipe. This sequence was observed to reinit the | ||
3573 | * camera or, at least, to initiate ISO data stream. | ||
3574 | * | ||
3575 | * History: | ||
3576 | * 1/2/00 Created. | ||
3577 | */ | ||
3578 | static void ibmcam_reinit_iso(struct uvd *uvd, int do_stop) | ||
3579 | { | ||
3580 | switch (IBMCAM_T(uvd)->camera_model) { | ||
3581 | case IBMCAM_MODEL_1: | ||
3582 | if (do_stop) | ||
3583 | ibmcam_video_stop(uvd); | ||
3584 | ibmcam_veio(uvd, 0, 0x0001, 0x0114); | ||
3585 | ibmcam_veio(uvd, 0, 0x00c0, 0x010c); | ||
3586 | usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp)); | ||
3587 | ibmcam_model1_setup_after_video_if(uvd); | ||
3588 | break; | ||
3589 | case IBMCAM_MODEL_2: | ||
3590 | ibmcam_model2_setup_after_video_if(uvd); | ||
3591 | break; | ||
3592 | case IBMCAM_MODEL_3: | ||
3593 | ibmcam_video_stop(uvd); | ||
3594 | ibmcam_model3_setup_after_video_if(uvd); | ||
3595 | break; | ||
3596 | case IBMCAM_MODEL_4: | ||
3597 | ibmcam_model4_setup_after_video_if(uvd); | ||
3598 | break; | ||
3599 | } | ||
3600 | } | ||
3601 | |||
3602 | static void ibmcam_video_start(struct uvd *uvd) | ||
3603 | { | ||
3604 | ibmcam_change_lighting_conditions(uvd); | ||
3605 | ibmcam_set_sharpness(uvd); | ||
3606 | ibmcam_reinit_iso(uvd, 0); | ||
3607 | } | ||
3608 | |||
3609 | /* | ||
3610 | * Return negative code on failure, 0 on success. | ||
3611 | */ | ||
3612 | static int ibmcam_setup_on_open(struct uvd *uvd) | ||
3613 | { | ||
3614 | int setup_ok = 0; /* Success by default */ | ||
3615 | /* Send init sequence only once, it's large! */ | ||
3616 | if (!IBMCAM_T(uvd)->initialized) { /* FIXME rename */ | ||
3617 | switch (IBMCAM_T(uvd)->camera_model) { | ||
3618 | case IBMCAM_MODEL_1: | ||
3619 | setup_ok = ibmcam_model1_setup(uvd); | ||
3620 | break; | ||
3621 | case IBMCAM_MODEL_2: | ||
3622 | setup_ok = ibmcam_model2_setup(uvd); | ||
3623 | break; | ||
3624 | case IBMCAM_MODEL_3: | ||
3625 | case IBMCAM_MODEL_4: | ||
3626 | /* We do all setup when Isoc stream is requested */ | ||
3627 | break; | ||
3628 | } | ||
3629 | IBMCAM_T(uvd)->initialized = (setup_ok != 0); | ||
3630 | } | ||
3631 | return setup_ok; | ||
3632 | } | ||
3633 | |||
3634 | static void ibmcam_configure_video(struct uvd *uvd) | ||
3635 | { | ||
3636 | if (uvd == NULL) | ||
3637 | return; | ||
3638 | |||
3639 | RESTRICT_TO_RANGE(init_brightness, 0, 255); | ||
3640 | RESTRICT_TO_RANGE(init_contrast, 0, 255); | ||
3641 | RESTRICT_TO_RANGE(init_color, 0, 255); | ||
3642 | RESTRICT_TO_RANGE(init_hue, 0, 255); | ||
3643 | RESTRICT_TO_RANGE(hue_correction, 0, 255); | ||
3644 | |||
3645 | memset(&uvd->vpic, 0, sizeof(uvd->vpic)); | ||
3646 | memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old)); | ||
3647 | |||
3648 | uvd->vpic.colour = init_color << 8; | ||
3649 | uvd->vpic.hue = init_hue << 8; | ||
3650 | uvd->vpic.brightness = init_brightness << 8; | ||
3651 | uvd->vpic.contrast = init_contrast << 8; | ||
3652 | uvd->vpic.whiteness = 105 << 8; /* This one isn't used */ | ||
3653 | uvd->vpic.depth = 24; | ||
3654 | uvd->vpic.palette = VIDEO_PALETTE_RGB24; | ||
3655 | |||
3656 | memset(&uvd->vcap, 0, sizeof(uvd->vcap)); | ||
3657 | strcpy(uvd->vcap.name, "IBM USB Camera"); | ||
3658 | uvd->vcap.type = VID_TYPE_CAPTURE; | ||
3659 | uvd->vcap.channels = 1; | ||
3660 | uvd->vcap.audios = 0; | ||
3661 | uvd->vcap.maxwidth = VIDEOSIZE_X(uvd->canvas); | ||
3662 | uvd->vcap.maxheight = VIDEOSIZE_Y(uvd->canvas); | ||
3663 | uvd->vcap.minwidth = min_canvasWidth; | ||
3664 | uvd->vcap.minheight = min_canvasHeight; | ||
3665 | |||
3666 | memset(&uvd->vchan, 0, sizeof(uvd->vchan)); | ||
3667 | uvd->vchan.flags = 0; | ||
3668 | uvd->vchan.tuners = 0; | ||
3669 | uvd->vchan.channel = 0; | ||
3670 | uvd->vchan.type = VIDEO_TYPE_CAMERA; | ||
3671 | strcpy(uvd->vchan.name, "Camera"); | ||
3672 | } | ||
3673 | |||
3674 | /* | ||
3675 | * ibmcam_probe() | ||
3676 | * | ||
3677 | * This procedure queries device descriptor and accepts the interface | ||
3678 | * if it looks like IBM C-it camera. | ||
3679 | * | ||
3680 | * History: | ||
3681 | * 22-Jan-2000 Moved camera init code to ibmcam_open() | ||
3682 | * 27=Jan-2000 Changed to use static structures, added locking. | ||
3683 | * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT). | ||
3684 | * 03-Jul-2000 Fixed endianness bug. | ||
3685 | * 12-Nov-2000 Reworked to comply with new probe() signature. | ||
3686 | * 23-Jan-2001 Added compatibility with 2.2.x kernels. | ||
3687 | */ | ||
3688 | static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id *devid) | ||
3689 | { | ||
3690 | struct usb_device *dev = interface_to_usbdev(intf); | ||
3691 | struct uvd *uvd = NULL; | ||
3692 | int ix, i, nas, model=0, canvasX=0, canvasY=0; | ||
3693 | int actInterface=-1, inactInterface=-1, maxPS=0; | ||
3694 | __u8 ifnum = intf->altsetting->desc.bInterfaceNumber; | ||
3695 | unsigned char video_ep = 0; | ||
3696 | |||
3697 | if (debug >= 1) | ||
3698 | dev_info(&dev->dev, "ibmcam_probe(%p,%u.)\n", intf, ifnum); | ||
3699 | |||
3700 | /* We don't handle multi-config cameras */ | ||
3701 | if (dev->descriptor.bNumConfigurations != 1) | ||
3702 | return -ENODEV; | ||
3703 | |||
3704 | /* Check the version/revision */ | ||
3705 | switch (le16_to_cpu(dev->descriptor.bcdDevice)) { | ||
3706 | case 0x0002: | ||
3707 | if (ifnum != 2) | ||
3708 | return -ENODEV; | ||
3709 | model = IBMCAM_MODEL_1; | ||
3710 | break; | ||
3711 | case 0x030A: | ||
3712 | if (ifnum != 0) | ||
3713 | return -ENODEV; | ||
3714 | if ((le16_to_cpu(dev->descriptor.idProduct) == NETCAM_PRODUCT_ID) || | ||
3715 | (le16_to_cpu(dev->descriptor.idProduct) == VEO_800D_PRODUCT_ID)) | ||
3716 | model = IBMCAM_MODEL_4; | ||
3717 | else | ||
3718 | model = IBMCAM_MODEL_2; | ||
3719 | break; | ||
3720 | case 0x0301: | ||
3721 | if (ifnum != 0) | ||
3722 | return -ENODEV; | ||
3723 | model = IBMCAM_MODEL_3; | ||
3724 | break; | ||
3725 | default: | ||
3726 | err("IBM camera with revision 0x%04x is not supported.", | ||
3727 | le16_to_cpu(dev->descriptor.bcdDevice)); | ||
3728 | return -ENODEV; | ||
3729 | } | ||
3730 | |||
3731 | /* Print detailed info on what we found so far */ | ||
3732 | do { | ||
3733 | char *brand = NULL; | ||
3734 | switch (le16_to_cpu(dev->descriptor.idProduct)) { | ||
3735 | case NETCAM_PRODUCT_ID: | ||
3736 | brand = "IBM NetCamera"; | ||
3737 | break; | ||
3738 | case VEO_800C_PRODUCT_ID: | ||
3739 | brand = "Veo Stingray [800C]"; | ||
3740 | break; | ||
3741 | case VEO_800D_PRODUCT_ID: | ||
3742 | brand = "Veo Stingray [800D]"; | ||
3743 | break; | ||
3744 | case IBMCAM_PRODUCT_ID: | ||
3745 | default: | ||
3746 | brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */ | ||
3747 | break; | ||
3748 | } | ||
3749 | dev_info(&dev->dev, | ||
3750 | "%s USB camera found (model %d, rev. 0x%04x)\n", | ||
3751 | brand, model, le16_to_cpu(dev->descriptor.bcdDevice)); | ||
3752 | } while (0); | ||
3753 | |||
3754 | /* Validate found interface: must have one ISO endpoint */ | ||
3755 | nas = intf->num_altsetting; | ||
3756 | if (debug > 0) | ||
3757 | dev_info(&dev->dev, "Number of alternate settings=%d.\n", | ||
3758 | nas); | ||
3759 | if (nas < 2) { | ||
3760 | err("Too few alternate settings for this camera!"); | ||
3761 | return -ENODEV; | ||
3762 | } | ||
3763 | /* Validate all alternate settings */ | ||
3764 | for (ix=0; ix < nas; ix++) { | ||
3765 | const struct usb_host_interface *interface; | ||
3766 | const struct usb_endpoint_descriptor *endpoint; | ||
3767 | |||
3768 | interface = &intf->altsetting[ix]; | ||
3769 | i = interface->desc.bAlternateSetting; | ||
3770 | if (interface->desc.bNumEndpoints != 1) { | ||
3771 | err("Interface %d. has %u. endpoints!", | ||
3772 | ifnum, (unsigned)(interface->desc.bNumEndpoints)); | ||
3773 | return -ENODEV; | ||
3774 | } | ||
3775 | endpoint = &interface->endpoint[0].desc; | ||
3776 | if (video_ep == 0) | ||
3777 | video_ep = endpoint->bEndpointAddress; | ||
3778 | else if (video_ep != endpoint->bEndpointAddress) { | ||
3779 | err("Alternate settings have different endpoint addresses!"); | ||
3780 | return -ENODEV; | ||
3781 | } | ||
3782 | if (!usb_endpoint_xfer_isoc(endpoint)) { | ||
3783 | err("Interface %d. has non-ISO endpoint!", ifnum); | ||
3784 | return -ENODEV; | ||
3785 | } | ||
3786 | if (usb_endpoint_dir_out(endpoint)) { | ||
3787 | err("Interface %d. has ISO OUT endpoint!", ifnum); | ||
3788 | return -ENODEV; | ||
3789 | } | ||
3790 | if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) { | ||
3791 | if (inactInterface < 0) | ||
3792 | inactInterface = i; | ||
3793 | else { | ||
3794 | err("More than one inactive alt. setting!"); | ||
3795 | return -ENODEV; | ||
3796 | } | ||
3797 | } else { | ||
3798 | if (actInterface < 0) { | ||
3799 | actInterface = i; | ||
3800 | maxPS = le16_to_cpu(endpoint->wMaxPacketSize); | ||
3801 | if (debug > 0) | ||
3802 | dev_info(&dev->dev, | ||
3803 | "Active setting=%d. " | ||
3804 | "maxPS=%d.\n", i, maxPS); | ||
3805 | } else | ||
3806 | err("More than one active alt. setting! Ignoring #%d.", i); | ||
3807 | } | ||
3808 | } | ||
3809 | if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) { | ||
3810 | err("Failed to recognize the camera!"); | ||
3811 | return -ENODEV; | ||
3812 | } | ||
3813 | |||
3814 | /* Validate options */ | ||
3815 | switch (model) { | ||
3816 | case IBMCAM_MODEL_1: | ||
3817 | RESTRICT_TO_RANGE(lighting, 0, 2); | ||
3818 | RESTRICT_TO_RANGE(size, SIZE_128x96, SIZE_352x288); | ||
3819 | if (framerate < 0) | ||
3820 | framerate = 2; | ||
3821 | canvasX = 352; | ||
3822 | canvasY = 288; | ||
3823 | break; | ||
3824 | case IBMCAM_MODEL_2: | ||
3825 | RESTRICT_TO_RANGE(lighting, 0, 15); | ||
3826 | RESTRICT_TO_RANGE(size, SIZE_176x144, SIZE_352x240); | ||
3827 | if (framerate < 0) | ||
3828 | framerate = 2; | ||
3829 | canvasX = 352; | ||
3830 | canvasY = 240; | ||
3831 | break; | ||
3832 | case IBMCAM_MODEL_3: | ||
3833 | RESTRICT_TO_RANGE(lighting, 0, 15); /* FIXME */ | ||
3834 | switch (size) { | ||
3835 | case SIZE_160x120: | ||
3836 | canvasX = 160; | ||
3837 | canvasY = 120; | ||
3838 | if (framerate < 0) | ||
3839 | framerate = 2; | ||
3840 | RESTRICT_TO_RANGE(framerate, 0, 5); | ||
3841 | break; | ||
3842 | default: | ||
3843 | dev_info(&dev->dev, "IBM camera: using 320x240\n"); | ||
3844 | size = SIZE_320x240; | ||
3845 | /* No break here */ | ||
3846 | case SIZE_320x240: | ||
3847 | canvasX = 320; | ||
3848 | canvasY = 240; | ||
3849 | if (framerate < 0) | ||
3850 | framerate = 3; | ||
3851 | RESTRICT_TO_RANGE(framerate, 0, 5); | ||
3852 | break; | ||
3853 | case SIZE_640x480: | ||
3854 | canvasX = 640; | ||
3855 | canvasY = 480; | ||
3856 | framerate = 0; /* Slowest, and maybe even that is too fast */ | ||
3857 | break; | ||
3858 | } | ||
3859 | break; | ||
3860 | case IBMCAM_MODEL_4: | ||
3861 | RESTRICT_TO_RANGE(lighting, 0, 2); | ||
3862 | switch (size) { | ||
3863 | case SIZE_128x96: | ||
3864 | canvasX = 128; | ||
3865 | canvasY = 96; | ||
3866 | break; | ||
3867 | case SIZE_160x120: | ||
3868 | canvasX = 160; | ||
3869 | canvasY = 120; | ||
3870 | break; | ||
3871 | default: | ||
3872 | dev_info(&dev->dev, "IBM NetCamera: using 176x144\n"); | ||
3873 | size = SIZE_176x144; | ||
3874 | /* No break here */ | ||
3875 | case SIZE_176x144: | ||
3876 | canvasX = 176; | ||
3877 | canvasY = 144; | ||
3878 | break; | ||
3879 | case SIZE_320x240: | ||
3880 | canvasX = 320; | ||
3881 | canvasY = 240; | ||
3882 | break; | ||
3883 | case SIZE_352x288: | ||
3884 | canvasX = 352; | ||
3885 | canvasY = 288; | ||
3886 | break; | ||
3887 | } | ||
3888 | break; | ||
3889 | default: | ||
3890 | err("IBM camera: Model %d. not supported!", model); | ||
3891 | return -ENODEV; | ||
3892 | } | ||
3893 | |||
3894 | uvd = usbvideo_AllocateDevice(cams); | ||
3895 | if (uvd != NULL) { | ||
3896 | /* Here uvd is a fully allocated uvd object */ | ||
3897 | uvd->flags = flags; | ||
3898 | uvd->debug = debug; | ||
3899 | uvd->dev = dev; | ||
3900 | uvd->iface = ifnum; | ||
3901 | uvd->ifaceAltInactive = inactInterface; | ||
3902 | uvd->ifaceAltActive = actInterface; | ||
3903 | uvd->video_endp = video_ep; | ||
3904 | uvd->iso_packet_len = maxPS; | ||
3905 | uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24; | ||
3906 | uvd->defaultPalette = VIDEO_PALETTE_RGB24; | ||
3907 | uvd->canvas = VIDEOSIZE(canvasX, canvasY); | ||
3908 | uvd->videosize = ibmcam_size_to_videosize(size); | ||
3909 | |||
3910 | /* Initialize ibmcam-specific data */ | ||
3911 | assert(IBMCAM_T(uvd) != NULL); | ||
3912 | IBMCAM_T(uvd)->camera_model = model; | ||
3913 | IBMCAM_T(uvd)->initialized = 0; | ||
3914 | |||
3915 | ibmcam_configure_video(uvd); | ||
3916 | |||
3917 | i = usbvideo_RegisterVideoDevice(uvd); | ||
3918 | if (i != 0) { | ||
3919 | err("usbvideo_RegisterVideoDevice() failed."); | ||
3920 | uvd = NULL; | ||
3921 | } | ||
3922 | } | ||
3923 | usb_set_intfdata (intf, uvd); | ||
3924 | return 0; | ||
3925 | } | ||
3926 | |||
3927 | |||
3928 | static struct usb_device_id id_table[] = { | ||
3929 | { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0002, 0x0002) }, /* Model 1 */ | ||
3930 | { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */ | ||
3931 | { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0301, 0x0301) }, /* Model 3 */ | ||
3932 | { USB_DEVICE_VER(IBMCAM_VENDOR_ID, NETCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */ | ||
3933 | { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800C_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */ | ||
3934 | { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800D_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */ | ||
3935 | { } /* Terminating entry */ | ||
3936 | }; | ||
3937 | |||
3938 | /* | ||
3939 | * ibmcam_init() | ||
3940 | * | ||
3941 | * This code is run to initialize the driver. | ||
3942 | * | ||
3943 | * History: | ||
3944 | * 1/27/00 Reworked to use statically allocated ibmcam structures. | ||
3945 | * 21/10/00 Completely redesigned to use usbvideo services. | ||
3946 | */ | ||
3947 | static int __init ibmcam_init(void) | ||
3948 | { | ||
3949 | struct usbvideo_cb cbTbl; | ||
3950 | memset(&cbTbl, 0, sizeof(cbTbl)); | ||
3951 | cbTbl.probe = ibmcam_probe; | ||
3952 | cbTbl.setupOnOpen = ibmcam_setup_on_open; | ||
3953 | cbTbl.videoStart = ibmcam_video_start; | ||
3954 | cbTbl.videoStop = ibmcam_video_stop; | ||
3955 | cbTbl.processData = ibmcam_ProcessIsocData; | ||
3956 | cbTbl.postProcess = usbvideo_DeinterlaceFrame; | ||
3957 | cbTbl.adjustPicture = ibmcam_adjust_picture; | ||
3958 | cbTbl.getFPS = ibmcam_calculate_fps; | ||
3959 | return usbvideo_register( | ||
3960 | &cams, | ||
3961 | MAX_IBMCAM, | ||
3962 | sizeof(ibmcam_t), | ||
3963 | "ibmcam", | ||
3964 | &cbTbl, | ||
3965 | THIS_MODULE, | ||
3966 | id_table); | ||
3967 | } | ||
3968 | |||
3969 | static void __exit ibmcam_cleanup(void) | ||
3970 | { | ||
3971 | usbvideo_Deregister(&cams); | ||
3972 | } | ||
3973 | |||
3974 | MODULE_DEVICE_TABLE(usb, id_table); | ||
3975 | |||
3976 | module_init(ibmcam_init); | ||
3977 | module_exit(ibmcam_cleanup); | ||
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c deleted file mode 100644 index 562e1d170be0..000000000000 --- a/drivers/media/video/usbvideo/konicawc.c +++ /dev/null | |||
@@ -1,992 +0,0 @@ | |||
1 | /* | ||
2 | * konicawc.c - konica webcam driver | ||
3 | * | ||
4 | * Author: Simon Evans <spse@secret.org.uk> | ||
5 | * | ||
6 | * Copyright (C) 2002 Simon Evans | ||
7 | * | ||
8 | * Licence: GPL | ||
9 | * | ||
10 | * Driver for USB webcams based on Konica chipset. This | ||
11 | * chipset is used in Intel YC76 camera. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/usb/input.h> | ||
19 | #include <linux/gfp.h> | ||
20 | |||
21 | #include "usbvideo.h" | ||
22 | |||
23 | #define MAX_BRIGHTNESS 108 | ||
24 | #define MAX_CONTRAST 108 | ||
25 | #define MAX_SATURATION 108 | ||
26 | #define MAX_SHARPNESS 108 | ||
27 | #define MAX_WHITEBAL 372 | ||
28 | #define MAX_SPEED 6 | ||
29 | |||
30 | |||
31 | #define MAX_CAMERAS 1 | ||
32 | |||
33 | #define DRIVER_VERSION "v1.4" | ||
34 | #define DRIVER_DESC "Konica Webcam driver" | ||
35 | |||
36 | enum ctrl_req { | ||
37 | SetWhitebal = 0x01, | ||
38 | SetBrightness = 0x02, | ||
39 | SetSharpness = 0x03, | ||
40 | SetContrast = 0x04, | ||
41 | SetSaturation = 0x05, | ||
42 | }; | ||
43 | |||
44 | |||
45 | enum frame_sizes { | ||
46 | SIZE_160X120 = 0, | ||
47 | SIZE_160X136 = 1, | ||
48 | SIZE_176X144 = 2, | ||
49 | SIZE_320X240 = 3, | ||
50 | |||
51 | }; | ||
52 | |||
53 | #define MAX_FRAME_SIZE SIZE_320X240 | ||
54 | |||
55 | static struct usbvideo *cams; | ||
56 | |||
57 | #ifdef CONFIG_USB_DEBUG | ||
58 | static int debug; | ||
59 | #define DEBUG(n, format, arg...) \ | ||
60 | if (n <= debug) { \ | ||
61 | printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \ | ||
62 | } | ||
63 | #else | ||
64 | #define DEBUG(n, arg...) | ||
65 | static const int debug; | ||
66 | #endif | ||
67 | |||
68 | |||
69 | /* Some default values for initial camera settings, | ||
70 | can be set by modprobe */ | ||
71 | |||
72 | static int size; | ||
73 | static int speed = 6; /* Speed (fps) 0 (slowest) to 6 (fastest) */ | ||
74 | static int brightness = MAX_BRIGHTNESS/2; | ||
75 | static int contrast = MAX_CONTRAST/2; | ||
76 | static int saturation = MAX_SATURATION/2; | ||
77 | static int sharpness = MAX_SHARPNESS/2; | ||
78 | static int whitebal = 3*(MAX_WHITEBAL/4); | ||
79 | |||
80 | static const int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 }; | ||
81 | |||
82 | /* These FPS speeds are from the windows config box. They are | ||
83 | * indexed on size (0-2) and speed (0-6). Divide by 3 to get the | ||
84 | * real fps. | ||
85 | */ | ||
86 | |||
87 | static const int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 }, | ||
88 | { 24, 40, 48, 60, 72, 80, 100 }, | ||
89 | { 18, 30, 36, 45, 54, 60, 75 }, | ||
90 | { 6, 10, 12, 15, 18, 21, 25 } }; | ||
91 | |||
92 | struct cam_size { | ||
93 | u16 width; | ||
94 | u16 height; | ||
95 | u8 cmd; | ||
96 | }; | ||
97 | |||
98 | static const struct cam_size camera_sizes[] = { { 160, 120, 0x7 }, | ||
99 | { 160, 136, 0xa }, | ||
100 | { 176, 144, 0x4 }, | ||
101 | { 320, 240, 0x5 } }; | ||
102 | |||
103 | struct konicawc { | ||
104 | u8 brightness; /* camera uses 0 - 9, x11 for real value */ | ||
105 | u8 contrast; /* as above */ | ||
106 | u8 saturation; /* as above */ | ||
107 | u8 sharpness; /* as above */ | ||
108 | u8 white_bal; /* 0 - 33, x11 for real value */ | ||
109 | u8 speed; /* Stored as 0 - 6, used as index in spd_to_* (above) */ | ||
110 | u8 size; /* Frame Size */ | ||
111 | int height; | ||
112 | int width; | ||
113 | struct urb *sts_urb[USBVIDEO_NUMSBUF]; | ||
114 | u8 sts_buf[USBVIDEO_NUMSBUF][FRAMES_PER_DESC]; | ||
115 | struct urb *last_data_urb; | ||
116 | int lastframe; | ||
117 | int cur_frame_size; /* number of bytes in current frame size */ | ||
118 | int maxline; /* number of lines per frame */ | ||
119 | int yplanesz; /* Number of bytes in the Y plane */ | ||
120 | unsigned int buttonsts:1; | ||
121 | #ifdef CONFIG_INPUT | ||
122 | struct input_dev *input; | ||
123 | char input_physname[64]; | ||
124 | #endif | ||
125 | }; | ||
126 | |||
127 | |||
128 | #define konicawc_set_misc(uvd, req, value, index) konicawc_ctrl_msg(uvd, USB_DIR_OUT, req, value, index, NULL, 0) | ||
129 | #define konicawc_get_misc(uvd, req, value, index, buf, sz) konicawc_ctrl_msg(uvd, USB_DIR_IN, req, value, index, buf, sz) | ||
130 | #define konicawc_set_value(uvd, value, index) konicawc_ctrl_msg(uvd, USB_DIR_OUT, 2, value, index, NULL, 0) | ||
131 | |||
132 | |||
133 | static int konicawc_ctrl_msg(struct uvd *uvd, u8 dir, u8 request, u16 value, u16 index, void *buf, int len) | ||
134 | { | ||
135 | int retval = usb_control_msg(uvd->dev, | ||
136 | dir ? usb_rcvctrlpipe(uvd->dev, 0) : usb_sndctrlpipe(uvd->dev, 0), | ||
137 | request, 0x40 | dir, value, index, buf, len, 1000); | ||
138 | return retval < 0 ? retval : 0; | ||
139 | } | ||
140 | |||
141 | |||
142 | static inline void konicawc_camera_on(struct uvd *uvd) | ||
143 | { | ||
144 | DEBUG(0, "camera on"); | ||
145 | konicawc_set_misc(uvd, 0x2, 1, 0x0b); | ||
146 | } | ||
147 | |||
148 | |||
149 | static inline void konicawc_camera_off(struct uvd *uvd) | ||
150 | { | ||
151 | DEBUG(0, "camera off"); | ||
152 | konicawc_set_misc(uvd, 0x2, 0, 0x0b); | ||
153 | } | ||
154 | |||
155 | |||
156 | static void konicawc_set_camera_size(struct uvd *uvd) | ||
157 | { | ||
158 | struct konicawc *cam = (struct konicawc *)uvd->user_data; | ||
159 | |||
160 | konicawc_set_misc(uvd, 0x2, camera_sizes[cam->size].cmd, 0x08); | ||
161 | cam->width = camera_sizes[cam->size].width; | ||
162 | cam->height = camera_sizes[cam->size].height; | ||
163 | cam->yplanesz = cam->height * cam->width; | ||
164 | cam->cur_frame_size = (cam->yplanesz * 3) / 2; | ||
165 | cam->maxline = cam->yplanesz / 256; | ||
166 | uvd->videosize = VIDEOSIZE(cam->width, cam->height); | ||
167 | } | ||
168 | |||
169 | |||
170 | static int konicawc_setup_on_open(struct uvd *uvd) | ||
171 | { | ||
172 | struct konicawc *cam = (struct konicawc *)uvd->user_data; | ||
173 | |||
174 | DEBUG(1, "setting brightness to %d (%d)", cam->brightness, | ||
175 | cam->brightness * 11); | ||
176 | konicawc_set_value(uvd, cam->brightness, SetBrightness); | ||
177 | DEBUG(1, "setting white balance to %d (%d)", cam->white_bal, | ||
178 | cam->white_bal * 11); | ||
179 | konicawc_set_value(uvd, cam->white_bal, SetWhitebal); | ||
180 | DEBUG(1, "setting contrast to %d (%d)", cam->contrast, | ||
181 | cam->contrast * 11); | ||
182 | konicawc_set_value(uvd, cam->contrast, SetContrast); | ||
183 | DEBUG(1, "setting saturation to %d (%d)", cam->saturation, | ||
184 | cam->saturation * 11); | ||
185 | konicawc_set_value(uvd, cam->saturation, SetSaturation); | ||
186 | DEBUG(1, "setting sharpness to %d (%d)", cam->sharpness, | ||
187 | cam->sharpness * 11); | ||
188 | konicawc_set_value(uvd, cam->sharpness, SetSharpness); | ||
189 | konicawc_set_camera_size(uvd); | ||
190 | cam->lastframe = -2; | ||
191 | cam->buttonsts = 0; | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | |||
196 | static void konicawc_adjust_picture(struct uvd *uvd) | ||
197 | { | ||
198 | struct konicawc *cam = (struct konicawc *)uvd->user_data; | ||
199 | |||
200 | konicawc_camera_off(uvd); | ||
201 | DEBUG(1, "new brightness: %d", uvd->vpic.brightness); | ||
202 | uvd->vpic.brightness = (uvd->vpic.brightness > MAX_BRIGHTNESS) ? MAX_BRIGHTNESS : uvd->vpic.brightness; | ||
203 | if(cam->brightness != uvd->vpic.brightness / 11) { | ||
204 | cam->brightness = uvd->vpic.brightness / 11; | ||
205 | DEBUG(1, "setting brightness to %d (%d)", cam->brightness, | ||
206 | cam->brightness * 11); | ||
207 | konicawc_set_value(uvd, cam->brightness, SetBrightness); | ||
208 | } | ||
209 | |||
210 | DEBUG(1, "new contrast: %d", uvd->vpic.contrast); | ||
211 | uvd->vpic.contrast = (uvd->vpic.contrast > MAX_CONTRAST) ? MAX_CONTRAST : uvd->vpic.contrast; | ||
212 | if(cam->contrast != uvd->vpic.contrast / 11) { | ||
213 | cam->contrast = uvd->vpic.contrast / 11; | ||
214 | DEBUG(1, "setting contrast to %d (%d)", cam->contrast, | ||
215 | cam->contrast * 11); | ||
216 | konicawc_set_value(uvd, cam->contrast, SetContrast); | ||
217 | } | ||
218 | konicawc_camera_on(uvd); | ||
219 | } | ||
220 | |||
221 | #ifdef CONFIG_INPUT | ||
222 | |||
223 | static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev) | ||
224 | { | ||
225 | struct input_dev *input_dev; | ||
226 | int error; | ||
227 | |||
228 | usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); | ||
229 | strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname)); | ||
230 | |||
231 | cam->input = input_dev = input_allocate_device(); | ||
232 | if (!input_dev) { | ||
233 | dev_warn(&dev->dev, | ||
234 | "Not enough memory for camera's input device\n"); | ||
235 | return; | ||
236 | } | ||
237 | |||
238 | input_dev->name = "Konicawc snapshot button"; | ||
239 | input_dev->phys = cam->input_physname; | ||
240 | usb_to_input_id(dev, &input_dev->id); | ||
241 | input_dev->dev.parent = &dev->dev; | ||
242 | |||
243 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
244 | input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA); | ||
245 | |||
246 | error = input_register_device(cam->input); | ||
247 | if (error) { | ||
248 | dev_warn(&dev->dev, | ||
249 | "Failed to register camera's input device, err: %d\n", | ||
250 | error); | ||
251 | input_free_device(cam->input); | ||
252 | cam->input = NULL; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | static void konicawc_unregister_input(struct konicawc *cam) | ||
257 | { | ||
258 | if (cam->input) { | ||
259 | input_unregister_device(cam->input); | ||
260 | cam->input = NULL; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | static void konicawc_report_buttonstat(struct konicawc *cam) | ||
265 | { | ||
266 | if (cam->input) { | ||
267 | input_report_key(cam->input, KEY_CAMERA, cam->buttonsts); | ||
268 | input_sync(cam->input); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | #else | ||
273 | |||
274 | static inline void konicawc_register_input(struct konicawc *cam, struct usb_device *dev) { } | ||
275 | static inline void konicawc_unregister_input(struct konicawc *cam) { } | ||
276 | static inline void konicawc_report_buttonstat(struct konicawc *cam) { } | ||
277 | |||
278 | #endif /* CONFIG_INPUT */ | ||
279 | |||
280 | static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct urb *stsurb) | ||
281 | { | ||
282 | char *cdata; | ||
283 | int i, totlen = 0; | ||
284 | unsigned char *status = stsurb->transfer_buffer; | ||
285 | int keep = 0, discard = 0, bad = 0; | ||
286 | struct konicawc *cam = (struct konicawc *)uvd->user_data; | ||
287 | |||
288 | for (i = 0; i < dataurb->number_of_packets; i++) { | ||
289 | int button = cam->buttonsts; | ||
290 | unsigned char sts; | ||
291 | int n = dataurb->iso_frame_desc[i].actual_length; | ||
292 | int st = dataurb->iso_frame_desc[i].status; | ||
293 | cdata = dataurb->transfer_buffer + | ||
294 | dataurb->iso_frame_desc[i].offset; | ||
295 | |||
296 | /* Detect and ignore errored packets */ | ||
297 | if (st < 0) { | ||
298 | DEBUG(1, "Data error: packet=%d. len=%d. status=%d.", | ||
299 | i, n, st); | ||
300 | uvd->stats.iso_err_count++; | ||
301 | continue; | ||
302 | } | ||
303 | |||
304 | /* Detect and ignore empty packets */ | ||
305 | if (n <= 0) { | ||
306 | uvd->stats.iso_skip_count++; | ||
307 | continue; | ||
308 | } | ||
309 | |||
310 | /* See what the status data said about the packet */ | ||
311 | sts = *(status+stsurb->iso_frame_desc[i].offset); | ||
312 | |||
313 | /* sts: 0x80-0xff: frame start with frame number (ie 0-7f) | ||
314 | * otherwise: | ||
315 | * bit 0 0: keep packet | ||
316 | * 1: drop packet (padding data) | ||
317 | * | ||
318 | * bit 4 0 button not clicked | ||
319 | * 1 button clicked | ||
320 | * button is used to `take a picture' (in software) | ||
321 | */ | ||
322 | |||
323 | if(sts < 0x80) { | ||
324 | button = !!(sts & 0x40); | ||
325 | sts &= ~0x40; | ||
326 | } | ||
327 | |||
328 | /* work out the button status, but don't do | ||
329 | anything with it for now */ | ||
330 | |||
331 | if(button != cam->buttonsts) { | ||
332 | DEBUG(2, "button: %sclicked", button ? "" : "un"); | ||
333 | cam->buttonsts = button; | ||
334 | konicawc_report_buttonstat(cam); | ||
335 | } | ||
336 | |||
337 | if(sts == 0x01) { /* drop frame */ | ||
338 | discard++; | ||
339 | continue; | ||
340 | } | ||
341 | |||
342 | if((sts > 0x01) && (sts < 0x80)) { | ||
343 | dev_info(&uvd->dev->dev, "unknown status %2.2x\n", | ||
344 | sts); | ||
345 | bad++; | ||
346 | continue; | ||
347 | } | ||
348 | if(!sts && cam->lastframe == -2) { | ||
349 | DEBUG(2, "dropping frame looking for image start"); | ||
350 | continue; | ||
351 | } | ||
352 | |||
353 | keep++; | ||
354 | if(sts & 0x80) { /* frame start */ | ||
355 | unsigned char marker[] = { 0, 0xff, 0, 0x00 }; | ||
356 | |||
357 | if(cam->lastframe == -2) { | ||
358 | DEBUG(2, "found initial image"); | ||
359 | cam->lastframe = -1; | ||
360 | } | ||
361 | |||
362 | marker[3] = sts & 0x7F; | ||
363 | RingQueue_Enqueue(&uvd->dp, marker, 4); | ||
364 | totlen += 4; | ||
365 | } | ||
366 | |||
367 | totlen += n; /* Little local accounting */ | ||
368 | RingQueue_Enqueue(&uvd->dp, cdata, n); | ||
369 | } | ||
370 | DEBUG(8, "finished: keep = %d discard = %d bad = %d added %d bytes", | ||
371 | keep, discard, bad, totlen); | ||
372 | return totlen; | ||
373 | } | ||
374 | |||
375 | |||
376 | static void resubmit_urb(struct uvd *uvd, struct urb *urb) | ||
377 | { | ||
378 | int i, ret; | ||
379 | for (i = 0; i < FRAMES_PER_DESC; i++) { | ||
380 | urb->iso_frame_desc[i].status = 0; | ||
381 | } | ||
382 | urb->dev = uvd->dev; | ||
383 | urb->status = 0; | ||
384 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
385 | DEBUG(3, "submitting urb of length %d", urb->transfer_buffer_length); | ||
386 | if(ret) | ||
387 | err("usb_submit_urb error (%d)", ret); | ||
388 | |||
389 | } | ||
390 | |||
391 | |||
392 | static void konicawc_isoc_irq(struct urb *urb) | ||
393 | { | ||
394 | struct uvd *uvd = urb->context; | ||
395 | struct konicawc *cam = (struct konicawc *)uvd->user_data; | ||
396 | |||
397 | /* We don't want to do anything if we are about to be removed! */ | ||
398 | if (!CAMERA_IS_OPERATIONAL(uvd)) | ||
399 | return; | ||
400 | |||
401 | if (!uvd->streaming) { | ||
402 | DEBUG(1, "Not streaming, but interrupt!"); | ||
403 | return; | ||
404 | } | ||
405 | |||
406 | DEBUG(3, "got frame %d len = %d buflen =%d", urb->start_frame, urb->actual_length, urb->transfer_buffer_length); | ||
407 | |||
408 | uvd->stats.urb_count++; | ||
409 | |||
410 | if (urb->transfer_buffer_length > 32) { | ||
411 | cam->last_data_urb = urb; | ||
412 | return; | ||
413 | } | ||
414 | /* Copy the data received into ring queue */ | ||
415 | if(cam->last_data_urb) { | ||
416 | int len = 0; | ||
417 | if(urb->start_frame != cam->last_data_urb->start_frame) | ||
418 | err("Lost sync on frames"); | ||
419 | else if (!urb->status && !cam->last_data_urb->status) | ||
420 | len = konicawc_compress_iso(uvd, cam->last_data_urb, urb); | ||
421 | |||
422 | resubmit_urb(uvd, cam->last_data_urb); | ||
423 | resubmit_urb(uvd, urb); | ||
424 | cam->last_data_urb = NULL; | ||
425 | uvd->stats.urb_length = len; | ||
426 | uvd->stats.data_count += len; | ||
427 | if(len) | ||
428 | RingQueue_WakeUpInterruptible(&uvd->dp); | ||
429 | return; | ||
430 | } | ||
431 | return; | ||
432 | } | ||
433 | |||
434 | |||
435 | static int konicawc_start_data(struct uvd *uvd) | ||
436 | { | ||
437 | struct usb_device *dev = uvd->dev; | ||
438 | int i, errFlag; | ||
439 | struct konicawc *cam = (struct konicawc *)uvd->user_data; | ||
440 | int pktsz; | ||
441 | struct usb_interface *intf; | ||
442 | struct usb_host_interface *interface = NULL; | ||
443 | |||
444 | intf = usb_ifnum_to_if(dev, uvd->iface); | ||
445 | if (intf) | ||
446 | interface = usb_altnum_to_altsetting(intf, | ||
447 | spd_to_iface[cam->speed]); | ||
448 | if (!interface) | ||
449 | return -ENXIO; | ||
450 | pktsz = le16_to_cpu(interface->endpoint[1].desc.wMaxPacketSize); | ||
451 | DEBUG(1, "pktsz = %d", pktsz); | ||
452 | if (!CAMERA_IS_OPERATIONAL(uvd)) { | ||
453 | err("Camera is not operational"); | ||
454 | return -EFAULT; | ||
455 | } | ||
456 | uvd->curframe = -1; | ||
457 | konicawc_camera_on(uvd); | ||
458 | /* Alternate interface 1 is is the biggest frame size */ | ||
459 | i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive); | ||
460 | if (i < 0) { | ||
461 | err("usb_set_interface error"); | ||
462 | uvd->last_error = i; | ||
463 | return -EBUSY; | ||
464 | } | ||
465 | |||
466 | /* We double buffer the Iso lists */ | ||
467 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | ||
468 | int j, k; | ||
469 | struct urb *urb = uvd->sbuf[i].urb; | ||
470 | urb->dev = dev; | ||
471 | urb->context = uvd; | ||
472 | urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp); | ||
473 | urb->interval = 1; | ||
474 | urb->transfer_flags = URB_ISO_ASAP; | ||
475 | urb->transfer_buffer = uvd->sbuf[i].data; | ||
476 | urb->complete = konicawc_isoc_irq; | ||
477 | urb->number_of_packets = FRAMES_PER_DESC; | ||
478 | urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC; | ||
479 | for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) { | ||
480 | urb->iso_frame_desc[j].offset = k; | ||
481 | urb->iso_frame_desc[j].length = pktsz; | ||
482 | } | ||
483 | |||
484 | urb = cam->sts_urb[i]; | ||
485 | urb->dev = dev; | ||
486 | urb->context = uvd; | ||
487 | urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp-1); | ||
488 | urb->interval = 1; | ||
489 | urb->transfer_flags = URB_ISO_ASAP; | ||
490 | urb->transfer_buffer = cam->sts_buf[i]; | ||
491 | urb->complete = konicawc_isoc_irq; | ||
492 | urb->number_of_packets = FRAMES_PER_DESC; | ||
493 | urb->transfer_buffer_length = FRAMES_PER_DESC; | ||
494 | for (j=0; j < FRAMES_PER_DESC; j++) { | ||
495 | urb->iso_frame_desc[j].offset = j; | ||
496 | urb->iso_frame_desc[j].length = 1; | ||
497 | } | ||
498 | } | ||
499 | |||
500 | cam->last_data_urb = NULL; | ||
501 | |||
502 | /* Submit all URBs */ | ||
503 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | ||
504 | errFlag = usb_submit_urb(cam->sts_urb[i], GFP_KERNEL); | ||
505 | if (errFlag) | ||
506 | err("usb_submit_isoc(%d) ret %d", i, errFlag); | ||
507 | |||
508 | errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL); | ||
509 | if (errFlag) | ||
510 | err ("usb_submit_isoc(%d) ret %d", i, errFlag); | ||
511 | } | ||
512 | |||
513 | uvd->streaming = 1; | ||
514 | DEBUG(1, "streaming=1 video_endp=$%02x", uvd->video_endp); | ||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | |||
519 | static void konicawc_stop_data(struct uvd *uvd) | ||
520 | { | ||
521 | int i, j; | ||
522 | struct konicawc *cam; | ||
523 | |||
524 | if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL)) | ||
525 | return; | ||
526 | |||
527 | konicawc_camera_off(uvd); | ||
528 | uvd->streaming = 0; | ||
529 | cam = (struct konicawc *)uvd->user_data; | ||
530 | cam->last_data_urb = NULL; | ||
531 | |||
532 | /* Unschedule all of the iso td's */ | ||
533 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | ||
534 | usb_kill_urb(uvd->sbuf[i].urb); | ||
535 | usb_kill_urb(cam->sts_urb[i]); | ||
536 | } | ||
537 | |||
538 | if (!uvd->remove_pending) { | ||
539 | /* Set packet size to 0 */ | ||
540 | j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive); | ||
541 | if (j < 0) { | ||
542 | err("usb_set_interface() error %d.", j); | ||
543 | uvd->last_error = j; | ||
544 | } | ||
545 | } | ||
546 | } | ||
547 | |||
548 | |||
549 | static void konicawc_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame) | ||
550 | { | ||
551 | struct konicawc *cam = (struct konicawc *)uvd->user_data; | ||
552 | int maxline = cam->maxline; | ||
553 | int yplanesz = cam->yplanesz; | ||
554 | |||
555 | assert(frame != NULL); | ||
556 | |||
557 | DEBUG(5, "maxline = %d yplanesz = %d", maxline, yplanesz); | ||
558 | DEBUG(3, "Frame state = %d", frame->scanstate); | ||
559 | |||
560 | if(frame->scanstate == ScanState_Scanning) { | ||
561 | int drop = 0; | ||
562 | int curframe; | ||
563 | int fdrops = 0; | ||
564 | DEBUG(3, "Searching for marker, queue len = %d", RingQueue_GetLength(&uvd->dp)); | ||
565 | while(RingQueue_GetLength(&uvd->dp) >= 4) { | ||
566 | if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) && | ||
567 | (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) && | ||
568 | (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) && | ||
569 | (RING_QUEUE_PEEK(&uvd->dp, 3) < 0x80)) { | ||
570 | curframe = RING_QUEUE_PEEK(&uvd->dp, 3); | ||
571 | if(cam->lastframe >= 0) { | ||
572 | fdrops = (0x80 + curframe - cam->lastframe) & 0x7F; | ||
573 | fdrops--; | ||
574 | if(fdrops) { | ||
575 | dev_info(&uvd->dev->dev, | ||
576 | "Dropped %d frames " | ||
577 | "(%d -> %d)\n", | ||
578 | fdrops, | ||
579 | cam->lastframe, | ||
580 | curframe); | ||
581 | } | ||
582 | } | ||
583 | cam->lastframe = curframe; | ||
584 | frame->curline = 0; | ||
585 | frame->scanstate = ScanState_Lines; | ||
586 | RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4); | ||
587 | break; | ||
588 | } | ||
589 | RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1); | ||
590 | drop++; | ||
591 | } | ||
592 | if(drop) | ||
593 | DEBUG(2, "dropped %d bytes looking for new frame", drop); | ||
594 | } | ||
595 | |||
596 | if(frame->scanstate == ScanState_Scanning) | ||
597 | return; | ||
598 | |||
599 | /* Try to move data from queue into frame buffer | ||
600 | * We get data in blocks of 384 bytes made up of: | ||
601 | * 256 Y, 64 U, 64 V. | ||
602 | * This needs to be written out as a Y plane, a U plane and a V plane. | ||
603 | */ | ||
604 | |||
605 | while ( frame->curline < maxline && (RingQueue_GetLength(&uvd->dp) >= 384)) { | ||
606 | /* Y */ | ||
607 | RingQueue_Dequeue(&uvd->dp, frame->data + (frame->curline * 256), 256); | ||
608 | /* U */ | ||
609 | RingQueue_Dequeue(&uvd->dp, frame->data + yplanesz + (frame->curline * 64), 64); | ||
610 | /* V */ | ||
611 | RingQueue_Dequeue(&uvd->dp, frame->data + (5 * yplanesz)/4 + (frame->curline * 64), 64); | ||
612 | frame->seqRead_Length += 384; | ||
613 | frame->curline++; | ||
614 | } | ||
615 | /* See if we filled the frame */ | ||
616 | if (frame->curline == maxline) { | ||
617 | DEBUG(5, "got whole frame"); | ||
618 | |||
619 | frame->frameState = FrameState_Done_Hold; | ||
620 | frame->curline = 0; | ||
621 | uvd->curframe = -1; | ||
622 | uvd->stats.frame_num++; | ||
623 | } | ||
624 | } | ||
625 | |||
626 | |||
627 | static int konicawc_find_fps(int size, int fps) | ||
628 | { | ||
629 | int i; | ||
630 | |||
631 | fps *= 3; | ||
632 | DEBUG(1, "konica_find_fps: size = %d fps = %d", size, fps); | ||
633 | if(fps <= spd_to_fps[size][0]) | ||
634 | return 0; | ||
635 | |||
636 | if(fps >= spd_to_fps[size][MAX_SPEED]) | ||
637 | return MAX_SPEED; | ||
638 | |||
639 | for(i = 0; i < MAX_SPEED; i++) { | ||
640 | if((fps >= spd_to_fps[size][i]) && (fps <= spd_to_fps[size][i+1])) { | ||
641 | DEBUG(2, "fps %d between %d and %d", fps, i, i+1); | ||
642 | if( (fps - spd_to_fps[size][i]) < (spd_to_fps[size][i+1] - fps)) | ||
643 | return i; | ||
644 | else | ||
645 | return i+1; | ||
646 | } | ||
647 | } | ||
648 | return MAX_SPEED+1; | ||
649 | } | ||
650 | |||
651 | |||
652 | static int konicawc_set_video_mode(struct uvd *uvd, struct video_window *vw) | ||
653 | { | ||
654 | struct konicawc *cam = (struct konicawc *)uvd->user_data; | ||
655 | int newspeed = cam->speed; | ||
656 | int newsize; | ||
657 | int x = vw->width; | ||
658 | int y = vw->height; | ||
659 | int fps = vw->flags; | ||
660 | |||
661 | if(x > 0 && y > 0) { | ||
662 | DEBUG(2, "trying to find size %d,%d", x, y); | ||
663 | for(newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) { | ||
664 | if((camera_sizes[newsize].width == x) && (camera_sizes[newsize].height == y)) | ||
665 | break; | ||
666 | } | ||
667 | } else { | ||
668 | newsize = cam->size; | ||
669 | } | ||
670 | |||
671 | if(newsize > MAX_FRAME_SIZE) { | ||
672 | DEBUG(1, "couldn't find size %d,%d", x, y); | ||
673 | return -EINVAL; | ||
674 | } | ||
675 | |||
676 | if(fps > 0) { | ||
677 | DEBUG(1, "trying to set fps to %d", fps); | ||
678 | newspeed = konicawc_find_fps(newsize, fps); | ||
679 | DEBUG(1, "find_fps returned %d (%d)", newspeed, spd_to_fps[newsize][newspeed]); | ||
680 | } | ||
681 | |||
682 | if(newspeed > MAX_SPEED) | ||
683 | return -EINVAL; | ||
684 | |||
685 | DEBUG(1, "setting size to %d speed to %d", newsize, newspeed); | ||
686 | if((newsize == cam->size) && (newspeed == cam->speed)) { | ||
687 | DEBUG(1, "Nothing to do"); | ||
688 | return 0; | ||
689 | } | ||
690 | DEBUG(0, "setting to %dx%d @ %d fps", camera_sizes[newsize].width, | ||
691 | camera_sizes[newsize].height, spd_to_fps[newsize][newspeed]/3); | ||
692 | |||
693 | konicawc_stop_data(uvd); | ||
694 | uvd->ifaceAltActive = spd_to_iface[newspeed]; | ||
695 | DEBUG(1, "new interface = %d", uvd->ifaceAltActive); | ||
696 | cam->speed = newspeed; | ||
697 | |||
698 | if(cam->size != newsize) { | ||
699 | cam->size = newsize; | ||
700 | konicawc_set_camera_size(uvd); | ||
701 | } | ||
702 | |||
703 | /* Flush the input queue and clear any current frame in progress */ | ||
704 | |||
705 | RingQueue_Flush(&uvd->dp); | ||
706 | cam->lastframe = -2; | ||
707 | if(uvd->curframe != -1) { | ||
708 | uvd->frame[uvd->curframe].curline = 0; | ||
709 | uvd->frame[uvd->curframe].seqRead_Length = 0; | ||
710 | uvd->frame[uvd->curframe].seqRead_Index = 0; | ||
711 | } | ||
712 | |||
713 | konicawc_start_data(uvd); | ||
714 | return 0; | ||
715 | } | ||
716 | |||
717 | |||
718 | static int konicawc_calculate_fps(struct uvd *uvd) | ||
719 | { | ||
720 | struct konicawc *cam = uvd->user_data; | ||
721 | return spd_to_fps[cam->size][cam->speed]/3; | ||
722 | } | ||
723 | |||
724 | |||
725 | static void konicawc_configure_video(struct uvd *uvd) | ||
726 | { | ||
727 | struct konicawc *cam = (struct konicawc *)uvd->user_data; | ||
728 | u8 buf[2]; | ||
729 | |||
730 | memset(&uvd->vpic, 0, sizeof(uvd->vpic)); | ||
731 | memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old)); | ||
732 | |||
733 | RESTRICT_TO_RANGE(brightness, 0, MAX_BRIGHTNESS); | ||
734 | RESTRICT_TO_RANGE(contrast, 0, MAX_CONTRAST); | ||
735 | RESTRICT_TO_RANGE(saturation, 0, MAX_SATURATION); | ||
736 | RESTRICT_TO_RANGE(sharpness, 0, MAX_SHARPNESS); | ||
737 | RESTRICT_TO_RANGE(whitebal, 0, MAX_WHITEBAL); | ||
738 | |||
739 | cam->brightness = brightness / 11; | ||
740 | cam->contrast = contrast / 11; | ||
741 | cam->saturation = saturation / 11; | ||
742 | cam->sharpness = sharpness / 11; | ||
743 | cam->white_bal = whitebal / 11; | ||
744 | |||
745 | uvd->vpic.colour = 108; | ||
746 | uvd->vpic.hue = 108; | ||
747 | uvd->vpic.brightness = brightness; | ||
748 | uvd->vpic.contrast = contrast; | ||
749 | uvd->vpic.whiteness = whitebal; | ||
750 | uvd->vpic.depth = 6; | ||
751 | uvd->vpic.palette = VIDEO_PALETTE_YUV420P; | ||
752 | |||
753 | memset(&uvd->vcap, 0, sizeof(uvd->vcap)); | ||
754 | strcpy(uvd->vcap.name, "Konica Webcam"); | ||
755 | uvd->vcap.type = VID_TYPE_CAPTURE; | ||
756 | uvd->vcap.channels = 1; | ||
757 | uvd->vcap.audios = 0; | ||
758 | uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width; | ||
759 | uvd->vcap.minheight = camera_sizes[SIZE_160X120].height; | ||
760 | uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width; | ||
761 | uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height; | ||
762 | |||
763 | memset(&uvd->vchan, 0, sizeof(uvd->vchan)); | ||
764 | uvd->vchan.flags = 0 ; | ||
765 | uvd->vchan.tuners = 0; | ||
766 | uvd->vchan.channel = 0; | ||
767 | uvd->vchan.type = VIDEO_TYPE_CAMERA; | ||
768 | strcpy(uvd->vchan.name, "Camera"); | ||
769 | |||
770 | /* Talk to device */ | ||
771 | DEBUG(1, "device init"); | ||
772 | if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2)) | ||
773 | DEBUG(2, "3,10 -> %2.2x %2.2x", buf[0], buf[1]); | ||
774 | if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2)) | ||
775 | DEBUG(2, "3,10 -> %2.2x %2.2x", buf[0], buf[1]); | ||
776 | if(konicawc_set_misc(uvd, 0x2, 0, 0xd)) | ||
777 | DEBUG(2, "2,0,d failed"); | ||
778 | DEBUG(1, "setting initial values"); | ||
779 | } | ||
780 | |||
781 | static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id *devid) | ||
782 | { | ||
783 | struct usb_device *dev = interface_to_usbdev(intf); | ||
784 | struct uvd *uvd = NULL; | ||
785 | int ix, i, nas; | ||
786 | int actInterface=-1, inactInterface=-1, maxPS=0; | ||
787 | unsigned char video_ep = 0; | ||
788 | |||
789 | DEBUG(1, "konicawc_probe(%p)", intf); | ||
790 | |||
791 | /* We don't handle multi-config cameras */ | ||
792 | if (dev->descriptor.bNumConfigurations != 1) | ||
793 | return -ENODEV; | ||
794 | |||
795 | dev_info(&intf->dev, "Konica Webcam (rev. 0x%04x)\n", | ||
796 | le16_to_cpu(dev->descriptor.bcdDevice)); | ||
797 | RESTRICT_TO_RANGE(speed, 0, MAX_SPEED); | ||
798 | |||
799 | /* Validate found interface: must have one ISO endpoint */ | ||
800 | nas = intf->num_altsetting; | ||
801 | if (nas != 8) { | ||
802 | err("Incorrect number of alternate settings (%d) for this camera!", nas); | ||
803 | return -ENODEV; | ||
804 | } | ||
805 | /* Validate all alternate settings */ | ||
806 | for (ix=0; ix < nas; ix++) { | ||
807 | const struct usb_host_interface *interface; | ||
808 | const struct usb_endpoint_descriptor *endpoint; | ||
809 | |||
810 | interface = &intf->altsetting[ix]; | ||
811 | i = interface->desc.bAlternateSetting; | ||
812 | if (interface->desc.bNumEndpoints != 2) { | ||
813 | err("Interface %d. has %u. endpoints!", | ||
814 | interface->desc.bInterfaceNumber, | ||
815 | (unsigned)(interface->desc.bNumEndpoints)); | ||
816 | return -ENODEV; | ||
817 | } | ||
818 | endpoint = &interface->endpoint[1].desc; | ||
819 | DEBUG(1, "found endpoint: addr: 0x%2.2x maxps = 0x%4.4x", | ||
820 | endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize)); | ||
821 | if (video_ep == 0) | ||
822 | video_ep = endpoint->bEndpointAddress; | ||
823 | else if (video_ep != endpoint->bEndpointAddress) { | ||
824 | err("Alternate settings have different endpoint addresses!"); | ||
825 | return -ENODEV; | ||
826 | } | ||
827 | if (!usb_endpoint_xfer_isoc(endpoint)) { | ||
828 | err("Interface %d. has non-ISO endpoint!", | ||
829 | interface->desc.bInterfaceNumber); | ||
830 | return -ENODEV; | ||
831 | } | ||
832 | if (usb_endpoint_dir_out(endpoint)) { | ||
833 | err("Interface %d. has ISO OUT endpoint!", | ||
834 | interface->desc.bInterfaceNumber); | ||
835 | return -ENODEV; | ||
836 | } | ||
837 | if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) { | ||
838 | if (inactInterface < 0) | ||
839 | inactInterface = i; | ||
840 | else { | ||
841 | err("More than one inactive alt. setting!"); | ||
842 | return -ENODEV; | ||
843 | } | ||
844 | } else { | ||
845 | if (i == spd_to_iface[speed]) { | ||
846 | /* This one is the requested one */ | ||
847 | actInterface = i; | ||
848 | } | ||
849 | } | ||
850 | if (le16_to_cpu(endpoint->wMaxPacketSize) > maxPS) | ||
851 | maxPS = le16_to_cpu(endpoint->wMaxPacketSize); | ||
852 | } | ||
853 | if(actInterface == -1) { | ||
854 | err("Cant find required endpoint"); | ||
855 | return -ENODEV; | ||
856 | } | ||
857 | |||
858 | DEBUG(1, "Selecting requested active setting=%d. maxPS=%d.", actInterface, maxPS); | ||
859 | |||
860 | uvd = usbvideo_AllocateDevice(cams); | ||
861 | if (uvd != NULL) { | ||
862 | struct konicawc *cam = (struct konicawc *)(uvd->user_data); | ||
863 | /* Here uvd is a fully allocated uvd object */ | ||
864 | for(i = 0; i < USBVIDEO_NUMSBUF; i++) { | ||
865 | cam->sts_urb[i] = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); | ||
866 | if(cam->sts_urb[i] == NULL) { | ||
867 | while(i--) { | ||
868 | usb_free_urb(cam->sts_urb[i]); | ||
869 | } | ||
870 | err("can't allocate urbs"); | ||
871 | return -ENOMEM; | ||
872 | } | ||
873 | } | ||
874 | cam->speed = speed; | ||
875 | RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240); | ||
876 | cam->width = camera_sizes[size].width; | ||
877 | cam->height = camera_sizes[size].height; | ||
878 | cam->size = size; | ||
879 | |||
880 | uvd->flags = 0; | ||
881 | uvd->debug = debug; | ||
882 | uvd->dev = dev; | ||
883 | uvd->iface = intf->altsetting->desc.bInterfaceNumber; | ||
884 | uvd->ifaceAltInactive = inactInterface; | ||
885 | uvd->ifaceAltActive = actInterface; | ||
886 | uvd->video_endp = video_ep; | ||
887 | uvd->iso_packet_len = maxPS; | ||
888 | uvd->paletteBits = 1L << VIDEO_PALETTE_YUV420P; | ||
889 | uvd->defaultPalette = VIDEO_PALETTE_YUV420P; | ||
890 | uvd->canvas = VIDEOSIZE(320, 240); | ||
891 | uvd->videosize = VIDEOSIZE(cam->width, cam->height); | ||
892 | |||
893 | /* Initialize konicawc specific data */ | ||
894 | konicawc_configure_video(uvd); | ||
895 | |||
896 | i = usbvideo_RegisterVideoDevice(uvd); | ||
897 | uvd->max_frame_size = (320 * 240 * 3)/2; | ||
898 | if (i != 0) { | ||
899 | err("usbvideo_RegisterVideoDevice() failed."); | ||
900 | uvd = NULL; | ||
901 | } | ||
902 | |||
903 | konicawc_register_input(cam, dev); | ||
904 | } | ||
905 | |||
906 | if (uvd) { | ||
907 | usb_set_intfdata (intf, uvd); | ||
908 | return 0; | ||
909 | } | ||
910 | return -EIO; | ||
911 | } | ||
912 | |||
913 | |||
914 | static void konicawc_free_uvd(struct uvd *uvd) | ||
915 | { | ||
916 | int i; | ||
917 | struct konicawc *cam = (struct konicawc *)uvd->user_data; | ||
918 | |||
919 | konicawc_unregister_input(cam); | ||
920 | |||
921 | for (i = 0; i < USBVIDEO_NUMSBUF; i++) { | ||
922 | usb_free_urb(cam->sts_urb[i]); | ||
923 | cam->sts_urb[i] = NULL; | ||
924 | } | ||
925 | } | ||
926 | |||
927 | |||
928 | static struct usb_device_id id_table[] = { | ||
929 | { USB_DEVICE(0x04c8, 0x0720) }, /* Intel YC 76 */ | ||
930 | { } /* Terminating entry */ | ||
931 | }; | ||
932 | |||
933 | |||
934 | static int __init konicawc_init(void) | ||
935 | { | ||
936 | struct usbvideo_cb cbTbl; | ||
937 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" | ||
938 | DRIVER_DESC "\n"); | ||
939 | memset(&cbTbl, 0, sizeof(cbTbl)); | ||
940 | cbTbl.probe = konicawc_probe; | ||
941 | cbTbl.setupOnOpen = konicawc_setup_on_open; | ||
942 | cbTbl.processData = konicawc_process_isoc; | ||
943 | cbTbl.getFPS = konicawc_calculate_fps; | ||
944 | cbTbl.setVideoMode = konicawc_set_video_mode; | ||
945 | cbTbl.startDataPump = konicawc_start_data; | ||
946 | cbTbl.stopDataPump = konicawc_stop_data; | ||
947 | cbTbl.adjustPicture = konicawc_adjust_picture; | ||
948 | cbTbl.userFree = konicawc_free_uvd; | ||
949 | return usbvideo_register( | ||
950 | &cams, | ||
951 | MAX_CAMERAS, | ||
952 | sizeof(struct konicawc), | ||
953 | "konicawc", | ||
954 | &cbTbl, | ||
955 | THIS_MODULE, | ||
956 | id_table); | ||
957 | } | ||
958 | |||
959 | |||
960 | static void __exit konicawc_cleanup(void) | ||
961 | { | ||
962 | usbvideo_Deregister(&cams); | ||
963 | } | ||
964 | |||
965 | |||
966 | MODULE_DEVICE_TABLE(usb, id_table); | ||
967 | |||
968 | MODULE_LICENSE("GPL"); | ||
969 | MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>"); | ||
970 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
971 | module_param(speed, int, 0); | ||
972 | MODULE_PARM_DESC(speed, "Initial speed: 0 (slowest) - 6 (fastest)"); | ||
973 | module_param(size, int, 0); | ||
974 | MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 160x136 2: 176x144 3: 320x240"); | ||
975 | module_param(brightness, int, 0); | ||
976 | MODULE_PARM_DESC(brightness, "Initial brightness 0 - 108"); | ||
977 | module_param(contrast, int, 0); | ||
978 | MODULE_PARM_DESC(contrast, "Initial contrast 0 - 108"); | ||
979 | module_param(saturation, int, 0); | ||
980 | MODULE_PARM_DESC(saturation, "Initial saturation 0 - 108"); | ||
981 | module_param(sharpness, int, 0); | ||
982 | MODULE_PARM_DESC(sharpness, "Initial brightness 0 - 108"); | ||
983 | module_param(whitebal, int, 0); | ||
984 | MODULE_PARM_DESC(whitebal, "Initial white balance 0 - 363"); | ||
985 | |||
986 | #ifdef CONFIG_USB_DEBUG | ||
987 | module_param(debug, int, S_IRUGO | S_IWUSR); | ||
988 | MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)"); | ||
989 | #endif | ||
990 | |||
991 | module_init(konicawc_init); | ||
992 | module_exit(konicawc_cleanup); | ||
diff --git a/drivers/media/video/usbvideo/ultracam.c b/drivers/media/video/usbvideo/ultracam.c deleted file mode 100644 index fbd1b6392290..000000000000 --- a/drivers/media/video/usbvideo/ultracam.c +++ /dev/null | |||
@@ -1,685 +0,0 @@ | |||
1 | /* | ||
2 | * USB NB Camera driver | ||
3 | * | ||
4 | * HISTORY: | ||
5 | * 25-Dec-2002 Dmitri Removed lighting, sharpness parameters, methods. | ||
6 | */ | ||
7 | |||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/init.h> | ||
11 | |||
12 | #include "usbvideo.h" | ||
13 | |||
14 | #define ULTRACAM_VENDOR_ID 0x0461 | ||
15 | #define ULTRACAM_PRODUCT_ID 0x0813 | ||
16 | |||
17 | #define MAX_CAMERAS 4 /* How many devices we allow to connect */ | ||
18 | |||
19 | /* | ||
20 | * This structure lives in uvd_t->user field. | ||
21 | */ | ||
22 | typedef struct { | ||
23 | int initialized; /* Had we already sent init sequence? */ | ||
24 | int camera_model; /* What type of IBM camera we got? */ | ||
25 | int has_hdr; | ||
26 | } ultracam_t; | ||
27 | #define ULTRACAM_T(uvd) ((ultracam_t *)((uvd)->user_data)) | ||
28 | |||
29 | static struct usbvideo *cams = NULL; | ||
30 | |||
31 | static int debug; | ||
32 | |||
33 | static int flags; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */ | ||
34 | |||
35 | static const int min_canvasWidth = 8; | ||
36 | static const int min_canvasHeight = 4; | ||
37 | |||
38 | #define FRAMERATE_MIN 0 | ||
39 | #define FRAMERATE_MAX 6 | ||
40 | static int framerate = -1; | ||
41 | |||
42 | /* | ||
43 | * Here we define several initialization variables. They may | ||
44 | * be used to automatically set color, hue, brightness and | ||
45 | * contrast to desired values. This is particularly useful in | ||
46 | * case of webcams (which have no controls and no on-screen | ||
47 | * output) and also when a client V4L software is used that | ||
48 | * does not have some of those controls. In any case it's | ||
49 | * good to have startup values as options. | ||
50 | * | ||
51 | * These values are all in [0..255] range. This simplifies | ||
52 | * operation. Note that actual values of V4L variables may | ||
53 | * be scaled up (as much as << 8). User can see that only | ||
54 | * on overlay output, however, or through a V4L client. | ||
55 | */ | ||
56 | static int init_brightness = 128; | ||
57 | static int init_contrast = 192; | ||
58 | static int init_color = 128; | ||
59 | static int init_hue = 128; | ||
60 | static int hue_correction = 128; | ||
61 | |||
62 | module_param(debug, int, S_IRUGO | S_IWUSR); | ||
63 | MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)"); | ||
64 | module_param(flags, int, 0); | ||
65 | MODULE_PARM_DESC(flags, | ||
66 | "Bitfield: 0=VIDIOCSYNC, " | ||
67 | "1=B/W, " | ||
68 | "2=show hints, " | ||
69 | "3=show stats, " | ||
70 | "4=test pattern, " | ||
71 | "5=separate frames, " | ||
72 | "6=clean frames"); | ||
73 | module_param(framerate, int, 0); | ||
74 | MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)"); | ||
75 | |||
76 | module_param(init_brightness, int, 0); | ||
77 | MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)"); | ||
78 | module_param(init_contrast, int, 0); | ||
79 | MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)"); | ||
80 | module_param(init_color, int, 0); | ||
81 | MODULE_PARM_DESC(init_color, "Color preconfiguration: 0-255 (default=128)"); | ||
82 | module_param(init_hue, int, 0); | ||
83 | MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)"); | ||
84 | module_param(hue_correction, int, 0); | ||
85 | MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)"); | ||
86 | |||
87 | /* | ||
88 | * ultracam_ProcessIsocData() | ||
89 | * | ||
90 | * Generic routine to parse the ring queue data. It employs either | ||
91 | * ultracam_find_header() or ultracam_parse_lines() to do most | ||
92 | * of work. | ||
93 | * | ||
94 | * 02-Nov-2000 First (mostly dummy) version. | ||
95 | * 06-Nov-2000 Rewrote to dump all data into frame. | ||
96 | */ | ||
97 | static void ultracam_ProcessIsocData(struct uvd *uvd, struct usbvideo_frame *frame) | ||
98 | { | ||
99 | int n; | ||
100 | |||
101 | assert(uvd != NULL); | ||
102 | assert(frame != NULL); | ||
103 | |||
104 | /* Try to move data from queue into frame buffer */ | ||
105 | n = RingQueue_GetLength(&uvd->dp); | ||
106 | if (n > 0) { | ||
107 | int m; | ||
108 | /* See how much spare we have left */ | ||
109 | m = uvd->max_frame_size - frame->seqRead_Length; | ||
110 | if (n > m) | ||
111 | n = m; | ||
112 | /* Now move that much data into frame buffer */ | ||
113 | RingQueue_Dequeue( | ||
114 | &uvd->dp, | ||
115 | frame->data + frame->seqRead_Length, | ||
116 | m); | ||
117 | frame->seqRead_Length += m; | ||
118 | } | ||
119 | /* See if we filled the frame */ | ||
120 | if (frame->seqRead_Length >= uvd->max_frame_size) { | ||
121 | frame->frameState = FrameState_Done; | ||
122 | uvd->curframe = -1; | ||
123 | uvd->stats.frame_num++; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * ultracam_veio() | ||
129 | * | ||
130 | * History: | ||
131 | * 1/27/00 Added check for dev == NULL; this happens if camera is unplugged. | ||
132 | */ | ||
133 | static int ultracam_veio( | ||
134 | struct uvd *uvd, | ||
135 | unsigned char req, | ||
136 | unsigned short value, | ||
137 | unsigned short index, | ||
138 | int is_out) | ||
139 | { | ||
140 | static const char proc[] = "ultracam_veio"; | ||
141 | unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */; | ||
142 | int i; | ||
143 | |||
144 | if (!CAMERA_IS_OPERATIONAL(uvd)) | ||
145 | return 0; | ||
146 | |||
147 | if (!is_out) { | ||
148 | i = usb_control_msg( | ||
149 | uvd->dev, | ||
150 | usb_rcvctrlpipe(uvd->dev, 0), | ||
151 | req, | ||
152 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
153 | value, | ||
154 | index, | ||
155 | cp, | ||
156 | sizeof(cp), | ||
157 | 1000); | ||
158 | #if 1 | ||
159 | dev_info(&uvd->dev->dev, | ||
160 | "USB => %02x%02x%02x%02x%02x%02x%02x%02x " | ||
161 | "(req=$%02x val=$%04x ind=$%04x)\n", | ||
162 | cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7], | ||
163 | req, value, index); | ||
164 | #endif | ||
165 | } else { | ||
166 | i = usb_control_msg( | ||
167 | uvd->dev, | ||
168 | usb_sndctrlpipe(uvd->dev, 0), | ||
169 | req, | ||
170 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
171 | value, | ||
172 | index, | ||
173 | NULL, | ||
174 | 0, | ||
175 | 1000); | ||
176 | } | ||
177 | if (i < 0) { | ||
178 | err("%s: ERROR=%d. Camera stopped; Reconnect or reload driver.", | ||
179 | proc, i); | ||
180 | uvd->last_error = i; | ||
181 | } | ||
182 | return i; | ||
183 | } | ||
184 | |||
185 | /* | ||
186 | * ultracam_calculate_fps() | ||
187 | */ | ||
188 | static int ultracam_calculate_fps(struct uvd *uvd) | ||
189 | { | ||
190 | return 3 + framerate*4 + framerate/2; | ||
191 | } | ||
192 | |||
193 | /* | ||
194 | * ultracam_adjust_contrast() | ||
195 | */ | ||
196 | static void ultracam_adjust_contrast(struct uvd *uvd) | ||
197 | { | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | * ultracam_set_brightness() | ||
202 | * | ||
203 | * This procedure changes brightness of the picture. | ||
204 | */ | ||
205 | static void ultracam_set_brightness(struct uvd *uvd) | ||
206 | { | ||
207 | } | ||
208 | |||
209 | static void ultracam_set_hue(struct uvd *uvd) | ||
210 | { | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * ultracam_adjust_picture() | ||
215 | * | ||
216 | * This procedure gets called from V4L interface to update picture settings. | ||
217 | * Here we change brightness and contrast. | ||
218 | */ | ||
219 | static void ultracam_adjust_picture(struct uvd *uvd) | ||
220 | { | ||
221 | ultracam_adjust_contrast(uvd); | ||
222 | ultracam_set_brightness(uvd); | ||
223 | ultracam_set_hue(uvd); | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | * ultracam_video_stop() | ||
228 | * | ||
229 | * This code tells camera to stop streaming. The interface remains | ||
230 | * configured and bandwidth - claimed. | ||
231 | */ | ||
232 | static void ultracam_video_stop(struct uvd *uvd) | ||
233 | { | ||
234 | } | ||
235 | |||
236 | /* | ||
237 | * ultracam_reinit_iso() | ||
238 | * | ||
239 | * This procedure sends couple of commands to the camera and then | ||
240 | * resets the video pipe. This sequence was observed to reinit the | ||
241 | * camera or, at least, to initiate ISO data stream. | ||
242 | */ | ||
243 | static void ultracam_reinit_iso(struct uvd *uvd, int do_stop) | ||
244 | { | ||
245 | } | ||
246 | |||
247 | static void ultracam_video_start(struct uvd *uvd) | ||
248 | { | ||
249 | ultracam_reinit_iso(uvd, 0); | ||
250 | } | ||
251 | |||
252 | static int ultracam_resetPipe(struct uvd *uvd) | ||
253 | { | ||
254 | usb_clear_halt(uvd->dev, uvd->video_endp); | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int ultracam_alternateSetting(struct uvd *uvd, int setting) | ||
259 | { | ||
260 | static const char proc[] = "ultracam_alternateSetting"; | ||
261 | int i; | ||
262 | i = usb_set_interface(uvd->dev, uvd->iface, setting); | ||
263 | if (i < 0) { | ||
264 | err("%s: usb_set_interface error", proc); | ||
265 | uvd->last_error = i; | ||
266 | return -EBUSY; | ||
267 | } | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | /* | ||
272 | * Return negative code on failure, 0 on success. | ||
273 | */ | ||
274 | static int ultracam_setup_on_open(struct uvd *uvd) | ||
275 | { | ||
276 | int setup_ok = 0; /* Success by default */ | ||
277 | /* Send init sequence only once, it's large! */ | ||
278 | if (!ULTRACAM_T(uvd)->initialized) { | ||
279 | ultracam_alternateSetting(uvd, 0x04); | ||
280 | ultracam_alternateSetting(uvd, 0x00); | ||
281 | ultracam_veio(uvd, 0x02, 0x0004, 0x000b, 1); | ||
282 | ultracam_veio(uvd, 0x02, 0x0001, 0x0005, 1); | ||
283 | ultracam_veio(uvd, 0x02, 0x8000, 0x0000, 1); | ||
284 | ultracam_veio(uvd, 0x00, 0x0000, 0x0000, 1); | ||
285 | ultracam_veio(uvd, 0x00, 0x00b0, 0x0001, 1); | ||
286 | ultracam_veio(uvd, 0x00, 0x0000, 0x0002, 1); | ||
287 | ultracam_veio(uvd, 0x00, 0x000c, 0x0003, 1); | ||
288 | ultracam_veio(uvd, 0x00, 0x000b, 0x0004, 1); | ||
289 | ultracam_veio(uvd, 0x00, 0x0000, 0x0005, 1); | ||
290 | ultracam_veio(uvd, 0x00, 0x0000, 0x0006, 1); | ||
291 | ultracam_veio(uvd, 0x00, 0x0079, 0x0007, 1); | ||
292 | ultracam_veio(uvd, 0x00, 0x003b, 0x0008, 1); | ||
293 | ultracam_veio(uvd, 0x00, 0x0002, 0x000f, 1); | ||
294 | ultracam_veio(uvd, 0x00, 0x0001, 0x0010, 1); | ||
295 | ultracam_veio(uvd, 0x00, 0x0000, 0x0011, 1); | ||
296 | ultracam_veio(uvd, 0x00, 0x0000, 0x00bf, 1); | ||
297 | ultracam_veio(uvd, 0x00, 0x0001, 0x00c0, 1); | ||
298 | ultracam_veio(uvd, 0x00, 0x0010, 0x00cb, 1); | ||
299 | ultracam_veio(uvd, 0x01, 0x00a4, 0x0001, 1); | ||
300 | ultracam_veio(uvd, 0x01, 0x0010, 0x0002, 1); | ||
301 | ultracam_veio(uvd, 0x01, 0x0066, 0x0007, 1); | ||
302 | ultracam_veio(uvd, 0x01, 0x000b, 0x0008, 1); | ||
303 | ultracam_veio(uvd, 0x01, 0x0034, 0x0009, 1); | ||
304 | ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 1); | ||
305 | ultracam_veio(uvd, 0x01, 0x002e, 0x000b, 1); | ||
306 | ultracam_veio(uvd, 0x01, 0x00d6, 0x000c, 1); | ||
307 | ultracam_veio(uvd, 0x01, 0x00fc, 0x000d, 1); | ||
308 | ultracam_veio(uvd, 0x01, 0x00f1, 0x000e, 1); | ||
309 | ultracam_veio(uvd, 0x01, 0x00da, 0x000f, 1); | ||
310 | ultracam_veio(uvd, 0x01, 0x0036, 0x0010, 1); | ||
311 | ultracam_veio(uvd, 0x01, 0x000b, 0x0011, 1); | ||
312 | ultracam_veio(uvd, 0x01, 0x0001, 0x0012, 1); | ||
313 | ultracam_veio(uvd, 0x01, 0x0000, 0x0013, 1); | ||
314 | ultracam_veio(uvd, 0x01, 0x0000, 0x0014, 1); | ||
315 | ultracam_veio(uvd, 0x01, 0x0087, 0x0051, 1); | ||
316 | ultracam_veio(uvd, 0x01, 0x0040, 0x0052, 1); | ||
317 | ultracam_veio(uvd, 0x01, 0x0058, 0x0053, 1); | ||
318 | ultracam_veio(uvd, 0x01, 0x0040, 0x0054, 1); | ||
319 | ultracam_veio(uvd, 0x01, 0x0000, 0x0040, 1); | ||
320 | ultracam_veio(uvd, 0x01, 0x0010, 0x0041, 1); | ||
321 | ultracam_veio(uvd, 0x01, 0x0020, 0x0042, 1); | ||
322 | ultracam_veio(uvd, 0x01, 0x0030, 0x0043, 1); | ||
323 | ultracam_veio(uvd, 0x01, 0x0040, 0x0044, 1); | ||
324 | ultracam_veio(uvd, 0x01, 0x0050, 0x0045, 1); | ||
325 | ultracam_veio(uvd, 0x01, 0x0060, 0x0046, 1); | ||
326 | ultracam_veio(uvd, 0x01, 0x0070, 0x0047, 1); | ||
327 | ultracam_veio(uvd, 0x01, 0x0080, 0x0048, 1); | ||
328 | ultracam_veio(uvd, 0x01, 0x0090, 0x0049, 1); | ||
329 | ultracam_veio(uvd, 0x01, 0x00a0, 0x004a, 1); | ||
330 | ultracam_veio(uvd, 0x01, 0x00b0, 0x004b, 1); | ||
331 | ultracam_veio(uvd, 0x01, 0x00c0, 0x004c, 1); | ||
332 | ultracam_veio(uvd, 0x01, 0x00d0, 0x004d, 1); | ||
333 | ultracam_veio(uvd, 0x01, 0x00e0, 0x004e, 1); | ||
334 | ultracam_veio(uvd, 0x01, 0x00f0, 0x004f, 1); | ||
335 | ultracam_veio(uvd, 0x01, 0x00ff, 0x0050, 1); | ||
336 | ultracam_veio(uvd, 0x01, 0x0000, 0x0056, 1); | ||
337 | ultracam_veio(uvd, 0x00, 0x0080, 0x00c1, 1); | ||
338 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c2, 1); | ||
339 | ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1); | ||
340 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
341 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
342 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
343 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
344 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
345 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
346 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
347 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
348 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
349 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
350 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
351 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
352 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
353 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
354 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
355 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
356 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
357 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
358 | ultracam_veio(uvd, 0x00, 0x0080, 0x00c1, 1); | ||
359 | ultracam_veio(uvd, 0x00, 0x0004, 0x00c2, 1); | ||
360 | ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1); | ||
361 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
362 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
363 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
364 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
365 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
366 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
367 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
368 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
369 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
370 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
371 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
372 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
373 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
374 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
375 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
376 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
377 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
378 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
379 | ultracam_veio(uvd, 0x00, 0x0002, 0x00c1, 1); | ||
380 | ultracam_veio(uvd, 0x00, 0x0020, 0x00c2, 1); | ||
381 | ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1); | ||
382 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1); | ||
383 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1); | ||
384 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1); | ||
385 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1); | ||
386 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1); | ||
387 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1); | ||
388 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
389 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1); | ||
390 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1); | ||
391 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1); | ||
392 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1); | ||
393 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1); | ||
394 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1); | ||
395 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
396 | ultracam_veio(uvd, 0x00, 0x0040, 0x00c1, 1); | ||
397 | ultracam_veio(uvd, 0x00, 0x0017, 0x00c2, 1); | ||
398 | ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1); | ||
399 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1); | ||
400 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1); | ||
401 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1); | ||
402 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1); | ||
403 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1); | ||
404 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1); | ||
405 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
406 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1); | ||
407 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1); | ||
408 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1); | ||
409 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1); | ||
410 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1); | ||
411 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1); | ||
412 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1); | ||
413 | ultracam_veio(uvd, 0x00, 0x00c0, 0x00c1, 1); | ||
414 | ultracam_veio(uvd, 0x00, 0x0000, 0x00c2, 1); | ||
415 | ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1); | ||
416 | ultracam_veio(uvd, 0x02, 0xc040, 0x0001, 1); | ||
417 | ultracam_veio(uvd, 0x01, 0x0000, 0x0008, 0); | ||
418 | ultracam_veio(uvd, 0x01, 0x0000, 0x0009, 0); | ||
419 | ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 0); | ||
420 | ultracam_veio(uvd, 0x01, 0x0000, 0x000b, 0); | ||
421 | ultracam_veio(uvd, 0x01, 0x0000, 0x000c, 0); | ||
422 | ultracam_veio(uvd, 0x01, 0x0000, 0x000d, 0); | ||
423 | ultracam_veio(uvd, 0x01, 0x0000, 0x000e, 0); | ||
424 | ultracam_veio(uvd, 0x01, 0x0000, 0x000f, 0); | ||
425 | ultracam_veio(uvd, 0x01, 0x0000, 0x0010, 0); | ||
426 | ultracam_veio(uvd, 0x01, 0x000b, 0x0008, 1); | ||
427 | ultracam_veio(uvd, 0x01, 0x0034, 0x0009, 1); | ||
428 | ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 1); | ||
429 | ultracam_veio(uvd, 0x01, 0x002e, 0x000b, 1); | ||
430 | ultracam_veio(uvd, 0x01, 0x00d6, 0x000c, 1); | ||
431 | ultracam_veio(uvd, 0x01, 0x00fc, 0x000d, 1); | ||
432 | ultracam_veio(uvd, 0x01, 0x00f1, 0x000e, 1); | ||
433 | ultracam_veio(uvd, 0x01, 0x00da, 0x000f, 1); | ||
434 | ultracam_veio(uvd, 0x01, 0x0036, 0x0010, 1); | ||
435 | ultracam_veio(uvd, 0x01, 0x0000, 0x0001, 0); | ||
436 | ultracam_veio(uvd, 0x01, 0x0064, 0x0001, 1); | ||
437 | ultracam_veio(uvd, 0x01, 0x0059, 0x0051, 1); | ||
438 | ultracam_veio(uvd, 0x01, 0x003f, 0x0052, 1); | ||
439 | ultracam_veio(uvd, 0x01, 0x0094, 0x0053, 1); | ||
440 | ultracam_veio(uvd, 0x01, 0x00ff, 0x0011, 1); | ||
441 | ultracam_veio(uvd, 0x01, 0x0003, 0x0012, 1); | ||
442 | ultracam_veio(uvd, 0x01, 0x00f7, 0x0013, 1); | ||
443 | ultracam_veio(uvd, 0x00, 0x0009, 0x0011, 1); | ||
444 | ultracam_veio(uvd, 0x00, 0x0000, 0x0001, 1); | ||
445 | ultracam_veio(uvd, 0x00, 0x0000, 0x0000, 1); | ||
446 | ultracam_veio(uvd, 0x00, 0x0020, 0x00c1, 1); | ||
447 | ultracam_veio(uvd, 0x00, 0x0010, 0x00c2, 1); | ||
448 | ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1); | ||
449 | ultracam_alternateSetting(uvd, 0x04); | ||
450 | ultracam_veio(uvd, 0x02, 0x0000, 0x0001, 1); | ||
451 | ultracam_veio(uvd, 0x02, 0x0000, 0x0001, 1); | ||
452 | ultracam_veio(uvd, 0x02, 0x0000, 0x0006, 1); | ||
453 | ultracam_veio(uvd, 0x02, 0x9000, 0x0007, 1); | ||
454 | ultracam_veio(uvd, 0x02, 0x0042, 0x0001, 1); | ||
455 | ultracam_veio(uvd, 0x02, 0x0000, 0x000b, 0); | ||
456 | ultracam_resetPipe(uvd); | ||
457 | ULTRACAM_T(uvd)->initialized = (setup_ok != 0); | ||
458 | } | ||
459 | return setup_ok; | ||
460 | } | ||
461 | |||
462 | static void ultracam_configure_video(struct uvd *uvd) | ||
463 | { | ||
464 | if (uvd == NULL) | ||
465 | return; | ||
466 | |||
467 | RESTRICT_TO_RANGE(init_brightness, 0, 255); | ||
468 | RESTRICT_TO_RANGE(init_contrast, 0, 255); | ||
469 | RESTRICT_TO_RANGE(init_color, 0, 255); | ||
470 | RESTRICT_TO_RANGE(init_hue, 0, 255); | ||
471 | RESTRICT_TO_RANGE(hue_correction, 0, 255); | ||
472 | |||
473 | memset(&uvd->vpic, 0, sizeof(uvd->vpic)); | ||
474 | memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old)); | ||
475 | |||
476 | uvd->vpic.colour = init_color << 8; | ||
477 | uvd->vpic.hue = init_hue << 8; | ||
478 | uvd->vpic.brightness = init_brightness << 8; | ||
479 | uvd->vpic.contrast = init_contrast << 8; | ||
480 | uvd->vpic.whiteness = 105 << 8; /* This one isn't used */ | ||
481 | uvd->vpic.depth = 24; | ||
482 | uvd->vpic.palette = VIDEO_PALETTE_RGB24; | ||
483 | |||
484 | memset(&uvd->vcap, 0, sizeof(uvd->vcap)); | ||
485 | strcpy(uvd->vcap.name, "IBM Ultra Camera"); | ||
486 | uvd->vcap.type = VID_TYPE_CAPTURE; | ||
487 | uvd->vcap.channels = 1; | ||
488 | uvd->vcap.audios = 0; | ||
489 | uvd->vcap.maxwidth = VIDEOSIZE_X(uvd->canvas); | ||
490 | uvd->vcap.maxheight = VIDEOSIZE_Y(uvd->canvas); | ||
491 | uvd->vcap.minwidth = min_canvasWidth; | ||
492 | uvd->vcap.minheight = min_canvasHeight; | ||
493 | |||
494 | memset(&uvd->vchan, 0, sizeof(uvd->vchan)); | ||
495 | uvd->vchan.flags = 0; | ||
496 | uvd->vchan.tuners = 0; | ||
497 | uvd->vchan.channel = 0; | ||
498 | uvd->vchan.type = VIDEO_TYPE_CAMERA; | ||
499 | strcpy(uvd->vchan.name, "Camera"); | ||
500 | } | ||
501 | |||
502 | /* | ||
503 | * ultracam_probe() | ||
504 | * | ||
505 | * This procedure queries device descriptor and accepts the interface | ||
506 | * if it looks like our camera. | ||
507 | * | ||
508 | * History: | ||
509 | * 12-Nov-2000 Reworked to comply with new probe() signature. | ||
510 | * 23-Jan-2001 Added compatibility with 2.2.x kernels. | ||
511 | */ | ||
512 | static int ultracam_probe(struct usb_interface *intf, const struct usb_device_id *devid) | ||
513 | { | ||
514 | struct usb_device *dev = interface_to_usbdev(intf); | ||
515 | struct uvd *uvd = NULL; | ||
516 | int ix, i, nas; | ||
517 | int actInterface=-1, inactInterface=-1, maxPS=0; | ||
518 | unsigned char video_ep = 0; | ||
519 | |||
520 | if (debug >= 1) | ||
521 | dev_info(&intf->dev, "ultracam_probe\n"); | ||
522 | |||
523 | /* We don't handle multi-config cameras */ | ||
524 | if (dev->descriptor.bNumConfigurations != 1) | ||
525 | return -ENODEV; | ||
526 | |||
527 | dev_info(&intf->dev, "IBM Ultra camera found (rev. 0x%04x)\n", | ||
528 | le16_to_cpu(dev->descriptor.bcdDevice)); | ||
529 | |||
530 | /* Validate found interface: must have one ISO endpoint */ | ||
531 | nas = intf->num_altsetting; | ||
532 | if (debug > 0) | ||
533 | dev_info(&intf->dev, "Number of alternate settings=%d.\n", | ||
534 | nas); | ||
535 | if (nas < 8) { | ||
536 | err("Too few alternate settings for this camera!"); | ||
537 | return -ENODEV; | ||
538 | } | ||
539 | /* Validate all alternate settings */ | ||
540 | for (ix=0; ix < nas; ix++) { | ||
541 | const struct usb_host_interface *interface; | ||
542 | const struct usb_endpoint_descriptor *endpoint; | ||
543 | |||
544 | interface = &intf->altsetting[ix]; | ||
545 | i = interface->desc.bAlternateSetting; | ||
546 | if (interface->desc.bNumEndpoints != 1) { | ||
547 | err("Interface %d. has %u. endpoints!", | ||
548 | interface->desc.bInterfaceNumber, | ||
549 | (unsigned)(interface->desc.bNumEndpoints)); | ||
550 | return -ENODEV; | ||
551 | } | ||
552 | endpoint = &interface->endpoint[0].desc; | ||
553 | if (video_ep == 0) | ||
554 | video_ep = endpoint->bEndpointAddress; | ||
555 | else if (video_ep != endpoint->bEndpointAddress) { | ||
556 | err("Alternate settings have different endpoint addresses!"); | ||
557 | return -ENODEV; | ||
558 | } | ||
559 | if (!usb_endpoint_xfer_isoc(endpoint)) { | ||
560 | err("Interface %d. has non-ISO endpoint!", | ||
561 | interface->desc.bInterfaceNumber); | ||
562 | return -ENODEV; | ||
563 | } | ||
564 | if (usb_endpoint_dir_out(endpoint)) { | ||
565 | err("Interface %d. has ISO OUT endpoint!", | ||
566 | interface->desc.bInterfaceNumber); | ||
567 | return -ENODEV; | ||
568 | } | ||
569 | if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) { | ||
570 | if (inactInterface < 0) | ||
571 | inactInterface = i; | ||
572 | else { | ||
573 | err("More than one inactive alt. setting!"); | ||
574 | return -ENODEV; | ||
575 | } | ||
576 | } else { | ||
577 | if (actInterface < 0) { | ||
578 | actInterface = i; | ||
579 | maxPS = le16_to_cpu(endpoint->wMaxPacketSize); | ||
580 | if (debug > 0) | ||
581 | dev_info(&intf->dev, | ||
582 | "Active setting=%d. " | ||
583 | "maxPS=%d.\n", i, maxPS); | ||
584 | } else { | ||
585 | /* Got another active alt. setting */ | ||
586 | if (maxPS < le16_to_cpu(endpoint->wMaxPacketSize)) { | ||
587 | /* This one is better! */ | ||
588 | actInterface = i; | ||
589 | maxPS = le16_to_cpu(endpoint->wMaxPacketSize); | ||
590 | if (debug > 0) { | ||
591 | dev_info(&intf->dev, | ||
592 | "Even better ctive " | ||
593 | "setting=%d. " | ||
594 | "maxPS=%d.\n", | ||
595 | i, maxPS); | ||
596 | } | ||
597 | } | ||
598 | } | ||
599 | } | ||
600 | } | ||
601 | if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) { | ||
602 | err("Failed to recognize the camera!"); | ||
603 | return -ENODEV; | ||
604 | } | ||
605 | |||
606 | uvd = usbvideo_AllocateDevice(cams); | ||
607 | if (uvd != NULL) { | ||
608 | /* Here uvd is a fully allocated uvd object */ | ||
609 | uvd->flags = flags; | ||
610 | uvd->debug = debug; | ||
611 | uvd->dev = dev; | ||
612 | uvd->iface = intf->altsetting->desc.bInterfaceNumber; | ||
613 | uvd->ifaceAltInactive = inactInterface; | ||
614 | uvd->ifaceAltActive = actInterface; | ||
615 | uvd->video_endp = video_ep; | ||
616 | uvd->iso_packet_len = maxPS; | ||
617 | uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24; | ||
618 | uvd->defaultPalette = VIDEO_PALETTE_RGB24; | ||
619 | uvd->canvas = VIDEOSIZE(640, 480); /* FIXME */ | ||
620 | uvd->videosize = uvd->canvas; /* ultracam_size_to_videosize(size);*/ | ||
621 | |||
622 | /* Initialize ibmcam-specific data */ | ||
623 | assert(ULTRACAM_T(uvd) != NULL); | ||
624 | ULTRACAM_T(uvd)->camera_model = 0; /* Not used yet */ | ||
625 | ULTRACAM_T(uvd)->initialized = 0; | ||
626 | |||
627 | ultracam_configure_video(uvd); | ||
628 | |||
629 | i = usbvideo_RegisterVideoDevice(uvd); | ||
630 | if (i != 0) { | ||
631 | err("usbvideo_RegisterVideoDevice() failed."); | ||
632 | uvd = NULL; | ||
633 | } | ||
634 | } | ||
635 | |||
636 | if (uvd) { | ||
637 | usb_set_intfdata (intf, uvd); | ||
638 | return 0; | ||
639 | } | ||
640 | return -EIO; | ||
641 | } | ||
642 | |||
643 | |||
644 | static struct usb_device_id id_table[] = { | ||
645 | { USB_DEVICE(ULTRACAM_VENDOR_ID, ULTRACAM_PRODUCT_ID) }, | ||
646 | { } /* Terminating entry */ | ||
647 | }; | ||
648 | |||
649 | /* | ||
650 | * ultracam_init() | ||
651 | * | ||
652 | * This code is run to initialize the driver. | ||
653 | */ | ||
654 | static int __init ultracam_init(void) | ||
655 | { | ||
656 | struct usbvideo_cb cbTbl; | ||
657 | memset(&cbTbl, 0, sizeof(cbTbl)); | ||
658 | cbTbl.probe = ultracam_probe; | ||
659 | cbTbl.setupOnOpen = ultracam_setup_on_open; | ||
660 | cbTbl.videoStart = ultracam_video_start; | ||
661 | cbTbl.videoStop = ultracam_video_stop; | ||
662 | cbTbl.processData = ultracam_ProcessIsocData; | ||
663 | cbTbl.postProcess = usbvideo_DeinterlaceFrame; | ||
664 | cbTbl.adjustPicture = ultracam_adjust_picture; | ||
665 | cbTbl.getFPS = ultracam_calculate_fps; | ||
666 | return usbvideo_register( | ||
667 | &cams, | ||
668 | MAX_CAMERAS, | ||
669 | sizeof(ultracam_t), | ||
670 | "ultracam", | ||
671 | &cbTbl, | ||
672 | THIS_MODULE, | ||
673 | id_table); | ||
674 | } | ||
675 | |||
676 | static void __exit ultracam_cleanup(void) | ||
677 | { | ||
678 | usbvideo_Deregister(&cams); | ||
679 | } | ||
680 | |||
681 | MODULE_DEVICE_TABLE(usb, id_table); | ||
682 | MODULE_LICENSE("GPL"); | ||
683 | |||
684 | module_init(ultracam_init); | ||
685 | module_exit(ultracam_cleanup); | ||
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c deleted file mode 100644 index f1fcf9744961..000000000000 --- a/drivers/media/video/usbvideo/usbvideo.c +++ /dev/null | |||
@@ -1,2230 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License as published by | ||
4 | * the Free Software Foundation; either version 2, or (at your option) | ||
5 | * any later version. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | * | ||
12 | * You should have received a copy of the GNU General Public License | ||
13 | * along with this program; if not, write to the Free Software | ||
14 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/list.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/mm.h> | ||
23 | #include <linux/vmalloc.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/spinlock.h> | ||
26 | |||
27 | #include <asm/io.h> | ||
28 | |||
29 | #include "usbvideo.h" | ||
30 | |||
31 | #if defined(MAP_NR) | ||
32 | #define virt_to_page(v) MAP_NR(v) /* Kernels 2.2.x */ | ||
33 | #endif | ||
34 | |||
35 | static int video_nr = -1; | ||
36 | module_param(video_nr, int, 0); | ||
37 | |||
38 | /* | ||
39 | * Local prototypes. | ||
40 | */ | ||
41 | static void usbvideo_Disconnect(struct usb_interface *intf); | ||
42 | static void usbvideo_CameraRelease(struct uvd *uvd); | ||
43 | |||
44 | static long usbvideo_v4l_ioctl(struct file *file, | ||
45 | unsigned int cmd, unsigned long arg); | ||
46 | static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma); | ||
47 | static int usbvideo_v4l_open(struct file *file); | ||
48 | static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, | ||
49 | size_t count, loff_t *ppos); | ||
50 | static int usbvideo_v4l_close(struct file *file); | ||
51 | |||
52 | static int usbvideo_StartDataPump(struct uvd *uvd); | ||
53 | static void usbvideo_StopDataPump(struct uvd *uvd); | ||
54 | static int usbvideo_GetFrame(struct uvd *uvd, int frameNum); | ||
55 | static int usbvideo_NewFrame(struct uvd *uvd, int framenum); | ||
56 | static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd, | ||
57 | struct usbvideo_frame *frame); | ||
58 | |||
59 | /*******************************/ | ||
60 | /* Memory management functions */ | ||
61 | /*******************************/ | ||
62 | static void *usbvideo_rvmalloc(unsigned long size) | ||
63 | { | ||
64 | void *mem; | ||
65 | unsigned long adr; | ||
66 | |||
67 | size = PAGE_ALIGN(size); | ||
68 | mem = vmalloc_32(size); | ||
69 | if (!mem) | ||
70 | return NULL; | ||
71 | |||
72 | memset(mem, 0, size); /* Clear the ram out, no junk to the user */ | ||
73 | adr = (unsigned long) mem; | ||
74 | while (size > 0) { | ||
75 | SetPageReserved(vmalloc_to_page((void *)adr)); | ||
76 | adr += PAGE_SIZE; | ||
77 | size -= PAGE_SIZE; | ||
78 | } | ||
79 | |||
80 | return mem; | ||
81 | } | ||
82 | |||
83 | static void usbvideo_rvfree(void *mem, unsigned long size) | ||
84 | { | ||
85 | unsigned long adr; | ||
86 | |||
87 | if (!mem) | ||
88 | return; | ||
89 | |||
90 | adr = (unsigned long) mem; | ||
91 | while ((long) size > 0) { | ||
92 | ClearPageReserved(vmalloc_to_page((void *)adr)); | ||
93 | adr += PAGE_SIZE; | ||
94 | size -= PAGE_SIZE; | ||
95 | } | ||
96 | vfree(mem); | ||
97 | } | ||
98 | |||
99 | static void RingQueue_Initialize(struct RingQueue *rq) | ||
100 | { | ||
101 | assert(rq != NULL); | ||
102 | init_waitqueue_head(&rq->wqh); | ||
103 | } | ||
104 | |||
105 | static void RingQueue_Allocate(struct RingQueue *rq, int rqLen) | ||
106 | { | ||
107 | /* Make sure the requested size is a power of 2 and | ||
108 | round up if necessary. This allows index wrapping | ||
109 | using masks rather than modulo */ | ||
110 | |||
111 | int i = 1; | ||
112 | assert(rq != NULL); | ||
113 | assert(rqLen > 0); | ||
114 | |||
115 | while(rqLen >> i) | ||
116 | i++; | ||
117 | if(rqLen != 1 << (i-1)) | ||
118 | rqLen = 1 << i; | ||
119 | |||
120 | rq->length = rqLen; | ||
121 | rq->ri = rq->wi = 0; | ||
122 | rq->queue = usbvideo_rvmalloc(rq->length); | ||
123 | assert(rq->queue != NULL); | ||
124 | } | ||
125 | |||
126 | static int RingQueue_IsAllocated(const struct RingQueue *rq) | ||
127 | { | ||
128 | if (rq == NULL) | ||
129 | return 0; | ||
130 | return (rq->queue != NULL) && (rq->length > 0); | ||
131 | } | ||
132 | |||
133 | static void RingQueue_Free(struct RingQueue *rq) | ||
134 | { | ||
135 | assert(rq != NULL); | ||
136 | if (RingQueue_IsAllocated(rq)) { | ||
137 | usbvideo_rvfree(rq->queue, rq->length); | ||
138 | rq->queue = NULL; | ||
139 | rq->length = 0; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | int RingQueue_Dequeue(struct RingQueue *rq, unsigned char *dst, int len) | ||
144 | { | ||
145 | int rql, toread; | ||
146 | |||
147 | assert(rq != NULL); | ||
148 | assert(dst != NULL); | ||
149 | |||
150 | rql = RingQueue_GetLength(rq); | ||
151 | if(!rql) | ||
152 | return 0; | ||
153 | |||
154 | /* Clip requested length to available data */ | ||
155 | if(len > rql) | ||
156 | len = rql; | ||
157 | |||
158 | toread = len; | ||
159 | if(rq->ri > rq->wi) { | ||
160 | /* Read data from tail */ | ||
161 | int read = (toread < (rq->length - rq->ri)) ? toread : rq->length - rq->ri; | ||
162 | memcpy(dst, rq->queue + rq->ri, read); | ||
163 | toread -= read; | ||
164 | dst += read; | ||
165 | rq->ri = (rq->ri + read) & (rq->length-1); | ||
166 | } | ||
167 | if(toread) { | ||
168 | /* Read data from head */ | ||
169 | memcpy(dst, rq->queue + rq->ri, toread); | ||
170 | rq->ri = (rq->ri + toread) & (rq->length-1); | ||
171 | } | ||
172 | return len; | ||
173 | } | ||
174 | |||
175 | EXPORT_SYMBOL(RingQueue_Dequeue); | ||
176 | |||
177 | int RingQueue_Enqueue(struct RingQueue *rq, const unsigned char *cdata, int n) | ||
178 | { | ||
179 | int enqueued = 0; | ||
180 | |||
181 | assert(rq != NULL); | ||
182 | assert(cdata != NULL); | ||
183 | assert(rq->length > 0); | ||
184 | while (n > 0) { | ||
185 | int m, q_avail; | ||
186 | |||
187 | /* Calculate the largest chunk that fits the tail of the ring */ | ||
188 | q_avail = rq->length - rq->wi; | ||
189 | if (q_avail <= 0) { | ||
190 | rq->wi = 0; | ||
191 | q_avail = rq->length; | ||
192 | } | ||
193 | m = n; | ||
194 | assert(q_avail > 0); | ||
195 | if (m > q_avail) | ||
196 | m = q_avail; | ||
197 | |||
198 | memcpy(rq->queue + rq->wi, cdata, m); | ||
199 | RING_QUEUE_ADVANCE_INDEX(rq, wi, m); | ||
200 | cdata += m; | ||
201 | enqueued += m; | ||
202 | n -= m; | ||
203 | } | ||
204 | return enqueued; | ||
205 | } | ||
206 | |||
207 | EXPORT_SYMBOL(RingQueue_Enqueue); | ||
208 | |||
209 | static void RingQueue_InterruptibleSleepOn(struct RingQueue *rq) | ||
210 | { | ||
211 | assert(rq != NULL); | ||
212 | interruptible_sleep_on(&rq->wqh); | ||
213 | } | ||
214 | |||
215 | void RingQueue_WakeUpInterruptible(struct RingQueue *rq) | ||
216 | { | ||
217 | assert(rq != NULL); | ||
218 | if (waitqueue_active(&rq->wqh)) | ||
219 | wake_up_interruptible(&rq->wqh); | ||
220 | } | ||
221 | |||
222 | EXPORT_SYMBOL(RingQueue_WakeUpInterruptible); | ||
223 | |||
224 | void RingQueue_Flush(struct RingQueue *rq) | ||
225 | { | ||
226 | assert(rq != NULL); | ||
227 | rq->ri = 0; | ||
228 | rq->wi = 0; | ||
229 | } | ||
230 | |||
231 | EXPORT_SYMBOL(RingQueue_Flush); | ||
232 | |||
233 | |||
234 | /* | ||
235 | * usbvideo_VideosizeToString() | ||
236 | * | ||
237 | * This procedure converts given videosize value to readable string. | ||
238 | * | ||
239 | * History: | ||
240 | * 07-Aug-2000 Created. | ||
241 | * 19-Oct-2000 Reworked for usbvideo module. | ||
242 | */ | ||
243 | static void usbvideo_VideosizeToString(char *buf, int bufLen, videosize_t vs) | ||
244 | { | ||
245 | char tmp[40]; | ||
246 | int n; | ||
247 | |||
248 | n = 1 + sprintf(tmp, "%ldx%ld", VIDEOSIZE_X(vs), VIDEOSIZE_Y(vs)); | ||
249 | assert(n < sizeof(tmp)); | ||
250 | if ((buf == NULL) || (bufLen < n)) | ||
251 | err("usbvideo_VideosizeToString: buffer is too small."); | ||
252 | else | ||
253 | memmove(buf, tmp, n); | ||
254 | } | ||
255 | |||
256 | /* | ||
257 | * usbvideo_OverlayChar() | ||
258 | * | ||
259 | * History: | ||
260 | * 01-Feb-2000 Created. | ||
261 | */ | ||
262 | static void usbvideo_OverlayChar(struct uvd *uvd, struct usbvideo_frame *frame, | ||
263 | int x, int y, int ch) | ||
264 | { | ||
265 | static const unsigned short digits[16] = { | ||
266 | 0xF6DE, /* 0 */ | ||
267 | 0x2492, /* 1 */ | ||
268 | 0xE7CE, /* 2 */ | ||
269 | 0xE79E, /* 3 */ | ||
270 | 0xB792, /* 4 */ | ||
271 | 0xF39E, /* 5 */ | ||
272 | 0xF3DE, /* 6 */ | ||
273 | 0xF492, /* 7 */ | ||
274 | 0xF7DE, /* 8 */ | ||
275 | 0xF79E, /* 9 */ | ||
276 | 0x77DA, /* a */ | ||
277 | 0xD75C, /* b */ | ||
278 | 0xF24E, /* c */ | ||
279 | 0xD6DC, /* d */ | ||
280 | 0xF34E, /* e */ | ||
281 | 0xF348 /* f */ | ||
282 | }; | ||
283 | unsigned short digit; | ||
284 | int ix, iy; | ||
285 | int value; | ||
286 | |||
287 | if ((uvd == NULL) || (frame == NULL)) | ||
288 | return; | ||
289 | |||
290 | value = hex_to_bin(ch); | ||
291 | if (value < 0) | ||
292 | return; | ||
293 | digit = digits[value]; | ||
294 | |||
295 | for (iy=0; iy < 5; iy++) { | ||
296 | for (ix=0; ix < 3; ix++) { | ||
297 | if (digit & 0x8000) { | ||
298 | if (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24)) { | ||
299 | /* TODO */ RGB24_PUTPIXEL(frame, x+ix, y+iy, 0xFF, 0xFF, 0xFF); | ||
300 | } | ||
301 | } | ||
302 | digit = digit << 1; | ||
303 | } | ||
304 | } | ||
305 | } | ||
306 | |||
307 | /* | ||
308 | * usbvideo_OverlayString() | ||
309 | * | ||
310 | * History: | ||
311 | * 01-Feb-2000 Created. | ||
312 | */ | ||
313 | static void usbvideo_OverlayString(struct uvd *uvd, struct usbvideo_frame *frame, | ||
314 | int x, int y, const char *str) | ||
315 | { | ||
316 | while (*str) { | ||
317 | usbvideo_OverlayChar(uvd, frame, x, y, *str); | ||
318 | str++; | ||
319 | x += 4; /* 3 pixels character + 1 space */ | ||
320 | } | ||
321 | } | ||
322 | |||
323 | /* | ||
324 | * usbvideo_OverlayStats() | ||
325 | * | ||
326 | * Overlays important debugging information. | ||
327 | * | ||
328 | * History: | ||
329 | * 01-Feb-2000 Created. | ||
330 | */ | ||
331 | static void usbvideo_OverlayStats(struct uvd *uvd, struct usbvideo_frame *frame) | ||
332 | { | ||
333 | const int y_diff = 8; | ||
334 | char tmp[16]; | ||
335 | int x = 10, y=10; | ||
336 | long i, j, barLength; | ||
337 | const int qi_x1 = 60, qi_y1 = 10; | ||
338 | const int qi_x2 = VIDEOSIZE_X(frame->request) - 10, qi_h = 10; | ||
339 | |||
340 | /* Call the user callback, see if we may proceed after that */ | ||
341 | if (VALID_CALLBACK(uvd, overlayHook)) { | ||
342 | if (GET_CALLBACK(uvd, overlayHook)(uvd, frame) < 0) | ||
343 | return; | ||
344 | } | ||
345 | |||
346 | /* | ||
347 | * We draw a (mostly) hollow rectangle with qi_xxx coordinates. | ||
348 | * Left edge symbolizes the queue index 0; right edge symbolizes | ||
349 | * the full capacity of the queue. | ||
350 | */ | ||
351 | barLength = qi_x2 - qi_x1 - 2; | ||
352 | if ((barLength > 10) && (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24))) { | ||
353 | /* TODO */ long u_lo, u_hi, q_used; | ||
354 | long m_ri, m_wi, m_lo, m_hi; | ||
355 | |||
356 | /* | ||
357 | * Determine fill zones (used areas of the queue): | ||
358 | * 0 xxxxxxx u_lo ...... uvd->dp.ri xxxxxxxx u_hi ..... uvd->dp.length | ||
359 | * | ||
360 | * if u_lo < 0 then there is no first filler. | ||
361 | */ | ||
362 | |||
363 | q_used = RingQueue_GetLength(&uvd->dp); | ||
364 | if ((uvd->dp.ri + q_used) >= uvd->dp.length) { | ||
365 | u_hi = uvd->dp.length; | ||
366 | u_lo = (q_used + uvd->dp.ri) & (uvd->dp.length-1); | ||
367 | } else { | ||
368 | u_hi = (q_used + uvd->dp.ri); | ||
369 | u_lo = -1; | ||
370 | } | ||
371 | |||
372 | /* Convert byte indices into screen units */ | ||
373 | m_ri = qi_x1 + ((barLength * uvd->dp.ri) / uvd->dp.length); | ||
374 | m_wi = qi_x1 + ((barLength * uvd->dp.wi) / uvd->dp.length); | ||
375 | m_lo = (u_lo > 0) ? (qi_x1 + ((barLength * u_lo) / uvd->dp.length)) : -1; | ||
376 | m_hi = qi_x1 + ((barLength * u_hi) / uvd->dp.length); | ||
377 | |||
378 | for (j=qi_y1; j < (qi_y1 + qi_h); j++) { | ||
379 | for (i=qi_x1; i < qi_x2; i++) { | ||
380 | /* Draw border lines */ | ||
381 | if ((j == qi_y1) || (j == (qi_y1 + qi_h - 1)) || | ||
382 | (i == qi_x1) || (i == (qi_x2 - 1))) { | ||
383 | RGB24_PUTPIXEL(frame, i, j, 0xFF, 0xFF, 0xFF); | ||
384 | continue; | ||
385 | } | ||
386 | /* For all other points the Y coordinate does not matter */ | ||
387 | if ((i >= m_ri) && (i <= (m_ri + 3))) { | ||
388 | RGB24_PUTPIXEL(frame, i, j, 0x00, 0xFF, 0x00); | ||
389 | } else if ((i >= m_wi) && (i <= (m_wi + 3))) { | ||
390 | RGB24_PUTPIXEL(frame, i, j, 0xFF, 0x00, 0x00); | ||
391 | } else if ((i < m_lo) || ((i > m_ri) && (i < m_hi))) | ||
392 | RGB24_PUTPIXEL(frame, i, j, 0x00, 0x00, 0xFF); | ||
393 | } | ||
394 | } | ||
395 | } | ||
396 | |||
397 | sprintf(tmp, "%8lx", uvd->stats.frame_num); | ||
398 | usbvideo_OverlayString(uvd, frame, x, y, tmp); | ||
399 | y += y_diff; | ||
400 | |||
401 | sprintf(tmp, "%8lx", uvd->stats.urb_count); | ||
402 | usbvideo_OverlayString(uvd, frame, x, y, tmp); | ||
403 | y += y_diff; | ||
404 | |||
405 | sprintf(tmp, "%8lx", uvd->stats.urb_length); | ||
406 | usbvideo_OverlayString(uvd, frame, x, y, tmp); | ||
407 | y += y_diff; | ||
408 | |||
409 | sprintf(tmp, "%8lx", uvd->stats.data_count); | ||
410 | usbvideo_OverlayString(uvd, frame, x, y, tmp); | ||
411 | y += y_diff; | ||
412 | |||
413 | sprintf(tmp, "%8lx", uvd->stats.header_count); | ||
414 | usbvideo_OverlayString(uvd, frame, x, y, tmp); | ||
415 | y += y_diff; | ||
416 | |||
417 | sprintf(tmp, "%8lx", uvd->stats.iso_skip_count); | ||
418 | usbvideo_OverlayString(uvd, frame, x, y, tmp); | ||
419 | y += y_diff; | ||
420 | |||
421 | sprintf(tmp, "%8lx", uvd->stats.iso_err_count); | ||
422 | usbvideo_OverlayString(uvd, frame, x, y, tmp); | ||
423 | y += y_diff; | ||
424 | |||
425 | sprintf(tmp, "%8x", uvd->vpic.colour); | ||
426 | usbvideo_OverlayString(uvd, frame, x, y, tmp); | ||
427 | y += y_diff; | ||
428 | |||
429 | sprintf(tmp, "%8x", uvd->vpic.hue); | ||
430 | usbvideo_OverlayString(uvd, frame, x, y, tmp); | ||
431 | y += y_diff; | ||
432 | |||
433 | sprintf(tmp, "%8x", uvd->vpic.brightness >> 8); | ||
434 | usbvideo_OverlayString(uvd, frame, x, y, tmp); | ||
435 | y += y_diff; | ||
436 | |||
437 | sprintf(tmp, "%8x", uvd->vpic.contrast >> 12); | ||
438 | usbvideo_OverlayString(uvd, frame, x, y, tmp); | ||
439 | y += y_diff; | ||
440 | |||
441 | sprintf(tmp, "%8d", uvd->vpic.whiteness >> 8); | ||
442 | usbvideo_OverlayString(uvd, frame, x, y, tmp); | ||
443 | y += y_diff; | ||
444 | } | ||
445 | |||
446 | /* | ||
447 | * usbvideo_ReportStatistics() | ||
448 | * | ||
449 | * This procedure prints packet and transfer statistics. | ||
450 | * | ||
451 | * History: | ||
452 | * 14-Jan-2000 Corrected default multiplier. | ||
453 | */ | ||
454 | static void usbvideo_ReportStatistics(const struct uvd *uvd) | ||
455 | { | ||
456 | if ((uvd != NULL) && (uvd->stats.urb_count > 0)) { | ||
457 | unsigned long allPackets, badPackets, goodPackets, percent; | ||
458 | allPackets = uvd->stats.urb_count * CAMERA_URB_FRAMES; | ||
459 | badPackets = uvd->stats.iso_skip_count + uvd->stats.iso_err_count; | ||
460 | goodPackets = allPackets - badPackets; | ||
461 | /* Calculate percentage wisely, remember integer limits */ | ||
462 | assert(allPackets != 0); | ||
463 | if (goodPackets < (((unsigned long)-1)/100)) | ||
464 | percent = (100 * goodPackets) / allPackets; | ||
465 | else | ||
466 | percent = goodPackets / (allPackets / 100); | ||
467 | dev_info(&uvd->dev->dev, | ||
468 | "Packet Statistics: Total=%lu. Empty=%lu. Usage=%lu%%\n", | ||
469 | allPackets, badPackets, percent); | ||
470 | if (uvd->iso_packet_len > 0) { | ||
471 | unsigned long allBytes, xferBytes; | ||
472 | char multiplier = ' '; | ||
473 | allBytes = allPackets * uvd->iso_packet_len; | ||
474 | xferBytes = uvd->stats.data_count; | ||
475 | assert(allBytes != 0); | ||
476 | if (xferBytes < (((unsigned long)-1)/100)) | ||
477 | percent = (100 * xferBytes) / allBytes; | ||
478 | else | ||
479 | percent = xferBytes / (allBytes / 100); | ||
480 | /* Scale xferBytes for easy reading */ | ||
481 | if (xferBytes > 10*1024) { | ||
482 | xferBytes /= 1024; | ||
483 | multiplier = 'K'; | ||
484 | if (xferBytes > 10*1024) { | ||
485 | xferBytes /= 1024; | ||
486 | multiplier = 'M'; | ||
487 | if (xferBytes > 10*1024) { | ||
488 | xferBytes /= 1024; | ||
489 | multiplier = 'G'; | ||
490 | if (xferBytes > 10*1024) { | ||
491 | xferBytes /= 1024; | ||
492 | multiplier = 'T'; | ||
493 | } | ||
494 | } | ||
495 | } | ||
496 | } | ||
497 | dev_info(&uvd->dev->dev, | ||
498 | "Transfer Statistics: Transferred=%lu%cB Usage=%lu%%\n", | ||
499 | xferBytes, multiplier, percent); | ||
500 | } | ||
501 | } | ||
502 | } | ||
503 | |||
504 | /* | ||
505 | * usbvideo_TestPattern() | ||
506 | * | ||
507 | * Procedure forms a test pattern (yellow grid on blue background). | ||
508 | * | ||
509 | * Parameters: | ||
510 | * fullframe: if TRUE then entire frame is filled, otherwise the procedure | ||
511 | * continues from the current scanline. | ||
512 | * pmode 0: fill the frame with solid blue color (like on VCR or TV) | ||
513 | * 1: Draw a colored grid | ||
514 | * | ||
515 | * History: | ||
516 | * 01-Feb-2000 Created. | ||
517 | */ | ||
518 | void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode) | ||
519 | { | ||
520 | struct usbvideo_frame *frame; | ||
521 | int num_cell = 0; | ||
522 | int scan_length = 0; | ||
523 | static int num_pass; | ||
524 | |||
525 | if (uvd == NULL) { | ||
526 | err("%s: uvd == NULL", __func__); | ||
527 | return; | ||
528 | } | ||
529 | if ((uvd->curframe < 0) || (uvd->curframe >= USBVIDEO_NUMFRAMES)) { | ||
530 | err("%s: uvd->curframe=%d.", __func__, uvd->curframe); | ||
531 | return; | ||
532 | } | ||
533 | |||
534 | /* Grab the current frame */ | ||
535 | frame = &uvd->frame[uvd->curframe]; | ||
536 | |||
537 | /* Optionally start at the beginning */ | ||
538 | if (fullframe) { | ||
539 | frame->curline = 0; | ||
540 | frame->seqRead_Length = 0; | ||
541 | } | ||
542 | #if 0 | ||
543 | { /* For debugging purposes only */ | ||
544 | char tmp[20]; | ||
545 | usbvideo_VideosizeToString(tmp, sizeof(tmp), frame->request); | ||
546 | dev_info(&uvd->dev->dev, "testpattern: frame=%s\n", tmp); | ||
547 | } | ||
548 | #endif | ||
549 | /* Form every scan line */ | ||
550 | for (; frame->curline < VIDEOSIZE_Y(frame->request); frame->curline++) { | ||
551 | int i; | ||
552 | unsigned char *f = frame->data + | ||
553 | (VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL * frame->curline); | ||
554 | for (i=0; i < VIDEOSIZE_X(frame->request); i++) { | ||
555 | unsigned char cb=0x80; | ||
556 | unsigned char cg = 0; | ||
557 | unsigned char cr = 0; | ||
558 | |||
559 | if (pmode == 1) { | ||
560 | if (frame->curline % 32 == 0) | ||
561 | cb = 0, cg = cr = 0xFF; | ||
562 | else if (i % 32 == 0) { | ||
563 | if (frame->curline % 32 == 1) | ||
564 | num_cell++; | ||
565 | cb = 0, cg = cr = 0xFF; | ||
566 | } else { | ||
567 | cb = ((num_cell*7) + num_pass) & 0xFF; | ||
568 | cg = ((num_cell*5) + num_pass*2) & 0xFF; | ||
569 | cr = ((num_cell*3) + num_pass*3) & 0xFF; | ||
570 | } | ||
571 | } else { | ||
572 | /* Just the blue screen */ | ||
573 | } | ||
574 | |||
575 | *f++ = cb; | ||
576 | *f++ = cg; | ||
577 | *f++ = cr; | ||
578 | scan_length += 3; | ||
579 | } | ||
580 | } | ||
581 | |||
582 | frame->frameState = FrameState_Done; | ||
583 | frame->seqRead_Length += scan_length; | ||
584 | ++num_pass; | ||
585 | |||
586 | /* We do this unconditionally, regardless of FLAGS_OVERLAY_STATS */ | ||
587 | usbvideo_OverlayStats(uvd, frame); | ||
588 | } | ||
589 | |||
590 | EXPORT_SYMBOL(usbvideo_TestPattern); | ||
591 | |||
592 | |||
593 | #ifdef DEBUG | ||
594 | /* | ||
595 | * usbvideo_HexDump() | ||
596 | * | ||
597 | * A debugging tool. Prints hex dumps. | ||
598 | * | ||
599 | * History: | ||
600 | * 29-Jul-2000 Added printing of offsets. | ||
601 | */ | ||
602 | void usbvideo_HexDump(const unsigned char *data, int len) | ||
603 | { | ||
604 | const int bytes_per_line = 32; | ||
605 | char tmp[128]; /* 32*3 + 5 */ | ||
606 | int i, k; | ||
607 | |||
608 | for (i=k=0; len > 0; i++, len--) { | ||
609 | if (i > 0 && ((i % bytes_per_line) == 0)) { | ||
610 | printk("%s\n", tmp); | ||
611 | k=0; | ||
612 | } | ||
613 | if ((i % bytes_per_line) == 0) | ||
614 | k += sprintf(&tmp[k], "%04x: ", i); | ||
615 | k += sprintf(&tmp[k], "%02x ", data[i]); | ||
616 | } | ||
617 | if (k > 0) | ||
618 | printk("%s\n", tmp); | ||
619 | } | ||
620 | |||
621 | EXPORT_SYMBOL(usbvideo_HexDump); | ||
622 | |||
623 | #endif | ||
624 | |||
625 | /* ******************************************************************** */ | ||
626 | |||
627 | /* XXX: this piece of crap really wants some error handling.. */ | ||
628 | static int usbvideo_ClientIncModCount(struct uvd *uvd) | ||
629 | { | ||
630 | if (uvd == NULL) { | ||
631 | err("%s: uvd == NULL", __func__); | ||
632 | return -EINVAL; | ||
633 | } | ||
634 | if (uvd->handle == NULL) { | ||
635 | err("%s: uvd->handle == NULL", __func__); | ||
636 | return -EINVAL; | ||
637 | } | ||
638 | if (!try_module_get(uvd->handle->md_module)) { | ||
639 | err("%s: try_module_get() == 0", __func__); | ||
640 | return -ENODEV; | ||
641 | } | ||
642 | return 0; | ||
643 | } | ||
644 | |||
645 | static void usbvideo_ClientDecModCount(struct uvd *uvd) | ||
646 | { | ||
647 | if (uvd == NULL) { | ||
648 | err("%s: uvd == NULL", __func__); | ||
649 | return; | ||
650 | } | ||
651 | if (uvd->handle == NULL) { | ||
652 | err("%s: uvd->handle == NULL", __func__); | ||
653 | return; | ||
654 | } | ||
655 | if (uvd->handle->md_module == NULL) { | ||
656 | err("%s: uvd->handle->md_module == NULL", __func__); | ||
657 | return; | ||
658 | } | ||
659 | module_put(uvd->handle->md_module); | ||
660 | } | ||
661 | |||
662 | int usbvideo_register( | ||
663 | struct usbvideo **pCams, | ||
664 | const int num_cams, | ||
665 | const int num_extra, | ||
666 | const char *driverName, | ||
667 | const struct usbvideo_cb *cbTbl, | ||
668 | struct module *md, | ||
669 | const struct usb_device_id *id_table) | ||
670 | { | ||
671 | struct usbvideo *cams; | ||
672 | int i, base_size, result; | ||
673 | |||
674 | /* Check parameters for sanity */ | ||
675 | if ((num_cams <= 0) || (pCams == NULL) || (cbTbl == NULL)) { | ||
676 | err("%s: Illegal call", __func__); | ||
677 | return -EINVAL; | ||
678 | } | ||
679 | |||
680 | /* Check registration callback - must be set! */ | ||
681 | if (cbTbl->probe == NULL) { | ||
682 | err("%s: probe() is required!", __func__); | ||
683 | return -EINVAL; | ||
684 | } | ||
685 | |||
686 | base_size = num_cams * sizeof(struct uvd) + sizeof(struct usbvideo); | ||
687 | cams = kzalloc(base_size, GFP_KERNEL); | ||
688 | if (cams == NULL) { | ||
689 | err("Failed to allocate %d. bytes for usbvideo struct", base_size); | ||
690 | return -ENOMEM; | ||
691 | } | ||
692 | dbg("%s: Allocated $%p (%d. bytes) for %d. cameras", | ||
693 | __func__, cams, base_size, num_cams); | ||
694 | |||
695 | /* Copy callbacks, apply defaults for those that are not set */ | ||
696 | memmove(&cams->cb, cbTbl, sizeof(cams->cb)); | ||
697 | if (cams->cb.getFrame == NULL) | ||
698 | cams->cb.getFrame = usbvideo_GetFrame; | ||
699 | if (cams->cb.disconnect == NULL) | ||
700 | cams->cb.disconnect = usbvideo_Disconnect; | ||
701 | if (cams->cb.startDataPump == NULL) | ||
702 | cams->cb.startDataPump = usbvideo_StartDataPump; | ||
703 | if (cams->cb.stopDataPump == NULL) | ||
704 | cams->cb.stopDataPump = usbvideo_StopDataPump; | ||
705 | |||
706 | cams->num_cameras = num_cams; | ||
707 | cams->cam = (struct uvd *) &cams[1]; | ||
708 | cams->md_module = md; | ||
709 | mutex_init(&cams->lock); /* to 1 == available */ | ||
710 | |||
711 | for (i = 0; i < num_cams; i++) { | ||
712 | struct uvd *up = &cams->cam[i]; | ||
713 | |||
714 | up->handle = cams; | ||
715 | |||
716 | /* Allocate user_data separately because of kmalloc's limits */ | ||
717 | if (num_extra > 0) { | ||
718 | up->user_size = num_cams * num_extra; | ||
719 | up->user_data = kmalloc(up->user_size, GFP_KERNEL); | ||
720 | if (up->user_data == NULL) { | ||
721 | err("%s: Failed to allocate user_data (%d. bytes)", | ||
722 | __func__, up->user_size); | ||
723 | while (i) { | ||
724 | up = &cams->cam[--i]; | ||
725 | kfree(up->user_data); | ||
726 | } | ||
727 | kfree(cams); | ||
728 | return -ENOMEM; | ||
729 | } | ||
730 | dbg("%s: Allocated cams[%d].user_data=$%p (%d. bytes)", | ||
731 | __func__, i, up->user_data, up->user_size); | ||
732 | } | ||
733 | } | ||
734 | |||
735 | /* | ||
736 | * Register ourselves with USB stack. | ||
737 | */ | ||
738 | strcpy(cams->drvName, (driverName != NULL) ? driverName : "Unknown"); | ||
739 | cams->usbdrv.name = cams->drvName; | ||
740 | cams->usbdrv.probe = cams->cb.probe; | ||
741 | cams->usbdrv.disconnect = cams->cb.disconnect; | ||
742 | cams->usbdrv.id_table = id_table; | ||
743 | |||
744 | /* | ||
745 | * Update global handle to usbvideo. This is very important | ||
746 | * because probe() can be called before usb_register() returns. | ||
747 | * If the handle is not yet updated then the probe() will fail. | ||
748 | */ | ||
749 | *pCams = cams; | ||
750 | result = usb_register(&cams->usbdrv); | ||
751 | if (result) { | ||
752 | for (i = 0; i < num_cams; i++) { | ||
753 | struct uvd *up = &cams->cam[i]; | ||
754 | kfree(up->user_data); | ||
755 | } | ||
756 | kfree(cams); | ||
757 | } | ||
758 | |||
759 | return result; | ||
760 | } | ||
761 | |||
762 | EXPORT_SYMBOL(usbvideo_register); | ||
763 | |||
764 | /* | ||
765 | * usbvideo_Deregister() | ||
766 | * | ||
767 | * Procedure frees all usbvideo and user data structures. Be warned that | ||
768 | * if you had some dynamically allocated components in ->user field then | ||
769 | * you should free them before calling here. | ||
770 | */ | ||
771 | void usbvideo_Deregister(struct usbvideo **pCams) | ||
772 | { | ||
773 | struct usbvideo *cams; | ||
774 | int i; | ||
775 | |||
776 | if (pCams == NULL) { | ||
777 | err("%s: pCams == NULL", __func__); | ||
778 | return; | ||
779 | } | ||
780 | cams = *pCams; | ||
781 | if (cams == NULL) { | ||
782 | err("%s: cams == NULL", __func__); | ||
783 | return; | ||
784 | } | ||
785 | |||
786 | dbg("%s: Deregistering %s driver.", __func__, cams->drvName); | ||
787 | usb_deregister(&cams->usbdrv); | ||
788 | |||
789 | dbg("%s: Deallocating cams=$%p (%d. cameras)", __func__, cams, cams->num_cameras); | ||
790 | for (i=0; i < cams->num_cameras; i++) { | ||
791 | struct uvd *up = &cams->cam[i]; | ||
792 | int warning = 0; | ||
793 | |||
794 | if (up->user_data != NULL) { | ||
795 | if (up->user_size <= 0) | ||
796 | ++warning; | ||
797 | } else { | ||
798 | if (up->user_size > 0) | ||
799 | ++warning; | ||
800 | } | ||
801 | if (warning) { | ||
802 | err("%s: Warning: user_data=$%p user_size=%d.", | ||
803 | __func__, up->user_data, up->user_size); | ||
804 | } else { | ||
805 | dbg("%s: Freeing %d. $%p->user_data=$%p", | ||
806 | __func__, i, up, up->user_data); | ||
807 | kfree(up->user_data); | ||
808 | } | ||
809 | } | ||
810 | /* Whole array was allocated in one chunk */ | ||
811 | dbg("%s: Freed %d uvd structures", | ||
812 | __func__, cams->num_cameras); | ||
813 | kfree(cams); | ||
814 | *pCams = NULL; | ||
815 | } | ||
816 | |||
817 | EXPORT_SYMBOL(usbvideo_Deregister); | ||
818 | |||
819 | /* | ||
820 | * usbvideo_Disconnect() | ||
821 | * | ||
822 | * This procedure stops all driver activity. Deallocation of | ||
823 | * the interface-private structure (pointed by 'ptr') is done now | ||
824 | * (if we don't have any open files) or later, when those files | ||
825 | * are closed. After that driver should be removable. | ||
826 | * | ||
827 | * This code handles surprise removal. The uvd->user is a counter which | ||
828 | * increments on open() and decrements on close(). If we see here that | ||
829 | * this counter is not 0 then we have a client who still has us opened. | ||
830 | * We set uvd->remove_pending flag as early as possible, and after that | ||
831 | * all access to the camera will gracefully fail. These failures should | ||
832 | * prompt client to (eventually) close the video device, and then - in | ||
833 | * usbvideo_v4l_close() - we decrement uvd->uvd_used and usage counter. | ||
834 | * | ||
835 | * History: | ||
836 | * 22-Jan-2000 Added polling of MOD_IN_USE to delay removal until all users gone. | ||
837 | * 27-Jan-2000 Reworked to allow pending disconnects; see xxx_close() | ||
838 | * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT). | ||
839 | * 19-Oct-2000 Moved to usbvideo module. | ||
840 | */ | ||
841 | static void usbvideo_Disconnect(struct usb_interface *intf) | ||
842 | { | ||
843 | struct uvd *uvd = usb_get_intfdata (intf); | ||
844 | int i; | ||
845 | |||
846 | if (uvd == NULL) { | ||
847 | err("%s($%p): Illegal call.", __func__, intf); | ||
848 | return; | ||
849 | } | ||
850 | |||
851 | usb_set_intfdata (intf, NULL); | ||
852 | |||
853 | usbvideo_ClientIncModCount(uvd); | ||
854 | if (uvd->debug > 0) | ||
855 | dev_info(&intf->dev, "%s(%p.)\n", __func__, intf); | ||
856 | |||
857 | mutex_lock(&uvd->lock); | ||
858 | uvd->remove_pending = 1; /* Now all ISO data will be ignored */ | ||
859 | |||
860 | /* At this time we ask to cancel outstanding URBs */ | ||
861 | GET_CALLBACK(uvd, stopDataPump)(uvd); | ||
862 | |||
863 | for (i=0; i < USBVIDEO_NUMSBUF; i++) | ||
864 | usb_free_urb(uvd->sbuf[i].urb); | ||
865 | |||
866 | usb_put_dev(uvd->dev); | ||
867 | uvd->dev = NULL; /* USB device is no more */ | ||
868 | |||
869 | video_unregister_device(&uvd->vdev); | ||
870 | if (uvd->debug > 0) | ||
871 | dev_info(&intf->dev, "%s: Video unregistered.\n", __func__); | ||
872 | |||
873 | if (uvd->user) | ||
874 | dev_info(&intf->dev, "%s: In use, disconnect pending.\n", | ||
875 | __func__); | ||
876 | else | ||
877 | usbvideo_CameraRelease(uvd); | ||
878 | mutex_unlock(&uvd->lock); | ||
879 | dev_info(&intf->dev, "USB camera disconnected.\n"); | ||
880 | |||
881 | usbvideo_ClientDecModCount(uvd); | ||
882 | } | ||
883 | |||
884 | /* | ||
885 | * usbvideo_CameraRelease() | ||
886 | * | ||
887 | * This code does final release of uvd. This happens | ||
888 | * after the device is disconnected -and- all clients | ||
889 | * closed their files. | ||
890 | * | ||
891 | * History: | ||
892 | * 27-Jan-2000 Created. | ||
893 | */ | ||
894 | static void usbvideo_CameraRelease(struct uvd *uvd) | ||
895 | { | ||
896 | if (uvd == NULL) { | ||
897 | err("%s: Illegal call", __func__); | ||
898 | return; | ||
899 | } | ||
900 | |||
901 | RingQueue_Free(&uvd->dp); | ||
902 | if (VALID_CALLBACK(uvd, userFree)) | ||
903 | GET_CALLBACK(uvd, userFree)(uvd); | ||
904 | uvd->uvd_used = 0; /* This is atomic, no need to take mutex */ | ||
905 | } | ||
906 | |||
907 | /* | ||
908 | * usbvideo_find_struct() | ||
909 | * | ||
910 | * This code searches the array of preallocated (static) structures | ||
911 | * and returns index of the first one that isn't in use. Returns -1 | ||
912 | * if there are no free structures. | ||
913 | * | ||
914 | * History: | ||
915 | * 27-Jan-2000 Created. | ||
916 | */ | ||
917 | static int usbvideo_find_struct(struct usbvideo *cams) | ||
918 | { | ||
919 | int u, rv = -1; | ||
920 | |||
921 | if (cams == NULL) { | ||
922 | err("No usbvideo handle?"); | ||
923 | return -1; | ||
924 | } | ||
925 | mutex_lock(&cams->lock); | ||
926 | for (u = 0; u < cams->num_cameras; u++) { | ||
927 | struct uvd *uvd = &cams->cam[u]; | ||
928 | if (!uvd->uvd_used) /* This one is free */ | ||
929 | { | ||
930 | uvd->uvd_used = 1; /* In use now */ | ||
931 | mutex_init(&uvd->lock); /* to 1 == available */ | ||
932 | uvd->dev = NULL; | ||
933 | rv = u; | ||
934 | break; | ||
935 | } | ||
936 | } | ||
937 | mutex_unlock(&cams->lock); | ||
938 | return rv; | ||
939 | } | ||
940 | |||
941 | static const struct v4l2_file_operations usbvideo_fops = { | ||
942 | .owner = THIS_MODULE, | ||
943 | .open = usbvideo_v4l_open, | ||
944 | .release =usbvideo_v4l_close, | ||
945 | .read = usbvideo_v4l_read, | ||
946 | .mmap = usbvideo_v4l_mmap, | ||
947 | .ioctl = usbvideo_v4l_ioctl, | ||
948 | }; | ||
949 | static const struct video_device usbvideo_template = { | ||
950 | .fops = &usbvideo_fops, | ||
951 | }; | ||
952 | |||
953 | struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams) | ||
954 | { | ||
955 | int i, devnum; | ||
956 | struct uvd *uvd = NULL; | ||
957 | |||
958 | if (cams == NULL) { | ||
959 | err("No usbvideo handle?"); | ||
960 | return NULL; | ||
961 | } | ||
962 | |||
963 | devnum = usbvideo_find_struct(cams); | ||
964 | if (devnum == -1) { | ||
965 | err("IBM USB camera driver: Too many devices!"); | ||
966 | return NULL; | ||
967 | } | ||
968 | uvd = &cams->cam[devnum]; | ||
969 | dbg("Device entry #%d. at $%p", devnum, uvd); | ||
970 | |||
971 | /* Not relying upon caller we increase module counter ourselves */ | ||
972 | usbvideo_ClientIncModCount(uvd); | ||
973 | |||
974 | mutex_lock(&uvd->lock); | ||
975 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | ||
976 | uvd->sbuf[i].urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); | ||
977 | if (uvd->sbuf[i].urb == NULL) { | ||
978 | err("usb_alloc_urb(%d.) failed.", FRAMES_PER_DESC); | ||
979 | uvd->uvd_used = 0; | ||
980 | uvd = NULL; | ||
981 | goto allocate_done; | ||
982 | } | ||
983 | } | ||
984 | uvd->user=0; | ||
985 | uvd->remove_pending = 0; | ||
986 | uvd->last_error = 0; | ||
987 | RingQueue_Initialize(&uvd->dp); | ||
988 | |||
989 | /* Initialize video device structure */ | ||
990 | uvd->vdev = usbvideo_template; | ||
991 | sprintf(uvd->vdev.name, "%.20s USB Camera", cams->drvName); | ||
992 | /* | ||
993 | * The client is free to overwrite those because we | ||
994 | * return control to the client's probe function right now. | ||
995 | */ | ||
996 | allocate_done: | ||
997 | mutex_unlock(&uvd->lock); | ||
998 | usbvideo_ClientDecModCount(uvd); | ||
999 | return uvd; | ||
1000 | } | ||
1001 | |||
1002 | EXPORT_SYMBOL(usbvideo_AllocateDevice); | ||
1003 | |||
1004 | int usbvideo_RegisterVideoDevice(struct uvd *uvd) | ||
1005 | { | ||
1006 | char tmp1[20], tmp2[20]; /* Buffers for printing */ | ||
1007 | |||
1008 | if (uvd == NULL) { | ||
1009 | err("%s: Illegal call.", __func__); | ||
1010 | return -EINVAL; | ||
1011 | } | ||
1012 | if (uvd->video_endp == 0) { | ||
1013 | dev_info(&uvd->dev->dev, | ||
1014 | "%s: No video endpoint specified; data pump disabled.\n", | ||
1015 | __func__); | ||
1016 | } | ||
1017 | if (uvd->paletteBits == 0) { | ||
1018 | err("%s: No palettes specified!", __func__); | ||
1019 | return -EINVAL; | ||
1020 | } | ||
1021 | if (uvd->defaultPalette == 0) { | ||
1022 | dev_info(&uvd->dev->dev, "%s: No default palette!\n", | ||
1023 | __func__); | ||
1024 | } | ||
1025 | |||
1026 | uvd->max_frame_size = VIDEOSIZE_X(uvd->canvas) * | ||
1027 | VIDEOSIZE_Y(uvd->canvas) * V4L_BYTES_PER_PIXEL; | ||
1028 | usbvideo_VideosizeToString(tmp1, sizeof(tmp1), uvd->videosize); | ||
1029 | usbvideo_VideosizeToString(tmp2, sizeof(tmp2), uvd->canvas); | ||
1030 | |||
1031 | if (uvd->debug > 0) { | ||
1032 | dev_info(&uvd->dev->dev, | ||
1033 | "%s: iface=%d. endpoint=$%02x paletteBits=$%08lx\n", | ||
1034 | __func__, uvd->iface, uvd->video_endp, | ||
1035 | uvd->paletteBits); | ||
1036 | } | ||
1037 | if (uvd->dev == NULL) { | ||
1038 | err("%s: uvd->dev == NULL", __func__); | ||
1039 | return -EINVAL; | ||
1040 | } | ||
1041 | uvd->vdev.parent = &uvd->dev->dev; | ||
1042 | uvd->vdev.release = video_device_release_empty; | ||
1043 | if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { | ||
1044 | err("%s: video_register_device failed", __func__); | ||
1045 | return -EPIPE; | ||
1046 | } | ||
1047 | if (uvd->debug > 1) { | ||
1048 | dev_info(&uvd->dev->dev, | ||
1049 | "%s: video_register_device() successful\n", __func__); | ||
1050 | } | ||
1051 | |||
1052 | dev_info(&uvd->dev->dev, "%s on %s: canvas=%s videosize=%s\n", | ||
1053 | (uvd->handle != NULL) ? uvd->handle->drvName : "???", | ||
1054 | video_device_node_name(&uvd->vdev), tmp2, tmp1); | ||
1055 | |||
1056 | usb_get_dev(uvd->dev); | ||
1057 | return 0; | ||
1058 | } | ||
1059 | |||
1060 | EXPORT_SYMBOL(usbvideo_RegisterVideoDevice); | ||
1061 | |||
1062 | /* ******************************************************************** */ | ||
1063 | |||
1064 | static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma) | ||
1065 | { | ||
1066 | struct uvd *uvd = file->private_data; | ||
1067 | unsigned long start = vma->vm_start; | ||
1068 | unsigned long size = vma->vm_end-vma->vm_start; | ||
1069 | unsigned long page, pos; | ||
1070 | |||
1071 | if (!CAMERA_IS_OPERATIONAL(uvd)) | ||
1072 | return -EFAULT; | ||
1073 | |||
1074 | if (size > (((USBVIDEO_NUMFRAMES * uvd->max_frame_size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) | ||
1075 | return -EINVAL; | ||
1076 | |||
1077 | pos = (unsigned long) uvd->fbuf; | ||
1078 | while (size > 0) { | ||
1079 | page = vmalloc_to_pfn((void *)pos); | ||
1080 | if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) | ||
1081 | return -EAGAIN; | ||
1082 | |||
1083 | start += PAGE_SIZE; | ||
1084 | pos += PAGE_SIZE; | ||
1085 | if (size > PAGE_SIZE) | ||
1086 | size -= PAGE_SIZE; | ||
1087 | else | ||
1088 | size = 0; | ||
1089 | } | ||
1090 | |||
1091 | return 0; | ||
1092 | } | ||
1093 | |||
1094 | /* | ||
1095 | * usbvideo_v4l_open() | ||
1096 | * | ||
1097 | * This is part of Video 4 Linux API. The driver can be opened by one | ||
1098 | * client only (checks internal counter 'uvdser'). The procedure | ||
1099 | * then allocates buffers needed for video processing. | ||
1100 | * | ||
1101 | * History: | ||
1102 | * 22-Jan-2000 Rewrote, moved scratch buffer allocation here. Now the | ||
1103 | * camera is also initialized here (once per connect), at | ||
1104 | * expense of V4L client (it waits on open() call). | ||
1105 | * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers. | ||
1106 | * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT). | ||
1107 | */ | ||
1108 | static int usbvideo_v4l_open(struct file *file) | ||
1109 | { | ||
1110 | struct video_device *dev = video_devdata(file); | ||
1111 | struct uvd *uvd = (struct uvd *) dev; | ||
1112 | const int sb_size = FRAMES_PER_DESC * uvd->iso_packet_len; | ||
1113 | int i, errCode = 0; | ||
1114 | |||
1115 | if (uvd->debug > 1) | ||
1116 | dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, dev); | ||
1117 | |||
1118 | if (usbvideo_ClientIncModCount(uvd) < 0) | ||
1119 | return -ENODEV; | ||
1120 | mutex_lock(&uvd->lock); | ||
1121 | |||
1122 | if (uvd->user) { | ||
1123 | err("%s: Someone tried to open an already opened device!", __func__); | ||
1124 | errCode = -EBUSY; | ||
1125 | } else { | ||
1126 | /* Clear statistics */ | ||
1127 | memset(&uvd->stats, 0, sizeof(uvd->stats)); | ||
1128 | |||
1129 | /* Clean pointers so we know if we allocated something */ | ||
1130 | for (i=0; i < USBVIDEO_NUMSBUF; i++) | ||
1131 | uvd->sbuf[i].data = NULL; | ||
1132 | |||
1133 | /* Allocate memory for the frame buffers */ | ||
1134 | uvd->fbuf_size = USBVIDEO_NUMFRAMES * uvd->max_frame_size; | ||
1135 | uvd->fbuf = usbvideo_rvmalloc(uvd->fbuf_size); | ||
1136 | RingQueue_Allocate(&uvd->dp, RING_QUEUE_SIZE); | ||
1137 | if ((uvd->fbuf == NULL) || | ||
1138 | (!RingQueue_IsAllocated(&uvd->dp))) { | ||
1139 | err("%s: Failed to allocate fbuf or dp", __func__); | ||
1140 | errCode = -ENOMEM; | ||
1141 | } else { | ||
1142 | /* Allocate all buffers */ | ||
1143 | for (i=0; i < USBVIDEO_NUMFRAMES; i++) { | ||
1144 | uvd->frame[i].frameState = FrameState_Unused; | ||
1145 | uvd->frame[i].data = uvd->fbuf + i*(uvd->max_frame_size); | ||
1146 | /* | ||
1147 | * Set default sizes in case IOCTL (VIDIOCMCAPTURE) | ||
1148 | * is not used (using read() instead). | ||
1149 | */ | ||
1150 | uvd->frame[i].canvas = uvd->canvas; | ||
1151 | uvd->frame[i].seqRead_Index = 0; | ||
1152 | } | ||
1153 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | ||
1154 | uvd->sbuf[i].data = kmalloc(sb_size, GFP_KERNEL); | ||
1155 | if (uvd->sbuf[i].data == NULL) { | ||
1156 | errCode = -ENOMEM; | ||
1157 | break; | ||
1158 | } | ||
1159 | } | ||
1160 | } | ||
1161 | if (errCode != 0) { | ||
1162 | /* Have to free all that memory */ | ||
1163 | if (uvd->fbuf != NULL) { | ||
1164 | usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size); | ||
1165 | uvd->fbuf = NULL; | ||
1166 | } | ||
1167 | RingQueue_Free(&uvd->dp); | ||
1168 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | ||
1169 | kfree(uvd->sbuf[i].data); | ||
1170 | uvd->sbuf[i].data = NULL; | ||
1171 | } | ||
1172 | } | ||
1173 | } | ||
1174 | |||
1175 | /* If so far no errors then we shall start the camera */ | ||
1176 | if (errCode == 0) { | ||
1177 | /* Start data pump if we have valid endpoint */ | ||
1178 | if (uvd->video_endp != 0) | ||
1179 | errCode = GET_CALLBACK(uvd, startDataPump)(uvd); | ||
1180 | if (errCode == 0) { | ||
1181 | if (VALID_CALLBACK(uvd, setupOnOpen)) { | ||
1182 | if (uvd->debug > 1) | ||
1183 | dev_info(&uvd->dev->dev, | ||
1184 | "%s: setupOnOpen callback\n", | ||
1185 | __func__); | ||
1186 | errCode = GET_CALLBACK(uvd, setupOnOpen)(uvd); | ||
1187 | if (errCode < 0) { | ||
1188 | err("%s: setupOnOpen callback failed (%d.).", | ||
1189 | __func__, errCode); | ||
1190 | } else if (uvd->debug > 1) { | ||
1191 | dev_info(&uvd->dev->dev, | ||
1192 | "%s: setupOnOpen callback successful\n", | ||
1193 | __func__); | ||
1194 | } | ||
1195 | } | ||
1196 | if (errCode == 0) { | ||
1197 | uvd->settingsAdjusted = 0; | ||
1198 | if (uvd->debug > 1) | ||
1199 | dev_info(&uvd->dev->dev, | ||
1200 | "%s: Open succeeded.\n", | ||
1201 | __func__); | ||
1202 | uvd->user++; | ||
1203 | file->private_data = uvd; | ||
1204 | } | ||
1205 | } | ||
1206 | } | ||
1207 | mutex_unlock(&uvd->lock); | ||
1208 | if (errCode != 0) | ||
1209 | usbvideo_ClientDecModCount(uvd); | ||
1210 | if (uvd->debug > 0) | ||
1211 | dev_info(&uvd->dev->dev, "%s: Returning %d.\n", __func__, | ||
1212 | errCode); | ||
1213 | return errCode; | ||
1214 | } | ||
1215 | |||
1216 | /* | ||
1217 | * usbvideo_v4l_close() | ||
1218 | * | ||
1219 | * This is part of Video 4 Linux API. The procedure | ||
1220 | * stops streaming and deallocates all buffers that were earlier | ||
1221 | * allocated in usbvideo_v4l_open(). | ||
1222 | * | ||
1223 | * History: | ||
1224 | * 22-Jan-2000 Moved scratch buffer deallocation here. | ||
1225 | * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers. | ||
1226 | * 24-May-2000 Moved MOD_DEC_USE_COUNT outside of code that can sleep. | ||
1227 | */ | ||
1228 | static int usbvideo_v4l_close(struct file *file) | ||
1229 | { | ||
1230 | struct video_device *dev = file->private_data; | ||
1231 | struct uvd *uvd = (struct uvd *) dev; | ||
1232 | int i; | ||
1233 | |||
1234 | if (uvd->debug > 1) | ||
1235 | dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, dev); | ||
1236 | |||
1237 | mutex_lock(&uvd->lock); | ||
1238 | GET_CALLBACK(uvd, stopDataPump)(uvd); | ||
1239 | usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size); | ||
1240 | uvd->fbuf = NULL; | ||
1241 | RingQueue_Free(&uvd->dp); | ||
1242 | |||
1243 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | ||
1244 | kfree(uvd->sbuf[i].data); | ||
1245 | uvd->sbuf[i].data = NULL; | ||
1246 | } | ||
1247 | |||
1248 | #if USBVIDEO_REPORT_STATS | ||
1249 | usbvideo_ReportStatistics(uvd); | ||
1250 | #endif | ||
1251 | |||
1252 | uvd->user--; | ||
1253 | if (uvd->remove_pending) { | ||
1254 | if (uvd->debug > 0) | ||
1255 | dev_info(&uvd->dev->dev, "%s: Final disconnect.\n", | ||
1256 | __func__); | ||
1257 | usbvideo_CameraRelease(uvd); | ||
1258 | } | ||
1259 | mutex_unlock(&uvd->lock); | ||
1260 | usbvideo_ClientDecModCount(uvd); | ||
1261 | |||
1262 | if (uvd->debug > 1) | ||
1263 | dev_info(&uvd->dev->dev, "%s: Completed.\n", __func__); | ||
1264 | file->private_data = NULL; | ||
1265 | return 0; | ||
1266 | } | ||
1267 | |||
1268 | /* | ||
1269 | * usbvideo_v4l_ioctl() | ||
1270 | * | ||
1271 | * This is part of Video 4 Linux API. The procedure handles ioctl() calls. | ||
1272 | * | ||
1273 | * History: | ||
1274 | * 22-Jan-2000 Corrected VIDIOCSPICT to reject unsupported settings. | ||
1275 | */ | ||
1276 | static long usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) | ||
1277 | { | ||
1278 | struct uvd *uvd = file->private_data; | ||
1279 | |||
1280 | if (!CAMERA_IS_OPERATIONAL(uvd)) | ||
1281 | return -EIO; | ||
1282 | |||
1283 | switch (cmd) { | ||
1284 | case VIDIOCGCAP: | ||
1285 | { | ||
1286 | struct video_capability *b = arg; | ||
1287 | *b = uvd->vcap; | ||
1288 | return 0; | ||
1289 | } | ||
1290 | case VIDIOCGCHAN: | ||
1291 | { | ||
1292 | struct video_channel *v = arg; | ||
1293 | *v = uvd->vchan; | ||
1294 | return 0; | ||
1295 | } | ||
1296 | case VIDIOCSCHAN: | ||
1297 | { | ||
1298 | struct video_channel *v = arg; | ||
1299 | if (v->channel != 0) | ||
1300 | return -EINVAL; | ||
1301 | return 0; | ||
1302 | } | ||
1303 | case VIDIOCGPICT: | ||
1304 | { | ||
1305 | struct video_picture *pic = arg; | ||
1306 | *pic = uvd->vpic; | ||
1307 | return 0; | ||
1308 | } | ||
1309 | case VIDIOCSPICT: | ||
1310 | { | ||
1311 | struct video_picture *pic = arg; | ||
1312 | /* | ||
1313 | * Use temporary 'video_picture' structure to preserve our | ||
1314 | * own settings (such as color depth, palette) that we | ||
1315 | * aren't allowing everyone (V4L client) to change. | ||
1316 | */ | ||
1317 | uvd->vpic.brightness = pic->brightness; | ||
1318 | uvd->vpic.hue = pic->hue; | ||
1319 | uvd->vpic.colour = pic->colour; | ||
1320 | uvd->vpic.contrast = pic->contrast; | ||
1321 | uvd->settingsAdjusted = 0; /* Will force new settings */ | ||
1322 | return 0; | ||
1323 | } | ||
1324 | case VIDIOCSWIN: | ||
1325 | { | ||
1326 | struct video_window *vw = arg; | ||
1327 | |||
1328 | if(VALID_CALLBACK(uvd, setVideoMode)) { | ||
1329 | return GET_CALLBACK(uvd, setVideoMode)(uvd, vw); | ||
1330 | } | ||
1331 | |||
1332 | if (vw->flags) | ||
1333 | return -EINVAL; | ||
1334 | if (vw->clipcount) | ||
1335 | return -EINVAL; | ||
1336 | if (vw->width != VIDEOSIZE_X(uvd->canvas)) | ||
1337 | return -EINVAL; | ||
1338 | if (vw->height != VIDEOSIZE_Y(uvd->canvas)) | ||
1339 | return -EINVAL; | ||
1340 | |||
1341 | return 0; | ||
1342 | } | ||
1343 | case VIDIOCGWIN: | ||
1344 | { | ||
1345 | struct video_window *vw = arg; | ||
1346 | |||
1347 | vw->x = 0; | ||
1348 | vw->y = 0; | ||
1349 | vw->width = VIDEOSIZE_X(uvd->videosize); | ||
1350 | vw->height = VIDEOSIZE_Y(uvd->videosize); | ||
1351 | vw->chromakey = 0; | ||
1352 | if (VALID_CALLBACK(uvd, getFPS)) | ||
1353 | vw->flags = GET_CALLBACK(uvd, getFPS)(uvd); | ||
1354 | else | ||
1355 | vw->flags = 10; /* FIXME: do better! */ | ||
1356 | return 0; | ||
1357 | } | ||
1358 | case VIDIOCGMBUF: | ||
1359 | { | ||
1360 | struct video_mbuf *vm = arg; | ||
1361 | int i; | ||
1362 | |||
1363 | memset(vm, 0, sizeof(*vm)); | ||
1364 | vm->size = uvd->max_frame_size * USBVIDEO_NUMFRAMES; | ||
1365 | vm->frames = USBVIDEO_NUMFRAMES; | ||
1366 | for(i = 0; i < USBVIDEO_NUMFRAMES; i++) | ||
1367 | vm->offsets[i] = i * uvd->max_frame_size; | ||
1368 | |||
1369 | return 0; | ||
1370 | } | ||
1371 | case VIDIOCMCAPTURE: | ||
1372 | { | ||
1373 | struct video_mmap *vm = arg; | ||
1374 | |||
1375 | if (uvd->debug >= 1) { | ||
1376 | dev_info(&uvd->dev->dev, | ||
1377 | "VIDIOCMCAPTURE: frame=%d. size=%dx%d, format=%d.\n", | ||
1378 | vm->frame, vm->width, vm->height, vm->format); | ||
1379 | } | ||
1380 | /* | ||
1381 | * Check if the requested size is supported. If the requestor | ||
1382 | * requests too big a frame then we may be tricked into accessing | ||
1383 | * outside of own preallocated frame buffer (in uvd->frame). | ||
1384 | * This will cause oops or a security hole. Theoretically, we | ||
1385 | * could only clamp the size down to acceptable bounds, but then | ||
1386 | * we'd need to figure out how to insert our smaller buffer into | ||
1387 | * larger caller's buffer... this is not an easy question. So we | ||
1388 | * here just flatly reject too large requests, assuming that the | ||
1389 | * caller will resubmit with smaller size. Callers should know | ||
1390 | * what size we support (returned by VIDIOCGCAP). However vidcat, | ||
1391 | * for one, does not care and allows to ask for any size. | ||
1392 | */ | ||
1393 | if ((vm->width > VIDEOSIZE_X(uvd->canvas)) || | ||
1394 | (vm->height > VIDEOSIZE_Y(uvd->canvas))) { | ||
1395 | if (uvd->debug > 0) { | ||
1396 | dev_info(&uvd->dev->dev, | ||
1397 | "VIDIOCMCAPTURE: Size=%dx%d " | ||
1398 | "too large; allowed only up " | ||
1399 | "to %ldx%ld\n", vm->width, | ||
1400 | vm->height, | ||
1401 | VIDEOSIZE_X(uvd->canvas), | ||
1402 | VIDEOSIZE_Y(uvd->canvas)); | ||
1403 | } | ||
1404 | return -EINVAL; | ||
1405 | } | ||
1406 | /* Check if the palette is supported */ | ||
1407 | if (((1L << vm->format) & uvd->paletteBits) == 0) { | ||
1408 | if (uvd->debug > 0) { | ||
1409 | dev_info(&uvd->dev->dev, | ||
1410 | "VIDIOCMCAPTURE: format=%d. " | ||
1411 | "not supported " | ||
1412 | "(paletteBits=$%08lx)\n", | ||
1413 | vm->format, uvd->paletteBits); | ||
1414 | } | ||
1415 | return -EINVAL; | ||
1416 | } | ||
1417 | if ((vm->frame < 0) || (vm->frame >= USBVIDEO_NUMFRAMES)) { | ||
1418 | err("VIDIOCMCAPTURE: vm.frame=%d. !E [0-%d]", vm->frame, USBVIDEO_NUMFRAMES-1); | ||
1419 | return -EINVAL; | ||
1420 | } | ||
1421 | if (uvd->frame[vm->frame].frameState == FrameState_Grabbing) { | ||
1422 | /* Not an error - can happen */ | ||
1423 | } | ||
1424 | uvd->frame[vm->frame].request = VIDEOSIZE(vm->width, vm->height); | ||
1425 | uvd->frame[vm->frame].palette = vm->format; | ||
1426 | |||
1427 | /* Mark it as ready */ | ||
1428 | uvd->frame[vm->frame].frameState = FrameState_Ready; | ||
1429 | |||
1430 | return usbvideo_NewFrame(uvd, vm->frame); | ||
1431 | } | ||
1432 | case VIDIOCSYNC: | ||
1433 | { | ||
1434 | int *frameNum = arg; | ||
1435 | int ret; | ||
1436 | |||
1437 | if (*frameNum < 0 || *frameNum >= USBVIDEO_NUMFRAMES) | ||
1438 | return -EINVAL; | ||
1439 | |||
1440 | if (uvd->debug >= 1) | ||
1441 | dev_info(&uvd->dev->dev, | ||
1442 | "VIDIOCSYNC: syncing to frame %d.\n", | ||
1443 | *frameNum); | ||
1444 | if (uvd->flags & FLAGS_NO_DECODING) | ||
1445 | ret = usbvideo_GetFrame(uvd, *frameNum); | ||
1446 | else if (VALID_CALLBACK(uvd, getFrame)) { | ||
1447 | ret = GET_CALLBACK(uvd, getFrame)(uvd, *frameNum); | ||
1448 | if ((ret < 0) && (uvd->debug >= 1)) { | ||
1449 | err("VIDIOCSYNC: getFrame() returned %d.", ret); | ||
1450 | } | ||
1451 | } else { | ||
1452 | err("VIDIOCSYNC: getFrame is not set"); | ||
1453 | ret = -EFAULT; | ||
1454 | } | ||
1455 | |||
1456 | /* | ||
1457 | * The frame is in FrameState_Done_Hold state. Release it | ||
1458 | * right now because its data is already mapped into | ||
1459 | * the user space and it's up to the application to | ||
1460 | * make use of it until it asks for another frame. | ||
1461 | */ | ||
1462 | uvd->frame[*frameNum].frameState = FrameState_Unused; | ||
1463 | return ret; | ||
1464 | } | ||
1465 | case VIDIOCGFBUF: | ||
1466 | { | ||
1467 | struct video_buffer *vb = arg; | ||
1468 | |||
1469 | memset(vb, 0, sizeof(*vb)); | ||
1470 | return 0; | ||
1471 | } | ||
1472 | case VIDIOCKEY: | ||
1473 | return 0; | ||
1474 | |||
1475 | case VIDIOCCAPTURE: | ||
1476 | return -EINVAL; | ||
1477 | |||
1478 | case VIDIOCSFBUF: | ||
1479 | |||
1480 | case VIDIOCGTUNER: | ||
1481 | case VIDIOCSTUNER: | ||
1482 | |||
1483 | case VIDIOCGFREQ: | ||
1484 | case VIDIOCSFREQ: | ||
1485 | |||
1486 | case VIDIOCGAUDIO: | ||
1487 | case VIDIOCSAUDIO: | ||
1488 | return -EINVAL; | ||
1489 | |||
1490 | default: | ||
1491 | return -ENOIOCTLCMD; | ||
1492 | } | ||
1493 | return 0; | ||
1494 | } | ||
1495 | |||
1496 | static long usbvideo_v4l_ioctl(struct file *file, | ||
1497 | unsigned int cmd, unsigned long arg) | ||
1498 | { | ||
1499 | return video_usercopy(file, cmd, arg, usbvideo_v4l_do_ioctl); | ||
1500 | } | ||
1501 | |||
1502 | /* | ||
1503 | * usbvideo_v4l_read() | ||
1504 | * | ||
1505 | * This is mostly boring stuff. We simply ask for a frame and when it | ||
1506 | * arrives copy all the video data from it into user space. There is | ||
1507 | * no obvious need to override this method. | ||
1508 | * | ||
1509 | * History: | ||
1510 | * 20-Oct-2000 Created. | ||
1511 | * 01-Nov-2000 Added mutex (uvd->lock). | ||
1512 | */ | ||
1513 | static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, | ||
1514 | size_t count, loff_t *ppos) | ||
1515 | { | ||
1516 | struct uvd *uvd = file->private_data; | ||
1517 | int noblock = file->f_flags & O_NONBLOCK; | ||
1518 | int frmx = -1, i; | ||
1519 | struct usbvideo_frame *frame; | ||
1520 | |||
1521 | if (!CAMERA_IS_OPERATIONAL(uvd) || (buf == NULL)) | ||
1522 | return -EFAULT; | ||
1523 | |||
1524 | if (uvd->debug >= 1) | ||
1525 | dev_info(&uvd->dev->dev, | ||
1526 | "%s: %Zd. bytes, noblock=%d.\n", | ||
1527 | __func__, count, noblock); | ||
1528 | |||
1529 | mutex_lock(&uvd->lock); | ||
1530 | |||
1531 | /* See if a frame is completed, then use it. */ | ||
1532 | for(i = 0; i < USBVIDEO_NUMFRAMES; i++) { | ||
1533 | if ((uvd->frame[i].frameState == FrameState_Done) || | ||
1534 | (uvd->frame[i].frameState == FrameState_Done_Hold) || | ||
1535 | (uvd->frame[i].frameState == FrameState_Error)) { | ||
1536 | frmx = i; | ||
1537 | break; | ||
1538 | } | ||
1539 | } | ||
1540 | |||
1541 | /* FIXME: If we don't start a frame here then who ever does? */ | ||
1542 | if (noblock && (frmx == -1)) { | ||
1543 | count = -EAGAIN; | ||
1544 | goto read_done; | ||
1545 | } | ||
1546 | |||
1547 | /* | ||
1548 | * If no FrameState_Done, look for a FrameState_Grabbing state. | ||
1549 | * See if a frame is in process (grabbing), then use it. | ||
1550 | * We will need to wait until it becomes cooked, of course. | ||
1551 | */ | ||
1552 | if (frmx == -1) { | ||
1553 | for(i = 0; i < USBVIDEO_NUMFRAMES; i++) { | ||
1554 | if (uvd->frame[i].frameState == FrameState_Grabbing) { | ||
1555 | frmx = i; | ||
1556 | break; | ||
1557 | } | ||
1558 | } | ||
1559 | } | ||
1560 | |||
1561 | /* | ||
1562 | * If no frame is active, start one. We don't care which one | ||
1563 | * it will be, so #0 is as good as any. | ||
1564 | * In read access mode we don't have convenience of VIDIOCMCAPTURE | ||
1565 | * to specify the requested palette (video format) on per-frame | ||
1566 | * basis. This means that we have to return data in -some- format | ||
1567 | * and just hope that the client knows what to do with it. | ||
1568 | * The default format is configured in uvd->defaultPalette field | ||
1569 | * as one of VIDEO_PALETTE_xxx values. We stuff it into the new | ||
1570 | * frame and initiate the frame filling process. | ||
1571 | */ | ||
1572 | if (frmx == -1) { | ||
1573 | if (uvd->defaultPalette == 0) { | ||
1574 | err("%s: No default palette; don't know what to do!", __func__); | ||
1575 | count = -EFAULT; | ||
1576 | goto read_done; | ||
1577 | } | ||
1578 | frmx = 0; | ||
1579 | /* | ||
1580 | * We have no per-frame control over video size. | ||
1581 | * Therefore we only can use whatever size was | ||
1582 | * specified as default. | ||
1583 | */ | ||
1584 | uvd->frame[frmx].request = uvd->videosize; | ||
1585 | uvd->frame[frmx].palette = uvd->defaultPalette; | ||
1586 | uvd->frame[frmx].frameState = FrameState_Ready; | ||
1587 | usbvideo_NewFrame(uvd, frmx); | ||
1588 | /* Now frame 0 is supposed to start filling... */ | ||
1589 | } | ||
1590 | |||
1591 | /* | ||
1592 | * Get a pointer to the active frame. It is either previously | ||
1593 | * completed frame or frame in progress but not completed yet. | ||
1594 | */ | ||
1595 | frame = &uvd->frame[frmx]; | ||
1596 | |||
1597 | /* | ||
1598 | * Sit back & wait until the frame gets filled and postprocessed. | ||
1599 | * If we fail to get the picture [in time] then return the error. | ||
1600 | * In this call we specify that we want the frame to be waited for, | ||
1601 | * postprocessed and switched into FrameState_Done_Hold state. This | ||
1602 | * state is used to hold the frame as "fully completed" between | ||
1603 | * subsequent partial reads of the same frame. | ||
1604 | */ | ||
1605 | if (frame->frameState != FrameState_Done_Hold) { | ||
1606 | long rv = -EFAULT; | ||
1607 | if (uvd->flags & FLAGS_NO_DECODING) | ||
1608 | rv = usbvideo_GetFrame(uvd, frmx); | ||
1609 | else if (VALID_CALLBACK(uvd, getFrame)) | ||
1610 | rv = GET_CALLBACK(uvd, getFrame)(uvd, frmx); | ||
1611 | else | ||
1612 | err("getFrame is not set"); | ||
1613 | if ((rv != 0) || (frame->frameState != FrameState_Done_Hold)) { | ||
1614 | count = rv; | ||
1615 | goto read_done; | ||
1616 | } | ||
1617 | } | ||
1618 | |||
1619 | /* | ||
1620 | * Copy bytes to user space. We allow for partial reads, which | ||
1621 | * means that the user application can request read less than | ||
1622 | * the full frame size. It is up to the application to issue | ||
1623 | * subsequent calls until entire frame is read. | ||
1624 | * | ||
1625 | * First things first, make sure we don't copy more than we | ||
1626 | * have - even if the application wants more. That would be | ||
1627 | * a big security embarassment! | ||
1628 | */ | ||
1629 | if ((count + frame->seqRead_Index) > frame->seqRead_Length) | ||
1630 | count = frame->seqRead_Length - frame->seqRead_Index; | ||
1631 | |||
1632 | /* | ||
1633 | * Copy requested amount of data to user space. We start | ||
1634 | * copying from the position where we last left it, which | ||
1635 | * will be zero for a new frame (not read before). | ||
1636 | */ | ||
1637 | if (copy_to_user(buf, frame->data + frame->seqRead_Index, count)) { | ||
1638 | count = -EFAULT; | ||
1639 | goto read_done; | ||
1640 | } | ||
1641 | |||
1642 | /* Update last read position */ | ||
1643 | frame->seqRead_Index += count; | ||
1644 | if (uvd->debug >= 1) { | ||
1645 | err("%s: {copy} count used=%Zd, new seqRead_Index=%ld", | ||
1646 | __func__, count, frame->seqRead_Index); | ||
1647 | } | ||
1648 | |||
1649 | /* Finally check if the frame is done with and "release" it */ | ||
1650 | if (frame->seqRead_Index >= frame->seqRead_Length) { | ||
1651 | /* All data has been read */ | ||
1652 | frame->seqRead_Index = 0; | ||
1653 | |||
1654 | /* Mark it as available to be used again. */ | ||
1655 | uvd->frame[frmx].frameState = FrameState_Unused; | ||
1656 | if (usbvideo_NewFrame(uvd, (frmx + 1) % USBVIDEO_NUMFRAMES)) { | ||
1657 | err("%s: usbvideo_NewFrame failed.", __func__); | ||
1658 | } | ||
1659 | } | ||
1660 | read_done: | ||
1661 | mutex_unlock(&uvd->lock); | ||
1662 | return count; | ||
1663 | } | ||
1664 | |||
1665 | /* | ||
1666 | * Make all of the blocks of data contiguous | ||
1667 | */ | ||
1668 | static int usbvideo_CompressIsochronous(struct uvd *uvd, struct urb *urb) | ||
1669 | { | ||
1670 | char *cdata; | ||
1671 | int i, totlen = 0; | ||
1672 | |||
1673 | for (i = 0; i < urb->number_of_packets; i++) { | ||
1674 | int n = urb->iso_frame_desc[i].actual_length; | ||
1675 | int st = urb->iso_frame_desc[i].status; | ||
1676 | |||
1677 | cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | ||
1678 | |||
1679 | /* Detect and ignore errored packets */ | ||
1680 | if (st < 0) { | ||
1681 | if (uvd->debug >= 1) | ||
1682 | err("Data error: packet=%d. len=%d. status=%d.", i, n, st); | ||
1683 | uvd->stats.iso_err_count++; | ||
1684 | continue; | ||
1685 | } | ||
1686 | |||
1687 | /* Detect and ignore empty packets */ | ||
1688 | if (n <= 0) { | ||
1689 | uvd->stats.iso_skip_count++; | ||
1690 | continue; | ||
1691 | } | ||
1692 | totlen += n; /* Little local accounting */ | ||
1693 | RingQueue_Enqueue(&uvd->dp, cdata, n); | ||
1694 | } | ||
1695 | return totlen; | ||
1696 | } | ||
1697 | |||
1698 | static void usbvideo_IsocIrq(struct urb *urb) | ||
1699 | { | ||
1700 | int i, ret, len; | ||
1701 | struct uvd *uvd = urb->context; | ||
1702 | |||
1703 | /* We don't want to do anything if we are about to be removed! */ | ||
1704 | if (!CAMERA_IS_OPERATIONAL(uvd)) | ||
1705 | return; | ||
1706 | #if 0 | ||
1707 | if (urb->actual_length > 0) { | ||
1708 | dev_info(&uvd->dev->dev, | ||
1709 | "urb=$%p status=%d. errcount=%d. length=%d.\n", | ||
1710 | urb, urb->status, urb->error_count, | ||
1711 | urb->actual_length); | ||
1712 | } else { | ||
1713 | static int c = 0; | ||
1714 | if (c++ % 100 == 0) | ||
1715 | dev_info(&uvd->dev->dev, "No Isoc data\n"); | ||
1716 | } | ||
1717 | #endif | ||
1718 | |||
1719 | if (!uvd->streaming) { | ||
1720 | if (uvd->debug >= 1) | ||
1721 | dev_info(&uvd->dev->dev, | ||
1722 | "Not streaming, but interrupt!\n"); | ||
1723 | return; | ||
1724 | } | ||
1725 | |||
1726 | uvd->stats.urb_count++; | ||
1727 | if (urb->actual_length <= 0) | ||
1728 | goto urb_done_with; | ||
1729 | |||
1730 | /* Copy the data received into ring queue */ | ||
1731 | len = usbvideo_CompressIsochronous(uvd, urb); | ||
1732 | uvd->stats.urb_length = len; | ||
1733 | if (len <= 0) | ||
1734 | goto urb_done_with; | ||
1735 | |||
1736 | /* Here we got some data */ | ||
1737 | uvd->stats.data_count += len; | ||
1738 | RingQueue_WakeUpInterruptible(&uvd->dp); | ||
1739 | |||
1740 | urb_done_with: | ||
1741 | for (i = 0; i < FRAMES_PER_DESC; i++) { | ||
1742 | urb->iso_frame_desc[i].status = 0; | ||
1743 | urb->iso_frame_desc[i].actual_length = 0; | ||
1744 | } | ||
1745 | urb->status = 0; | ||
1746 | urb->dev = uvd->dev; | ||
1747 | ret = usb_submit_urb (urb, GFP_KERNEL); | ||
1748 | if(ret) | ||
1749 | err("usb_submit_urb error (%d)", ret); | ||
1750 | return; | ||
1751 | } | ||
1752 | |||
1753 | /* | ||
1754 | * usbvideo_StartDataPump() | ||
1755 | * | ||
1756 | * History: | ||
1757 | * 27-Jan-2000 Used ibmcam->iface, ibmcam->ifaceAltActive instead | ||
1758 | * of hardcoded values. Simplified by using for loop, | ||
1759 | * allowed any number of URBs. | ||
1760 | */ | ||
1761 | static int usbvideo_StartDataPump(struct uvd *uvd) | ||
1762 | { | ||
1763 | struct usb_device *dev = uvd->dev; | ||
1764 | int i, errFlag; | ||
1765 | |||
1766 | if (uvd->debug > 1) | ||
1767 | dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, uvd); | ||
1768 | |||
1769 | if (!CAMERA_IS_OPERATIONAL(uvd)) { | ||
1770 | err("%s: Camera is not operational", __func__); | ||
1771 | return -EFAULT; | ||
1772 | } | ||
1773 | uvd->curframe = -1; | ||
1774 | |||
1775 | /* Alternate interface 1 is is the biggest frame size */ | ||
1776 | i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive); | ||
1777 | if (i < 0) { | ||
1778 | err("%s: usb_set_interface error", __func__); | ||
1779 | uvd->last_error = i; | ||
1780 | return -EBUSY; | ||
1781 | } | ||
1782 | if (VALID_CALLBACK(uvd, videoStart)) | ||
1783 | GET_CALLBACK(uvd, videoStart)(uvd); | ||
1784 | else | ||
1785 | err("%s: videoStart not set", __func__); | ||
1786 | |||
1787 | /* We double buffer the Iso lists */ | ||
1788 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | ||
1789 | int j, k; | ||
1790 | struct urb *urb = uvd->sbuf[i].urb; | ||
1791 | urb->dev = dev; | ||
1792 | urb->context = uvd; | ||
1793 | urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp); | ||
1794 | urb->interval = 1; | ||
1795 | urb->transfer_flags = URB_ISO_ASAP; | ||
1796 | urb->transfer_buffer = uvd->sbuf[i].data; | ||
1797 | urb->complete = usbvideo_IsocIrq; | ||
1798 | urb->number_of_packets = FRAMES_PER_DESC; | ||
1799 | urb->transfer_buffer_length = uvd->iso_packet_len * FRAMES_PER_DESC; | ||
1800 | for (j=k=0; j < FRAMES_PER_DESC; j++, k += uvd->iso_packet_len) { | ||
1801 | urb->iso_frame_desc[j].offset = k; | ||
1802 | urb->iso_frame_desc[j].length = uvd->iso_packet_len; | ||
1803 | } | ||
1804 | } | ||
1805 | |||
1806 | /* Submit all URBs */ | ||
1807 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | ||
1808 | errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL); | ||
1809 | if (errFlag) | ||
1810 | err("%s: usb_submit_isoc(%d) ret %d", __func__, i, errFlag); | ||
1811 | } | ||
1812 | |||
1813 | uvd->streaming = 1; | ||
1814 | if (uvd->debug > 1) | ||
1815 | dev_info(&uvd->dev->dev, | ||
1816 | "%s: streaming=1 video_endp=$%02x\n", __func__, | ||
1817 | uvd->video_endp); | ||
1818 | return 0; | ||
1819 | } | ||
1820 | |||
1821 | /* | ||
1822 | * usbvideo_StopDataPump() | ||
1823 | * | ||
1824 | * This procedure stops streaming and deallocates URBs. Then it | ||
1825 | * activates zero-bandwidth alt. setting of the video interface. | ||
1826 | * | ||
1827 | * History: | ||
1828 | * 22-Jan-2000 Corrected order of actions to work after surprise removal. | ||
1829 | * 27-Jan-2000 Used uvd->iface, uvd->ifaceAltInactive instead of hardcoded values. | ||
1830 | */ | ||
1831 | static void usbvideo_StopDataPump(struct uvd *uvd) | ||
1832 | { | ||
1833 | int i, j; | ||
1834 | |||
1835 | if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL)) | ||
1836 | return; | ||
1837 | |||
1838 | if (uvd->debug > 1) | ||
1839 | dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, uvd); | ||
1840 | |||
1841 | /* Unschedule all of the iso td's */ | ||
1842 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | ||
1843 | usb_kill_urb(uvd->sbuf[i].urb); | ||
1844 | } | ||
1845 | if (uvd->debug > 1) | ||
1846 | dev_info(&uvd->dev->dev, "%s: streaming=0\n", __func__); | ||
1847 | uvd->streaming = 0; | ||
1848 | |||
1849 | if (!uvd->remove_pending) { | ||
1850 | /* Invoke minidriver's magic to stop the camera */ | ||
1851 | if (VALID_CALLBACK(uvd, videoStop)) | ||
1852 | GET_CALLBACK(uvd, videoStop)(uvd); | ||
1853 | else | ||
1854 | err("%s: videoStop not set", __func__); | ||
1855 | |||
1856 | /* Set packet size to 0 */ | ||
1857 | j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive); | ||
1858 | if (j < 0) { | ||
1859 | err("%s: usb_set_interface() error %d.", __func__, j); | ||
1860 | uvd->last_error = j; | ||
1861 | } | ||
1862 | } | ||
1863 | } | ||
1864 | |||
1865 | /* | ||
1866 | * usbvideo_NewFrame() | ||
1867 | * | ||
1868 | * History: | ||
1869 | * 29-Mar-00 Added copying of previous frame into the current one. | ||
1870 | * 6-Aug-00 Added model 3 video sizes, removed redundant width, height. | ||
1871 | */ | ||
1872 | static int usbvideo_NewFrame(struct uvd *uvd, int framenum) | ||
1873 | { | ||
1874 | struct usbvideo_frame *frame; | ||
1875 | int n; | ||
1876 | |||
1877 | if (uvd->debug > 1) | ||
1878 | dev_info(&uvd->dev->dev, "usbvideo_NewFrame($%p,%d.)\n", uvd, | ||
1879 | framenum); | ||
1880 | |||
1881 | /* If we're not grabbing a frame right now and the other frame is */ | ||
1882 | /* ready to be grabbed into, then use it instead */ | ||
1883 | if (uvd->curframe != -1) | ||
1884 | return 0; | ||
1885 | |||
1886 | /* If necessary we adjust picture settings between frames */ | ||
1887 | if (!uvd->settingsAdjusted) { | ||
1888 | if (VALID_CALLBACK(uvd, adjustPicture)) | ||
1889 | GET_CALLBACK(uvd, adjustPicture)(uvd); | ||
1890 | uvd->settingsAdjusted = 1; | ||
1891 | } | ||
1892 | |||
1893 | n = (framenum + 1) % USBVIDEO_NUMFRAMES; | ||
1894 | if (uvd->frame[n].frameState == FrameState_Ready) | ||
1895 | framenum = n; | ||
1896 | |||
1897 | frame = &uvd->frame[framenum]; | ||
1898 | |||
1899 | frame->frameState = FrameState_Grabbing; | ||
1900 | frame->scanstate = ScanState_Scanning; | ||
1901 | frame->seqRead_Length = 0; /* Accumulated in xxx_parse_data() */ | ||
1902 | frame->deinterlace = Deinterlace_None; | ||
1903 | frame->flags = 0; /* No flags yet, up to minidriver (or us) to set them */ | ||
1904 | uvd->curframe = framenum; | ||
1905 | |||
1906 | /* | ||
1907 | * Normally we would want to copy previous frame into the current one | ||
1908 | * before we even start filling it with data; this allows us to stop | ||
1909 | * filling at any moment; top portion of the frame will be new and | ||
1910 | * bottom portion will stay as it was in previous frame. If we don't | ||
1911 | * do that then missing chunks of video stream will result in flickering | ||
1912 | * portions of old data whatever it was before. | ||
1913 | * | ||
1914 | * If we choose not to copy previous frame (to, for example, save few | ||
1915 | * bus cycles - the frame can be pretty large!) then we have an option | ||
1916 | * to clear the frame before using. If we experience losses in this | ||
1917 | * mode then missing picture will be black (no flickering). | ||
1918 | * | ||
1919 | * Finally, if user chooses not to clean the current frame before | ||
1920 | * filling it with data then the old data will be visible if we fail | ||
1921 | * to refill entire frame with new data. | ||
1922 | */ | ||
1923 | if (!(uvd->flags & FLAGS_SEPARATE_FRAMES)) { | ||
1924 | /* This copies previous frame into this one to mask losses */ | ||
1925 | int prev = (framenum - 1 + USBVIDEO_NUMFRAMES) % USBVIDEO_NUMFRAMES; | ||
1926 | memmove(frame->data, uvd->frame[prev].data, uvd->max_frame_size); | ||
1927 | } else { | ||
1928 | if (uvd->flags & FLAGS_CLEAN_FRAMES) { | ||
1929 | /* This provides a "clean" frame but slows things down */ | ||
1930 | memset(frame->data, 0, uvd->max_frame_size); | ||
1931 | } | ||
1932 | } | ||
1933 | return 0; | ||
1934 | } | ||
1935 | |||
1936 | /* | ||
1937 | * usbvideo_CollectRawData() | ||
1938 | * | ||
1939 | * This procedure can be used instead of 'processData' callback if you | ||
1940 | * only want to dump the raw data from the camera into the output | ||
1941 | * device (frame buffer). You can look at it with V4L client, but the | ||
1942 | * image will be unwatchable. The main purpose of this code and of the | ||
1943 | * mode FLAGS_NO_DECODING is debugging and capturing of datastreams from | ||
1944 | * new, unknown cameras. This procedure will be automatically invoked | ||
1945 | * instead of the specified callback handler when uvd->flags has bit | ||
1946 | * FLAGS_NO_DECODING set. Therefore, any regular build of any driver | ||
1947 | * based on usbvideo can use this feature at any time. | ||
1948 | */ | ||
1949 | static void usbvideo_CollectRawData(struct uvd *uvd, struct usbvideo_frame *frame) | ||
1950 | { | ||
1951 | int n; | ||
1952 | |||
1953 | assert(uvd != NULL); | ||
1954 | assert(frame != NULL); | ||
1955 | |||
1956 | /* Try to move data from queue into frame buffer */ | ||
1957 | n = RingQueue_GetLength(&uvd->dp); | ||
1958 | if (n > 0) { | ||
1959 | int m; | ||
1960 | /* See how much space we have left */ | ||
1961 | m = uvd->max_frame_size - frame->seqRead_Length; | ||
1962 | if (n > m) | ||
1963 | n = m; | ||
1964 | /* Now move that much data into frame buffer */ | ||
1965 | RingQueue_Dequeue( | ||
1966 | &uvd->dp, | ||
1967 | frame->data + frame->seqRead_Length, | ||
1968 | m); | ||
1969 | frame->seqRead_Length += m; | ||
1970 | } | ||
1971 | /* See if we filled the frame */ | ||
1972 | if (frame->seqRead_Length >= uvd->max_frame_size) { | ||
1973 | frame->frameState = FrameState_Done; | ||
1974 | uvd->curframe = -1; | ||
1975 | uvd->stats.frame_num++; | ||
1976 | } | ||
1977 | } | ||
1978 | |||
1979 | static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) | ||
1980 | { | ||
1981 | struct usbvideo_frame *frame = &uvd->frame[frameNum]; | ||
1982 | |||
1983 | if (uvd->debug >= 2) | ||
1984 | dev_info(&uvd->dev->dev, "%s($%p,%d.)\n", __func__, uvd, | ||
1985 | frameNum); | ||
1986 | |||
1987 | switch (frame->frameState) { | ||
1988 | case FrameState_Unused: | ||
1989 | if (uvd->debug >= 2) | ||
1990 | dev_info(&uvd->dev->dev, "%s: FrameState_Unused\n", | ||
1991 | __func__); | ||
1992 | return -EINVAL; | ||
1993 | case FrameState_Ready: | ||
1994 | case FrameState_Grabbing: | ||
1995 | case FrameState_Error: | ||
1996 | { | ||
1997 | int ntries, signalPending; | ||
1998 | redo: | ||
1999 | if (!CAMERA_IS_OPERATIONAL(uvd)) { | ||
2000 | if (uvd->debug >= 2) | ||
2001 | dev_info(&uvd->dev->dev, | ||
2002 | "%s: Camera is not operational (1)\n", | ||
2003 | __func__); | ||
2004 | return -EIO; | ||
2005 | } | ||
2006 | ntries = 0; | ||
2007 | do { | ||
2008 | RingQueue_InterruptibleSleepOn(&uvd->dp); | ||
2009 | signalPending = signal_pending(current); | ||
2010 | if (!CAMERA_IS_OPERATIONAL(uvd)) { | ||
2011 | if (uvd->debug >= 2) | ||
2012 | dev_info(&uvd->dev->dev, | ||
2013 | "%s: Camera is not " | ||
2014 | "operational (2)\n", __func__); | ||
2015 | return -EIO; | ||
2016 | } | ||
2017 | assert(uvd->fbuf != NULL); | ||
2018 | if (signalPending) { | ||
2019 | if (uvd->debug >= 2) | ||
2020 | dev_info(&uvd->dev->dev, | ||
2021 | "%s: Signal=$%08x\n", __func__, | ||
2022 | signalPending); | ||
2023 | if (uvd->flags & FLAGS_RETRY_VIDIOCSYNC) { | ||
2024 | usbvideo_TestPattern(uvd, 1, 0); | ||
2025 | uvd->curframe = -1; | ||
2026 | uvd->stats.frame_num++; | ||
2027 | if (uvd->debug >= 2) | ||
2028 | dev_info(&uvd->dev->dev, | ||
2029 | "%s: Forced test " | ||
2030 | "pattern screen\n", | ||
2031 | __func__); | ||
2032 | return 0; | ||
2033 | } else { | ||
2034 | /* Standard answer: Interrupted! */ | ||
2035 | if (uvd->debug >= 2) | ||
2036 | dev_info(&uvd->dev->dev, | ||
2037 | "%s: Interrupted!\n", | ||
2038 | __func__); | ||
2039 | return -EINTR; | ||
2040 | } | ||
2041 | } else { | ||
2042 | /* No signals - we just got new data in dp queue */ | ||
2043 | if (uvd->flags & FLAGS_NO_DECODING) | ||
2044 | usbvideo_CollectRawData(uvd, frame); | ||
2045 | else if (VALID_CALLBACK(uvd, processData)) | ||
2046 | GET_CALLBACK(uvd, processData)(uvd, frame); | ||
2047 | else | ||
2048 | err("%s: processData not set", __func__); | ||
2049 | } | ||
2050 | } while (frame->frameState == FrameState_Grabbing); | ||
2051 | if (uvd->debug >= 2) { | ||
2052 | dev_info(&uvd->dev->dev, | ||
2053 | "%s: Grabbing done; state=%d. (%lu. bytes)\n", | ||
2054 | __func__, frame->frameState, | ||
2055 | frame->seqRead_Length); | ||
2056 | } | ||
2057 | if (frame->frameState == FrameState_Error) { | ||
2058 | int ret = usbvideo_NewFrame(uvd, frameNum); | ||
2059 | if (ret < 0) { | ||
2060 | err("%s: usbvideo_NewFrame() failed (%d.)", __func__, ret); | ||
2061 | return ret; | ||
2062 | } | ||
2063 | goto redo; | ||
2064 | } | ||
2065 | /* Note that we fall through to meet our destiny below */ | ||
2066 | } | ||
2067 | case FrameState_Done: | ||
2068 | /* | ||
2069 | * Do all necessary postprocessing of data prepared in | ||
2070 | * "interrupt" code and the collecting code above. The | ||
2071 | * frame gets marked as FrameState_Done by queue parsing code. | ||
2072 | * This status means that we collected enough data and | ||
2073 | * most likely processed it as we went through. However | ||
2074 | * the data may need postprocessing, such as deinterlacing | ||
2075 | * or picture adjustments implemented in software (horror!) | ||
2076 | * | ||
2077 | * As soon as the frame becomes "final" it gets promoted to | ||
2078 | * FrameState_Done_Hold status where it will remain until the | ||
2079 | * caller consumed all the video data from the frame. Then | ||
2080 | * the empty shell of ex-frame is thrown out for dogs to eat. | ||
2081 | * But we, worried about pets, will recycle the frame! | ||
2082 | */ | ||
2083 | uvd->stats.frame_num++; | ||
2084 | if ((uvd->flags & FLAGS_NO_DECODING) == 0) { | ||
2085 | if (VALID_CALLBACK(uvd, postProcess)) | ||
2086 | GET_CALLBACK(uvd, postProcess)(uvd, frame); | ||
2087 | if (frame->flags & USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST) | ||
2088 | usbvideo_SoftwareContrastAdjustment(uvd, frame); | ||
2089 | } | ||
2090 | frame->frameState = FrameState_Done_Hold; | ||
2091 | if (uvd->debug >= 2) | ||
2092 | dev_info(&uvd->dev->dev, | ||
2093 | "%s: Entered FrameState_Done_Hold state.\n", | ||
2094 | __func__); | ||
2095 | return 0; | ||
2096 | |||
2097 | case FrameState_Done_Hold: | ||
2098 | /* | ||
2099 | * We stay in this state indefinitely until someone external, | ||
2100 | * like ioctl() or read() call finishes digesting the frame | ||
2101 | * data. Then it will mark the frame as FrameState_Unused and | ||
2102 | * it will be released back into the wild to roam freely. | ||
2103 | */ | ||
2104 | if (uvd->debug >= 2) | ||
2105 | dev_info(&uvd->dev->dev, | ||
2106 | "%s: FrameState_Done_Hold state.\n", | ||
2107 | __func__); | ||
2108 | return 0; | ||
2109 | } | ||
2110 | |||
2111 | /* Catch-all for other cases. We shall not be here. */ | ||
2112 | err("%s: Invalid state %d.", __func__, frame->frameState); | ||
2113 | frame->frameState = FrameState_Unused; | ||
2114 | return 0; | ||
2115 | } | ||
2116 | |||
2117 | /* | ||
2118 | * usbvideo_DeinterlaceFrame() | ||
2119 | * | ||
2120 | * This procedure deinterlaces the given frame. Some cameras produce | ||
2121 | * only half of scanlines - sometimes only even lines, sometimes only | ||
2122 | * odd lines. The deinterlacing method is stored in frame->deinterlace | ||
2123 | * variable. | ||
2124 | * | ||
2125 | * Here we scan the frame vertically and replace missing scanlines with | ||
2126 | * average between surrounding ones - before and after. If we have no | ||
2127 | * line above then we just copy next line. Similarly, if we need to | ||
2128 | * create a last line then preceding line is used. | ||
2129 | */ | ||
2130 | void usbvideo_DeinterlaceFrame(struct uvd *uvd, struct usbvideo_frame *frame) | ||
2131 | { | ||
2132 | if ((uvd == NULL) || (frame == NULL)) | ||
2133 | return; | ||
2134 | |||
2135 | if ((frame->deinterlace == Deinterlace_FillEvenLines) || | ||
2136 | (frame->deinterlace == Deinterlace_FillOddLines)) | ||
2137 | { | ||
2138 | const int v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL; | ||
2139 | int i = (frame->deinterlace == Deinterlace_FillEvenLines) ? 0 : 1; | ||
2140 | |||
2141 | for (; i < VIDEOSIZE_Y(frame->request); i += 2) { | ||
2142 | const unsigned char *fs1, *fs2; | ||
2143 | unsigned char *fd; | ||
2144 | int ip, in, j; /* Previous and next lines */ | ||
2145 | |||
2146 | /* | ||
2147 | * Need to average lines before and after 'i'. | ||
2148 | * If we go out of bounds seeking those lines then | ||
2149 | * we point back to existing line. | ||
2150 | */ | ||
2151 | ip = i - 1; /* First, get rough numbers */ | ||
2152 | in = i + 1; | ||
2153 | |||
2154 | /* Now validate */ | ||
2155 | if (ip < 0) | ||
2156 | ip = in; | ||
2157 | if (in >= VIDEOSIZE_Y(frame->request)) | ||
2158 | in = ip; | ||
2159 | |||
2160 | /* Sanity check */ | ||
2161 | if ((ip < 0) || (in < 0) || | ||
2162 | (ip >= VIDEOSIZE_Y(frame->request)) || | ||
2163 | (in >= VIDEOSIZE_Y(frame->request))) | ||
2164 | { | ||
2165 | err("Error: ip=%d. in=%d. req.height=%ld.", | ||
2166 | ip, in, VIDEOSIZE_Y(frame->request)); | ||
2167 | break; | ||
2168 | } | ||
2169 | |||
2170 | /* Now we need to average lines 'ip' and 'in' to produce line 'i' */ | ||
2171 | fs1 = frame->data + (v4l_linesize * ip); | ||
2172 | fs2 = frame->data + (v4l_linesize * in); | ||
2173 | fd = frame->data + (v4l_linesize * i); | ||
2174 | |||
2175 | /* Average lines around destination */ | ||
2176 | for (j=0; j < v4l_linesize; j++) { | ||
2177 | fd[j] = (unsigned char)((((unsigned) fs1[j]) + | ||
2178 | ((unsigned)fs2[j])) >> 1); | ||
2179 | } | ||
2180 | } | ||
2181 | } | ||
2182 | |||
2183 | /* Optionally display statistics on the screen */ | ||
2184 | if (uvd->flags & FLAGS_OVERLAY_STATS) | ||
2185 | usbvideo_OverlayStats(uvd, frame); | ||
2186 | } | ||
2187 | |||
2188 | EXPORT_SYMBOL(usbvideo_DeinterlaceFrame); | ||
2189 | |||
2190 | /* | ||
2191 | * usbvideo_SoftwareContrastAdjustment() | ||
2192 | * | ||
2193 | * This code adjusts the contrast of the frame, assuming RGB24 format. | ||
2194 | * As most software image processing, this job is CPU-intensive. | ||
2195 | * Get a camera that supports hardware adjustment! | ||
2196 | * | ||
2197 | * History: | ||
2198 | * 09-Feb-2001 Created. | ||
2199 | */ | ||
2200 | static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd, | ||
2201 | struct usbvideo_frame *frame) | ||
2202 | { | ||
2203 | int i, j, v4l_linesize; | ||
2204 | signed long adj; | ||
2205 | const int ccm = 128; /* Color correction median - see below */ | ||
2206 | |||
2207 | if ((uvd == NULL) || (frame == NULL)) { | ||
2208 | err("%s: Illegal call.", __func__); | ||
2209 | return; | ||
2210 | } | ||
2211 | adj = (uvd->vpic.contrast - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/ | ||
2212 | RESTRICT_TO_RANGE(adj, -ccm, ccm+1); | ||
2213 | if (adj == 0) { | ||
2214 | /* In rare case of no adjustment */ | ||
2215 | return; | ||
2216 | } | ||
2217 | v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL; | ||
2218 | for (i=0; i < VIDEOSIZE_Y(frame->request); i++) { | ||
2219 | unsigned char *fd = frame->data + (v4l_linesize * i); | ||
2220 | for (j=0; j < v4l_linesize; j++) { | ||
2221 | signed long v = (signed long) fd[j]; | ||
2222 | /* Magnify up to 2 times, reduce down to zero */ | ||
2223 | v = 128 + ((ccm + adj) * (v - 128)) / ccm; | ||
2224 | RESTRICT_TO_RANGE(v, 0, 0xFF); /* Must flatten tails */ | ||
2225 | fd[j] = (unsigned char) v; | ||
2226 | } | ||
2227 | } | ||
2228 | } | ||
2229 | |||
2230 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/usbvideo/usbvideo.h b/drivers/media/video/usbvideo/usbvideo.h deleted file mode 100644 index c66985beb8c9..000000000000 --- a/drivers/media/video/usbvideo/usbvideo.h +++ /dev/null | |||
@@ -1,395 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License as published by | ||
4 | * the Free Software Foundation; either version 2, or (at your option) | ||
5 | * any later version. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | * | ||
12 | * You should have received a copy of the GNU General Public License | ||
13 | * along with this program; if not, write to the Free Software | ||
14 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
15 | */ | ||
16 | #ifndef usbvideo_h | ||
17 | #define usbvideo_h | ||
18 | |||
19 | #include <linux/videodev.h> | ||
20 | #include <media/v4l2-common.h> | ||
21 | #include <media/v4l2-ioctl.h> | ||
22 | #include <linux/usb.h> | ||
23 | #include <linux/mutex.h> | ||
24 | |||
25 | /* Most helpful debugging aid */ | ||
26 | #define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__)))) | ||
27 | |||
28 | #define USBVIDEO_REPORT_STATS 1 /* Set to 0 to block statistics on close */ | ||
29 | |||
30 | /* Bit flags (options) */ | ||
31 | #define FLAGS_RETRY_VIDIOCSYNC (1 << 0) | ||
32 | #define FLAGS_MONOCHROME (1 << 1) | ||
33 | #define FLAGS_DISPLAY_HINTS (1 << 2) | ||
34 | #define FLAGS_OVERLAY_STATS (1 << 3) | ||
35 | #define FLAGS_FORCE_TESTPATTERN (1 << 4) | ||
36 | #define FLAGS_SEPARATE_FRAMES (1 << 5) | ||
37 | #define FLAGS_CLEAN_FRAMES (1 << 6) | ||
38 | #define FLAGS_NO_DECODING (1 << 7) | ||
39 | |||
40 | /* Bit flags for frames (apply to the frame where they are specified) */ | ||
41 | #define USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST (1 << 0) | ||
42 | |||
43 | /* Camera capabilities (maximum) */ | ||
44 | #define CAMERA_URB_FRAMES 32 | ||
45 | #define CAMERA_MAX_ISO_PACKET 1023 /* 1022 actually sent by camera */ | ||
46 | #define FRAMES_PER_DESC (CAMERA_URB_FRAMES) | ||
47 | #define FRAME_SIZE_PER_DESC (CAMERA_MAX_ISO_PACKET) | ||
48 | |||
49 | /* This macro restricts an int variable to an inclusive range */ | ||
50 | #define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); } | ||
51 | |||
52 | #define V4L_BYTES_PER_PIXEL 3 /* Because we produce RGB24 */ | ||
53 | |||
54 | /* | ||
55 | * Use this macro to construct constants for different video sizes. | ||
56 | * We have to deal with different video sizes that have to be | ||
57 | * configured in the device or compared against when we receive | ||
58 | * a data. Normally one would define a bunch of VIDEOSIZE_x_by_y | ||
59 | * #defines and that's the end of story. However this solution | ||
60 | * does not allow to convert between real pixel sizes and the | ||
61 | * constant (integer) value that may be used to tag a frame or | ||
62 | * whatever. The set of macros below constructs videosize constants | ||
63 | * from the pixel size and allows to reconstruct the pixel size | ||
64 | * from the combined value later. | ||
65 | */ | ||
66 | #define VIDEOSIZE(x,y) (((x) & 0xFFFFL) | (((y) & 0xFFFFL) << 16)) | ||
67 | #define VIDEOSIZE_X(vs) ((vs) & 0xFFFFL) | ||
68 | #define VIDEOSIZE_Y(vs) (((vs) >> 16) & 0xFFFFL) | ||
69 | typedef unsigned long videosize_t; | ||
70 | |||
71 | /* | ||
72 | * This macro checks if the camera is still operational. The 'uvd' | ||
73 | * pointer must be valid, uvd->dev must be valid, we are not | ||
74 | * removing the device and the device has not erred on us. | ||
75 | */ | ||
76 | #define CAMERA_IS_OPERATIONAL(uvd) (\ | ||
77 | (uvd != NULL) && \ | ||
78 | ((uvd)->dev != NULL) && \ | ||
79 | ((uvd)->last_error == 0) && \ | ||
80 | (!(uvd)->remove_pending)) | ||
81 | |||
82 | /* | ||
83 | * We use macros to do YUV -> RGB conversion because this is | ||
84 | * very important for speed and totally unimportant for size. | ||
85 | * | ||
86 | * YUV -> RGB Conversion | ||
87 | * --------------------- | ||
88 | * | ||
89 | * B = 1.164*(Y-16) + 2.018*(V-128) | ||
90 | * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128) | ||
91 | * R = 1.164*(Y-16) + 1.596*(U-128) | ||
92 | * | ||
93 | * If you fancy integer arithmetics (as you should), hear this: | ||
94 | * | ||
95 | * 65536*B = 76284*(Y-16) + 132252*(V-128) | ||
96 | * 65536*G = 76284*(Y-16) - 53281*(U-128) - 25625*(V-128) | ||
97 | * 65536*R = 76284*(Y-16) + 104595*(U-128) | ||
98 | * | ||
99 | * Make sure the output values are within [0..255] range. | ||
100 | */ | ||
101 | #define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x))) | ||
102 | #define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \ | ||
103 | int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \ | ||
104 | mm_y = (my) - 16; \ | ||
105 | mm_u = (mu) - 128; \ | ||
106 | mm_v = (mv) - 128; \ | ||
107 | mm_yc= mm_y * 76284; \ | ||
108 | mm_b = (mm_yc + 132252*mm_v ) >> 16; \ | ||
109 | mm_g = (mm_yc - 53281*mm_u - 25625*mm_v ) >> 16; \ | ||
110 | mm_r = (mm_yc + 104595*mm_u ) >> 16; \ | ||
111 | mb = LIMIT_RGB(mm_b); \ | ||
112 | mg = LIMIT_RGB(mm_g); \ | ||
113 | mr = LIMIT_RGB(mm_r); \ | ||
114 | } | ||
115 | |||
116 | #define RING_QUEUE_SIZE (128*1024) /* Must be a power of 2 */ | ||
117 | #define RING_QUEUE_ADVANCE_INDEX(rq,ind,n) (rq)->ind = ((rq)->ind + (n)) & ((rq)->length-1) | ||
118 | #define RING_QUEUE_DEQUEUE_BYTES(rq,n) RING_QUEUE_ADVANCE_INDEX(rq,ri,n) | ||
119 | #define RING_QUEUE_PEEK(rq,ofs) ((rq)->queue[((ofs) + (rq)->ri) & ((rq)->length-1)]) | ||
120 | |||
121 | struct RingQueue { | ||
122 | unsigned char *queue; /* Data from the Isoc data pump */ | ||
123 | int length; /* How many bytes allocated for the queue */ | ||
124 | int wi; /* That's where we write */ | ||
125 | int ri; /* Read from here until you hit write index */ | ||
126 | wait_queue_head_t wqh; /* Processes waiting */ | ||
127 | }; | ||
128 | |||
129 | enum ScanState { | ||
130 | ScanState_Scanning, /* Scanning for header */ | ||
131 | ScanState_Lines /* Parsing lines */ | ||
132 | }; | ||
133 | |||
134 | /* Completion states of the data parser */ | ||
135 | enum ParseState { | ||
136 | scan_Continue, /* Just parse next item */ | ||
137 | scan_NextFrame, /* Frame done, send it to V4L */ | ||
138 | scan_Out, /* Not enough data for frame */ | ||
139 | scan_EndParse /* End parsing */ | ||
140 | }; | ||
141 | |||
142 | enum FrameState { | ||
143 | FrameState_Unused, /* Unused (no MCAPTURE) */ | ||
144 | FrameState_Ready, /* Ready to start grabbing */ | ||
145 | FrameState_Grabbing, /* In the process of being grabbed into */ | ||
146 | FrameState_Done, /* Finished grabbing, but not been synced yet */ | ||
147 | FrameState_Done_Hold, /* Are syncing or reading */ | ||
148 | FrameState_Error, /* Something bad happened while processing */ | ||
149 | }; | ||
150 | |||
151 | /* | ||
152 | * Some frames may contain only even or odd lines. This type | ||
153 | * specifies what type of deinterlacing is required. | ||
154 | */ | ||
155 | enum Deinterlace { | ||
156 | Deinterlace_None=0, | ||
157 | Deinterlace_FillOddLines, | ||
158 | Deinterlace_FillEvenLines | ||
159 | }; | ||
160 | |||
161 | #define USBVIDEO_NUMFRAMES 2 /* How many frames we work with */ | ||
162 | #define USBVIDEO_NUMSBUF 2 /* How many URBs linked in a ring */ | ||
163 | |||
164 | /* This structure represents one Isoc request - URB and buffer */ | ||
165 | struct usbvideo_sbuf { | ||
166 | char *data; | ||
167 | struct urb *urb; | ||
168 | }; | ||
169 | |||
170 | struct usbvideo_frame { | ||
171 | char *data; /* Frame buffer */ | ||
172 | unsigned long header; /* Significant bits from the header */ | ||
173 | |||
174 | videosize_t canvas; /* The canvas (max. image) allocated */ | ||
175 | videosize_t request; /* That's what the application asked for */ | ||
176 | unsigned short palette; /* The desired format */ | ||
177 | |||
178 | enum FrameState frameState;/* State of grabbing */ | ||
179 | enum ScanState scanstate; /* State of scanning */ | ||
180 | enum Deinterlace deinterlace; | ||
181 | int flags; /* USBVIDEO_FRAME_FLAG_xxx bit flags */ | ||
182 | |||
183 | int curline; /* Line of frame we're working on */ | ||
184 | |||
185 | long seqRead_Length; /* Raw data length of frame */ | ||
186 | long seqRead_Index; /* Amount of data that has been already read */ | ||
187 | |||
188 | void *user; /* Additional data that user may need */ | ||
189 | }; | ||
190 | |||
191 | /* Statistics that can be overlaid on screen */ | ||
192 | struct usbvideo_statistics { | ||
193 | unsigned long frame_num; /* Sequential number of the frame */ | ||
194 | unsigned long urb_count; /* How many URBs we received so far */ | ||
195 | unsigned long urb_length; /* Length of last URB */ | ||
196 | unsigned long data_count; /* How many bytes we received */ | ||
197 | unsigned long header_count; /* How many frame headers we found */ | ||
198 | unsigned long iso_skip_count; /* How many empty ISO packets received */ | ||
199 | unsigned long iso_err_count; /* How many bad ISO packets received */ | ||
200 | }; | ||
201 | |||
202 | struct usbvideo; | ||
203 | |||
204 | struct uvd { | ||
205 | struct video_device vdev; /* Must be the first field! */ | ||
206 | struct usb_device *dev; | ||
207 | struct usbvideo *handle; /* Points back to the struct usbvideo */ | ||
208 | void *user_data; /* Camera-dependent data */ | ||
209 | int user_size; /* Size of that camera-dependent data */ | ||
210 | int debug; /* Debug level for usbvideo */ | ||
211 | unsigned char iface; /* Video interface number */ | ||
212 | unsigned char video_endp; | ||
213 | unsigned char ifaceAltActive; | ||
214 | unsigned char ifaceAltInactive; /* Alt settings */ | ||
215 | unsigned long flags; /* FLAGS_USBVIDEO_xxx */ | ||
216 | unsigned long paletteBits; /* Which palettes we accept? */ | ||
217 | unsigned short defaultPalette; /* What palette to use for read() */ | ||
218 | struct mutex lock; | ||
219 | int user; /* user count for exclusive use */ | ||
220 | |||
221 | videosize_t videosize; /* Current setting */ | ||
222 | videosize_t canvas; /* This is the width,height of the V4L canvas */ | ||
223 | int max_frame_size; /* Bytes in one video frame */ | ||
224 | |||
225 | int uvd_used; /* Is this structure in use? */ | ||
226 | int streaming; /* Are we streaming Isochronous? */ | ||
227 | int grabbing; /* Are we grabbing? */ | ||
228 | int settingsAdjusted; /* Have we adjusted contrast etc.? */ | ||
229 | int last_error; /* What calamity struck us? */ | ||
230 | |||
231 | char *fbuf; /* Videodev buffer area */ | ||
232 | int fbuf_size; /* Videodev buffer size */ | ||
233 | |||
234 | int curframe; | ||
235 | int iso_packet_len; /* Videomode-dependent, saves bus bandwidth */ | ||
236 | |||
237 | struct RingQueue dp; /* Isoc data pump */ | ||
238 | struct usbvideo_frame frame[USBVIDEO_NUMFRAMES]; | ||
239 | struct usbvideo_sbuf sbuf[USBVIDEO_NUMSBUF]; | ||
240 | |||
241 | volatile int remove_pending; /* If set then about to exit */ | ||
242 | |||
243 | struct video_picture vpic, vpic_old; /* Picture settings */ | ||
244 | struct video_capability vcap; /* Video capabilities */ | ||
245 | struct video_channel vchan; /* May be used for tuner support */ | ||
246 | struct usbvideo_statistics stats; | ||
247 | char videoName[32]; /* Holds name like "video7" */ | ||
248 | }; | ||
249 | |||
250 | /* | ||
251 | * usbvideo callbacks (virtual methods). They are set when usbvideo | ||
252 | * services are registered. All of these default to NULL, except those | ||
253 | * that default to usbvideo-provided methods. | ||
254 | */ | ||
255 | struct usbvideo_cb { | ||
256 | int (*probe)(struct usb_interface *, const struct usb_device_id *); | ||
257 | void (*userFree)(struct uvd *); | ||
258 | void (*disconnect)(struct usb_interface *); | ||
259 | int (*setupOnOpen)(struct uvd *); | ||
260 | void (*videoStart)(struct uvd *); | ||
261 | void (*videoStop)(struct uvd *); | ||
262 | void (*processData)(struct uvd *, struct usbvideo_frame *); | ||
263 | void (*postProcess)(struct uvd *, struct usbvideo_frame *); | ||
264 | void (*adjustPicture)(struct uvd *); | ||
265 | int (*getFPS)(struct uvd *); | ||
266 | int (*overlayHook)(struct uvd *, struct usbvideo_frame *); | ||
267 | int (*getFrame)(struct uvd *, int); | ||
268 | int (*startDataPump)(struct uvd *uvd); | ||
269 | void (*stopDataPump)(struct uvd *uvd); | ||
270 | int (*setVideoMode)(struct uvd *uvd, struct video_window *vw); | ||
271 | }; | ||
272 | |||
273 | struct usbvideo { | ||
274 | int num_cameras; /* As allocated */ | ||
275 | struct usb_driver usbdrv; /* Interface to the USB stack */ | ||
276 | char drvName[80]; /* Driver name */ | ||
277 | struct mutex lock; /* Mutex protecting camera structures */ | ||
278 | struct usbvideo_cb cb; /* Table of callbacks (virtual methods) */ | ||
279 | struct video_device vdt; /* Video device template */ | ||
280 | struct uvd *cam; /* Array of camera structures */ | ||
281 | struct module *md_module; /* Minidriver module */ | ||
282 | }; | ||
283 | |||
284 | |||
285 | /* | ||
286 | * This macro retrieves callback address from the struct uvd object. | ||
287 | * No validity checks are done here, so be sure to check the | ||
288 | * callback beforehand with VALID_CALLBACK. | ||
289 | */ | ||
290 | #define GET_CALLBACK(uvd,cbName) ((uvd)->handle->cb.cbName) | ||
291 | |||
292 | /* | ||
293 | * This macro returns either callback pointer or NULL. This is safe | ||
294 | * macro, meaning that most of components of data structures involved | ||
295 | * may be NULL - this only results in NULL being returned. You may | ||
296 | * wish to use this macro to make sure that the callback is callable. | ||
297 | * However keep in mind that those checks take time. | ||
298 | */ | ||
299 | #define VALID_CALLBACK(uvd,cbName) ((((uvd) != NULL) && \ | ||
300 | ((uvd)->handle != NULL)) ? GET_CALLBACK(uvd,cbName) : NULL) | ||
301 | |||
302 | int RingQueue_Dequeue(struct RingQueue *rq, unsigned char *dst, int len); | ||
303 | int RingQueue_Enqueue(struct RingQueue *rq, const unsigned char *cdata, int n); | ||
304 | void RingQueue_WakeUpInterruptible(struct RingQueue *rq); | ||
305 | void RingQueue_Flush(struct RingQueue *rq); | ||
306 | |||
307 | static inline int RingQueue_GetLength(const struct RingQueue *rq) | ||
308 | { | ||
309 | return (rq->wi - rq->ri + rq->length) & (rq->length-1); | ||
310 | } | ||
311 | |||
312 | static inline int RingQueue_GetFreeSpace(const struct RingQueue *rq) | ||
313 | { | ||
314 | return rq->length - RingQueue_GetLength(rq); | ||
315 | } | ||
316 | |||
317 | void usbvideo_DrawLine( | ||
318 | struct usbvideo_frame *frame, | ||
319 | int x1, int y1, | ||
320 | int x2, int y2, | ||
321 | unsigned char cr, unsigned char cg, unsigned char cb); | ||
322 | void usbvideo_HexDump(const unsigned char *data, int len); | ||
323 | void usbvideo_SayAndWait(const char *what); | ||
324 | void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode); | ||
325 | |||
326 | /* Memory allocation routines */ | ||
327 | unsigned long usbvideo_kvirt_to_pa(unsigned long adr); | ||
328 | |||
329 | int usbvideo_register( | ||
330 | struct usbvideo **pCams, | ||
331 | const int num_cams, | ||
332 | const int num_extra, | ||
333 | const char *driverName, | ||
334 | const struct usbvideo_cb *cbTable, | ||
335 | struct module *md, | ||
336 | const struct usb_device_id *id_table); | ||
337 | struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams); | ||
338 | int usbvideo_RegisterVideoDevice(struct uvd *uvd); | ||
339 | void usbvideo_Deregister(struct usbvideo **uvt); | ||
340 | |||
341 | int usbvideo_v4l_initialize(struct video_device *dev); | ||
342 | |||
343 | void usbvideo_DeinterlaceFrame(struct uvd *uvd, struct usbvideo_frame *frame); | ||
344 | |||
345 | /* | ||
346 | * This code performs bounds checking - use it when working with | ||
347 | * new formats, or else you may get oopses all over the place. | ||
348 | * If pixel falls out of bounds then it gets shoved back (as close | ||
349 | * to place of offence as possible) and is painted bright red. | ||
350 | * | ||
351 | * There are two important concepts: frame width, height and | ||
352 | * V4L canvas width, height. The former is the area requested by | ||
353 | * the application -for this very frame-. The latter is the largest | ||
354 | * possible frame that we can serve (we advertise that via V4L ioctl). | ||
355 | * The frame data is expected to be formatted as lines of length | ||
356 | * VIDEOSIZE_X(fr->request), total VIDEOSIZE_Y(frame->request) lines. | ||
357 | */ | ||
358 | static inline void RGB24_PUTPIXEL( | ||
359 | struct usbvideo_frame *fr, | ||
360 | int ix, int iy, | ||
361 | unsigned char vr, | ||
362 | unsigned char vg, | ||
363 | unsigned char vb) | ||
364 | { | ||
365 | register unsigned char *pf; | ||
366 | int limiter = 0, mx, my; | ||
367 | mx = ix; | ||
368 | my = iy; | ||
369 | if (mx < 0) { | ||
370 | mx=0; | ||
371 | limiter++; | ||
372 | } else if (mx >= VIDEOSIZE_X((fr)->request)) { | ||
373 | mx= VIDEOSIZE_X((fr)->request) - 1; | ||
374 | limiter++; | ||
375 | } | ||
376 | if (my < 0) { | ||
377 | my = 0; | ||
378 | limiter++; | ||
379 | } else if (my >= VIDEOSIZE_Y((fr)->request)) { | ||
380 | my = VIDEOSIZE_Y((fr)->request) - 1; | ||
381 | limiter++; | ||
382 | } | ||
383 | pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*VIDEOSIZE_X((fr)->request) + (ix)); | ||
384 | if (limiter) { | ||
385 | *pf++ = 0; | ||
386 | *pf++ = 0; | ||
387 | *pf++ = 0xFF; | ||
388 | } else { | ||
389 | *pf++ = (vb); | ||
390 | *pf++ = (vg); | ||
391 | *pf++ = (vr); | ||
392 | } | ||
393 | } | ||
394 | |||
395 | #endif /* usbvideo_h */ | ||
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c deleted file mode 100644 index dc17cce2fbb6..000000000000 --- a/drivers/media/video/usbvideo/vicam.c +++ /dev/null | |||
@@ -1,952 +0,0 @@ | |||
1 | /* | ||
2 | * USB ViCam WebCam driver | ||
3 | * Copyright (c) 2002 Joe Burks (jburks@wavicle.org), | ||
4 | * Christopher L Cheney (ccheney@cheney.cx), | ||
5 | * Pavel Machek (pavel@ucw.cz), | ||
6 | * John Tyner (jtyner@cs.ucr.edu), | ||
7 | * Monroe Williams (monroe@pobox.com) | ||
8 | * | ||
9 | * Supports 3COM HomeConnect PC Digital WebCam | ||
10 | * Supports Compro PS39U WebCam | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | * | ||
26 | * This source code is based heavily on the CPiA webcam driver which was | ||
27 | * written by Peter Pregler, Scott J. Bertin and Johannes Erdfelt | ||
28 | * | ||
29 | * Portions of this code were also copied from usbvideo.c | ||
30 | * | ||
31 | * Special thanks to the whole team at Sourceforge for help making | ||
32 | * this driver become a reality. Notably: | ||
33 | * Andy Armstrong who reverse engineered the color encoding and | ||
34 | * Pavel Machek and Chris Cheney who worked on reverse engineering the | ||
35 | * camera controls and wrote the first generation driver. | ||
36 | */ | ||
37 | |||
38 | #include <linux/kernel.h> | ||
39 | #include <linux/module.h> | ||
40 | #include <linux/init.h> | ||
41 | #include <linux/videodev.h> | ||
42 | #include <linux/usb.h> | ||
43 | #include <linux/vmalloc.h> | ||
44 | #include <linux/mm.h> | ||
45 | #include <linux/slab.h> | ||
46 | #include <linux/mutex.h> | ||
47 | #include <linux/firmware.h> | ||
48 | #include <linux/ihex.h> | ||
49 | #include "usbvideo.h" | ||
50 | |||
51 | // #define VICAM_DEBUG | ||
52 | |||
53 | #ifdef VICAM_DEBUG | ||
54 | #define ADBG(lineno,fmt,args...) printk(fmt, jiffies, __func__, lineno, ##args) | ||
55 | #define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt,##args) | ||
56 | #else | ||
57 | #define DBG(fmn,args...) do {} while(0) | ||
58 | #endif | ||
59 | |||
60 | #define DRIVER_AUTHOR "Joe Burks, jburks@wavicle.org" | ||
61 | #define DRIVER_DESC "ViCam WebCam Driver" | ||
62 | |||
63 | /* Define these values to match your device */ | ||
64 | #define USB_VICAM_VENDOR_ID 0x04c1 | ||
65 | #define USB_VICAM_PRODUCT_ID 0x009d | ||
66 | #define USB_COMPRO_VENDOR_ID 0x0602 | ||
67 | #define USB_COMPRO_PRODUCT_ID 0x1001 | ||
68 | |||
69 | #define VICAM_BYTES_PER_PIXEL 3 | ||
70 | #define VICAM_MAX_READ_SIZE (512*242+128) | ||
71 | #define VICAM_MAX_FRAME_SIZE (VICAM_BYTES_PER_PIXEL*320*240) | ||
72 | #define VICAM_FRAMES 2 | ||
73 | |||
74 | #define VICAM_HEADER_SIZE 64 | ||
75 | |||
76 | /* rvmalloc / rvfree copied from usbvideo.c | ||
77 | * | ||
78 | * Not sure why these are not yet non-statics which I can reference through | ||
79 | * usbvideo.h the same as it is in 2.4.20. I bet this will get fixed sometime | ||
80 | * in the future. | ||
81 | * | ||
82 | */ | ||
83 | static void *rvmalloc(unsigned long size) | ||
84 | { | ||
85 | void *mem; | ||
86 | unsigned long adr; | ||
87 | |||
88 | size = PAGE_ALIGN(size); | ||
89 | mem = vmalloc_32(size); | ||
90 | if (!mem) | ||
91 | return NULL; | ||
92 | |||
93 | memset(mem, 0, size); /* Clear the ram out, no junk to the user */ | ||
94 | adr = (unsigned long) mem; | ||
95 | while (size > 0) { | ||
96 | SetPageReserved(vmalloc_to_page((void *)adr)); | ||
97 | adr += PAGE_SIZE; | ||
98 | size -= PAGE_SIZE; | ||
99 | } | ||
100 | |||
101 | return mem; | ||
102 | } | ||
103 | |||
104 | static void rvfree(void *mem, unsigned long size) | ||
105 | { | ||
106 | unsigned long adr; | ||
107 | |||
108 | if (!mem) | ||
109 | return; | ||
110 | |||
111 | adr = (unsigned long) mem; | ||
112 | while ((long) size > 0) { | ||
113 | ClearPageReserved(vmalloc_to_page((void *)adr)); | ||
114 | adr += PAGE_SIZE; | ||
115 | size -= PAGE_SIZE; | ||
116 | } | ||
117 | vfree(mem); | ||
118 | } | ||
119 | |||
120 | struct vicam_camera { | ||
121 | u16 shutter_speed; // capture shutter speed | ||
122 | u16 gain; // capture gain | ||
123 | |||
124 | u8 *raw_image; // raw data captured from the camera | ||
125 | u8 *framebuf; // processed data in RGB24 format | ||
126 | u8 *cntrlbuf; // area used to send control msgs | ||
127 | |||
128 | struct video_device vdev; // v4l video device | ||
129 | struct usb_device *udev; // usb device | ||
130 | |||
131 | /* guard against simultaneous accesses to the camera */ | ||
132 | struct mutex cam_lock; | ||
133 | |||
134 | int is_initialized; | ||
135 | u8 open_count; | ||
136 | u8 bulkEndpoint; | ||
137 | int needsDummyRead; | ||
138 | }; | ||
139 | |||
140 | static int vicam_probe( struct usb_interface *intf, const struct usb_device_id *id); | ||
141 | static void vicam_disconnect(struct usb_interface *intf); | ||
142 | static void read_frame(struct vicam_camera *cam, int framenum); | ||
143 | static void vicam_decode_color(const u8 *, u8 *); | ||
144 | |||
145 | static int __send_control_msg(struct vicam_camera *cam, | ||
146 | u8 request, | ||
147 | u16 value, | ||
148 | u16 index, | ||
149 | unsigned char *cp, | ||
150 | u16 size) | ||
151 | { | ||
152 | int status; | ||
153 | |||
154 | /* cp must be memory that has been allocated by kmalloc */ | ||
155 | |||
156 | status = usb_control_msg(cam->udev, | ||
157 | usb_sndctrlpipe(cam->udev, 0), | ||
158 | request, | ||
159 | USB_DIR_OUT | USB_TYPE_VENDOR | | ||
160 | USB_RECIP_DEVICE, value, index, | ||
161 | cp, size, 1000); | ||
162 | |||
163 | status = min(status, 0); | ||
164 | |||
165 | if (status < 0) { | ||
166 | printk(KERN_INFO "Failed sending control message, error %d.\n", | ||
167 | status); | ||
168 | } | ||
169 | |||
170 | return status; | ||
171 | } | ||
172 | |||
173 | static int send_control_msg(struct vicam_camera *cam, | ||
174 | u8 request, | ||
175 | u16 value, | ||
176 | u16 index, | ||
177 | unsigned char *cp, | ||
178 | u16 size) | ||
179 | { | ||
180 | int status = -ENODEV; | ||
181 | mutex_lock(&cam->cam_lock); | ||
182 | if (cam->udev) { | ||
183 | status = __send_control_msg(cam, request, value, | ||
184 | index, cp, size); | ||
185 | } | ||
186 | mutex_unlock(&cam->cam_lock); | ||
187 | return status; | ||
188 | } | ||
189 | static int | ||
190 | initialize_camera(struct vicam_camera *cam) | ||
191 | { | ||
192 | int err; | ||
193 | const struct ihex_binrec *rec; | ||
194 | const struct firmware *uninitialized_var(fw); | ||
195 | |||
196 | err = request_ihex_firmware(&fw, "vicam/firmware.fw", &cam->udev->dev); | ||
197 | if (err) { | ||
198 | printk(KERN_ERR "Failed to load \"vicam/firmware.fw\": %d\n", | ||
199 | err); | ||
200 | return err; | ||
201 | } | ||
202 | |||
203 | for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) { | ||
204 | memcpy(cam->cntrlbuf, rec->data, be16_to_cpu(rec->len)); | ||
205 | |||
206 | err = send_control_msg(cam, 0xff, 0, 0, | ||
207 | cam->cntrlbuf, be16_to_cpu(rec->len)); | ||
208 | if (err) | ||
209 | break; | ||
210 | } | ||
211 | |||
212 | release_firmware(fw); | ||
213 | |||
214 | return err; | ||
215 | } | ||
216 | |||
217 | static int | ||
218 | set_camera_power(struct vicam_camera *cam, int state) | ||
219 | { | ||
220 | int status; | ||
221 | |||
222 | if ((status = send_control_msg(cam, 0x50, state, 0, NULL, 0)) < 0) | ||
223 | return status; | ||
224 | |||
225 | if (state) { | ||
226 | send_control_msg(cam, 0x55, 1, 0, NULL, 0); | ||
227 | } | ||
228 | |||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | static long | ||
233 | vicam_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg) | ||
234 | { | ||
235 | void __user *user_arg = (void __user *)arg; | ||
236 | struct vicam_camera *cam = file->private_data; | ||
237 | long retval = 0; | ||
238 | |||
239 | if (!cam) | ||
240 | return -ENODEV; | ||
241 | |||
242 | switch (ioctlnr) { | ||
243 | /* query capabilities */ | ||
244 | case VIDIOCGCAP: | ||
245 | { | ||
246 | struct video_capability b; | ||
247 | |||
248 | DBG("VIDIOCGCAP\n"); | ||
249 | memset(&b, 0, sizeof(b)); | ||
250 | strcpy(b.name, "ViCam-based Camera"); | ||
251 | b.type = VID_TYPE_CAPTURE; | ||
252 | b.channels = 1; | ||
253 | b.audios = 0; | ||
254 | b.maxwidth = 320; /* VIDEOSIZE_CIF */ | ||
255 | b.maxheight = 240; | ||
256 | b.minwidth = 320; /* VIDEOSIZE_48_48 */ | ||
257 | b.minheight = 240; | ||
258 | |||
259 | if (copy_to_user(user_arg, &b, sizeof(b))) | ||
260 | retval = -EFAULT; | ||
261 | |||
262 | break; | ||
263 | } | ||
264 | /* get/set video source - we are a camera and nothing else */ | ||
265 | case VIDIOCGCHAN: | ||
266 | { | ||
267 | struct video_channel v; | ||
268 | |||
269 | DBG("VIDIOCGCHAN\n"); | ||
270 | if (copy_from_user(&v, user_arg, sizeof(v))) { | ||
271 | retval = -EFAULT; | ||
272 | break; | ||
273 | } | ||
274 | if (v.channel != 0) { | ||
275 | retval = -EINVAL; | ||
276 | break; | ||
277 | } | ||
278 | |||
279 | v.channel = 0; | ||
280 | strcpy(v.name, "Camera"); | ||
281 | v.tuners = 0; | ||
282 | v.flags = 0; | ||
283 | v.type = VIDEO_TYPE_CAMERA; | ||
284 | v.norm = 0; | ||
285 | |||
286 | if (copy_to_user(user_arg, &v, sizeof(v))) | ||
287 | retval = -EFAULT; | ||
288 | break; | ||
289 | } | ||
290 | |||
291 | case VIDIOCSCHAN: | ||
292 | { | ||
293 | int v; | ||
294 | |||
295 | if (copy_from_user(&v, user_arg, sizeof(v))) | ||
296 | retval = -EFAULT; | ||
297 | DBG("VIDIOCSCHAN %d\n", v); | ||
298 | |||
299 | if (retval == 0 && v != 0) | ||
300 | retval = -EINVAL; | ||
301 | |||
302 | break; | ||
303 | } | ||
304 | |||
305 | /* image properties */ | ||
306 | case VIDIOCGPICT: | ||
307 | { | ||
308 | struct video_picture vp; | ||
309 | DBG("VIDIOCGPICT\n"); | ||
310 | memset(&vp, 0, sizeof (struct video_picture)); | ||
311 | vp.brightness = cam->gain << 8; | ||
312 | vp.depth = 24; | ||
313 | vp.palette = VIDEO_PALETTE_RGB24; | ||
314 | if (copy_to_user(user_arg, &vp, sizeof (struct video_picture))) | ||
315 | retval = -EFAULT; | ||
316 | break; | ||
317 | } | ||
318 | |||
319 | case VIDIOCSPICT: | ||
320 | { | ||
321 | struct video_picture vp; | ||
322 | |||
323 | if (copy_from_user(&vp, user_arg, sizeof(vp))) { | ||
324 | retval = -EFAULT; | ||
325 | break; | ||
326 | } | ||
327 | |||
328 | DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp.depth, | ||
329 | vp.palette); | ||
330 | |||
331 | cam->gain = vp.brightness >> 8; | ||
332 | |||
333 | if (vp.depth != 24 | ||
334 | || vp.palette != VIDEO_PALETTE_RGB24) | ||
335 | retval = -EINVAL; | ||
336 | |||
337 | break; | ||
338 | } | ||
339 | |||
340 | /* get/set capture window */ | ||
341 | case VIDIOCGWIN: | ||
342 | { | ||
343 | struct video_window vw; | ||
344 | vw.x = 0; | ||
345 | vw.y = 0; | ||
346 | vw.width = 320; | ||
347 | vw.height = 240; | ||
348 | vw.chromakey = 0; | ||
349 | vw.flags = 0; | ||
350 | vw.clips = NULL; | ||
351 | vw.clipcount = 0; | ||
352 | |||
353 | DBG("VIDIOCGWIN\n"); | ||
354 | |||
355 | if (copy_to_user(user_arg, (void *)&vw, sizeof(vw))) | ||
356 | retval = -EFAULT; | ||
357 | |||
358 | // I'm not sure what the deal with a capture window is, it is very poorly described | ||
359 | // in the doc. So I won't support it now. | ||
360 | break; | ||
361 | } | ||
362 | |||
363 | case VIDIOCSWIN: | ||
364 | { | ||
365 | |||
366 | struct video_window vw; | ||
367 | |||
368 | if (copy_from_user(&vw, user_arg, sizeof(vw))) { | ||
369 | retval = -EFAULT; | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | DBG("VIDIOCSWIN %d x %d\n", vw.width, vw.height); | ||
374 | |||
375 | if ( vw.width != 320 || vw.height != 240 ) | ||
376 | retval = -EFAULT; | ||
377 | |||
378 | break; | ||
379 | } | ||
380 | |||
381 | /* mmap interface */ | ||
382 | case VIDIOCGMBUF: | ||
383 | { | ||
384 | struct video_mbuf vm; | ||
385 | int i; | ||
386 | |||
387 | DBG("VIDIOCGMBUF\n"); | ||
388 | memset(&vm, 0, sizeof (vm)); | ||
389 | vm.size = | ||
390 | VICAM_MAX_FRAME_SIZE * VICAM_FRAMES; | ||
391 | vm.frames = VICAM_FRAMES; | ||
392 | for (i = 0; i < VICAM_FRAMES; i++) | ||
393 | vm.offsets[i] = VICAM_MAX_FRAME_SIZE * i; | ||
394 | |||
395 | if (copy_to_user(user_arg, (void *)&vm, sizeof(vm))) | ||
396 | retval = -EFAULT; | ||
397 | |||
398 | break; | ||
399 | } | ||
400 | |||
401 | case VIDIOCMCAPTURE: | ||
402 | { | ||
403 | struct video_mmap vm; | ||
404 | // int video_size; | ||
405 | |||
406 | if (copy_from_user((void *)&vm, user_arg, sizeof(vm))) { | ||
407 | retval = -EFAULT; | ||
408 | break; | ||
409 | } | ||
410 | |||
411 | DBG("VIDIOCMCAPTURE frame=%d, height=%d, width=%d, format=%d.\n",vm.frame,vm.width,vm.height,vm.format); | ||
412 | |||
413 | if ( vm.frame >= VICAM_FRAMES || vm.format != VIDEO_PALETTE_RGB24 ) | ||
414 | retval = -EINVAL; | ||
415 | |||
416 | // in theory right here we'd start the image capturing | ||
417 | // (fill in a bulk urb and submit it asynchronously) | ||
418 | // | ||
419 | // Instead we're going to do a total hack job for now and | ||
420 | // retrieve the frame in VIDIOCSYNC | ||
421 | |||
422 | break; | ||
423 | } | ||
424 | |||
425 | case VIDIOCSYNC: | ||
426 | { | ||
427 | int frame; | ||
428 | |||
429 | if (copy_from_user((void *)&frame, user_arg, sizeof(int))) { | ||
430 | retval = -EFAULT; | ||
431 | break; | ||
432 | } | ||
433 | DBG("VIDIOCSYNC: %d\n", frame); | ||
434 | |||
435 | read_frame(cam, frame); | ||
436 | vicam_decode_color(cam->raw_image, | ||
437 | cam->framebuf + | ||
438 | frame * VICAM_MAX_FRAME_SIZE ); | ||
439 | |||
440 | break; | ||
441 | } | ||
442 | |||
443 | /* pointless to implement overlay with this camera */ | ||
444 | case VIDIOCCAPTURE: | ||
445 | case VIDIOCGFBUF: | ||
446 | case VIDIOCSFBUF: | ||
447 | case VIDIOCKEY: | ||
448 | retval = -EINVAL; | ||
449 | break; | ||
450 | |||
451 | /* tuner interface - we have none */ | ||
452 | case VIDIOCGTUNER: | ||
453 | case VIDIOCSTUNER: | ||
454 | case VIDIOCGFREQ: | ||
455 | case VIDIOCSFREQ: | ||
456 | retval = -EINVAL; | ||
457 | break; | ||
458 | |||
459 | /* audio interface - we have none */ | ||
460 | case VIDIOCGAUDIO: | ||
461 | case VIDIOCSAUDIO: | ||
462 | retval = -EINVAL; | ||
463 | break; | ||
464 | default: | ||
465 | retval = -ENOIOCTLCMD; | ||
466 | break; | ||
467 | } | ||
468 | |||
469 | return retval; | ||
470 | } | ||
471 | |||
472 | static int | ||
473 | vicam_open(struct file *file) | ||
474 | { | ||
475 | struct vicam_camera *cam = video_drvdata(file); | ||
476 | |||
477 | DBG("open\n"); | ||
478 | |||
479 | if (!cam) { | ||
480 | printk(KERN_ERR | ||
481 | "vicam video_device improperly initialized"); | ||
482 | return -EINVAL; | ||
483 | } | ||
484 | |||
485 | /* cam_lock/open_count protects us from simultaneous opens | ||
486 | * ... for now. we probably shouldn't rely on this fact forever. | ||
487 | */ | ||
488 | |||
489 | mutex_lock(&cam->cam_lock); | ||
490 | if (cam->open_count > 0) { | ||
491 | printk(KERN_INFO | ||
492 | "vicam_open called on already opened camera"); | ||
493 | mutex_unlock(&cam->cam_lock); | ||
494 | return -EBUSY; | ||
495 | } | ||
496 | |||
497 | cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL); | ||
498 | if (!cam->raw_image) { | ||
499 | mutex_unlock(&cam->cam_lock); | ||
500 | return -ENOMEM; | ||
501 | } | ||
502 | |||
503 | cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); | ||
504 | if (!cam->framebuf) { | ||
505 | kfree(cam->raw_image); | ||
506 | mutex_unlock(&cam->cam_lock); | ||
507 | return -ENOMEM; | ||
508 | } | ||
509 | |||
510 | cam->cntrlbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
511 | if (!cam->cntrlbuf) { | ||
512 | kfree(cam->raw_image); | ||
513 | rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); | ||
514 | mutex_unlock(&cam->cam_lock); | ||
515 | return -ENOMEM; | ||
516 | } | ||
517 | |||
518 | cam->needsDummyRead = 1; | ||
519 | cam->open_count++; | ||
520 | |||
521 | file->private_data = cam; | ||
522 | mutex_unlock(&cam->cam_lock); | ||
523 | |||
524 | |||
525 | // First upload firmware, then turn the camera on | ||
526 | |||
527 | if (!cam->is_initialized) { | ||
528 | initialize_camera(cam); | ||
529 | |||
530 | cam->is_initialized = 1; | ||
531 | } | ||
532 | |||
533 | set_camera_power(cam, 1); | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int | ||
539 | vicam_close(struct file *file) | ||
540 | { | ||
541 | struct vicam_camera *cam = file->private_data; | ||
542 | int open_count; | ||
543 | struct usb_device *udev; | ||
544 | |||
545 | DBG("close\n"); | ||
546 | |||
547 | /* it's not the end of the world if | ||
548 | * we fail to turn the camera off. | ||
549 | */ | ||
550 | |||
551 | set_camera_power(cam, 0); | ||
552 | |||
553 | kfree(cam->raw_image); | ||
554 | rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); | ||
555 | kfree(cam->cntrlbuf); | ||
556 | |||
557 | mutex_lock(&cam->cam_lock); | ||
558 | |||
559 | cam->open_count--; | ||
560 | open_count = cam->open_count; | ||
561 | udev = cam->udev; | ||
562 | |||
563 | mutex_unlock(&cam->cam_lock); | ||
564 | |||
565 | if (!open_count && !udev) { | ||
566 | kfree(cam); | ||
567 | } | ||
568 | |||
569 | return 0; | ||
570 | } | ||
571 | |||
572 | static void vicam_decode_color(const u8 *data, u8 *rgb) | ||
573 | { | ||
574 | /* vicam_decode_color - Convert from Vicam Y-Cr-Cb to RGB | ||
575 | * Copyright (C) 2002 Monroe Williams (monroe@pobox.com) | ||
576 | */ | ||
577 | |||
578 | int i, prevY, nextY; | ||
579 | |||
580 | prevY = 512; | ||
581 | nextY = 512; | ||
582 | |||
583 | data += VICAM_HEADER_SIZE; | ||
584 | |||
585 | for( i = 0; i < 240; i++, data += 512 ) { | ||
586 | const int y = ( i * 242 ) / 240; | ||
587 | |||
588 | int j, prevX, nextX; | ||
589 | int Y, Cr, Cb; | ||
590 | |||
591 | if ( y == 242 - 1 ) { | ||
592 | nextY = -512; | ||
593 | } | ||
594 | |||
595 | prevX = 1; | ||
596 | nextX = 1; | ||
597 | |||
598 | for ( j = 0; j < 320; j++, rgb += 3 ) { | ||
599 | const int x = ( j * 512 ) / 320; | ||
600 | const u8 * const src = &data[x]; | ||
601 | |||
602 | if ( x == 512 - 1 ) { | ||
603 | nextX = -1; | ||
604 | } | ||
605 | |||
606 | Cr = ( src[prevX] - src[0] ) + | ||
607 | ( src[nextX] - src[0] ); | ||
608 | Cr /= 2; | ||
609 | |||
610 | Cb = ( src[prevY] - src[prevX + prevY] ) + | ||
611 | ( src[prevY] - src[nextX + prevY] ) + | ||
612 | ( src[nextY] - src[prevX + nextY] ) + | ||
613 | ( src[nextY] - src[nextX + nextY] ); | ||
614 | Cb /= 4; | ||
615 | |||
616 | Y = 1160 * ( src[0] + ( Cr / 2 ) - 16 ); | ||
617 | |||
618 | if ( i & 1 ) { | ||
619 | int Ct = Cr; | ||
620 | Cr = Cb; | ||
621 | Cb = Ct; | ||
622 | } | ||
623 | |||
624 | if ( ( x ^ i ) & 1 ) { | ||
625 | Cr = -Cr; | ||
626 | Cb = -Cb; | ||
627 | } | ||
628 | |||
629 | rgb[0] = clamp( ( ( Y + ( 2017 * Cb ) ) + | ||
630 | 500 ) / 900, 0, 255 ); | ||
631 | rgb[1] = clamp( ( ( Y - ( 392 * Cb ) - | ||
632 | ( 813 * Cr ) ) + | ||
633 | 500 ) / 1000, 0, 255 ); | ||
634 | rgb[2] = clamp( ( ( Y + ( 1594 * Cr ) ) + | ||
635 | 500 ) / 1300, 0, 255 ); | ||
636 | |||
637 | prevX = -1; | ||
638 | } | ||
639 | |||
640 | prevY = -512; | ||
641 | } | ||
642 | } | ||
643 | |||
644 | static void | ||
645 | read_frame(struct vicam_camera *cam, int framenum) | ||
646 | { | ||
647 | unsigned char *request = cam->cntrlbuf; | ||
648 | int realShutter; | ||
649 | int n; | ||
650 | int actual_length; | ||
651 | |||
652 | if (cam->needsDummyRead) { | ||
653 | cam->needsDummyRead = 0; | ||
654 | read_frame(cam, framenum); | ||
655 | } | ||
656 | |||
657 | memset(request, 0, 16); | ||
658 | request[0] = cam->gain; // 0 = 0% gain, FF = 100% gain | ||
659 | |||
660 | request[1] = 0; // 512x242 capture | ||
661 | |||
662 | request[2] = 0x90; // the function of these two bytes | ||
663 | request[3] = 0x07; // is not yet understood | ||
664 | |||
665 | if (cam->shutter_speed > 60) { | ||
666 | // Short exposure | ||
667 | realShutter = | ||
668 | ((-15631900 / cam->shutter_speed) + 260533) / 1000; | ||
669 | request[4] = realShutter & 0xFF; | ||
670 | request[5] = (realShutter >> 8) & 0xFF; | ||
671 | request[6] = 0x03; | ||
672 | request[7] = 0x01; | ||
673 | } else { | ||
674 | // Long exposure | ||
675 | realShutter = 15600 / cam->shutter_speed - 1; | ||
676 | request[4] = 0; | ||
677 | request[5] = 0; | ||
678 | request[6] = realShutter & 0xFF; | ||
679 | request[7] = realShutter >> 8; | ||
680 | } | ||
681 | |||
682 | // Per John Markus Bjørndalen, byte at index 8 causes problems if it isn't 0 | ||
683 | request[8] = 0; | ||
684 | // bytes 9-15 do not seem to affect exposure or image quality | ||
685 | |||
686 | mutex_lock(&cam->cam_lock); | ||
687 | |||
688 | if (!cam->udev) { | ||
689 | goto done; | ||
690 | } | ||
691 | |||
692 | n = __send_control_msg(cam, 0x51, 0x80, 0, request, 16); | ||
693 | |||
694 | if (n < 0) { | ||
695 | printk(KERN_ERR | ||
696 | " Problem sending frame capture control message"); | ||
697 | goto done; | ||
698 | } | ||
699 | |||
700 | n = usb_bulk_msg(cam->udev, | ||
701 | usb_rcvbulkpipe(cam->udev, cam->bulkEndpoint), | ||
702 | cam->raw_image, | ||
703 | 512 * 242 + 128, &actual_length, 10000); | ||
704 | |||
705 | if (n < 0) { | ||
706 | printk(KERN_ERR "Problem during bulk read of frame data: %d\n", | ||
707 | n); | ||
708 | } | ||
709 | |||
710 | done: | ||
711 | mutex_unlock(&cam->cam_lock); | ||
712 | } | ||
713 | |||
714 | static ssize_t | ||
715 | vicam_read( struct file *file, char __user *buf, size_t count, loff_t *ppos ) | ||
716 | { | ||
717 | struct vicam_camera *cam = file->private_data; | ||
718 | |||
719 | DBG("read %d bytes.\n", (int) count); | ||
720 | |||
721 | if (*ppos >= VICAM_MAX_FRAME_SIZE) { | ||
722 | *ppos = 0; | ||
723 | return 0; | ||
724 | } | ||
725 | |||
726 | if (*ppos == 0) { | ||
727 | read_frame(cam, 0); | ||
728 | vicam_decode_color(cam->raw_image, | ||
729 | cam->framebuf + | ||
730 | 0 * VICAM_MAX_FRAME_SIZE); | ||
731 | } | ||
732 | |||
733 | count = min_t(size_t, count, VICAM_MAX_FRAME_SIZE - *ppos); | ||
734 | |||
735 | if (copy_to_user(buf, &cam->framebuf[*ppos], count)) { | ||
736 | count = -EFAULT; | ||
737 | } else { | ||
738 | *ppos += count; | ||
739 | } | ||
740 | |||
741 | if (count == VICAM_MAX_FRAME_SIZE) { | ||
742 | *ppos = 0; | ||
743 | } | ||
744 | |||
745 | return count; | ||
746 | } | ||
747 | |||
748 | |||
749 | static int | ||
750 | vicam_mmap(struct file *file, struct vm_area_struct *vma) | ||
751 | { | ||
752 | // TODO: allocate the raw frame buffer if necessary | ||
753 | unsigned long page, pos; | ||
754 | unsigned long start = vma->vm_start; | ||
755 | unsigned long size = vma->vm_end-vma->vm_start; | ||
756 | struct vicam_camera *cam = file->private_data; | ||
757 | |||
758 | if (!cam) | ||
759 | return -ENODEV; | ||
760 | |||
761 | DBG("vicam_mmap: %ld\n", size); | ||
762 | |||
763 | /* We let mmap allocate as much as it wants because Linux was adding 2048 bytes | ||
764 | * to the size the application requested for mmap and it was screwing apps up. | ||
765 | if (size > VICAM_FRAMES*VICAM_MAX_FRAME_SIZE) | ||
766 | return -EINVAL; | ||
767 | */ | ||
768 | |||
769 | pos = (unsigned long)cam->framebuf; | ||
770 | while (size > 0) { | ||
771 | page = vmalloc_to_pfn((void *)pos); | ||
772 | if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) | ||
773 | return -EAGAIN; | ||
774 | |||
775 | start += PAGE_SIZE; | ||
776 | pos += PAGE_SIZE; | ||
777 | if (size > PAGE_SIZE) | ||
778 | size -= PAGE_SIZE; | ||
779 | else | ||
780 | size = 0; | ||
781 | } | ||
782 | |||
783 | return 0; | ||
784 | } | ||
785 | |||
786 | static const struct v4l2_file_operations vicam_fops = { | ||
787 | .owner = THIS_MODULE, | ||
788 | .open = vicam_open, | ||
789 | .release = vicam_close, | ||
790 | .read = vicam_read, | ||
791 | .mmap = vicam_mmap, | ||
792 | .ioctl = vicam_ioctl, | ||
793 | }; | ||
794 | |||
795 | static struct video_device vicam_template = { | ||
796 | .name = "ViCam-based USB Camera", | ||
797 | .fops = &vicam_fops, | ||
798 | .release = video_device_release_empty, | ||
799 | }; | ||
800 | |||
801 | /* table of devices that work with this driver */ | ||
802 | static struct usb_device_id vicam_table[] = { | ||
803 | {USB_DEVICE(USB_VICAM_VENDOR_ID, USB_VICAM_PRODUCT_ID)}, | ||
804 | {USB_DEVICE(USB_COMPRO_VENDOR_ID, USB_COMPRO_PRODUCT_ID)}, | ||
805 | {} /* Terminating entry */ | ||
806 | }; | ||
807 | |||
808 | MODULE_DEVICE_TABLE(usb, vicam_table); | ||
809 | |||
810 | static struct usb_driver vicam_driver = { | ||
811 | .name = "vicam", | ||
812 | .probe = vicam_probe, | ||
813 | .disconnect = vicam_disconnect, | ||
814 | .id_table = vicam_table | ||
815 | }; | ||
816 | |||
817 | /** | ||
818 | * vicam_probe | ||
819 | * @intf: the interface | ||
820 | * @id: the device id | ||
821 | * | ||
822 | * Called by the usb core when a new device is connected that it thinks | ||
823 | * this driver might be interested in. | ||
824 | */ | ||
825 | static int | ||
826 | vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) | ||
827 | { | ||
828 | struct usb_device *dev = interface_to_usbdev(intf); | ||
829 | int bulkEndpoint = 0; | ||
830 | const struct usb_host_interface *interface; | ||
831 | const struct usb_endpoint_descriptor *endpoint; | ||
832 | struct vicam_camera *cam; | ||
833 | |||
834 | printk(KERN_INFO "ViCam based webcam connected\n"); | ||
835 | |||
836 | interface = intf->cur_altsetting; | ||
837 | |||
838 | DBG(KERN_DEBUG "Interface %d. has %u. endpoints!\n", | ||
839 | interface->desc.bInterfaceNumber, (unsigned) (interface->desc.bNumEndpoints)); | ||
840 | endpoint = &interface->endpoint[0].desc; | ||
841 | |||
842 | if (usb_endpoint_is_bulk_in(endpoint)) { | ||
843 | /* we found a bulk in endpoint */ | ||
844 | bulkEndpoint = endpoint->bEndpointAddress; | ||
845 | } else { | ||
846 | printk(KERN_ERR | ||
847 | "No bulk in endpoint was found ?! (this is bad)\n"); | ||
848 | } | ||
849 | |||
850 | if ((cam = | ||
851 | kzalloc(sizeof (struct vicam_camera), GFP_KERNEL)) == NULL) { | ||
852 | printk(KERN_WARNING | ||
853 | "could not allocate kernel memory for vicam_camera struct\n"); | ||
854 | return -ENOMEM; | ||
855 | } | ||
856 | |||
857 | |||
858 | cam->shutter_speed = 15; | ||
859 | |||
860 | mutex_init(&cam->cam_lock); | ||
861 | |||
862 | memcpy(&cam->vdev, &vicam_template, sizeof(vicam_template)); | ||
863 | video_set_drvdata(&cam->vdev, cam); | ||
864 | |||
865 | cam->udev = dev; | ||
866 | cam->bulkEndpoint = bulkEndpoint; | ||
867 | |||
868 | if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1) < 0) { | ||
869 | kfree(cam); | ||
870 | printk(KERN_WARNING "video_register_device failed\n"); | ||
871 | return -EIO; | ||
872 | } | ||
873 | |||
874 | printk(KERN_INFO "ViCam webcam driver now controlling device %s\n", | ||
875 | video_device_node_name(&cam->vdev)); | ||
876 | |||
877 | usb_set_intfdata (intf, cam); | ||
878 | |||
879 | return 0; | ||
880 | } | ||
881 | |||
882 | static void | ||
883 | vicam_disconnect(struct usb_interface *intf) | ||
884 | { | ||
885 | int open_count; | ||
886 | struct vicam_camera *cam = usb_get_intfdata (intf); | ||
887 | usb_set_intfdata (intf, NULL); | ||
888 | |||
889 | /* we must unregister the device before taking its | ||
890 | * cam_lock. This is because the video open call | ||
891 | * holds the same lock as video unregister. if we | ||
892 | * unregister inside of the cam_lock and open also | ||
893 | * uses the cam_lock, we get deadlock. | ||
894 | */ | ||
895 | |||
896 | video_unregister_device(&cam->vdev); | ||
897 | |||
898 | /* stop the camera from being used */ | ||
899 | |||
900 | mutex_lock(&cam->cam_lock); | ||
901 | |||
902 | /* mark the camera as gone */ | ||
903 | |||
904 | cam->udev = NULL; | ||
905 | |||
906 | /* the only thing left to do is synchronize with | ||
907 | * our close/release function on who should release | ||
908 | * the camera memory. if there are any users using the | ||
909 | * camera, it's their job. if there are no users, | ||
910 | * it's ours. | ||
911 | */ | ||
912 | |||
913 | open_count = cam->open_count; | ||
914 | |||
915 | mutex_unlock(&cam->cam_lock); | ||
916 | |||
917 | if (!open_count) { | ||
918 | kfree(cam); | ||
919 | } | ||
920 | |||
921 | printk(KERN_DEBUG "ViCam-based WebCam disconnected\n"); | ||
922 | } | ||
923 | |||
924 | /* | ||
925 | */ | ||
926 | static int __init | ||
927 | usb_vicam_init(void) | ||
928 | { | ||
929 | int retval; | ||
930 | DBG(KERN_INFO "ViCam-based WebCam driver startup\n"); | ||
931 | retval = usb_register(&vicam_driver); | ||
932 | if (retval) | ||
933 | printk(KERN_WARNING "usb_register failed!\n"); | ||
934 | return retval; | ||
935 | } | ||
936 | |||
937 | static void __exit | ||
938 | usb_vicam_exit(void) | ||
939 | { | ||
940 | DBG(KERN_INFO | ||
941 | "ViCam-based WebCam driver shutdown\n"); | ||
942 | |||
943 | usb_deregister(&vicam_driver); | ||
944 | } | ||
945 | |||
946 | module_init(usb_vicam_init); | ||
947 | module_exit(usb_vicam_exit); | ||
948 | |||
949 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
950 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
951 | MODULE_LICENSE("GPL"); | ||
952 | MODULE_FIRMWARE("vicam/firmware.fw"); | ||
diff --git a/drivers/media/video/usbvision/usbvision-cards.c b/drivers/media/video/usbvision/usbvision-cards.c index 503b13beb922..68b998bd203f 100644 --- a/drivers/media/video/usbvision/usbvision-cards.c +++ b/drivers/media/video/usbvision/usbvision-cards.c | |||
@@ -32,1072 +32,1072 @@ | |||
32 | /* Supported Devices: A table for usbvision.c*/ | 32 | /* Supported Devices: A table for usbvision.c*/ |
33 | struct usbvision_device_data_st usbvision_device_data[] = { | 33 | struct usbvision_device_data_st usbvision_device_data[] = { |
34 | [XANBOO] = { | 34 | [XANBOO] = { |
35 | .Interface = -1, | 35 | .interface = -1, |
36 | .Codec = CODEC_SAA7113, | 36 | .codec = CODEC_SAA7113, |
37 | .VideoChannels = 4, | 37 | .video_channels = 4, |
38 | .VideoNorm = V4L2_STD_NTSC, | 38 | .video_norm = V4L2_STD_NTSC, |
39 | .AudioChannels = 1, | 39 | .audio_channels = 1, |
40 | .Radio = 0, | 40 | .radio = 0, |
41 | .vbi = 1, | 41 | .vbi = 1, |
42 | .Tuner = 0, | 42 | .tuner = 0, |
43 | .TunerType = 0, | 43 | .tuner_type = 0, |
44 | .X_Offset = -1, | 44 | .x_offset = -1, |
45 | .Y_Offset = -1, | 45 | .y_offset = -1, |
46 | .ModelString = "Xanboo", | 46 | .model_string = "Xanboo", |
47 | }, | 47 | }, |
48 | [BELKIN_VIDEOBUS_II] = { | 48 | [BELKIN_VIDEOBUS_II] = { |
49 | .Interface = -1, | 49 | .interface = -1, |
50 | .Codec = CODEC_SAA7113, | 50 | .codec = CODEC_SAA7113, |
51 | .VideoChannels = 2, | 51 | .video_channels = 2, |
52 | .VideoNorm = V4L2_STD_PAL, | 52 | .video_norm = V4L2_STD_PAL, |
53 | .AudioChannels = 1, | 53 | .audio_channels = 1, |
54 | .Radio = 0, | 54 | .radio = 0, |
55 | .vbi = 1, | 55 | .vbi = 1, |
56 | .Tuner = 0, | 56 | .tuner = 0, |
57 | .TunerType = 0, | 57 | .tuner_type = 0, |
58 | .X_Offset = 0, | 58 | .x_offset = 0, |
59 | .Y_Offset = 3, | 59 | .y_offset = 3, |
60 | .Dvi_yuv_override = 1, | 60 | .dvi_yuv_override = 1, |
61 | .Dvi_yuv = 7, | 61 | .dvi_yuv = 7, |
62 | .ModelString = "Belkin USB VideoBus II Adapter", | 62 | .model_string = "Belkin USB VideoBus II Adapter", |
63 | }, | 63 | }, |
64 | [BELKIN_VIDEOBUS] = { | 64 | [BELKIN_VIDEOBUS] = { |
65 | .Interface = -1, | 65 | .interface = -1, |
66 | .Codec = CODEC_SAA7111, | 66 | .codec = CODEC_SAA7111, |
67 | .VideoChannels = 2, | 67 | .video_channels = 2, |
68 | .VideoNorm = V4L2_STD_NTSC, | 68 | .video_norm = V4L2_STD_NTSC, |
69 | .AudioChannels = 1, | 69 | .audio_channels = 1, |
70 | .Radio = 0, | 70 | .radio = 0, |
71 | .vbi = 1, | 71 | .vbi = 1, |
72 | .Tuner = 0, | 72 | .tuner = 0, |
73 | .TunerType = 0, | 73 | .tuner_type = 0, |
74 | .X_Offset = -1, | 74 | .x_offset = -1, |
75 | .Y_Offset = -1, | 75 | .y_offset = -1, |
76 | .ModelString = "Belkin Components USB VideoBus", | 76 | .model_string = "Belkin Components USB VideoBus", |
77 | }, | 77 | }, |
78 | [BELKIN_USB_VIDEOBUS_II] = { | 78 | [BELKIN_USB_VIDEOBUS_II] = { |
79 | .Interface = -1, | 79 | .interface = -1, |
80 | .Codec = CODEC_SAA7113, | 80 | .codec = CODEC_SAA7113, |
81 | .VideoChannels = 2, | 81 | .video_channels = 2, |
82 | .VideoNorm = V4L2_STD_NTSC, | 82 | .video_norm = V4L2_STD_NTSC, |
83 | .AudioChannels = 1, | 83 | .audio_channels = 1, |
84 | .Radio = 0, | 84 | .radio = 0, |
85 | .vbi = 1, | 85 | .vbi = 1, |
86 | .Tuner = 0, | 86 | .tuner = 0, |
87 | .TunerType = 0, | 87 | .tuner_type = 0, |
88 | .X_Offset = 0, | 88 | .x_offset = 0, |
89 | .Y_Offset = 3, | 89 | .y_offset = 3, |
90 | .Dvi_yuv_override = 1, | 90 | .dvi_yuv_override = 1, |
91 | .Dvi_yuv = 7, | 91 | .dvi_yuv = 7, |
92 | .ModelString = "Belkin USB VideoBus II", | 92 | .model_string = "Belkin USB VideoBus II", |
93 | }, | 93 | }, |
94 | [ECHOFX_INTERVIEW_LITE] = { | 94 | [ECHOFX_INTERVIEW_LITE] = { |
95 | .Interface = 0, | 95 | .interface = 0, |
96 | .Codec = CODEC_SAA7111, | 96 | .codec = CODEC_SAA7111, |
97 | .VideoChannels = 2, | 97 | .video_channels = 2, |
98 | .VideoNorm = V4L2_STD_PAL, | 98 | .video_norm = V4L2_STD_PAL, |
99 | .AudioChannels = 0, | 99 | .audio_channels = 0, |
100 | .Radio = 0, | 100 | .radio = 0, |
101 | .vbi = 1, | 101 | .vbi = 1, |
102 | .Tuner = 0, | 102 | .tuner = 0, |
103 | .TunerType = 0, | 103 | .tuner_type = 0, |
104 | .X_Offset = -1, | 104 | .x_offset = -1, |
105 | .Y_Offset = -1, | 105 | .y_offset = -1, |
106 | .Dvi_yuv_override = 1, | 106 | .dvi_yuv_override = 1, |
107 | .Dvi_yuv = 7, | 107 | .dvi_yuv = 7, |
108 | .ModelString = "echoFX InterView Lite", | 108 | .model_string = "echoFX InterView Lite", |
109 | }, | 109 | }, |
110 | [USBGEAR_USBG_V1] = { | 110 | [USBGEAR_USBG_V1] = { |
111 | .Interface = -1, | 111 | .interface = -1, |
112 | .Codec = CODEC_SAA7111, | 112 | .codec = CODEC_SAA7111, |
113 | .VideoChannels = 2, | 113 | .video_channels = 2, |
114 | .VideoNorm = V4L2_STD_NTSC, | 114 | .video_norm = V4L2_STD_NTSC, |
115 | .AudioChannels = 1, | 115 | .audio_channels = 1, |
116 | .Radio = 0, | 116 | .radio = 0, |
117 | .vbi = 1, | 117 | .vbi = 1, |
118 | .Tuner = 0, | 118 | .tuner = 0, |
119 | .TunerType = 0, | 119 | .tuner_type = 0, |
120 | .X_Offset = -1, | 120 | .x_offset = -1, |
121 | .Y_Offset = -1, | 121 | .y_offset = -1, |
122 | .ModelString = "USBGear USBG-V1 resp. HAMA USB", | 122 | .model_string = "USBGear USBG-V1 resp. HAMA USB", |
123 | }, | 123 | }, |
124 | [D_LINK_V100] = { | 124 | [D_LINK_V100] = { |
125 | .Interface = -1, | 125 | .interface = -1, |
126 | .Codec = CODEC_SAA7113, | 126 | .codec = CODEC_SAA7113, |
127 | .VideoChannels = 4, | 127 | .video_channels = 4, |
128 | .VideoNorm = V4L2_STD_NTSC, | 128 | .video_norm = V4L2_STD_NTSC, |
129 | .AudioChannels = 0, | 129 | .audio_channels = 0, |
130 | .Radio = 0, | 130 | .radio = 0, |
131 | .vbi = 1, | 131 | .vbi = 1, |
132 | .Tuner = 0, | 132 | .tuner = 0, |
133 | .TunerType = 0, | 133 | .tuner_type = 0, |
134 | .X_Offset = 0, | 134 | .x_offset = 0, |
135 | .Y_Offset = 3, | 135 | .y_offset = 3, |
136 | .Dvi_yuv_override = 1, | 136 | .dvi_yuv_override = 1, |
137 | .Dvi_yuv = 7, | 137 | .dvi_yuv = 7, |
138 | .ModelString = "D-Link V100", | 138 | .model_string = "D-Link V100", |
139 | }, | 139 | }, |
140 | [X10_USB_CAMERA] = { | 140 | [X10_USB_CAMERA] = { |
141 | .Interface = -1, | 141 | .interface = -1, |
142 | .Codec = CODEC_SAA7111, | 142 | .codec = CODEC_SAA7111, |
143 | .VideoChannels = 2, | 143 | .video_channels = 2, |
144 | .VideoNorm = V4L2_STD_NTSC, | 144 | .video_norm = V4L2_STD_NTSC, |
145 | .AudioChannels = 1, | 145 | .audio_channels = 1, |
146 | .Radio = 0, | 146 | .radio = 0, |
147 | .vbi = 1, | 147 | .vbi = 1, |
148 | .Tuner = 0, | 148 | .tuner = 0, |
149 | .TunerType = 0, | 149 | .tuner_type = 0, |
150 | .X_Offset = -1, | 150 | .x_offset = -1, |
151 | .Y_Offset = -1, | 151 | .y_offset = -1, |
152 | .ModelString = "X10 USB Camera", | 152 | .model_string = "X10 USB Camera", |
153 | }, | 153 | }, |
154 | [HPG_WINTV_LIVE_PAL_BG] = { | 154 | [HPG_WINTV_LIVE_PAL_BG] = { |
155 | .Interface = -1, | 155 | .interface = -1, |
156 | .Codec = CODEC_SAA7111, | 156 | .codec = CODEC_SAA7111, |
157 | .VideoChannels = 2, | 157 | .video_channels = 2, |
158 | .VideoNorm = V4L2_STD_PAL, | 158 | .video_norm = V4L2_STD_PAL, |
159 | .AudioChannels = 1, | 159 | .audio_channels = 1, |
160 | .Radio = 0, | 160 | .radio = 0, |
161 | .vbi = 1, | 161 | .vbi = 1, |
162 | .Tuner = 0, | 162 | .tuner = 0, |
163 | .TunerType = 0, | 163 | .tuner_type = 0, |
164 | .X_Offset = -1, | 164 | .x_offset = -1, |
165 | .Y_Offset = 3, | 165 | .y_offset = 3, |
166 | .Dvi_yuv_override = 1, | 166 | .dvi_yuv_override = 1, |
167 | .Dvi_yuv = 7, | 167 | .dvi_yuv = 7, |
168 | .ModelString = "Hauppauge WinTV USB Live (PAL B/G)", | 168 | .model_string = "Hauppauge WinTV USB Live (PAL B/G)", |
169 | }, | 169 | }, |
170 | [HPG_WINTV_LIVE_PRO_NTSC_MN] = { | 170 | [HPG_WINTV_LIVE_PRO_NTSC_MN] = { |
171 | .Interface = -1, | 171 | .interface = -1, |
172 | .Codec = CODEC_SAA7113, | 172 | .codec = CODEC_SAA7113, |
173 | .VideoChannels = 2, | 173 | .video_channels = 2, |
174 | .VideoNorm = V4L2_STD_NTSC, | 174 | .video_norm = V4L2_STD_NTSC, |
175 | .AudioChannels = 0, | 175 | .audio_channels = 0, |
176 | .Radio = 0, | 176 | .radio = 0, |
177 | .vbi = 1, | 177 | .vbi = 1, |
178 | .Tuner = 0, | 178 | .tuner = 0, |
179 | .TunerType = 0, | 179 | .tuner_type = 0, |
180 | .X_Offset = 0, | 180 | .x_offset = 0, |
181 | .Y_Offset = 3, | 181 | .y_offset = 3, |
182 | .Dvi_yuv_override = 1, | 182 | .dvi_yuv_override = 1, |
183 | .Dvi_yuv = 7, | 183 | .dvi_yuv = 7, |
184 | .ModelString = "Hauppauge WinTV USB Live Pro (NTSC M/N)", | 184 | .model_string = "Hauppauge WinTV USB Live Pro (NTSC M/N)", |
185 | }, | 185 | }, |
186 | [ZORAN_PMD_NOGATECH] = { | 186 | [ZORAN_PMD_NOGATECH] = { |
187 | .Interface = -1, | 187 | .interface = -1, |
188 | .Codec = CODEC_SAA7113, | 188 | .codec = CODEC_SAA7113, |
189 | .VideoChannels = 2, | 189 | .video_channels = 2, |
190 | .VideoNorm = V4L2_STD_PAL, | 190 | .video_norm = V4L2_STD_PAL, |
191 | .AudioChannels = 2, | 191 | .audio_channels = 2, |
192 | .Radio = 0, | 192 | .radio = 0, |
193 | .vbi = 1, | 193 | .vbi = 1, |
194 | .Tuner = 0, | 194 | .tuner = 0, |
195 | .TunerType = 0, | 195 | .tuner_type = 0, |
196 | .X_Offset = 0, | 196 | .x_offset = 0, |
197 | .Y_Offset = 3, | 197 | .y_offset = 3, |
198 | .Dvi_yuv_override = 1, | 198 | .dvi_yuv_override = 1, |
199 | .Dvi_yuv = 7, | 199 | .dvi_yuv = 7, |
200 | .ModelString = "Zoran Co. PMD (Nogatech) AV-grabber Manhattan", | 200 | .model_string = "Zoran Co. PMD (Nogatech) AV-grabber Manhattan", |
201 | }, | 201 | }, |
202 | [NOGATECH_USB_TV_NTSC_FM] = { | 202 | [NOGATECH_USB_TV_NTSC_FM] = { |
203 | .Interface = -1, | 203 | .interface = -1, |
204 | .Codec = CODEC_SAA7111, | 204 | .codec = CODEC_SAA7111, |
205 | .VideoChannels = 3, | 205 | .video_channels = 3, |
206 | .VideoNorm = V4L2_STD_NTSC, | 206 | .video_norm = V4L2_STD_NTSC, |
207 | .AudioChannels = 1, | 207 | .audio_channels = 1, |
208 | .Radio = 1, | 208 | .radio = 1, |
209 | .vbi = 1, | 209 | .vbi = 1, |
210 | .Tuner = 1, | 210 | .tuner = 1, |
211 | .TunerType = TUNER_PHILIPS_NTSC_M, | 211 | .tuner_type = TUNER_PHILIPS_NTSC_M, |
212 | .X_Offset = -1, | 212 | .x_offset = -1, |
213 | .Y_Offset = 20, | 213 | .y_offset = 20, |
214 | .ModelString = "Nogatech USB-TV (NTSC) FM", | 214 | .model_string = "Nogatech USB-TV (NTSC) FM", |
215 | }, | 215 | }, |
216 | [PNY_USB_TV_NTSC_FM] = { | 216 | [PNY_USB_TV_NTSC_FM] = { |
217 | .Interface = -1, | 217 | .interface = -1, |
218 | .Codec = CODEC_SAA7111, | 218 | .codec = CODEC_SAA7111, |
219 | .VideoChannels = 3, | 219 | .video_channels = 3, |
220 | .VideoNorm = V4L2_STD_NTSC, | 220 | .video_norm = V4L2_STD_NTSC, |
221 | .AudioChannels = 1, | 221 | .audio_channels = 1, |
222 | .Radio = 1, | 222 | .radio = 1, |
223 | .vbi = 1, | 223 | .vbi = 1, |
224 | .Tuner = 1, | 224 | .tuner = 1, |
225 | .TunerType = TUNER_PHILIPS_NTSC_M, | 225 | .tuner_type = TUNER_PHILIPS_NTSC_M, |
226 | .X_Offset = -1, | 226 | .x_offset = -1, |
227 | .Y_Offset = 20, | 227 | .y_offset = 20, |
228 | .ModelString = "PNY USB-TV (NTSC) FM", | 228 | .model_string = "PNY USB-TV (NTSC) FM", |
229 | }, | 229 | }, |
230 | [PV_PLAYTV_USB_PRO_PAL_FM] = { | 230 | [PV_PLAYTV_USB_PRO_PAL_FM] = { |
231 | .Interface = 0, | 231 | .interface = 0, |
232 | .Codec = CODEC_SAA7113, | 232 | .codec = CODEC_SAA7113, |
233 | .VideoChannels = 3, | 233 | .video_channels = 3, |
234 | .VideoNorm = V4L2_STD_PAL, | 234 | .video_norm = V4L2_STD_PAL, |
235 | .AudioChannels = 1, | 235 | .audio_channels = 1, |
236 | .Radio = 1, | 236 | .radio = 1, |
237 | .vbi = 1, | 237 | .vbi = 1, |
238 | .Tuner = 1, | 238 | .tuner = 1, |
239 | .TunerType = TUNER_PHILIPS_PAL, | 239 | .tuner_type = TUNER_PHILIPS_PAL, |
240 | .X_Offset = 0, | 240 | .x_offset = 0, |
241 | .Y_Offset = 3, | 241 | .y_offset = 3, |
242 | .Dvi_yuv_override = 1, | 242 | .dvi_yuv_override = 1, |
243 | .Dvi_yuv = 7, | 243 | .dvi_yuv = 7, |
244 | .ModelString = "PixelView PlayTv-USB PRO (PAL) FM", | 244 | .model_string = "PixelView PlayTv-USB PRO (PAL) FM", |
245 | }, | 245 | }, |
246 | [ZT_721] = { | 246 | [ZT_721] = { |
247 | .Interface = 0, | 247 | .interface = 0, |
248 | .Codec = CODEC_SAA7113, | 248 | .codec = CODEC_SAA7113, |
249 | .VideoChannels = 3, | 249 | .video_channels = 3, |
250 | .VideoNorm = V4L2_STD_PAL, | 250 | .video_norm = V4L2_STD_PAL, |
251 | .AudioChannels = 1, | 251 | .audio_channels = 1, |
252 | .Radio = 1, | 252 | .radio = 1, |
253 | .vbi = 1, | 253 | .vbi = 1, |
254 | .Tuner = 1, | 254 | .tuner = 1, |
255 | .TunerType = TUNER_PHILIPS_PAL, | 255 | .tuner_type = TUNER_PHILIPS_PAL, |
256 | .X_Offset = 0, | 256 | .x_offset = 0, |
257 | .Y_Offset = 3, | 257 | .y_offset = 3, |
258 | .Dvi_yuv_override = 1, | 258 | .dvi_yuv_override = 1, |
259 | .Dvi_yuv = 7, | 259 | .dvi_yuv = 7, |
260 | .ModelString = "ZTV ZT-721 2.4GHz USB A/V Receiver", | 260 | .model_string = "ZTV ZT-721 2.4GHz USB A/V Receiver", |
261 | }, | 261 | }, |
262 | [HPG_WINTV_NTSC_MN] = { | 262 | [HPG_WINTV_NTSC_MN] = { |
263 | .Interface = -1, | 263 | .interface = -1, |
264 | .Codec = CODEC_SAA7111, | 264 | .codec = CODEC_SAA7111, |
265 | .VideoChannels = 3, | 265 | .video_channels = 3, |
266 | .VideoNorm = V4L2_STD_NTSC, | 266 | .video_norm = V4L2_STD_NTSC, |
267 | .AudioChannels = 1, | 267 | .audio_channels = 1, |
268 | .Radio = 0, | 268 | .radio = 0, |
269 | .vbi = 1, | 269 | .vbi = 1, |
270 | .Tuner = 1, | 270 | .tuner = 1, |
271 | .TunerType = TUNER_PHILIPS_NTSC_M, | 271 | .tuner_type = TUNER_PHILIPS_NTSC_M, |
272 | .X_Offset = -1, | 272 | .x_offset = -1, |
273 | .Y_Offset = 20, | 273 | .y_offset = 20, |
274 | .ModelString = "Hauppauge WinTV USB (NTSC M/N)", | 274 | .model_string = "Hauppauge WinTV USB (NTSC M/N)", |
275 | }, | 275 | }, |
276 | [HPG_WINTV_PAL_BG] = { | 276 | [HPG_WINTV_PAL_BG] = { |
277 | .Interface = -1, | 277 | .interface = -1, |
278 | .Codec = CODEC_SAA7111, | 278 | .codec = CODEC_SAA7111, |
279 | .VideoChannels = 3, | 279 | .video_channels = 3, |
280 | .VideoNorm = V4L2_STD_PAL, | 280 | .video_norm = V4L2_STD_PAL, |
281 | .AudioChannels = 1, | 281 | .audio_channels = 1, |
282 | .Radio = 0, | 282 | .radio = 0, |
283 | .vbi = 1, | 283 | .vbi = 1, |
284 | .Tuner = 1, | 284 | .tuner = 1, |
285 | .TunerType = TUNER_PHILIPS_PAL, | 285 | .tuner_type = TUNER_PHILIPS_PAL, |
286 | .X_Offset = -1, | 286 | .x_offset = -1, |
287 | .Y_Offset = -1, | 287 | .y_offset = -1, |
288 | .ModelString = "Hauppauge WinTV USB (PAL B/G)", | 288 | .model_string = "Hauppauge WinTV USB (PAL B/G)", |
289 | }, | 289 | }, |
290 | [HPG_WINTV_PAL_I] = { | 290 | [HPG_WINTV_PAL_I] = { |
291 | .Interface = -1, | 291 | .interface = -1, |
292 | .Codec = CODEC_SAA7111, | 292 | .codec = CODEC_SAA7111, |
293 | .VideoChannels = 3, | 293 | .video_channels = 3, |
294 | .VideoNorm = V4L2_STD_PAL, | 294 | .video_norm = V4L2_STD_PAL, |
295 | .AudioChannels = 1, | 295 | .audio_channels = 1, |
296 | .Radio = 0, | 296 | .radio = 0, |
297 | .vbi = 1, | 297 | .vbi = 1, |
298 | .Tuner = 1, | 298 | .tuner = 1, |
299 | .TunerType = TUNER_PHILIPS_PAL, | 299 | .tuner_type = TUNER_PHILIPS_PAL, |
300 | .X_Offset = -1, | 300 | .x_offset = -1, |
301 | .Y_Offset = -1, | 301 | .y_offset = -1, |
302 | .ModelString = "Hauppauge WinTV USB (PAL I)", | 302 | .model_string = "Hauppauge WinTV USB (PAL I)", |
303 | }, | 303 | }, |
304 | [HPG_WINTV_PAL_SECAM_L] = { | 304 | [HPG_WINTV_PAL_SECAM_L] = { |
305 | .Interface = -1, | 305 | .interface = -1, |
306 | .Codec = CODEC_SAA7111, | 306 | .codec = CODEC_SAA7111, |
307 | .VideoChannels = 3, | 307 | .video_channels = 3, |
308 | .VideoNorm = V4L2_STD_SECAM, | 308 | .video_norm = V4L2_STD_SECAM, |
309 | .AudioChannels = 1, | 309 | .audio_channels = 1, |
310 | .Radio = 0, | 310 | .radio = 0, |
311 | .vbi = 1, | 311 | .vbi = 1, |
312 | .Tuner = 1, | 312 | .tuner = 1, |
313 | .TunerType = TUNER_PHILIPS_SECAM, | 313 | .tuner_type = TUNER_PHILIPS_SECAM, |
314 | .X_Offset = 0x80, | 314 | .x_offset = 0x80, |
315 | .Y_Offset = 0x16, | 315 | .y_offset = 0x16, |
316 | .ModelString = "Hauppauge WinTV USB (PAL/SECAM L)", | 316 | .model_string = "Hauppauge WinTV USB (PAL/SECAM L)", |
317 | }, | 317 | }, |
318 | [HPG_WINTV_PAL_D_K] = { | 318 | [HPG_WINTV_PAL_D_K] = { |
319 | .Interface = -1, | 319 | .interface = -1, |
320 | .Codec = CODEC_SAA7111, | 320 | .codec = CODEC_SAA7111, |
321 | .VideoChannels = 3, | 321 | .video_channels = 3, |
322 | .VideoNorm = V4L2_STD_PAL, | 322 | .video_norm = V4L2_STD_PAL, |
323 | .AudioChannels = 1, | 323 | .audio_channels = 1, |
324 | .Radio = 0, | 324 | .radio = 0, |
325 | .vbi = 1, | 325 | .vbi = 1, |
326 | .Tuner = 1, | 326 | .tuner = 1, |
327 | .TunerType = TUNER_PHILIPS_PAL, | 327 | .tuner_type = TUNER_PHILIPS_PAL, |
328 | .X_Offset = -1, | 328 | .x_offset = -1, |
329 | .Y_Offset = -1, | 329 | .y_offset = -1, |
330 | .ModelString = "Hauppauge WinTV USB (PAL D/K)", | 330 | .model_string = "Hauppauge WinTV USB (PAL D/K)", |
331 | }, | 331 | }, |
332 | [HPG_WINTV_NTSC_FM] = { | 332 | [HPG_WINTV_NTSC_FM] = { |
333 | .Interface = -1, | 333 | .interface = -1, |
334 | .Codec = CODEC_SAA7111, | 334 | .codec = CODEC_SAA7111, |
335 | .VideoChannels = 3, | 335 | .video_channels = 3, |
336 | .VideoNorm = V4L2_STD_NTSC, | 336 | .video_norm = V4L2_STD_NTSC, |
337 | .AudioChannels = 1, | 337 | .audio_channels = 1, |
338 | .Radio = 1, | 338 | .radio = 1, |
339 | .vbi = 1, | 339 | .vbi = 1, |
340 | .Tuner = 1, | 340 | .tuner = 1, |
341 | .TunerType = TUNER_PHILIPS_NTSC_M, | 341 | .tuner_type = TUNER_PHILIPS_NTSC_M, |
342 | .X_Offset = -1, | 342 | .x_offset = -1, |
343 | .Y_Offset = -1, | 343 | .y_offset = -1, |
344 | .ModelString = "Hauppauge WinTV USB (NTSC FM)", | 344 | .model_string = "Hauppauge WinTV USB (NTSC FM)", |
345 | }, | 345 | }, |
346 | [HPG_WINTV_PAL_BG_FM] = { | 346 | [HPG_WINTV_PAL_BG_FM] = { |
347 | .Interface = -1, | 347 | .interface = -1, |
348 | .Codec = CODEC_SAA7111, | 348 | .codec = CODEC_SAA7111, |
349 | .VideoChannels = 3, | 349 | .video_channels = 3, |
350 | .VideoNorm = V4L2_STD_PAL, | 350 | .video_norm = V4L2_STD_PAL, |
351 | .AudioChannels = 1, | 351 | .audio_channels = 1, |
352 | .Radio = 1, | 352 | .radio = 1, |
353 | .vbi = 1, | 353 | .vbi = 1, |
354 | .Tuner = 1, | 354 | .tuner = 1, |
355 | .TunerType = TUNER_PHILIPS_PAL, | 355 | .tuner_type = TUNER_PHILIPS_PAL, |
356 | .X_Offset = -1, | 356 | .x_offset = -1, |
357 | .Y_Offset = -1, | 357 | .y_offset = -1, |
358 | .ModelString = "Hauppauge WinTV USB (PAL B/G FM)", | 358 | .model_string = "Hauppauge WinTV USB (PAL B/G FM)", |
359 | }, | 359 | }, |
360 | [HPG_WINTV_PAL_I_FM] = { | 360 | [HPG_WINTV_PAL_I_FM] = { |
361 | .Interface = -1, | 361 | .interface = -1, |
362 | .Codec = CODEC_SAA7111, | 362 | .codec = CODEC_SAA7111, |
363 | .VideoChannels = 3, | 363 | .video_channels = 3, |
364 | .VideoNorm = V4L2_STD_PAL, | 364 | .video_norm = V4L2_STD_PAL, |
365 | .AudioChannels = 1, | 365 | .audio_channels = 1, |
366 | .Radio = 1, | 366 | .radio = 1, |
367 | .vbi = 1, | 367 | .vbi = 1, |
368 | .Tuner = 1, | 368 | .tuner = 1, |
369 | .TunerType = TUNER_PHILIPS_PAL, | 369 | .tuner_type = TUNER_PHILIPS_PAL, |
370 | .X_Offset = -1, | 370 | .x_offset = -1, |
371 | .Y_Offset = -1, | 371 | .y_offset = -1, |
372 | .ModelString = "Hauppauge WinTV USB (PAL I FM)", | 372 | .model_string = "Hauppauge WinTV USB (PAL I FM)", |
373 | }, | 373 | }, |
374 | [HPG_WINTV_PAL_D_K_FM] = { | 374 | [HPG_WINTV_PAL_D_K_FM] = { |
375 | .Interface = -1, | 375 | .interface = -1, |
376 | .Codec = CODEC_SAA7111, | 376 | .codec = CODEC_SAA7111, |
377 | .VideoChannels = 3, | 377 | .video_channels = 3, |
378 | .VideoNorm = V4L2_STD_PAL, | 378 | .video_norm = V4L2_STD_PAL, |
379 | .AudioChannels = 1, | 379 | .audio_channels = 1, |
380 | .Radio = 1, | 380 | .radio = 1, |
381 | .vbi = 1, | 381 | .vbi = 1, |
382 | .Tuner = 1, | 382 | .tuner = 1, |
383 | .TunerType = TUNER_PHILIPS_PAL, | 383 | .tuner_type = TUNER_PHILIPS_PAL, |
384 | .X_Offset = -1, | 384 | .x_offset = -1, |
385 | .Y_Offset = -1, | 385 | .y_offset = -1, |
386 | .ModelString = "Hauppauge WinTV USB (PAL D/K FM)", | 386 | .model_string = "Hauppauge WinTV USB (PAL D/K FM)", |
387 | }, | 387 | }, |
388 | [HPG_WINTV_PRO_NTSC_MN] = { | 388 | [HPG_WINTV_PRO_NTSC_MN] = { |
389 | .Interface = 0, | 389 | .interface = 0, |
390 | .Codec = CODEC_SAA7113, | 390 | .codec = CODEC_SAA7113, |
391 | .VideoChannels = 3, | 391 | .video_channels = 3, |
392 | .VideoNorm = V4L2_STD_NTSC, | 392 | .video_norm = V4L2_STD_NTSC, |
393 | .AudioChannels = 1, | 393 | .audio_channels = 1, |
394 | .Radio = 1, | 394 | .radio = 1, |
395 | .vbi = 1, | 395 | .vbi = 1, |
396 | .Tuner = 1, | 396 | .tuner = 1, |
397 | .TunerType = TUNER_MICROTUNE_4049FM5, | 397 | .tuner_type = TUNER_MICROTUNE_4049FM5, |
398 | .X_Offset = 0, | 398 | .x_offset = 0, |
399 | .Y_Offset = 3, | 399 | .y_offset = 3, |
400 | .Dvi_yuv_override = 1, | 400 | .dvi_yuv_override = 1, |
401 | .Dvi_yuv = 7, | 401 | .dvi_yuv = 7, |
402 | .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N)", | 402 | .model_string = "Hauppauge WinTV USB Pro (NTSC M/N)", |
403 | }, | 403 | }, |
404 | [HPG_WINTV_PRO_NTSC_MN_V2] = { | 404 | [HPG_WINTV_PRO_NTSC_MN_V2] = { |
405 | .Interface = 0, | 405 | .interface = 0, |
406 | .Codec = CODEC_SAA7113, | 406 | .codec = CODEC_SAA7113, |
407 | .VideoChannels = 3, | 407 | .video_channels = 3, |
408 | .VideoNorm = V4L2_STD_NTSC, | 408 | .video_norm = V4L2_STD_NTSC, |
409 | .AudioChannels = 1, | 409 | .audio_channels = 1, |
410 | .Radio = 1, | 410 | .radio = 1, |
411 | .vbi = 1, | 411 | .vbi = 1, |
412 | .Tuner = 1, | 412 | .tuner = 1, |
413 | .TunerType = TUNER_MICROTUNE_4049FM5, | 413 | .tuner_type = TUNER_MICROTUNE_4049FM5, |
414 | .X_Offset = 0, | 414 | .x_offset = 0, |
415 | .Y_Offset = 3, | 415 | .y_offset = 3, |
416 | .Dvi_yuv_override = 1, | 416 | .dvi_yuv_override = 1, |
417 | .Dvi_yuv = 7, | 417 | .dvi_yuv = 7, |
418 | .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N) V2", | 418 | .model_string = "Hauppauge WinTV USB Pro (NTSC M/N) V2", |
419 | }, | 419 | }, |
420 | [HPG_WINTV_PRO_PAL] = { | 420 | [HPG_WINTV_PRO_PAL] = { |
421 | .Interface = 0, | 421 | .interface = 0, |
422 | .Codec = CODEC_SAA7113, | 422 | .codec = CODEC_SAA7113, |
423 | .VideoChannels = 3, | 423 | .video_channels = 3, |
424 | .VideoNorm = V4L2_STD_PAL, | 424 | .video_norm = V4L2_STD_PAL, |
425 | .AudioChannels = 1, | 425 | .audio_channels = 1, |
426 | .Radio = 0, | 426 | .radio = 0, |
427 | .vbi = 1, | 427 | .vbi = 1, |
428 | .Tuner = 1, | 428 | .tuner = 1, |
429 | .TunerType = TUNER_PHILIPS_FM1216ME_MK3, | 429 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
430 | .X_Offset = 0, | 430 | .x_offset = 0, |
431 | .Y_Offset = 3, | 431 | .y_offset = 3, |
432 | .Dvi_yuv_override = 1, | 432 | .dvi_yuv_override = 1, |
433 | .Dvi_yuv = 7, | 433 | .dvi_yuv = 7, |
434 | .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L)", | 434 | .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L)", |
435 | }, | 435 | }, |
436 | [HPG_WINTV_PRO_NTSC_MN_V3] = { | 436 | [HPG_WINTV_PRO_NTSC_MN_V3] = { |
437 | .Interface = 0, | 437 | .interface = 0, |
438 | .Codec = CODEC_SAA7113, | 438 | .codec = CODEC_SAA7113, |
439 | .VideoChannels = 3, | 439 | .video_channels = 3, |
440 | .VideoNorm = V4L2_STD_NTSC, | 440 | .video_norm = V4L2_STD_NTSC, |
441 | .AudioChannels = 1, | 441 | .audio_channels = 1, |
442 | .Radio = 1, | 442 | .radio = 1, |
443 | .vbi = 1, | 443 | .vbi = 1, |
444 | .Tuner = 1, | 444 | .tuner = 1, |
445 | .TunerType = TUNER_PHILIPS_NTSC_M, | 445 | .tuner_type = TUNER_PHILIPS_NTSC_M, |
446 | .X_Offset = 0, | 446 | .x_offset = 0, |
447 | .Y_Offset = 3, | 447 | .y_offset = 3, |
448 | .Dvi_yuv_override = 1, | 448 | .dvi_yuv_override = 1, |
449 | .Dvi_yuv = 7, | 449 | .dvi_yuv = 7, |
450 | .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N) V3", | 450 | .model_string = "Hauppauge WinTV USB Pro (NTSC M/N) V3", |
451 | }, | 451 | }, |
452 | [HPG_WINTV_PRO_PAL_BG] = { | 452 | [HPG_WINTV_PRO_PAL_BG] = { |
453 | .Interface = 0, | 453 | .interface = 0, |
454 | .Codec = CODEC_SAA7113, | 454 | .codec = CODEC_SAA7113, |
455 | .VideoChannels = 3, | 455 | .video_channels = 3, |
456 | .VideoNorm = V4L2_STD_PAL, | 456 | .video_norm = V4L2_STD_PAL, |
457 | .AudioChannels = 1, | 457 | .audio_channels = 1, |
458 | .Radio = 0, | 458 | .radio = 0, |
459 | .vbi = 1, | 459 | .vbi = 1, |
460 | .Tuner = 1, | 460 | .tuner = 1, |
461 | .TunerType = TUNER_PHILIPS_PAL, | 461 | .tuner_type = TUNER_PHILIPS_PAL, |
462 | .X_Offset = 0, | 462 | .x_offset = 0, |
463 | .Y_Offset = 3, | 463 | .y_offset = 3, |
464 | .Dvi_yuv_override = 1, | 464 | .dvi_yuv_override = 1, |
465 | .Dvi_yuv = 7, | 465 | .dvi_yuv = 7, |
466 | .ModelString = "Hauppauge WinTV USB Pro (PAL B/G)", | 466 | .model_string = "Hauppauge WinTV USB Pro (PAL B/G)", |
467 | }, | 467 | }, |
468 | [HPG_WINTV_PRO_PAL_I] = { | 468 | [HPG_WINTV_PRO_PAL_I] = { |
469 | .Interface = 0, | 469 | .interface = 0, |
470 | .Codec = CODEC_SAA7113, | 470 | .codec = CODEC_SAA7113, |
471 | .VideoChannels = 3, | 471 | .video_channels = 3, |
472 | .VideoNorm = V4L2_STD_PAL, | 472 | .video_norm = V4L2_STD_PAL, |
473 | .AudioChannels = 1, | 473 | .audio_channels = 1, |
474 | .Radio = 0, | 474 | .radio = 0, |
475 | .vbi = 1, | 475 | .vbi = 1, |
476 | .Tuner = 1, | 476 | .tuner = 1, |
477 | .TunerType = TUNER_PHILIPS_PAL, | 477 | .tuner_type = TUNER_PHILIPS_PAL, |
478 | .X_Offset = 0, | 478 | .x_offset = 0, |
479 | .Y_Offset = 3, | 479 | .y_offset = 3, |
480 | .Dvi_yuv_override = 1, | 480 | .dvi_yuv_override = 1, |
481 | .Dvi_yuv = 7, | 481 | .dvi_yuv = 7, |
482 | .ModelString = "Hauppauge WinTV USB Pro (PAL I)", | 482 | .model_string = "Hauppauge WinTV USB Pro (PAL I)", |
483 | }, | 483 | }, |
484 | [HPG_WINTV_PRO_PAL_SECAM_L] = { | 484 | [HPG_WINTV_PRO_PAL_SECAM_L] = { |
485 | .Interface = -1, | 485 | .interface = -1, |
486 | .Codec = CODEC_SAA7113, | 486 | .codec = CODEC_SAA7113, |
487 | .VideoChannels = 3, | 487 | .video_channels = 3, |
488 | .VideoNorm = V4L2_STD_SECAM, | 488 | .video_norm = V4L2_STD_SECAM, |
489 | .AudioChannels = 1, | 489 | .audio_channels = 1, |
490 | .Radio = 0, | 490 | .radio = 0, |
491 | .vbi = 1, | 491 | .vbi = 1, |
492 | .Tuner = 1, | 492 | .tuner = 1, |
493 | .TunerType = TUNER_PHILIPS_SECAM, | 493 | .tuner_type = TUNER_PHILIPS_SECAM, |
494 | .X_Offset = 0, | 494 | .x_offset = 0, |
495 | .Y_Offset = 3, | 495 | .y_offset = 3, |
496 | .Dvi_yuv_override = 1, | 496 | .dvi_yuv_override = 1, |
497 | .Dvi_yuv = 7, | 497 | .dvi_yuv = 7, |
498 | .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM L)", | 498 | .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM L)", |
499 | }, | 499 | }, |
500 | [HPG_WINTV_PRO_PAL_D_K] = { | 500 | [HPG_WINTV_PRO_PAL_D_K] = { |
501 | .Interface = -1, | 501 | .interface = -1, |
502 | .Codec = CODEC_SAA7113, | 502 | .codec = CODEC_SAA7113, |
503 | .VideoChannels = 3, | 503 | .video_channels = 3, |
504 | .VideoNorm = V4L2_STD_PAL, | 504 | .video_norm = V4L2_STD_PAL, |
505 | .AudioChannels = 1, | 505 | .audio_channels = 1, |
506 | .Radio = 0, | 506 | .radio = 0, |
507 | .vbi = 1, | 507 | .vbi = 1, |
508 | .Tuner = 1, | 508 | .tuner = 1, |
509 | .TunerType = TUNER_PHILIPS_PAL, | 509 | .tuner_type = TUNER_PHILIPS_PAL, |
510 | .X_Offset = 0, | 510 | .x_offset = 0, |
511 | .Y_Offset = 3, | 511 | .y_offset = 3, |
512 | .Dvi_yuv_override = 1, | 512 | .dvi_yuv_override = 1, |
513 | .Dvi_yuv = 7, | 513 | .dvi_yuv = 7, |
514 | .ModelString = "Hauppauge WinTV USB Pro (PAL D/K)", | 514 | .model_string = "Hauppauge WinTV USB Pro (PAL D/K)", |
515 | }, | 515 | }, |
516 | [HPG_WINTV_PRO_PAL_SECAM] = { | 516 | [HPG_WINTV_PRO_PAL_SECAM] = { |
517 | .Interface = -1, | 517 | .interface = -1, |
518 | .Codec = CODEC_SAA7113, | 518 | .codec = CODEC_SAA7113, |
519 | .VideoChannels = 3, | 519 | .video_channels = 3, |
520 | .VideoNorm = V4L2_STD_SECAM, | 520 | .video_norm = V4L2_STD_SECAM, |
521 | .AudioChannels = 1, | 521 | .audio_channels = 1, |
522 | .Radio = 0, | 522 | .radio = 0, |
523 | .vbi = 1, | 523 | .vbi = 1, |
524 | .Tuner = 1, | 524 | .tuner = 1, |
525 | .TunerType = TUNER_PHILIPS_SECAM, | 525 | .tuner_type = TUNER_PHILIPS_SECAM, |
526 | .X_Offset = 0, | 526 | .x_offset = 0, |
527 | .Y_Offset = 3, | 527 | .y_offset = 3, |
528 | .Dvi_yuv_override = 1, | 528 | .dvi_yuv_override = 1, |
529 | .Dvi_yuv = 7, | 529 | .dvi_yuv = 7, |
530 | .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)", | 530 | .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)", |
531 | }, | 531 | }, |
532 | [HPG_WINTV_PRO_PAL_SECAM_V2] = { | 532 | [HPG_WINTV_PRO_PAL_SECAM_V2] = { |
533 | .Interface = -1, | 533 | .interface = -1, |
534 | .Codec = CODEC_SAA7113, | 534 | .codec = CODEC_SAA7113, |
535 | .VideoChannels = 3, | 535 | .video_channels = 3, |
536 | .VideoNorm = V4L2_STD_SECAM, | 536 | .video_norm = V4L2_STD_SECAM, |
537 | .AudioChannels = 1, | 537 | .audio_channels = 1, |
538 | .Radio = 0, | 538 | .radio = 0, |
539 | .vbi = 1, | 539 | .vbi = 1, |
540 | .Tuner = 1, | 540 | .tuner = 1, |
541 | .TunerType = TUNER_PHILIPS_SECAM, | 541 | .tuner_type = TUNER_PHILIPS_SECAM, |
542 | .X_Offset = 0, | 542 | .x_offset = 0, |
543 | .Y_Offset = 3, | 543 | .y_offset = 3, |
544 | .Dvi_yuv_override = 1, | 544 | .dvi_yuv_override = 1, |
545 | .Dvi_yuv = 7, | 545 | .dvi_yuv = 7, |
546 | .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2", | 546 | .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2", |
547 | }, | 547 | }, |
548 | [HPG_WINTV_PRO_PAL_BG_V2] = { | 548 | [HPG_WINTV_PRO_PAL_BG_V2] = { |
549 | .Interface = -1, | 549 | .interface = -1, |
550 | .Codec = CODEC_SAA7113, | 550 | .codec = CODEC_SAA7113, |
551 | .VideoChannels = 3, | 551 | .video_channels = 3, |
552 | .VideoNorm = V4L2_STD_PAL, | 552 | .video_norm = V4L2_STD_PAL, |
553 | .AudioChannels = 1, | 553 | .audio_channels = 1, |
554 | .Radio = 0, | 554 | .radio = 0, |
555 | .vbi = 1, | 555 | .vbi = 1, |
556 | .Tuner = 1, | 556 | .tuner = 1, |
557 | .TunerType = TUNER_ALPS_TSBE1_PAL, | 557 | .tuner_type = TUNER_ALPS_TSBE1_PAL, |
558 | .X_Offset = 0, | 558 | .x_offset = 0, |
559 | .Y_Offset = 3, | 559 | .y_offset = 3, |
560 | .Dvi_yuv_override = 1, | 560 | .dvi_yuv_override = 1, |
561 | .Dvi_yuv = 7, | 561 | .dvi_yuv = 7, |
562 | .ModelString = "Hauppauge WinTV USB Pro (PAL B/G) V2", | 562 | .model_string = "Hauppauge WinTV USB Pro (PAL B/G) V2", |
563 | }, | 563 | }, |
564 | [HPG_WINTV_PRO_PAL_BG_D_K] = { | 564 | [HPG_WINTV_PRO_PAL_BG_D_K] = { |
565 | .Interface = -1, | 565 | .interface = -1, |
566 | .Codec = CODEC_SAA7113, | 566 | .codec = CODEC_SAA7113, |
567 | .VideoChannels = 3, | 567 | .video_channels = 3, |
568 | .VideoNorm = V4L2_STD_PAL, | 568 | .video_norm = V4L2_STD_PAL, |
569 | .AudioChannels = 1, | 569 | .audio_channels = 1, |
570 | .Radio = 0, | 570 | .radio = 0, |
571 | .vbi = 1, | 571 | .vbi = 1, |
572 | .Tuner = 1, | 572 | .tuner = 1, |
573 | .TunerType = TUNER_ALPS_TSBE1_PAL, | 573 | .tuner_type = TUNER_ALPS_TSBE1_PAL, |
574 | .X_Offset = 0, | 574 | .x_offset = 0, |
575 | .Y_Offset = 3, | 575 | .y_offset = 3, |
576 | .Dvi_yuv_override = 1, | 576 | .dvi_yuv_override = 1, |
577 | .Dvi_yuv = 7, | 577 | .dvi_yuv = 7, |
578 | .ModelString = "Hauppauge WinTV USB Pro (PAL B/G,D/K)", | 578 | .model_string = "Hauppauge WinTV USB Pro (PAL B/G,D/K)", |
579 | }, | 579 | }, |
580 | [HPG_WINTV_PRO_PAL_I_D_K] = { | 580 | [HPG_WINTV_PRO_PAL_I_D_K] = { |
581 | .Interface = -1, | 581 | .interface = -1, |
582 | .Codec = CODEC_SAA7113, | 582 | .codec = CODEC_SAA7113, |
583 | .VideoChannels = 3, | 583 | .video_channels = 3, |
584 | .VideoNorm = V4L2_STD_PAL, | 584 | .video_norm = V4L2_STD_PAL, |
585 | .AudioChannels = 1, | 585 | .audio_channels = 1, |
586 | .Radio = 0, | 586 | .radio = 0, |
587 | .vbi = 1, | 587 | .vbi = 1, |
588 | .Tuner = 1, | 588 | .tuner = 1, |
589 | .TunerType = TUNER_LG_PAL_NEW_TAPC, | 589 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, |
590 | .X_Offset = 0, | 590 | .x_offset = 0, |
591 | .Y_Offset = 3, | 591 | .y_offset = 3, |
592 | .Dvi_yuv_override = 1, | 592 | .dvi_yuv_override = 1, |
593 | .Dvi_yuv = 7, | 593 | .dvi_yuv = 7, |
594 | .ModelString = "Hauppauge WinTV USB Pro (PAL I,D/K)", | 594 | .model_string = "Hauppauge WinTV USB Pro (PAL I,D/K)", |
595 | }, | 595 | }, |
596 | [HPG_WINTV_PRO_NTSC_MN_FM] = { | 596 | [HPG_WINTV_PRO_NTSC_MN_FM] = { |
597 | .Interface = -1, | 597 | .interface = -1, |
598 | .Codec = CODEC_SAA7113, | 598 | .codec = CODEC_SAA7113, |
599 | .VideoChannels = 3, | 599 | .video_channels = 3, |
600 | .VideoNorm = V4L2_STD_NTSC, | 600 | .video_norm = V4L2_STD_NTSC, |
601 | .AudioChannels = 1, | 601 | .audio_channels = 1, |
602 | .Radio = 1, | 602 | .radio = 1, |
603 | .vbi = 1, | 603 | .vbi = 1, |
604 | .Tuner = 1, | 604 | .tuner = 1, |
605 | .TunerType = TUNER_PHILIPS_NTSC_M, | 605 | .tuner_type = TUNER_PHILIPS_NTSC_M, |
606 | .X_Offset = 0, | 606 | .x_offset = 0, |
607 | .Y_Offset = 3, | 607 | .y_offset = 3, |
608 | .Dvi_yuv_override = 1, | 608 | .dvi_yuv_override = 1, |
609 | .Dvi_yuv = 7, | 609 | .dvi_yuv = 7, |
610 | .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N FM)", | 610 | .model_string = "Hauppauge WinTV USB Pro (NTSC M/N FM)", |
611 | }, | 611 | }, |
612 | [HPG_WINTV_PRO_PAL_BG_FM] = { | 612 | [HPG_WINTV_PRO_PAL_BG_FM] = { |
613 | .Interface = 0, | 613 | .interface = 0, |
614 | .Codec = CODEC_SAA7113, | 614 | .codec = CODEC_SAA7113, |
615 | .VideoChannels = 3, | 615 | .video_channels = 3, |
616 | .VideoNorm = V4L2_STD_PAL, | 616 | .video_norm = V4L2_STD_PAL, |
617 | .AudioChannels = 1, | 617 | .audio_channels = 1, |
618 | .Radio = 1, | 618 | .radio = 1, |
619 | .vbi = 1, | 619 | .vbi = 1, |
620 | .Tuner = 1, | 620 | .tuner = 1, |
621 | .TunerType = TUNER_PHILIPS_PAL, | 621 | .tuner_type = TUNER_PHILIPS_PAL, |
622 | .X_Offset = 0, | 622 | .x_offset = 0, |
623 | .Y_Offset = 3, | 623 | .y_offset = 3, |
624 | .Dvi_yuv_override = 1, | 624 | .dvi_yuv_override = 1, |
625 | .Dvi_yuv = 7, | 625 | .dvi_yuv = 7, |
626 | .ModelString = "Hauppauge WinTV USB Pro (PAL B/G FM)", | 626 | .model_string = "Hauppauge WinTV USB Pro (PAL B/G FM)", |
627 | }, | 627 | }, |
628 | [HPG_WINTV_PRO_PAL_I_FM] = { | 628 | [HPG_WINTV_PRO_PAL_I_FM] = { |
629 | .Interface = 0, | 629 | .interface = 0, |
630 | .Codec = CODEC_SAA7113, | 630 | .codec = CODEC_SAA7113, |
631 | .VideoChannels = 3, | 631 | .video_channels = 3, |
632 | .VideoNorm = V4L2_STD_PAL, | 632 | .video_norm = V4L2_STD_PAL, |
633 | .AudioChannels = 1, | 633 | .audio_channels = 1, |
634 | .Radio = 1, | 634 | .radio = 1, |
635 | .vbi = 1, | 635 | .vbi = 1, |
636 | .Tuner = 1, | 636 | .tuner = 1, |
637 | .TunerType = TUNER_PHILIPS_PAL, | 637 | .tuner_type = TUNER_PHILIPS_PAL, |
638 | .X_Offset = 0, | 638 | .x_offset = 0, |
639 | .Y_Offset = 3, | 639 | .y_offset = 3, |
640 | .Dvi_yuv_override = 1, | 640 | .dvi_yuv_override = 1, |
641 | .Dvi_yuv = 7, | 641 | .dvi_yuv = 7, |
642 | .ModelString = "Hauppauge WinTV USB Pro (PAL I FM)", | 642 | .model_string = "Hauppauge WinTV USB Pro (PAL I FM)", |
643 | }, | 643 | }, |
644 | [HPG_WINTV_PRO_PAL_D_K_FM] = { | 644 | [HPG_WINTV_PRO_PAL_D_K_FM] = { |
645 | .Interface = 0, | 645 | .interface = 0, |
646 | .Codec = CODEC_SAA7113, | 646 | .codec = CODEC_SAA7113, |
647 | .VideoChannels = 3, | 647 | .video_channels = 3, |
648 | .VideoNorm = V4L2_STD_PAL, | 648 | .video_norm = V4L2_STD_PAL, |
649 | .AudioChannels = 1, | 649 | .audio_channels = 1, |
650 | .Radio = 1, | 650 | .radio = 1, |
651 | .vbi = 1, | 651 | .vbi = 1, |
652 | .Tuner = 1, | 652 | .tuner = 1, |
653 | .TunerType = TUNER_PHILIPS_PAL, | 653 | .tuner_type = TUNER_PHILIPS_PAL, |
654 | .X_Offset = 0, | 654 | .x_offset = 0, |
655 | .Y_Offset = 3, | 655 | .y_offset = 3, |
656 | .Dvi_yuv_override = 1, | 656 | .dvi_yuv_override = 1, |
657 | .Dvi_yuv = 7, | 657 | .dvi_yuv = 7, |
658 | .ModelString = "Hauppauge WinTV USB Pro (PAL D/K FM)", | 658 | .model_string = "Hauppauge WinTV USB Pro (PAL D/K FM)", |
659 | }, | 659 | }, |
660 | [HPG_WINTV_PRO_TEMIC_PAL_FM] = { | 660 | [HPG_WINTV_PRO_TEMIC_PAL_FM] = { |
661 | .Interface = 0, | 661 | .interface = 0, |
662 | .Codec = CODEC_SAA7113, | 662 | .codec = CODEC_SAA7113, |
663 | .VideoChannels = 3, | 663 | .video_channels = 3, |
664 | .VideoNorm = V4L2_STD_PAL, | 664 | .video_norm = V4L2_STD_PAL, |
665 | .AudioChannels = 1, | 665 | .audio_channels = 1, |
666 | .Radio = 1, | 666 | .radio = 1, |
667 | .vbi = 1, | 667 | .vbi = 1, |
668 | .Tuner = 1, | 668 | .tuner = 1, |
669 | .TunerType = TUNER_MICROTUNE_4049FM5, | 669 | .tuner_type = TUNER_MICROTUNE_4049FM5, |
670 | .X_Offset = 0, | 670 | .x_offset = 0, |
671 | .Y_Offset = 3, | 671 | .y_offset = 3, |
672 | .Dvi_yuv_override = 1, | 672 | .dvi_yuv_override = 1, |
673 | .Dvi_yuv = 7, | 673 | .dvi_yuv = 7, |
674 | .ModelString = "Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM)", | 674 | .model_string = "Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM)", |
675 | }, | 675 | }, |
676 | [HPG_WINTV_PRO_TEMIC_PAL_BG_FM] = { | 676 | [HPG_WINTV_PRO_TEMIC_PAL_BG_FM] = { |
677 | .Interface = 0, | 677 | .interface = 0, |
678 | .Codec = CODEC_SAA7113, | 678 | .codec = CODEC_SAA7113, |
679 | .VideoChannels = 3, | 679 | .video_channels = 3, |
680 | .VideoNorm = V4L2_STD_PAL, | 680 | .video_norm = V4L2_STD_PAL, |
681 | .AudioChannels = 1, | 681 | .audio_channels = 1, |
682 | .Radio = 1, | 682 | .radio = 1, |
683 | .vbi = 1, | 683 | .vbi = 1, |
684 | .Tuner = 1, | 684 | .tuner = 1, |
685 | .TunerType = TUNER_MICROTUNE_4049FM5, | 685 | .tuner_type = TUNER_MICROTUNE_4049FM5, |
686 | .X_Offset = 0, | 686 | .x_offset = 0, |
687 | .Y_Offset = 3, | 687 | .y_offset = 3, |
688 | .Dvi_yuv_override = 1, | 688 | .dvi_yuv_override = 1, |
689 | .Dvi_yuv = 7, | 689 | .dvi_yuv = 7, |
690 | .ModelString = "Hauppauge WinTV USB Pro (Temic PAL B/G FM)", | 690 | .model_string = "Hauppauge WinTV USB Pro (Temic PAL B/G FM)", |
691 | }, | 691 | }, |
692 | [HPG_WINTV_PRO_PAL_FM] = { | 692 | [HPG_WINTV_PRO_PAL_FM] = { |
693 | .Interface = 0, | 693 | .interface = 0, |
694 | .Codec = CODEC_SAA7113, | 694 | .codec = CODEC_SAA7113, |
695 | .VideoChannels = 3, | 695 | .video_channels = 3, |
696 | .VideoNorm = V4L2_STD_PAL, | 696 | .video_norm = V4L2_STD_PAL, |
697 | .AudioChannels = 1, | 697 | .audio_channels = 1, |
698 | .Radio = 1, | 698 | .radio = 1, |
699 | .vbi = 1, | 699 | .vbi = 1, |
700 | .Tuner = 1, | 700 | .tuner = 1, |
701 | .TunerType = TUNER_PHILIPS_FM1216ME_MK3, | 701 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
702 | .X_Offset = 0, | 702 | .x_offset = 0, |
703 | .Y_Offset = 3, | 703 | .y_offset = 3, |
704 | .Dvi_yuv_override = 1, | 704 | .dvi_yuv_override = 1, |
705 | .Dvi_yuv = 7, | 705 | .dvi_yuv = 7, |
706 | .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM)", | 706 | .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM)", |
707 | }, | 707 | }, |
708 | [HPG_WINTV_PRO_NTSC_MN_FM_V2] = { | 708 | [HPG_WINTV_PRO_NTSC_MN_FM_V2] = { |
709 | .Interface = 0, | 709 | .interface = 0, |
710 | .Codec = CODEC_SAA7113, | 710 | .codec = CODEC_SAA7113, |
711 | .VideoChannels = 3, | 711 | .video_channels = 3, |
712 | .VideoNorm = V4L2_STD_NTSC, | 712 | .video_norm = V4L2_STD_NTSC, |
713 | .AudioChannels = 1, | 713 | .audio_channels = 1, |
714 | .Radio = 1, | 714 | .radio = 1, |
715 | .vbi = 1, | 715 | .vbi = 1, |
716 | .Tuner = 1, | 716 | .tuner = 1, |
717 | .TunerType = TUNER_PHILIPS_NTSC_M, | 717 | .tuner_type = TUNER_PHILIPS_NTSC_M, |
718 | .X_Offset = 0, | 718 | .x_offset = 0, |
719 | .Y_Offset = 3, | 719 | .y_offset = 3, |
720 | .Dvi_yuv_override = 1, | 720 | .dvi_yuv_override = 1, |
721 | .Dvi_yuv = 7, | 721 | .dvi_yuv = 7, |
722 | .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N FM) V2", | 722 | .model_string = "Hauppauge WinTV USB Pro (NTSC M/N FM) V2", |
723 | }, | 723 | }, |
724 | [CAMTEL_TVB330] = { | 724 | [CAMTEL_TVB330] = { |
725 | .Interface = -1, | 725 | .interface = -1, |
726 | .Codec = CODEC_SAA7113, | 726 | .codec = CODEC_SAA7113, |
727 | .VideoChannels = 3, | 727 | .video_channels = 3, |
728 | .VideoNorm = V4L2_STD_NTSC, | 728 | .video_norm = V4L2_STD_NTSC, |
729 | .AudioChannels = 1, | 729 | .audio_channels = 1, |
730 | .Radio = 1, | 730 | .radio = 1, |
731 | .vbi = 1, | 731 | .vbi = 1, |
732 | .Tuner = 1, | 732 | .tuner = 1, |
733 | .TunerType = TUNER_PHILIPS_NTSC_M, | 733 | .tuner_type = TUNER_PHILIPS_NTSC_M, |
734 | .X_Offset = 5, | 734 | .x_offset = 5, |
735 | .Y_Offset = 5, | 735 | .y_offset = 5, |
736 | .ModelString = "Camtel Technology USB TV Genie Pro FM Model TVB330", | 736 | .model_string = "Camtel Technology USB TV Genie Pro FM Model TVB330", |
737 | }, | 737 | }, |
738 | [DIGITAL_VIDEO_CREATOR_I] = { | 738 | [DIGITAL_VIDEO_CREATOR_I] = { |
739 | .Interface = -1, | 739 | .interface = -1, |
740 | .Codec = CODEC_SAA7113, | 740 | .codec = CODEC_SAA7113, |
741 | .VideoChannels = 2, | 741 | .video_channels = 2, |
742 | .VideoNorm = V4L2_STD_PAL, | 742 | .video_norm = V4L2_STD_PAL, |
743 | .AudioChannels = 0, | 743 | .audio_channels = 0, |
744 | .Radio = 0, | 744 | .radio = 0, |
745 | .vbi = 1, | 745 | .vbi = 1, |
746 | .Tuner = 0, | 746 | .tuner = 0, |
747 | .TunerType = 0, | 747 | .tuner_type = 0, |
748 | .X_Offset = 0, | 748 | .x_offset = 0, |
749 | .Y_Offset = 3, | 749 | .y_offset = 3, |
750 | .Dvi_yuv_override = 1, | 750 | .dvi_yuv_override = 1, |
751 | .Dvi_yuv = 7, | 751 | .dvi_yuv = 7, |
752 | .ModelString = "Digital Video Creator I", | 752 | .model_string = "Digital Video Creator I", |
753 | }, | 753 | }, |
754 | [GLOBAL_VILLAGE_GV_007_NTSC] = { | 754 | [GLOBAL_VILLAGE_GV_007_NTSC] = { |
755 | .Interface = -1, | 755 | .interface = -1, |
756 | .Codec = CODEC_SAA7111, | 756 | .codec = CODEC_SAA7111, |
757 | .VideoChannels = 2, | 757 | .video_channels = 2, |
758 | .VideoNorm = V4L2_STD_NTSC, | 758 | .video_norm = V4L2_STD_NTSC, |
759 | .AudioChannels = 0, | 759 | .audio_channels = 0, |
760 | .Radio = 0, | 760 | .radio = 0, |
761 | .vbi = 1, | 761 | .vbi = 1, |
762 | .Tuner = 0, | 762 | .tuner = 0, |
763 | .TunerType = 0, | 763 | .tuner_type = 0, |
764 | .X_Offset = 82, | 764 | .x_offset = 82, |
765 | .Y_Offset = 20, | 765 | .y_offset = 20, |
766 | .Dvi_yuv_override = 1, | 766 | .dvi_yuv_override = 1, |
767 | .Dvi_yuv = 7, | 767 | .dvi_yuv = 7, |
768 | .ModelString = "Global Village GV-007 (NTSC)", | 768 | .model_string = "Global Village GV-007 (NTSC)", |
769 | }, | 769 | }, |
770 | [DAZZLE_DVC_50_REV_1_NTSC] = { | 770 | [DAZZLE_DVC_50_REV_1_NTSC] = { |
771 | .Interface = 0, | 771 | .interface = 0, |
772 | .Codec = CODEC_SAA7113, | 772 | .codec = CODEC_SAA7113, |
773 | .VideoChannels = 2, | 773 | .video_channels = 2, |
774 | .VideoNorm = V4L2_STD_NTSC, | 774 | .video_norm = V4L2_STD_NTSC, |
775 | .AudioChannels = 0, | 775 | .audio_channels = 0, |
776 | .Radio = 0, | 776 | .radio = 0, |
777 | .vbi = 1, | 777 | .vbi = 1, |
778 | .Tuner = 0, | 778 | .tuner = 0, |
779 | .TunerType = 0, | 779 | .tuner_type = 0, |
780 | .X_Offset = 0, | 780 | .x_offset = 0, |
781 | .Y_Offset = 3, | 781 | .y_offset = 3, |
782 | .Dvi_yuv_override = 1, | 782 | .dvi_yuv_override = 1, |
783 | .Dvi_yuv = 7, | 783 | .dvi_yuv = 7, |
784 | .ModelString = "Dazzle Fusion Model DVC-50 Rev 1 (NTSC)", | 784 | .model_string = "Dazzle Fusion Model DVC-50 Rev 1 (NTSC)", |
785 | }, | 785 | }, |
786 | [DAZZLE_DVC_80_REV_1_PAL] = { | 786 | [DAZZLE_DVC_80_REV_1_PAL] = { |
787 | .Interface = 0, | 787 | .interface = 0, |
788 | .Codec = CODEC_SAA7113, | 788 | .codec = CODEC_SAA7113, |
789 | .VideoChannels = 2, | 789 | .video_channels = 2, |
790 | .VideoNorm = V4L2_STD_PAL, | 790 | .video_norm = V4L2_STD_PAL, |
791 | .AudioChannels = 0, | 791 | .audio_channels = 0, |
792 | .Radio = 0, | 792 | .radio = 0, |
793 | .vbi = 1, | 793 | .vbi = 1, |
794 | .Tuner = 0, | 794 | .tuner = 0, |
795 | .TunerType = 0, | 795 | .tuner_type = 0, |
796 | .X_Offset = 0, | 796 | .x_offset = 0, |
797 | .Y_Offset = 3, | 797 | .y_offset = 3, |
798 | .Dvi_yuv_override = 1, | 798 | .dvi_yuv_override = 1, |
799 | .Dvi_yuv = 7, | 799 | .dvi_yuv = 7, |
800 | .ModelString = "Dazzle Fusion Model DVC-80 Rev 1 (PAL)", | 800 | .model_string = "Dazzle Fusion Model DVC-80 Rev 1 (PAL)", |
801 | }, | 801 | }, |
802 | [DAZZLE_DVC_90_REV_1_SECAM] = { | 802 | [DAZZLE_DVC_90_REV_1_SECAM] = { |
803 | .Interface = 0, | 803 | .interface = 0, |
804 | .Codec = CODEC_SAA7113, | 804 | .codec = CODEC_SAA7113, |
805 | .VideoChannels = 2, | 805 | .video_channels = 2, |
806 | .VideoNorm = V4L2_STD_SECAM, | 806 | .video_norm = V4L2_STD_SECAM, |
807 | .AudioChannels = 0, | 807 | .audio_channels = 0, |
808 | .Radio = 0, | 808 | .radio = 0, |
809 | .vbi = 1, | 809 | .vbi = 1, |
810 | .Tuner = 0, | 810 | .tuner = 0, |
811 | .TunerType = 0, | 811 | .tuner_type = 0, |
812 | .X_Offset = 0, | 812 | .x_offset = 0, |
813 | .Y_Offset = 3, | 813 | .y_offset = 3, |
814 | .Dvi_yuv_override = 1, | 814 | .dvi_yuv_override = 1, |
815 | .Dvi_yuv = 7, | 815 | .dvi_yuv = 7, |
816 | .ModelString = "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)", | 816 | .model_string = "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)", |
817 | }, | 817 | }, |
818 | [ESKAPE_LABS_MYTV2GO] = { | 818 | [ESKAPE_LABS_MYTV2GO] = { |
819 | .Interface = 0, | 819 | .interface = 0, |
820 | .Codec = CODEC_SAA7113, | 820 | .codec = CODEC_SAA7113, |
821 | .VideoChannels = 2, | 821 | .video_channels = 2, |
822 | .VideoNorm = V4L2_STD_PAL, | 822 | .video_norm = V4L2_STD_PAL, |
823 | .AudioChannels = 1, | 823 | .audio_channels = 1, |
824 | .Radio = 1, | 824 | .radio = 1, |
825 | .vbi = 1, | 825 | .vbi = 1, |
826 | .Tuner = 1, | 826 | .tuner = 1, |
827 | .TunerType = TUNER_PHILIPS_FM1216ME_MK3, | 827 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
828 | .X_Offset = 0, | 828 | .x_offset = 0, |
829 | .Y_Offset = 3, | 829 | .y_offset = 3, |
830 | .Dvi_yuv_override = 1, | 830 | .dvi_yuv_override = 1, |
831 | .Dvi_yuv = 7, | 831 | .dvi_yuv = 7, |
832 | .ModelString = "Eskape Labs MyTV2Go", | 832 | .model_string = "Eskape Labs MyTV2Go", |
833 | }, | 833 | }, |
834 | [PINNA_PCTV_USB_PAL] = { | 834 | [PINNA_PCTV_USB_PAL] = { |
835 | .Interface = -1, | 835 | .interface = -1, |
836 | .Codec = CODEC_SAA7111, | 836 | .codec = CODEC_SAA7111, |
837 | .VideoChannels = 3, | 837 | .video_channels = 3, |
838 | .VideoNorm = V4L2_STD_PAL, | 838 | .video_norm = V4L2_STD_PAL, |
839 | .AudioChannels = 1, | 839 | .audio_channels = 1, |
840 | .Radio = 0, | 840 | .radio = 0, |
841 | .vbi = 0, | 841 | .vbi = 0, |
842 | .Tuner = 1, | 842 | .tuner = 1, |
843 | .TunerType = TUNER_TEMIC_4066FY5_PAL_I, | 843 | .tuner_type = TUNER_TEMIC_4066FY5_PAL_I, |
844 | .X_Offset = -1, | 844 | .x_offset = -1, |
845 | .Y_Offset = -1, | 845 | .y_offset = -1, |
846 | .ModelString = "Pinnacle Studio PCTV USB (PAL)", | 846 | .model_string = "Pinnacle Studio PCTV USB (PAL)", |
847 | }, | 847 | }, |
848 | [PINNA_PCTV_USB_SECAM] = { | 848 | [PINNA_PCTV_USB_SECAM] = { |
849 | .Interface = -1, | 849 | .interface = -1, |
850 | .Codec = CODEC_SAA7111, | 850 | .codec = CODEC_SAA7111, |
851 | .VideoChannels = 3, | 851 | .video_channels = 3, |
852 | .VideoNorm = V4L2_STD_SECAM, | 852 | .video_norm = V4L2_STD_SECAM, |
853 | .AudioChannels = 1, | 853 | .audio_channels = 1, |
854 | .Radio = 0, | 854 | .radio = 0, |
855 | .vbi = 1, | 855 | .vbi = 1, |
856 | .Tuner = 1, | 856 | .tuner = 1, |
857 | .TunerType = TUNER_PHILIPS_SECAM, | 857 | .tuner_type = TUNER_PHILIPS_SECAM, |
858 | .X_Offset = -1, | 858 | .x_offset = -1, |
859 | .Y_Offset = -1, | 859 | .y_offset = -1, |
860 | .ModelString = "Pinnacle Studio PCTV USB (SECAM)", | 860 | .model_string = "Pinnacle Studio PCTV USB (SECAM)", |
861 | }, | 861 | }, |
862 | [PINNA_PCTV_USB_PAL_FM] = { | 862 | [PINNA_PCTV_USB_PAL_FM] = { |
863 | .Interface = -1, | 863 | .interface = -1, |
864 | .Codec = CODEC_SAA7111, | 864 | .codec = CODEC_SAA7111, |
865 | .VideoChannels = 3, | 865 | .video_channels = 3, |
866 | .VideoNorm = V4L2_STD_PAL, | 866 | .video_norm = V4L2_STD_PAL, |
867 | .AudioChannels = 1, | 867 | .audio_channels = 1, |
868 | .Radio = 1, | 868 | .radio = 1, |
869 | .vbi = 1, | 869 | .vbi = 1, |
870 | .Tuner = 1, | 870 | .tuner = 1, |
871 | .TunerType = TUNER_PHILIPS_PAL, | 871 | .tuner_type = TUNER_PHILIPS_PAL, |
872 | .X_Offset = 128, | 872 | .x_offset = 128, |
873 | .Y_Offset = 23, | 873 | .y_offset = 23, |
874 | .ModelString = "Pinnacle Studio PCTV USB (PAL) FM", | 874 | .model_string = "Pinnacle Studio PCTV USB (PAL) FM", |
875 | }, | 875 | }, |
876 | [MIRO_PCTV_USB] = { | 876 | [MIRO_PCTV_USB] = { |
877 | .Interface = -1, | 877 | .interface = -1, |
878 | .Codec = CODEC_SAA7111, | 878 | .codec = CODEC_SAA7111, |
879 | .VideoChannels = 3, | 879 | .video_channels = 3, |
880 | .VideoNorm = V4L2_STD_PAL, | 880 | .video_norm = V4L2_STD_PAL, |
881 | .AudioChannels = 1, | 881 | .audio_channels = 1, |
882 | .Radio = 0, | 882 | .radio = 0, |
883 | .vbi = 1, | 883 | .vbi = 1, |
884 | .Tuner = 1, | 884 | .tuner = 1, |
885 | .TunerType = TUNER_PHILIPS_PAL, | 885 | .tuner_type = TUNER_PHILIPS_PAL, |
886 | .X_Offset = -1, | 886 | .x_offset = -1, |
887 | .Y_Offset = -1, | 887 | .y_offset = -1, |
888 | .ModelString = "Miro PCTV USB", | 888 | .model_string = "Miro PCTV USB", |
889 | }, | 889 | }, |
890 | [PINNA_PCTV_USB_NTSC_FM] = { | 890 | [PINNA_PCTV_USB_NTSC_FM] = { |
891 | .Interface = -1, | 891 | .interface = -1, |
892 | .Codec = CODEC_SAA7111, | 892 | .codec = CODEC_SAA7111, |
893 | .VideoChannels = 3, | 893 | .video_channels = 3, |
894 | .VideoNorm = V4L2_STD_NTSC, | 894 | .video_norm = V4L2_STD_NTSC, |
895 | .AudioChannels = 1, | 895 | .audio_channels = 1, |
896 | .Radio = 1, | 896 | .radio = 1, |
897 | .vbi = 1, | 897 | .vbi = 1, |
898 | .Tuner = 1, | 898 | .tuner = 1, |
899 | .TunerType = TUNER_PHILIPS_NTSC_M, | 899 | .tuner_type = TUNER_PHILIPS_NTSC_M, |
900 | .X_Offset = -1, | 900 | .x_offset = -1, |
901 | .Y_Offset = -1, | 901 | .y_offset = -1, |
902 | .ModelString = "Pinnacle Studio PCTV USB (NTSC) FM", | 902 | .model_string = "Pinnacle Studio PCTV USB (NTSC) FM", |
903 | }, | 903 | }, |
904 | [PINNA_PCTV_USB_NTSC_FM_V3] = { | 904 | [PINNA_PCTV_USB_NTSC_FM_V3] = { |
905 | .Interface = -1, | 905 | .interface = -1, |
906 | .Codec = CODEC_SAA7111, | 906 | .codec = CODEC_SAA7111, |
907 | .VideoChannels = 3, | 907 | .video_channels = 3, |
908 | .VideoNorm = V4L2_STD_NTSC, | 908 | .video_norm = V4L2_STD_NTSC, |
909 | .AudioChannels = 1, | 909 | .audio_channels = 1, |
910 | .Radio = 1, | 910 | .radio = 1, |
911 | .vbi = 1, | 911 | .vbi = 1, |
912 | .Tuner = 1, | 912 | .tuner = 1, |
913 | .TunerType = TUNER_PHILIPS_NTSC_M, | 913 | .tuner_type = TUNER_PHILIPS_NTSC_M, |
914 | .X_Offset = -1, | 914 | .x_offset = -1, |
915 | .Y_Offset = -1, | 915 | .y_offset = -1, |
916 | .ModelString = "Pinnacle Studio PCTV USB (NTSC) FM V3", | 916 | .model_string = "Pinnacle Studio PCTV USB (NTSC) FM V3", |
917 | }, | 917 | }, |
918 | [PINNA_PCTV_USB_PAL_FM_V2] = { | 918 | [PINNA_PCTV_USB_PAL_FM_V2] = { |
919 | .Interface = -1, | 919 | .interface = -1, |
920 | .Codec = CODEC_SAA7113, | 920 | .codec = CODEC_SAA7113, |
921 | .VideoChannels = 3, | 921 | .video_channels = 3, |
922 | .VideoNorm = V4L2_STD_PAL, | 922 | .video_norm = V4L2_STD_PAL, |
923 | .AudioChannels = 1, | 923 | .audio_channels = 1, |
924 | .Radio = 1, | 924 | .radio = 1, |
925 | .vbi = 1, | 925 | .vbi = 1, |
926 | .Tuner = 1, | 926 | .tuner = 1, |
927 | .TunerType = TUNER_TEMIC_4009FR5_PAL, | 927 | .tuner_type = TUNER_TEMIC_4009FR5_PAL, |
928 | .X_Offset = 0, | 928 | .x_offset = 0, |
929 | .Y_Offset = 3, | 929 | .y_offset = 3, |
930 | .Dvi_yuv_override = 1, | 930 | .dvi_yuv_override = 1, |
931 | .Dvi_yuv = 7, | 931 | .dvi_yuv = 7, |
932 | .ModelString = "Pinnacle Studio PCTV USB (PAL) FM V2", | 932 | .model_string = "Pinnacle Studio PCTV USB (PAL) FM V2", |
933 | }, | 933 | }, |
934 | [PINNA_PCTV_USB_NTSC_FM_V2] = { | 934 | [PINNA_PCTV_USB_NTSC_FM_V2] = { |
935 | .Interface = -1, | 935 | .interface = -1, |
936 | .Codec = CODEC_SAA7111, | 936 | .codec = CODEC_SAA7111, |
937 | .VideoChannels = 3, | 937 | .video_channels = 3, |
938 | .VideoNorm = V4L2_STD_NTSC, | 938 | .video_norm = V4L2_STD_NTSC, |
939 | .AudioChannels = 1, | 939 | .audio_channels = 1, |
940 | .Radio = 1, | 940 | .radio = 1, |
941 | .vbi = 1, | 941 | .vbi = 1, |
942 | .Tuner = 1, | 942 | .tuner = 1, |
943 | .TunerType = TUNER_TEMIC_4039FR5_NTSC, | 943 | .tuner_type = TUNER_TEMIC_4039FR5_NTSC, |
944 | .X_Offset = 0, | 944 | .x_offset = 0, |
945 | .Y_Offset = 3, | 945 | .y_offset = 3, |
946 | .Dvi_yuv_override = 1, | 946 | .dvi_yuv_override = 1, |
947 | .Dvi_yuv = 7, | 947 | .dvi_yuv = 7, |
948 | .ModelString = "Pinnacle Studio PCTV USB (NTSC) FM V2", | 948 | .model_string = "Pinnacle Studio PCTV USB (NTSC) FM V2", |
949 | }, | 949 | }, |
950 | [PINNA_PCTV_USB_PAL_FM_V3] = { | 950 | [PINNA_PCTV_USB_PAL_FM_V3] = { |
951 | .Interface = -1, | 951 | .interface = -1, |
952 | .Codec = CODEC_SAA7113, | 952 | .codec = CODEC_SAA7113, |
953 | .VideoChannels = 3, | 953 | .video_channels = 3, |
954 | .VideoNorm = V4L2_STD_PAL, | 954 | .video_norm = V4L2_STD_PAL, |
955 | .AudioChannels = 1, | 955 | .audio_channels = 1, |
956 | .Radio = 1, | 956 | .radio = 1, |
957 | .vbi = 1, | 957 | .vbi = 1, |
958 | .Tuner = 1, | 958 | .tuner = 1, |
959 | .TunerType = TUNER_TEMIC_4009FR5_PAL, | 959 | .tuner_type = TUNER_TEMIC_4009FR5_PAL, |
960 | .X_Offset = 0, | 960 | .x_offset = 0, |
961 | .Y_Offset = 3, | 961 | .y_offset = 3, |
962 | .Dvi_yuv_override = 1, | 962 | .dvi_yuv_override = 1, |
963 | .Dvi_yuv = 7, | 963 | .dvi_yuv = 7, |
964 | .ModelString = "Pinnacle Studio PCTV USB (PAL) FM V3", | 964 | .model_string = "Pinnacle Studio PCTV USB (PAL) FM V3", |
965 | }, | 965 | }, |
966 | [PINNA_LINX_VD_IN_CAB_NTSC] = { | 966 | [PINNA_LINX_VD_IN_CAB_NTSC] = { |
967 | .Interface = -1, | 967 | .interface = -1, |
968 | .Codec = CODEC_SAA7113, | 968 | .codec = CODEC_SAA7113, |
969 | .VideoChannels = 2, | 969 | .video_channels = 2, |
970 | .VideoNorm = V4L2_STD_NTSC, | 970 | .video_norm = V4L2_STD_NTSC, |
971 | .AudioChannels = 1, | 971 | .audio_channels = 1, |
972 | .Radio = 0, | 972 | .radio = 0, |
973 | .vbi = 1, | 973 | .vbi = 1, |
974 | .Tuner = 0, | 974 | .tuner = 0, |
975 | .TunerType = 0, | 975 | .tuner_type = 0, |
976 | .X_Offset = 0, | 976 | .x_offset = 0, |
977 | .Y_Offset = 3, | 977 | .y_offset = 3, |
978 | .Dvi_yuv_override = 1, | 978 | .dvi_yuv_override = 1, |
979 | .Dvi_yuv = 7, | 979 | .dvi_yuv = 7, |
980 | .ModelString = "Pinnacle Studio Linx Video input cable (NTSC)", | 980 | .model_string = "Pinnacle Studio Linx Video input cable (NTSC)", |
981 | }, | 981 | }, |
982 | [PINNA_LINX_VD_IN_CAB_PAL] = { | 982 | [PINNA_LINX_VD_IN_CAB_PAL] = { |
983 | .Interface = -1, | 983 | .interface = -1, |
984 | .Codec = CODEC_SAA7113, | 984 | .codec = CODEC_SAA7113, |
985 | .VideoChannels = 2, | 985 | .video_channels = 2, |
986 | .VideoNorm = V4L2_STD_PAL, | 986 | .video_norm = V4L2_STD_PAL, |
987 | .AudioChannels = 1, | 987 | .audio_channels = 1, |
988 | .Radio = 0, | 988 | .radio = 0, |
989 | .vbi = 1, | 989 | .vbi = 1, |
990 | .Tuner = 0, | 990 | .tuner = 0, |
991 | .TunerType = 0, | 991 | .tuner_type = 0, |
992 | .X_Offset = 0, | 992 | .x_offset = 0, |
993 | .Y_Offset = 3, | 993 | .y_offset = 3, |
994 | .Dvi_yuv_override = 1, | 994 | .dvi_yuv_override = 1, |
995 | .Dvi_yuv = 7, | 995 | .dvi_yuv = 7, |
996 | .ModelString = "Pinnacle Studio Linx Video input cable (PAL)", | 996 | .model_string = "Pinnacle Studio Linx Video input cable (PAL)", |
997 | }, | 997 | }, |
998 | [PINNA_PCTV_BUNGEE_PAL_FM] = { | 998 | [PINNA_PCTV_BUNGEE_PAL_FM] = { |
999 | .Interface = -1, | 999 | .interface = -1, |
1000 | .Codec = CODEC_SAA7113, | 1000 | .codec = CODEC_SAA7113, |
1001 | .VideoChannels = 3, | 1001 | .video_channels = 3, |
1002 | .VideoNorm = V4L2_STD_PAL, | 1002 | .video_norm = V4L2_STD_PAL, |
1003 | .AudioChannels = 1, | 1003 | .audio_channels = 1, |
1004 | .Radio = 1, | 1004 | .radio = 1, |
1005 | .vbi = 1, | 1005 | .vbi = 1, |
1006 | .Tuner = 1, | 1006 | .tuner = 1, |
1007 | .TunerType = TUNER_TEMIC_4009FR5_PAL, | 1007 | .tuner_type = TUNER_TEMIC_4009FR5_PAL, |
1008 | .X_Offset = 0, | 1008 | .x_offset = 0, |
1009 | .Y_Offset = 3, | 1009 | .y_offset = 3, |
1010 | .Dvi_yuv_override = 1, | 1010 | .dvi_yuv_override = 1, |
1011 | .Dvi_yuv = 7, | 1011 | .dvi_yuv = 7, |
1012 | .ModelString = "Pinnacle PCTV Bungee USB (PAL) FM", | 1012 | .model_string = "Pinnacle PCTV Bungee USB (PAL) FM", |
1013 | }, | 1013 | }, |
1014 | [HPG_WINTV] = { | 1014 | [HPG_WINTV] = { |
1015 | .Interface = -1, | 1015 | .interface = -1, |
1016 | .Codec = CODEC_SAA7111, | 1016 | .codec = CODEC_SAA7111, |
1017 | .VideoChannels = 3, | 1017 | .video_channels = 3, |
1018 | .VideoNorm = V4L2_STD_NTSC, | 1018 | .video_norm = V4L2_STD_NTSC, |
1019 | .AudioChannels = 1, | 1019 | .audio_channels = 1, |
1020 | .Radio = 0, | 1020 | .radio = 0, |
1021 | .vbi = 1, | 1021 | .vbi = 1, |
1022 | .Tuner = 1, | 1022 | .tuner = 1, |
1023 | .TunerType = TUNER_PHILIPS_NTSC_M, | 1023 | .tuner_type = TUNER_PHILIPS_NTSC_M, |
1024 | .X_Offset = -1, | 1024 | .x_offset = -1, |
1025 | .Y_Offset = -1, | 1025 | .y_offset = -1, |
1026 | .ModelString = "Hauppauge WinTv-USB", | 1026 | .model_string = "Hauppauge WinTv-USB", |
1027 | }, | 1027 | }, |
1028 | }; | 1028 | }; |
1029 | const int usbvision_device_data_size=ARRAY_SIZE(usbvision_device_data); | 1029 | const int usbvision_device_data_size = ARRAY_SIZE(usbvision_device_data); |
1030 | 1030 | ||
1031 | /* Supported Devices */ | 1031 | /* Supported Devices */ |
1032 | 1032 | ||
1033 | struct usb_device_id usbvision_table [] = { | 1033 | struct usb_device_id usbvision_table[] = { |
1034 | { USB_DEVICE(0x0a6f, 0x0400), .driver_info=XANBOO }, | 1034 | { USB_DEVICE(0x0a6f, 0x0400), .driver_info = XANBOO }, |
1035 | { USB_DEVICE(0x050d, 0x0106), .driver_info=BELKIN_VIDEOBUS_II }, | 1035 | { USB_DEVICE(0x050d, 0x0106), .driver_info = BELKIN_VIDEOBUS_II }, |
1036 | { USB_DEVICE(0x050d, 0x0207), .driver_info=BELKIN_VIDEOBUS }, | 1036 | { USB_DEVICE(0x050d, 0x0207), .driver_info = BELKIN_VIDEOBUS }, |
1037 | { USB_DEVICE(0x050d, 0x0208), .driver_info=BELKIN_USB_VIDEOBUS_II }, | 1037 | { USB_DEVICE(0x050d, 0x0208), .driver_info = BELKIN_USB_VIDEOBUS_II }, |
1038 | { USB_DEVICE(0x0571, 0x0002), .driver_info=ECHOFX_INTERVIEW_LITE }, | 1038 | { USB_DEVICE(0x0571, 0x0002), .driver_info = ECHOFX_INTERVIEW_LITE }, |
1039 | { USB_DEVICE(0x0573, 0x0003), .driver_info=USBGEAR_USBG_V1 }, | 1039 | { USB_DEVICE(0x0573, 0x0003), .driver_info = USBGEAR_USBG_V1 }, |
1040 | { USB_DEVICE(0x0573, 0x0400), .driver_info=D_LINK_V100 }, | 1040 | { USB_DEVICE(0x0573, 0x0400), .driver_info = D_LINK_V100 }, |
1041 | { USB_DEVICE(0x0573, 0x2000), .driver_info=X10_USB_CAMERA }, | 1041 | { USB_DEVICE(0x0573, 0x2000), .driver_info = X10_USB_CAMERA }, |
1042 | { USB_DEVICE(0x0573, 0x2d00), .driver_info=HPG_WINTV_LIVE_PAL_BG }, | 1042 | { USB_DEVICE(0x0573, 0x2d00), .driver_info = HPG_WINTV_LIVE_PAL_BG }, |
1043 | { USB_DEVICE(0x0573, 0x2d01), .driver_info=HPG_WINTV_LIVE_PRO_NTSC_MN }, | 1043 | { USB_DEVICE(0x0573, 0x2d01), .driver_info = HPG_WINTV_LIVE_PRO_NTSC_MN }, |
1044 | { USB_DEVICE(0x0573, 0x2101), .driver_info=ZORAN_PMD_NOGATECH }, | 1044 | { USB_DEVICE(0x0573, 0x2101), .driver_info = ZORAN_PMD_NOGATECH }, |
1045 | { USB_DEVICE(0x0573, 0x4100), .driver_info=NOGATECH_USB_TV_NTSC_FM }, | 1045 | { USB_DEVICE(0x0573, 0x4100), .driver_info = NOGATECH_USB_TV_NTSC_FM }, |
1046 | { USB_DEVICE(0x0573, 0x4110), .driver_info=PNY_USB_TV_NTSC_FM }, | 1046 | { USB_DEVICE(0x0573, 0x4110), .driver_info = PNY_USB_TV_NTSC_FM }, |
1047 | { USB_DEVICE(0x0573, 0x4450), .driver_info=PV_PLAYTV_USB_PRO_PAL_FM }, | 1047 | { USB_DEVICE(0x0573, 0x4450), .driver_info = PV_PLAYTV_USB_PRO_PAL_FM }, |
1048 | { USB_DEVICE(0x0573, 0x4550), .driver_info=ZT_721 }, | 1048 | { USB_DEVICE(0x0573, 0x4550), .driver_info = ZT_721 }, |
1049 | { USB_DEVICE(0x0573, 0x4d00), .driver_info=HPG_WINTV_NTSC_MN }, | 1049 | { USB_DEVICE(0x0573, 0x4d00), .driver_info = HPG_WINTV_NTSC_MN }, |
1050 | { USB_DEVICE(0x0573, 0x4d01), .driver_info=HPG_WINTV_PAL_BG }, | 1050 | { USB_DEVICE(0x0573, 0x4d01), .driver_info = HPG_WINTV_PAL_BG }, |
1051 | { USB_DEVICE(0x0573, 0x4d02), .driver_info=HPG_WINTV_PAL_I }, | 1051 | { USB_DEVICE(0x0573, 0x4d02), .driver_info = HPG_WINTV_PAL_I }, |
1052 | { USB_DEVICE(0x0573, 0x4d03), .driver_info=HPG_WINTV_PAL_SECAM_L }, | 1052 | { USB_DEVICE(0x0573, 0x4d03), .driver_info = HPG_WINTV_PAL_SECAM_L }, |
1053 | { USB_DEVICE(0x0573, 0x4d04), .driver_info=HPG_WINTV_PAL_D_K }, | 1053 | { USB_DEVICE(0x0573, 0x4d04), .driver_info = HPG_WINTV_PAL_D_K }, |
1054 | { USB_DEVICE(0x0573, 0x4d10), .driver_info=HPG_WINTV_NTSC_FM }, | 1054 | { USB_DEVICE(0x0573, 0x4d10), .driver_info = HPG_WINTV_NTSC_FM }, |
1055 | { USB_DEVICE(0x0573, 0x4d11), .driver_info=HPG_WINTV_PAL_BG_FM }, | 1055 | { USB_DEVICE(0x0573, 0x4d11), .driver_info = HPG_WINTV_PAL_BG_FM }, |
1056 | { USB_DEVICE(0x0573, 0x4d12), .driver_info=HPG_WINTV_PAL_I_FM }, | 1056 | { USB_DEVICE(0x0573, 0x4d12), .driver_info = HPG_WINTV_PAL_I_FM }, |
1057 | { USB_DEVICE(0x0573, 0x4d14), .driver_info=HPG_WINTV_PAL_D_K_FM }, | 1057 | { USB_DEVICE(0x0573, 0x4d14), .driver_info = HPG_WINTV_PAL_D_K_FM }, |
1058 | { USB_DEVICE(0x0573, 0x4d2a), .driver_info=HPG_WINTV_PRO_NTSC_MN }, | 1058 | { USB_DEVICE(0x0573, 0x4d2a), .driver_info = HPG_WINTV_PRO_NTSC_MN }, |
1059 | { USB_DEVICE(0x0573, 0x4d2b), .driver_info=HPG_WINTV_PRO_NTSC_MN_V2 }, | 1059 | { USB_DEVICE(0x0573, 0x4d2b), .driver_info = HPG_WINTV_PRO_NTSC_MN_V2 }, |
1060 | { USB_DEVICE(0x0573, 0x4d2c), .driver_info=HPG_WINTV_PRO_PAL }, | 1060 | { USB_DEVICE(0x0573, 0x4d2c), .driver_info = HPG_WINTV_PRO_PAL }, |
1061 | { USB_DEVICE(0x0573, 0x4d20), .driver_info = HPG_WINTV_PRO_NTSC_MN_V3 }, | 1061 | { USB_DEVICE(0x0573, 0x4d20), .driver_info = HPG_WINTV_PRO_NTSC_MN_V3 }, |
1062 | { USB_DEVICE(0x0573, 0x4d21), .driver_info=HPG_WINTV_PRO_PAL_BG }, | 1062 | { USB_DEVICE(0x0573, 0x4d21), .driver_info = HPG_WINTV_PRO_PAL_BG }, |
1063 | { USB_DEVICE(0x0573, 0x4d22), .driver_info=HPG_WINTV_PRO_PAL_I }, | 1063 | { USB_DEVICE(0x0573, 0x4d22), .driver_info = HPG_WINTV_PRO_PAL_I }, |
1064 | { USB_DEVICE(0x0573, 0x4d23), .driver_info=HPG_WINTV_PRO_PAL_SECAM_L }, | 1064 | { USB_DEVICE(0x0573, 0x4d23), .driver_info = HPG_WINTV_PRO_PAL_SECAM_L }, |
1065 | { USB_DEVICE(0x0573, 0x4d24), .driver_info=HPG_WINTV_PRO_PAL_D_K }, | 1065 | { USB_DEVICE(0x0573, 0x4d24), .driver_info = HPG_WINTV_PRO_PAL_D_K }, |
1066 | { USB_DEVICE(0x0573, 0x4d25), .driver_info=HPG_WINTV_PRO_PAL_SECAM }, | 1066 | { USB_DEVICE(0x0573, 0x4d25), .driver_info = HPG_WINTV_PRO_PAL_SECAM }, |
1067 | { USB_DEVICE(0x0573, 0x4d26), .driver_info=HPG_WINTV_PRO_PAL_SECAM_V2 }, | 1067 | { USB_DEVICE(0x0573, 0x4d26), .driver_info = HPG_WINTV_PRO_PAL_SECAM_V2 }, |
1068 | { USB_DEVICE(0x0573, 0x4d27), .driver_info=HPG_WINTV_PRO_PAL_BG_V2 }, | 1068 | { USB_DEVICE(0x0573, 0x4d27), .driver_info = HPG_WINTV_PRO_PAL_BG_V2 }, |
1069 | { USB_DEVICE(0x0573, 0x4d28), .driver_info=HPG_WINTV_PRO_PAL_BG_D_K }, | 1069 | { USB_DEVICE(0x0573, 0x4d28), .driver_info = HPG_WINTV_PRO_PAL_BG_D_K }, |
1070 | { USB_DEVICE(0x0573, 0x4d29), .driver_info=HPG_WINTV_PRO_PAL_I_D_K }, | 1070 | { USB_DEVICE(0x0573, 0x4d29), .driver_info = HPG_WINTV_PRO_PAL_I_D_K }, |
1071 | { USB_DEVICE(0x0573, 0x4d30), .driver_info=HPG_WINTV_PRO_NTSC_MN_FM }, | 1071 | { USB_DEVICE(0x0573, 0x4d30), .driver_info = HPG_WINTV_PRO_NTSC_MN_FM }, |
1072 | { USB_DEVICE(0x0573, 0x4d31), .driver_info=HPG_WINTV_PRO_PAL_BG_FM }, | 1072 | { USB_DEVICE(0x0573, 0x4d31), .driver_info = HPG_WINTV_PRO_PAL_BG_FM }, |
1073 | { USB_DEVICE(0x0573, 0x4d32), .driver_info=HPG_WINTV_PRO_PAL_I_FM }, | 1073 | { USB_DEVICE(0x0573, 0x4d32), .driver_info = HPG_WINTV_PRO_PAL_I_FM }, |
1074 | { USB_DEVICE(0x0573, 0x4d34), .driver_info=HPG_WINTV_PRO_PAL_D_K_FM }, | 1074 | { USB_DEVICE(0x0573, 0x4d34), .driver_info = HPG_WINTV_PRO_PAL_D_K_FM }, |
1075 | { USB_DEVICE(0x0573, 0x4d35), .driver_info=HPG_WINTV_PRO_TEMIC_PAL_FM }, | 1075 | { USB_DEVICE(0x0573, 0x4d35), .driver_info = HPG_WINTV_PRO_TEMIC_PAL_FM }, |
1076 | { USB_DEVICE(0x0573, 0x4d36), .driver_info=HPG_WINTV_PRO_TEMIC_PAL_BG_FM }, | 1076 | { USB_DEVICE(0x0573, 0x4d36), .driver_info = HPG_WINTV_PRO_TEMIC_PAL_BG_FM }, |
1077 | { USB_DEVICE(0x0573, 0x4d37), .driver_info=HPG_WINTV_PRO_PAL_FM }, | 1077 | { USB_DEVICE(0x0573, 0x4d37), .driver_info = HPG_WINTV_PRO_PAL_FM }, |
1078 | { USB_DEVICE(0x0573, 0x4d38), .driver_info=HPG_WINTV_PRO_NTSC_MN_FM_V2 }, | 1078 | { USB_DEVICE(0x0573, 0x4d38), .driver_info = HPG_WINTV_PRO_NTSC_MN_FM_V2 }, |
1079 | { USB_DEVICE(0x0768, 0x0006), .driver_info=CAMTEL_TVB330 }, | 1079 | { USB_DEVICE(0x0768, 0x0006), .driver_info = CAMTEL_TVB330 }, |
1080 | { USB_DEVICE(0x07d0, 0x0001), .driver_info=DIGITAL_VIDEO_CREATOR_I }, | 1080 | { USB_DEVICE(0x07d0, 0x0001), .driver_info = DIGITAL_VIDEO_CREATOR_I }, |
1081 | { USB_DEVICE(0x07d0, 0x0002), .driver_info=GLOBAL_VILLAGE_GV_007_NTSC }, | 1081 | { USB_DEVICE(0x07d0, 0x0002), .driver_info = GLOBAL_VILLAGE_GV_007_NTSC }, |
1082 | { USB_DEVICE(0x07d0, 0x0003), .driver_info=DAZZLE_DVC_50_REV_1_NTSC }, | 1082 | { USB_DEVICE(0x07d0, 0x0003), .driver_info = DAZZLE_DVC_50_REV_1_NTSC }, |
1083 | { USB_DEVICE(0x07d0, 0x0004), .driver_info=DAZZLE_DVC_80_REV_1_PAL }, | 1083 | { USB_DEVICE(0x07d0, 0x0004), .driver_info = DAZZLE_DVC_80_REV_1_PAL }, |
1084 | { USB_DEVICE(0x07d0, 0x0005), .driver_info=DAZZLE_DVC_90_REV_1_SECAM }, | 1084 | { USB_DEVICE(0x07d0, 0x0005), .driver_info = DAZZLE_DVC_90_REV_1_SECAM }, |
1085 | { USB_DEVICE(0x07f8, 0x9104), .driver_info=ESKAPE_LABS_MYTV2GO }, | 1085 | { USB_DEVICE(0x07f8, 0x9104), .driver_info = ESKAPE_LABS_MYTV2GO }, |
1086 | { USB_DEVICE(0x2304, 0x010d), .driver_info=PINNA_PCTV_USB_PAL }, | 1086 | { USB_DEVICE(0x2304, 0x010d), .driver_info = PINNA_PCTV_USB_PAL }, |
1087 | { USB_DEVICE(0x2304, 0x0109), .driver_info=PINNA_PCTV_USB_SECAM }, | 1087 | { USB_DEVICE(0x2304, 0x0109), .driver_info = PINNA_PCTV_USB_SECAM }, |
1088 | { USB_DEVICE(0x2304, 0x0110), .driver_info=PINNA_PCTV_USB_PAL_FM }, | 1088 | { USB_DEVICE(0x2304, 0x0110), .driver_info = PINNA_PCTV_USB_PAL_FM }, |
1089 | { USB_DEVICE(0x2304, 0x0111), .driver_info=MIRO_PCTV_USB }, | 1089 | { USB_DEVICE(0x2304, 0x0111), .driver_info = MIRO_PCTV_USB }, |
1090 | { USB_DEVICE(0x2304, 0x0112), .driver_info=PINNA_PCTV_USB_NTSC_FM }, | 1090 | { USB_DEVICE(0x2304, 0x0112), .driver_info = PINNA_PCTV_USB_NTSC_FM }, |
1091 | { USB_DEVICE(0x2304, 0x0113), | 1091 | { USB_DEVICE(0x2304, 0x0113), |
1092 | .driver_info = PINNA_PCTV_USB_NTSC_FM_V3 }, | 1092 | .driver_info = PINNA_PCTV_USB_NTSC_FM_V3 }, |
1093 | { USB_DEVICE(0x2304, 0x0210), .driver_info=PINNA_PCTV_USB_PAL_FM_V2 }, | 1093 | { USB_DEVICE(0x2304, 0x0210), .driver_info = PINNA_PCTV_USB_PAL_FM_V2 }, |
1094 | { USB_DEVICE(0x2304, 0x0212), .driver_info=PINNA_PCTV_USB_NTSC_FM_V2 }, | 1094 | { USB_DEVICE(0x2304, 0x0212), .driver_info = PINNA_PCTV_USB_NTSC_FM_V2 }, |
1095 | { USB_DEVICE(0x2304, 0x0214), .driver_info=PINNA_PCTV_USB_PAL_FM_V3 }, | 1095 | { USB_DEVICE(0x2304, 0x0214), .driver_info = PINNA_PCTV_USB_PAL_FM_V3 }, |
1096 | { USB_DEVICE(0x2304, 0x0300), .driver_info=PINNA_LINX_VD_IN_CAB_NTSC }, | 1096 | { USB_DEVICE(0x2304, 0x0300), .driver_info = PINNA_LINX_VD_IN_CAB_NTSC }, |
1097 | { USB_DEVICE(0x2304, 0x0301), .driver_info=PINNA_LINX_VD_IN_CAB_PAL }, | 1097 | { USB_DEVICE(0x2304, 0x0301), .driver_info = PINNA_LINX_VD_IN_CAB_PAL }, |
1098 | { USB_DEVICE(0x2304, 0x0419), .driver_info=PINNA_PCTV_BUNGEE_PAL_FM }, | 1098 | { USB_DEVICE(0x2304, 0x0419), .driver_info = PINNA_PCTV_BUNGEE_PAL_FM }, |
1099 | { USB_DEVICE(0x2400, 0x4200), .driver_info=HPG_WINTV }, | 1099 | { USB_DEVICE(0x2400, 0x4200), .driver_info = HPG_WINTV }, |
1100 | { }, /* terminate list */ | 1100 | { }, /* terminate list */ |
1101 | }; | 1101 | }; |
1102 | 1102 | ||
1103 | MODULE_DEVICE_TABLE (usb, usbvision_table); | 1103 | MODULE_DEVICE_TABLE(usb, usbvision_table); |
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index b9dd74fde212..c8feb0d6fccf 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
36 | #include <asm/io.h> | 36 | #include <linux/io.h> |
37 | #include <linux/videodev2.h> | 37 | #include <linux/videodev2.h> |
38 | #include <linux/i2c.h> | 38 | #include <linux/i2c.h> |
39 | 39 | ||
@@ -46,30 +46,30 @@ | |||
46 | #include "usbvision.h" | 46 | #include "usbvision.h" |
47 | 47 | ||
48 | static unsigned int core_debug; | 48 | static unsigned int core_debug; |
49 | module_param(core_debug,int,0644); | 49 | module_param(core_debug, int, 0644); |
50 | MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); | 50 | MODULE_PARM_DESC(core_debug, "enable debug messages [core]"); |
51 | 51 | ||
52 | static unsigned int force_testpattern; | 52 | static unsigned int force_testpattern; |
53 | module_param(force_testpattern,int,0644); | 53 | module_param(force_testpattern, int, 0644); |
54 | MODULE_PARM_DESC(force_testpattern,"enable test pattern display [core]"); | 54 | MODULE_PARM_DESC(force_testpattern, "enable test pattern display [core]"); |
55 | 55 | ||
56 | static int adjustCompression = 1; /* Set the compression to be adaptive */ | 56 | static int adjust_compression = 1; /* Set the compression to be adaptive */ |
57 | module_param(adjustCompression, int, 0444); | 57 | module_param(adjust_compression, int, 0444); |
58 | MODULE_PARM_DESC(adjustCompression, " Set the ADPCM compression for the device. Default: 1 (On)"); | 58 | MODULE_PARM_DESC(adjust_compression, " Set the ADPCM compression for the device. Default: 1 (On)"); |
59 | 59 | ||
60 | /* To help people with Black and White output with using s-video input. | 60 | /* To help people with Black and White output with using s-video input. |
61 | * Some cables and input device are wired differently. */ | 61 | * Some cables and input device are wired differently. */ |
62 | static int SwitchSVideoInput; | 62 | static int switch_svideo_input; |
63 | module_param(SwitchSVideoInput, int, 0444); | 63 | module_param(switch_svideo_input, int, 0444); |
64 | MODULE_PARM_DESC(SwitchSVideoInput, " Set the S-Video input. Some cables and input device are wired differently. Default: 0 (Off)"); | 64 | MODULE_PARM_DESC(switch_svideo_input, " Set the S-Video input. Some cables and input device are wired differently. Default: 0 (Off)"); |
65 | 65 | ||
66 | static unsigned int adjust_X_Offset = -1; | 66 | static unsigned int adjust_x_offset = -1; |
67 | module_param(adjust_X_Offset, int, 0644); | 67 | module_param(adjust_x_offset, int, 0644); |
68 | MODULE_PARM_DESC(adjust_X_Offset, "adjust X offset display [core]"); | 68 | MODULE_PARM_DESC(adjust_x_offset, "adjust X offset display [core]"); |
69 | 69 | ||
70 | static unsigned int adjust_Y_Offset = -1; | 70 | static unsigned int adjust_y_offset = -1; |
71 | module_param(adjust_Y_Offset, int, 0644); | 71 | module_param(adjust_y_offset, int, 0644); |
72 | MODULE_PARM_DESC(adjust_Y_Offset, "adjust Y offset display [core]"); | 72 | MODULE_PARM_DESC(adjust_y_offset, "adjust Y offset display [core]"); |
73 | 73 | ||
74 | 74 | ||
75 | #define ENABLE_HEXDUMP 0 /* Enable if you need it */ | 75 | #define ENABLE_HEXDUMP 0 /* Enable if you need it */ |
@@ -82,15 +82,15 @@ MODULE_PARM_DESC(adjust_Y_Offset, "adjust Y offset display [core]"); | |||
82 | __func__, __LINE__ , ## args); \ | 82 | __func__, __LINE__ , ## args); \ |
83 | } | 83 | } |
84 | #else | 84 | #else |
85 | #define PDEBUG(level, fmt, args...) do {} while(0) | 85 | #define PDEBUG(level, fmt, args...) do {} while (0) |
86 | #endif | 86 | #endif |
87 | 87 | ||
88 | #define DBG_HEADER 1<<0 | 88 | #define DBG_HEADER (1 << 0) |
89 | #define DBG_IRQ 1<<1 | 89 | #define DBG_IRQ (1 << 1) |
90 | #define DBG_ISOC 1<<2 | 90 | #define DBG_ISOC (1 << 2) |
91 | #define DBG_PARSE 1<<3 | 91 | #define DBG_PARSE (1 << 3) |
92 | #define DBG_SCRATCH 1<<4 | 92 | #define DBG_SCRATCH (1 << 4) |
93 | #define DBG_FUNC 1<<5 | 93 | #define DBG_FUNC (1 << 5) |
94 | 94 | ||
95 | static const int max_imgwidth = MAX_FRAME_WIDTH; | 95 | static const int max_imgwidth = MAX_FRAME_WIDTH; |
96 | static const int max_imgheight = MAX_FRAME_HEIGHT; | 96 | static const int max_imgheight = MAX_FRAME_HEIGHT; |
@@ -103,14 +103,14 @@ static const int min_imgheight = MIN_FRAME_HEIGHT; | |||
103 | * to work with. This setting can be adjusted, but the default value | 103 | * to work with. This setting can be adjusted, but the default value |
104 | * should be OK for most desktop users. | 104 | * should be OK for most desktop users. |
105 | */ | 105 | */ |
106 | #define DEFAULT_SCRATCH_BUF_SIZE (0x20000) // 128kB memory scratch buffer | 106 | #define DEFAULT_SCRATCH_BUF_SIZE (0x20000) /* 128kB memory scratch buffer */ |
107 | static const int scratch_buf_size = DEFAULT_SCRATCH_BUF_SIZE; | 107 | static const int scratch_buf_size = DEFAULT_SCRATCH_BUF_SIZE; |
108 | 108 | ||
109 | // Function prototypes | 109 | /* Function prototypes */ |
110 | static int usbvision_request_intra (struct usb_usbvision *usbvision); | 110 | static int usbvision_request_intra(struct usb_usbvision *usbvision); |
111 | static int usbvision_unrequest_intra (struct usb_usbvision *usbvision); | 111 | static int usbvision_unrequest_intra(struct usb_usbvision *usbvision); |
112 | static int usbvision_adjust_compression (struct usb_usbvision *usbvision); | 112 | static int usbvision_adjust_compression(struct usb_usbvision *usbvision); |
113 | static int usbvision_measure_bandwidth (struct usb_usbvision *usbvision); | 113 | static int usbvision_measure_bandwidth(struct usb_usbvision *usbvision); |
114 | 114 | ||
115 | /*******************************/ | 115 | /*******************************/ |
116 | /* Memory management functions */ | 116 | /* Memory management functions */ |
@@ -176,19 +176,19 @@ static void usbvision_hexdump(const unsigned char *data, int len) | |||
176 | k += sprintf(&tmp[k], "%02x ", data[i]); | 176 | k += sprintf(&tmp[k], "%02x ", data[i]); |
177 | } | 177 | } |
178 | if (k > 0) | 178 | if (k > 0) |
179 | printk("%s\n", tmp); | 179 | printk(KERN_CONT "%s\n", tmp); |
180 | } | 180 | } |
181 | #endif | 181 | #endif |
182 | 182 | ||
183 | /******************************** | 183 | /******************************** |
184 | * scratch ring buffer handling | 184 | * scratch ring buffer handling |
185 | ********************************/ | 185 | ********************************/ |
186 | static int scratch_len(struct usb_usbvision *usbvision) /*This returns the amount of data actually in the buffer */ | 186 | static int scratch_len(struct usb_usbvision *usbvision) /* This returns the amount of data actually in the buffer */ |
187 | { | 187 | { |
188 | int len = usbvision->scratch_write_ptr - usbvision->scratch_read_ptr; | 188 | int len = usbvision->scratch_write_ptr - usbvision->scratch_read_ptr; |
189 | if (len < 0) { | 189 | |
190 | if (len < 0) | ||
190 | len += scratch_buf_size; | 191 | len += scratch_buf_size; |
191 | } | ||
192 | PDEBUG(DBG_SCRATCH, "scratch_len() = %d\n", len); | 192 | PDEBUG(DBG_SCRATCH, "scratch_len() = %d\n", len); |
193 | 193 | ||
194 | return len; | 194 | return len; |
@@ -199,9 +199,8 @@ static int scratch_len(struct usb_usbvision *usbvision) /*This returns the am | |||
199 | static int scratch_free(struct usb_usbvision *usbvision) | 199 | static int scratch_free(struct usb_usbvision *usbvision) |
200 | { | 200 | { |
201 | int free = usbvision->scratch_read_ptr - usbvision->scratch_write_ptr; | 201 | int free = usbvision->scratch_read_ptr - usbvision->scratch_write_ptr; |
202 | if (free <= 0) { | 202 | if (free <= 0) |
203 | free += scratch_buf_size; | 203 | free += scratch_buf_size; |
204 | } | ||
205 | if (free) { | 204 | if (free) { |
206 | free -= 1; /* at least one byte in the buffer must */ | 205 | free -= 1; /* at least one byte in the buffer must */ |
207 | /* left blank, otherwise there is no chance to differ between full and empty */ | 206 | /* left blank, otherwise there is no chance to differ between full and empty */ |
@@ -221,14 +220,12 @@ static int scratch_put(struct usb_usbvision *usbvision, unsigned char *data, | |||
221 | if (usbvision->scratch_write_ptr + len < scratch_buf_size) { | 220 | if (usbvision->scratch_write_ptr + len < scratch_buf_size) { |
222 | memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len); | 221 | memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len); |
223 | usbvision->scratch_write_ptr += len; | 222 | usbvision->scratch_write_ptr += len; |
224 | } | 223 | } else { |
225 | else { | ||
226 | len_part = scratch_buf_size - usbvision->scratch_write_ptr; | 224 | len_part = scratch_buf_size - usbvision->scratch_write_ptr; |
227 | memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len_part); | 225 | memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len_part); |
228 | if (len == len_part) { | 226 | if (len == len_part) { |
229 | usbvision->scratch_write_ptr = 0; /* just set write_ptr to zero */ | 227 | usbvision->scratch_write_ptr = 0; /* just set write_ptr to zero */ |
230 | } | 228 | } else { |
231 | else { | ||
232 | memcpy(usbvision->scratch, data + len_part, len - len_part); | 229 | memcpy(usbvision->scratch, data + len_part, len - len_part); |
233 | usbvision->scratch_write_ptr = len - len_part; | 230 | usbvision->scratch_write_ptr = len - len_part; |
234 | } | 231 | } |
@@ -255,17 +252,16 @@ static int scratch_get_extra(struct usb_usbvision *usbvision, | |||
255 | unsigned char *data, int *ptr, int len) | 252 | unsigned char *data, int *ptr, int len) |
256 | { | 253 | { |
257 | int len_part; | 254 | int len_part; |
255 | |||
258 | if (*ptr + len < scratch_buf_size) { | 256 | if (*ptr + len < scratch_buf_size) { |
259 | memcpy(data, usbvision->scratch + *ptr, len); | 257 | memcpy(data, usbvision->scratch + *ptr, len); |
260 | *ptr += len; | 258 | *ptr += len; |
261 | } | 259 | } else { |
262 | else { | ||
263 | len_part = scratch_buf_size - *ptr; | 260 | len_part = scratch_buf_size - *ptr; |
264 | memcpy(data, usbvision->scratch + *ptr, len_part); | 261 | memcpy(data, usbvision->scratch + *ptr, len_part); |
265 | if (len == len_part) { | 262 | if (len == len_part) { |
266 | *ptr = 0; /* just set the y_ptr to zero */ | 263 | *ptr = 0; /* just set the y_ptr to zero */ |
267 | } | 264 | } else { |
268 | else { | ||
269 | memcpy(data + len_part, usbvision->scratch, len - len_part); | 265 | memcpy(data + len_part, usbvision->scratch, len - len_part); |
270 | *ptr = len - len_part; | 266 | *ptr = len - len_part; |
271 | } | 267 | } |
@@ -281,13 +277,13 @@ static int scratch_get_extra(struct usb_usbvision *usbvision, | |||
281 | static void scratch_set_extra_ptr(struct usb_usbvision *usbvision, int *ptr, | 277 | static void scratch_set_extra_ptr(struct usb_usbvision *usbvision, int *ptr, |
282 | int len) | 278 | int len) |
283 | { | 279 | { |
284 | *ptr = (usbvision->scratch_read_ptr + len)%scratch_buf_size; | 280 | *ptr = (usbvision->scratch_read_ptr + len) % scratch_buf_size; |
285 | 281 | ||
286 | PDEBUG(DBG_SCRATCH, "ptr=%d\n", *ptr); | 282 | PDEBUG(DBG_SCRATCH, "ptr=%d\n", *ptr); |
287 | } | 283 | } |
288 | 284 | ||
289 | 285 | ||
290 | /*This increments the scratch extra read pointer */ | 286 | /* This increments the scratch extra read pointer */ |
291 | static void scratch_inc_extra_ptr(int *ptr, int len) | 287 | static void scratch_inc_extra_ptr(int *ptr, int len) |
292 | { | 288 | { |
293 | *ptr = (*ptr + len) % scratch_buf_size; | 289 | *ptr = (*ptr + len) % scratch_buf_size; |
@@ -301,17 +297,16 @@ static int scratch_get(struct usb_usbvision *usbvision, unsigned char *data, | |||
301 | int len) | 297 | int len) |
302 | { | 298 | { |
303 | int len_part; | 299 | int len_part; |
300 | |||
304 | if (usbvision->scratch_read_ptr + len < scratch_buf_size) { | 301 | if (usbvision->scratch_read_ptr + len < scratch_buf_size) { |
305 | memcpy(data, usbvision->scratch + usbvision->scratch_read_ptr, len); | 302 | memcpy(data, usbvision->scratch + usbvision->scratch_read_ptr, len); |
306 | usbvision->scratch_read_ptr += len; | 303 | usbvision->scratch_read_ptr += len; |
307 | } | 304 | } else { |
308 | else { | ||
309 | len_part = scratch_buf_size - usbvision->scratch_read_ptr; | 305 | len_part = scratch_buf_size - usbvision->scratch_read_ptr; |
310 | memcpy(data, usbvision->scratch + usbvision->scratch_read_ptr, len_part); | 306 | memcpy(data, usbvision->scratch + usbvision->scratch_read_ptr, len_part); |
311 | if (len == len_part) { | 307 | if (len == len_part) { |
312 | usbvision->scratch_read_ptr = 0; /* just set the read_ptr to zero */ | 308 | usbvision->scratch_read_ptr = 0; /* just set the read_ptr to zero */ |
313 | } | 309 | } else { |
314 | else { | ||
315 | memcpy(data + len_part, usbvision->scratch, len - len_part); | 310 | memcpy(data + len_part, usbvision->scratch, len - len_part); |
316 | usbvision->scratch_read_ptr = len - len_part; | 311 | usbvision->scratch_read_ptr = len - len_part; |
317 | } | 312 | } |
@@ -327,7 +322,7 @@ static int scratch_get(struct usb_usbvision *usbvision, unsigned char *data, | |||
327 | static int scratch_get_header(struct usb_usbvision *usbvision, | 322 | static int scratch_get_header(struct usb_usbvision *usbvision, |
328 | struct usbvision_frame_header *header) | 323 | struct usbvision_frame_header *header) |
329 | { | 324 | { |
330 | int errCode = 0; | 325 | int err_code = 0; |
331 | 326 | ||
332 | PDEBUG(DBG_SCRATCH, "from read_ptr=%d", usbvision->scratch_headermarker_read_ptr); | 327 | PDEBUG(DBG_SCRATCH, "from read_ptr=%d", usbvision->scratch_headermarker_read_ptr); |
333 | 328 | ||
@@ -340,29 +335,28 @@ static int scratch_get_header(struct usb_usbvision *usbvision, | |||
340 | scratch_get(usbvision, (unsigned char *)header, USBVISION_HEADER_LENGTH); | 335 | scratch_get(usbvision, (unsigned char *)header, USBVISION_HEADER_LENGTH); |
341 | if ((header->magic_1 == USBVISION_MAGIC_1) | 336 | if ((header->magic_1 == USBVISION_MAGIC_1) |
342 | && (header->magic_2 == USBVISION_MAGIC_2) | 337 | && (header->magic_2 == USBVISION_MAGIC_2) |
343 | && (header->headerLength == USBVISION_HEADER_LENGTH)) { | 338 | && (header->header_length == USBVISION_HEADER_LENGTH)) { |
344 | errCode = USBVISION_HEADER_LENGTH; | 339 | err_code = USBVISION_HEADER_LENGTH; |
345 | header->frameWidth = header->frameWidthLo + (header->frameWidthHi << 8); | 340 | header->frame_width = header->frame_width_lo + (header->frame_width_hi << 8); |
346 | header->frameHeight = header->frameHeightLo + (header->frameHeightHi << 8); | 341 | header->frame_height = header->frame_height_lo + (header->frame_height_hi << 8); |
347 | break; | 342 | break; |
348 | } | 343 | } |
349 | } | 344 | } |
350 | 345 | ||
351 | return errCode; | 346 | return err_code; |
352 | } | 347 | } |
353 | 348 | ||
354 | 349 | ||
355 | /*This removes len bytes of old data from the buffer */ | 350 | /* This removes len bytes of old data from the buffer */ |
356 | static void scratch_rm_old(struct usb_usbvision *usbvision, int len) | 351 | static void scratch_rm_old(struct usb_usbvision *usbvision, int len) |
357 | { | 352 | { |
358 | |||
359 | usbvision->scratch_read_ptr += len; | 353 | usbvision->scratch_read_ptr += len; |
360 | usbvision->scratch_read_ptr %= scratch_buf_size; | 354 | usbvision->scratch_read_ptr %= scratch_buf_size; |
361 | PDEBUG(DBG_SCRATCH, "read_ptr is now %d\n", usbvision->scratch_read_ptr); | 355 | PDEBUG(DBG_SCRATCH, "read_ptr is now %d\n", usbvision->scratch_read_ptr); |
362 | } | 356 | } |
363 | 357 | ||
364 | 358 | ||
365 | /*This resets the buffer - kills all data in it too */ | 359 | /* This resets the buffer - kills all data in it too */ |
366 | static void scratch_reset(struct usb_usbvision *usbvision) | 360 | static void scratch_reset(struct usb_usbvision *usbvision) |
367 | { | 361 | { |
368 | PDEBUG(DBG_SCRATCH, "\n"); | 362 | PDEBUG(DBG_SCRATCH, "\n"); |
@@ -371,14 +365,14 @@ static void scratch_reset(struct usb_usbvision *usbvision) | |||
371 | usbvision->scratch_write_ptr = 0; | 365 | usbvision->scratch_write_ptr = 0; |
372 | usbvision->scratch_headermarker_read_ptr = 0; | 366 | usbvision->scratch_headermarker_read_ptr = 0; |
373 | usbvision->scratch_headermarker_write_ptr = 0; | 367 | usbvision->scratch_headermarker_write_ptr = 0; |
374 | usbvision->isocstate = IsocState_NoFrame; | 368 | usbvision->isocstate = isoc_state_no_frame; |
375 | } | 369 | } |
376 | 370 | ||
377 | int usbvision_scratch_alloc(struct usb_usbvision *usbvision) | 371 | int usbvision_scratch_alloc(struct usb_usbvision *usbvision) |
378 | { | 372 | { |
379 | usbvision->scratch = vmalloc_32(scratch_buf_size); | 373 | usbvision->scratch = vmalloc_32(scratch_buf_size); |
380 | scratch_reset(usbvision); | 374 | scratch_reset(usbvision); |
381 | if(usbvision->scratch == NULL) { | 375 | if (usbvision->scratch == NULL) { |
382 | dev_err(&usbvision->dev->dev, | 376 | dev_err(&usbvision->dev->dev, |
383 | "%s: unable to allocate %d bytes for scratch\n", | 377 | "%s: unable to allocate %d bytes for scratch\n", |
384 | __func__, scratch_buf_size); | 378 | __func__, scratch_buf_size); |
@@ -391,7 +385,6 @@ void usbvision_scratch_free(struct usb_usbvision *usbvision) | |||
391 | { | 385 | { |
392 | vfree(usbvision->scratch); | 386 | vfree(usbvision->scratch); |
393 | usbvision->scratch = NULL; | 387 | usbvision->scratch = NULL; |
394 | |||
395 | } | 388 | } |
396 | 389 | ||
397 | /* | 390 | /* |
@@ -420,13 +413,13 @@ static void usbvision_testpattern(struct usb_usbvision *usbvision, | |||
420 | printk(KERN_ERR "%s: usbvision == NULL\n", proc); | 413 | printk(KERN_ERR "%s: usbvision == NULL\n", proc); |
421 | return; | 414 | return; |
422 | } | 415 | } |
423 | if (usbvision->curFrame == NULL) { | 416 | if (usbvision->cur_frame == NULL) { |
424 | printk(KERN_ERR "%s: usbvision->curFrame is NULL.\n", proc); | 417 | printk(KERN_ERR "%s: usbvision->cur_frame is NULL.\n", proc); |
425 | return; | 418 | return; |
426 | } | 419 | } |
427 | 420 | ||
428 | /* Grab the current frame */ | 421 | /* Grab the current frame */ |
429 | frame = usbvision->curFrame; | 422 | frame = usbvision->cur_frame; |
430 | 423 | ||
431 | /* Optionally start at the beginning */ | 424 | /* Optionally start at the beginning */ |
432 | if (fullframe) { | 425 | if (fullframe) { |
@@ -473,10 +466,9 @@ static void usbvision_testpattern(struct usb_usbvision *usbvision, | |||
473 | } | 466 | } |
474 | } | 467 | } |
475 | 468 | ||
476 | frame->grabstate = FrameState_Done; | 469 | frame->grabstate = frame_state_done; |
477 | frame->scanlength += scan_length; | 470 | frame->scanlength += scan_length; |
478 | ++num_pass; | 471 | ++num_pass; |
479 | |||
480 | } | 472 | } |
481 | 473 | ||
482 | /* | 474 | /* |
@@ -487,8 +479,9 @@ static void usbvision_testpattern(struct usb_usbvision *usbvision, | |||
487 | int usbvision_decompress_alloc(struct usb_usbvision *usbvision) | 479 | int usbvision_decompress_alloc(struct usb_usbvision *usbvision) |
488 | { | 480 | { |
489 | int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2; | 481 | int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2; |
490 | usbvision->IntraFrameBuffer = vmalloc_32(IFB_size); | 482 | |
491 | if (usbvision->IntraFrameBuffer == NULL) { | 483 | usbvision->intra_frame_buffer = vmalloc_32(IFB_size); |
484 | if (usbvision->intra_frame_buffer == NULL) { | ||
492 | dev_err(&usbvision->dev->dev, | 485 | dev_err(&usbvision->dev->dev, |
493 | "%s: unable to allocate %d for compr. frame buffer\n", | 486 | "%s: unable to allocate %d for compr. frame buffer\n", |
494 | __func__, IFB_size); | 487 | __func__, IFB_size); |
@@ -504,8 +497,8 @@ int usbvision_decompress_alloc(struct usb_usbvision *usbvision) | |||
504 | */ | 497 | */ |
505 | void usbvision_decompress_free(struct usb_usbvision *usbvision) | 498 | void usbvision_decompress_free(struct usb_usbvision *usbvision) |
506 | { | 499 | { |
507 | vfree(usbvision->IntraFrameBuffer); | 500 | vfree(usbvision->intra_frame_buffer); |
508 | usbvision->IntraFrameBuffer = NULL; | 501 | usbvision->intra_frame_buffer = NULL; |
509 | 502 | ||
510 | } | 503 | } |
511 | 504 | ||
@@ -517,117 +510,111 @@ void usbvision_decompress_free(struct usb_usbvision *usbvision) | |||
517 | * | 510 | * |
518 | * Locate one of supported header markers in the scratch buffer. | 511 | * Locate one of supported header markers in the scratch buffer. |
519 | */ | 512 | */ |
520 | static enum ParseState usbvision_find_header(struct usb_usbvision *usbvision) | 513 | static enum parse_state usbvision_find_header(struct usb_usbvision *usbvision) |
521 | { | 514 | { |
522 | struct usbvision_frame *frame; | 515 | struct usbvision_frame *frame; |
523 | int foundHeader = 0; | 516 | int found_header = 0; |
524 | 517 | ||
525 | frame = usbvision->curFrame; | 518 | frame = usbvision->cur_frame; |
526 | 519 | ||
527 | while (scratch_get_header(usbvision, &frame->isocHeader) == USBVISION_HEADER_LENGTH) { | 520 | while (scratch_get_header(usbvision, &frame->isoc_header) == USBVISION_HEADER_LENGTH) { |
528 | // found header in scratch | 521 | /* found header in scratch */ |
529 | PDEBUG(DBG_HEADER, "found header: 0x%02x%02x %d %d %d %d %#x 0x%02x %u %u", | 522 | PDEBUG(DBG_HEADER, "found header: 0x%02x%02x %d %d %d %d %#x 0x%02x %u %u", |
530 | frame->isocHeader.magic_2, | 523 | frame->isoc_header.magic_2, |
531 | frame->isocHeader.magic_1, | 524 | frame->isoc_header.magic_1, |
532 | frame->isocHeader.headerLength, | 525 | frame->isoc_header.header_length, |
533 | frame->isocHeader.frameNum, | 526 | frame->isoc_header.frame_num, |
534 | frame->isocHeader.framePhase, | 527 | frame->isoc_header.frame_phase, |
535 | frame->isocHeader.frameLatency, | 528 | frame->isoc_header.frame_latency, |
536 | frame->isocHeader.dataFormat, | 529 | frame->isoc_header.data_format, |
537 | frame->isocHeader.formatParam, | 530 | frame->isoc_header.format_param, |
538 | frame->isocHeader.frameWidth, | 531 | frame->isoc_header.frame_width, |
539 | frame->isocHeader.frameHeight); | 532 | frame->isoc_header.frame_height); |
540 | 533 | ||
541 | if (usbvision->requestIntra) { | 534 | if (usbvision->request_intra) { |
542 | if (frame->isocHeader.formatParam & 0x80) { | 535 | if (frame->isoc_header.format_param & 0x80) { |
543 | foundHeader = 1; | 536 | found_header = 1; |
544 | usbvision->lastIsocFrameNum = -1; // do not check for lost frames this time | 537 | usbvision->last_isoc_frame_num = -1; /* do not check for lost frames this time */ |
545 | usbvision_unrequest_intra(usbvision); | 538 | usbvision_unrequest_intra(usbvision); |
546 | break; | 539 | break; |
547 | } | 540 | } |
548 | } | 541 | } else { |
549 | else { | 542 | found_header = 1; |
550 | foundHeader = 1; | ||
551 | break; | 543 | break; |
552 | } | 544 | } |
553 | } | 545 | } |
554 | 546 | ||
555 | if (foundHeader) { | 547 | if (found_header) { |
556 | frame->frmwidth = frame->isocHeader.frameWidth * usbvision->stretch_width; | 548 | frame->frmwidth = frame->isoc_header.frame_width * usbvision->stretch_width; |
557 | frame->frmheight = frame->isocHeader.frameHeight * usbvision->stretch_height; | 549 | frame->frmheight = frame->isoc_header.frame_height * usbvision->stretch_height; |
558 | frame->v4l2_linesize = (frame->frmwidth * frame->v4l2_format.depth)>> 3; | 550 | frame->v4l2_linesize = (frame->frmwidth * frame->v4l2_format.depth) >> 3; |
559 | } | 551 | } else { /* no header found */ |
560 | else { // no header found | ||
561 | PDEBUG(DBG_HEADER, "skipping scratch data, no header"); | 552 | PDEBUG(DBG_HEADER, "skipping scratch data, no header"); |
562 | scratch_reset(usbvision); | 553 | scratch_reset(usbvision); |
563 | return ParseState_EndParse; | 554 | return parse_state_end_parse; |
564 | } | 555 | } |
565 | 556 | ||
566 | // found header | 557 | /* found header */ |
567 | if (frame->isocHeader.dataFormat==ISOC_MODE_COMPRESS) { | 558 | if (frame->isoc_header.data_format == ISOC_MODE_COMPRESS) { |
568 | //check isocHeader.frameNum for lost frames | 559 | /* check isoc_header.frame_num for lost frames */ |
569 | if (usbvision->lastIsocFrameNum >= 0) { | 560 | if (usbvision->last_isoc_frame_num >= 0) { |
570 | if (((usbvision->lastIsocFrameNum + 1) % 32) != frame->isocHeader.frameNum) { | 561 | if (((usbvision->last_isoc_frame_num + 1) % 32) != frame->isoc_header.frame_num) { |
571 | // unexpected frame drop: need to request new intra frame | 562 | /* unexpected frame drop: need to request new intra frame */ |
572 | PDEBUG(DBG_HEADER, "Lost frame before %d on USB", frame->isocHeader.frameNum); | 563 | PDEBUG(DBG_HEADER, "Lost frame before %d on USB", frame->isoc_header.frame_num); |
573 | usbvision_request_intra(usbvision); | 564 | usbvision_request_intra(usbvision); |
574 | return ParseState_NextFrame; | 565 | return parse_state_next_frame; |
575 | } | 566 | } |
576 | } | 567 | } |
577 | usbvision->lastIsocFrameNum = frame->isocHeader.frameNum; | 568 | usbvision->last_isoc_frame_num = frame->isoc_header.frame_num; |
578 | } | 569 | } |
579 | usbvision->header_count++; | 570 | usbvision->header_count++; |
580 | frame->scanstate = ScanState_Lines; | 571 | frame->scanstate = scan_state_lines; |
581 | frame->curline = 0; | 572 | frame->curline = 0; |
582 | 573 | ||
583 | if (force_testpattern) { | 574 | if (force_testpattern) { |
584 | usbvision_testpattern(usbvision, 1, 1); | 575 | usbvision_testpattern(usbvision, 1, 1); |
585 | return ParseState_NextFrame; | 576 | return parse_state_next_frame; |
586 | } | 577 | } |
587 | return ParseState_Continue; | 578 | return parse_state_continue; |
588 | } | 579 | } |
589 | 580 | ||
590 | static enum ParseState usbvision_parse_lines_422(struct usb_usbvision *usbvision, | 581 | static enum parse_state usbvision_parse_lines_422(struct usb_usbvision *usbvision, |
591 | long *pcopylen) | 582 | long *pcopylen) |
592 | { | 583 | { |
593 | volatile struct usbvision_frame *frame; | 584 | volatile struct usbvision_frame *frame; |
594 | unsigned char *f; | 585 | unsigned char *f; |
595 | int len; | 586 | int len; |
596 | int i; | 587 | int i; |
597 | unsigned char yuyv[4]={180, 128, 10, 128}; // YUV components | 588 | unsigned char yuyv[4] = { 180, 128, 10, 128 }; /* YUV components */ |
598 | unsigned char rv, gv, bv; // RGB components | 589 | unsigned char rv, gv, bv; /* RGB components */ |
599 | int clipmask_index, bytes_per_pixel; | 590 | int clipmask_index, bytes_per_pixel; |
600 | int stretch_bytes, clipmask_add; | 591 | int stretch_bytes, clipmask_add; |
601 | 592 | ||
602 | frame = usbvision->curFrame; | 593 | frame = usbvision->cur_frame; |
603 | f = frame->data + (frame->v4l2_linesize * frame->curline); | 594 | f = frame->data + (frame->v4l2_linesize * frame->curline); |
604 | 595 | ||
605 | /* Make sure there's enough data for the entire line */ | 596 | /* Make sure there's enough data for the entire line */ |
606 | len = (frame->isocHeader.frameWidth * 2)+5; | 597 | len = (frame->isoc_header.frame_width * 2) + 5; |
607 | if (scratch_len(usbvision) < len) { | 598 | if (scratch_len(usbvision) < len) { |
608 | PDEBUG(DBG_PARSE, "out of data in line %d, need %u.\n", frame->curline, len); | 599 | PDEBUG(DBG_PARSE, "out of data in line %d, need %u.\n", frame->curline, len); |
609 | return ParseState_Out; | 600 | return parse_state_out; |
610 | } | 601 | } |
611 | 602 | ||
612 | if ((frame->curline + 1) >= frame->frmheight) { | 603 | if ((frame->curline + 1) >= frame->frmheight) |
613 | return ParseState_NextFrame; | 604 | return parse_state_next_frame; |
614 | } | ||
615 | 605 | ||
616 | bytes_per_pixel = frame->v4l2_format.bytes_per_pixel; | 606 | bytes_per_pixel = frame->v4l2_format.bytes_per_pixel; |
617 | stretch_bytes = (usbvision->stretch_width - 1) * bytes_per_pixel; | 607 | stretch_bytes = (usbvision->stretch_width - 1) * bytes_per_pixel; |
618 | clipmask_index = frame->curline * MAX_FRAME_WIDTH; | 608 | clipmask_index = frame->curline * MAX_FRAME_WIDTH; |
619 | clipmask_add = usbvision->stretch_width; | 609 | clipmask_add = usbvision->stretch_width; |
620 | 610 | ||
621 | for (i = 0; i < frame->frmwidth; i+=(2 * usbvision->stretch_width)) { | 611 | for (i = 0; i < frame->frmwidth; i += (2 * usbvision->stretch_width)) { |
622 | |||
623 | scratch_get(usbvision, &yuyv[0], 4); | 612 | scratch_get(usbvision, &yuyv[0], 4); |
624 | 613 | ||
625 | if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { | 614 | if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { |
626 | *f++ = yuyv[0]; // Y | 615 | *f++ = yuyv[0]; /* Y */ |
627 | *f++ = yuyv[3]; // U | 616 | *f++ = yuyv[3]; /* U */ |
628 | } | 617 | } else { |
629 | else { | ||
630 | |||
631 | YUV_TO_RGB_BY_THE_BOOK(yuyv[0], yuyv[1], yuyv[3], rv, gv, bv); | 618 | YUV_TO_RGB_BY_THE_BOOK(yuyv[0], yuyv[1], yuyv[3], rv, gv, bv); |
632 | switch (frame->v4l2_format.format) { | 619 | switch (frame->v4l2_format.format) { |
633 | case V4L2_PIX_FMT_RGB565: | 620 | case V4L2_PIX_FMT_RGB565: |
@@ -659,11 +646,9 @@ static enum ParseState usbvision_parse_lines_422(struct usb_usbvision *usbvision | |||
659 | f += stretch_bytes; | 646 | f += stretch_bytes; |
660 | 647 | ||
661 | if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { | 648 | if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { |
662 | *f++ = yuyv[2]; // Y | 649 | *f++ = yuyv[2]; /* Y */ |
663 | *f++ = yuyv[1]; // V | 650 | *f++ = yuyv[1]; /* V */ |
664 | } | 651 | } else { |
665 | else { | ||
666 | |||
667 | YUV_TO_RGB_BY_THE_BOOK(yuyv[2], yuyv[1], yuyv[3], rv, gv, bv); | 652 | YUV_TO_RGB_BY_THE_BOOK(yuyv[2], yuyv[1], yuyv[3], rv, gv, bv); |
668 | switch (frame->v4l2_format.format) { | 653 | switch (frame->v4l2_format.format) { |
669 | case V4L2_PIX_FMT_RGB565: | 654 | case V4L2_PIX_FMT_RGB565: |
@@ -698,100 +683,94 @@ static enum ParseState usbvision_parse_lines_422(struct usb_usbvision *usbvision | |||
698 | frame->curline += usbvision->stretch_height; | 683 | frame->curline += usbvision->stretch_height; |
699 | *pcopylen += frame->v4l2_linesize * usbvision->stretch_height; | 684 | *pcopylen += frame->v4l2_linesize * usbvision->stretch_height; |
700 | 685 | ||
701 | if (frame->curline >= frame->frmheight) { | 686 | if (frame->curline >= frame->frmheight) |
702 | return ParseState_NextFrame; | 687 | return parse_state_next_frame; |
703 | } | 688 | return parse_state_continue; |
704 | else { | ||
705 | return ParseState_Continue; | ||
706 | } | ||
707 | } | 689 | } |
708 | 690 | ||
709 | /* The decompression routine */ | 691 | /* The decompression routine */ |
710 | static int usbvision_decompress(struct usb_usbvision *usbvision,unsigned char *Compressed, | 692 | static int usbvision_decompress(struct usb_usbvision *usbvision, unsigned char *compressed, |
711 | unsigned char *Decompressed, int *StartPos, | 693 | unsigned char *decompressed, int *start_pos, |
712 | int *BlockTypeStartPos, int Len) | 694 | int *block_typestart_pos, int len) |
713 | { | 695 | { |
714 | int RestPixel, Idx, MaxPos, Pos, ExtraPos, BlockLen, BlockTypePos, BlockTypeLen; | 696 | int rest_pixel, idx, max_pos, pos, extra_pos, block_len, block_type_pos, block_type_len; |
715 | unsigned char BlockByte, BlockCode, BlockType, BlockTypeByte, Integrator; | 697 | unsigned char block_byte, block_code, block_type, block_type_byte, integrator; |
716 | 698 | ||
717 | Integrator = 0; | 699 | integrator = 0; |
718 | Pos = *StartPos; | 700 | pos = *start_pos; |
719 | BlockTypePos = *BlockTypeStartPos; | 701 | block_type_pos = *block_typestart_pos; |
720 | MaxPos = 396; //Pos + Len; | 702 | max_pos = 396; /* pos + len; */ |
721 | ExtraPos = Pos; | 703 | extra_pos = pos; |
722 | BlockLen = 0; | 704 | block_len = 0; |
723 | BlockByte = 0; | 705 | block_byte = 0; |
724 | BlockCode = 0; | 706 | block_code = 0; |
725 | BlockType = 0; | 707 | block_type = 0; |
726 | BlockTypeByte = 0; | 708 | block_type_byte = 0; |
727 | BlockTypeLen = 0; | 709 | block_type_len = 0; |
728 | RestPixel = Len; | 710 | rest_pixel = len; |
729 | 711 | ||
730 | for (Idx = 0; Idx < Len; Idx++) { | 712 | for (idx = 0; idx < len; idx++) { |
731 | 713 | if (block_len == 0) { | |
732 | if (BlockLen == 0) { | 714 | if (block_type_len == 0) { |
733 | if (BlockTypeLen==0) { | 715 | block_type_byte = compressed[block_type_pos]; |
734 | BlockTypeByte = Compressed[BlockTypePos]; | 716 | block_type_pos++; |
735 | BlockTypePos++; | 717 | block_type_len = 4; |
736 | BlockTypeLen = 4; | ||
737 | } | 718 | } |
738 | BlockType = (BlockTypeByte & 0xC0) >> 6; | 719 | block_type = (block_type_byte & 0xC0) >> 6; |
739 | 720 | ||
740 | //statistic: | 721 | /* statistic: */ |
741 | usbvision->ComprBlockTypes[BlockType]++; | 722 | usbvision->compr_block_types[block_type]++; |
742 | 723 | ||
743 | Pos = ExtraPos; | 724 | pos = extra_pos; |
744 | if (BlockType == 0) { | 725 | if (block_type == 0) { |
745 | if(RestPixel >= 24) { | 726 | if (rest_pixel >= 24) { |
746 | Idx += 23; | 727 | idx += 23; |
747 | RestPixel -= 24; | 728 | rest_pixel -= 24; |
748 | Integrator = Decompressed[Idx]; | 729 | integrator = decompressed[idx]; |
749 | } else { | 730 | } else { |
750 | Idx += RestPixel - 1; | 731 | idx += rest_pixel - 1; |
751 | RestPixel = 0; | 732 | rest_pixel = 0; |
752 | } | 733 | } |
753 | } else { | 734 | } else { |
754 | BlockCode = Compressed[Pos]; | 735 | block_code = compressed[pos]; |
755 | Pos++; | 736 | pos++; |
756 | if (RestPixel >= 24) { | 737 | if (rest_pixel >= 24) |
757 | BlockLen = 24; | 738 | block_len = 24; |
758 | } else { | 739 | else |
759 | BlockLen = RestPixel; | 740 | block_len = rest_pixel; |
760 | } | 741 | rest_pixel -= block_len; |
761 | RestPixel -= BlockLen; | 742 | extra_pos = pos + (block_len / 4); |
762 | ExtraPos = Pos + (BlockLen / 4); | ||
763 | } | 743 | } |
764 | BlockTypeByte <<= 2; | 744 | block_type_byte <<= 2; |
765 | BlockTypeLen -= 1; | 745 | block_type_len -= 1; |
766 | } | 746 | } |
767 | if (BlockLen > 0) { | 747 | if (block_len > 0) { |
768 | if ((BlockLen%4) == 0) { | 748 | if ((block_len % 4) == 0) { |
769 | BlockByte = Compressed[Pos]; | 749 | block_byte = compressed[pos]; |
770 | Pos++; | 750 | pos++; |
771 | } | 751 | } |
772 | if (BlockType == 1) { //inter Block | 752 | if (block_type == 1) /* inter Block */ |
773 | Integrator = Decompressed[Idx]; | 753 | integrator = decompressed[idx]; |
774 | } | 754 | switch (block_byte & 0xC0) { |
775 | switch (BlockByte & 0xC0) { | 755 | case 0x03 << 6: |
776 | case 0x03<<6: | 756 | integrator += compressed[extra_pos]; |
777 | Integrator += Compressed[ExtraPos]; | 757 | extra_pos++; |
778 | ExtraPos++; | 758 | break; |
779 | break; | 759 | case 0x02 << 6: |
780 | case 0x02<<6: | 760 | integrator += block_code; |
781 | Integrator += BlockCode; | 761 | break; |
782 | break; | 762 | case 0x00: |
783 | case 0x00: | 763 | integrator -= block_code; |
784 | Integrator -= BlockCode; | 764 | break; |
785 | break; | ||
786 | } | 765 | } |
787 | Decompressed[Idx] = Integrator; | 766 | decompressed[idx] = integrator; |
788 | BlockByte <<= 2; | 767 | block_byte <<= 2; |
789 | BlockLen -= 1; | 768 | block_len -= 1; |
790 | } | 769 | } |
791 | } | 770 | } |
792 | *StartPos = ExtraPos; | 771 | *start_pos = extra_pos; |
793 | *BlockTypeStartPos = BlockTypePos; | 772 | *block_typestart_pos = block_type_pos; |
794 | return Idx; | 773 | return idx; |
795 | } | 774 | } |
796 | 775 | ||
797 | 776 | ||
@@ -803,7 +782,7 @@ static int usbvision_decompress(struct usb_usbvision *usbvision,unsigned char *C | |||
803 | * number of bytes (RGB) to the *pcopylen. | 782 | * number of bytes (RGB) to the *pcopylen. |
804 | * | 783 | * |
805 | */ | 784 | */ |
806 | static enum ParseState usbvision_parse_compress(struct usb_usbvision *usbvision, | 785 | static enum parse_state usbvision_parse_compress(struct usb_usbvision *usbvision, |
807 | long *pcopylen) | 786 | long *pcopylen) |
808 | { | 787 | { |
809 | #define USBVISION_STRIP_MAGIC 0x5A | 788 | #define USBVISION_STRIP_MAGIC 0x5A |
@@ -811,191 +790,165 @@ static enum ParseState usbvision_parse_compress(struct usb_usbvision *usbvision, | |||
811 | #define USBVISION_STRIP_HEADER_LEN 3 | 790 | #define USBVISION_STRIP_HEADER_LEN 3 |
812 | 791 | ||
813 | struct usbvision_frame *frame; | 792 | struct usbvision_frame *frame; |
814 | unsigned char *f,*u = NULL ,*v = NULL; | 793 | unsigned char *f, *u = NULL, *v = NULL; |
815 | unsigned char StripData[USBVISION_STRIP_LEN_MAX]; | 794 | unsigned char strip_data[USBVISION_STRIP_LEN_MAX]; |
816 | unsigned char StripHeader[USBVISION_STRIP_HEADER_LEN]; | 795 | unsigned char strip_header[USBVISION_STRIP_HEADER_LEN]; |
817 | int Idx, IdxEnd, StripLen, StripPtr, StartBlockPos, BlockPos, BlockTypePos; | 796 | int idx, idx_end, strip_len, strip_ptr, startblock_pos, block_pos, block_type_pos; |
818 | int clipmask_index, bytes_per_pixel, rc; | 797 | int clipmask_index, bytes_per_pixel, rc; |
819 | int imageSize; | 798 | int image_size; |
820 | unsigned char rv, gv, bv; | 799 | unsigned char rv, gv, bv; |
821 | static unsigned char *Y, *U, *V; | 800 | static unsigned char *Y, *U, *V; |
822 | 801 | ||
823 | frame = usbvision->curFrame; | 802 | frame = usbvision->cur_frame; |
824 | imageSize = frame->frmwidth * frame->frmheight; | 803 | image_size = frame->frmwidth * frame->frmheight; |
825 | if ( (frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) || | 804 | if ((frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) || |
826 | (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) ) { // this is a planar format | 805 | (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420)) { /* this is a planar format */ |
827 | //... v4l2_linesize not used here. | 806 | /* ... v4l2_linesize not used here. */ |
828 | f = frame->data + (frame->width * frame->curline); | 807 | f = frame->data + (frame->width * frame->curline); |
829 | } else | 808 | } else |
830 | f = frame->data + (frame->v4l2_linesize * frame->curline); | 809 | f = frame->data + (frame->v4l2_linesize * frame->curline); |
831 | 810 | ||
832 | if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV){ //initialise u and v pointers | 811 | if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { /* initialise u and v pointers */ |
833 | // get base of u and b planes add halfoffset | 812 | /* get base of u and b planes add halfoffset */ |
834 | |||
835 | u = frame->data | 813 | u = frame->data |
836 | + imageSize | 814 | + image_size |
837 | + (frame->frmwidth >>1) * frame->curline ; | 815 | + (frame->frmwidth >> 1) * frame->curline; |
838 | v = u + (imageSize >>1 ); | 816 | v = u + (image_size >> 1); |
839 | 817 | } else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) { | |
840 | } else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420){ | 818 | v = frame->data + image_size + ((frame->curline * (frame->width)) >> 2); |
841 | 819 | u = v + (image_size >> 2); | |
842 | v = frame->data + imageSize + ((frame->curline* (frame->width))>>2) ; | ||
843 | u = v + (imageSize >>2) ; | ||
844 | } | 820 | } |
845 | 821 | ||
846 | if (frame->curline == 0) { | 822 | if (frame->curline == 0) |
847 | usbvision_adjust_compression(usbvision); | 823 | usbvision_adjust_compression(usbvision); |
848 | } | ||
849 | 824 | ||
850 | if (scratch_len(usbvision) < USBVISION_STRIP_HEADER_LEN) { | 825 | if (scratch_len(usbvision) < USBVISION_STRIP_HEADER_LEN) |
851 | return ParseState_Out; | 826 | return parse_state_out; |
852 | } | ||
853 | 827 | ||
854 | //get strip header without changing the scratch_read_ptr | 828 | /* get strip header without changing the scratch_read_ptr */ |
855 | scratch_set_extra_ptr(usbvision, &StripPtr, 0); | 829 | scratch_set_extra_ptr(usbvision, &strip_ptr, 0); |
856 | scratch_get_extra(usbvision, &StripHeader[0], &StripPtr, | 830 | scratch_get_extra(usbvision, &strip_header[0], &strip_ptr, |
857 | USBVISION_STRIP_HEADER_LEN); | 831 | USBVISION_STRIP_HEADER_LEN); |
858 | 832 | ||
859 | if (StripHeader[0] != USBVISION_STRIP_MAGIC) { | 833 | if (strip_header[0] != USBVISION_STRIP_MAGIC) { |
860 | // wrong strip magic | 834 | /* wrong strip magic */ |
861 | usbvision->stripMagicErrors++; | 835 | usbvision->strip_magic_errors++; |
862 | return ParseState_NextFrame; | 836 | return parse_state_next_frame; |
863 | } | 837 | } |
864 | 838 | ||
865 | if (frame->curline != (int)StripHeader[2]) { | 839 | if (frame->curline != (int)strip_header[2]) { |
866 | //line number missmatch error | 840 | /* line number mismatch error */ |
867 | usbvision->stripLineNumberErrors++; | 841 | usbvision->strip_line_number_errors++; |
868 | } | 842 | } |
869 | 843 | ||
870 | StripLen = 2 * (unsigned int)StripHeader[1]; | 844 | strip_len = 2 * (unsigned int)strip_header[1]; |
871 | if (StripLen > USBVISION_STRIP_LEN_MAX) { | 845 | if (strip_len > USBVISION_STRIP_LEN_MAX) { |
872 | // strip overrun | 846 | /* strip overrun */ |
873 | // I think this never happens | 847 | /* I think this never happens */ |
874 | usbvision_request_intra(usbvision); | 848 | usbvision_request_intra(usbvision); |
875 | } | 849 | } |
876 | 850 | ||
877 | if (scratch_len(usbvision) < StripLen) { | 851 | if (scratch_len(usbvision) < strip_len) { |
878 | //there is not enough data for the strip | 852 | /* there is not enough data for the strip */ |
879 | return ParseState_Out; | 853 | return parse_state_out; |
880 | } | 854 | } |
881 | 855 | ||
882 | if (usbvision->IntraFrameBuffer) { | 856 | if (usbvision->intra_frame_buffer) { |
883 | Y = usbvision->IntraFrameBuffer + frame->frmwidth * frame->curline; | 857 | Y = usbvision->intra_frame_buffer + frame->frmwidth * frame->curline; |
884 | U = usbvision->IntraFrameBuffer + imageSize + (frame->frmwidth / 2) * (frame->curline / 2); | 858 | U = usbvision->intra_frame_buffer + image_size + (frame->frmwidth / 2) * (frame->curline / 2); |
885 | V = usbvision->IntraFrameBuffer + imageSize / 4 * 5 + (frame->frmwidth / 2) * (frame->curline / 2); | 859 | V = usbvision->intra_frame_buffer + image_size / 4 * 5 + (frame->frmwidth / 2) * (frame->curline / 2); |
886 | } | 860 | } else { |
887 | else { | 861 | return parse_state_next_frame; |
888 | return ParseState_NextFrame; | ||
889 | } | 862 | } |
890 | 863 | ||
891 | bytes_per_pixel = frame->v4l2_format.bytes_per_pixel; | 864 | bytes_per_pixel = frame->v4l2_format.bytes_per_pixel; |
892 | clipmask_index = frame->curline * MAX_FRAME_WIDTH; | 865 | clipmask_index = frame->curline * MAX_FRAME_WIDTH; |
893 | 866 | ||
894 | scratch_get(usbvision, StripData, StripLen); | 867 | scratch_get(usbvision, strip_data, strip_len); |
895 | 868 | ||
896 | IdxEnd = frame->frmwidth; | 869 | idx_end = frame->frmwidth; |
897 | BlockTypePos = USBVISION_STRIP_HEADER_LEN; | 870 | block_type_pos = USBVISION_STRIP_HEADER_LEN; |
898 | StartBlockPos = BlockTypePos + (IdxEnd - 1) / 96 + (IdxEnd / 2 - 1) / 96 + 2; | 871 | startblock_pos = block_type_pos + (idx_end - 1) / 96 + (idx_end / 2 - 1) / 96 + 2; |
899 | BlockPos = StartBlockPos; | 872 | block_pos = startblock_pos; |
900 | 873 | ||
901 | usbvision->BlockPos = BlockPos; | 874 | usbvision->block_pos = block_pos; |
902 | 875 | ||
903 | if ((rc = usbvision_decompress(usbvision, StripData, Y, &BlockPos, &BlockTypePos, IdxEnd)) != IdxEnd) { | 876 | rc = usbvision_decompress(usbvision, strip_data, Y, &block_pos, &block_type_pos, idx_end); |
904 | //return ParseState_Continue; | 877 | if (strip_len > usbvision->max_strip_len) |
905 | } | 878 | usbvision->max_strip_len = strip_len; |
906 | if (StripLen > usbvision->maxStripLen) { | ||
907 | usbvision->maxStripLen = StripLen; | ||
908 | } | ||
909 | 879 | ||
910 | if (frame->curline%2) { | 880 | if (frame->curline % 2) |
911 | if ((rc = usbvision_decompress(usbvision, StripData, V, &BlockPos, &BlockTypePos, IdxEnd/2)) != IdxEnd/2) { | 881 | rc = usbvision_decompress(usbvision, strip_data, V, &block_pos, &block_type_pos, idx_end / 2); |
912 | //return ParseState_Continue; | 882 | else |
913 | } | 883 | rc = usbvision_decompress(usbvision, strip_data, U, &block_pos, &block_type_pos, idx_end / 2); |
914 | } | ||
915 | else { | ||
916 | if ((rc = usbvision_decompress(usbvision, StripData, U, &BlockPos, &BlockTypePos, IdxEnd/2)) != IdxEnd/2) { | ||
917 | //return ParseState_Continue; | ||
918 | } | ||
919 | } | ||
920 | 884 | ||
921 | if (BlockPos > usbvision->comprBlockPos) { | 885 | if (block_pos > usbvision->comprblock_pos) |
922 | usbvision->comprBlockPos = BlockPos; | 886 | usbvision->comprblock_pos = block_pos; |
923 | } | 887 | if (block_pos > strip_len) |
924 | if (BlockPos > StripLen) { | 888 | usbvision->strip_len_errors++; |
925 | usbvision->stripLenErrors++; | ||
926 | } | ||
927 | 889 | ||
928 | for (Idx = 0; Idx < IdxEnd; Idx++) { | 890 | for (idx = 0; idx < idx_end; idx++) { |
929 | if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { | 891 | if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { |
930 | *f++ = Y[Idx]; | 892 | *f++ = Y[idx]; |
931 | *f++ = Idx & 0x01 ? U[Idx/2] : V[Idx/2]; | 893 | *f++ = idx & 0x01 ? U[idx / 2] : V[idx / 2]; |
932 | } | 894 | } else if (frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) { |
933 | else if(frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) { | 895 | *f++ = Y[idx]; |
934 | *f++ = Y[Idx]; | 896 | if (idx & 0x01) |
935 | if ( Idx & 0x01) | 897 | *u++ = U[idx >> 1]; |
936 | *u++ = U[Idx>>1] ; | ||
937 | else | 898 | else |
938 | *v++ = V[Idx>>1]; | 899 | *v++ = V[idx >> 1]; |
939 | } | 900 | } else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) { |
940 | else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) { | 901 | *f++ = Y[idx]; |
941 | *f++ = Y [Idx]; | 902 | if (!((idx & 0x01) | (frame->curline & 0x01))) { |
942 | if ( !(( Idx & 0x01 ) | ( frame->curline & 0x01 )) ){ | 903 | /* only need do this for 1 in 4 pixels */ |
943 | 904 | /* intraframe buffer is YUV420 format */ | |
944 | /* only need do this for 1 in 4 pixels */ | 905 | *u++ = U[idx >> 1]; |
945 | /* intraframe buffer is YUV420 format */ | 906 | *v++ = V[idx >> 1]; |
946 | |||
947 | *u++ = U[Idx >>1]; | ||
948 | *v++ = V[Idx >>1]; | ||
949 | } | 907 | } |
950 | 908 | } else { | |
951 | } | 909 | YUV_TO_RGB_BY_THE_BOOK(Y[idx], U[idx / 2], V[idx / 2], rv, gv, bv); |
952 | else { | ||
953 | YUV_TO_RGB_BY_THE_BOOK(Y[Idx], U[Idx/2], V[Idx/2], rv, gv, bv); | ||
954 | switch (frame->v4l2_format.format) { | 910 | switch (frame->v4l2_format.format) { |
955 | case V4L2_PIX_FMT_GREY: | 911 | case V4L2_PIX_FMT_GREY: |
956 | *f++ = Y[Idx]; | 912 | *f++ = Y[idx]; |
957 | break; | 913 | break; |
958 | case V4L2_PIX_FMT_RGB555: | 914 | case V4L2_PIX_FMT_RGB555: |
959 | *f++ = (0x1F & rv) | | 915 | *f++ = (0x1F & rv) | |
960 | (0xE0 & (gv << 5)); | 916 | (0xE0 & (gv << 5)); |
961 | *f++ = (0x03 & (gv >> 3)) | | 917 | *f++ = (0x03 & (gv >> 3)) | |
962 | (0x7C & (bv << 2)); | 918 | (0x7C & (bv << 2)); |
963 | break; | 919 | break; |
964 | case V4L2_PIX_FMT_RGB565: | 920 | case V4L2_PIX_FMT_RGB565: |
965 | *f++ = (0x1F & rv) | | 921 | *f++ = (0x1F & rv) | |
966 | (0xE0 & (gv << 5)); | 922 | (0xE0 & (gv << 5)); |
967 | *f++ = (0x07 & (gv >> 3)) | | 923 | *f++ = (0x07 & (gv >> 3)) | |
968 | (0xF8 & bv); | 924 | (0xF8 & bv); |
969 | break; | 925 | break; |
970 | case V4L2_PIX_FMT_RGB24: | 926 | case V4L2_PIX_FMT_RGB24: |
971 | *f++ = rv; | 927 | *f++ = rv; |
972 | *f++ = gv; | 928 | *f++ = gv; |
973 | *f++ = bv; | 929 | *f++ = bv; |
974 | break; | 930 | break; |
975 | case V4L2_PIX_FMT_RGB32: | 931 | case V4L2_PIX_FMT_RGB32: |
976 | *f++ = rv; | 932 | *f++ = rv; |
977 | *f++ = gv; | 933 | *f++ = gv; |
978 | *f++ = bv; | 934 | *f++ = bv; |
979 | f++; | 935 | f++; |
980 | break; | 936 | break; |
981 | } | 937 | } |
982 | } | 938 | } |
983 | clipmask_index++; | 939 | clipmask_index++; |
984 | } | 940 | } |
985 | /* Deal with non-integer no. of bytes for YUV420P */ | 941 | /* Deal with non-integer no. of bytes for YUV420P */ |
986 | if (frame->v4l2_format.format != V4L2_PIX_FMT_YVU420 ) | 942 | if (frame->v4l2_format.format != V4L2_PIX_FMT_YVU420) |
987 | *pcopylen += frame->v4l2_linesize; | 943 | *pcopylen += frame->v4l2_linesize; |
988 | else | 944 | else |
989 | *pcopylen += frame->curline & 0x01 ? frame->v4l2_linesize : frame->v4l2_linesize << 1; | 945 | *pcopylen += frame->curline & 0x01 ? frame->v4l2_linesize : frame->v4l2_linesize << 1; |
990 | 946 | ||
991 | frame->curline += 1; | 947 | frame->curline += 1; |
992 | 948 | ||
993 | if (frame->curline >= frame->frmheight) { | 949 | if (frame->curline >= frame->frmheight) |
994 | return ParseState_NextFrame; | 950 | return parse_state_next_frame; |
995 | } | 951 | return parse_state_continue; |
996 | else { | ||
997 | return ParseState_Continue; | ||
998 | } | ||
999 | 952 | ||
1000 | } | 953 | } |
1001 | 954 | ||
@@ -1008,7 +961,7 @@ static enum ParseState usbvision_parse_compress(struct usb_usbvision *usbvision, | |||
1008 | * number of bytes (RGB) to the *pcopylen. | 961 | * number of bytes (RGB) to the *pcopylen. |
1009 | * | 962 | * |
1010 | */ | 963 | */ |
1011 | static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision, | 964 | static enum parse_state usbvision_parse_lines_420(struct usb_usbvision *usbvision, |
1012 | long *pcopylen) | 965 | long *pcopylen) |
1013 | { | 966 | { |
1014 | struct usbvision_frame *frame; | 967 | struct usbvision_frame *frame; |
@@ -1016,11 +969,11 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision | |||
1016 | unsigned int pixel_per_line, block; | 969 | unsigned int pixel_per_line, block; |
1017 | int pixel, block_split; | 970 | int pixel, block_split; |
1018 | int y_ptr, u_ptr, v_ptr, y_odd_offset; | 971 | int y_ptr, u_ptr, v_ptr, y_odd_offset; |
1019 | const int y_block_size = 128; | 972 | const int y_block_size = 128; |
1020 | const int uv_block_size = 64; | 973 | const int uv_block_size = 64; |
1021 | const int sub_block_size = 32; | 974 | const int sub_block_size = 32; |
1022 | const int y_step[] = { 0, 0, 0, 2 }, y_step_size = 4; | 975 | const int y_step[] = { 0, 0, 0, 2 }, y_step_size = 4; |
1023 | const int uv_step[]= { 0, 0, 0, 4 }, uv_step_size = 4; | 976 | const int uv_step[] = { 0, 0, 0, 4 }, uv_step_size = 4; |
1024 | unsigned char y[2], u, v; /* YUV components */ | 977 | unsigned char y[2], u, v; /* YUV components */ |
1025 | int y_, u_, v_, vb, uvg, ur; | 978 | int y_, u_, v_, vb, uvg, ur; |
1026 | int r_, g_, b_; /* RGB components */ | 979 | int r_, g_, b_; /* RGB components */ |
@@ -1028,7 +981,7 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision | |||
1028 | int clipmask_even_index, clipmask_odd_index, bytes_per_pixel; | 981 | int clipmask_even_index, clipmask_odd_index, bytes_per_pixel; |
1029 | int clipmask_add, stretch_bytes; | 982 | int clipmask_add, stretch_bytes; |
1030 | 983 | ||
1031 | frame = usbvision->curFrame; | 984 | frame = usbvision->cur_frame; |
1032 | f_even = frame->data + (frame->v4l2_linesize * frame->curline); | 985 | f_even = frame->data + (frame->v4l2_linesize * frame->curline); |
1033 | f_odd = f_even + frame->v4l2_linesize * usbvision->stretch_height; | 986 | f_odd = f_even + frame->v4l2_linesize * usbvision->stretch_height; |
1034 | 987 | ||
@@ -1040,18 +993,17 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision | |||
1040 | clipmask_even_index = frame->curline * MAX_FRAME_WIDTH; | 993 | clipmask_even_index = frame->curline * MAX_FRAME_WIDTH; |
1041 | clipmask_odd_index = clipmask_even_index + MAX_FRAME_WIDTH; | 994 | clipmask_odd_index = clipmask_even_index + MAX_FRAME_WIDTH; |
1042 | clipmask_add = usbvision->stretch_width; | 995 | clipmask_add = usbvision->stretch_width; |
1043 | pixel_per_line = frame->isocHeader.frameWidth; | 996 | pixel_per_line = frame->isoc_header.frame_width; |
1044 | 997 | ||
1045 | if (scratch_len(usbvision) < (int)pixel_per_line * 3) { | 998 | if (scratch_len(usbvision) < (int)pixel_per_line * 3) { |
1046 | //printk(KERN_DEBUG "out of data, need %d\n", len); | 999 | /* printk(KERN_DEBUG "out of data, need %d\n", len); */ |
1047 | return ParseState_Out; | 1000 | return parse_state_out; |
1048 | } | 1001 | } |
1049 | 1002 | ||
1050 | if ((frame->curline + 1) >= frame->frmheight) { | 1003 | if ((frame->curline + 1) >= frame->frmheight) |
1051 | return ParseState_NextFrame; | 1004 | return parse_state_next_frame; |
1052 | } | ||
1053 | 1005 | ||
1054 | block_split = (pixel_per_line%y_block_size) ? 1 : 0; //are some blocks splitted into different lines? | 1006 | block_split = (pixel_per_line%y_block_size) ? 1 : 0; /* are some blocks splitted into different lines? */ |
1055 | 1007 | ||
1056 | y_odd_offset = (pixel_per_line / y_block_size) * (y_block_size + uv_block_size) | 1008 | y_odd_offset = (pixel_per_line / y_block_size) * (y_block_size + uv_block_size) |
1057 | + block_split * uv_block_size; | 1009 | + block_split * uv_block_size; |
@@ -1061,31 +1013,27 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision | |||
1061 | scratch_set_extra_ptr(usbvision, &v_ptr, y_odd_offset | 1013 | scratch_set_extra_ptr(usbvision, &v_ptr, y_odd_offset |
1062 | + (4 - block_split) * sub_block_size); | 1014 | + (4 - block_split) * sub_block_size); |
1063 | 1015 | ||
1064 | for (block = 0; block < (pixel_per_line / sub_block_size); | 1016 | for (block = 0; block < (pixel_per_line / sub_block_size); block++) { |
1065 | block++) { | 1017 | for (pixel = 0; pixel < sub_block_size; pixel += 2) { |
1066 | |||
1067 | |||
1068 | for (pixel = 0; pixel < sub_block_size; pixel +=2) { | ||
1069 | scratch_get(usbvision, &y[0], 2); | 1018 | scratch_get(usbvision, &y[0], 2); |
1070 | scratch_get_extra(usbvision, &u, &u_ptr, 1); | 1019 | scratch_get_extra(usbvision, &u, &u_ptr, 1); |
1071 | scratch_get_extra(usbvision, &v, &v_ptr, 1); | 1020 | scratch_get_extra(usbvision, &v, &v_ptr, 1); |
1072 | 1021 | ||
1073 | //I don't use the YUV_TO_RGB macro for better performance | 1022 | /* I don't use the YUV_TO_RGB macro for better performance */ |
1074 | v_ = v - 128; | 1023 | v_ = v - 128; |
1075 | u_ = u - 128; | 1024 | u_ = u - 128; |
1076 | vb = 132252 * v_; | 1025 | vb = 132252 * v_; |
1077 | uvg= -53281 * u_ - 25625 * v_; | 1026 | uvg = -53281 * u_ - 25625 * v_; |
1078 | ur = 104595 * u_; | 1027 | ur = 104595 * u_; |
1079 | 1028 | ||
1080 | if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { | 1029 | if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { |
1081 | *f_even++ = y[0]; | 1030 | *f_even++ = y[0]; |
1082 | *f_even++ = v; | 1031 | *f_even++ = v; |
1083 | } | 1032 | } else { |
1084 | else { | ||
1085 | y_ = 76284 * (y[0] - 16); | 1033 | y_ = 76284 * (y[0] - 16); |
1086 | 1034 | ||
1087 | b_ = (y_ + vb) >> 16; | 1035 | b_ = (y_ + vb) >> 16; |
1088 | g_ = (y_ + uvg)>> 16; | 1036 | g_ = (y_ + uvg) >> 16; |
1089 | r_ = (y_ + ur) >> 16; | 1037 | r_ = (y_ + ur) >> 16; |
1090 | 1038 | ||
1091 | switch (frame->v4l2_format.format) { | 1039 | switch (frame->v4l2_format.format) { |
@@ -1121,15 +1069,14 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision | |||
1121 | clipmask_even_index += clipmask_add; | 1069 | clipmask_even_index += clipmask_add; |
1122 | f_even += stretch_bytes; | 1070 | f_even += stretch_bytes; |
1123 | 1071 | ||
1124 | if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { | 1072 | if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { |
1125 | *f_even++ = y[1]; | 1073 | *f_even++ = y[1]; |
1126 | *f_even++ = u; | 1074 | *f_even++ = u; |
1127 | } | 1075 | } else { |
1128 | else { | ||
1129 | y_ = 76284 * (y[1] - 16); | 1076 | y_ = 76284 * (y[1] - 16); |
1130 | 1077 | ||
1131 | b_ = (y_ + vb) >> 16; | 1078 | b_ = (y_ + vb) >> 16; |
1132 | g_ = (y_ + uvg)>> 16; | 1079 | g_ = (y_ + uvg) >> 16; |
1133 | r_ = (y_ + ur) >> 16; | 1080 | r_ = (y_ + ur) >> 16; |
1134 | 1081 | ||
1135 | switch (frame->v4l2_format.format) { | 1082 | switch (frame->v4l2_format.format) { |
@@ -1167,15 +1114,14 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision | |||
1167 | 1114 | ||
1168 | scratch_get_extra(usbvision, &y[0], &y_ptr, 2); | 1115 | scratch_get_extra(usbvision, &y[0], &y_ptr, 2); |
1169 | 1116 | ||
1170 | if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { | 1117 | if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { |
1171 | *f_odd++ = y[0]; | 1118 | *f_odd++ = y[0]; |
1172 | *f_odd++ = v; | 1119 | *f_odd++ = v; |
1173 | } | 1120 | } else { |
1174 | else { | ||
1175 | y_ = 76284 * (y[0] - 16); | 1121 | y_ = 76284 * (y[0] - 16); |
1176 | 1122 | ||
1177 | b_ = (y_ + vb) >> 16; | 1123 | b_ = (y_ + vb) >> 16; |
1178 | g_ = (y_ + uvg)>> 16; | 1124 | g_ = (y_ + uvg) >> 16; |
1179 | r_ = (y_ + ur) >> 16; | 1125 | r_ = (y_ + ur) >> 16; |
1180 | 1126 | ||
1181 | switch (frame->v4l2_format.format) { | 1127 | switch (frame->v4l2_format.format) { |
@@ -1211,15 +1157,14 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision | |||
1211 | clipmask_odd_index += clipmask_add; | 1157 | clipmask_odd_index += clipmask_add; |
1212 | f_odd += stretch_bytes; | 1158 | f_odd += stretch_bytes; |
1213 | 1159 | ||
1214 | if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { | 1160 | if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { |
1215 | *f_odd++ = y[1]; | 1161 | *f_odd++ = y[1]; |
1216 | *f_odd++ = u; | 1162 | *f_odd++ = u; |
1217 | } | 1163 | } else { |
1218 | else { | ||
1219 | y_ = 76284 * (y[1] - 16); | 1164 | y_ = 76284 * (y[1] - 16); |
1220 | 1165 | ||
1221 | b_ = (y_ + vb) >> 16; | 1166 | b_ = (y_ + vb) >> 16; |
1222 | g_ = (y_ + uvg)>> 16; | 1167 | g_ = (y_ + uvg) >> 16; |
1223 | r_ = (y_ + ur) >> 16; | 1168 | r_ = (y_ + ur) >> 16; |
1224 | 1169 | ||
1225 | switch (frame->v4l2_format.format) { | 1170 | switch (frame->v4l2_format.format) { |
@@ -1256,7 +1201,7 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision | |||
1256 | f_odd += stretch_bytes; | 1201 | f_odd += stretch_bytes; |
1257 | } | 1202 | } |
1258 | 1203 | ||
1259 | scratch_rm_old(usbvision,y_step[block % y_step_size] * sub_block_size); | 1204 | scratch_rm_old(usbvision, y_step[block % y_step_size] * sub_block_size); |
1260 | scratch_inc_extra_ptr(&y_ptr, y_step[(block + 2 * block_split) % y_step_size] | 1205 | scratch_inc_extra_ptr(&y_ptr, y_step[(block + 2 * block_split) % y_step_size] |
1261 | * sub_block_size); | 1206 | * sub_block_size); |
1262 | scratch_inc_extra_ptr(&u_ptr, uv_step[block % uv_step_size] | 1207 | scratch_inc_extra_ptr(&u_ptr, uv_step[block % uv_step_size] |
@@ -1272,9 +1217,8 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision | |||
1272 | *pcopylen += frame->v4l2_linesize * 2 * usbvision->stretch_height; | 1217 | *pcopylen += frame->v4l2_linesize * 2 * usbvision->stretch_height; |
1273 | 1218 | ||
1274 | if (frame->curline >= frame->frmheight) | 1219 | if (frame->curline >= frame->frmheight) |
1275 | return ParseState_NextFrame; | 1220 | return parse_state_next_frame; |
1276 | else | 1221 | return parse_state_continue; |
1277 | return ParseState_Continue; | ||
1278 | } | 1222 | } |
1279 | 1223 | ||
1280 | /* | 1224 | /* |
@@ -1288,53 +1232,43 @@ static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision | |||
1288 | static void usbvision_parse_data(struct usb_usbvision *usbvision) | 1232 | static void usbvision_parse_data(struct usb_usbvision *usbvision) |
1289 | { | 1233 | { |
1290 | struct usbvision_frame *frame; | 1234 | struct usbvision_frame *frame; |
1291 | enum ParseState newstate; | 1235 | enum parse_state newstate; |
1292 | long copylen = 0; | 1236 | long copylen = 0; |
1293 | unsigned long lock_flags; | 1237 | unsigned long lock_flags; |
1294 | 1238 | ||
1295 | frame = usbvision->curFrame; | 1239 | frame = usbvision->cur_frame; |
1296 | 1240 | ||
1297 | PDEBUG(DBG_PARSE, "parsing len=%d\n", scratch_len(usbvision)); | 1241 | PDEBUG(DBG_PARSE, "parsing len=%d\n", scratch_len(usbvision)); |
1298 | 1242 | ||
1299 | while (1) { | 1243 | while (1) { |
1300 | 1244 | newstate = parse_state_out; | |
1301 | newstate = ParseState_Out; | ||
1302 | if (scratch_len(usbvision)) { | 1245 | if (scratch_len(usbvision)) { |
1303 | if (frame->scanstate == ScanState_Scanning) { | 1246 | if (frame->scanstate == scan_state_scanning) { |
1304 | newstate = usbvision_find_header(usbvision); | 1247 | newstate = usbvision_find_header(usbvision); |
1305 | } | 1248 | } else if (frame->scanstate == scan_state_lines) { |
1306 | else if (frame->scanstate == ScanState_Lines) { | 1249 | if (usbvision->isoc_mode == ISOC_MODE_YUV420) |
1307 | if (usbvision->isocMode == ISOC_MODE_YUV420) { | ||
1308 | newstate = usbvision_parse_lines_420(usbvision, ©len); | 1250 | newstate = usbvision_parse_lines_420(usbvision, ©len); |
1309 | } | 1251 | else if (usbvision->isoc_mode == ISOC_MODE_YUV422) |
1310 | else if (usbvision->isocMode == ISOC_MODE_YUV422) { | ||
1311 | newstate = usbvision_parse_lines_422(usbvision, ©len); | 1252 | newstate = usbvision_parse_lines_422(usbvision, ©len); |
1312 | } | 1253 | else if (usbvision->isoc_mode == ISOC_MODE_COMPRESS) |
1313 | else if (usbvision->isocMode == ISOC_MODE_COMPRESS) { | ||
1314 | newstate = usbvision_parse_compress(usbvision, ©len); | 1254 | newstate = usbvision_parse_compress(usbvision, ©len); |
1315 | } | ||
1316 | |||
1317 | } | 1255 | } |
1318 | } | 1256 | } |
1319 | if (newstate == ParseState_Continue) { | 1257 | if (newstate == parse_state_continue) |
1320 | continue; | 1258 | continue; |
1321 | } | 1259 | if ((newstate == parse_state_next_frame) || (newstate == parse_state_out)) |
1322 | else if ((newstate == ParseState_NextFrame) || (newstate == ParseState_Out)) { | ||
1323 | break; | 1260 | break; |
1324 | } | 1261 | return; /* parse_state_end_parse */ |
1325 | else { | ||
1326 | return; /* ParseState_EndParse */ | ||
1327 | } | ||
1328 | } | 1262 | } |
1329 | 1263 | ||
1330 | if (newstate == ParseState_NextFrame) { | 1264 | if (newstate == parse_state_next_frame) { |
1331 | frame->grabstate = FrameState_Done; | 1265 | frame->grabstate = frame_state_done; |
1332 | do_gettimeofday(&(frame->timestamp)); | 1266 | do_gettimeofday(&(frame->timestamp)); |
1333 | frame->sequence = usbvision->frame_num; | 1267 | frame->sequence = usbvision->frame_num; |
1334 | 1268 | ||
1335 | spin_lock_irqsave(&usbvision->queue_lock, lock_flags); | 1269 | spin_lock_irqsave(&usbvision->queue_lock, lock_flags); |
1336 | list_move_tail(&(frame->frame), &usbvision->outqueue); | 1270 | list_move_tail(&(frame->frame), &usbvision->outqueue); |
1337 | usbvision->curFrame = NULL; | 1271 | usbvision->cur_frame = NULL; |
1338 | spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags); | 1272 | spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags); |
1339 | 1273 | ||
1340 | usbvision->frame_num++; | 1274 | usbvision->frame_num++; |
@@ -1344,10 +1278,9 @@ static void usbvision_parse_data(struct usb_usbvision *usbvision) | |||
1344 | PDEBUG(DBG_PARSE, "Wake up !"); | 1278 | PDEBUG(DBG_PARSE, "Wake up !"); |
1345 | wake_up_interruptible(&usbvision->wait_frame); | 1279 | wake_up_interruptible(&usbvision->wait_frame); |
1346 | } | 1280 | } |
1281 | } else { | ||
1282 | frame->grabstate = frame_state_grabbing; | ||
1347 | } | 1283 | } |
1348 | else | ||
1349 | frame->grabstate = FrameState_Grabbing; | ||
1350 | |||
1351 | 1284 | ||
1352 | /* Update the frame's uncompressed length. */ | 1285 | /* Update the frame's uncompressed length. */ |
1353 | frame->scanlength += copylen; | 1286 | frame->scanlength += copylen; |
@@ -1370,34 +1303,32 @@ static int usbvision_compress_isochronous(struct usb_usbvision *usbvision, | |||
1370 | packet_data = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | 1303 | packet_data = urb->transfer_buffer + urb->iso_frame_desc[i].offset; |
1371 | 1304 | ||
1372 | /* Detect and ignore errored packets */ | 1305 | /* Detect and ignore errored packets */ |
1373 | if (packet_stat) { // packet_stat != 0 ????????????? | 1306 | if (packet_stat) { /* packet_stat != 0 ????????????? */ |
1374 | PDEBUG(DBG_ISOC, "data error: [%d] len=%d, status=%X", i, packet_len, packet_stat); | 1307 | PDEBUG(DBG_ISOC, "data error: [%d] len=%d, status=%X", i, packet_len, packet_stat); |
1375 | usbvision->isocErrCount++; | 1308 | usbvision->isoc_err_count++; |
1376 | continue; | 1309 | continue; |
1377 | } | 1310 | } |
1378 | 1311 | ||
1379 | /* Detect and ignore empty packets */ | 1312 | /* Detect and ignore empty packets */ |
1380 | if (packet_len < 0) { | 1313 | if (packet_len < 0) { |
1381 | PDEBUG(DBG_ISOC, "error packet [%d]", i); | 1314 | PDEBUG(DBG_ISOC, "error packet [%d]", i); |
1382 | usbvision->isocSkipCount++; | 1315 | usbvision->isoc_skip_count++; |
1383 | continue; | 1316 | continue; |
1384 | } | 1317 | } else if (packet_len == 0) { /* Frame end ????? */ |
1385 | else if (packet_len == 0) { /* Frame end ????? */ | ||
1386 | PDEBUG(DBG_ISOC, "null packet [%d]", i); | 1318 | PDEBUG(DBG_ISOC, "null packet [%d]", i); |
1387 | usbvision->isocstate=IsocState_NoFrame; | 1319 | usbvision->isocstate = isoc_state_no_frame; |
1388 | usbvision->isocSkipCount++; | 1320 | usbvision->isoc_skip_count++; |
1389 | continue; | 1321 | continue; |
1390 | } | 1322 | } else if (packet_len > usbvision->isoc_packet_size) { |
1391 | else if (packet_len > usbvision->isocPacketSize) { | 1323 | PDEBUG(DBG_ISOC, "packet[%d] > isoc_packet_size", i); |
1392 | PDEBUG(DBG_ISOC, "packet[%d] > isocPacketSize", i); | 1324 | usbvision->isoc_skip_count++; |
1393 | usbvision->isocSkipCount++; | ||
1394 | continue; | 1325 | continue; |
1395 | } | 1326 | } |
1396 | 1327 | ||
1397 | PDEBUG(DBG_ISOC, "packet ok [%d] len=%d", i, packet_len); | 1328 | PDEBUG(DBG_ISOC, "packet ok [%d] len=%d", i, packet_len); |
1398 | 1329 | ||
1399 | if (usbvision->isocstate==IsocState_NoFrame) { //new frame begins | 1330 | if (usbvision->isocstate == isoc_state_no_frame) { /* new frame begins */ |
1400 | usbvision->isocstate=IsocState_InFrame; | 1331 | usbvision->isocstate = isoc_state_in_frame; |
1401 | scratch_mark_header(usbvision); | 1332 | scratch_mark_header(usbvision); |
1402 | usbvision_measure_bandwidth(usbvision); | 1333 | usbvision_measure_bandwidth(usbvision); |
1403 | PDEBUG(DBG_ISOC, "packet with header"); | 1334 | PDEBUG(DBG_ISOC, "packet with header"); |
@@ -1412,7 +1343,6 @@ static int usbvision_compress_isochronous(struct usb_usbvision *usbvision, | |||
1412 | * your favorite evil here. | 1343 | * your favorite evil here. |
1413 | */ | 1344 | */ |
1414 | if (scratch_free(usbvision) < packet_len) { | 1345 | if (scratch_free(usbvision) < packet_len) { |
1415 | |||
1416 | usbvision->scratch_ovf_count++; | 1346 | usbvision->scratch_ovf_count++; |
1417 | PDEBUG(DBG_ISOC, "scratch buf overflow! scr_len: %d, n: %d", | 1347 | PDEBUG(DBG_ISOC, "scratch buf overflow! scr_len: %d, n: %d", |
1418 | scratch_len(usbvision), packet_len); | 1348 | scratch_len(usbvision), packet_len); |
@@ -1422,12 +1352,13 @@ static int usbvision_compress_isochronous(struct usb_usbvision *usbvision, | |||
1422 | /* Now we know that there is enough room in scratch buffer */ | 1352 | /* Now we know that there is enough room in scratch buffer */ |
1423 | scratch_put(usbvision, packet_data, packet_len); | 1353 | scratch_put(usbvision, packet_data, packet_len); |
1424 | totlen += packet_len; | 1354 | totlen += packet_len; |
1425 | usbvision->isocDataCount += packet_len; | 1355 | usbvision->isoc_data_count += packet_len; |
1426 | usbvision->isocPacketCount++; | 1356 | usbvision->isoc_packet_count++; |
1427 | } | 1357 | } |
1428 | #if ENABLE_HEXDUMP | 1358 | #if ENABLE_HEXDUMP |
1429 | if (totlen > 0) { | 1359 | if (totlen > 0) { |
1430 | static int foo; | 1360 | static int foo; |
1361 | |||
1431 | if (foo < 1) { | 1362 | if (foo < 1) { |
1432 | printk(KERN_DEBUG "+%d.\n", usbvision->scratchlen); | 1363 | printk(KERN_DEBUG "+%d.\n", usbvision->scratchlen); |
1433 | usbvision_hexdump(data0, (totlen > 64) ? 64 : totlen); | 1364 | usbvision_hexdump(data0, (totlen > 64) ? 64 : totlen); |
@@ -1435,16 +1366,16 @@ static int usbvision_compress_isochronous(struct usb_usbvision *usbvision, | |||
1435 | } | 1366 | } |
1436 | } | 1367 | } |
1437 | #endif | 1368 | #endif |
1438 | return totlen; | 1369 | return totlen; |
1439 | } | 1370 | } |
1440 | 1371 | ||
1441 | static void usbvision_isocIrq(struct urb *urb) | 1372 | static void usbvision_isoc_irq(struct urb *urb) |
1442 | { | 1373 | { |
1443 | int errCode = 0; | 1374 | int err_code = 0; |
1444 | int len; | 1375 | int len; |
1445 | struct usb_usbvision *usbvision = urb->context; | 1376 | struct usb_usbvision *usbvision = urb->context; |
1446 | int i; | 1377 | int i; |
1447 | unsigned long startTime = jiffies; | 1378 | unsigned long start_time = jiffies; |
1448 | struct usbvision_frame **f; | 1379 | struct usbvision_frame **f; |
1449 | 1380 | ||
1450 | /* We don't want to do anything if we are about to be removed! */ | 1381 | /* We don't want to do anything if we are about to be removed! */ |
@@ -1452,18 +1383,17 @@ static void usbvision_isocIrq(struct urb *urb) | |||
1452 | return; | 1383 | return; |
1453 | 1384 | ||
1454 | /* any urb with wrong status is ignored without acknowledgement */ | 1385 | /* any urb with wrong status is ignored without acknowledgement */ |
1455 | if (urb->status == -ENOENT) { | 1386 | if (urb->status == -ENOENT) |
1456 | return; | 1387 | return; |
1457 | } | ||
1458 | 1388 | ||
1459 | f = &usbvision->curFrame; | 1389 | f = &usbvision->cur_frame; |
1460 | 1390 | ||
1461 | /* Manage streaming interruption */ | 1391 | /* Manage streaming interruption */ |
1462 | if (usbvision->streaming == Stream_Interrupt) { | 1392 | if (usbvision->streaming == stream_interrupt) { |
1463 | usbvision->streaming = Stream_Idle; | 1393 | usbvision->streaming = stream_idle; |
1464 | if ((*f)) { | 1394 | if ((*f)) { |
1465 | (*f)->grabstate = FrameState_Ready; | 1395 | (*f)->grabstate = frame_state_ready; |
1466 | (*f)->scanstate = ScanState_Scanning; | 1396 | (*f)->scanstate = scan_state_scanning; |
1467 | } | 1397 | } |
1468 | PDEBUG(DBG_IRQ, "stream interrupted"); | 1398 | PDEBUG(DBG_IRQ, "stream interrupted"); |
1469 | wake_up_interruptible(&usbvision->wait_stream); | 1399 | wake_up_interruptible(&usbvision->wait_stream); |
@@ -1472,35 +1402,32 @@ static void usbvision_isocIrq(struct urb *urb) | |||
1472 | /* Copy the data received into our scratch buffer */ | 1402 | /* Copy the data received into our scratch buffer */ |
1473 | len = usbvision_compress_isochronous(usbvision, urb); | 1403 | len = usbvision_compress_isochronous(usbvision, urb); |
1474 | 1404 | ||
1475 | usbvision->isocUrbCount++; | 1405 | usbvision->isoc_urb_count++; |
1476 | usbvision->urb_length = len; | 1406 | usbvision->urb_length = len; |
1477 | 1407 | ||
1478 | if (usbvision->streaming == Stream_On) { | 1408 | if (usbvision->streaming == stream_on) { |
1479 | |||
1480 | /* If we collected enough data let's parse! */ | 1409 | /* If we collected enough data let's parse! */ |
1481 | if ((scratch_len(usbvision) > USBVISION_HEADER_LENGTH) && | 1410 | if (scratch_len(usbvision) > USBVISION_HEADER_LENGTH && |
1482 | (!list_empty(&(usbvision->inqueue))) ) { | 1411 | !list_empty(&(usbvision->inqueue))) { |
1483 | if (!(*f)) { | 1412 | if (!(*f)) { |
1484 | (*f) = list_entry(usbvision->inqueue.next, | 1413 | (*f) = list_entry(usbvision->inqueue.next, |
1485 | struct usbvision_frame, | 1414 | struct usbvision_frame, |
1486 | frame); | 1415 | frame); |
1487 | } | 1416 | } |
1488 | usbvision_parse_data(usbvision); | 1417 | usbvision_parse_data(usbvision); |
1489 | } | 1418 | } else { |
1490 | else { | 1419 | /* If we don't have a frame |
1491 | /*If we don't have a frame | ||
1492 | we're current working on, complain */ | 1420 | we're current working on, complain */ |
1493 | PDEBUG(DBG_IRQ, | 1421 | PDEBUG(DBG_IRQ, |
1494 | "received data, but no one needs it"); | 1422 | "received data, but no one needs it"); |
1495 | scratch_reset(usbvision); | 1423 | scratch_reset(usbvision); |
1496 | } | 1424 | } |
1497 | } | 1425 | } else { |
1498 | else { | ||
1499 | PDEBUG(DBG_IRQ, "received data, but no one needs it"); | 1426 | PDEBUG(DBG_IRQ, "received data, but no one needs it"); |
1500 | scratch_reset(usbvision); | 1427 | scratch_reset(usbvision); |
1501 | } | 1428 | } |
1502 | 1429 | ||
1503 | usbvision->timeInIrq += jiffies - startTime; | 1430 | usbvision->time_in_irq += jiffies - start_time; |
1504 | 1431 | ||
1505 | for (i = 0; i < USBVISION_URB_FRAMES; i++) { | 1432 | for (i = 0; i < USBVISION_URB_FRAMES; i++) { |
1506 | urb->iso_frame_desc[i].status = 0; | 1433 | urb->iso_frame_desc[i].status = 0; |
@@ -1509,12 +1436,12 @@ static void usbvision_isocIrq(struct urb *urb) | |||
1509 | 1436 | ||
1510 | urb->status = 0; | 1437 | urb->status = 0; |
1511 | urb->dev = usbvision->dev; | 1438 | urb->dev = usbvision->dev; |
1512 | errCode = usb_submit_urb (urb, GFP_ATOMIC); | 1439 | err_code = usb_submit_urb(urb, GFP_ATOMIC); |
1513 | 1440 | ||
1514 | if(errCode) { | 1441 | if (err_code) { |
1515 | dev_err(&usbvision->dev->dev, | 1442 | dev_err(&usbvision->dev->dev, |
1516 | "%s: usb_submit_urb failed: error %d\n", | 1443 | "%s: usb_submit_urb failed: error %d\n", |
1517 | __func__, errCode); | 1444 | __func__, err_code); |
1518 | } | 1445 | } |
1519 | 1446 | ||
1520 | return; | 1447 | return; |
@@ -1533,21 +1460,21 @@ static void usbvision_isocIrq(struct urb *urb) | |||
1533 | 1460 | ||
1534 | int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg) | 1461 | int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg) |
1535 | { | 1462 | { |
1536 | int errCode = 0; | 1463 | int err_code = 0; |
1537 | unsigned char buffer[1]; | 1464 | unsigned char buffer[1]; |
1538 | 1465 | ||
1539 | if (!USBVISION_IS_OPERATIONAL(usbvision)) | 1466 | if (!USBVISION_IS_OPERATIONAL(usbvision)) |
1540 | return -1; | 1467 | return -1; |
1541 | 1468 | ||
1542 | errCode = usb_control_msg(usbvision->dev, usb_rcvctrlpipe(usbvision->dev, 1), | 1469 | err_code = usb_control_msg(usbvision->dev, usb_rcvctrlpipe(usbvision->dev, 1), |
1543 | USBVISION_OP_CODE, | 1470 | USBVISION_OP_CODE, |
1544 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, | 1471 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, |
1545 | 0, (__u16) reg, buffer, 1, HZ); | 1472 | 0, (__u16) reg, buffer, 1, HZ); |
1546 | 1473 | ||
1547 | if (errCode < 0) { | 1474 | if (err_code < 0) { |
1548 | dev_err(&usbvision->dev->dev, | 1475 | dev_err(&usbvision->dev->dev, |
1549 | "%s: failed: error %d\n", __func__, errCode); | 1476 | "%s: failed: error %d\n", __func__, err_code); |
1550 | return errCode; | 1477 | return err_code; |
1551 | } | 1478 | } |
1552 | return buffer[0]; | 1479 | return buffer[0]; |
1553 | } | 1480 | } |
@@ -1563,179 +1490,176 @@ int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg) | |||
1563 | int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg, | 1490 | int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg, |
1564 | unsigned char value) | 1491 | unsigned char value) |
1565 | { | 1492 | { |
1566 | int errCode = 0; | 1493 | int err_code = 0; |
1567 | 1494 | ||
1568 | if (!USBVISION_IS_OPERATIONAL(usbvision)) | 1495 | if (!USBVISION_IS_OPERATIONAL(usbvision)) |
1569 | return 0; | 1496 | return 0; |
1570 | 1497 | ||
1571 | errCode = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1), | 1498 | err_code = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1), |
1572 | USBVISION_OP_CODE, | 1499 | USBVISION_OP_CODE, |
1573 | USB_DIR_OUT | USB_TYPE_VENDOR | | 1500 | USB_DIR_OUT | USB_TYPE_VENDOR | |
1574 | USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ); | 1501 | USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ); |
1575 | 1502 | ||
1576 | if (errCode < 0) { | 1503 | if (err_code < 0) { |
1577 | dev_err(&usbvision->dev->dev, | 1504 | dev_err(&usbvision->dev->dev, |
1578 | "%s: failed: error %d\n", __func__, errCode); | 1505 | "%s: failed: error %d\n", __func__, err_code); |
1579 | } | 1506 | } |
1580 | return errCode; | 1507 | return err_code; |
1581 | } | 1508 | } |
1582 | 1509 | ||
1583 | 1510 | ||
1584 | static void usbvision_ctrlUrb_complete(struct urb *urb) | 1511 | static void usbvision_ctrl_urb_complete(struct urb *urb) |
1585 | { | 1512 | { |
1586 | struct usb_usbvision *usbvision = (struct usb_usbvision *)urb->context; | 1513 | struct usb_usbvision *usbvision = (struct usb_usbvision *)urb->context; |
1587 | 1514 | ||
1588 | PDEBUG(DBG_IRQ, ""); | 1515 | PDEBUG(DBG_IRQ, ""); |
1589 | usbvision->ctrlUrbBusy = 0; | 1516 | usbvision->ctrl_urb_busy = 0; |
1590 | if (waitqueue_active(&usbvision->ctrlUrb_wq)) { | 1517 | if (waitqueue_active(&usbvision->ctrl_urb_wq)) |
1591 | wake_up_interruptible(&usbvision->ctrlUrb_wq); | 1518 | wake_up_interruptible(&usbvision->ctrl_urb_wq); |
1592 | } | ||
1593 | } | 1519 | } |
1594 | 1520 | ||
1595 | 1521 | ||
1596 | static int usbvision_write_reg_irq(struct usb_usbvision *usbvision,int address, | 1522 | static int usbvision_write_reg_irq(struct usb_usbvision *usbvision, int address, |
1597 | unsigned char *data, int len) | 1523 | unsigned char *data, int len) |
1598 | { | 1524 | { |
1599 | int errCode = 0; | 1525 | int err_code = 0; |
1600 | 1526 | ||
1601 | PDEBUG(DBG_IRQ, ""); | 1527 | PDEBUG(DBG_IRQ, ""); |
1602 | if (len > 8) { | 1528 | if (len > 8) |
1603 | return -EFAULT; | 1529 | return -EFAULT; |
1604 | } | 1530 | if (usbvision->ctrl_urb_busy) |
1605 | if (usbvision->ctrlUrbBusy) { | ||
1606 | return -EBUSY; | 1531 | return -EBUSY; |
1607 | } | 1532 | usbvision->ctrl_urb_busy = 1; |
1608 | usbvision->ctrlUrbBusy = 1; | 1533 | |
1609 | 1534 | usbvision->ctrl_urb_setup.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; | |
1610 | usbvision->ctrlUrbSetup.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; | 1535 | usbvision->ctrl_urb_setup.bRequest = USBVISION_OP_CODE; |
1611 | usbvision->ctrlUrbSetup.bRequest = USBVISION_OP_CODE; | 1536 | usbvision->ctrl_urb_setup.wValue = 0; |
1612 | usbvision->ctrlUrbSetup.wValue = 0; | 1537 | usbvision->ctrl_urb_setup.wIndex = cpu_to_le16(address); |
1613 | usbvision->ctrlUrbSetup.wIndex = cpu_to_le16(address); | 1538 | usbvision->ctrl_urb_setup.wLength = cpu_to_le16(len); |
1614 | usbvision->ctrlUrbSetup.wLength = cpu_to_le16(len); | 1539 | usb_fill_control_urb(usbvision->ctrl_urb, usbvision->dev, |
1615 | usb_fill_control_urb (usbvision->ctrlUrb, usbvision->dev, | ||
1616 | usb_sndctrlpipe(usbvision->dev, 1), | 1540 | usb_sndctrlpipe(usbvision->dev, 1), |
1617 | (unsigned char *)&usbvision->ctrlUrbSetup, | 1541 | (unsigned char *)&usbvision->ctrl_urb_setup, |
1618 | (void *)usbvision->ctrlUrbBuffer, len, | 1542 | (void *)usbvision->ctrl_urb_buffer, len, |
1619 | usbvision_ctrlUrb_complete, | 1543 | usbvision_ctrl_urb_complete, |
1620 | (void *)usbvision); | 1544 | (void *)usbvision); |
1621 | 1545 | ||
1622 | memcpy(usbvision->ctrlUrbBuffer, data, len); | 1546 | memcpy(usbvision->ctrl_urb_buffer, data, len); |
1623 | 1547 | ||
1624 | errCode = usb_submit_urb(usbvision->ctrlUrb, GFP_ATOMIC); | 1548 | err_code = usb_submit_urb(usbvision->ctrl_urb, GFP_ATOMIC); |
1625 | if (errCode < 0) { | 1549 | if (err_code < 0) { |
1626 | // error in usb_submit_urb() | 1550 | /* error in usb_submit_urb() */ |
1627 | usbvision->ctrlUrbBusy = 0; | 1551 | usbvision->ctrl_urb_busy = 0; |
1628 | } | 1552 | } |
1629 | PDEBUG(DBG_IRQ, "submit %d byte: error %d", len, errCode); | 1553 | PDEBUG(DBG_IRQ, "submit %d byte: error %d", len, err_code); |
1630 | return errCode; | 1554 | return err_code; |
1631 | } | 1555 | } |
1632 | 1556 | ||
1633 | 1557 | ||
1634 | static int usbvision_init_compression(struct usb_usbvision *usbvision) | 1558 | static int usbvision_init_compression(struct usb_usbvision *usbvision) |
1635 | { | 1559 | { |
1636 | int errCode = 0; | 1560 | int err_code = 0; |
1637 | 1561 | ||
1638 | usbvision->lastIsocFrameNum = -1; | 1562 | usbvision->last_isoc_frame_num = -1; |
1639 | usbvision->isocDataCount = 0; | 1563 | usbvision->isoc_data_count = 0; |
1640 | usbvision->isocPacketCount = 0; | 1564 | usbvision->isoc_packet_count = 0; |
1641 | usbvision->isocSkipCount = 0; | 1565 | usbvision->isoc_skip_count = 0; |
1642 | usbvision->comprLevel = 50; | 1566 | usbvision->compr_level = 50; |
1643 | usbvision->lastComprLevel = -1; | 1567 | usbvision->last_compr_level = -1; |
1644 | usbvision->isocUrbCount = 0; | 1568 | usbvision->isoc_urb_count = 0; |
1645 | usbvision->requestIntra = 1; | 1569 | usbvision->request_intra = 1; |
1646 | usbvision->isocMeasureBandwidthCount = 0; | 1570 | usbvision->isoc_measure_bandwidth_count = 0; |
1647 | 1571 | ||
1648 | return errCode; | 1572 | return err_code; |
1649 | } | 1573 | } |
1650 | 1574 | ||
1651 | /* this function measures the used bandwidth since last call | 1575 | /* this function measures the used bandwidth since last call |
1652 | * return: 0 : no error | 1576 | * return: 0 : no error |
1653 | * sets usedBandwidth to 1-100 : 1-100% of full bandwidth resp. to isocPacketSize | 1577 | * sets used_bandwidth to 1-100 : 1-100% of full bandwidth resp. to isoc_packet_size |
1654 | */ | 1578 | */ |
1655 | static int usbvision_measure_bandwidth (struct usb_usbvision *usbvision) | 1579 | static int usbvision_measure_bandwidth(struct usb_usbvision *usbvision) |
1656 | { | 1580 | { |
1657 | int errCode = 0; | 1581 | int err_code = 0; |
1658 | 1582 | ||
1659 | if (usbvision->isocMeasureBandwidthCount < 2) { // this gives an average bandwidth of 3 frames | 1583 | if (usbvision->isoc_measure_bandwidth_count < 2) { /* this gives an average bandwidth of 3 frames */ |
1660 | usbvision->isocMeasureBandwidthCount++; | 1584 | usbvision->isoc_measure_bandwidth_count++; |
1661 | return errCode; | 1585 | return err_code; |
1662 | } | 1586 | } |
1663 | if ((usbvision->isocPacketSize > 0) && (usbvision->isocPacketCount > 0)) { | 1587 | if ((usbvision->isoc_packet_size > 0) && (usbvision->isoc_packet_count > 0)) { |
1664 | usbvision->usedBandwidth = usbvision->isocDataCount / | 1588 | usbvision->used_bandwidth = usbvision->isoc_data_count / |
1665 | (usbvision->isocPacketCount + usbvision->isocSkipCount) * | 1589 | (usbvision->isoc_packet_count + usbvision->isoc_skip_count) * |
1666 | 100 / usbvision->isocPacketSize; | 1590 | 100 / usbvision->isoc_packet_size; |
1667 | } | 1591 | } |
1668 | usbvision->isocMeasureBandwidthCount = 0; | 1592 | usbvision->isoc_measure_bandwidth_count = 0; |
1669 | usbvision->isocDataCount = 0; | 1593 | usbvision->isoc_data_count = 0; |
1670 | usbvision->isocPacketCount = 0; | 1594 | usbvision->isoc_packet_count = 0; |
1671 | usbvision->isocSkipCount = 0; | 1595 | usbvision->isoc_skip_count = 0; |
1672 | return errCode; | 1596 | return err_code; |
1673 | } | 1597 | } |
1674 | 1598 | ||
1675 | static int usbvision_adjust_compression (struct usb_usbvision *usbvision) | 1599 | static int usbvision_adjust_compression(struct usb_usbvision *usbvision) |
1676 | { | 1600 | { |
1677 | int errCode = 0; | 1601 | int err_code = 0; |
1678 | unsigned char buffer[6]; | 1602 | unsigned char buffer[6]; |
1679 | 1603 | ||
1680 | PDEBUG(DBG_IRQ, ""); | 1604 | PDEBUG(DBG_IRQ, ""); |
1681 | if ((adjustCompression) && (usbvision->usedBandwidth > 0)) { | 1605 | if ((adjust_compression) && (usbvision->used_bandwidth > 0)) { |
1682 | usbvision->comprLevel += (usbvision->usedBandwidth - 90) / 2; | 1606 | usbvision->compr_level += (usbvision->used_bandwidth - 90) / 2; |
1683 | RESTRICT_TO_RANGE(usbvision->comprLevel, 0, 100); | 1607 | RESTRICT_TO_RANGE(usbvision->compr_level, 0, 100); |
1684 | if (usbvision->comprLevel != usbvision->lastComprLevel) { | 1608 | if (usbvision->compr_level != usbvision->last_compr_level) { |
1685 | int distorsion; | 1609 | int distortion; |
1686 | if (usbvision->bridgeType == BRIDGE_NT1004 || usbvision->bridgeType == BRIDGE_NT1005) { | 1610 | |
1687 | buffer[0] = (unsigned char)(4 + 16 * usbvision->comprLevel / 100); // PCM Threshold 1 | 1611 | if (usbvision->bridge_type == BRIDGE_NT1004 || usbvision->bridge_type == BRIDGE_NT1005) { |
1688 | buffer[1] = (unsigned char)(4 + 8 * usbvision->comprLevel / 100); // PCM Threshold 2 | 1612 | buffer[0] = (unsigned char)(4 + 16 * usbvision->compr_level / 100); /* PCM Threshold 1 */ |
1689 | distorsion = 7 + 248 * usbvision->comprLevel / 100; | 1613 | buffer[1] = (unsigned char)(4 + 8 * usbvision->compr_level / 100); /* PCM Threshold 2 */ |
1690 | buffer[2] = (unsigned char)(distorsion & 0xFF); // Average distorsion Threshold (inter) | 1614 | distortion = 7 + 248 * usbvision->compr_level / 100; |
1691 | buffer[3] = (unsigned char)(distorsion & 0xFF); // Average distorsion Threshold (intra) | 1615 | buffer[2] = (unsigned char)(distortion & 0xFF); /* Average distortion Threshold (inter) */ |
1692 | distorsion = 1 + 42 * usbvision->comprLevel / 100; | 1616 | buffer[3] = (unsigned char)(distortion & 0xFF); /* Average distortion Threshold (intra) */ |
1693 | buffer[4] = (unsigned char)(distorsion & 0xFF); // Maximum distorsion Threshold (inter) | 1617 | distortion = 1 + 42 * usbvision->compr_level / 100; |
1694 | buffer[5] = (unsigned char)(distorsion & 0xFF); // Maximum distorsion Threshold (intra) | 1618 | buffer[4] = (unsigned char)(distortion & 0xFF); /* Maximum distortion Threshold (inter) */ |
1695 | } | 1619 | buffer[5] = (unsigned char)(distortion & 0xFF); /* Maximum distortion Threshold (intra) */ |
1696 | else { //BRIDGE_NT1003 | 1620 | } else { /* BRIDGE_NT1003 */ |
1697 | buffer[0] = (unsigned char)(4 + 16 * usbvision->comprLevel / 100); // PCM threshold 1 | 1621 | buffer[0] = (unsigned char)(4 + 16 * usbvision->compr_level / 100); /* PCM threshold 1 */ |
1698 | buffer[1] = (unsigned char)(4 + 8 * usbvision->comprLevel / 100); // PCM threshold 2 | 1622 | buffer[1] = (unsigned char)(4 + 8 * usbvision->compr_level / 100); /* PCM threshold 2 */ |
1699 | distorsion = 2 + 253 * usbvision->comprLevel / 100; | 1623 | distortion = 2 + 253 * usbvision->compr_level / 100; |
1700 | buffer[2] = (unsigned char)(distorsion & 0xFF); // distorsion threshold bit0-7 | 1624 | buffer[2] = (unsigned char)(distortion & 0xFF); /* distortion threshold bit0-7 */ |
1701 | buffer[3] = 0; //(unsigned char)((distorsion >> 8) & 0x0F); // distorsion threshold bit 8-11 | 1625 | buffer[3] = 0; /* (unsigned char)((distortion >> 8) & 0x0F); distortion threshold bit 8-11 */ |
1702 | distorsion = 0 + 43 * usbvision->comprLevel / 100; | 1626 | distortion = 0 + 43 * usbvision->compr_level / 100; |
1703 | buffer[4] = (unsigned char)(distorsion & 0xFF); // maximum distorsion bit0-7 | 1627 | buffer[4] = (unsigned char)(distortion & 0xFF); /* maximum distortion bit0-7 */ |
1704 | buffer[5] = 0; //(unsigned char)((distorsion >> 8) & 0x01); // maximum distorsion bit 8 | 1628 | buffer[5] = 0; /* (unsigned char)((distortion >> 8) & 0x01); maximum distortion bit 8 */ |
1705 | } | 1629 | } |
1706 | errCode = usbvision_write_reg_irq(usbvision, USBVISION_PCM_THR1, buffer, 6); | 1630 | err_code = usbvision_write_reg_irq(usbvision, USBVISION_PCM_THR1, buffer, 6); |
1707 | if (errCode == 0){ | 1631 | if (err_code == 0) { |
1708 | PDEBUG(DBG_IRQ, "new compr params %#02x %#02x %#02x %#02x %#02x %#02x", buffer[0], | 1632 | PDEBUG(DBG_IRQ, "new compr params %#02x %#02x %#02x %#02x %#02x %#02x", buffer[0], |
1709 | buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); | 1633 | buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); |
1710 | usbvision->lastComprLevel = usbvision->comprLevel; | 1634 | usbvision->last_compr_level = usbvision->compr_level; |
1711 | } | 1635 | } |
1712 | } | 1636 | } |
1713 | } | 1637 | } |
1714 | return errCode; | 1638 | return err_code; |
1715 | } | 1639 | } |
1716 | 1640 | ||
1717 | static int usbvision_request_intra (struct usb_usbvision *usbvision) | 1641 | static int usbvision_request_intra(struct usb_usbvision *usbvision) |
1718 | { | 1642 | { |
1719 | int errCode = 0; | 1643 | int err_code = 0; |
1720 | unsigned char buffer[1]; | 1644 | unsigned char buffer[1]; |
1721 | 1645 | ||
1722 | PDEBUG(DBG_IRQ, ""); | 1646 | PDEBUG(DBG_IRQ, ""); |
1723 | usbvision->requestIntra = 1; | 1647 | usbvision->request_intra = 1; |
1724 | buffer[0] = 1; | 1648 | buffer[0] = 1; |
1725 | usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1); | 1649 | usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1); |
1726 | return errCode; | 1650 | return err_code; |
1727 | } | 1651 | } |
1728 | 1652 | ||
1729 | static int usbvision_unrequest_intra (struct usb_usbvision *usbvision) | 1653 | static int usbvision_unrequest_intra(struct usb_usbvision *usbvision) |
1730 | { | 1654 | { |
1731 | int errCode = 0; | 1655 | int err_code = 0; |
1732 | unsigned char buffer[1]; | 1656 | unsigned char buffer[1]; |
1733 | 1657 | ||
1734 | PDEBUG(DBG_IRQ, ""); | 1658 | PDEBUG(DBG_IRQ, ""); |
1735 | usbvision->requestIntra = 0; | 1659 | usbvision->request_intra = 0; |
1736 | buffer[0] = 0; | 1660 | buffer[0] = 0; |
1737 | usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1); | 1661 | usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1); |
1738 | return errCode; | 1662 | return err_code; |
1739 | } | 1663 | } |
1740 | 1664 | ||
1741 | /******************************* | 1665 | /******************************* |
@@ -1744,16 +1668,15 @@ static int usbvision_unrequest_intra (struct usb_usbvision *usbvision) | |||
1744 | 1668 | ||
1745 | int usbvision_power_off(struct usb_usbvision *usbvision) | 1669 | int usbvision_power_off(struct usb_usbvision *usbvision) |
1746 | { | 1670 | { |
1747 | int errCode = 0; | 1671 | int err_code = 0; |
1748 | 1672 | ||
1749 | PDEBUG(DBG_FUNC, ""); | 1673 | PDEBUG(DBG_FUNC, ""); |
1750 | 1674 | ||
1751 | errCode = usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN); | 1675 | err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN); |
1752 | if (errCode == 1) { | 1676 | if (err_code == 1) |
1753 | usbvision->power = 0; | 1677 | usbvision->power = 0; |
1754 | } | 1678 | PDEBUG(DBG_FUNC, "%s: err_code %d", (err_code != 1) ? "ERROR" : "power is off", err_code); |
1755 | PDEBUG(DBG_FUNC, "%s: errCode %d", (errCode!=1)?"ERROR":"power is off", errCode); | 1679 | return err_code; |
1756 | return errCode; | ||
1757 | } | 1680 | } |
1758 | 1681 | ||
1759 | /* | 1682 | /* |
@@ -1769,7 +1692,7 @@ static int usbvision_set_video_format(struct usb_usbvision *usbvision, int forma | |||
1769 | if (!USBVISION_IS_OPERATIONAL(usbvision)) | 1692 | if (!USBVISION_IS_OPERATIONAL(usbvision)) |
1770 | return 0; | 1693 | return 0; |
1771 | 1694 | ||
1772 | PDEBUG(DBG_FUNC, "isocMode %#02x", format); | 1695 | PDEBUG(DBG_FUNC, "isoc_mode %#02x", format); |
1773 | 1696 | ||
1774 | if ((format != ISOC_MODE_YUV422) | 1697 | if ((format != ISOC_MODE_YUV422) |
1775 | && (format != ISOC_MODE_YUV420) | 1698 | && (format != ISOC_MODE_YUV420) |
@@ -1778,8 +1701,8 @@ static int usbvision_set_video_format(struct usb_usbvision *usbvision, int forma | |||
1778 | format); | 1701 | format); |
1779 | format = ISOC_MODE_YUV420; | 1702 | format = ISOC_MODE_YUV420; |
1780 | } | 1703 | } |
1781 | value[0] = 0x0A; //TODO: See the effect of the filter | 1704 | value[0] = 0x0A; /* TODO: See the effect of the filter */ |
1782 | value[1] = format; // Sets the VO_MODE register which follows FILT_CONT | 1705 | value[1] = format; /* Sets the VO_MODE register which follows FILT_CONT */ |
1783 | rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1), | 1706 | rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1), |
1784 | USBVISION_OP_CODE, | 1707 | USBVISION_OP_CODE, |
1785 | USB_DIR_OUT | USB_TYPE_VENDOR | | 1708 | USB_DIR_OUT | USB_TYPE_VENDOR | |
@@ -1790,7 +1713,7 @@ static int usbvision_set_video_format(struct usb_usbvision *usbvision, int forma | |||
1790 | printk(KERN_ERR "%s: ERROR=%d. USBVISION stopped - " | 1713 | printk(KERN_ERR "%s: ERROR=%d. USBVISION stopped - " |
1791 | "reconnect or reload driver.\n", proc, rc); | 1714 | "reconnect or reload driver.\n", proc, rc); |
1792 | } | 1715 | } |
1793 | usbvision->isocMode = format; | 1716 | usbvision->isoc_mode = format; |
1794 | return rc; | 1717 | return rc; |
1795 | } | 1718 | } |
1796 | 1719 | ||
@@ -1802,96 +1725,88 @@ static int usbvision_set_video_format(struct usb_usbvision *usbvision, int forma | |||
1802 | int usbvision_set_output(struct usb_usbvision *usbvision, int width, | 1725 | int usbvision_set_output(struct usb_usbvision *usbvision, int width, |
1803 | int height) | 1726 | int height) |
1804 | { | 1727 | { |
1805 | int errCode = 0; | 1728 | int err_code = 0; |
1806 | int UsbWidth, UsbHeight; | 1729 | int usb_width, usb_height; |
1807 | unsigned int frameRate=0, frameDrop=0; | 1730 | unsigned int frame_rate = 0, frame_drop = 0; |
1808 | unsigned char value[4]; | 1731 | unsigned char value[4]; |
1809 | 1732 | ||
1810 | if (!USBVISION_IS_OPERATIONAL(usbvision)) { | 1733 | if (!USBVISION_IS_OPERATIONAL(usbvision)) |
1811 | return 0; | 1734 | return 0; |
1812 | } | ||
1813 | 1735 | ||
1814 | if (width > MAX_USB_WIDTH) { | 1736 | if (width > MAX_USB_WIDTH) { |
1815 | UsbWidth = width / 2; | 1737 | usb_width = width / 2; |
1816 | usbvision->stretch_width = 2; | 1738 | usbvision->stretch_width = 2; |
1817 | } | 1739 | } else { |
1818 | else { | 1740 | usb_width = width; |
1819 | UsbWidth = width; | ||
1820 | usbvision->stretch_width = 1; | 1741 | usbvision->stretch_width = 1; |
1821 | } | 1742 | } |
1822 | 1743 | ||
1823 | if (height > MAX_USB_HEIGHT) { | 1744 | if (height > MAX_USB_HEIGHT) { |
1824 | UsbHeight = height / 2; | 1745 | usb_height = height / 2; |
1825 | usbvision->stretch_height = 2; | 1746 | usbvision->stretch_height = 2; |
1826 | } | 1747 | } else { |
1827 | else { | 1748 | usb_height = height; |
1828 | UsbHeight = height; | ||
1829 | usbvision->stretch_height = 1; | 1749 | usbvision->stretch_height = 1; |
1830 | } | 1750 | } |
1831 | 1751 | ||
1832 | RESTRICT_TO_RANGE(UsbWidth, MIN_FRAME_WIDTH, MAX_USB_WIDTH); | 1752 | RESTRICT_TO_RANGE(usb_width, MIN_FRAME_WIDTH, MAX_USB_WIDTH); |
1833 | UsbWidth &= ~(MIN_FRAME_WIDTH-1); | 1753 | usb_width &= ~(MIN_FRAME_WIDTH-1); |
1834 | RESTRICT_TO_RANGE(UsbHeight, MIN_FRAME_HEIGHT, MAX_USB_HEIGHT); | 1754 | RESTRICT_TO_RANGE(usb_height, MIN_FRAME_HEIGHT, MAX_USB_HEIGHT); |
1835 | UsbHeight &= ~(1); | 1755 | usb_height &= ~(1); |
1836 | 1756 | ||
1837 | PDEBUG(DBG_FUNC, "usb %dx%d; screen %dx%d; stretch %dx%d", | 1757 | PDEBUG(DBG_FUNC, "usb %dx%d; screen %dx%d; stretch %dx%d", |
1838 | UsbWidth, UsbHeight, width, height, | 1758 | usb_width, usb_height, width, height, |
1839 | usbvision->stretch_width, usbvision->stretch_height); | 1759 | usbvision->stretch_width, usbvision->stretch_height); |
1840 | 1760 | ||
1841 | /* I'll not rewrite the same values */ | 1761 | /* I'll not rewrite the same values */ |
1842 | if ((UsbWidth != usbvision->curwidth) || (UsbHeight != usbvision->curheight)) { | 1762 | if ((usb_width != usbvision->curwidth) || (usb_height != usbvision->curheight)) { |
1843 | value[0] = UsbWidth & 0xff; //LSB | 1763 | value[0] = usb_width & 0xff; /* LSB */ |
1844 | value[1] = (UsbWidth >> 8) & 0x03; //MSB | 1764 | value[1] = (usb_width >> 8) & 0x03; /* MSB */ |
1845 | value[2] = UsbHeight & 0xff; //LSB | 1765 | value[2] = usb_height & 0xff; /* LSB */ |
1846 | value[3] = (UsbHeight >> 8) & 0x03; //MSB | 1766 | value[3] = (usb_height >> 8) & 0x03; /* MSB */ |
1847 | 1767 | ||
1848 | errCode = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1), | 1768 | err_code = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1), |
1849 | USBVISION_OP_CODE, | 1769 | USBVISION_OP_CODE, |
1850 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, | 1770 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, |
1851 | 0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ); | 1771 | 0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ); |
1852 | 1772 | ||
1853 | if (errCode < 0) { | 1773 | if (err_code < 0) { |
1854 | dev_err(&usbvision->dev->dev, | 1774 | dev_err(&usbvision->dev->dev, |
1855 | "%s failed: error %d\n", __func__, errCode); | 1775 | "%s failed: error %d\n", __func__, err_code); |
1856 | return errCode; | 1776 | return err_code; |
1857 | } | 1777 | } |
1858 | usbvision->curwidth = usbvision->stretch_width * UsbWidth; | 1778 | usbvision->curwidth = usbvision->stretch_width * usb_width; |
1859 | usbvision->curheight = usbvision->stretch_height * UsbHeight; | 1779 | usbvision->curheight = usbvision->stretch_height * usb_height; |
1860 | } | 1780 | } |
1861 | 1781 | ||
1862 | if (usbvision->isocMode == ISOC_MODE_YUV422) { | 1782 | if (usbvision->isoc_mode == ISOC_MODE_YUV422) |
1863 | frameRate = (usbvision->isocPacketSize * 1000) / (UsbWidth * UsbHeight * 2); | 1783 | frame_rate = (usbvision->isoc_packet_size * 1000) / (usb_width * usb_height * 2); |
1864 | } | 1784 | else if (usbvision->isoc_mode == ISOC_MODE_YUV420) |
1865 | else if (usbvision->isocMode == ISOC_MODE_YUV420) { | 1785 | frame_rate = (usbvision->isoc_packet_size * 1000) / ((usb_width * usb_height * 12) / 8); |
1866 | frameRate = (usbvision->isocPacketSize * 1000) / ((UsbWidth * UsbHeight * 12) / 8); | 1786 | else |
1867 | } | 1787 | frame_rate = FRAMERATE_MAX; |
1868 | else { | ||
1869 | frameRate = FRAMERATE_MAX; | ||
1870 | } | ||
1871 | 1788 | ||
1872 | if (usbvision->tvnormId & V4L2_STD_625_50) { | 1789 | if (usbvision->tvnorm_id & V4L2_STD_625_50) |
1873 | frameDrop = frameRate * 32 / 25 - 1; | 1790 | frame_drop = frame_rate * 32 / 25 - 1; |
1874 | } | 1791 | else if (usbvision->tvnorm_id & V4L2_STD_525_60) |
1875 | else if (usbvision->tvnormId & V4L2_STD_525_60) { | 1792 | frame_drop = frame_rate * 32 / 30 - 1; |
1876 | frameDrop = frameRate * 32 / 30 - 1; | ||
1877 | } | ||
1878 | 1793 | ||
1879 | RESTRICT_TO_RANGE(frameDrop, FRAMERATE_MIN, FRAMERATE_MAX); | 1794 | RESTRICT_TO_RANGE(frame_drop, FRAMERATE_MIN, FRAMERATE_MAX); |
1880 | 1795 | ||
1881 | PDEBUG(DBG_FUNC, "frameRate %d fps, frameDrop %d", frameRate, frameDrop); | 1796 | PDEBUG(DBG_FUNC, "frame_rate %d fps, frame_drop %d", frame_rate, frame_drop); |
1882 | 1797 | ||
1883 | frameDrop = FRAMERATE_MAX; // We can allow the maximum here, because dropping is controlled | 1798 | frame_drop = FRAMERATE_MAX; /* We can allow the maximum here, because dropping is controlled */ |
1884 | 1799 | ||
1885 | /* frameDrop = 7; => framePhase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ... | 1800 | /* frame_drop = 7; => frame_phase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ... |
1886 | => frameSkip = 4; | 1801 | => frame_skip = 4; |
1887 | => frameRate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25; | 1802 | => frame_rate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25; |
1888 | 1803 | ||
1889 | frameDrop = 9; => framePhase = 1, 5, 8, 11, 14, 17, 21, 24, 27, 1, 4, 8, ... | 1804 | frame_drop = 9; => frame_phase = 1, 5, 8, 11, 14, 17, 21, 24, 27, 1, 4, 8, ... |
1890 | => frameSkip = 4, 3, 3, 3, 3, 4, 3, 3, 3, 3, 4, ... | 1805 | => frame_skip = 4, 3, 3, 3, 3, 4, 3, 3, 3, 3, 4, ... |
1891 | => frameRate = (9 + 1) * 25 / 32 = 250 / 32 = 7.8125; | 1806 | => frame_rate = (9 + 1) * 25 / 32 = 250 / 32 = 7.8125; |
1892 | */ | 1807 | */ |
1893 | errCode = usbvision_write_reg(usbvision, USBVISION_FRM_RATE, frameDrop); | 1808 | err_code = usbvision_write_reg(usbvision, USBVISION_FRM_RATE, frame_drop); |
1894 | return errCode; | 1809 | return err_code; |
1895 | } | 1810 | } |
1896 | 1811 | ||
1897 | 1812 | ||
@@ -1903,8 +1818,8 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames | |||
1903 | { | 1818 | { |
1904 | int i; | 1819 | int i; |
1905 | 1820 | ||
1906 | /*needs to be page aligned cause the buffers can be mapped individually! */ | 1821 | /* needs to be page aligned cause the buffers can be mapped individually! */ |
1907 | usbvision->max_frame_size = PAGE_ALIGN(usbvision->curwidth * | 1822 | usbvision->max_frame_size = PAGE_ALIGN(usbvision->curwidth * |
1908 | usbvision->curheight * | 1823 | usbvision->curheight * |
1909 | usbvision->palette.bytes_per_pixel); | 1824 | usbvision->palette.bytes_per_pixel); |
1910 | 1825 | ||
@@ -1912,9 +1827,9 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames | |||
1912 | usbvision->num_frames = number_of_frames; | 1827 | usbvision->num_frames = number_of_frames; |
1913 | while (usbvision->num_frames > 0) { | 1828 | while (usbvision->num_frames > 0) { |
1914 | usbvision->fbuf_size = usbvision->num_frames * usbvision->max_frame_size; | 1829 | usbvision->fbuf_size = usbvision->num_frames * usbvision->max_frame_size; |
1915 | if((usbvision->fbuf = usbvision_rvmalloc(usbvision->fbuf_size))) { | 1830 | usbvision->fbuf = usbvision_rvmalloc(usbvision->fbuf_size); |
1831 | if (usbvision->fbuf) | ||
1916 | break; | 1832 | break; |
1917 | } | ||
1918 | usbvision->num_frames--; | 1833 | usbvision->num_frames--; |
1919 | } | 1834 | } |
1920 | 1835 | ||
@@ -1925,7 +1840,7 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames | |||
1925 | /* Allocate all buffers */ | 1840 | /* Allocate all buffers */ |
1926 | for (i = 0; i < usbvision->num_frames; i++) { | 1841 | for (i = 0; i < usbvision->num_frames; i++) { |
1927 | usbvision->frame[i].index = i; | 1842 | usbvision->frame[i].index = i; |
1928 | usbvision->frame[i].grabstate = FrameState_Unused; | 1843 | usbvision->frame[i].grabstate = frame_state_unused; |
1929 | usbvision->frame[i].data = usbvision->fbuf + | 1844 | usbvision->frame[i].data = usbvision->fbuf + |
1930 | i * usbvision->max_frame_size; | 1845 | i * usbvision->max_frame_size; |
1931 | /* | 1846 | /* |
@@ -1937,7 +1852,8 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames | |||
1937 | usbvision->frame[i].height = usbvision->curheight; | 1852 | usbvision->frame[i].height = usbvision->curheight; |
1938 | usbvision->frame[i].bytes_read = 0; | 1853 | usbvision->frame[i].bytes_read = 0; |
1939 | } | 1854 | } |
1940 | PDEBUG(DBG_FUNC, "allocated %d frames (%d bytes per frame)",usbvision->num_frames,usbvision->max_frame_size); | 1855 | PDEBUG(DBG_FUNC, "allocated %d frames (%d bytes per frame)", |
1856 | usbvision->num_frames, usbvision->max_frame_size); | ||
1941 | return usbvision->num_frames; | 1857 | return usbvision->num_frames; |
1942 | } | 1858 | } |
1943 | 1859 | ||
@@ -1948,7 +1864,7 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames | |||
1948 | void usbvision_frames_free(struct usb_usbvision *usbvision) | 1864 | void usbvision_frames_free(struct usb_usbvision *usbvision) |
1949 | { | 1865 | { |
1950 | /* Have to free all that memory */ | 1866 | /* Have to free all that memory */ |
1951 | PDEBUG(DBG_FUNC, "free %d frames",usbvision->num_frames); | 1867 | PDEBUG(DBG_FUNC, "free %d frames", usbvision->num_frames); |
1952 | 1868 | ||
1953 | if (usbvision->fbuf != NULL) { | 1869 | if (usbvision->fbuf != NULL) { |
1954 | usbvision_rvfree(usbvision->fbuf, usbvision->fbuf_size); | 1870 | usbvision_rvfree(usbvision->fbuf, usbvision->fbuf_size); |
@@ -1969,7 +1885,7 @@ void usbvision_empty_framequeues(struct usb_usbvision *usbvision) | |||
1969 | INIT_LIST_HEAD(&(usbvision->outqueue)); | 1885 | INIT_LIST_HEAD(&(usbvision->outqueue)); |
1970 | 1886 | ||
1971 | for (i = 0; i < USBVISION_NUMFRAMES; i++) { | 1887 | for (i = 0; i < USBVISION_NUMFRAMES; i++) { |
1972 | usbvision->frame[i].grabstate = FrameState_Unused; | 1888 | usbvision->frame[i].grabstate = frame_state_unused; |
1973 | usbvision->frame[i].bytes_read = 0; | 1889 | usbvision->frame[i].bytes_read = 0; |
1974 | } | 1890 | } |
1975 | } | 1891 | } |
@@ -1984,9 +1900,9 @@ int usbvision_stream_interrupt(struct usb_usbvision *usbvision) | |||
1984 | 1900 | ||
1985 | /* stop reading from the device */ | 1901 | /* stop reading from the device */ |
1986 | 1902 | ||
1987 | usbvision->streaming = Stream_Interrupt; | 1903 | usbvision->streaming = stream_interrupt; |
1988 | ret = wait_event_timeout(usbvision->wait_stream, | 1904 | ret = wait_event_timeout(usbvision->wait_stream, |
1989 | (usbvision->streaming == Stream_Idle), | 1905 | (usbvision->streaming == stream_idle), |
1990 | msecs_to_jiffies(USBVISION_NUMSBUF*USBVISION_URB_FRAMES)); | 1906 | msecs_to_jiffies(USBVISION_NUMSBUF*USBVISION_URB_FRAMES)); |
1991 | return ret; | 1907 | return ret; |
1992 | } | 1908 | } |
@@ -2002,19 +1918,19 @@ static int usbvision_set_compress_params(struct usb_usbvision *usbvision) | |||
2002 | int rc; | 1918 | int rc; |
2003 | unsigned char value[6]; | 1919 | unsigned char value[6]; |
2004 | 1920 | ||
2005 | value[0] = 0x0F; // Intra-Compression cycle | 1921 | value[0] = 0x0F; /* Intra-Compression cycle */ |
2006 | value[1] = 0x01; // Reg.45 one line per strip | 1922 | value[1] = 0x01; /* Reg.45 one line per strip */ |
2007 | value[2] = 0x00; // Reg.46 Force intra mode on all new frames | 1923 | value[2] = 0x00; /* Reg.46 Force intra mode on all new frames */ |
2008 | value[3] = 0x00; // Reg.47 FORCE_UP <- 0 normal operation (not force) | 1924 | value[3] = 0x00; /* Reg.47 FORCE_UP <- 0 normal operation (not force) */ |
2009 | value[4] = 0xA2; // Reg.48 BUF_THR I'm not sure if this does something in not compressed mode. | 1925 | value[4] = 0xA2; /* Reg.48 BUF_THR I'm not sure if this does something in not compressed mode. */ |
2010 | value[5] = 0x00; // Reg.49 DVI_YUV This has nothing to do with compression | 1926 | value[5] = 0x00; /* Reg.49 DVI_YUV This has nothing to do with compression */ |
2011 | 1927 | ||
2012 | //catched values for NT1004 | 1928 | /* catched values for NT1004 */ |
2013 | // value[0] = 0xFF; // Never apply intra mode automatically | 1929 | /* value[0] = 0xFF; Never apply intra mode automatically */ |
2014 | // value[1] = 0xF1; // Use full frame height for virtual strip width; One line per strip | 1930 | /* value[1] = 0xF1; Use full frame height for virtual strip width; One line per strip */ |
2015 | // value[2] = 0x01; // Force intra mode on all new frames | 1931 | /* value[2] = 0x01; Force intra mode on all new frames */ |
2016 | // value[3] = 0x00; // Strip size 400 Bytes; do not force up | 1932 | /* value[3] = 0x00; Strip size 400 Bytes; do not force up */ |
2017 | // value[4] = 0xA2; // | 1933 | /* value[4] = 0xA2; */ |
2018 | if (!USBVISION_IS_OPERATIONAL(usbvision)) | 1934 | if (!USBVISION_IS_OPERATIONAL(usbvision)) |
2019 | return 0; | 1935 | return 0; |
2020 | 1936 | ||
@@ -2030,21 +1946,20 @@ static int usbvision_set_compress_params(struct usb_usbvision *usbvision) | |||
2030 | return rc; | 1946 | return rc; |
2031 | } | 1947 | } |
2032 | 1948 | ||
2033 | if (usbvision->bridgeType == BRIDGE_NT1004) { | 1949 | if (usbvision->bridge_type == BRIDGE_NT1004) { |
2034 | value[0] = 20; // PCM Threshold 1 | 1950 | value[0] = 20; /* PCM Threshold 1 */ |
2035 | value[1] = 12; // PCM Threshold 2 | 1951 | value[1] = 12; /* PCM Threshold 2 */ |
2036 | value[2] = 255; // Distorsion Threshold inter | 1952 | value[2] = 255; /* Distortion Threshold inter */ |
2037 | value[3] = 255; // Distorsion Threshold intra | 1953 | value[3] = 255; /* Distortion Threshold intra */ |
2038 | value[4] = 43; // Max Distorsion inter | 1954 | value[4] = 43; /* Max Distortion inter */ |
2039 | value[5] = 43; // Max Distorsion intra | 1955 | value[5] = 43; /* Max Distortion intra */ |
2040 | } | 1956 | } else { |
2041 | else { | 1957 | value[0] = 20; /* PCM Threshold 1 */ |
2042 | value[0] = 20; // PCM Threshold 1 | 1958 | value[1] = 12; /* PCM Threshold 2 */ |
2043 | value[1] = 12; // PCM Threshold 2 | 1959 | value[2] = 255; /* Distortion Threshold d7-d0 */ |
2044 | value[2] = 255; // Distorsion Threshold d7-d0 | 1960 | value[3] = 0; /* Distortion Threshold d11-d8 */ |
2045 | value[3] = 0; // Distorsion Threshold d11-d8 | 1961 | value[4] = 43; /* Max Distortion d7-d0 */ |
2046 | value[4] = 43; // Max Distorsion d7-d0 | 1962 | value[5] = 0; /* Max Distortion d8 */ |
2047 | value[5] = 0; // Max Distorsion d8 | ||
2048 | } | 1963 | } |
2049 | 1964 | ||
2050 | if (!USBVISION_IS_OPERATIONAL(usbvision)) | 1965 | if (!USBVISION_IS_OPERATIONAL(usbvision)) |
@@ -2059,10 +1974,7 @@ static int usbvision_set_compress_params(struct usb_usbvision *usbvision) | |||
2059 | if (rc < 0) { | 1974 | if (rc < 0) { |
2060 | printk(KERN_ERR "%sERROR=%d. USBVISION stopped - " | 1975 | printk(KERN_ERR "%sERROR=%d. USBVISION stopped - " |
2061 | "reconnect or reload driver.\n", proc, rc); | 1976 | "reconnect or reload driver.\n", proc, rc); |
2062 | return rc; | ||
2063 | } | 1977 | } |
2064 | |||
2065 | |||
2066 | return rc; | 1978 | return rc; |
2067 | } | 1979 | } |
2068 | 1980 | ||
@@ -2085,9 +1997,9 @@ int usbvision_set_input(struct usb_usbvision *usbvision) | |||
2085 | return 0; | 1997 | return 0; |
2086 | 1998 | ||
2087 | /* Set input format expected from decoder*/ | 1999 | /* Set input format expected from decoder*/ |
2088 | if (usbvision_device_data[usbvision->DevModel].Vin_Reg1_override) { | 2000 | if (usbvision_device_data[usbvision->dev_model].vin_reg1_override) { |
2089 | value[0] = usbvision_device_data[usbvision->DevModel].Vin_Reg1; | 2001 | value[0] = usbvision_device_data[usbvision->dev_model].vin_reg1; |
2090 | } else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) { | 2002 | } else if (usbvision_device_data[usbvision->dev_model].codec == CODEC_SAA7113) { |
2091 | /* SAA7113 uses 8 bit output */ | 2003 | /* SAA7113 uses 8 bit output */ |
2092 | value[0] = USBVISION_8_422_SYNC; | 2004 | value[0] = USBVISION_8_422_SYNC; |
2093 | } else { | 2005 | } else { |
@@ -2105,53 +2017,53 @@ int usbvision_set_input(struct usb_usbvision *usbvision) | |||
2105 | } | 2017 | } |
2106 | 2018 | ||
2107 | 2019 | ||
2108 | if (usbvision->tvnormId & V4L2_STD_PAL) { | 2020 | if (usbvision->tvnorm_id & V4L2_STD_PAL) { |
2109 | value[0] = 0xC0; | 2021 | value[0] = 0xC0; |
2110 | value[1] = 0x02; //0x02C0 -> 704 Input video line length | 2022 | value[1] = 0x02; /* 0x02C0 -> 704 Input video line length */ |
2111 | value[2] = 0x20; | 2023 | value[2] = 0x20; |
2112 | value[3] = 0x01; //0x0120 -> 288 Input video n. of lines | 2024 | value[3] = 0x01; /* 0x0120 -> 288 Input video n. of lines */ |
2113 | value[4] = 0x60; | 2025 | value[4] = 0x60; |
2114 | value[5] = 0x00; //0x0060 -> 96 Input video h offset | 2026 | value[5] = 0x00; /* 0x0060 -> 96 Input video h offset */ |
2115 | value[6] = 0x16; | 2027 | value[6] = 0x16; |
2116 | value[7] = 0x00; //0x0016 -> 22 Input video v offset | 2028 | value[7] = 0x00; /* 0x0016 -> 22 Input video v offset */ |
2117 | } else if (usbvision->tvnormId & V4L2_STD_SECAM) { | 2029 | } else if (usbvision->tvnorm_id & V4L2_STD_SECAM) { |
2118 | value[0] = 0xC0; | 2030 | value[0] = 0xC0; |
2119 | value[1] = 0x02; //0x02C0 -> 704 Input video line length | 2031 | value[1] = 0x02; /* 0x02C0 -> 704 Input video line length */ |
2120 | value[2] = 0x20; | 2032 | value[2] = 0x20; |
2121 | value[3] = 0x01; //0x0120 -> 288 Input video n. of lines | 2033 | value[3] = 0x01; /* 0x0120 -> 288 Input video n. of lines */ |
2122 | value[4] = 0x01; | 2034 | value[4] = 0x01; |
2123 | value[5] = 0x00; //0x0001 -> 01 Input video h offset | 2035 | value[5] = 0x00; /* 0x0001 -> 01 Input video h offset */ |
2124 | value[6] = 0x01; | 2036 | value[6] = 0x01; |
2125 | value[7] = 0x00; //0x0001 -> 01 Input video v offset | 2037 | value[7] = 0x00; /* 0x0001 -> 01 Input video v offset */ |
2126 | } else { /* V4L2_STD_NTSC */ | 2038 | } else { /* V4L2_STD_NTSC */ |
2127 | value[0] = 0xD0; | 2039 | value[0] = 0xD0; |
2128 | value[1] = 0x02; //0x02D0 -> 720 Input video line length | 2040 | value[1] = 0x02; /* 0x02D0 -> 720 Input video line length */ |
2129 | value[2] = 0xF0; | 2041 | value[2] = 0xF0; |
2130 | value[3] = 0x00; //0x00F0 -> 240 Input video number of lines | 2042 | value[3] = 0x00; /* 0x00F0 -> 240 Input video number of lines */ |
2131 | value[4] = 0x50; | 2043 | value[4] = 0x50; |
2132 | value[5] = 0x00; //0x0050 -> 80 Input video h offset | 2044 | value[5] = 0x00; /* 0x0050 -> 80 Input video h offset */ |
2133 | value[6] = 0x10; | 2045 | value[6] = 0x10; |
2134 | value[7] = 0x00; //0x0010 -> 16 Input video v offset | 2046 | value[7] = 0x00; /* 0x0010 -> 16 Input video v offset */ |
2135 | } | 2047 | } |
2136 | 2048 | ||
2137 | if (usbvision_device_data[usbvision->DevModel].X_Offset >= 0) { | 2049 | if (usbvision_device_data[usbvision->dev_model].x_offset >= 0) { |
2138 | value[4]=usbvision_device_data[usbvision->DevModel].X_Offset & 0xff; | 2050 | value[4] = usbvision_device_data[usbvision->dev_model].x_offset & 0xff; |
2139 | value[5]=(usbvision_device_data[usbvision->DevModel].X_Offset & 0x0300) >> 8; | 2051 | value[5] = (usbvision_device_data[usbvision->dev_model].x_offset & 0x0300) >> 8; |
2140 | } | 2052 | } |
2141 | 2053 | ||
2142 | if (adjust_X_Offset != -1) { | 2054 | if (adjust_x_offset != -1) { |
2143 | value[4] = adjust_X_Offset & 0xff; | 2055 | value[4] = adjust_x_offset & 0xff; |
2144 | value[5] = (adjust_X_Offset & 0x0300) >> 8; | 2056 | value[5] = (adjust_x_offset & 0x0300) >> 8; |
2145 | } | 2057 | } |
2146 | 2058 | ||
2147 | if (usbvision_device_data[usbvision->DevModel].Y_Offset >= 0) { | 2059 | if (usbvision_device_data[usbvision->dev_model].y_offset >= 0) { |
2148 | value[6]=usbvision_device_data[usbvision->DevModel].Y_Offset & 0xff; | 2060 | value[6] = usbvision_device_data[usbvision->dev_model].y_offset & 0xff; |
2149 | value[7]=(usbvision_device_data[usbvision->DevModel].Y_Offset & 0x0300) >> 8; | 2061 | value[7] = (usbvision_device_data[usbvision->dev_model].y_offset & 0x0300) >> 8; |
2150 | } | 2062 | } |
2151 | 2063 | ||
2152 | if (adjust_Y_Offset != -1) { | 2064 | if (adjust_y_offset != -1) { |
2153 | value[6] = adjust_Y_Offset & 0xff; | 2065 | value[6] = adjust_y_offset & 0xff; |
2154 | value[7] = (adjust_Y_Offset & 0x0300) >> 8; | 2066 | value[7] = (adjust_y_offset & 0x0300) >> 8; |
2155 | } | 2067 | } |
2156 | 2068 | ||
2157 | rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1), | 2069 | rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1), |
@@ -2167,15 +2079,14 @@ int usbvision_set_input(struct usb_usbvision *usbvision) | |||
2167 | 2079 | ||
2168 | dvi_yuv_value = 0x00; /* U comes after V, Ya comes after U/V, Yb comes after Yb */ | 2080 | dvi_yuv_value = 0x00; /* U comes after V, Ya comes after U/V, Yb comes after Yb */ |
2169 | 2081 | ||
2170 | if(usbvision_device_data[usbvision->DevModel].Dvi_yuv_override){ | 2082 | if (usbvision_device_data[usbvision->dev_model].dvi_yuv_override) { |
2171 | dvi_yuv_value = usbvision_device_data[usbvision->DevModel].Dvi_yuv; | 2083 | dvi_yuv_value = usbvision_device_data[usbvision->dev_model].dvi_yuv; |
2172 | } | 2084 | } else if (usbvision_device_data[usbvision->dev_model].codec == CODEC_SAA7113) { |
2173 | else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) { | 2085 | /* This changes as the fine sync control changes. Further investigation necessary */ |
2174 | /* This changes as the fine sync control changes. Further investigation necessary */ | ||
2175 | dvi_yuv_value = 0x06; | 2086 | dvi_yuv_value = 0x06; |
2176 | } | 2087 | } |
2177 | 2088 | ||
2178 | return (usbvision_write_reg(usbvision, USBVISION_DVI_YUV, dvi_yuv_value)); | 2089 | return usbvision_write_reg(usbvision, USBVISION_DVI_YUV, dvi_yuv_value); |
2179 | } | 2090 | } |
2180 | 2091 | ||
2181 | 2092 | ||
@@ -2192,7 +2103,7 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision) | |||
2192 | int rc; | 2103 | int rc; |
2193 | unsigned char value[8]; | 2104 | unsigned char value[8]; |
2194 | 2105 | ||
2195 | if (usbvision->isocMode == ISOC_MODE_COMPRESS) { | 2106 | if (usbvision->isoc_mode == ISOC_MODE_COMPRESS) { |
2196 | value[0] = 0x42; | 2107 | value[0] = 0x42; |
2197 | value[1] = 0x71; | 2108 | value[1] = 0x71; |
2198 | value[2] = 0xff; | 2109 | value[2] = 0xff; |
@@ -2201,11 +2112,10 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision) | |||
2201 | value[5] = 0xe0; | 2112 | value[5] = 0xe0; |
2202 | value[6] = 0x71; | 2113 | value[6] = 0x71; |
2203 | value[7] = 0xff; | 2114 | value[7] = 0xff; |
2204 | // UR: 0x0E200-0x3FFFF = 204288 Words (1 Word = 2 Byte) | 2115 | /* UR: 0x0E200-0x3FFFF = 204288 Words (1 Word = 2 Byte) */ |
2205 | // FDL: 0x00000-0x0E099 = 57498 Words | 2116 | /* FDL: 0x00000-0x0E099 = 57498 Words */ |
2206 | // VDW: 0x0E3FF-0x3FFFF | 2117 | /* VDW: 0x0E3FF-0x3FFFF */ |
2207 | } | 2118 | } else { |
2208 | else { | ||
2209 | value[0] = 0x42; | 2119 | value[0] = 0x42; |
2210 | value[1] = 0x00; | 2120 | value[1] = 0x00; |
2211 | value[2] = 0xff; | 2121 | value[2] = 0xff; |
@@ -2218,14 +2128,14 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision) | |||
2218 | /* These are the values of the address of the video buffer, | 2128 | /* These are the values of the address of the video buffer, |
2219 | * they have to be loaded into the USBVISION_DRM_PRM1-8 | 2129 | * they have to be loaded into the USBVISION_DRM_PRM1-8 |
2220 | * | 2130 | * |
2221 | * Start address of video output buffer for read: drm_prm1-2 -> 0x00000 | 2131 | * Start address of video output buffer for read: drm_prm1-2 -> 0x00000 |
2222 | * End address of video output buffer for read: drm_prm1-3 -> 0x1ffff | 2132 | * End address of video output buffer for read: drm_prm1-3 -> 0x1ffff |
2223 | * Start address of video frame delay buffer: drm_prm1-4 -> 0x20000 | 2133 | * Start address of video frame delay buffer: drm_prm1-4 -> 0x20000 |
2224 | * Only used in compressed mode | 2134 | * Only used in compressed mode |
2225 | * End address of video frame delay buffer: drm_prm1-5-6 -> 0x3ffff | 2135 | * End address of video frame delay buffer: drm_prm1-5-6 -> 0x3ffff |
2226 | * Only used in compressed mode | 2136 | * Only used in compressed mode |
2227 | * Start address of video output buffer for write: drm_prm1-7 -> 0x00000 | 2137 | * Start address of video output buffer for write: drm_prm1-7 -> 0x00000 |
2228 | * End address of video output buffer for write: drm_prm1-8 -> 0x1ffff | 2138 | * End address of video output buffer for write: drm_prm1-8 -> 0x1ffff |
2229 | */ | 2139 | */ |
2230 | 2140 | ||
2231 | if (!USBVISION_IS_OPERATIONAL(usbvision)) | 2141 | if (!USBVISION_IS_OPERATIONAL(usbvision)) |
@@ -2243,8 +2153,9 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision) | |||
2243 | } | 2153 | } |
2244 | 2154 | ||
2245 | /* Restart the video buffer logic */ | 2155 | /* Restart the video buffer logic */ |
2246 | if ((rc = usbvision_write_reg(usbvision, USBVISION_DRM_CONT, USBVISION_RES_UR | | 2156 | rc = usbvision_write_reg(usbvision, USBVISION_DRM_CONT, USBVISION_RES_UR | |
2247 | USBVISION_RES_FDL | USBVISION_RES_VDW)) < 0) | 2157 | USBVISION_RES_FDL | USBVISION_RES_VDW); |
2158 | if (rc < 0) | ||
2248 | return rc; | 2159 | return rc; |
2249 | rc = usbvision_write_reg(usbvision, USBVISION_DRM_CONT, 0x00); | 2160 | rc = usbvision_write_reg(usbvision, USBVISION_DRM_CONT, 0x00); |
2250 | 2161 | ||
@@ -2261,23 +2172,22 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision) | |||
2261 | 2172 | ||
2262 | int usbvision_power_on(struct usb_usbvision *usbvision) | 2173 | int usbvision_power_on(struct usb_usbvision *usbvision) |
2263 | { | 2174 | { |
2264 | int errCode = 0; | 2175 | int err_code = 0; |
2265 | 2176 | ||
2266 | PDEBUG(DBG_FUNC, ""); | 2177 | PDEBUG(DBG_FUNC, ""); |
2267 | 2178 | ||
2268 | usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN); | 2179 | usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN); |
2269 | usbvision_write_reg(usbvision, USBVISION_PWR_REG, | 2180 | usbvision_write_reg(usbvision, USBVISION_PWR_REG, |
2270 | USBVISION_SSPND_EN | USBVISION_RES2); | 2181 | USBVISION_SSPND_EN | USBVISION_RES2); |
2271 | 2182 | ||
2272 | usbvision_write_reg(usbvision, USBVISION_PWR_REG, | 2183 | usbvision_write_reg(usbvision, USBVISION_PWR_REG, |
2273 | USBVISION_SSPND_EN | USBVISION_PWR_VID); | 2184 | USBVISION_SSPND_EN | USBVISION_PWR_VID); |
2274 | errCode = usbvision_write_reg(usbvision, USBVISION_PWR_REG, | 2185 | err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG, |
2275 | USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2); | 2186 | USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2); |
2276 | if (errCode == 1) { | 2187 | if (err_code == 1) |
2277 | usbvision->power = 1; | 2188 | usbvision->power = 1; |
2278 | } | 2189 | PDEBUG(DBG_FUNC, "%s: err_code %d", (err_code < 0) ? "ERROR" : "power is on", err_code); |
2279 | PDEBUG(DBG_FUNC, "%s: errCode %d", (errCode<0)?"ERROR":"power is on", errCode); | 2190 | return err_code; |
2280 | return errCode; | ||
2281 | } | 2191 | } |
2282 | 2192 | ||
2283 | 2193 | ||
@@ -2285,53 +2195,50 @@ int usbvision_power_on(struct usb_usbvision *usbvision) | |||
2285 | * usbvision timer stuff | 2195 | * usbvision timer stuff |
2286 | */ | 2196 | */ |
2287 | 2197 | ||
2288 | // to call usbvision_power_off from task queue | 2198 | /* to call usbvision_power_off from task queue */ |
2289 | static void call_usbvision_power_off(struct work_struct *work) | 2199 | static void call_usbvision_power_off(struct work_struct *work) |
2290 | { | 2200 | { |
2291 | struct usb_usbvision *usbvision = container_of(work, struct usb_usbvision, powerOffWork); | 2201 | struct usb_usbvision *usbvision = container_of(work, struct usb_usbvision, power_off_work); |
2292 | 2202 | ||
2293 | PDEBUG(DBG_FUNC, ""); | 2203 | PDEBUG(DBG_FUNC, ""); |
2294 | if(mutex_lock_interruptible(&usbvision->lock)) { | 2204 | if (mutex_lock_interruptible(&usbvision->v4l2_lock)) |
2295 | return; | 2205 | return; |
2296 | } | ||
2297 | 2206 | ||
2298 | 2207 | if (usbvision->user == 0) { | |
2299 | if(usbvision->user == 0) { | ||
2300 | usbvision_i2c_unregister(usbvision); | 2208 | usbvision_i2c_unregister(usbvision); |
2301 | 2209 | ||
2302 | usbvision_power_off(usbvision); | 2210 | usbvision_power_off(usbvision); |
2303 | usbvision->initialized = 0; | 2211 | usbvision->initialized = 0; |
2304 | } | 2212 | } |
2305 | mutex_unlock(&usbvision->lock); | 2213 | mutex_unlock(&usbvision->v4l2_lock); |
2306 | } | 2214 | } |
2307 | 2215 | ||
2308 | static void usbvision_powerOffTimer(unsigned long data) | 2216 | static void usbvision_power_off_timer(unsigned long data) |
2309 | { | 2217 | { |
2310 | struct usb_usbvision *usbvision = (void *) data; | 2218 | struct usb_usbvision *usbvision = (void *)data; |
2311 | 2219 | ||
2312 | PDEBUG(DBG_FUNC, ""); | 2220 | PDEBUG(DBG_FUNC, ""); |
2313 | del_timer(&usbvision->powerOffTimer); | 2221 | del_timer(&usbvision->power_off_timer); |
2314 | INIT_WORK(&usbvision->powerOffWork, call_usbvision_power_off); | 2222 | INIT_WORK(&usbvision->power_off_work, call_usbvision_power_off); |
2315 | (void) schedule_work(&usbvision->powerOffWork); | 2223 | (void) schedule_work(&usbvision->power_off_work); |
2316 | } | 2224 | } |
2317 | 2225 | ||
2318 | void usbvision_init_powerOffTimer(struct usb_usbvision *usbvision) | 2226 | void usbvision_init_power_off_timer(struct usb_usbvision *usbvision) |
2319 | { | 2227 | { |
2320 | init_timer(&usbvision->powerOffTimer); | 2228 | init_timer(&usbvision->power_off_timer); |
2321 | usbvision->powerOffTimer.data = (long) usbvision; | 2229 | usbvision->power_off_timer.data = (long)usbvision; |
2322 | usbvision->powerOffTimer.function = usbvision_powerOffTimer; | 2230 | usbvision->power_off_timer.function = usbvision_power_off_timer; |
2323 | } | 2231 | } |
2324 | 2232 | ||
2325 | void usbvision_set_powerOffTimer(struct usb_usbvision *usbvision) | 2233 | void usbvision_set_power_off_timer(struct usb_usbvision *usbvision) |
2326 | { | 2234 | { |
2327 | mod_timer(&usbvision->powerOffTimer, jiffies + USBVISION_POWEROFF_TIME); | 2235 | mod_timer(&usbvision->power_off_timer, jiffies + USBVISION_POWEROFF_TIME); |
2328 | } | 2236 | } |
2329 | 2237 | ||
2330 | void usbvision_reset_powerOffTimer(struct usb_usbvision *usbvision) | 2238 | void usbvision_reset_power_off_timer(struct usb_usbvision *usbvision) |
2331 | { | 2239 | { |
2332 | if (timer_pending(&usbvision->powerOffTimer)) { | 2240 | if (timer_pending(&usbvision->power_off_timer)) |
2333 | del_timer(&usbvision->powerOffTimer); | 2241 | del_timer(&usbvision->power_off_timer); |
2334 | } | ||
2335 | } | 2242 | } |
2336 | 2243 | ||
2337 | /* | 2244 | /* |
@@ -2341,14 +2248,10 @@ void usbvision_reset_powerOffTimer(struct usb_usbvision *usbvision) | |||
2341 | */ | 2248 | */ |
2342 | int usbvision_begin_streaming(struct usb_usbvision *usbvision) | 2249 | int usbvision_begin_streaming(struct usb_usbvision *usbvision) |
2343 | { | 2250 | { |
2344 | int errCode = 0; | 2251 | if (usbvision->isoc_mode == ISOC_MODE_COMPRESS) |
2345 | |||
2346 | if (usbvision->isocMode == ISOC_MODE_COMPRESS) { | ||
2347 | usbvision_init_compression(usbvision); | 2252 | usbvision_init_compression(usbvision); |
2348 | } | 2253 | return usbvision_write_reg(usbvision, USBVISION_VIN_REG2, |
2349 | errCode = usbvision_write_reg(usbvision, USBVISION_VIN_REG2, USBVISION_NOHVALID | | 2254 | USBVISION_NOHVALID | usbvision->vin_reg2_preset); |
2350 | usbvision->Vin_Reg2_Preset); | ||
2351 | return errCode; | ||
2352 | } | 2255 | } |
2353 | 2256 | ||
2354 | /* | 2257 | /* |
@@ -2360,25 +2263,24 @@ int usbvision_restart_isoc(struct usb_usbvision *usbvision) | |||
2360 | { | 2263 | { |
2361 | int ret; | 2264 | int ret; |
2362 | 2265 | ||
2363 | if ( | 2266 | ret = usbvision_write_reg(usbvision, USBVISION_PWR_REG, |
2364 | (ret = | 2267 | USBVISION_SSPND_EN | USBVISION_PWR_VID); |
2365 | usbvision_write_reg(usbvision, USBVISION_PWR_REG, | 2268 | if (ret < 0) |
2366 | USBVISION_SSPND_EN | USBVISION_PWR_VID)) < 0) | ||
2367 | return ret; | 2269 | return ret; |
2368 | if ( | 2270 | ret = usbvision_write_reg(usbvision, USBVISION_PWR_REG, |
2369 | (ret = | ||
2370 | usbvision_write_reg(usbvision, USBVISION_PWR_REG, | ||
2371 | USBVISION_SSPND_EN | USBVISION_PWR_VID | | 2271 | USBVISION_SSPND_EN | USBVISION_PWR_VID | |
2372 | USBVISION_RES2)) < 0) | 2272 | USBVISION_RES2); |
2273 | if (ret < 0) | ||
2373 | return ret; | 2274 | return ret; |
2374 | if ( | 2275 | ret = usbvision_write_reg(usbvision, USBVISION_VIN_REG2, |
2375 | (ret = | ||
2376 | usbvision_write_reg(usbvision, USBVISION_VIN_REG2, | ||
2377 | USBVISION_KEEP_BLANK | USBVISION_NOHVALID | | 2276 | USBVISION_KEEP_BLANK | USBVISION_NOHVALID | |
2378 | usbvision->Vin_Reg2_Preset)) < 0) return ret; | 2277 | usbvision->vin_reg2_preset); |
2278 | if (ret < 0) | ||
2279 | return ret; | ||
2379 | 2280 | ||
2380 | /* TODO: schedule timeout */ | 2281 | /* TODO: schedule timeout */ |
2381 | while ((usbvision_read_reg(usbvision, USBVISION_STATUS_REG) & 0x01) != 1); | 2282 | while ((usbvision_read_reg(usbvision, USBVISION_STATUS_REG) & 0x01) != 1) |
2283 | ; | ||
2382 | 2284 | ||
2383 | return 0; | 2285 | return 0; |
2384 | } | 2286 | } |
@@ -2386,27 +2288,27 @@ int usbvision_restart_isoc(struct usb_usbvision *usbvision) | |||
2386 | int usbvision_audio_off(struct usb_usbvision *usbvision) | 2288 | int usbvision_audio_off(struct usb_usbvision *usbvision) |
2387 | { | 2289 | { |
2388 | if (usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, USBVISION_AUDIO_MUTE) < 0) { | 2290 | if (usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, USBVISION_AUDIO_MUTE) < 0) { |
2389 | printk(KERN_ERR "usbvision_audio_off: can't wirte reg\n"); | 2291 | printk(KERN_ERR "usbvision_audio_off: can't write reg\n"); |
2390 | return -1; | 2292 | return -1; |
2391 | } | 2293 | } |
2392 | usbvision->AudioMute = 0; | 2294 | usbvision->audio_mute = 0; |
2393 | usbvision->AudioChannel = USBVISION_AUDIO_MUTE; | 2295 | usbvision->audio_channel = USBVISION_AUDIO_MUTE; |
2394 | return 0; | 2296 | return 0; |
2395 | } | 2297 | } |
2396 | 2298 | ||
2397 | int usbvision_set_audio(struct usb_usbvision *usbvision, int AudioChannel) | 2299 | int usbvision_set_audio(struct usb_usbvision *usbvision, int audio_channel) |
2398 | { | 2300 | { |
2399 | if (!usbvision->AudioMute) { | 2301 | if (!usbvision->audio_mute) { |
2400 | if (usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, AudioChannel) < 0) { | 2302 | if (usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, audio_channel) < 0) { |
2401 | printk(KERN_ERR "usbvision_set_audio: can't write iopin register for audio switching\n"); | 2303 | printk(KERN_ERR "usbvision_set_audio: can't write iopin register for audio switching\n"); |
2402 | return -1; | 2304 | return -1; |
2403 | } | 2305 | } |
2404 | } | 2306 | } |
2405 | usbvision->AudioChannel = AudioChannel; | 2307 | usbvision->audio_channel = audio_channel; |
2406 | return 0; | 2308 | return 0; |
2407 | } | 2309 | } |
2408 | 2310 | ||
2409 | int usbvision_setup(struct usb_usbvision *usbvision,int format) | 2311 | int usbvision_setup(struct usb_usbvision *usbvision, int format) |
2410 | { | 2312 | { |
2411 | usbvision_set_video_format(usbvision, format); | 2313 | usbvision_set_video_format(usbvision, format); |
2412 | usbvision_set_dram_settings(usbvision); | 2314 | usbvision_set_dram_settings(usbvision); |
@@ -2421,27 +2323,28 @@ int usbvision_setup(struct usb_usbvision *usbvision,int format) | |||
2421 | 2323 | ||
2422 | int usbvision_set_alternate(struct usb_usbvision *dev) | 2324 | int usbvision_set_alternate(struct usb_usbvision *dev) |
2423 | { | 2325 | { |
2424 | int errCode, prev_alt = dev->ifaceAlt; | 2326 | int err_code, prev_alt = dev->iface_alt; |
2425 | int i; | 2327 | int i; |
2426 | 2328 | ||
2427 | dev->ifaceAlt=0; | 2329 | dev->iface_alt = 0; |
2428 | for(i=0;i< dev->num_alt; i++) | 2330 | for (i = 0; i < dev->num_alt; i++) |
2429 | if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->ifaceAlt]) | 2331 | if (dev->alt_max_pkt_size[i] > dev->alt_max_pkt_size[dev->iface_alt]) |
2430 | dev->ifaceAlt=i; | 2332 | dev->iface_alt = i; |
2431 | 2333 | ||
2432 | if (dev->ifaceAlt != prev_alt) { | 2334 | if (dev->iface_alt != prev_alt) { |
2433 | dev->isocPacketSize = dev->alt_max_pkt_size[dev->ifaceAlt]; | 2335 | dev->isoc_packet_size = dev->alt_max_pkt_size[dev->iface_alt]; |
2434 | PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize); | 2336 | PDEBUG(DBG_FUNC, "setting alternate %d with max_packet_size=%u", |
2435 | errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt); | 2337 | dev->iface_alt, dev->isoc_packet_size); |
2436 | if (errCode < 0) { | 2338 | err_code = usb_set_interface(dev->dev, dev->iface, dev->iface_alt); |
2339 | if (err_code < 0) { | ||
2437 | dev_err(&dev->dev->dev, | 2340 | dev_err(&dev->dev->dev, |
2438 | "cannot change alternate number to %d (error=%i)\n", | 2341 | "cannot change alternate number to %d (error=%i)\n", |
2439 | dev->ifaceAlt, errCode); | 2342 | dev->iface_alt, err_code); |
2440 | return errCode; | 2343 | return err_code; |
2441 | } | 2344 | } |
2442 | } | 2345 | } |
2443 | 2346 | ||
2444 | PDEBUG(DBG_ISOC, "ISO Packet Length:%d", dev->isocPacketSize); | 2347 | PDEBUG(DBG_ISOC, "ISO Packet Length:%d", dev->isoc_packet_size); |
2445 | 2348 | ||
2446 | return 0; | 2349 | return 0; |
2447 | } | 2350 | } |
@@ -2453,27 +2356,27 @@ int usbvision_set_alternate(struct usb_usbvision *dev) | |||
2453 | int usbvision_init_isoc(struct usb_usbvision *usbvision) | 2356 | int usbvision_init_isoc(struct usb_usbvision *usbvision) |
2454 | { | 2357 | { |
2455 | struct usb_device *dev = usbvision->dev; | 2358 | struct usb_device *dev = usbvision->dev; |
2456 | int bufIdx, errCode, regValue; | 2359 | int buf_idx, err_code, reg_value; |
2457 | int sb_size; | 2360 | int sb_size; |
2458 | 2361 | ||
2459 | if (!USBVISION_IS_OPERATIONAL(usbvision)) | 2362 | if (!USBVISION_IS_OPERATIONAL(usbvision)) |
2460 | return -EFAULT; | 2363 | return -EFAULT; |
2461 | 2364 | ||
2462 | usbvision->curFrame = NULL; | 2365 | usbvision->cur_frame = NULL; |
2463 | scratch_reset(usbvision); | 2366 | scratch_reset(usbvision); |
2464 | 2367 | ||
2465 | /* Alternate interface 1 is is the biggest frame size */ | 2368 | /* Alternate interface 1 is is the biggest frame size */ |
2466 | errCode = usbvision_set_alternate(usbvision); | 2369 | err_code = usbvision_set_alternate(usbvision); |
2467 | if (errCode < 0) { | 2370 | if (err_code < 0) { |
2468 | usbvision->last_error = errCode; | 2371 | usbvision->last_error = err_code; |
2469 | return -EBUSY; | 2372 | return -EBUSY; |
2470 | } | 2373 | } |
2471 | sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize; | 2374 | sb_size = USBVISION_URB_FRAMES * usbvision->isoc_packet_size; |
2472 | 2375 | ||
2473 | regValue = (16 - usbvision_read_reg(usbvision, | 2376 | reg_value = (16 - usbvision_read_reg(usbvision, |
2474 | USBVISION_ALTER_REG)) & 0x0F; | 2377 | USBVISION_ALTER_REG)) & 0x0F; |
2475 | 2378 | ||
2476 | usbvision->usb_bandwidth = regValue >> 1; | 2379 | usbvision->usb_bandwidth = reg_value >> 1; |
2477 | PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", | 2380 | PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", |
2478 | usbvision->usb_bandwidth); | 2381 | usbvision->usb_bandwidth); |
2479 | 2382 | ||
@@ -2481,7 +2384,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
2481 | 2384 | ||
2482 | /* We double buffer the Iso lists */ | 2385 | /* We double buffer the Iso lists */ |
2483 | 2386 | ||
2484 | for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) { | 2387 | for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) { |
2485 | int j, k; | 2388 | int j, k; |
2486 | struct urb *urb; | 2389 | struct urb *urb; |
2487 | 2390 | ||
@@ -2491,8 +2394,8 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
2491 | "%s: usb_alloc_urb() failed\n", __func__); | 2394 | "%s: usb_alloc_urb() failed\n", __func__); |
2492 | return -ENOMEM; | 2395 | return -ENOMEM; |
2493 | } | 2396 | } |
2494 | usbvision->sbuf[bufIdx].urb = urb; | 2397 | usbvision->sbuf[buf_idx].urb = urb; |
2495 | usbvision->sbuf[bufIdx].data = | 2398 | usbvision->sbuf[buf_idx].data = |
2496 | usb_alloc_coherent(usbvision->dev, | 2399 | usb_alloc_coherent(usbvision->dev, |
2497 | sb_size, | 2400 | sb_size, |
2498 | GFP_KERNEL, | 2401 | GFP_KERNEL, |
@@ -2502,31 +2405,31 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
2502 | urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp); | 2405 | urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp); |
2503 | urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; | 2406 | urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; |
2504 | urb->interval = 1; | 2407 | urb->interval = 1; |
2505 | urb->transfer_buffer = usbvision->sbuf[bufIdx].data; | 2408 | urb->transfer_buffer = usbvision->sbuf[buf_idx].data; |
2506 | urb->complete = usbvision_isocIrq; | 2409 | urb->complete = usbvision_isoc_irq; |
2507 | urb->number_of_packets = USBVISION_URB_FRAMES; | 2410 | urb->number_of_packets = USBVISION_URB_FRAMES; |
2508 | urb->transfer_buffer_length = | 2411 | urb->transfer_buffer_length = |
2509 | usbvision->isocPacketSize * USBVISION_URB_FRAMES; | 2412 | usbvision->isoc_packet_size * USBVISION_URB_FRAMES; |
2510 | for (j = k = 0; j < USBVISION_URB_FRAMES; j++, | 2413 | for (j = k = 0; j < USBVISION_URB_FRAMES; j++, |
2511 | k += usbvision->isocPacketSize) { | 2414 | k += usbvision->isoc_packet_size) { |
2512 | urb->iso_frame_desc[j].offset = k; | 2415 | urb->iso_frame_desc[j].offset = k; |
2513 | urb->iso_frame_desc[j].length = | 2416 | urb->iso_frame_desc[j].length = |
2514 | usbvision->isocPacketSize; | 2417 | usbvision->isoc_packet_size; |
2515 | } | 2418 | } |
2516 | } | 2419 | } |
2517 | 2420 | ||
2518 | /* Submit all URBs */ | 2421 | /* Submit all URBs */ |
2519 | for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) { | 2422 | for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) { |
2520 | errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb, | 2423 | err_code = usb_submit_urb(usbvision->sbuf[buf_idx].urb, |
2521 | GFP_KERNEL); | 2424 | GFP_KERNEL); |
2522 | if (errCode) { | 2425 | if (err_code) { |
2523 | dev_err(&usbvision->dev->dev, | 2426 | dev_err(&usbvision->dev->dev, |
2524 | "%s: usb_submit_urb(%d) failed: error %d\n", | 2427 | "%s: usb_submit_urb(%d) failed: error %d\n", |
2525 | __func__, bufIdx, errCode); | 2428 | __func__, buf_idx, err_code); |
2526 | } | 2429 | } |
2527 | } | 2430 | } |
2528 | 2431 | ||
2529 | usbvision->streaming = Stream_Idle; | 2432 | usbvision->streaming = stream_idle; |
2530 | PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", | 2433 | PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", |
2531 | __func__, | 2434 | __func__, |
2532 | usbvision->video_endp); | 2435 | usbvision->video_endp); |
@@ -2542,47 +2445,46 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
2542 | */ | 2445 | */ |
2543 | void usbvision_stop_isoc(struct usb_usbvision *usbvision) | 2446 | void usbvision_stop_isoc(struct usb_usbvision *usbvision) |
2544 | { | 2447 | { |
2545 | int bufIdx, errCode, regValue; | 2448 | int buf_idx, err_code, reg_value; |
2546 | int sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize; | 2449 | int sb_size = USBVISION_URB_FRAMES * usbvision->isoc_packet_size; |
2547 | 2450 | ||
2548 | if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL)) | 2451 | if ((usbvision->streaming == stream_off) || (usbvision->dev == NULL)) |
2549 | return; | 2452 | return; |
2550 | 2453 | ||
2551 | /* Unschedule all of the iso td's */ | 2454 | /* Unschedule all of the iso td's */ |
2552 | for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) { | 2455 | for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) { |
2553 | usb_kill_urb(usbvision->sbuf[bufIdx].urb); | 2456 | usb_kill_urb(usbvision->sbuf[buf_idx].urb); |
2554 | if (usbvision->sbuf[bufIdx].data){ | 2457 | if (usbvision->sbuf[buf_idx].data) { |
2555 | usb_free_coherent(usbvision->dev, | 2458 | usb_free_coherent(usbvision->dev, |
2556 | sb_size, | 2459 | sb_size, |
2557 | usbvision->sbuf[bufIdx].data, | 2460 | usbvision->sbuf[buf_idx].data, |
2558 | usbvision->sbuf[bufIdx].urb->transfer_dma); | 2461 | usbvision->sbuf[buf_idx].urb->transfer_dma); |
2559 | } | 2462 | } |
2560 | usb_free_urb(usbvision->sbuf[bufIdx].urb); | 2463 | usb_free_urb(usbvision->sbuf[buf_idx].urb); |
2561 | usbvision->sbuf[bufIdx].urb = NULL; | 2464 | usbvision->sbuf[buf_idx].urb = NULL; |
2562 | } | 2465 | } |
2563 | 2466 | ||
2564 | PDEBUG(DBG_ISOC, "%s: streaming=Stream_Off\n", __func__); | 2467 | PDEBUG(DBG_ISOC, "%s: streaming=stream_off\n", __func__); |
2565 | usbvision->streaming = Stream_Off; | 2468 | usbvision->streaming = stream_off; |
2566 | 2469 | ||
2567 | if (!usbvision->remove_pending) { | 2470 | if (!usbvision->remove_pending) { |
2568 | |||
2569 | /* Set packet size to 0 */ | 2471 | /* Set packet size to 0 */ |
2570 | usbvision->ifaceAlt=0; | 2472 | usbvision->iface_alt = 0; |
2571 | errCode = usb_set_interface(usbvision->dev, usbvision->iface, | 2473 | err_code = usb_set_interface(usbvision->dev, usbvision->iface, |
2572 | usbvision->ifaceAlt); | 2474 | usbvision->iface_alt); |
2573 | if (errCode < 0) { | 2475 | if (err_code < 0) { |
2574 | dev_err(&usbvision->dev->dev, | 2476 | dev_err(&usbvision->dev->dev, |
2575 | "%s: usb_set_interface() failed: error %d\n", | 2477 | "%s: usb_set_interface() failed: error %d\n", |
2576 | __func__, errCode); | 2478 | __func__, err_code); |
2577 | usbvision->last_error = errCode; | 2479 | usbvision->last_error = err_code; |
2578 | } | 2480 | } |
2579 | regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; | 2481 | reg_value = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; |
2580 | usbvision->isocPacketSize = | 2482 | usbvision->isoc_packet_size = |
2581 | (regValue == 0) ? 0 : (regValue * 64) - 1; | 2483 | (reg_value == 0) ? 0 : (reg_value * 64) - 1; |
2582 | PDEBUG(DBG_ISOC, "ISO Packet Length:%d", | 2484 | PDEBUG(DBG_ISOC, "ISO Packet Length:%d", |
2583 | usbvision->isocPacketSize); | 2485 | usbvision->isoc_packet_size); |
2584 | 2486 | ||
2585 | usbvision->usb_bandwidth = regValue >> 1; | 2487 | usbvision->usb_bandwidth = reg_value >> 1; |
2586 | PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", | 2488 | PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", |
2587 | usbvision->usb_bandwidth); | 2489 | usbvision->usb_bandwidth); |
2588 | } | 2490 | } |
@@ -2592,39 +2494,38 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel) | |||
2592 | { | 2494 | { |
2593 | /* inputs #0 and #3 are constant for every SAA711x. */ | 2495 | /* inputs #0 and #3 are constant for every SAA711x. */ |
2594 | /* inputs #1 and #2 are variable for SAA7111 and SAA7113 */ | 2496 | /* inputs #1 and #2 are variable for SAA7111 and SAA7113 */ |
2595 | int mode[4]= {SAA7115_COMPOSITE0, 0, 0, SAA7115_COMPOSITE3}; | 2497 | int mode[4] = { SAA7115_COMPOSITE0, 0, 0, SAA7115_COMPOSITE3 }; |
2596 | int audio[]= {1, 0, 0, 0}; | 2498 | int audio[] = { 1, 0, 0, 0 }; |
2597 | //channel 0 is TV with audiochannel 1 (tuner mono) | 2499 | /* channel 0 is TV with audiochannel 1 (tuner mono) */ |
2598 | //channel 1 is Composite with audio channel 0 (line in) | 2500 | /* channel 1 is Composite with audio channel 0 (line in) */ |
2599 | //channel 2 is S-Video with audio channel 0 (line in) | 2501 | /* channel 2 is S-Video with audio channel 0 (line in) */ |
2600 | //channel 3 is additional video inputs to the device with audio channel 0 (line in) | 2502 | /* channel 3 is additional video inputs to the device with audio channel 0 (line in) */ |
2601 | 2503 | ||
2602 | RESTRICT_TO_RANGE(channel, 0, usbvision->video_inputs); | 2504 | RESTRICT_TO_RANGE(channel, 0, usbvision->video_inputs); |
2603 | usbvision->ctl_input = channel; | 2505 | usbvision->ctl_input = channel; |
2604 | 2506 | ||
2605 | // set the new channel | 2507 | /* set the new channel */ |
2606 | // Regular USB TV Tuners -> channel: 0 = Television, 1 = Composite, 2 = S-Video | 2508 | /* Regular USB TV Tuners -> channel: 0 = Television, 1 = Composite, 2 = S-Video */ |
2607 | // Four video input devices -> channel: 0 = Chan White, 1 = Chan Green, 2 = Chan Yellow, 3 = Chan Red | 2509 | /* Four video input devices -> channel: 0 = Chan White, 1 = Chan Green, 2 = Chan Yellow, 3 = Chan Red */ |
2608 | 2510 | ||
2609 | switch (usbvision_device_data[usbvision->DevModel].Codec) { | 2511 | switch (usbvision_device_data[usbvision->dev_model].codec) { |
2610 | case CODEC_SAA7113: | 2512 | case CODEC_SAA7113: |
2611 | mode[1] = SAA7115_COMPOSITE2; | 2513 | mode[1] = SAA7115_COMPOSITE2; |
2612 | if (SwitchSVideoInput) { | 2514 | if (switch_svideo_input) { |
2613 | /* To handle problems with S-Video Input for | 2515 | /* To handle problems with S-Video Input for |
2614 | * some devices. Use SwitchSVideoInput | 2516 | * some devices. Use switch_svideo_input |
2615 | * parameter when loading the module.*/ | 2517 | * parameter when loading the module.*/ |
2616 | mode[2] = SAA7115_COMPOSITE1; | 2518 | mode[2] = SAA7115_COMPOSITE1; |
2617 | } | 2519 | } else { |
2618 | else { | ||
2619 | mode[2] = SAA7115_SVIDEO1; | ||
2620 | } | ||
2621 | break; | ||
2622 | case CODEC_SAA7111: | ||
2623 | default: | ||
2624 | /* modes for saa7111 */ | ||
2625 | mode[1] = SAA7115_COMPOSITE1; | ||
2626 | mode[2] = SAA7115_SVIDEO1; | 2520 | mode[2] = SAA7115_SVIDEO1; |
2627 | break; | 2521 | } |
2522 | break; | ||
2523 | case CODEC_SAA7111: | ||
2524 | default: | ||
2525 | /* modes for saa7111 */ | ||
2526 | mode[1] = SAA7115_COMPOSITE1; | ||
2527 | mode[2] = SAA7115_SVIDEO1; | ||
2528 | break; | ||
2628 | } | 2529 | } |
2629 | call_all(usbvision, video, s_routing, mode[channel], 0, 0); | 2530 | call_all(usbvision, video, s_routing, mode[channel], 0, 0); |
2630 | usbvision_set_audio(usbvision, audio[channel]); | 2531 | usbvision_set_audio(usbvision, audio[channel]); |
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index 81dd53bb5267..05b1344181cd 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c | |||
@@ -28,18 +28,18 @@ | |||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <asm/uaccess.h> | 31 | #include <linux/uaccess.h> |
32 | #include <linux/ioport.h> | 32 | #include <linux/ioport.h> |
33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
34 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
35 | #include <linux/i2c.h> | 35 | #include <linux/i2c.h> |
36 | #include "usbvision.h" | 36 | #include "usbvision.h" |
37 | 37 | ||
38 | #define DBG_I2C 1<<0 | 38 | #define DBG_I2C (1 << 0) |
39 | 39 | ||
40 | static int i2c_debug; | 40 | static int i2c_debug; |
41 | 41 | ||
42 | module_param (i2c_debug, int, 0644); // debug_i2c_usb mode of the device driver | 42 | module_param(i2c_debug, int, 0644); /* debug_i2c_usb mode of the device driver */ |
43 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | 43 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); |
44 | 44 | ||
45 | #define PDEBUG(level, fmt, args...) { \ | 45 | #define PDEBUG(level, fmt, args...) { \ |
@@ -72,8 +72,8 @@ static inline int try_write_address(struct i2c_adapter *i2c_adap, | |||
72 | udelay(10); | 72 | udelay(10); |
73 | } | 73 | } |
74 | if (i) { | 74 | if (i) { |
75 | PDEBUG(DBG_I2C,"Needed %d retries for address %#2x", i, addr); | 75 | PDEBUG(DBG_I2C, "Needed %d retries for address %#2x", i, addr); |
76 | PDEBUG(DBG_I2C,"Maybe there's no device at this address"); | 76 | PDEBUG(DBG_I2C, "Maybe there's no device at this address"); |
77 | } | 77 | } |
78 | return ret; | 78 | return ret; |
79 | } | 79 | } |
@@ -96,8 +96,8 @@ static inline int try_read_address(struct i2c_adapter *i2c_adap, | |||
96 | udelay(10); | 96 | udelay(10); |
97 | } | 97 | } |
98 | if (i) { | 98 | if (i) { |
99 | PDEBUG(DBG_I2C,"Needed %d retries for address %#2x", i, addr); | 99 | PDEBUG(DBG_I2C, "Needed %d retries for address %#2x", i, addr); |
100 | PDEBUG(DBG_I2C,"Maybe there's no device at this address"); | 100 | PDEBUG(DBG_I2C, "Maybe there's no device at this address"); |
101 | } | 101 | } |
102 | return ret; | 102 | return ret; |
103 | } | 103 | } |
@@ -143,9 +143,8 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap, | |||
143 | else | 143 | else |
144 | ret = try_write_address(i2c_adap, addr, retries); | 144 | ret = try_write_address(i2c_adap, addr, retries); |
145 | 145 | ||
146 | if (ret != 1) { | 146 | if (ret != 1) |
147 | return -EREMOTEIO; | 147 | return -EREMOTEIO; |
148 | } | ||
149 | } | 148 | } |
150 | return 0; | 149 | return 0; |
151 | } | 150 | } |
@@ -164,22 +163,20 @@ usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) | |||
164 | pmsg = &msgs[i]; | 163 | pmsg = &msgs[i]; |
165 | ret = usb_find_address(i2c_adap, pmsg, i2c_adap->retries, &addr); | 164 | ret = usb_find_address(i2c_adap, pmsg, i2c_adap->retries, &addr); |
166 | if (ret != 0) { | 165 | if (ret != 0) { |
167 | PDEBUG(DBG_I2C,"got NAK from device, message #%d", i); | 166 | PDEBUG(DBG_I2C, "got NAK from device, message #%d", i); |
168 | return (ret < 0) ? ret : -EREMOTEIO; | 167 | return (ret < 0) ? ret : -EREMOTEIO; |
169 | } | 168 | } |
170 | 169 | ||
171 | if (pmsg->flags & I2C_M_RD) { | 170 | if (pmsg->flags & I2C_M_RD) { |
172 | /* read bytes into buffer */ | 171 | /* read bytes into buffer */ |
173 | ret = (usbvision_i2c_read(usbvision, addr, pmsg->buf, pmsg->len)); | 172 | ret = (usbvision_i2c_read(usbvision, addr, pmsg->buf, pmsg->len)); |
174 | if (ret < pmsg->len) { | 173 | if (ret < pmsg->len) |
175 | return (ret < 0) ? ret : -EREMOTEIO; | 174 | return (ret < 0) ? ret : -EREMOTEIO; |
176 | } | ||
177 | } else { | 175 | } else { |
178 | /* write bytes from buffer */ | 176 | /* write bytes from buffer */ |
179 | ret = (usbvision_i2c_write(usbvision, addr, pmsg->buf, pmsg->len)); | 177 | ret = (usbvision_i2c_write(usbvision, addr, pmsg->buf, pmsg->len)); |
180 | if (ret < pmsg->len) { | 178 | if (ret < pmsg->len) |
181 | return (ret < 0) ? ret : -EREMOTEIO; | 179 | return (ret < 0) ? ret : -EREMOTEIO; |
182 | } | ||
183 | } | 180 | } |
184 | } | 181 | } |
185 | return num; | 182 | return num; |
@@ -219,7 +216,7 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) | |||
219 | 216 | ||
220 | sprintf(usbvision->i2c_adap.name, "%s-%d-%s", i2c_adap_template.name, | 217 | sprintf(usbvision->i2c_adap.name, "%s-%d-%s", i2c_adap_template.name, |
221 | usbvision->dev->bus->busnum, usbvision->dev->devpath); | 218 | usbvision->dev->bus->busnum, usbvision->dev->devpath); |
222 | PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name); | 219 | PDEBUG(DBG_I2C, "Adaptername: %s", usbvision->i2c_adap.name); |
223 | usbvision->i2c_adap.dev.parent = &usbvision->dev->dev; | 220 | usbvision->i2c_adap.dev.parent = &usbvision->dev->dev; |
224 | 221 | ||
225 | i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev); | 222 | i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev); |
@@ -244,7 +241,7 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) | |||
244 | PDEBUG(DBG_I2C, "i2c bus for %s registered", usbvision->i2c_adap.name); | 241 | PDEBUG(DBG_I2C, "i2c bus for %s registered", usbvision->i2c_adap.name); |
245 | 242 | ||
246 | /* Request the load of the i2c modules we need */ | 243 | /* Request the load of the i2c modules we need */ |
247 | switch (usbvision_device_data[usbvision->DevModel].Codec) { | 244 | switch (usbvision_device_data[usbvision->dev_model].codec) { |
248 | case CODEC_SAA7113: | 245 | case CODEC_SAA7113: |
249 | case CODEC_SAA7111: | 246 | case CODEC_SAA7111: |
250 | /* Without this delay the detection of the saa711x is | 247 | /* Without this delay the detection of the saa711x is |
@@ -255,7 +252,7 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) | |||
255 | "saa7115_auto", 0, saa711x_addrs); | 252 | "saa7115_auto", 0, saa711x_addrs); |
256 | break; | 253 | break; |
257 | } | 254 | } |
258 | if (usbvision_device_data[usbvision->DevModel].Tuner == 1) { | 255 | if (usbvision_device_data[usbvision->dev_model].tuner == 1) { |
259 | struct v4l2_subdev *sd; | 256 | struct v4l2_subdev *sd; |
260 | enum v4l2_i2c_tuner_type type; | 257 | enum v4l2_i2c_tuner_type type; |
261 | struct tuner_setup tun_setup; | 258 | struct tuner_setup tun_setup; |
@@ -293,7 +290,7 @@ int usbvision_i2c_unregister(struct usb_usbvision *usbvision) | |||
293 | i2c_del_adapter(&(usbvision->i2c_adap)); | 290 | i2c_del_adapter(&(usbvision->i2c_adap)); |
294 | usbvision->registered_i2c = 0; | 291 | usbvision->registered_i2c = 0; |
295 | 292 | ||
296 | PDEBUG(DBG_I2C,"i2c bus for %s unregistered", usbvision->i2c_adap.name); | 293 | PDEBUG(DBG_I2C, "i2c bus for %s unregistered", usbvision->i2c_adap.name); |
297 | 294 | ||
298 | return 0; | 295 | return 0; |
299 | } | 296 | } |
@@ -355,9 +352,9 @@ usbvision_i2c_read_max4(struct usb_usbvision *usbvision, unsigned char addr, | |||
355 | 352 | ||
356 | if (i2c_debug & DBG_I2C) { | 353 | if (i2c_debug & DBG_I2C) { |
357 | int idx; | 354 | int idx; |
358 | for (idx = 0; idx < len; idx++) { | 355 | |
359 | PDEBUG(DBG_I2C,"read %x from address %x", (unsigned char)buf[idx], addr); | 356 | for (idx = 0; idx < len; idx++) |
360 | } | 357 | PDEBUG(DBG_I2C, "read %x from address %x", (unsigned char)buf[idx], addr); |
361 | } | 358 | } |
362 | return len; | 359 | return len; |
363 | } | 360 | } |
@@ -416,9 +413,9 @@ static int usbvision_i2c_write_max4(struct usb_usbvision *usbvision, | |||
416 | 413 | ||
417 | if (i2c_debug & DBG_I2C) { | 414 | if (i2c_debug & DBG_I2C) { |
418 | int idx; | 415 | int idx; |
419 | for (idx = 0; idx < len; idx++) { | 416 | |
420 | PDEBUG(DBG_I2C,"wrote %x at address %x", (unsigned char)buf[idx], addr); | 417 | for (idx = 0; idx < len; idx++) |
421 | } | 418 | PDEBUG(DBG_I2C, "wrote %x at address %x", (unsigned char)buf[idx], addr); |
422 | } | 419 | } |
423 | return len; | 420 | return len; |
424 | } | 421 | } |
@@ -426,18 +423,18 @@ static int usbvision_i2c_write_max4(struct usb_usbvision *usbvision, | |||
426 | static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf, | 423 | static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf, |
427 | short len) | 424 | short len) |
428 | { | 425 | { |
429 | char *bufPtr = buf; | 426 | char *buf_ptr = buf; |
430 | int retval; | 427 | int retval; |
431 | int wrcount = 0; | 428 | int wrcount = 0; |
432 | int count; | 429 | int count; |
433 | int maxLen = 4; | 430 | int max_len = 4; |
434 | 431 | ||
435 | while (len > 0) { | 432 | while (len > 0) { |
436 | count = (len > maxLen) ? maxLen : len; | 433 | count = (len > max_len) ? max_len : len; |
437 | retval = usbvision_i2c_write_max4(usbvision, addr, bufPtr, count); | 434 | retval = usbvision_i2c_write_max4(usbvision, addr, buf_ptr, count); |
438 | if (retval > 0) { | 435 | if (retval > 0) { |
439 | len -= count; | 436 | len -= count; |
440 | bufPtr += count; | 437 | buf_ptr += count; |
441 | wrcount += count; | 438 | wrcount += count; |
442 | } else | 439 | } else |
443 | return (retval < 0) ? retval : -EFAULT; | 440 | return (retval < 0) ? retval : -EFAULT; |
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 011c0c386995..6083137f0bf8 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
@@ -56,7 +56,7 @@ | |||
56 | #include <linux/module.h> | 56 | #include <linux/module.h> |
57 | #include <linux/init.h> | 57 | #include <linux/init.h> |
58 | #include <linux/spinlock.h> | 58 | #include <linux/spinlock.h> |
59 | #include <asm/io.h> | 59 | #include <linux/io.h> |
60 | #include <linux/videodev2.h> | 60 | #include <linux/videodev2.h> |
61 | #include <linux/i2c.h> | 61 | #include <linux/i2c.h> |
62 | 62 | ||
@@ -70,8 +70,8 @@ | |||
70 | #include "usbvision.h" | 70 | #include "usbvision.h" |
71 | #include "usbvision-cards.h" | 71 | #include "usbvision-cards.h" |
72 | 72 | ||
73 | #define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>,\ | 73 | #define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>, \ |
74 | Dwaine Garden <DwaineGarden@rogers.com>" | 74 | Dwaine Garden <DwaineGarden@rogers.com>" |
75 | #define DRIVER_NAME "usbvision" | 75 | #define DRIVER_NAME "usbvision" |
76 | #define DRIVER_ALIAS "USBVision" | 76 | #define DRIVER_ALIAS "USBVision" |
77 | #define DRIVER_DESC "USBVision USB Video Device Driver for Linux" | 77 | #define DRIVER_DESC "USBVision USB Video Device Driver for Linux" |
@@ -82,9 +82,9 @@ | |||
82 | #define USBVISION_DRIVER_VERSION KERNEL_VERSION(USBVISION_DRIVER_VERSION_MAJOR,\ | 82 | #define USBVISION_DRIVER_VERSION KERNEL_VERSION(USBVISION_DRIVER_VERSION_MAJOR,\ |
83 | USBVISION_DRIVER_VERSION_MINOR,\ | 83 | USBVISION_DRIVER_VERSION_MINOR,\ |
84 | USBVISION_DRIVER_VERSION_PATCHLEVEL) | 84 | USBVISION_DRIVER_VERSION_PATCHLEVEL) |
85 | #define USBVISION_VERSION_STRING __stringify(USBVISION_DRIVER_VERSION_MAJOR)\ | 85 | #define USBVISION_VERSION_STRING __stringify(USBVISION_DRIVER_VERSION_MAJOR) \ |
86 | "." __stringify(USBVISION_DRIVER_VERSION_MINOR)\ | 86 | "." __stringify(USBVISION_DRIVER_VERSION_MINOR) \ |
87 | "." __stringify(USBVISION_DRIVER_VERSION_PATCHLEVEL) | 87 | "." __stringify(USBVISION_DRIVER_VERSION_PATCHLEVEL) |
88 | 88 | ||
89 | #define ENABLE_HEXDUMP 0 /* Enable if you need it */ | 89 | #define ENABLE_HEXDUMP 0 /* Enable if you need it */ |
90 | 90 | ||
@@ -96,16 +96,16 @@ USBVISION_DRIVER_VERSION_PATCHLEVEL) | |||
96 | __func__, __LINE__ , ## args); \ | 96 | __func__, __LINE__ , ## args); \ |
97 | } | 97 | } |
98 | #else | 98 | #else |
99 | #define PDEBUG(level, fmt, args...) do {} while(0) | 99 | #define PDEBUG(level, fmt, args...) do {} while (0) |
100 | #endif | 100 | #endif |
101 | 101 | ||
102 | #define DBG_IO 1<<1 | 102 | #define DBG_IO (1 << 1) |
103 | #define DBG_PROBE 1<<2 | 103 | #define DBG_PROBE (1 << 2) |
104 | #define DBG_MMAP 1<<3 | 104 | #define DBG_MMAP (1 << 3) |
105 | 105 | ||
106 | //String operations | 106 | /* String operations */ |
107 | #define rmspace(str) while(*str==' ') str++; | 107 | #define rmspace(str) while (*str == ' ') str++; |
108 | #define goto2next(str) while(*str!=' ') str++; while(*str==' ') str++; | 108 | #define goto2next(str) while (*str != ' ') str++; while (*str == ' ') str++; |
109 | 109 | ||
110 | 110 | ||
111 | /* sequential number of usbvision device */ | 111 | /* sequential number of usbvision device */ |
@@ -118,7 +118,7 @@ static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = { | |||
118 | { 1, 4, 32, V4L2_PIX_FMT_RGB32 , "RGB32" }, | 118 | { 1, 4, 32, V4L2_PIX_FMT_RGB32 , "RGB32" }, |
119 | { 1, 2, 16, V4L2_PIX_FMT_RGB555 , "RGB555" }, | 119 | { 1, 2, 16, V4L2_PIX_FMT_RGB555 , "RGB555" }, |
120 | { 1, 2, 16, V4L2_PIX_FMT_YUYV , "YUV422" }, | 120 | { 1, 2, 16, V4L2_PIX_FMT_YUYV , "YUV422" }, |
121 | { 1, 2, 12, V4L2_PIX_FMT_YVU420 , "YUV420P" }, // 1.5 ! | 121 | { 1, 2, 12, V4L2_PIX_FMT_YVU420 , "YUV420P" }, /* 1.5 ! */ |
122 | { 1, 2, 16, V4L2_PIX_FMT_YUV422P , "YUV422P" } | 122 | { 1, 2, 16, V4L2_PIX_FMT_YUV422P , "YUV422P" } |
123 | }; | 123 | }; |
124 | 124 | ||
@@ -127,11 +127,11 @@ static void usbvision_release(struct usb_usbvision *usbvision); | |||
127 | 127 | ||
128 | /* Default initialization of device driver parameters */ | 128 | /* Default initialization of device driver parameters */ |
129 | /* Set the default format for ISOC endpoint */ | 129 | /* Set the default format for ISOC endpoint */ |
130 | static int isocMode = ISOC_MODE_COMPRESS; | 130 | static int isoc_mode = ISOC_MODE_COMPRESS; |
131 | /* Set the default Debug Mode of the device driver */ | 131 | /* Set the default Debug Mode of the device driver */ |
132 | static int video_debug; | 132 | static int video_debug; |
133 | /* Set the default device to power on at startup */ | 133 | /* Set the default device to power on at startup */ |
134 | static int PowerOnAtOpen = 1; | 134 | static int power_on_at_open = 1; |
135 | /* Sequential Number of Video Device */ | 135 | /* Sequential Number of Video Device */ |
136 | static int video_nr = -1; | 136 | static int video_nr = -1; |
137 | /* Sequential Number of Radio Device */ | 137 | /* Sequential Number of Radio Device */ |
@@ -140,20 +140,20 @@ static int radio_nr = -1; | |||
140 | /* Grab parameters for the device driver */ | 140 | /* Grab parameters for the device driver */ |
141 | 141 | ||
142 | /* Showing parameters under SYSFS */ | 142 | /* Showing parameters under SYSFS */ |
143 | module_param(isocMode, int, 0444); | 143 | module_param(isoc_mode, int, 0444); |
144 | module_param(video_debug, int, 0444); | 144 | module_param(video_debug, int, 0444); |
145 | module_param(PowerOnAtOpen, int, 0444); | 145 | module_param(power_on_at_open, int, 0444); |
146 | module_param(video_nr, int, 0444); | 146 | module_param(video_nr, int, 0444); |
147 | module_param(radio_nr, int, 0444); | 147 | module_param(radio_nr, int, 0444); |
148 | 148 | ||
149 | MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)"); | 149 | MODULE_PARM_DESC(isoc_mode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)"); |
150 | MODULE_PARM_DESC(video_debug, " Set the default Debug Mode of the device driver. Default: 0 (Off)"); | 150 | MODULE_PARM_DESC(video_debug, " Set the default Debug Mode of the device driver. Default: 0 (Off)"); |
151 | MODULE_PARM_DESC(PowerOnAtOpen, " Set the default device to power on when device is opened. Default: 1 (On)"); | 151 | MODULE_PARM_DESC(power_on_at_open, " Set the default device to power on when device is opened. Default: 1 (On)"); |
152 | MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)"); | 152 | MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)"); |
153 | MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)"); | 153 | MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)"); |
154 | 154 | ||
155 | 155 | ||
156 | // Misc stuff | 156 | /* Misc stuff */ |
157 | MODULE_AUTHOR(DRIVER_AUTHOR); | 157 | MODULE_AUTHOR(DRIVER_AUTHOR); |
158 | MODULE_DESCRIPTION(DRIVER_DESC); | 158 | MODULE_DESCRIPTION(DRIVER_DESC); |
159 | MODULE_LICENSE(DRIVER_LICENSE); | 159 | MODULE_LICENSE(DRIVER_LICENSE); |
@@ -192,7 +192,7 @@ static ssize_t show_model(struct device *cd, | |||
192 | container_of(cd, struct video_device, dev); | 192 | container_of(cd, struct video_device, dev); |
193 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); | 193 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); |
194 | return sprintf(buf, "%s\n", | 194 | return sprintf(buf, "%s\n", |
195 | usbvision_device_data[usbvision->DevModel].ModelString); | 195 | usbvision_device_data[usbvision->dev_model].model_string); |
196 | } | 196 | } |
197 | static DEVICE_ATTR(model, S_IRUGO, show_model, NULL); | 197 | static DEVICE_ATTR(model, S_IRUGO, show_model, NULL); |
198 | 198 | ||
@@ -205,7 +205,7 @@ static ssize_t show_hue(struct device *cd, | |||
205 | struct v4l2_control ctrl; | 205 | struct v4l2_control ctrl; |
206 | ctrl.id = V4L2_CID_HUE; | 206 | ctrl.id = V4L2_CID_HUE; |
207 | ctrl.value = 0; | 207 | ctrl.value = 0; |
208 | if(usbvision->user) | 208 | if (usbvision->user) |
209 | call_all(usbvision, core, g_ctrl, &ctrl); | 209 | call_all(usbvision, core, g_ctrl, &ctrl); |
210 | return sprintf(buf, "%d\n", ctrl.value); | 210 | return sprintf(buf, "%d\n", ctrl.value); |
211 | } | 211 | } |
@@ -220,7 +220,7 @@ static ssize_t show_contrast(struct device *cd, | |||
220 | struct v4l2_control ctrl; | 220 | struct v4l2_control ctrl; |
221 | ctrl.id = V4L2_CID_CONTRAST; | 221 | ctrl.id = V4L2_CID_CONTRAST; |
222 | ctrl.value = 0; | 222 | ctrl.value = 0; |
223 | if(usbvision->user) | 223 | if (usbvision->user) |
224 | call_all(usbvision, core, g_ctrl, &ctrl); | 224 | call_all(usbvision, core, g_ctrl, &ctrl); |
225 | return sprintf(buf, "%d\n", ctrl.value); | 225 | return sprintf(buf, "%d\n", ctrl.value); |
226 | } | 226 | } |
@@ -235,7 +235,7 @@ static ssize_t show_brightness(struct device *cd, | |||
235 | struct v4l2_control ctrl; | 235 | struct v4l2_control ctrl; |
236 | ctrl.id = V4L2_CID_BRIGHTNESS; | 236 | ctrl.id = V4L2_CID_BRIGHTNESS; |
237 | ctrl.value = 0; | 237 | ctrl.value = 0; |
238 | if(usbvision->user) | 238 | if (usbvision->user) |
239 | call_all(usbvision, core, g_ctrl, &ctrl); | 239 | call_all(usbvision, core, g_ctrl, &ctrl); |
240 | return sprintf(buf, "%d\n", ctrl.value); | 240 | return sprintf(buf, "%d\n", ctrl.value); |
241 | } | 241 | } |
@@ -250,7 +250,7 @@ static ssize_t show_saturation(struct device *cd, | |||
250 | struct v4l2_control ctrl; | 250 | struct v4l2_control ctrl; |
251 | ctrl.id = V4L2_CID_SATURATION; | 251 | ctrl.id = V4L2_CID_SATURATION; |
252 | ctrl.value = 0; | 252 | ctrl.value = 0; |
253 | if(usbvision->user) | 253 | if (usbvision->user) |
254 | call_all(usbvision, core, g_ctrl, &ctrl); | 254 | call_all(usbvision, core, g_ctrl, &ctrl); |
255 | return sprintf(buf, "%d\n", ctrl.value); | 255 | return sprintf(buf, "%d\n", ctrl.value); |
256 | } | 256 | } |
@@ -263,7 +263,7 @@ static ssize_t show_streaming(struct device *cd, | |||
263 | container_of(cd, struct video_device, dev); | 263 | container_of(cd, struct video_device, dev); |
264 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); | 264 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); |
265 | return sprintf(buf, "%s\n", | 265 | return sprintf(buf, "%s\n", |
266 | YES_NO(usbvision->streaming==Stream_On?1:0)); | 266 | YES_NO(usbvision->streaming == stream_on ? 1 : 0)); |
267 | } | 267 | } |
268 | static DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL); | 268 | static DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL); |
269 | 269 | ||
@@ -274,7 +274,7 @@ static ssize_t show_compression(struct device *cd, | |||
274 | container_of(cd, struct video_device, dev); | 274 | container_of(cd, struct video_device, dev); |
275 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); | 275 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); |
276 | return sprintf(buf, "%s\n", | 276 | return sprintf(buf, "%s\n", |
277 | YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS)); | 277 | YES_NO(usbvision->isoc_mode == ISOC_MODE_COMPRESS)); |
278 | } | 278 | } |
279 | static DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL); | 279 | static DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL); |
280 | 280 | ||
@@ -284,42 +284,43 @@ static ssize_t show_device_bridge(struct device *cd, | |||
284 | struct video_device *vdev = | 284 | struct video_device *vdev = |
285 | container_of(cd, struct video_device, dev); | 285 | container_of(cd, struct video_device, dev); |
286 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); | 286 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); |
287 | return sprintf(buf, "%d\n", usbvision->bridgeType); | 287 | return sprintf(buf, "%d\n", usbvision->bridge_type); |
288 | } | 288 | } |
289 | static DEVICE_ATTR(bridge, S_IRUGO, show_device_bridge, NULL); | 289 | static DEVICE_ATTR(bridge, S_IRUGO, show_device_bridge, NULL); |
290 | 290 | ||
291 | static void usbvision_create_sysfs(struct video_device *vdev) | 291 | static void usbvision_create_sysfs(struct video_device *vdev) |
292 | { | 292 | { |
293 | int res; | 293 | int res; |
294 | |||
294 | if (!vdev) | 295 | if (!vdev) |
295 | return; | 296 | return; |
296 | do { | 297 | do { |
297 | res = device_create_file(&vdev->dev, &dev_attr_version); | 298 | res = device_create_file(&vdev->dev, &dev_attr_version); |
298 | if (res<0) | 299 | if (res < 0) |
299 | break; | 300 | break; |
300 | res = device_create_file(&vdev->dev, &dev_attr_model); | 301 | res = device_create_file(&vdev->dev, &dev_attr_model); |
301 | if (res<0) | 302 | if (res < 0) |
302 | break; | 303 | break; |
303 | res = device_create_file(&vdev->dev, &dev_attr_hue); | 304 | res = device_create_file(&vdev->dev, &dev_attr_hue); |
304 | if (res<0) | 305 | if (res < 0) |
305 | break; | 306 | break; |
306 | res = device_create_file(&vdev->dev, &dev_attr_contrast); | 307 | res = device_create_file(&vdev->dev, &dev_attr_contrast); |
307 | if (res<0) | 308 | if (res < 0) |
308 | break; | 309 | break; |
309 | res = device_create_file(&vdev->dev, &dev_attr_brightness); | 310 | res = device_create_file(&vdev->dev, &dev_attr_brightness); |
310 | if (res<0) | 311 | if (res < 0) |
311 | break; | 312 | break; |
312 | res = device_create_file(&vdev->dev, &dev_attr_saturation); | 313 | res = device_create_file(&vdev->dev, &dev_attr_saturation); |
313 | if (res<0) | 314 | if (res < 0) |
314 | break; | 315 | break; |
315 | res = device_create_file(&vdev->dev, &dev_attr_streaming); | 316 | res = device_create_file(&vdev->dev, &dev_attr_streaming); |
316 | if (res<0) | 317 | if (res < 0) |
317 | break; | 318 | break; |
318 | res = device_create_file(&vdev->dev, &dev_attr_compression); | 319 | res = device_create_file(&vdev->dev, &dev_attr_compression); |
319 | if (res<0) | 320 | if (res < 0) |
320 | break; | 321 | break; |
321 | res = device_create_file(&vdev->dev, &dev_attr_bridge); | 322 | res = device_create_file(&vdev->dev, &dev_attr_bridge); |
322 | if (res>=0) | 323 | if (res >= 0) |
323 | return; | 324 | return; |
324 | } while (0); | 325 | } while (0); |
325 | 326 | ||
@@ -352,24 +353,23 @@ static void usbvision_remove_sysfs(struct video_device *vdev) | |||
352 | static int usbvision_v4l2_open(struct file *file) | 353 | static int usbvision_v4l2_open(struct file *file) |
353 | { | 354 | { |
354 | struct usb_usbvision *usbvision = video_drvdata(file); | 355 | struct usb_usbvision *usbvision = video_drvdata(file); |
355 | int errCode = 0; | 356 | int err_code = 0; |
356 | 357 | ||
357 | PDEBUG(DBG_IO, "open"); | 358 | PDEBUG(DBG_IO, "open"); |
358 | 359 | ||
359 | mutex_lock(&usbvision->lock); | 360 | usbvision_reset_power_off_timer(usbvision); |
360 | usbvision_reset_powerOffTimer(usbvision); | ||
361 | 361 | ||
362 | if (usbvision->user) | 362 | if (usbvision->user) |
363 | errCode = -EBUSY; | 363 | err_code = -EBUSY; |
364 | else { | 364 | else { |
365 | /* Allocate memory for the scratch ring buffer */ | 365 | /* Allocate memory for the scratch ring buffer */ |
366 | errCode = usbvision_scratch_alloc(usbvision); | 366 | err_code = usbvision_scratch_alloc(usbvision); |
367 | if (isocMode==ISOC_MODE_COMPRESS) { | 367 | if (isoc_mode == ISOC_MODE_COMPRESS) { |
368 | /* Allocate intermediate decompression buffers | 368 | /* Allocate intermediate decompression buffers |
369 | only if needed */ | 369 | only if needed */ |
370 | errCode = usbvision_decompress_alloc(usbvision); | 370 | err_code = usbvision_decompress_alloc(usbvision); |
371 | } | 371 | } |
372 | if (errCode) { | 372 | if (err_code) { |
373 | /* Deallocate all buffers if trouble */ | 373 | /* Deallocate all buffers if trouble */ |
374 | usbvision_scratch_free(usbvision); | 374 | usbvision_scratch_free(usbvision); |
375 | usbvision_decompress_free(usbvision); | 375 | usbvision_decompress_free(usbvision); |
@@ -377,7 +377,7 @@ static int usbvision_v4l2_open(struct file *file) | |||
377 | } | 377 | } |
378 | 378 | ||
379 | /* If so far no errors then we shall start the camera */ | 379 | /* If so far no errors then we shall start the camera */ |
380 | if (!errCode) { | 380 | if (!err_code) { |
381 | if (usbvision->power == 0) { | 381 | if (usbvision->power == 0) { |
382 | usbvision_power_on(usbvision); | 382 | usbvision_power_on(usbvision); |
383 | usbvision_i2c_register(usbvision); | 383 | usbvision_i2c_register(usbvision); |
@@ -386,21 +386,21 @@ static int usbvision_v4l2_open(struct file *file) | |||
386 | /* Send init sequence only once, it's large! */ | 386 | /* Send init sequence only once, it's large! */ |
387 | if (!usbvision->initialized) { | 387 | if (!usbvision->initialized) { |
388 | int setup_ok = 0; | 388 | int setup_ok = 0; |
389 | setup_ok = usbvision_setup(usbvision,isocMode); | 389 | setup_ok = usbvision_setup(usbvision, isoc_mode); |
390 | if (setup_ok) | 390 | if (setup_ok) |
391 | usbvision->initialized = 1; | 391 | usbvision->initialized = 1; |
392 | else | 392 | else |
393 | errCode = -EBUSY; | 393 | err_code = -EBUSY; |
394 | } | 394 | } |
395 | 395 | ||
396 | if (!errCode) { | 396 | if (!err_code) { |
397 | usbvision_begin_streaming(usbvision); | 397 | usbvision_begin_streaming(usbvision); |
398 | errCode = usbvision_init_isoc(usbvision); | 398 | err_code = usbvision_init_isoc(usbvision); |
399 | /* device must be initialized before isoc transfer */ | 399 | /* device must be initialized before isoc transfer */ |
400 | usbvision_muxsel(usbvision,0); | 400 | usbvision_muxsel(usbvision, 0); |
401 | usbvision->user++; | 401 | usbvision->user++; |
402 | } else { | 402 | } else { |
403 | if (PowerOnAtOpen) { | 403 | if (power_on_at_open) { |
404 | usbvision_i2c_unregister(usbvision); | 404 | usbvision_i2c_unregister(usbvision); |
405 | usbvision_power_off(usbvision); | 405 | usbvision_power_off(usbvision); |
406 | usbvision->initialized = 0; | 406 | usbvision->initialized = 0; |
@@ -412,8 +412,7 @@ static int usbvision_v4l2_open(struct file *file) | |||
412 | usbvision_empty_framequeues(usbvision); | 412 | usbvision_empty_framequeues(usbvision); |
413 | 413 | ||
414 | PDEBUG(DBG_IO, "success"); | 414 | PDEBUG(DBG_IO, "success"); |
415 | mutex_unlock(&usbvision->lock); | 415 | return err_code; |
416 | return errCode; | ||
417 | } | 416 | } |
418 | 417 | ||
419 | /* | 418 | /* |
@@ -429,7 +428,6 @@ static int usbvision_v4l2_close(struct file *file) | |||
429 | struct usb_usbvision *usbvision = video_drvdata(file); | 428 | struct usb_usbvision *usbvision = video_drvdata(file); |
430 | 429 | ||
431 | PDEBUG(DBG_IO, "close"); | 430 | PDEBUG(DBG_IO, "close"); |
432 | mutex_lock(&usbvision->lock); | ||
433 | 431 | ||
434 | usbvision_audio_off(usbvision); | 432 | usbvision_audio_off(usbvision); |
435 | usbvision_restart_isoc(usbvision); | 433 | usbvision_restart_isoc(usbvision); |
@@ -442,15 +440,13 @@ static int usbvision_v4l2_close(struct file *file) | |||
442 | 440 | ||
443 | usbvision->user--; | 441 | usbvision->user--; |
444 | 442 | ||
445 | if (PowerOnAtOpen) { | 443 | if (power_on_at_open) { |
446 | /* power off in a little while | 444 | /* power off in a little while |
447 | to avoid off/on every close/open short sequences */ | 445 | to avoid off/on every close/open short sequences */ |
448 | usbvision_set_powerOffTimer(usbvision); | 446 | usbvision_set_power_off_timer(usbvision); |
449 | usbvision->initialized = 0; | 447 | usbvision->initialized = 0; |
450 | } | 448 | } |
451 | 449 | ||
452 | mutex_unlock(&usbvision->lock); | ||
453 | |||
454 | if (usbvision->remove_pending) { | 450 | if (usbvision->remove_pending) { |
455 | printk(KERN_INFO "%s: Final disconnect\n", __func__); | 451 | printk(KERN_INFO "%s: Final disconnect\n", __func__); |
456 | usbvision_release(usbvision); | 452 | usbvision_release(usbvision); |
@@ -468,55 +464,55 @@ static int usbvision_v4l2_close(struct file *file) | |||
468 | * | 464 | * |
469 | */ | 465 | */ |
470 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 466 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
471 | static int vidioc_g_register (struct file *file, void *priv, | 467 | static int vidioc_g_register(struct file *file, void *priv, |
472 | struct v4l2_dbg_register *reg) | 468 | struct v4l2_dbg_register *reg) |
473 | { | 469 | { |
474 | struct usb_usbvision *usbvision = video_drvdata(file); | 470 | struct usb_usbvision *usbvision = video_drvdata(file); |
475 | int errCode; | 471 | int err_code; |
476 | 472 | ||
477 | if (!v4l2_chip_match_host(®->match)) | 473 | if (!v4l2_chip_match_host(®->match)) |
478 | return -EINVAL; | 474 | return -EINVAL; |
479 | /* NT100x has a 8-bit register space */ | 475 | /* NT100x has a 8-bit register space */ |
480 | errCode = usbvision_read_reg(usbvision, reg->reg&0xff); | 476 | err_code = usbvision_read_reg(usbvision, reg->reg&0xff); |
481 | if (errCode < 0) { | 477 | if (err_code < 0) { |
482 | dev_err(&usbvision->vdev->dev, | 478 | dev_err(&usbvision->vdev->dev, |
483 | "%s: VIDIOC_DBG_G_REGISTER failed: error %d\n", | 479 | "%s: VIDIOC_DBG_G_REGISTER failed: error %d\n", |
484 | __func__, errCode); | 480 | __func__, err_code); |
485 | return errCode; | 481 | return err_code; |
486 | } | 482 | } |
487 | reg->val = errCode; | 483 | reg->val = err_code; |
488 | reg->size = 1; | 484 | reg->size = 1; |
489 | return 0; | 485 | return 0; |
490 | } | 486 | } |
491 | 487 | ||
492 | static int vidioc_s_register (struct file *file, void *priv, | 488 | static int vidioc_s_register(struct file *file, void *priv, |
493 | struct v4l2_dbg_register *reg) | 489 | struct v4l2_dbg_register *reg) |
494 | { | 490 | { |
495 | struct usb_usbvision *usbvision = video_drvdata(file); | 491 | struct usb_usbvision *usbvision = video_drvdata(file); |
496 | int errCode; | 492 | int err_code; |
497 | 493 | ||
498 | if (!v4l2_chip_match_host(®->match)) | 494 | if (!v4l2_chip_match_host(®->match)) |
499 | return -EINVAL; | 495 | return -EINVAL; |
500 | /* NT100x has a 8-bit register space */ | 496 | /* NT100x has a 8-bit register space */ |
501 | errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); | 497 | err_code = usbvision_write_reg(usbvision, reg->reg & 0xff, reg->val); |
502 | if (errCode < 0) { | 498 | if (err_code < 0) { |
503 | dev_err(&usbvision->vdev->dev, | 499 | dev_err(&usbvision->vdev->dev, |
504 | "%s: VIDIOC_DBG_S_REGISTER failed: error %d\n", | 500 | "%s: VIDIOC_DBG_S_REGISTER failed: error %d\n", |
505 | __func__, errCode); | 501 | __func__, err_code); |
506 | return errCode; | 502 | return err_code; |
507 | } | 503 | } |
508 | return 0; | 504 | return 0; |
509 | } | 505 | } |
510 | #endif | 506 | #endif |
511 | 507 | ||
512 | static int vidioc_querycap (struct file *file, void *priv, | 508 | static int vidioc_querycap(struct file *file, void *priv, |
513 | struct v4l2_capability *vc) | 509 | struct v4l2_capability *vc) |
514 | { | 510 | { |
515 | struct usb_usbvision *usbvision = video_drvdata(file); | 511 | struct usb_usbvision *usbvision = video_drvdata(file); |
516 | 512 | ||
517 | strlcpy(vc->driver, "USBVision", sizeof(vc->driver)); | 513 | strlcpy(vc->driver, "USBVision", sizeof(vc->driver)); |
518 | strlcpy(vc->card, | 514 | strlcpy(vc->card, |
519 | usbvision_device_data[usbvision->DevModel].ModelString, | 515 | usbvision_device_data[usbvision->dev_model].model_string, |
520 | sizeof(vc->card)); | 516 | sizeof(vc->card)); |
521 | usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info)); | 517 | usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info)); |
522 | vc->version = USBVISION_DRIVER_VERSION; | 518 | vc->version = USBVISION_DRIVER_VERSION; |
@@ -528,7 +524,7 @@ static int vidioc_querycap (struct file *file, void *priv, | |||
528 | return 0; | 524 | return 0; |
529 | } | 525 | } |
530 | 526 | ||
531 | static int vidioc_enum_input (struct file *file, void *priv, | 527 | static int vidioc_enum_input(struct file *file, void *priv, |
532 | struct v4l2_input *vi) | 528 | struct v4l2_input *vi) |
533 | { | 529 | { |
534 | struct usb_usbvision *usbvision = video_drvdata(file); | 530 | struct usb_usbvision *usbvision = video_drvdata(file); |
@@ -536,16 +532,16 @@ static int vidioc_enum_input (struct file *file, void *priv, | |||
536 | 532 | ||
537 | if (vi->index >= usbvision->video_inputs) | 533 | if (vi->index >= usbvision->video_inputs) |
538 | return -EINVAL; | 534 | return -EINVAL; |
539 | if (usbvision->have_tuner) { | 535 | if (usbvision->have_tuner) |
540 | chan = vi->index; | 536 | chan = vi->index; |
541 | } else { | 537 | else |
542 | chan = vi->index + 1; /*skip Television string*/ | 538 | chan = vi->index + 1; /* skip Television string*/ |
543 | } | 539 | |
544 | /* Determine the requested input characteristics | 540 | /* Determine the requested input characteristics |
545 | specific for each usbvision card model */ | 541 | specific for each usbvision card model */ |
546 | switch(chan) { | 542 | switch (chan) { |
547 | case 0: | 543 | case 0: |
548 | if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) { | 544 | if (usbvision_device_data[usbvision->dev_model].video_channels == 4) { |
549 | strcpy(vi->name, "White Video Input"); | 545 | strcpy(vi->name, "White Video Input"); |
550 | } else { | 546 | } else { |
551 | strcpy(vi->name, "Television"); | 547 | strcpy(vi->name, "Television"); |
@@ -557,20 +553,18 @@ static int vidioc_enum_input (struct file *file, void *priv, | |||
557 | break; | 553 | break; |
558 | case 1: | 554 | case 1: |
559 | vi->type = V4L2_INPUT_TYPE_CAMERA; | 555 | vi->type = V4L2_INPUT_TYPE_CAMERA; |
560 | if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) { | 556 | if (usbvision_device_data[usbvision->dev_model].video_channels == 4) |
561 | strcpy(vi->name, "Green Video Input"); | 557 | strcpy(vi->name, "Green Video Input"); |
562 | } else { | 558 | else |
563 | strcpy(vi->name, "Composite Video Input"); | 559 | strcpy(vi->name, "Composite Video Input"); |
564 | } | ||
565 | vi->std = V4L2_STD_PAL; | 560 | vi->std = V4L2_STD_PAL; |
566 | break; | 561 | break; |
567 | case 2: | 562 | case 2: |
568 | vi->type = V4L2_INPUT_TYPE_CAMERA; | 563 | vi->type = V4L2_INPUT_TYPE_CAMERA; |
569 | if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) { | 564 | if (usbvision_device_data[usbvision->dev_model].video_channels == 4) |
570 | strcpy(vi->name, "Yellow Video Input"); | 565 | strcpy(vi->name, "Yellow Video Input"); |
571 | } else { | 566 | else |
572 | strcpy(vi->name, "S-Video Input"); | 567 | strcpy(vi->name, "S-Video Input"); |
573 | } | ||
574 | vi->std = V4L2_STD_PAL; | 568 | vi->std = V4L2_STD_PAL; |
575 | break; | 569 | break; |
576 | case 3: | 570 | case 3: |
@@ -582,7 +576,7 @@ static int vidioc_enum_input (struct file *file, void *priv, | |||
582 | return 0; | 576 | return 0; |
583 | } | 577 | } |
584 | 578 | ||
585 | static int vidioc_g_input (struct file *file, void *priv, unsigned int *input) | 579 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *input) |
586 | { | 580 | { |
587 | struct usb_usbvision *usbvision = video_drvdata(file); | 581 | struct usb_usbvision *usbvision = video_drvdata(file); |
588 | 582 | ||
@@ -590,46 +584,42 @@ static int vidioc_g_input (struct file *file, void *priv, unsigned int *input) | |||
590 | return 0; | 584 | return 0; |
591 | } | 585 | } |
592 | 586 | ||
593 | static int vidioc_s_input (struct file *file, void *priv, unsigned int input) | 587 | static int vidioc_s_input(struct file *file, void *priv, unsigned int input) |
594 | { | 588 | { |
595 | struct usb_usbvision *usbvision = video_drvdata(file); | 589 | struct usb_usbvision *usbvision = video_drvdata(file); |
596 | 590 | ||
597 | if (input >= usbvision->video_inputs) | 591 | if (input >= usbvision->video_inputs) |
598 | return -EINVAL; | 592 | return -EINVAL; |
599 | 593 | ||
600 | mutex_lock(&usbvision->lock); | ||
601 | usbvision_muxsel(usbvision, input); | 594 | usbvision_muxsel(usbvision, input); |
602 | usbvision_set_input(usbvision); | 595 | usbvision_set_input(usbvision); |
603 | usbvision_set_output(usbvision, | 596 | usbvision_set_output(usbvision, |
604 | usbvision->curwidth, | 597 | usbvision->curwidth, |
605 | usbvision->curheight); | 598 | usbvision->curheight); |
606 | mutex_unlock(&usbvision->lock); | ||
607 | return 0; | 599 | return 0; |
608 | } | 600 | } |
609 | 601 | ||
610 | static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id) | 602 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) |
611 | { | 603 | { |
612 | struct usb_usbvision *usbvision = video_drvdata(file); | 604 | struct usb_usbvision *usbvision = video_drvdata(file); |
613 | 605 | ||
614 | usbvision->tvnormId=*id; | 606 | usbvision->tvnorm_id = *id; |
615 | 607 | ||
616 | mutex_lock(&usbvision->lock); | 608 | call_all(usbvision, core, s_std, usbvision->tvnorm_id); |
617 | call_all(usbvision, core, s_std, usbvision->tvnormId); | ||
618 | mutex_unlock(&usbvision->lock); | ||
619 | /* propagate the change to the decoder */ | 609 | /* propagate the change to the decoder */ |
620 | usbvision_muxsel(usbvision, usbvision->ctl_input); | 610 | usbvision_muxsel(usbvision, usbvision->ctl_input); |
621 | 611 | ||
622 | return 0; | 612 | return 0; |
623 | } | 613 | } |
624 | 614 | ||
625 | static int vidioc_g_tuner (struct file *file, void *priv, | 615 | static int vidioc_g_tuner(struct file *file, void *priv, |
626 | struct v4l2_tuner *vt) | 616 | struct v4l2_tuner *vt) |
627 | { | 617 | { |
628 | struct usb_usbvision *usbvision = video_drvdata(file); | 618 | struct usb_usbvision *usbvision = video_drvdata(file); |
629 | 619 | ||
630 | if (!usbvision->have_tuner || vt->index) // Only tuner 0 | 620 | if (!usbvision->have_tuner || vt->index) /* Only tuner 0 */ |
631 | return -EINVAL; | 621 | return -EINVAL; |
632 | if(usbvision->radio) { | 622 | if (usbvision->radio) { |
633 | strcpy(vt->name, "Radio"); | 623 | strcpy(vt->name, "Radio"); |
634 | vt->type = V4L2_TUNER_RADIO; | 624 | vt->type = V4L2_TUNER_RADIO; |
635 | } else { | 625 | } else { |
@@ -641,12 +631,12 @@ static int vidioc_g_tuner (struct file *file, void *priv, | |||
641 | return 0; | 631 | return 0; |
642 | } | 632 | } |
643 | 633 | ||
644 | static int vidioc_s_tuner (struct file *file, void *priv, | 634 | static int vidioc_s_tuner(struct file *file, void *priv, |
645 | struct v4l2_tuner *vt) | 635 | struct v4l2_tuner *vt) |
646 | { | 636 | { |
647 | struct usb_usbvision *usbvision = video_drvdata(file); | 637 | struct usb_usbvision *usbvision = video_drvdata(file); |
648 | 638 | ||
649 | // Only no or one tuner for now | 639 | /* Only no or one tuner for now */ |
650 | if (!usbvision->have_tuner || vt->index) | 640 | if (!usbvision->have_tuner || vt->index) |
651 | return -EINVAL; | 641 | return -EINVAL; |
652 | /* let clients handle this */ | 642 | /* let clients handle this */ |
@@ -655,28 +645,27 @@ static int vidioc_s_tuner (struct file *file, void *priv, | |||
655 | return 0; | 645 | return 0; |
656 | } | 646 | } |
657 | 647 | ||
658 | static int vidioc_g_frequency (struct file *file, void *priv, | 648 | static int vidioc_g_frequency(struct file *file, void *priv, |
659 | struct v4l2_frequency *freq) | 649 | struct v4l2_frequency *freq) |
660 | { | 650 | { |
661 | struct usb_usbvision *usbvision = video_drvdata(file); | 651 | struct usb_usbvision *usbvision = video_drvdata(file); |
662 | 652 | ||
663 | freq->tuner = 0; // Only one tuner | 653 | freq->tuner = 0; /* Only one tuner */ |
664 | if(usbvision->radio) { | 654 | if (usbvision->radio) |
665 | freq->type = V4L2_TUNER_RADIO; | 655 | freq->type = V4L2_TUNER_RADIO; |
666 | } else { | 656 | else |
667 | freq->type = V4L2_TUNER_ANALOG_TV; | 657 | freq->type = V4L2_TUNER_ANALOG_TV; |
668 | } | ||
669 | freq->frequency = usbvision->freq; | 658 | freq->frequency = usbvision->freq; |
670 | 659 | ||
671 | return 0; | 660 | return 0; |
672 | } | 661 | } |
673 | 662 | ||
674 | static int vidioc_s_frequency (struct file *file, void *priv, | 663 | static int vidioc_s_frequency(struct file *file, void *priv, |
675 | struct v4l2_frequency *freq) | 664 | struct v4l2_frequency *freq) |
676 | { | 665 | { |
677 | struct usb_usbvision *usbvision = video_drvdata(file); | 666 | struct usb_usbvision *usbvision = video_drvdata(file); |
678 | 667 | ||
679 | // Only no or one tuner for now | 668 | /* Only no or one tuner for now */ |
680 | if (!usbvision->have_tuner || freq->tuner) | 669 | if (!usbvision->have_tuner || freq->tuner) |
681 | return -EINVAL; | 670 | return -EINVAL; |
682 | 671 | ||
@@ -686,30 +675,27 @@ static int vidioc_s_frequency (struct file *file, void *priv, | |||
686 | return 0; | 675 | return 0; |
687 | } | 676 | } |
688 | 677 | ||
689 | static int vidioc_g_audio (struct file *file, void *priv, struct v4l2_audio *a) | 678 | static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) |
690 | { | 679 | { |
691 | struct usb_usbvision *usbvision = video_drvdata(file); | 680 | struct usb_usbvision *usbvision = video_drvdata(file); |
692 | 681 | ||
693 | if(usbvision->radio) { | 682 | if (usbvision->radio) |
694 | strcpy(a->name,"Radio"); | 683 | strcpy(a->name, "Radio"); |
695 | } else { | 684 | else |
696 | strcpy(a->name, "TV"); | 685 | strcpy(a->name, "TV"); |
697 | } | ||
698 | 686 | ||
699 | return 0; | 687 | return 0; |
700 | } | 688 | } |
701 | 689 | ||
702 | static int vidioc_s_audio (struct file *file, void *fh, | 690 | static int vidioc_s_audio(struct file *file, void *fh, |
703 | struct v4l2_audio *a) | 691 | struct v4l2_audio *a) |
704 | { | 692 | { |
705 | if(a->index) { | 693 | if (a->index) |
706 | return -EINVAL; | 694 | return -EINVAL; |
707 | } | ||
708 | |||
709 | return 0; | 695 | return 0; |
710 | } | 696 | } |
711 | 697 | ||
712 | static int vidioc_queryctrl (struct file *file, void *priv, | 698 | static int vidioc_queryctrl(struct file *file, void *priv, |
713 | struct v4l2_queryctrl *ctrl) | 699 | struct v4l2_queryctrl *ctrl) |
714 | { | 700 | { |
715 | struct usb_usbvision *usbvision = video_drvdata(file); | 701 | struct usb_usbvision *usbvision = video_drvdata(file); |
@@ -722,52 +708,53 @@ static int vidioc_queryctrl (struct file *file, void *priv, | |||
722 | return 0; | 708 | return 0; |
723 | } | 709 | } |
724 | 710 | ||
725 | static int vidioc_g_ctrl (struct file *file, void *priv, | 711 | static int vidioc_g_ctrl(struct file *file, void *priv, |
726 | struct v4l2_control *ctrl) | 712 | struct v4l2_control *ctrl) |
727 | { | 713 | { |
728 | struct usb_usbvision *usbvision = video_drvdata(file); | 714 | struct usb_usbvision *usbvision = video_drvdata(file); |
729 | call_all(usbvision, core, g_ctrl, ctrl); | ||
730 | 715 | ||
716 | call_all(usbvision, core, g_ctrl, ctrl); | ||
731 | return 0; | 717 | return 0; |
732 | } | 718 | } |
733 | 719 | ||
734 | static int vidioc_s_ctrl (struct file *file, void *priv, | 720 | static int vidioc_s_ctrl(struct file *file, void *priv, |
735 | struct v4l2_control *ctrl) | 721 | struct v4l2_control *ctrl) |
736 | { | 722 | { |
737 | struct usb_usbvision *usbvision = video_drvdata(file); | 723 | struct usb_usbvision *usbvision = video_drvdata(file); |
738 | call_all(usbvision, core, s_ctrl, ctrl); | ||
739 | 724 | ||
725 | call_all(usbvision, core, s_ctrl, ctrl); | ||
740 | return 0; | 726 | return 0; |
741 | } | 727 | } |
742 | 728 | ||
743 | static int vidioc_reqbufs (struct file *file, | 729 | static int vidioc_reqbufs(struct file *file, |
744 | void *priv, struct v4l2_requestbuffers *vr) | 730 | void *priv, struct v4l2_requestbuffers *vr) |
745 | { | 731 | { |
746 | struct usb_usbvision *usbvision = video_drvdata(file); | 732 | struct usb_usbvision *usbvision = video_drvdata(file); |
747 | int ret; | 733 | int ret; |
748 | 734 | ||
749 | RESTRICT_TO_RANGE(vr->count,1,USBVISION_NUMFRAMES); | 735 | RESTRICT_TO_RANGE(vr->count, 1, USBVISION_NUMFRAMES); |
750 | 736 | ||
751 | /* Check input validity: | 737 | /* Check input validity: |
752 | the user must do a VIDEO CAPTURE and MMAP method. */ | 738 | the user must do a VIDEO CAPTURE and MMAP method. */ |
753 | if (vr->memory != V4L2_MEMORY_MMAP) | 739 | if (vr->memory != V4L2_MEMORY_MMAP) |
754 | return -EINVAL; | 740 | return -EINVAL; |
755 | 741 | ||
756 | if(usbvision->streaming == Stream_On) { | 742 | if (usbvision->streaming == stream_on) { |
757 | if ((ret = usbvision_stream_interrupt(usbvision))) | 743 | ret = usbvision_stream_interrupt(usbvision); |
744 | if (ret) | ||
758 | return ret; | 745 | return ret; |
759 | } | 746 | } |
760 | 747 | ||
761 | usbvision_frames_free(usbvision); | 748 | usbvision_frames_free(usbvision); |
762 | usbvision_empty_framequeues(usbvision); | 749 | usbvision_empty_framequeues(usbvision); |
763 | vr->count = usbvision_frames_alloc(usbvision,vr->count); | 750 | vr->count = usbvision_frames_alloc(usbvision, vr->count); |
764 | 751 | ||
765 | usbvision->curFrame = NULL; | 752 | usbvision->cur_frame = NULL; |
766 | 753 | ||
767 | return 0; | 754 | return 0; |
768 | } | 755 | } |
769 | 756 | ||
770 | static int vidioc_querybuf (struct file *file, | 757 | static int vidioc_querybuf(struct file *file, |
771 | void *priv, struct v4l2_buffer *vb) | 758 | void *priv, struct v4l2_buffer *vb) |
772 | { | 759 | { |
773 | struct usb_usbvision *usbvision = video_drvdata(file); | 760 | struct usb_usbvision *usbvision = video_drvdata(file); |
@@ -775,52 +762,49 @@ static int vidioc_querybuf (struct file *file, | |||
775 | 762 | ||
776 | /* FIXME : must control | 763 | /* FIXME : must control |
777 | that buffers are mapped (VIDIOC_REQBUFS has been called) */ | 764 | that buffers are mapped (VIDIOC_REQBUFS has been called) */ |
778 | if(vb->index>=usbvision->num_frames) { | 765 | if (vb->index >= usbvision->num_frames) |
779 | return -EINVAL; | 766 | return -EINVAL; |
780 | } | ||
781 | /* Updating the corresponding frame state */ | 767 | /* Updating the corresponding frame state */ |
782 | vb->flags = 0; | 768 | vb->flags = 0; |
783 | frame = &usbvision->frame[vb->index]; | 769 | frame = &usbvision->frame[vb->index]; |
784 | if(frame->grabstate >= FrameState_Ready) | 770 | if (frame->grabstate >= frame_state_ready) |
785 | vb->flags |= V4L2_BUF_FLAG_QUEUED; | 771 | vb->flags |= V4L2_BUF_FLAG_QUEUED; |
786 | if(frame->grabstate >= FrameState_Done) | 772 | if (frame->grabstate >= frame_state_done) |
787 | vb->flags |= V4L2_BUF_FLAG_DONE; | 773 | vb->flags |= V4L2_BUF_FLAG_DONE; |
788 | if(frame->grabstate == FrameState_Unused) | 774 | if (frame->grabstate == frame_state_unused) |
789 | vb->flags |= V4L2_BUF_FLAG_MAPPED; | 775 | vb->flags |= V4L2_BUF_FLAG_MAPPED; |
790 | vb->memory = V4L2_MEMORY_MMAP; | 776 | vb->memory = V4L2_MEMORY_MMAP; |
791 | 777 | ||
792 | vb->m.offset = vb->index*PAGE_ALIGN(usbvision->max_frame_size); | 778 | vb->m.offset = vb->index * PAGE_ALIGN(usbvision->max_frame_size); |
793 | 779 | ||
794 | vb->memory = V4L2_MEMORY_MMAP; | 780 | vb->memory = V4L2_MEMORY_MMAP; |
795 | vb->field = V4L2_FIELD_NONE; | 781 | vb->field = V4L2_FIELD_NONE; |
796 | vb->length = usbvision->curwidth* | 782 | vb->length = usbvision->curwidth * |
797 | usbvision->curheight* | 783 | usbvision->curheight * |
798 | usbvision->palette.bytes_per_pixel; | 784 | usbvision->palette.bytes_per_pixel; |
799 | vb->timestamp = usbvision->frame[vb->index].timestamp; | 785 | vb->timestamp = usbvision->frame[vb->index].timestamp; |
800 | vb->sequence = usbvision->frame[vb->index].sequence; | 786 | vb->sequence = usbvision->frame[vb->index].sequence; |
801 | return 0; | 787 | return 0; |
802 | } | 788 | } |
803 | 789 | ||
804 | static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *vb) | 790 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *vb) |
805 | { | 791 | { |
806 | struct usb_usbvision *usbvision = video_drvdata(file); | 792 | struct usb_usbvision *usbvision = video_drvdata(file); |
807 | struct usbvision_frame *frame; | 793 | struct usbvision_frame *frame; |
808 | unsigned long lock_flags; | 794 | unsigned long lock_flags; |
809 | 795 | ||
810 | /* FIXME : works only on VIDEO_CAPTURE MODE, MMAP. */ | 796 | /* FIXME : works only on VIDEO_CAPTURE MODE, MMAP. */ |
811 | if(vb->index>=usbvision->num_frames) { | 797 | if (vb->index >= usbvision->num_frames) |
812 | return -EINVAL; | 798 | return -EINVAL; |
813 | } | ||
814 | 799 | ||
815 | frame = &usbvision->frame[vb->index]; | 800 | frame = &usbvision->frame[vb->index]; |
816 | 801 | ||
817 | if (frame->grabstate != FrameState_Unused) { | 802 | if (frame->grabstate != frame_state_unused) |
818 | return -EAGAIN; | 803 | return -EAGAIN; |
819 | } | ||
820 | 804 | ||
821 | /* Mark it as ready and enqueue frame */ | 805 | /* Mark it as ready and enqueue frame */ |
822 | frame->grabstate = FrameState_Ready; | 806 | frame->grabstate = frame_state_ready; |
823 | frame->scanstate = ScanState_Scanning; | 807 | frame->scanstate = scan_state_scanning; |
824 | frame->scanlength = 0; /* Accumulated in usbvision_parse_data() */ | 808 | frame->scanlength = 0; /* Accumulated in usbvision_parse_data() */ |
825 | 809 | ||
826 | vb->flags &= ~V4L2_BUF_FLAG_DONE; | 810 | vb->flags &= ~V4L2_BUF_FLAG_DONE; |
@@ -835,7 +819,7 @@ static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *vb) | |||
835 | return 0; | 819 | return 0; |
836 | } | 820 | } |
837 | 821 | ||
838 | static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb) | 822 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *vb) |
839 | { | 823 | { |
840 | struct usb_usbvision *usbvision = video_drvdata(file); | 824 | struct usb_usbvision *usbvision = video_drvdata(file); |
841 | int ret; | 825 | int ret; |
@@ -843,7 +827,7 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb) | |||
843 | unsigned long lock_flags; | 827 | unsigned long lock_flags; |
844 | 828 | ||
845 | if (list_empty(&(usbvision->outqueue))) { | 829 | if (list_empty(&(usbvision->outqueue))) { |
846 | if (usbvision->streaming == Stream_Idle) | 830 | if (usbvision->streaming == stream_idle) |
847 | return -EINVAL; | 831 | return -EINVAL; |
848 | ret = wait_event_interruptible | 832 | ret = wait_event_interruptible |
849 | (usbvision->wait_frame, | 833 | (usbvision->wait_frame, |
@@ -858,7 +842,7 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb) | |||
858 | list_del(usbvision->outqueue.next); | 842 | list_del(usbvision->outqueue.next); |
859 | spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags); | 843 | spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags); |
860 | 844 | ||
861 | f->grabstate = FrameState_Unused; | 845 | f->grabstate = frame_state_unused; |
862 | 846 | ||
863 | vb->memory = V4L2_MEMORY_MMAP; | 847 | vb->memory = V4L2_MEMORY_MMAP; |
864 | vb->flags = V4L2_BUF_FLAG_MAPPED | | 848 | vb->flags = V4L2_BUF_FLAG_MAPPED | |
@@ -877,7 +861,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | |||
877 | { | 861 | { |
878 | struct usb_usbvision *usbvision = video_drvdata(file); | 862 | struct usb_usbvision *usbvision = video_drvdata(file); |
879 | 863 | ||
880 | usbvision->streaming = Stream_On; | 864 | usbvision->streaming = stream_on; |
881 | call_all(usbvision, video, s_stream, 1); | 865 | call_all(usbvision, video, s_stream, 1); |
882 | 866 | ||
883 | return 0; | 867 | return 0; |
@@ -891,7 +875,7 @@ static int vidioc_streamoff(struct file *file, | |||
891 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 875 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
892 | return -EINVAL; | 876 | return -EINVAL; |
893 | 877 | ||
894 | if(usbvision->streaming == Stream_On) { | 878 | if (usbvision->streaming == stream_on) { |
895 | usbvision_stream_interrupt(usbvision); | 879 | usbvision_stream_interrupt(usbvision); |
896 | /* Stop all video streamings */ | 880 | /* Stop all video streamings */ |
897 | call_all(usbvision, video, s_stream, 0); | 881 | call_all(usbvision, video, s_stream, 0); |
@@ -901,18 +885,17 @@ static int vidioc_streamoff(struct file *file, | |||
901 | return 0; | 885 | return 0; |
902 | } | 886 | } |
903 | 887 | ||
904 | static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, | 888 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, |
905 | struct v4l2_fmtdesc *vfd) | 889 | struct v4l2_fmtdesc *vfd) |
906 | { | 890 | { |
907 | if(vfd->index>=USBVISION_SUPPORTED_PALETTES-1) { | 891 | if (vfd->index >= USBVISION_SUPPORTED_PALETTES - 1) |
908 | return -EINVAL; | 892 | return -EINVAL; |
909 | } | 893 | strcpy(vfd->description, usbvision_v4l2_format[vfd->index].desc); |
910 | strcpy(vfd->description,usbvision_v4l2_format[vfd->index].desc); | ||
911 | vfd->pixelformat = usbvision_v4l2_format[vfd->index].format; | 894 | vfd->pixelformat = usbvision_v4l2_format[vfd->index].format; |
912 | return 0; | 895 | return 0; |
913 | } | 896 | } |
914 | 897 | ||
915 | static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, | 898 | static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, |
916 | struct v4l2_format *vf) | 899 | struct v4l2_format *vf) |
917 | { | 900 | { |
918 | struct usb_usbvision *usbvision = video_drvdata(file); | 901 | struct usb_usbvision *usbvision = video_drvdata(file); |
@@ -920,32 +903,31 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, | |||
920 | vf->fmt.pix.height = usbvision->curheight; | 903 | vf->fmt.pix.height = usbvision->curheight; |
921 | vf->fmt.pix.pixelformat = usbvision->palette.format; | 904 | vf->fmt.pix.pixelformat = usbvision->palette.format; |
922 | vf->fmt.pix.bytesperline = | 905 | vf->fmt.pix.bytesperline = |
923 | usbvision->curwidth*usbvision->palette.bytes_per_pixel; | 906 | usbvision->curwidth * usbvision->palette.bytes_per_pixel; |
924 | vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline*usbvision->curheight; | 907 | vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline * usbvision->curheight; |
925 | vf->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 908 | vf->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
926 | vf->fmt.pix.field = V4L2_FIELD_NONE; /* Always progressive image */ | 909 | vf->fmt.pix.field = V4L2_FIELD_NONE; /* Always progressive image */ |
927 | 910 | ||
928 | return 0; | 911 | return 0; |
929 | } | 912 | } |
930 | 913 | ||
931 | static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, | 914 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, |
932 | struct v4l2_format *vf) | 915 | struct v4l2_format *vf) |
933 | { | 916 | { |
934 | struct usb_usbvision *usbvision = video_drvdata(file); | 917 | struct usb_usbvision *usbvision = video_drvdata(file); |
935 | int formatIdx; | 918 | int format_idx; |
936 | 919 | ||
937 | /* Find requested format in available ones */ | 920 | /* Find requested format in available ones */ |
938 | for(formatIdx=0;formatIdx<USBVISION_SUPPORTED_PALETTES;formatIdx++) { | 921 | for (format_idx = 0; format_idx < USBVISION_SUPPORTED_PALETTES; format_idx++) { |
939 | if(vf->fmt.pix.pixelformat == | 922 | if (vf->fmt.pix.pixelformat == |
940 | usbvision_v4l2_format[formatIdx].format) { | 923 | usbvision_v4l2_format[format_idx].format) { |
941 | usbvision->palette = usbvision_v4l2_format[formatIdx]; | 924 | usbvision->palette = usbvision_v4l2_format[format_idx]; |
942 | break; | 925 | break; |
943 | } | 926 | } |
944 | } | 927 | } |
945 | /* robustness */ | 928 | /* robustness */ |
946 | if(formatIdx == USBVISION_SUPPORTED_PALETTES) { | 929 | if (format_idx == USBVISION_SUPPORTED_PALETTES) |
947 | return -EINVAL; | 930 | return -EINVAL; |
948 | } | ||
949 | RESTRICT_TO_RANGE(vf->fmt.pix.width, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH); | 931 | RESTRICT_TO_RANGE(vf->fmt.pix.width, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH); |
950 | RESTRICT_TO_RANGE(vf->fmt.pix.height, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT); | 932 | RESTRICT_TO_RANGE(vf->fmt.pix.height, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT); |
951 | 933 | ||
@@ -962,24 +944,23 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
962 | struct usb_usbvision *usbvision = video_drvdata(file); | 944 | struct usb_usbvision *usbvision = video_drvdata(file); |
963 | int ret; | 945 | int ret; |
964 | 946 | ||
965 | if( 0 != (ret=vidioc_try_fmt_vid_cap (file, priv, vf)) ) { | 947 | ret = vidioc_try_fmt_vid_cap(file, priv, vf); |
948 | if (ret) | ||
966 | return ret; | 949 | return ret; |
967 | } | ||
968 | 950 | ||
969 | /* stop io in case it is already in progress */ | 951 | /* stop io in case it is already in progress */ |
970 | if(usbvision->streaming == Stream_On) { | 952 | if (usbvision->streaming == stream_on) { |
971 | if ((ret = usbvision_stream_interrupt(usbvision))) | 953 | ret = usbvision_stream_interrupt(usbvision); |
954 | if (ret) | ||
972 | return ret; | 955 | return ret; |
973 | } | 956 | } |
974 | usbvision_frames_free(usbvision); | 957 | usbvision_frames_free(usbvision); |
975 | usbvision_empty_framequeues(usbvision); | 958 | usbvision_empty_framequeues(usbvision); |
976 | 959 | ||
977 | usbvision->curFrame = NULL; | 960 | usbvision->cur_frame = NULL; |
978 | 961 | ||
979 | /* by now we are committed to the new data... */ | 962 | /* by now we are committed to the new data... */ |
980 | mutex_lock(&usbvision->lock); | ||
981 | usbvision_set_output(usbvision, vf->fmt.pix.width, vf->fmt.pix.height); | 963 | usbvision_set_output(usbvision, vf->fmt.pix.width, vf->fmt.pix.height); |
982 | mutex_unlock(&usbvision->lock); | ||
983 | 964 | ||
984 | return 0; | 965 | return 0; |
985 | } | 966 | } |
@@ -990,8 +971,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | |||
990 | struct usb_usbvision *usbvision = video_drvdata(file); | 971 | struct usb_usbvision *usbvision = video_drvdata(file); |
991 | int noblock = file->f_flags & O_NONBLOCK; | 972 | int noblock = file->f_flags & O_NONBLOCK; |
992 | unsigned long lock_flags; | 973 | unsigned long lock_flags; |
993 | 974 | int ret, i; | |
994 | int ret,i; | ||
995 | struct usbvision_frame *frame; | 975 | struct usbvision_frame *frame; |
996 | 976 | ||
997 | PDEBUG(DBG_IO, "%s: %ld bytes, noblock=%d", __func__, | 977 | PDEBUG(DBG_IO, "%s: %ld bytes, noblock=%d", __func__, |
@@ -1003,28 +983,28 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | |||
1003 | /* This entry point is compatible with the mmap routines | 983 | /* This entry point is compatible with the mmap routines |
1004 | so that a user can do either VIDIOC_QBUF/VIDIOC_DQBUF | 984 | so that a user can do either VIDIOC_QBUF/VIDIOC_DQBUF |
1005 | to get frames or call read on the device. */ | 985 | to get frames or call read on the device. */ |
1006 | if(!usbvision->num_frames) { | 986 | if (!usbvision->num_frames) { |
1007 | /* First, allocate some frames to work with | 987 | /* First, allocate some frames to work with |
1008 | if this has not been done with VIDIOC_REQBUF */ | 988 | if this has not been done with VIDIOC_REQBUF */ |
1009 | usbvision_frames_free(usbvision); | 989 | usbvision_frames_free(usbvision); |
1010 | usbvision_empty_framequeues(usbvision); | 990 | usbvision_empty_framequeues(usbvision); |
1011 | usbvision_frames_alloc(usbvision,USBVISION_NUMFRAMES); | 991 | usbvision_frames_alloc(usbvision, USBVISION_NUMFRAMES); |
1012 | } | 992 | } |
1013 | 993 | ||
1014 | if(usbvision->streaming != Stream_On) { | 994 | if (usbvision->streaming != stream_on) { |
1015 | /* no stream is running, make it running ! */ | 995 | /* no stream is running, make it running ! */ |
1016 | usbvision->streaming = Stream_On; | 996 | usbvision->streaming = stream_on; |
1017 | call_all(usbvision, video, s_stream, 1); | 997 | call_all(usbvision, video, s_stream, 1); |
1018 | } | 998 | } |
1019 | 999 | ||
1020 | /* Then, enqueue as many frames as possible | 1000 | /* Then, enqueue as many frames as possible |
1021 | (like a user of VIDIOC_QBUF would do) */ | 1001 | (like a user of VIDIOC_QBUF would do) */ |
1022 | for(i=0;i<usbvision->num_frames;i++) { | 1002 | for (i = 0; i < usbvision->num_frames; i++) { |
1023 | frame = &usbvision->frame[i]; | 1003 | frame = &usbvision->frame[i]; |
1024 | if(frame->grabstate == FrameState_Unused) { | 1004 | if (frame->grabstate == frame_state_unused) { |
1025 | /* Mark it as ready and enqueue frame */ | 1005 | /* Mark it as ready and enqueue frame */ |
1026 | frame->grabstate = FrameState_Ready; | 1006 | frame->grabstate = frame_state_ready; |
1027 | frame->scanstate = ScanState_Scanning; | 1007 | frame->scanstate = scan_state_scanning; |
1028 | /* Accumulated in usbvision_parse_data() */ | 1008 | /* Accumulated in usbvision_parse_data() */ |
1029 | frame->scanlength = 0; | 1009 | frame->scanlength = 0; |
1030 | 1010 | ||
@@ -1040,7 +1020,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | |||
1040 | 1020 | ||
1041 | /* Then try to steal a frame (like a VIDIOC_DQBUF would do) */ | 1021 | /* Then try to steal a frame (like a VIDIOC_DQBUF would do) */ |
1042 | if (list_empty(&(usbvision->outqueue))) { | 1022 | if (list_empty(&(usbvision->outqueue))) { |
1043 | if(noblock) | 1023 | if (noblock) |
1044 | return -EAGAIN; | 1024 | return -EAGAIN; |
1045 | 1025 | ||
1046 | ret = wait_event_interruptible | 1026 | ret = wait_event_interruptible |
@@ -1057,7 +1037,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | |||
1057 | spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags); | 1037 | spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags); |
1058 | 1038 | ||
1059 | /* An error returns an empty frame */ | 1039 | /* An error returns an empty frame */ |
1060 | if (frame->grabstate == FrameState_Error) { | 1040 | if (frame->grabstate == frame_state_error) { |
1061 | frame->bytes_read = 0; | 1041 | frame->bytes_read = 0; |
1062 | return 0; | 1042 | return 0; |
1063 | } | 1043 | } |
@@ -1070,9 +1050,8 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | |||
1070 | if ((count + frame->bytes_read) > (unsigned long)frame->scanlength) | 1050 | if ((count + frame->bytes_read) > (unsigned long)frame->scanlength) |
1071 | count = frame->scanlength - frame->bytes_read; | 1051 | count = frame->scanlength - frame->bytes_read; |
1072 | 1052 | ||
1073 | if (copy_to_user(buf, frame->data + frame->bytes_read, count)) { | 1053 | if (copy_to_user(buf, frame->data + frame->bytes_read, count)) |
1074 | return -EFAULT; | 1054 | return -EFAULT; |
1075 | } | ||
1076 | 1055 | ||
1077 | frame->bytes_read += count; | 1056 | frame->bytes_read += count; |
1078 | PDEBUG(DBG_IO, "%s: {copy} count used=%ld, new bytes_read=%ld", | 1057 | PDEBUG(DBG_IO, "%s: {copy} count used=%ld, new bytes_read=%ld", |
@@ -1080,12 +1059,12 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | |||
1080 | (unsigned long)count, frame->bytes_read); | 1059 | (unsigned long)count, frame->bytes_read); |
1081 | 1060 | ||
1082 | /* For now, forget the frame if it has not been read in one shot. */ | 1061 | /* For now, forget the frame if it has not been read in one shot. */ |
1083 | /* if (frame->bytes_read >= frame->scanlength) {// All data has been read */ | 1062 | /* if (frame->bytes_read >= frame->scanlength) {*/ /* All data has been read */ |
1084 | frame->bytes_read = 0; | 1063 | frame->bytes_read = 0; |
1085 | 1064 | ||
1086 | /* Mark it as available to be used again. */ | 1065 | /* Mark it as available to be used again. */ |
1087 | frame->grabstate = FrameState_Unused; | 1066 | frame->grabstate = frame_state_unused; |
1088 | /* } */ | 1067 | /* } */ |
1089 | 1068 | ||
1090 | return count; | 1069 | return count; |
1091 | } | 1070 | } |
@@ -1100,16 +1079,11 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
1100 | 1079 | ||
1101 | PDEBUG(DBG_MMAP, "mmap"); | 1080 | PDEBUG(DBG_MMAP, "mmap"); |
1102 | 1081 | ||
1103 | mutex_lock(&usbvision->lock); | 1082 | if (!USBVISION_IS_OPERATIONAL(usbvision)) |
1104 | |||
1105 | if (!USBVISION_IS_OPERATIONAL(usbvision)) { | ||
1106 | mutex_unlock(&usbvision->lock); | ||
1107 | return -EFAULT; | 1083 | return -EFAULT; |
1108 | } | ||
1109 | 1084 | ||
1110 | if (!(vma->vm_flags & VM_WRITE) || | 1085 | if (!(vma->vm_flags & VM_WRITE) || |
1111 | size != PAGE_ALIGN(usbvision->max_frame_size)) { | 1086 | size != PAGE_ALIGN(usbvision->max_frame_size)) { |
1112 | mutex_unlock(&usbvision->lock); | ||
1113 | return -EINVAL; | 1087 | return -EINVAL; |
1114 | } | 1088 | } |
1115 | 1089 | ||
@@ -1121,7 +1095,6 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
1121 | if (i == usbvision->num_frames) { | 1095 | if (i == usbvision->num_frames) { |
1122 | PDEBUG(DBG_MMAP, | 1096 | PDEBUG(DBG_MMAP, |
1123 | "mmap: user supplied mapping address is out of range"); | 1097 | "mmap: user supplied mapping address is out of range"); |
1124 | mutex_unlock(&usbvision->lock); | ||
1125 | return -EINVAL; | 1098 | return -EINVAL; |
1126 | } | 1099 | } |
1127 | 1100 | ||
@@ -1131,10 +1104,8 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
1131 | 1104 | ||
1132 | pos = usbvision->frame[i].data; | 1105 | pos = usbvision->frame[i].data; |
1133 | while (size > 0) { | 1106 | while (size > 0) { |
1134 | |||
1135 | if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { | 1107 | if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { |
1136 | PDEBUG(DBG_MMAP, "mmap: vm_insert_page failed"); | 1108 | PDEBUG(DBG_MMAP, "mmap: vm_insert_page failed"); |
1137 | mutex_unlock(&usbvision->lock); | ||
1138 | return -EAGAIN; | 1109 | return -EAGAIN; |
1139 | } | 1110 | } |
1140 | start += PAGE_SIZE; | 1111 | start += PAGE_SIZE; |
@@ -1142,7 +1113,6 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
1142 | size -= PAGE_SIZE; | 1113 | size -= PAGE_SIZE; |
1143 | } | 1114 | } |
1144 | 1115 | ||
1145 | mutex_unlock(&usbvision->lock); | ||
1146 | return 0; | 1116 | return 0; |
1147 | } | 1117 | } |
1148 | 1118 | ||
@@ -1154,21 +1124,18 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
1154 | static int usbvision_radio_open(struct file *file) | 1124 | static int usbvision_radio_open(struct file *file) |
1155 | { | 1125 | { |
1156 | struct usb_usbvision *usbvision = video_drvdata(file); | 1126 | struct usb_usbvision *usbvision = video_drvdata(file); |
1157 | int errCode = 0; | 1127 | int err_code = 0; |
1158 | 1128 | ||
1159 | PDEBUG(DBG_IO, "%s:", __func__); | 1129 | PDEBUG(DBG_IO, "%s:", __func__); |
1160 | 1130 | ||
1161 | mutex_lock(&usbvision->lock); | ||
1162 | |||
1163 | if (usbvision->user) { | 1131 | if (usbvision->user) { |
1164 | dev_err(&usbvision->rdev->dev, | 1132 | dev_err(&usbvision->rdev->dev, |
1165 | "%s: Someone tried to open an already opened USBVision Radio!\n", | 1133 | "%s: Someone tried to open an already opened USBVision Radio!\n", |
1166 | __func__); | 1134 | __func__); |
1167 | errCode = -EBUSY; | 1135 | err_code = -EBUSY; |
1168 | } | 1136 | } else { |
1169 | else { | 1137 | if (power_on_at_open) { |
1170 | if(PowerOnAtOpen) { | 1138 | usbvision_reset_power_off_timer(usbvision); |
1171 | usbvision_reset_powerOffTimer(usbvision); | ||
1172 | if (usbvision->power == 0) { | 1139 | if (usbvision->power == 0) { |
1173 | usbvision_power_on(usbvision); | 1140 | usbvision_power_on(usbvision); |
1174 | usbvision_i2c_register(usbvision); | 1141 | usbvision_i2c_register(usbvision); |
@@ -1176,80 +1143,73 @@ static int usbvision_radio_open(struct file *file) | |||
1176 | } | 1143 | } |
1177 | 1144 | ||
1178 | /* Alternate interface 1 is is the biggest frame size */ | 1145 | /* Alternate interface 1 is is the biggest frame size */ |
1179 | errCode = usbvision_set_alternate(usbvision); | 1146 | err_code = usbvision_set_alternate(usbvision); |
1180 | if (errCode < 0) { | 1147 | if (err_code < 0) { |
1181 | usbvision->last_error = errCode; | 1148 | usbvision->last_error = err_code; |
1182 | errCode = -EBUSY; | 1149 | err_code = -EBUSY; |
1183 | goto out; | 1150 | goto out; |
1184 | } | 1151 | } |
1185 | 1152 | ||
1186 | // If so far no errors then we shall start the radio | 1153 | /* If so far no errors then we shall start the radio */ |
1187 | usbvision->radio = 1; | 1154 | usbvision->radio = 1; |
1188 | call_all(usbvision, tuner, s_radio); | 1155 | call_all(usbvision, tuner, s_radio); |
1189 | usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO); | 1156 | usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO); |
1190 | usbvision->user++; | 1157 | usbvision->user++; |
1191 | } | 1158 | } |
1192 | 1159 | ||
1193 | if (errCode) { | 1160 | if (err_code) { |
1194 | if (PowerOnAtOpen) { | 1161 | if (power_on_at_open) { |
1195 | usbvision_i2c_unregister(usbvision); | 1162 | usbvision_i2c_unregister(usbvision); |
1196 | usbvision_power_off(usbvision); | 1163 | usbvision_power_off(usbvision); |
1197 | usbvision->initialized = 0; | 1164 | usbvision->initialized = 0; |
1198 | } | 1165 | } |
1199 | } | 1166 | } |
1200 | out: | 1167 | out: |
1201 | mutex_unlock(&usbvision->lock); | 1168 | return err_code; |
1202 | return errCode; | ||
1203 | } | 1169 | } |
1204 | 1170 | ||
1205 | 1171 | ||
1206 | static int usbvision_radio_close(struct file *file) | 1172 | static int usbvision_radio_close(struct file *file) |
1207 | { | 1173 | { |
1208 | struct usb_usbvision *usbvision = video_drvdata(file); | 1174 | struct usb_usbvision *usbvision = video_drvdata(file); |
1209 | int errCode = 0; | 1175 | int err_code = 0; |
1210 | 1176 | ||
1211 | PDEBUG(DBG_IO, ""); | 1177 | PDEBUG(DBG_IO, ""); |
1212 | 1178 | ||
1213 | mutex_lock(&usbvision->lock); | ||
1214 | |||
1215 | /* Set packet size to 0 */ | 1179 | /* Set packet size to 0 */ |
1216 | usbvision->ifaceAlt=0; | 1180 | usbvision->iface_alt = 0; |
1217 | errCode = usb_set_interface(usbvision->dev, usbvision->iface, | 1181 | err_code = usb_set_interface(usbvision->dev, usbvision->iface, |
1218 | usbvision->ifaceAlt); | 1182 | usbvision->iface_alt); |
1219 | 1183 | ||
1220 | usbvision_audio_off(usbvision); | 1184 | usbvision_audio_off(usbvision); |
1221 | usbvision->radio=0; | 1185 | usbvision->radio = 0; |
1222 | usbvision->user--; | 1186 | usbvision->user--; |
1223 | 1187 | ||
1224 | if (PowerOnAtOpen) { | 1188 | if (power_on_at_open) { |
1225 | usbvision_set_powerOffTimer(usbvision); | 1189 | usbvision_set_power_off_timer(usbvision); |
1226 | usbvision->initialized = 0; | 1190 | usbvision->initialized = 0; |
1227 | } | 1191 | } |
1228 | 1192 | ||
1229 | mutex_unlock(&usbvision->lock); | ||
1230 | |||
1231 | if (usbvision->remove_pending) { | 1193 | if (usbvision->remove_pending) { |
1232 | printk(KERN_INFO "%s: Final disconnect\n", __func__); | 1194 | printk(KERN_INFO "%s: Final disconnect\n", __func__); |
1233 | usbvision_release(usbvision); | 1195 | usbvision_release(usbvision); |
1234 | } | 1196 | } |
1235 | 1197 | ||
1236 | PDEBUG(DBG_IO, "success"); | 1198 | PDEBUG(DBG_IO, "success"); |
1237 | return errCode; | 1199 | return err_code; |
1238 | } | 1200 | } |
1239 | 1201 | ||
1240 | // | 1202 | /* Video registration stuff */ |
1241 | // Video registration stuff | ||
1242 | // | ||
1243 | 1203 | ||
1244 | // Video template | 1204 | /* Video template */ |
1245 | static const struct v4l2_file_operations usbvision_fops = { | 1205 | static const struct v4l2_file_operations usbvision_fops = { |
1246 | .owner = THIS_MODULE, | 1206 | .owner = THIS_MODULE, |
1247 | .open = usbvision_v4l2_open, | 1207 | .open = usbvision_v4l2_open, |
1248 | .release = usbvision_v4l2_close, | 1208 | .release = usbvision_v4l2_close, |
1249 | .read = usbvision_v4l2_read, | 1209 | .read = usbvision_v4l2_read, |
1250 | .mmap = usbvision_v4l2_mmap, | 1210 | .mmap = usbvision_v4l2_mmap, |
1251 | .ioctl = video_ioctl2, | 1211 | .unlocked_ioctl = video_ioctl2, |
1252 | /* .poll = video_poll, */ | 1212 | /* .poll = video_poll, */ |
1253 | }; | 1213 | }; |
1254 | 1214 | ||
1255 | static const struct v4l2_ioctl_ops usbvision_ioctl_ops = { | 1215 | static const struct v4l2_ioctl_ops usbvision_ioctl_ops = { |
@@ -1273,9 +1233,6 @@ static const struct v4l2_ioctl_ops usbvision_ioctl_ops = { | |||
1273 | .vidioc_s_ctrl = vidioc_s_ctrl, | 1233 | .vidioc_s_ctrl = vidioc_s_ctrl, |
1274 | .vidioc_streamon = vidioc_streamon, | 1234 | .vidioc_streamon = vidioc_streamon, |
1275 | .vidioc_streamoff = vidioc_streamoff, | 1235 | .vidioc_streamoff = vidioc_streamoff, |
1276 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1277 | /* .vidiocgmbuf = vidiocgmbuf, */ | ||
1278 | #endif | ||
1279 | .vidioc_g_tuner = vidioc_g_tuner, | 1236 | .vidioc_g_tuner = vidioc_g_tuner, |
1280 | .vidioc_s_tuner = vidioc_s_tuner, | 1237 | .vidioc_s_tuner = vidioc_s_tuner, |
1281 | .vidioc_g_frequency = vidioc_g_frequency, | 1238 | .vidioc_g_frequency = vidioc_g_frequency, |
@@ -1288,20 +1245,20 @@ static const struct v4l2_ioctl_ops usbvision_ioctl_ops = { | |||
1288 | 1245 | ||
1289 | static struct video_device usbvision_video_template = { | 1246 | static struct video_device usbvision_video_template = { |
1290 | .fops = &usbvision_fops, | 1247 | .fops = &usbvision_fops, |
1291 | .ioctl_ops = &usbvision_ioctl_ops, | 1248 | .ioctl_ops = &usbvision_ioctl_ops, |
1292 | .name = "usbvision-video", | 1249 | .name = "usbvision-video", |
1293 | .release = video_device_release, | 1250 | .release = video_device_release, |
1294 | .tvnorms = USBVISION_NORMS, | 1251 | .tvnorms = USBVISION_NORMS, |
1295 | .current_norm = V4L2_STD_PAL | 1252 | .current_norm = V4L2_STD_PAL |
1296 | }; | 1253 | }; |
1297 | 1254 | ||
1298 | 1255 | ||
1299 | // Radio template | 1256 | /* Radio template */ |
1300 | static const struct v4l2_file_operations usbvision_radio_fops = { | 1257 | static const struct v4l2_file_operations usbvision_radio_fops = { |
1301 | .owner = THIS_MODULE, | 1258 | .owner = THIS_MODULE, |
1302 | .open = usbvision_radio_open, | 1259 | .open = usbvision_radio_open, |
1303 | .release = usbvision_radio_close, | 1260 | .release = usbvision_radio_close, |
1304 | .ioctl = video_ioctl2, | 1261 | .unlocked_ioctl = video_ioctl2, |
1305 | }; | 1262 | }; |
1306 | 1263 | ||
1307 | static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = { | 1264 | static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = { |
@@ -1322,9 +1279,9 @@ static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = { | |||
1322 | 1279 | ||
1323 | static struct video_device usbvision_radio_template = { | 1280 | static struct video_device usbvision_radio_template = { |
1324 | .fops = &usbvision_radio_fops, | 1281 | .fops = &usbvision_radio_fops, |
1325 | .name = "usbvision-radio", | 1282 | .name = "usbvision-radio", |
1326 | .release = video_device_release, | 1283 | .release = video_device_release, |
1327 | .ioctl_ops = &usbvision_radio_ioctl_ops, | 1284 | .ioctl_ops = &usbvision_radio_ioctl_ops, |
1328 | 1285 | ||
1329 | .tvnorms = USBVISION_NORMS, | 1286 | .tvnorms = USBVISION_NORMS, |
1330 | .current_norm = V4L2_STD_PAL | 1287 | .current_norm = V4L2_STD_PAL |
@@ -1345,80 +1302,70 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision, | |||
1345 | } | 1302 | } |
1346 | 1303 | ||
1347 | vdev = video_device_alloc(); | 1304 | vdev = video_device_alloc(); |
1348 | if (NULL == vdev) { | 1305 | if (NULL == vdev) |
1349 | return NULL; | 1306 | return NULL; |
1350 | } | ||
1351 | *vdev = *vdev_template; | 1307 | *vdev = *vdev_template; |
1308 | vdev->lock = &usbvision->v4l2_lock; | ||
1352 | vdev->v4l2_dev = &usbvision->v4l2_dev; | 1309 | vdev->v4l2_dev = &usbvision->v4l2_dev; |
1353 | snprintf(vdev->name, sizeof(vdev->name), "%s", name); | 1310 | snprintf(vdev->name, sizeof(vdev->name), "%s", name); |
1354 | video_set_drvdata(vdev, usbvision); | 1311 | video_set_drvdata(vdev, usbvision); |
1355 | return vdev; | 1312 | return vdev; |
1356 | } | 1313 | } |
1357 | 1314 | ||
1358 | // unregister video4linux devices | 1315 | /* unregister video4linux devices */ |
1359 | static void usbvision_unregister_video(struct usb_usbvision *usbvision) | 1316 | static void usbvision_unregister_video(struct usb_usbvision *usbvision) |
1360 | { | 1317 | { |
1361 | // Radio Device: | 1318 | /* Radio Device: */ |
1362 | if (usbvision->rdev) { | 1319 | if (usbvision->rdev) { |
1363 | PDEBUG(DBG_PROBE, "unregister %s [v4l2]", | 1320 | PDEBUG(DBG_PROBE, "unregister %s [v4l2]", |
1364 | video_device_node_name(usbvision->rdev)); | 1321 | video_device_node_name(usbvision->rdev)); |
1365 | if (video_is_registered(usbvision->rdev)) { | 1322 | if (video_is_registered(usbvision->rdev)) |
1366 | video_unregister_device(usbvision->rdev); | 1323 | video_unregister_device(usbvision->rdev); |
1367 | } else { | 1324 | else |
1368 | video_device_release(usbvision->rdev); | 1325 | video_device_release(usbvision->rdev); |
1369 | } | ||
1370 | usbvision->rdev = NULL; | 1326 | usbvision->rdev = NULL; |
1371 | } | 1327 | } |
1372 | 1328 | ||
1373 | // Video Device: | 1329 | /* Video Device: */ |
1374 | if (usbvision->vdev) { | 1330 | if (usbvision->vdev) { |
1375 | PDEBUG(DBG_PROBE, "unregister %s [v4l2]", | 1331 | PDEBUG(DBG_PROBE, "unregister %s [v4l2]", |
1376 | video_device_node_name(usbvision->vdev)); | 1332 | video_device_node_name(usbvision->vdev)); |
1377 | if (video_is_registered(usbvision->vdev)) { | 1333 | if (video_is_registered(usbvision->vdev)) |
1378 | video_unregister_device(usbvision->vdev); | 1334 | video_unregister_device(usbvision->vdev); |
1379 | } else { | 1335 | else |
1380 | video_device_release(usbvision->vdev); | 1336 | video_device_release(usbvision->vdev); |
1381 | } | ||
1382 | usbvision->vdev = NULL; | 1337 | usbvision->vdev = NULL; |
1383 | } | 1338 | } |
1384 | } | 1339 | } |
1385 | 1340 | ||
1386 | // register video4linux devices | 1341 | /* register video4linux devices */ |
1387 | static int __devinit usbvision_register_video(struct usb_usbvision *usbvision) | 1342 | static int __devinit usbvision_register_video(struct usb_usbvision *usbvision) |
1388 | { | 1343 | { |
1389 | // Video Device: | 1344 | /* Video Device: */ |
1390 | usbvision->vdev = usbvision_vdev_init(usbvision, | 1345 | usbvision->vdev = usbvision_vdev_init(usbvision, |
1391 | &usbvision_video_template, | 1346 | &usbvision_video_template, |
1392 | "USBVision Video"); | 1347 | "USBVision Video"); |
1393 | if (usbvision->vdev == NULL) { | 1348 | if (usbvision->vdev == NULL) |
1394 | goto err_exit; | 1349 | goto err_exit; |
1395 | } | 1350 | if (video_register_device(usbvision->vdev, VFL_TYPE_GRABBER, video_nr) < 0) |
1396 | if (video_register_device(usbvision->vdev, | ||
1397 | VFL_TYPE_GRABBER, | ||
1398 | video_nr)<0) { | ||
1399 | goto err_exit; | 1351 | goto err_exit; |
1400 | } | ||
1401 | printk(KERN_INFO "USBVision[%d]: registered USBVision Video device %s [v4l2]\n", | 1352 | printk(KERN_INFO "USBVision[%d]: registered USBVision Video device %s [v4l2]\n", |
1402 | usbvision->nr, video_device_node_name(usbvision->vdev)); | 1353 | usbvision->nr, video_device_node_name(usbvision->vdev)); |
1403 | 1354 | ||
1404 | // Radio Device: | 1355 | /* Radio Device: */ |
1405 | if (usbvision_device_data[usbvision->DevModel].Radio) { | 1356 | if (usbvision_device_data[usbvision->dev_model].radio) { |
1406 | // usbvision has radio | 1357 | /* usbvision has radio */ |
1407 | usbvision->rdev = usbvision_vdev_init(usbvision, | 1358 | usbvision->rdev = usbvision_vdev_init(usbvision, |
1408 | &usbvision_radio_template, | 1359 | &usbvision_radio_template, |
1409 | "USBVision Radio"); | 1360 | "USBVision Radio"); |
1410 | if (usbvision->rdev == NULL) { | 1361 | if (usbvision->rdev == NULL) |
1411 | goto err_exit; | 1362 | goto err_exit; |
1412 | } | 1363 | if (video_register_device(usbvision->rdev, VFL_TYPE_RADIO, radio_nr) < 0) |
1413 | if (video_register_device(usbvision->rdev, | ||
1414 | VFL_TYPE_RADIO, | ||
1415 | radio_nr)<0) { | ||
1416 | goto err_exit; | 1364 | goto err_exit; |
1417 | } | ||
1418 | printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device %s [v4l2]\n", | 1365 | printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device %s [v4l2]\n", |
1419 | usbvision->nr, video_device_node_name(usbvision->rdev)); | 1366 | usbvision->nr, video_device_node_name(usbvision->rdev)); |
1420 | } | 1367 | } |
1421 | // all done | 1368 | /* all done */ |
1422 | return 0; | 1369 | return 0; |
1423 | 1370 | ||
1424 | err_exit: | 1371 | err_exit: |
@@ -1451,15 +1398,15 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev, | |||
1451 | if (v4l2_device_register(&intf->dev, &usbvision->v4l2_dev)) | 1398 | if (v4l2_device_register(&intf->dev, &usbvision->v4l2_dev)) |
1452 | goto err_free; | 1399 | goto err_free; |
1453 | 1400 | ||
1454 | mutex_init(&usbvision->lock); /* available */ | 1401 | mutex_init(&usbvision->v4l2_lock); |
1455 | 1402 | ||
1456 | // prepare control urb for control messages during interrupts | 1403 | /* prepare control urb for control messages during interrupts */ |
1457 | usbvision->ctrlUrb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL); | 1404 | usbvision->ctrl_urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL); |
1458 | if (usbvision->ctrlUrb == NULL) | 1405 | if (usbvision->ctrl_urb == NULL) |
1459 | goto err_unreg; | 1406 | goto err_unreg; |
1460 | init_waitqueue_head(&usbvision->ctrlUrb_wq); | 1407 | init_waitqueue_head(&usbvision->ctrl_urb_wq); |
1461 | 1408 | ||
1462 | usbvision_init_powerOffTimer(usbvision); | 1409 | usbvision_init_power_off_timer(usbvision); |
1463 | 1410 | ||
1464 | return usbvision; | 1411 | return usbvision; |
1465 | 1412 | ||
@@ -1481,20 +1428,14 @@ static void usbvision_release(struct usb_usbvision *usbvision) | |||
1481 | { | 1428 | { |
1482 | PDEBUG(DBG_PROBE, ""); | 1429 | PDEBUG(DBG_PROBE, ""); |
1483 | 1430 | ||
1484 | mutex_lock(&usbvision->lock); | 1431 | usbvision_reset_power_off_timer(usbvision); |
1485 | |||
1486 | usbvision_reset_powerOffTimer(usbvision); | ||
1487 | 1432 | ||
1488 | usbvision->initialized = 0; | 1433 | usbvision->initialized = 0; |
1489 | 1434 | ||
1490 | mutex_unlock(&usbvision->lock); | ||
1491 | |||
1492 | usbvision_remove_sysfs(usbvision->vdev); | 1435 | usbvision_remove_sysfs(usbvision->vdev); |
1493 | usbvision_unregister_video(usbvision); | 1436 | usbvision_unregister_video(usbvision); |
1494 | 1437 | ||
1495 | if (usbvision->ctrlUrb) { | 1438 | usb_free_urb(usbvision->ctrl_urb); |
1496 | usb_free_urb(usbvision->ctrlUrb); | ||
1497 | } | ||
1498 | 1439 | ||
1499 | v4l2_device_unregister(&usbvision->v4l2_dev); | 1440 | v4l2_device_unregister(&usbvision->v4l2_dev); |
1500 | kfree(usbvision); | 1441 | kfree(usbvision); |
@@ -1512,25 +1453,25 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision) | |||
1512 | if (usbvision == NULL) | 1453 | if (usbvision == NULL) |
1513 | return; | 1454 | return; |
1514 | 1455 | ||
1515 | model = usbvision->DevModel; | 1456 | model = usbvision->dev_model; |
1516 | usbvision->palette = usbvision_v4l2_format[2]; // V4L2_PIX_FMT_RGB24; | 1457 | usbvision->palette = usbvision_v4l2_format[2]; /* V4L2_PIX_FMT_RGB24; */ |
1517 | 1458 | ||
1518 | if (usbvision_device_data[usbvision->DevModel].Vin_Reg2_override) { | 1459 | if (usbvision_device_data[usbvision->dev_model].vin_reg2_override) { |
1519 | usbvision->Vin_Reg2_Preset = | 1460 | usbvision->vin_reg2_preset = |
1520 | usbvision_device_data[usbvision->DevModel].Vin_Reg2; | 1461 | usbvision_device_data[usbvision->dev_model].vin_reg2; |
1521 | } else { | 1462 | } else { |
1522 | usbvision->Vin_Reg2_Preset = 0; | 1463 | usbvision->vin_reg2_preset = 0; |
1523 | } | 1464 | } |
1524 | 1465 | ||
1525 | usbvision->tvnormId = usbvision_device_data[model].VideoNorm; | 1466 | usbvision->tvnorm_id = usbvision_device_data[model].video_norm; |
1526 | 1467 | ||
1527 | usbvision->video_inputs = usbvision_device_data[model].VideoChannels; | 1468 | usbvision->video_inputs = usbvision_device_data[model].video_channels; |
1528 | usbvision->ctl_input = 0; | 1469 | usbvision->ctl_input = 0; |
1529 | 1470 | ||
1530 | /* This should be here to make i2c clients to be able to register */ | 1471 | /* This should be here to make i2c clients to be able to register */ |
1531 | /* first switch off audio */ | 1472 | /* first switch off audio */ |
1532 | usbvision_audio_off(usbvision); | 1473 | usbvision_audio_off(usbvision); |
1533 | if (!PowerOnAtOpen) { | 1474 | if (!power_on_at_open) { |
1534 | /* and then power up the noisy tuner */ | 1475 | /* and then power up the noisy tuner */ |
1535 | usbvision_power_on(usbvision); | 1476 | usbvision_power_on(usbvision); |
1536 | usbvision_i2c_register(usbvision); | 1477 | usbvision_i2c_register(usbvision); |
@@ -1553,25 +1494,24 @@ static int __devinit usbvision_probe(struct usb_interface *intf, | |||
1553 | const struct usb_host_interface *interface; | 1494 | const struct usb_host_interface *interface; |
1554 | struct usb_usbvision *usbvision = NULL; | 1495 | struct usb_usbvision *usbvision = NULL; |
1555 | const struct usb_endpoint_descriptor *endpoint; | 1496 | const struct usb_endpoint_descriptor *endpoint; |
1556 | int model,i; | 1497 | int model, i; |
1557 | 1498 | ||
1558 | PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u", | 1499 | PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u", |
1559 | dev->descriptor.idVendor, | 1500 | dev->descriptor.idVendor, |
1560 | dev->descriptor.idProduct, ifnum); | 1501 | dev->descriptor.idProduct, ifnum); |
1561 | 1502 | ||
1562 | model = devid->driver_info; | 1503 | model = devid->driver_info; |
1563 | if ( (model<0) || (model>=usbvision_device_data_size) ) { | 1504 | if (model < 0 || model >= usbvision_device_data_size) { |
1564 | PDEBUG(DBG_PROBE, "model out of bounds %d",model); | 1505 | PDEBUG(DBG_PROBE, "model out of bounds %d", model); |
1565 | return -ENODEV; | 1506 | return -ENODEV; |
1566 | } | 1507 | } |
1567 | printk(KERN_INFO "%s: %s found\n", __func__, | 1508 | printk(KERN_INFO "%s: %s found\n", __func__, |
1568 | usbvision_device_data[model].ModelString); | 1509 | usbvision_device_data[model].model_string); |
1569 | 1510 | ||
1570 | if (usbvision_device_data[model].Interface >= 0) { | 1511 | if (usbvision_device_data[model].interface >= 0) |
1571 | interface = &dev->actconfig->interface[usbvision_device_data[model].Interface]->altsetting[0]; | 1512 | interface = &dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0]; |
1572 | } else { | 1513 | else |
1573 | interface = &dev->actconfig->interface[ifnum]->altsetting[0]; | 1514 | interface = &dev->actconfig->interface[ifnum]->altsetting[0]; |
1574 | } | ||
1575 | endpoint = &interface->endpoint[1].desc; | 1515 | endpoint = &interface->endpoint[1].desc; |
1576 | if (!usb_endpoint_xfer_isoc(endpoint)) { | 1516 | if (!usb_endpoint_xfer_isoc(endpoint)) { |
1577 | dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n", | 1517 | dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n", |
@@ -1592,59 +1532,52 @@ static int __devinit usbvision_probe(struct usb_interface *intf, | |||
1592 | return -ENOMEM; | 1532 | return -ENOMEM; |
1593 | } | 1533 | } |
1594 | 1534 | ||
1595 | if (dev->descriptor.bNumConfigurations > 1) { | 1535 | if (dev->descriptor.bNumConfigurations > 1) |
1596 | usbvision->bridgeType = BRIDGE_NT1004; | 1536 | usbvision->bridge_type = BRIDGE_NT1004; |
1597 | } else if (model == DAZZLE_DVC_90_REV_1_SECAM) { | 1537 | else if (model == DAZZLE_DVC_90_REV_1_SECAM) |
1598 | usbvision->bridgeType = BRIDGE_NT1005; | 1538 | usbvision->bridge_type = BRIDGE_NT1005; |
1599 | } else { | 1539 | else |
1600 | usbvision->bridgeType = BRIDGE_NT1003; | 1540 | usbvision->bridge_type = BRIDGE_NT1003; |
1601 | } | 1541 | PDEBUG(DBG_PROBE, "bridge_type %d", usbvision->bridge_type); |
1602 | PDEBUG(DBG_PROBE, "bridgeType %d", usbvision->bridgeType); | ||
1603 | |||
1604 | mutex_lock(&usbvision->lock); | ||
1605 | 1542 | ||
1606 | /* compute alternate max packet sizes */ | 1543 | /* compute alternate max packet sizes */ |
1607 | uif = dev->actconfig->interface[0]; | 1544 | uif = dev->actconfig->interface[0]; |
1608 | 1545 | ||
1609 | usbvision->num_alt=uif->num_altsetting; | 1546 | usbvision->num_alt = uif->num_altsetting; |
1610 | PDEBUG(DBG_PROBE, "Alternate settings: %i",usbvision->num_alt); | 1547 | PDEBUG(DBG_PROBE, "Alternate settings: %i", usbvision->num_alt); |
1611 | usbvision->alt_max_pkt_size = kmalloc(32* | 1548 | usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL); |
1612 | usbvision->num_alt,GFP_KERNEL); | ||
1613 | if (usbvision->alt_max_pkt_size == NULL) { | 1549 | if (usbvision->alt_max_pkt_size == NULL) { |
1614 | dev_err(&intf->dev, "usbvision: out of memory!\n"); | 1550 | dev_err(&intf->dev, "usbvision: out of memory!\n"); |
1615 | mutex_unlock(&usbvision->lock); | ||
1616 | return -ENOMEM; | 1551 | return -ENOMEM; |
1617 | } | 1552 | } |
1618 | 1553 | ||
1619 | for (i = 0; i < usbvision->num_alt ; i++) { | 1554 | for (i = 0; i < usbvision->num_alt; i++) { |
1620 | u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc. | 1555 | u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc. |
1621 | wMaxPacketSize); | 1556 | wMaxPacketSize); |
1622 | usbvision->alt_max_pkt_size[i] = | 1557 | usbvision->alt_max_pkt_size[i] = |
1623 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | 1558 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); |
1624 | PDEBUG(DBG_PROBE, "Alternate setting %i, max size= %i",i, | 1559 | PDEBUG(DBG_PROBE, "Alternate setting %i, max size= %i", i, |
1625 | usbvision->alt_max_pkt_size[i]); | 1560 | usbvision->alt_max_pkt_size[i]); |
1626 | } | 1561 | } |
1627 | 1562 | ||
1628 | 1563 | ||
1629 | usbvision->nr = usbvision_nr++; | 1564 | usbvision->nr = usbvision_nr++; |
1630 | 1565 | ||
1631 | usbvision->have_tuner = usbvision_device_data[model].Tuner; | 1566 | usbvision->have_tuner = usbvision_device_data[model].tuner; |
1632 | if (usbvision->have_tuner) { | 1567 | if (usbvision->have_tuner) |
1633 | usbvision->tuner_type = usbvision_device_data[model].TunerType; | 1568 | usbvision->tuner_type = usbvision_device_data[model].tuner_type; |
1634 | } | ||
1635 | 1569 | ||
1636 | usbvision->DevModel = model; | 1570 | usbvision->dev_model = model; |
1637 | usbvision->remove_pending = 0; | 1571 | usbvision->remove_pending = 0; |
1638 | usbvision->iface = ifnum; | 1572 | usbvision->iface = ifnum; |
1639 | usbvision->ifaceAlt = 0; | 1573 | usbvision->iface_alt = 0; |
1640 | usbvision->video_endp = endpoint->bEndpointAddress; | 1574 | usbvision->video_endp = endpoint->bEndpointAddress; |
1641 | usbvision->isocPacketSize = 0; | 1575 | usbvision->isoc_packet_size = 0; |
1642 | usbvision->usb_bandwidth = 0; | 1576 | usbvision->usb_bandwidth = 0; |
1643 | usbvision->user = 0; | 1577 | usbvision->user = 0; |
1644 | usbvision->streaming = Stream_Off; | 1578 | usbvision->streaming = stream_off; |
1645 | usbvision_configure_video(usbvision); | 1579 | usbvision_configure_video(usbvision); |
1646 | usbvision_register_video(usbvision); | 1580 | usbvision_register_video(usbvision); |
1647 | mutex_unlock(&usbvision->lock); | ||
1648 | 1581 | ||
1649 | usbvision_create_sysfs(usbvision->vdev); | 1582 | usbvision_create_sysfs(usbvision->vdev); |
1650 | 1583 | ||
@@ -1672,9 +1605,9 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf) | |||
1672 | return; | 1605 | return; |
1673 | } | 1606 | } |
1674 | 1607 | ||
1675 | mutex_lock(&usbvision->lock); | 1608 | mutex_lock(&usbvision->v4l2_lock); |
1676 | 1609 | ||
1677 | // At this time we ask to cancel outstanding URBs | 1610 | /* At this time we ask to cancel outstanding URBs */ |
1678 | usbvision_stop_isoc(usbvision); | 1611 | usbvision_stop_isoc(usbvision); |
1679 | 1612 | ||
1680 | v4l2_device_disconnect(&usbvision->v4l2_dev); | 1613 | v4l2_device_disconnect(&usbvision->v4l2_dev); |
@@ -1683,12 +1616,12 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf) | |||
1683 | usbvision_i2c_unregister(usbvision); | 1616 | usbvision_i2c_unregister(usbvision); |
1684 | usbvision_power_off(usbvision); | 1617 | usbvision_power_off(usbvision); |
1685 | } | 1618 | } |
1686 | usbvision->remove_pending = 1; // Now all ISO data will be ignored | 1619 | usbvision->remove_pending = 1; /* Now all ISO data will be ignored */ |
1687 | 1620 | ||
1688 | usb_put_dev(usbvision->dev); | 1621 | usb_put_dev(usbvision->dev); |
1689 | usbvision->dev = NULL; // USB device is no more | 1622 | usbvision->dev = NULL; /* USB device is no more */ |
1690 | 1623 | ||
1691 | mutex_unlock(&usbvision->lock); | 1624 | mutex_unlock(&usbvision->v4l2_lock); |
1692 | 1625 | ||
1693 | if (usbvision->user) { | 1626 | if (usbvision->user) { |
1694 | printk(KERN_INFO "%s: In use, disconnect pending\n", | 1627 | printk(KERN_INFO "%s: In use, disconnect pending\n", |
@@ -1717,7 +1650,7 @@ static struct usb_driver usbvision_driver = { | |||
1717 | */ | 1650 | */ |
1718 | static int __init usbvision_init(void) | 1651 | static int __init usbvision_init(void) |
1719 | { | 1652 | { |
1720 | int errCode; | 1653 | int err_code; |
1721 | 1654 | ||
1722 | PDEBUG(DBG_PROBE, ""); | 1655 | PDEBUG(DBG_PROBE, ""); |
1723 | 1656 | ||
@@ -1726,27 +1659,27 @@ static int __init usbvision_init(void) | |||
1726 | PDEBUG(DBG_MMAP, "MMAP debugging is enabled [video]"); | 1659 | PDEBUG(DBG_MMAP, "MMAP debugging is enabled [video]"); |
1727 | 1660 | ||
1728 | /* disable planar mode support unless compression enabled */ | 1661 | /* disable planar mode support unless compression enabled */ |
1729 | if (isocMode != ISOC_MODE_COMPRESS ) { | 1662 | if (isoc_mode != ISOC_MODE_COMPRESS) { |
1730 | // FIXME : not the right way to set supported flag | 1663 | /* FIXME : not the right way to set supported flag */ |
1731 | usbvision_v4l2_format[6].supported = 0; // V4L2_PIX_FMT_YVU420 | 1664 | usbvision_v4l2_format[6].supported = 0; /* V4L2_PIX_FMT_YVU420 */ |
1732 | usbvision_v4l2_format[7].supported = 0; // V4L2_PIX_FMT_YUV422P | 1665 | usbvision_v4l2_format[7].supported = 0; /* V4L2_PIX_FMT_YUV422P */ |
1733 | } | 1666 | } |
1734 | 1667 | ||
1735 | errCode = usb_register(&usbvision_driver); | 1668 | err_code = usb_register(&usbvision_driver); |
1736 | 1669 | ||
1737 | if (errCode == 0) { | 1670 | if (err_code == 0) { |
1738 | printk(KERN_INFO DRIVER_DESC " : " USBVISION_VERSION_STRING "\n"); | 1671 | printk(KERN_INFO DRIVER_DESC " : " USBVISION_VERSION_STRING "\n"); |
1739 | PDEBUG(DBG_PROBE, "success"); | 1672 | PDEBUG(DBG_PROBE, "success"); |
1740 | } | 1673 | } |
1741 | return errCode; | 1674 | return err_code; |
1742 | } | 1675 | } |
1743 | 1676 | ||
1744 | static void __exit usbvision_exit(void) | 1677 | static void __exit usbvision_exit(void) |
1745 | { | 1678 | { |
1746 | PDEBUG(DBG_PROBE, ""); | 1679 | PDEBUG(DBG_PROBE, ""); |
1747 | 1680 | ||
1748 | usb_deregister(&usbvision_driver); | 1681 | usb_deregister(&usbvision_driver); |
1749 | PDEBUG(DBG_PROBE, "success"); | 1682 | PDEBUG(DBG_PROBE, "success"); |
1750 | } | 1683 | } |
1751 | 1684 | ||
1752 | module_init(usbvision_init); | 1685 | module_init(usbvision_init); |
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h index cc4e96c8cd6c..8074787fd1ac 100644 --- a/drivers/media/video/usbvision/usbvision.h +++ b/drivers/media/video/usbvision/usbvision.h | |||
@@ -132,15 +132,15 @@ | |||
132 | #define MAX_BYTES_PER_PIXEL 4 | 132 | #define MAX_BYTES_PER_PIXEL 4 |
133 | 133 | ||
134 | #define MIN_FRAME_WIDTH 64 | 134 | #define MIN_FRAME_WIDTH 64 |
135 | #define MAX_USB_WIDTH 320 //384 | 135 | #define MAX_USB_WIDTH 320 /* 384 */ |
136 | #define MAX_FRAME_WIDTH 320 //384 /*streching sometimes causes crashes*/ | 136 | #define MAX_FRAME_WIDTH 320 /* 384 */ /* streching sometimes causes crashes*/ |
137 | 137 | ||
138 | #define MIN_FRAME_HEIGHT 48 | 138 | #define MIN_FRAME_HEIGHT 48 |
139 | #define MAX_USB_HEIGHT 240 //288 | 139 | #define MAX_USB_HEIGHT 240 /* 288 */ |
140 | #define MAX_FRAME_HEIGHT 240 //288 /*Streching sometimes causes crashes*/ | 140 | #define MAX_FRAME_HEIGHT 240 /* 288 */ /* Streching sometimes causes crashes*/ |
141 | 141 | ||
142 | #define MAX_FRAME_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * MAX_BYTES_PER_PIXEL) | 142 | #define MAX_FRAME_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * MAX_BYTES_PER_PIXEL) |
143 | #define USBVISION_CLIPMASK_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) //bytesize of clipmask | 143 | #define USBVISION_CLIPMASK_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) /* bytesize of clipmask */ |
144 | 144 | ||
145 | #define USBVISION_URB_FRAMES 32 | 145 | #define USBVISION_URB_FRAMES 32 |
146 | 146 | ||
@@ -148,7 +148,7 @@ | |||
148 | #define USBVISION_NUMFRAMES 3 /* Maximum number of frames an application can get */ | 148 | #define USBVISION_NUMFRAMES 3 /* Maximum number of frames an application can get */ |
149 | #define USBVISION_NUMSBUF 2 /* Dimensioning the USB S buffering */ | 149 | #define USBVISION_NUMSBUF 2 /* Dimensioning the USB S buffering */ |
150 | 150 | ||
151 | #define USBVISION_POWEROFF_TIME 3 * (HZ) // 3 seconds | 151 | #define USBVISION_POWEROFF_TIME (3 * HZ) /* 3 seconds */ |
152 | 152 | ||
153 | 153 | ||
154 | #define FRAMERATE_MIN 0 | 154 | #define FRAMERATE_MIN 0 |
@@ -161,7 +161,8 @@ enum { | |||
161 | }; | 161 | }; |
162 | 162 | ||
163 | /* This macro restricts an int variable to an inclusive range */ | 163 | /* This macro restricts an int variable to an inclusive range */ |
164 | #define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); } | 164 | #define RESTRICT_TO_RANGE(v, mi, ma) \ |
165 | { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); } | ||
165 | 166 | ||
166 | /* | 167 | /* |
167 | * We use macros to do YUV -> RGB conversion because this is | 168 | * We use macros to do YUV -> RGB conversion because this is |
@@ -183,18 +184,18 @@ enum { | |||
183 | * Make sure the output values are within [0..255] range. | 184 | * Make sure the output values are within [0..255] range. |
184 | */ | 185 | */ |
185 | #define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x))) | 186 | #define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x))) |
186 | #define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \ | 187 | #define YUV_TO_RGB_BY_THE_BOOK(my, mu, mv, mr, mg, mb) { \ |
187 | int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \ | 188 | int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \ |
188 | mm_y = (my) - 16; \ | 189 | mm_y = (my) - 16; \ |
189 | mm_u = (mu) - 128; \ | 190 | mm_u = (mu) - 128; \ |
190 | mm_v = (mv) - 128; \ | 191 | mm_v = (mv) - 128; \ |
191 | mm_yc= mm_y * 76284; \ | 192 | mm_yc = mm_y * 76284; \ |
192 | mm_b = (mm_yc + 132252*mm_v ) >> 16; \ | 193 | mm_b = (mm_yc + 132252 * mm_v) >> 16; \ |
193 | mm_g = (mm_yc - 53281*mm_u - 25625*mm_v ) >> 16; \ | 194 | mm_g = (mm_yc - 53281 * mm_u - 25625 * mm_v) >> 16; \ |
194 | mm_r = (mm_yc + 104595*mm_u ) >> 16; \ | 195 | mm_r = (mm_yc + 104595 * mm_u) >> 16; \ |
195 | mb = LIMIT_RGB(mm_b); \ | 196 | mb = LIMIT_RGB(mm_b); \ |
196 | mg = LIMIT_RGB(mm_g); \ | 197 | mg = LIMIT_RGB(mm_g); \ |
197 | mr = LIMIT_RGB(mm_r); \ | 198 | mr = LIMIT_RGB(mm_r); \ |
198 | } | 199 | } |
199 | 200 | ||
200 | /* Debugging aid */ | 201 | /* Debugging aid */ |
@@ -202,7 +203,7 @@ enum { | |||
202 | wait_queue_head_t wq; \ | 203 | wait_queue_head_t wq; \ |
203 | init_waitqueue_head(&wq); \ | 204 | init_waitqueue_head(&wq); \ |
204 | printk(KERN_INFO "Say: %s\n", what); \ | 205 | printk(KERN_INFO "Say: %s\n", what); \ |
205 | interruptible_sleep_on_timeout (&wq, HZ*3); \ | 206 | interruptible_sleep_on_timeout(&wq, HZ * 3); \ |
206 | } | 207 | } |
207 | 208 | ||
208 | /* | 209 | /* |
@@ -223,39 +224,39 @@ enum { | |||
223 | /* ----------------------------------------------------------------- */ | 224 | /* ----------------------------------------------------------------- */ |
224 | /* usbvision video structures */ | 225 | /* usbvision video structures */ |
225 | /* ----------------------------------------------------------------- */ | 226 | /* ----------------------------------------------------------------- */ |
226 | enum ScanState { | 227 | enum scan_state { |
227 | ScanState_Scanning, /* Scanning for header */ | 228 | scan_state_scanning, /* Scanning for header */ |
228 | ScanState_Lines /* Parsing lines */ | 229 | scan_state_lines /* Parsing lines */ |
229 | }; | 230 | }; |
230 | 231 | ||
231 | /* Completion states of the data parser */ | 232 | /* Completion states of the data parser */ |
232 | enum ParseState { | 233 | enum parse_state { |
233 | ParseState_Continue, /* Just parse next item */ | 234 | parse_state_continue, /* Just parse next item */ |
234 | ParseState_NextFrame, /* Frame done, send it to V4L */ | 235 | parse_state_next_frame, /* Frame done, send it to V4L */ |
235 | ParseState_Out, /* Not enough data for frame */ | 236 | parse_state_out, /* Not enough data for frame */ |
236 | ParseState_EndParse /* End parsing */ | 237 | parse_state_end_parse /* End parsing */ |
237 | }; | 238 | }; |
238 | 239 | ||
239 | enum FrameState { | 240 | enum frame_state { |
240 | FrameState_Unused, /* Unused (no MCAPTURE) */ | 241 | frame_state_unused, /* Unused (no MCAPTURE) */ |
241 | FrameState_Ready, /* Ready to start grabbing */ | 242 | frame_state_ready, /* Ready to start grabbing */ |
242 | FrameState_Grabbing, /* In the process of being grabbed into */ | 243 | frame_state_grabbing, /* In the process of being grabbed into */ |
243 | FrameState_Done, /* Finished grabbing, but not been synced yet */ | 244 | frame_state_done, /* Finished grabbing, but not been synced yet */ |
244 | FrameState_DoneHold, /* Are syncing or reading */ | 245 | frame_state_done_hold, /* Are syncing or reading */ |
245 | FrameState_Error, /* Something bad happened while processing */ | 246 | frame_state_error, /* Something bad happened while processing */ |
246 | }; | 247 | }; |
247 | 248 | ||
248 | /* stream states */ | 249 | /* stream states */ |
249 | enum StreamState { | 250 | enum stream_state { |
250 | Stream_Off, /* Driver streaming is completely OFF */ | 251 | stream_off, /* Driver streaming is completely OFF */ |
251 | Stream_Idle, /* Driver streaming is ready to be put ON by the application */ | 252 | stream_idle, /* Driver streaming is ready to be put ON by the application */ |
252 | Stream_Interrupt, /* Driver streaming must be interrupted */ | 253 | stream_interrupt, /* Driver streaming must be interrupted */ |
253 | Stream_On, /* Driver streaming is put ON by the application */ | 254 | stream_on, /* Driver streaming is put ON by the application */ |
254 | }; | 255 | }; |
255 | 256 | ||
256 | enum IsocState { | 257 | enum isoc_state { |
257 | IsocState_InFrame, /* Isoc packet is member of frame */ | 258 | isoc_state_in_frame, /* Isoc packet is member of frame */ |
258 | IsocState_NoFrame, /* Isoc packet is not member of any frame */ | 259 | isoc_state_no_frame, /* Isoc packet is not member of any frame */ |
259 | }; | 260 | }; |
260 | 261 | ||
261 | struct usb_device; | 262 | struct usb_device; |
@@ -265,8 +266,8 @@ struct usbvision_sbuf { | |||
265 | struct urb *urb; | 266 | struct urb *urb; |
266 | }; | 267 | }; |
267 | 268 | ||
268 | #define USBVISION_MAGIC_1 0x55 | 269 | #define USBVISION_MAGIC_1 0x55 |
269 | #define USBVISION_MAGIC_2 0xAA | 270 | #define USBVISION_MAGIC_2 0xAA |
270 | #define USBVISION_HEADER_LENGTH 0x0c | 271 | #define USBVISION_HEADER_LENGTH 0x0c |
271 | #define USBVISION_SAA7111_ADDR 0x48 | 272 | #define USBVISION_SAA7111_ADDR 0x48 |
272 | #define USBVISION_SAA7113_ADDR 0x4a | 273 | #define USBVISION_SAA7113_ADDR 0x4a |
@@ -286,23 +287,23 @@ struct usbvision_v4l2_format_st { | |||
286 | struct usbvision_frame_header { | 287 | struct usbvision_frame_header { |
287 | unsigned char magic_1; /* 0 magic */ | 288 | unsigned char magic_1; /* 0 magic */ |
288 | unsigned char magic_2; /* 1 magic */ | 289 | unsigned char magic_2; /* 1 magic */ |
289 | unsigned char headerLength; /* 2 */ | 290 | unsigned char header_length; /* 2 */ |
290 | unsigned char frameNum; /* 3 */ | 291 | unsigned char frame_num; /* 3 */ |
291 | unsigned char framePhase; /* 4 */ | 292 | unsigned char frame_phase; /* 4 */ |
292 | unsigned char frameLatency; /* 5 */ | 293 | unsigned char frame_latency; /* 5 */ |
293 | unsigned char dataFormat; /* 6 */ | 294 | unsigned char data_format; /* 6 */ |
294 | unsigned char formatParam; /* 7 */ | 295 | unsigned char format_param; /* 7 */ |
295 | unsigned char frameWidthLo; /* 8 */ | 296 | unsigned char frame_width_lo; /* 8 */ |
296 | unsigned char frameWidthHi; /* 9 */ | 297 | unsigned char frame_width_hi; /* 9 */ |
297 | unsigned char frameHeightLo; /* 10 */ | 298 | unsigned char frame_height_lo; /* 10 */ |
298 | unsigned char frameHeightHi; /* 11 */ | 299 | unsigned char frame_height_hi; /* 11 */ |
299 | __u16 frameWidth; /* 8 - 9 after endian correction*/ | 300 | __u16 frame_width; /* 8 - 9 after endian correction*/ |
300 | __u16 frameHeight; /* 10 - 11 after endian correction*/ | 301 | __u16 frame_height; /* 10 - 11 after endian correction*/ |
301 | }; | 302 | }; |
302 | 303 | ||
303 | struct usbvision_frame { | 304 | struct usbvision_frame { |
304 | char *data; /* Frame buffer */ | 305 | char *data; /* Frame buffer */ |
305 | struct usbvision_frame_header isocHeader; /* Header from stream */ | 306 | struct usbvision_frame_header isoc_header; /* Header from stream */ |
306 | 307 | ||
307 | int width; /* Width application is expecting */ | 308 | int width; /* Width application is expecting */ |
308 | int height; /* Height */ | 309 | int height; /* Height */ |
@@ -322,7 +323,7 @@ struct usbvision_frame { | |||
322 | struct usbvision_v4l2_format_st v4l2_format; /* format the user needs*/ | 323 | struct usbvision_v4l2_format_st v4l2_format; /* format the user needs*/ |
323 | int v4l2_linesize; /* bytes for one videoline*/ | 324 | int v4l2_linesize; /* bytes for one videoline*/ |
324 | struct timeval timestamp; | 325 | struct timeval timestamp; |
325 | int sequence; // How many video frames we send to user | 326 | int sequence; /* How many video frames we send to user */ |
326 | }; | 327 | }; |
327 | 328 | ||
328 | #define CODEC_SAA7113 7113 | 329 | #define CODEC_SAA7113 7113 |
@@ -332,24 +333,24 @@ struct usbvision_frame { | |||
332 | #define BRIDGE_NT1005 1005 | 333 | #define BRIDGE_NT1005 1005 |
333 | 334 | ||
334 | struct usbvision_device_data_st { | 335 | struct usbvision_device_data_st { |
335 | __u64 VideoNorm; | 336 | __u64 video_norm; |
336 | const char *ModelString; | 337 | const char *model_string; |
337 | int Interface; /* to handle special interface number like BELKIN and Hauppauge WinTV-USB II */ | 338 | int interface; /* to handle special interface number like BELKIN and Hauppauge WinTV-USB II */ |
338 | __u16 Codec; | 339 | __u16 codec; |
339 | unsigned VideoChannels:3; | 340 | unsigned video_channels:3; |
340 | unsigned AudioChannels:2; | 341 | unsigned audio_channels:2; |
341 | unsigned Radio:1; | 342 | unsigned radio:1; |
342 | unsigned vbi:1; | 343 | unsigned vbi:1; |
343 | unsigned Tuner:1; | 344 | unsigned tuner:1; |
344 | unsigned Vin_Reg1_override:1; /* Override default value with */ | 345 | unsigned vin_reg1_override:1; /* Override default value with */ |
345 | unsigned Vin_Reg2_override:1; /* Vin_Reg1, Vin_Reg2, etc. */ | 346 | unsigned vin_reg2_override:1; /* vin_reg1, vin_reg2, etc. */ |
346 | unsigned Dvi_yuv_override:1; | 347 | unsigned dvi_yuv_override:1; |
347 | __u8 Vin_Reg1; | 348 | __u8 vin_reg1; |
348 | __u8 Vin_Reg2; | 349 | __u8 vin_reg2; |
349 | __u8 Dvi_yuv; | 350 | __u8 dvi_yuv; |
350 | __u8 TunerType; | 351 | __u8 tuner_type; |
351 | __s16 X_Offset; | 352 | __s16 x_offset; |
352 | __s16 Y_Offset; | 353 | __s16 y_offset; |
353 | }; | 354 | }; |
354 | 355 | ||
355 | /* Declared on usbvision-cards.c */ | 356 | /* Declared on usbvision-cards.c */ |
@@ -358,50 +359,50 @@ extern struct usb_device_id usbvision_table[]; | |||
358 | 359 | ||
359 | struct usb_usbvision { | 360 | struct usb_usbvision { |
360 | struct v4l2_device v4l2_dev; | 361 | struct v4l2_device v4l2_dev; |
361 | struct video_device *vdev; /* Video Device */ | 362 | struct video_device *vdev; /* Video Device */ |
362 | struct video_device *rdev; /* Radio Device */ | 363 | struct video_device *rdev; /* Radio Device */ |
363 | 364 | ||
364 | /* i2c Declaration Section*/ | 365 | /* i2c Declaration Section*/ |
365 | struct i2c_adapter i2c_adap; | 366 | struct i2c_adapter i2c_adap; |
366 | int registered_i2c; | 367 | int registered_i2c; |
367 | 368 | ||
368 | struct urb *ctrlUrb; | 369 | struct urb *ctrl_urb; |
369 | unsigned char ctrlUrbBuffer[8]; | 370 | unsigned char ctrl_urb_buffer[8]; |
370 | int ctrlUrbBusy; | 371 | int ctrl_urb_busy; |
371 | struct usb_ctrlrequest ctrlUrbSetup; | 372 | struct usb_ctrlrequest ctrl_urb_setup; |
372 | wait_queue_head_t ctrlUrb_wq; // Processes waiting | 373 | wait_queue_head_t ctrl_urb_wq; /* Processes waiting */ |
373 | 374 | ||
374 | /* configuration part */ | 375 | /* configuration part */ |
375 | int have_tuner; | 376 | int have_tuner; |
376 | int tuner_type; | 377 | int tuner_type; |
377 | int bridgeType; // NT1003, NT1004, NT1005 | 378 | int bridge_type; /* NT1003, NT1004, NT1005 */ |
378 | int radio; | 379 | int radio; |
379 | int video_inputs; // # of inputs | 380 | int video_inputs; /* # of inputs */ |
380 | unsigned long freq; | 381 | unsigned long freq; |
381 | int AudioMute; | 382 | int audio_mute; |
382 | int AudioChannel; | 383 | int audio_channel; |
383 | int isocMode; // format of video data for the usb isoc-transfer | 384 | int isoc_mode; /* format of video data for the usb isoc-transfer */ |
384 | unsigned int nr; // Number of the device | 385 | unsigned int nr; /* Number of the device */ |
385 | 386 | ||
386 | /* Device structure */ | 387 | /* Device structure */ |
387 | struct usb_device *dev; | 388 | struct usb_device *dev; |
388 | /* usb transfer */ | 389 | /* usb transfer */ |
389 | int num_alt; /* Number of alternative settings */ | 390 | int num_alt; /* Number of alternative settings */ |
390 | unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ | 391 | unsigned int *alt_max_pkt_size; /* array of max_packet_size */ |
391 | unsigned char iface; /* Video interface number */ | 392 | unsigned char iface; /* Video interface number */ |
392 | unsigned char ifaceAlt; /* Alt settings */ | 393 | unsigned char iface_alt; /* Alt settings */ |
393 | unsigned char Vin_Reg2_Preset; | 394 | unsigned char vin_reg2_preset; |
394 | struct mutex lock; | 395 | struct mutex v4l2_lock; |
395 | struct timer_list powerOffTimer; | 396 | struct timer_list power_off_timer; |
396 | struct work_struct powerOffWork; | 397 | struct work_struct power_off_work; |
397 | int power; /* is the device powered on? */ | 398 | int power; /* is the device powered on? */ |
398 | int user; /* user count for exclusive use */ | 399 | int user; /* user count for exclusive use */ |
399 | int initialized; /* Had we already sent init sequence? */ | 400 | int initialized; /* Had we already sent init sequence? */ |
400 | int DevModel; /* What type of USBVISION device we got? */ | 401 | int dev_model; /* What type of USBVISION device we got? */ |
401 | enum StreamState streaming; /* Are we streaming Isochronous? */ | 402 | enum stream_state streaming; /* Are we streaming Isochronous? */ |
402 | int last_error; /* What calamity struck us? */ | 403 | int last_error; /* What calamity struck us? */ |
403 | int curwidth; /* width of the frame the device is currently set to*/ | 404 | int curwidth; /* width of the frame the device is currently set to*/ |
404 | int curheight; /* height of the frame the device is currently set to*/ | 405 | int curheight; /* height of the frame the device is currently set to*/ |
405 | int stretch_width; /* stretch-factor for frame width (from usb to screen)*/ | 406 | int stretch_width; /* stretch-factor for frame width (from usb to screen)*/ |
406 | int stretch_height; /* stretch-factor for frame height (from usb to screen)*/ | 407 | int stretch_height; /* stretch-factor for frame height (from usb to screen)*/ |
407 | char *fbuf; /* Videodev buffer area for mmap*/ | 408 | char *fbuf; /* Videodev buffer area for mmap*/ |
@@ -411,10 +412,10 @@ struct usb_usbvision { | |||
411 | struct list_head inqueue, outqueue; /* queued frame list and ready to dequeue frame list */ | 412 | struct list_head inqueue, outqueue; /* queued frame list and ready to dequeue frame list */ |
412 | wait_queue_head_t wait_frame; /* Processes waiting */ | 413 | wait_queue_head_t wait_frame; /* Processes waiting */ |
413 | wait_queue_head_t wait_stream; /* Processes waiting */ | 414 | wait_queue_head_t wait_stream; /* Processes waiting */ |
414 | struct usbvision_frame *curFrame; // pointer to current frame, set by usbvision_find_header | 415 | struct usbvision_frame *cur_frame; /* pointer to current frame, set by usbvision_find_header */ |
415 | struct usbvision_frame frame[USBVISION_NUMFRAMES]; // frame buffer | 416 | struct usbvision_frame frame[USBVISION_NUMFRAMES]; /* frame buffer */ |
416 | int num_frames; // number of frames allocated | 417 | int num_frames; /* number of frames allocated */ |
417 | struct usbvision_sbuf sbuf[USBVISION_NUMSBUF]; // S buffering | 418 | struct usbvision_sbuf sbuf[USBVISION_NUMSBUF]; /* S buffering */ |
418 | volatile int remove_pending; /* If set then about to exit */ | 419 | volatile int remove_pending; /* If set then about to exit */ |
419 | 420 | ||
420 | /* Scratch space from the Isochronous Pipe.*/ | 421 | /* Scratch space from the Isochronous Pipe.*/ |
@@ -424,43 +425,43 @@ struct usb_usbvision { | |||
424 | int scratch_headermarker[USBVISION_NUM_HEADERMARKER]; | 425 | int scratch_headermarker[USBVISION_NUM_HEADERMARKER]; |
425 | int scratch_headermarker_read_ptr; | 426 | int scratch_headermarker_read_ptr; |
426 | int scratch_headermarker_write_ptr; | 427 | int scratch_headermarker_write_ptr; |
427 | enum IsocState isocstate; | 428 | enum isoc_state isocstate; |
428 | struct usbvision_v4l2_format_st palette; | 429 | struct usbvision_v4l2_format_st palette; |
429 | 430 | ||
430 | struct v4l2_capability vcap; /* Video capabilities */ | 431 | struct v4l2_capability vcap; /* Video capabilities */ |
431 | unsigned int ctl_input; /* selected input */ | 432 | unsigned int ctl_input; /* selected input */ |
432 | v4l2_std_id tvnormId; /* selected tv norm */ | 433 | v4l2_std_id tvnorm_id; /* selected tv norm */ |
433 | unsigned char video_endp; /* 0x82 for USBVISION devices based */ | 434 | unsigned char video_endp; /* 0x82 for USBVISION devices based */ |
434 | 435 | ||
435 | // Decompression stuff: | 436 | /* Decompression stuff: */ |
436 | unsigned char *IntraFrameBuffer; /* Buffer for reference frame */ | 437 | unsigned char *intra_frame_buffer; /* Buffer for reference frame */ |
437 | int BlockPos; //for test only | 438 | int block_pos; /* for test only */ |
438 | int requestIntra; // 0 = normal; 1 = intra frame is requested; | 439 | int request_intra; /* 0 = normal; 1 = intra frame is requested; */ |
439 | int lastIsocFrameNum; // check for lost isoc frames | 440 | int last_isoc_frame_num; /* check for lost isoc frames */ |
440 | int isocPacketSize; // need to calculate usedBandwidth | 441 | int isoc_packet_size; /* need to calculate used_bandwidth */ |
441 | int usedBandwidth; // used bandwidth 0-100%, need to set comprLevel | 442 | int used_bandwidth; /* used bandwidth 0-100%, need to set compr_level */ |
442 | int comprLevel; // How strong (100) or weak (0) is compression | 443 | int compr_level; /* How strong (100) or weak (0) is compression */ |
443 | int lastComprLevel; // How strong (100) or weak (0) was compression | 444 | int last_compr_level; /* How strong (100) or weak (0) was compression */ |
444 | int usb_bandwidth; /* Mbit/s */ | 445 | int usb_bandwidth; /* Mbit/s */ |
445 | 446 | ||
446 | /* Statistics that can be overlayed on the screen */ | 447 | /* Statistics that can be overlayed on the screen */ |
447 | unsigned long isocUrbCount; // How many URBs we received so far | 448 | unsigned long isoc_urb_count; /* How many URBs we received so far */ |
448 | unsigned long urb_length; /* Length of last URB */ | 449 | unsigned long urb_length; /* Length of last URB */ |
449 | unsigned long isocDataCount; /* How many bytes we received */ | 450 | unsigned long isoc_data_count; /* How many bytes we received */ |
450 | unsigned long header_count; /* How many frame headers we found */ | 451 | unsigned long header_count; /* How many frame headers we found */ |
451 | unsigned long scratch_ovf_count; /* How many times we overflowed scratch */ | 452 | unsigned long scratch_ovf_count; /* How many times we overflowed scratch */ |
452 | unsigned long isocSkipCount; /* How many empty ISO packets received */ | 453 | unsigned long isoc_skip_count; /* How many empty ISO packets received */ |
453 | unsigned long isocErrCount; /* How many bad ISO packets received */ | 454 | unsigned long isoc_err_count; /* How many bad ISO packets received */ |
454 | unsigned long isocPacketCount; // How many packets we totally got | 455 | unsigned long isoc_packet_count; /* How many packets we totally got */ |
455 | unsigned long timeInIrq; // How long do we need for interrupt | 456 | unsigned long time_in_irq; /* How long do we need for interrupt */ |
456 | int isocMeasureBandwidthCount; | 457 | int isoc_measure_bandwidth_count; |
457 | int frame_num; // How many video frames we send to user | 458 | int frame_num; /* How many video frames we send to user */ |
458 | int maxStripLen; // How big is the biggest strip | 459 | int max_strip_len; /* How big is the biggest strip */ |
459 | int comprBlockPos; | 460 | int comprblock_pos; |
460 | int stripLenErrors; // How many times was BlockPos greater than StripLen | 461 | int strip_len_errors; /* How many times was block_pos greater than strip_len */ |
461 | int stripMagicErrors; | 462 | int strip_magic_errors; |
462 | int stripLineNumberErrors; | 463 | int strip_line_number_errors; |
463 | int ComprBlockTypes[4]; | 464 | int compr_block_types[4]; |
464 | }; | 465 | }; |
465 | 466 | ||
466 | static inline struct usb_usbvision *to_usbvision(struct v4l2_device *v4l2_dev) | 467 | static inline struct usb_usbvision *to_usbvision(struct v4l2_device *v4l2_dev) |
@@ -494,13 +495,13 @@ void usbvision_scratch_free(struct usb_usbvision *usbvision); | |||
494 | int usbvision_decompress_alloc(struct usb_usbvision *usbvision); | 495 | int usbvision_decompress_alloc(struct usb_usbvision *usbvision); |
495 | void usbvision_decompress_free(struct usb_usbvision *usbvision); | 496 | void usbvision_decompress_free(struct usb_usbvision *usbvision); |
496 | 497 | ||
497 | int usbvision_setup(struct usb_usbvision *usbvision,int format); | 498 | int usbvision_setup(struct usb_usbvision *usbvision, int format); |
498 | int usbvision_init_isoc(struct usb_usbvision *usbvision); | 499 | int usbvision_init_isoc(struct usb_usbvision *usbvision); |
499 | int usbvision_restart_isoc(struct usb_usbvision *usbvision); | 500 | int usbvision_restart_isoc(struct usb_usbvision *usbvision); |
500 | void usbvision_stop_isoc(struct usb_usbvision *usbvision); | 501 | void usbvision_stop_isoc(struct usb_usbvision *usbvision); |
501 | int usbvision_set_alternate(struct usb_usbvision *dev); | 502 | int usbvision_set_alternate(struct usb_usbvision *dev); |
502 | 503 | ||
503 | int usbvision_set_audio(struct usb_usbvision *usbvision, int AudioChannel); | 504 | int usbvision_set_audio(struct usb_usbvision *usbvision, int audio_channel); |
504 | int usbvision_audio_off(struct usb_usbvision *usbvision); | 505 | int usbvision_audio_off(struct usb_usbvision *usbvision); |
505 | 506 | ||
506 | int usbvision_begin_streaming(struct usb_usbvision *usbvision); | 507 | int usbvision_begin_streaming(struct usb_usbvision *usbvision); |
@@ -511,9 +512,9 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel); | |||
511 | int usbvision_set_input(struct usb_usbvision *usbvision); | 512 | int usbvision_set_input(struct usb_usbvision *usbvision); |
512 | int usbvision_set_output(struct usb_usbvision *usbvision, int width, int height); | 513 | int usbvision_set_output(struct usb_usbvision *usbvision, int width, int height); |
513 | 514 | ||
514 | void usbvision_init_powerOffTimer(struct usb_usbvision *usbvision); | 515 | void usbvision_init_power_off_timer(struct usb_usbvision *usbvision); |
515 | void usbvision_set_powerOffTimer(struct usb_usbvision *usbvision); | 516 | void usbvision_set_power_off_timer(struct usb_usbvision *usbvision); |
516 | void usbvision_reset_powerOffTimer(struct usb_usbvision *usbvision); | 517 | void usbvision_reset_power_off_timer(struct usb_usbvision *usbvision); |
517 | int usbvision_power_off(struct usb_usbvision *usbvision); | 518 | int usbvision_power_off(struct usb_usbvision *usbvision); |
518 | int usbvision_power_on(struct usb_usbvision *usbvision); | 519 | int usbvision_power_on(struct usb_usbvision *usbvision); |
519 | 520 | ||
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 8cf61e8a634f..9005a8d9d5f8 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c | |||
@@ -1035,11 +1035,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1035 | return uvc_xu_ctrl_query(chain, arg, 1); | 1035 | return uvc_xu_ctrl_query(chain, arg, 1); |
1036 | 1036 | ||
1037 | default: | 1037 | default: |
1038 | if ((ret = v4l_compat_translate_ioctl(file, cmd, arg, | 1038 | uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd); |
1039 | uvc_v4l2_do_ioctl)) == -ENOIOCTLCMD) | 1039 | return -EINVAL; |
1040 | uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", | ||
1041 | cmd); | ||
1042 | return ret; | ||
1043 | } | 1040 | } |
1044 | 1041 | ||
1045 | return ret; | 1042 | return ret; |
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c deleted file mode 100644 index d4ac751036a2..000000000000 --- a/drivers/media/video/v4l1-compat.c +++ /dev/null | |||
@@ -1,1277 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Video for Linux Two | ||
4 | * Backward Compatibility Layer | ||
5 | * | ||
6 | * Support subroutines for providing V4L2 drivers with backward | ||
7 | * compatibility with applications using the old API. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | * | ||
14 | * Author: Bill Dirks <bill@thedirks.org> | ||
15 | * et al. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | |||
20 | #include <linux/init.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/mm.h> | ||
26 | #include <linux/fs.h> | ||
27 | #include <linux/file.h> | ||
28 | #include <linux/string.h> | ||
29 | #include <linux/errno.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/videodev.h> | ||
32 | #include <media/v4l2-common.h> | ||
33 | #include <media/v4l2-ioctl.h> | ||
34 | |||
35 | #include <asm/uaccess.h> | ||
36 | #include <asm/system.h> | ||
37 | #include <asm/pgtable.h> | ||
38 | |||
39 | static unsigned int debug; | ||
40 | module_param(debug, int, 0644); | ||
41 | MODULE_PARM_DESC(debug, "enable debug messages"); | ||
42 | MODULE_AUTHOR("Bill Dirks"); | ||
43 | MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers."); | ||
44 | MODULE_LICENSE("GPL"); | ||
45 | |||
46 | #define dprintk(fmt, arg...) \ | ||
47 | do { \ | ||
48 | if (debug) \ | ||
49 | printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg);\ | ||
50 | } while (0) | ||
51 | |||
52 | /* | ||
53 | * I O C T L T R A N S L A T I O N | ||
54 | * | ||
55 | * From here on down is the code for translating the numerous | ||
56 | * ioctl commands from the old API to the new API. | ||
57 | */ | ||
58 | |||
59 | static int | ||
60 | get_v4l_control(struct file *file, | ||
61 | int cid, | ||
62 | v4l2_kioctl drv) | ||
63 | { | ||
64 | struct v4l2_queryctrl qctrl2; | ||
65 | struct v4l2_control ctrl2; | ||
66 | int err; | ||
67 | |||
68 | qctrl2.id = cid; | ||
69 | err = drv(file, VIDIOC_QUERYCTRL, &qctrl2); | ||
70 | if (err < 0) | ||
71 | dprintk("VIDIOC_QUERYCTRL: %d\n", err); | ||
72 | if (err == 0 && !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) { | ||
73 | ctrl2.id = qctrl2.id; | ||
74 | err = drv(file, VIDIOC_G_CTRL, &ctrl2); | ||
75 | if (err < 0) { | ||
76 | dprintk("VIDIOC_G_CTRL: %d\n", err); | ||
77 | return 0; | ||
78 | } | ||
79 | return DIV_ROUND_CLOSEST((ctrl2.value-qctrl2.minimum) * 65535, | ||
80 | qctrl2.maximum - qctrl2.minimum); | ||
81 | } | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int | ||
86 | set_v4l_control(struct file *file, | ||
87 | int cid, | ||
88 | int value, | ||
89 | v4l2_kioctl drv) | ||
90 | { | ||
91 | struct v4l2_queryctrl qctrl2; | ||
92 | struct v4l2_control ctrl2; | ||
93 | int err; | ||
94 | |||
95 | qctrl2.id = cid; | ||
96 | err = drv(file, VIDIOC_QUERYCTRL, &qctrl2); | ||
97 | if (err < 0) | ||
98 | dprintk("VIDIOC_QUERYCTRL: %d\n", err); | ||
99 | if (err == 0 && | ||
100 | !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) && | ||
101 | !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED)) { | ||
102 | if (value < 0) | ||
103 | value = 0; | ||
104 | if (value > 65535) | ||
105 | value = 65535; | ||
106 | if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN) | ||
107 | value = 65535; | ||
108 | ctrl2.id = qctrl2.id; | ||
109 | ctrl2.value = | ||
110 | (value * (qctrl2.maximum - qctrl2.minimum) | ||
111 | + 32767) | ||
112 | / 65535; | ||
113 | ctrl2.value += qctrl2.minimum; | ||
114 | err = drv(file, VIDIOC_S_CTRL, &ctrl2); | ||
115 | if (err < 0) | ||
116 | dprintk("VIDIOC_S_CTRL: %d\n", err); | ||
117 | } | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | /* ----------------------------------------------------------------- */ | ||
122 | |||
123 | static const unsigned int palette2pixelformat[] = { | ||
124 | [VIDEO_PALETTE_GREY] = V4L2_PIX_FMT_GREY, | ||
125 | [VIDEO_PALETTE_RGB555] = V4L2_PIX_FMT_RGB555, | ||
126 | [VIDEO_PALETTE_RGB565] = V4L2_PIX_FMT_RGB565, | ||
127 | [VIDEO_PALETTE_RGB24] = V4L2_PIX_FMT_BGR24, | ||
128 | [VIDEO_PALETTE_RGB32] = V4L2_PIX_FMT_BGR32, | ||
129 | /* yuv packed pixel */ | ||
130 | [VIDEO_PALETTE_YUYV] = V4L2_PIX_FMT_YUYV, | ||
131 | [VIDEO_PALETTE_YUV422] = V4L2_PIX_FMT_YUYV, | ||
132 | [VIDEO_PALETTE_UYVY] = V4L2_PIX_FMT_UYVY, | ||
133 | /* yuv planar */ | ||
134 | [VIDEO_PALETTE_YUV410P] = V4L2_PIX_FMT_YUV410, | ||
135 | [VIDEO_PALETTE_YUV420] = V4L2_PIX_FMT_YUV420, | ||
136 | [VIDEO_PALETTE_YUV420P] = V4L2_PIX_FMT_YUV420, | ||
137 | [VIDEO_PALETTE_YUV411P] = V4L2_PIX_FMT_YUV411P, | ||
138 | [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P, | ||
139 | }; | ||
140 | |||
141 | static unsigned int __pure | ||
142 | palette_to_pixelformat(unsigned int palette) | ||
143 | { | ||
144 | if (palette < ARRAY_SIZE(palette2pixelformat)) | ||
145 | return palette2pixelformat[palette]; | ||
146 | else | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static unsigned int __attribute_const__ | ||
151 | pixelformat_to_palette(unsigned int pixelformat) | ||
152 | { | ||
153 | int palette = 0; | ||
154 | switch (pixelformat) { | ||
155 | case V4L2_PIX_FMT_GREY: | ||
156 | palette = VIDEO_PALETTE_GREY; | ||
157 | break; | ||
158 | case V4L2_PIX_FMT_RGB555: | ||
159 | palette = VIDEO_PALETTE_RGB555; | ||
160 | break; | ||
161 | case V4L2_PIX_FMT_RGB565: | ||
162 | palette = VIDEO_PALETTE_RGB565; | ||
163 | break; | ||
164 | case V4L2_PIX_FMT_BGR24: | ||
165 | palette = VIDEO_PALETTE_RGB24; | ||
166 | break; | ||
167 | case V4L2_PIX_FMT_BGR32: | ||
168 | palette = VIDEO_PALETTE_RGB32; | ||
169 | break; | ||
170 | /* yuv packed pixel */ | ||
171 | case V4L2_PIX_FMT_YUYV: | ||
172 | palette = VIDEO_PALETTE_YUYV; | ||
173 | break; | ||
174 | case V4L2_PIX_FMT_UYVY: | ||
175 | palette = VIDEO_PALETTE_UYVY; | ||
176 | break; | ||
177 | /* yuv planar */ | ||
178 | case V4L2_PIX_FMT_YUV410: | ||
179 | palette = VIDEO_PALETTE_YUV420; | ||
180 | break; | ||
181 | case V4L2_PIX_FMT_YUV420: | ||
182 | palette = VIDEO_PALETTE_YUV420; | ||
183 | break; | ||
184 | case V4L2_PIX_FMT_YUV411P: | ||
185 | palette = VIDEO_PALETTE_YUV411P; | ||
186 | break; | ||
187 | case V4L2_PIX_FMT_YUV422P: | ||
188 | palette = VIDEO_PALETTE_YUV422P; | ||
189 | break; | ||
190 | } | ||
191 | return palette; | ||
192 | } | ||
193 | |||
194 | /* ----------------------------------------------------------------- */ | ||
195 | |||
196 | static int poll_one(struct file *file, struct poll_wqueues *pwq) | ||
197 | { | ||
198 | int retval = 1; | ||
199 | poll_table *table; | ||
200 | |||
201 | poll_initwait(pwq); | ||
202 | table = &pwq->pt; | ||
203 | for (;;) { | ||
204 | int mask; | ||
205 | mask = file->f_op->poll(file, table); | ||
206 | if (mask & POLLIN) | ||
207 | break; | ||
208 | table = NULL; | ||
209 | if (signal_pending(current)) { | ||
210 | retval = -ERESTARTSYS; | ||
211 | break; | ||
212 | } | ||
213 | poll_schedule(pwq, TASK_INTERRUPTIBLE); | ||
214 | } | ||
215 | poll_freewait(pwq); | ||
216 | return retval; | ||
217 | } | ||
218 | |||
219 | static int count_inputs( | ||
220 | struct file *file, | ||
221 | v4l2_kioctl drv) | ||
222 | { | ||
223 | struct v4l2_input input2; | ||
224 | int i; | ||
225 | |||
226 | for (i = 0;; i++) { | ||
227 | memset(&input2, 0, sizeof(input2)); | ||
228 | input2.index = i; | ||
229 | if (0 != drv(file, VIDIOC_ENUMINPUT, &input2)) | ||
230 | break; | ||
231 | } | ||
232 | return i; | ||
233 | } | ||
234 | |||
235 | static int check_size( | ||
236 | struct file *file, | ||
237 | v4l2_kioctl drv, | ||
238 | int *maxw, | ||
239 | int *maxh) | ||
240 | { | ||
241 | struct v4l2_fmtdesc desc2; | ||
242 | struct v4l2_format fmt2; | ||
243 | |||
244 | memset(&desc2, 0, sizeof(desc2)); | ||
245 | memset(&fmt2, 0, sizeof(fmt2)); | ||
246 | |||
247 | desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
248 | if (0 != drv(file, VIDIOC_ENUM_FMT, &desc2)) | ||
249 | goto done; | ||
250 | |||
251 | fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
252 | fmt2.fmt.pix.width = 10000; | ||
253 | fmt2.fmt.pix.height = 10000; | ||
254 | fmt2.fmt.pix.pixelformat = desc2.pixelformat; | ||
255 | if (0 != drv(file, VIDIOC_TRY_FMT, &fmt2)) | ||
256 | goto done; | ||
257 | |||
258 | *maxw = fmt2.fmt.pix.width; | ||
259 | *maxh = fmt2.fmt.pix.height; | ||
260 | |||
261 | done: | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | /* ----------------------------------------------------------------- */ | ||
266 | |||
267 | static noinline long v4l1_compat_get_capabilities( | ||
268 | struct video_capability *cap, | ||
269 | struct file *file, | ||
270 | v4l2_kioctl drv) | ||
271 | { | ||
272 | long err; | ||
273 | struct v4l2_framebuffer fbuf; | ||
274 | struct v4l2_capability *cap2; | ||
275 | |||
276 | cap2 = kzalloc(sizeof(*cap2), GFP_KERNEL); | ||
277 | if (!cap2) { | ||
278 | err = -ENOMEM; | ||
279 | return err; | ||
280 | } | ||
281 | memset(cap, 0, sizeof(*cap)); | ||
282 | memset(&fbuf, 0, sizeof(fbuf)); | ||
283 | |||
284 | err = drv(file, VIDIOC_QUERYCAP, cap2); | ||
285 | if (err < 0) { | ||
286 | dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %ld\n", err); | ||
287 | goto done; | ||
288 | } | ||
289 | if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) { | ||
290 | err = drv(file, VIDIOC_G_FBUF, &fbuf); | ||
291 | if (err < 0) { | ||
292 | dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %ld\n", err); | ||
293 | memset(&fbuf, 0, sizeof(fbuf)); | ||
294 | } | ||
295 | err = 0; | ||
296 | } | ||
297 | |||
298 | memcpy(cap->name, cap2->card, | ||
299 | min(sizeof(cap->name), sizeof(cap2->card))); | ||
300 | cap->name[sizeof(cap->name) - 1] = 0; | ||
301 | if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE) | ||
302 | cap->type |= VID_TYPE_CAPTURE; | ||
303 | if (cap2->capabilities & V4L2_CAP_TUNER) | ||
304 | cap->type |= VID_TYPE_TUNER; | ||
305 | if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE) | ||
306 | cap->type |= VID_TYPE_TELETEXT; | ||
307 | if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) | ||
308 | cap->type |= VID_TYPE_OVERLAY; | ||
309 | if (fbuf.capability & V4L2_FBUF_CAP_LIST_CLIPPING) | ||
310 | cap->type |= VID_TYPE_CLIPPING; | ||
311 | |||
312 | cap->channels = count_inputs(file, drv); | ||
313 | check_size(file, drv, | ||
314 | &cap->maxwidth, &cap->maxheight); | ||
315 | cap->audios = 0; /* FIXME */ | ||
316 | cap->minwidth = 48; /* FIXME */ | ||
317 | cap->minheight = 32; /* FIXME */ | ||
318 | |||
319 | done: | ||
320 | kfree(cap2); | ||
321 | return err; | ||
322 | } | ||
323 | |||
324 | static noinline long v4l1_compat_get_frame_buffer( | ||
325 | struct video_buffer *buffer, | ||
326 | struct file *file, | ||
327 | v4l2_kioctl drv) | ||
328 | { | ||
329 | long err; | ||
330 | struct v4l2_framebuffer fbuf; | ||
331 | |||
332 | memset(buffer, 0, sizeof(*buffer)); | ||
333 | memset(&fbuf, 0, sizeof(fbuf)); | ||
334 | |||
335 | err = drv(file, VIDIOC_G_FBUF, &fbuf); | ||
336 | if (err < 0) { | ||
337 | dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %ld\n", err); | ||
338 | goto done; | ||
339 | } | ||
340 | buffer->base = fbuf.base; | ||
341 | buffer->height = fbuf.fmt.height; | ||
342 | buffer->width = fbuf.fmt.width; | ||
343 | |||
344 | switch (fbuf.fmt.pixelformat) { | ||
345 | case V4L2_PIX_FMT_RGB332: | ||
346 | buffer->depth = 8; | ||
347 | break; | ||
348 | case V4L2_PIX_FMT_RGB555: | ||
349 | buffer->depth = 15; | ||
350 | break; | ||
351 | case V4L2_PIX_FMT_RGB565: | ||
352 | buffer->depth = 16; | ||
353 | break; | ||
354 | case V4L2_PIX_FMT_BGR24: | ||
355 | buffer->depth = 24; | ||
356 | break; | ||
357 | case V4L2_PIX_FMT_BGR32: | ||
358 | buffer->depth = 32; | ||
359 | break; | ||
360 | default: | ||
361 | buffer->depth = 0; | ||
362 | } | ||
363 | if (fbuf.fmt.bytesperline) { | ||
364 | buffer->bytesperline = fbuf.fmt.bytesperline; | ||
365 | if (!buffer->depth && buffer->width) | ||
366 | buffer->depth = ((fbuf.fmt.bytesperline<<3) | ||
367 | + (buffer->width-1)) | ||
368 | / buffer->width; | ||
369 | } else { | ||
370 | buffer->bytesperline = | ||
371 | (buffer->width * buffer->depth + 7) & 7; | ||
372 | buffer->bytesperline >>= 3; | ||
373 | } | ||
374 | done: | ||
375 | return err; | ||
376 | } | ||
377 | |||
378 | static noinline long v4l1_compat_set_frame_buffer( | ||
379 | struct video_buffer *buffer, | ||
380 | struct file *file, | ||
381 | v4l2_kioctl drv) | ||
382 | { | ||
383 | long err; | ||
384 | struct v4l2_framebuffer fbuf; | ||
385 | |||
386 | memset(&fbuf, 0, sizeof(fbuf)); | ||
387 | fbuf.base = buffer->base; | ||
388 | fbuf.fmt.height = buffer->height; | ||
389 | fbuf.fmt.width = buffer->width; | ||
390 | switch (buffer->depth) { | ||
391 | case 8: | ||
392 | fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB332; | ||
393 | break; | ||
394 | case 15: | ||
395 | fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB555; | ||
396 | break; | ||
397 | case 16: | ||
398 | fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB565; | ||
399 | break; | ||
400 | case 24: | ||
401 | fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR24; | ||
402 | break; | ||
403 | case 32: | ||
404 | fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR32; | ||
405 | break; | ||
406 | } | ||
407 | fbuf.fmt.bytesperline = buffer->bytesperline; | ||
408 | err = drv(file, VIDIOC_S_FBUF, &fbuf); | ||
409 | if (err < 0) | ||
410 | dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %ld\n", err); | ||
411 | return err; | ||
412 | } | ||
413 | |||
414 | static noinline long v4l1_compat_get_win_cap_dimensions( | ||
415 | struct video_window *win, | ||
416 | struct file *file, | ||
417 | v4l2_kioctl drv) | ||
418 | { | ||
419 | long err; | ||
420 | struct v4l2_format *fmt; | ||
421 | |||
422 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); | ||
423 | if (!fmt) { | ||
424 | err = -ENOMEM; | ||
425 | return err; | ||
426 | } | ||
427 | memset(win, 0, sizeof(*win)); | ||
428 | |||
429 | fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY; | ||
430 | err = drv(file, VIDIOC_G_FMT, fmt); | ||
431 | if (err < 0) | ||
432 | dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %ld\n", err); | ||
433 | if (err == 0) { | ||
434 | win->x = fmt->fmt.win.w.left; | ||
435 | win->y = fmt->fmt.win.w.top; | ||
436 | win->width = fmt->fmt.win.w.width; | ||
437 | win->height = fmt->fmt.win.w.height; | ||
438 | win->chromakey = fmt->fmt.win.chromakey; | ||
439 | win->clips = NULL; | ||
440 | win->clipcount = 0; | ||
441 | goto done; | ||
442 | } | ||
443 | |||
444 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
445 | err = drv(file, VIDIOC_G_FMT, fmt); | ||
446 | if (err < 0) { | ||
447 | dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %ld\n", err); | ||
448 | goto done; | ||
449 | } | ||
450 | win->x = 0; | ||
451 | win->y = 0; | ||
452 | win->width = fmt->fmt.pix.width; | ||
453 | win->height = fmt->fmt.pix.height; | ||
454 | win->chromakey = 0; | ||
455 | win->clips = NULL; | ||
456 | win->clipcount = 0; | ||
457 | done: | ||
458 | kfree(fmt); | ||
459 | return err; | ||
460 | } | ||
461 | |||
462 | static noinline long v4l1_compat_set_win_cap_dimensions( | ||
463 | struct video_window *win, | ||
464 | struct file *file, | ||
465 | v4l2_kioctl drv) | ||
466 | { | ||
467 | long err, err1, err2; | ||
468 | struct v4l2_format *fmt; | ||
469 | |||
470 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); | ||
471 | if (!fmt) { | ||
472 | err = -ENOMEM; | ||
473 | return err; | ||
474 | } | ||
475 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
476 | drv(file, VIDIOC_STREAMOFF, &fmt->type); | ||
477 | err1 = drv(file, VIDIOC_G_FMT, fmt); | ||
478 | if (err1 < 0) | ||
479 | dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %ld\n", err1); | ||
480 | if (err1 == 0) { | ||
481 | fmt->fmt.pix.width = win->width; | ||
482 | fmt->fmt.pix.height = win->height; | ||
483 | fmt->fmt.pix.field = V4L2_FIELD_ANY; | ||
484 | fmt->fmt.pix.bytesperline = 0; | ||
485 | err = drv(file, VIDIOC_S_FMT, fmt); | ||
486 | if (err < 0) | ||
487 | dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %ld\n", | ||
488 | err); | ||
489 | win->width = fmt->fmt.pix.width; | ||
490 | win->height = fmt->fmt.pix.height; | ||
491 | } | ||
492 | |||
493 | memset(fmt, 0, sizeof(*fmt)); | ||
494 | fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY; | ||
495 | fmt->fmt.win.w.left = win->x; | ||
496 | fmt->fmt.win.w.top = win->y; | ||
497 | fmt->fmt.win.w.width = win->width; | ||
498 | fmt->fmt.win.w.height = win->height; | ||
499 | fmt->fmt.win.chromakey = win->chromakey; | ||
500 | fmt->fmt.win.clips = (void __user *)win->clips; | ||
501 | fmt->fmt.win.clipcount = win->clipcount; | ||
502 | err2 = drv(file, VIDIOC_S_FMT, fmt); | ||
503 | if (err2 < 0) | ||
504 | dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %ld\n", err2); | ||
505 | |||
506 | if (err1 != 0 && err2 != 0) | ||
507 | err = err1; | ||
508 | else | ||
509 | err = 0; | ||
510 | kfree(fmt); | ||
511 | return err; | ||
512 | } | ||
513 | |||
514 | static noinline long v4l1_compat_turn_preview_on_off( | ||
515 | int *on, | ||
516 | struct file *file, | ||
517 | v4l2_kioctl drv) | ||
518 | { | ||
519 | long err; | ||
520 | enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
521 | |||
522 | if (0 == *on) { | ||
523 | /* dirty hack time. But v4l1 has no STREAMOFF | ||
524 | * equivalent in the API, and this one at | ||
525 | * least comes close ... */ | ||
526 | drv(file, VIDIOC_STREAMOFF, &captype); | ||
527 | } | ||
528 | err = drv(file, VIDIOC_OVERLAY, on); | ||
529 | if (err < 0) | ||
530 | dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %ld\n", err); | ||
531 | return err; | ||
532 | } | ||
533 | |||
534 | static noinline long v4l1_compat_get_input_info( | ||
535 | struct video_channel *chan, | ||
536 | struct file *file, | ||
537 | v4l2_kioctl drv) | ||
538 | { | ||
539 | long err; | ||
540 | struct v4l2_input input2; | ||
541 | v4l2_std_id sid; | ||
542 | |||
543 | memset(&input2, 0, sizeof(input2)); | ||
544 | input2.index = chan->channel; | ||
545 | err = drv(file, VIDIOC_ENUMINPUT, &input2); | ||
546 | if (err < 0) { | ||
547 | dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: " | ||
548 | "channel=%d err=%ld\n", chan->channel, err); | ||
549 | goto done; | ||
550 | } | ||
551 | chan->channel = input2.index; | ||
552 | memcpy(chan->name, input2.name, | ||
553 | min(sizeof(chan->name), sizeof(input2.name))); | ||
554 | chan->name[sizeof(chan->name) - 1] = 0; | ||
555 | chan->tuners = (input2.type == V4L2_INPUT_TYPE_TUNER) ? 1 : 0; | ||
556 | chan->flags = (chan->tuners) ? VIDEO_VC_TUNER : 0; | ||
557 | switch (input2.type) { | ||
558 | case V4L2_INPUT_TYPE_TUNER: | ||
559 | chan->type = VIDEO_TYPE_TV; | ||
560 | break; | ||
561 | default: | ||
562 | case V4L2_INPUT_TYPE_CAMERA: | ||
563 | chan->type = VIDEO_TYPE_CAMERA; | ||
564 | break; | ||
565 | } | ||
566 | chan->norm = 0; | ||
567 | /* Note: G_STD might not be present for radio receivers, | ||
568 | * so we should ignore any errors. */ | ||
569 | if (drv(file, VIDIOC_G_STD, &sid) == 0) { | ||
570 | if (sid & V4L2_STD_PAL) | ||
571 | chan->norm = VIDEO_MODE_PAL; | ||
572 | if (sid & V4L2_STD_NTSC) | ||
573 | chan->norm = VIDEO_MODE_NTSC; | ||
574 | if (sid & V4L2_STD_SECAM) | ||
575 | chan->norm = VIDEO_MODE_SECAM; | ||
576 | if (sid == V4L2_STD_ALL) | ||
577 | chan->norm = VIDEO_MODE_AUTO; | ||
578 | } | ||
579 | done: | ||
580 | return err; | ||
581 | } | ||
582 | |||
583 | static noinline long v4l1_compat_set_input( | ||
584 | struct video_channel *chan, | ||
585 | struct file *file, | ||
586 | v4l2_kioctl drv) | ||
587 | { | ||
588 | long err; | ||
589 | v4l2_std_id sid = 0; | ||
590 | |||
591 | err = drv(file, VIDIOC_S_INPUT, &chan->channel); | ||
592 | if (err < 0) | ||
593 | dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %ld\n", err); | ||
594 | switch (chan->norm) { | ||
595 | case VIDEO_MODE_PAL: | ||
596 | sid = V4L2_STD_PAL; | ||
597 | break; | ||
598 | case VIDEO_MODE_NTSC: | ||
599 | sid = V4L2_STD_NTSC; | ||
600 | break; | ||
601 | case VIDEO_MODE_SECAM: | ||
602 | sid = V4L2_STD_SECAM; | ||
603 | break; | ||
604 | case VIDEO_MODE_AUTO: | ||
605 | sid = V4L2_STD_ALL; | ||
606 | break; | ||
607 | } | ||
608 | if (0 != sid) { | ||
609 | err = drv(file, VIDIOC_S_STD, &sid); | ||
610 | if (err < 0) | ||
611 | dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %ld\n", err); | ||
612 | } | ||
613 | return err; | ||
614 | } | ||
615 | |||
616 | static noinline long v4l1_compat_get_picture( | ||
617 | struct video_picture *pict, | ||
618 | struct file *file, | ||
619 | v4l2_kioctl drv) | ||
620 | { | ||
621 | long err; | ||
622 | struct v4l2_format *fmt; | ||
623 | |||
624 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); | ||
625 | if (!fmt) { | ||
626 | err = -ENOMEM; | ||
627 | return err; | ||
628 | } | ||
629 | |||
630 | pict->brightness = get_v4l_control(file, | ||
631 | V4L2_CID_BRIGHTNESS, drv); | ||
632 | pict->hue = get_v4l_control(file, | ||
633 | V4L2_CID_HUE, drv); | ||
634 | pict->contrast = get_v4l_control(file, | ||
635 | V4L2_CID_CONTRAST, drv); | ||
636 | pict->colour = get_v4l_control(file, | ||
637 | V4L2_CID_SATURATION, drv); | ||
638 | pict->whiteness = get_v4l_control(file, | ||
639 | V4L2_CID_WHITENESS, drv); | ||
640 | |||
641 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
642 | err = drv(file, VIDIOC_G_FMT, fmt); | ||
643 | if (err < 0) { | ||
644 | dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %ld\n", err); | ||
645 | goto done; | ||
646 | } | ||
647 | |||
648 | if (fmt->fmt.pix.width) | ||
649 | { | ||
650 | pict->depth = ((fmt->fmt.pix.bytesperline << 3) | ||
651 | + (fmt->fmt.pix.width - 1)) | ||
652 | / fmt->fmt.pix.width; | ||
653 | } else { | ||
654 | err = -EINVAL; | ||
655 | goto done; | ||
656 | } | ||
657 | |||
658 | pict->palette = pixelformat_to_palette( | ||
659 | fmt->fmt.pix.pixelformat); | ||
660 | done: | ||
661 | kfree(fmt); | ||
662 | return err; | ||
663 | } | ||
664 | |||
665 | static noinline long v4l1_compat_set_picture( | ||
666 | struct video_picture *pict, | ||
667 | struct file *file, | ||
668 | v4l2_kioctl drv) | ||
669 | { | ||
670 | long err; | ||
671 | struct v4l2_framebuffer fbuf; | ||
672 | int mem_err = 0, ovl_err = 0; | ||
673 | struct v4l2_format *fmt; | ||
674 | |||
675 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); | ||
676 | if (!fmt) { | ||
677 | err = -ENOMEM; | ||
678 | return err; | ||
679 | } | ||
680 | memset(&fbuf, 0, sizeof(fbuf)); | ||
681 | |||
682 | set_v4l_control(file, | ||
683 | V4L2_CID_BRIGHTNESS, pict->brightness, drv); | ||
684 | set_v4l_control(file, | ||
685 | V4L2_CID_HUE, pict->hue, drv); | ||
686 | set_v4l_control(file, | ||
687 | V4L2_CID_CONTRAST, pict->contrast, drv); | ||
688 | set_v4l_control(file, | ||
689 | V4L2_CID_SATURATION, pict->colour, drv); | ||
690 | set_v4l_control(file, | ||
691 | V4L2_CID_WHITENESS, pict->whiteness, drv); | ||
692 | /* | ||
693 | * V4L1 uses this ioctl to set both memory capture and overlay | ||
694 | * pixel format, while V4L2 has two different ioctls for this. | ||
695 | * Some cards may not support one or the other, and may support | ||
696 | * different pixel formats for memory vs overlay. | ||
697 | */ | ||
698 | |||
699 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
700 | err = drv(file, VIDIOC_G_FMT, fmt); | ||
701 | /* If VIDIOC_G_FMT failed, then the driver likely doesn't | ||
702 | support memory capture. Trying to set the memory capture | ||
703 | parameters would be pointless. */ | ||
704 | if (err < 0) { | ||
705 | dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %ld\n", err); | ||
706 | mem_err = -1000; /* didn't even try */ | ||
707 | } else if (fmt->fmt.pix.pixelformat != | ||
708 | palette_to_pixelformat(pict->palette)) { | ||
709 | fmt->fmt.pix.pixelformat = palette_to_pixelformat( | ||
710 | pict->palette); | ||
711 | mem_err = drv(file, VIDIOC_S_FMT, fmt); | ||
712 | if (mem_err < 0) | ||
713 | dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n", | ||
714 | mem_err); | ||
715 | } | ||
716 | |||
717 | err = drv(file, VIDIOC_G_FBUF, &fbuf); | ||
718 | /* If VIDIOC_G_FBUF failed, then the driver likely doesn't | ||
719 | support overlay. Trying to set the overlay parameters | ||
720 | would be quite pointless. */ | ||
721 | if (err < 0) { | ||
722 | dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %ld\n", err); | ||
723 | ovl_err = -1000; /* didn't even try */ | ||
724 | } else if (fbuf.fmt.pixelformat != | ||
725 | palette_to_pixelformat(pict->palette)) { | ||
726 | fbuf.fmt.pixelformat = palette_to_pixelformat( | ||
727 | pict->palette); | ||
728 | ovl_err = drv(file, VIDIOC_S_FBUF, &fbuf); | ||
729 | if (ovl_err < 0) | ||
730 | dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n", | ||
731 | ovl_err); | ||
732 | } | ||
733 | if (ovl_err < 0 && mem_err < 0) { | ||
734 | /* ioctl failed, couldn't set either parameter */ | ||
735 | if (mem_err != -1000) | ||
736 | err = mem_err; | ||
737 | else if (ovl_err == -EPERM) | ||
738 | err = 0; | ||
739 | else | ||
740 | err = ovl_err; | ||
741 | } else | ||
742 | err = 0; | ||
743 | kfree(fmt); | ||
744 | return err; | ||
745 | } | ||
746 | |||
747 | static noinline long v4l1_compat_get_tuner( | ||
748 | struct video_tuner *tun, | ||
749 | struct file *file, | ||
750 | v4l2_kioctl drv) | ||
751 | { | ||
752 | long err; | ||
753 | int i; | ||
754 | struct v4l2_tuner tun2; | ||
755 | struct v4l2_standard std2; | ||
756 | v4l2_std_id sid; | ||
757 | |||
758 | memset(&tun2, 0, sizeof(tun2)); | ||
759 | err = drv(file, VIDIOC_G_TUNER, &tun2); | ||
760 | if (err < 0) { | ||
761 | dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %ld\n", err); | ||
762 | goto done; | ||
763 | } | ||
764 | memcpy(tun->name, tun2.name, | ||
765 | min(sizeof(tun->name), sizeof(tun2.name))); | ||
766 | tun->name[sizeof(tun->name) - 1] = 0; | ||
767 | tun->rangelow = tun2.rangelow; | ||
768 | tun->rangehigh = tun2.rangehigh; | ||
769 | tun->flags = 0; | ||
770 | tun->mode = VIDEO_MODE_AUTO; | ||
771 | |||
772 | for (i = 0; i < 64; i++) { | ||
773 | memset(&std2, 0, sizeof(std2)); | ||
774 | std2.index = i; | ||
775 | if (0 != drv(file, VIDIOC_ENUMSTD, &std2)) | ||
776 | break; | ||
777 | if (std2.id & V4L2_STD_PAL) | ||
778 | tun->flags |= VIDEO_TUNER_PAL; | ||
779 | if (std2.id & V4L2_STD_NTSC) | ||
780 | tun->flags |= VIDEO_TUNER_NTSC; | ||
781 | if (std2.id & V4L2_STD_SECAM) | ||
782 | tun->flags |= VIDEO_TUNER_SECAM; | ||
783 | } | ||
784 | |||
785 | /* Note: G_STD might not be present for radio receivers, | ||
786 | * so we should ignore any errors. */ | ||
787 | if (drv(file, VIDIOC_G_STD, &sid) == 0) { | ||
788 | if (sid & V4L2_STD_PAL) | ||
789 | tun->mode = VIDEO_MODE_PAL; | ||
790 | if (sid & V4L2_STD_NTSC) | ||
791 | tun->mode = VIDEO_MODE_NTSC; | ||
792 | if (sid & V4L2_STD_SECAM) | ||
793 | tun->mode = VIDEO_MODE_SECAM; | ||
794 | } | ||
795 | |||
796 | if (tun2.capability & V4L2_TUNER_CAP_LOW) | ||
797 | tun->flags |= VIDEO_TUNER_LOW; | ||
798 | if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO) | ||
799 | tun->flags |= VIDEO_TUNER_STEREO_ON; | ||
800 | tun->signal = tun2.signal; | ||
801 | done: | ||
802 | return err; | ||
803 | } | ||
804 | |||
805 | static noinline long v4l1_compat_select_tuner( | ||
806 | struct video_tuner *tun, | ||
807 | struct file *file, | ||
808 | v4l2_kioctl drv) | ||
809 | { | ||
810 | long err; | ||
811 | struct v4l2_tuner t;/*84 bytes on x86_64*/ | ||
812 | memset(&t, 0, sizeof(t)); | ||
813 | |||
814 | t.index = tun->tuner; | ||
815 | |||
816 | err = drv(file, VIDIOC_S_TUNER, &t); | ||
817 | if (err < 0) | ||
818 | dprintk("VIDIOCSTUNER / VIDIOC_S_TUNER: %ld\n", err); | ||
819 | return err; | ||
820 | } | ||
821 | |||
822 | static noinline long v4l1_compat_get_frequency( | ||
823 | unsigned long *freq, | ||
824 | struct file *file, | ||
825 | v4l2_kioctl drv) | ||
826 | { | ||
827 | long err; | ||
828 | struct v4l2_frequency freq2; | ||
829 | memset(&freq2, 0, sizeof(freq2)); | ||
830 | |||
831 | freq2.tuner = 0; | ||
832 | err = drv(file, VIDIOC_G_FREQUENCY, &freq2); | ||
833 | if (err < 0) | ||
834 | dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %ld\n", err); | ||
835 | if (0 == err) | ||
836 | *freq = freq2.frequency; | ||
837 | return err; | ||
838 | } | ||
839 | |||
840 | static noinline long v4l1_compat_set_frequency( | ||
841 | unsigned long *freq, | ||
842 | struct file *file, | ||
843 | v4l2_kioctl drv) | ||
844 | { | ||
845 | long err; | ||
846 | struct v4l2_frequency freq2; | ||
847 | memset(&freq2, 0, sizeof(freq2)); | ||
848 | |||
849 | drv(file, VIDIOC_G_FREQUENCY, &freq2); | ||
850 | freq2.frequency = *freq; | ||
851 | err = drv(file, VIDIOC_S_FREQUENCY, &freq2); | ||
852 | if (err < 0) | ||
853 | dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %ld\n", err); | ||
854 | return err; | ||
855 | } | ||
856 | |||
857 | static noinline long v4l1_compat_get_audio( | ||
858 | struct video_audio *aud, | ||
859 | struct file *file, | ||
860 | v4l2_kioctl drv) | ||
861 | { | ||
862 | long err; | ||
863 | int i; | ||
864 | struct v4l2_queryctrl qctrl2; | ||
865 | struct v4l2_audio aud2; | ||
866 | struct v4l2_tuner tun2; | ||
867 | memset(&aud2, 0, sizeof(aud2)); | ||
868 | |||
869 | err = drv(file, VIDIOC_G_AUDIO, &aud2); | ||
870 | if (err < 0) { | ||
871 | dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %ld\n", err); | ||
872 | goto done; | ||
873 | } | ||
874 | memcpy(aud->name, aud2.name, | ||
875 | min(sizeof(aud->name), sizeof(aud2.name))); | ||
876 | aud->name[sizeof(aud->name) - 1] = 0; | ||
877 | aud->audio = aud2.index; | ||
878 | aud->flags = 0; | ||
879 | i = get_v4l_control(file, V4L2_CID_AUDIO_VOLUME, drv); | ||
880 | if (i >= 0) { | ||
881 | aud->volume = i; | ||
882 | aud->flags |= VIDEO_AUDIO_VOLUME; | ||
883 | } | ||
884 | i = get_v4l_control(file, V4L2_CID_AUDIO_BASS, drv); | ||
885 | if (i >= 0) { | ||
886 | aud->bass = i; | ||
887 | aud->flags |= VIDEO_AUDIO_BASS; | ||
888 | } | ||
889 | i = get_v4l_control(file, V4L2_CID_AUDIO_TREBLE, drv); | ||
890 | if (i >= 0) { | ||
891 | aud->treble = i; | ||
892 | aud->flags |= VIDEO_AUDIO_TREBLE; | ||
893 | } | ||
894 | i = get_v4l_control(file, V4L2_CID_AUDIO_BALANCE, drv); | ||
895 | if (i >= 0) { | ||
896 | aud->balance = i; | ||
897 | aud->flags |= VIDEO_AUDIO_BALANCE; | ||
898 | } | ||
899 | i = get_v4l_control(file, V4L2_CID_AUDIO_MUTE, drv); | ||
900 | if (i >= 0) { | ||
901 | if (i) | ||
902 | aud->flags |= VIDEO_AUDIO_MUTE; | ||
903 | aud->flags |= VIDEO_AUDIO_MUTABLE; | ||
904 | } | ||
905 | aud->step = 1; | ||
906 | qctrl2.id = V4L2_CID_AUDIO_VOLUME; | ||
907 | if (drv(file, VIDIOC_QUERYCTRL, &qctrl2) == 0 && | ||
908 | !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) | ||
909 | aud->step = qctrl2.step; | ||
910 | aud->mode = 0; | ||
911 | |||
912 | memset(&tun2, 0, sizeof(tun2)); | ||
913 | err = drv(file, VIDIOC_G_TUNER, &tun2); | ||
914 | if (err < 0) { | ||
915 | dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %ld\n", err); | ||
916 | err = 0; | ||
917 | goto done; | ||
918 | } | ||
919 | |||
920 | if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2) | ||
921 | aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; | ||
922 | else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO) | ||
923 | aud->mode = VIDEO_SOUND_STEREO; | ||
924 | else if (tun2.rxsubchans & V4L2_TUNER_SUB_MONO) | ||
925 | aud->mode = VIDEO_SOUND_MONO; | ||
926 | done: | ||
927 | return err; | ||
928 | } | ||
929 | |||
930 | static noinline long v4l1_compat_set_audio( | ||
931 | struct video_audio *aud, | ||
932 | struct file *file, | ||
933 | v4l2_kioctl drv) | ||
934 | { | ||
935 | long err; | ||
936 | struct v4l2_audio aud2; | ||
937 | struct v4l2_tuner tun2; | ||
938 | |||
939 | memset(&aud2, 0, sizeof(aud2)); | ||
940 | memset(&tun2, 0, sizeof(tun2)); | ||
941 | |||
942 | aud2.index = aud->audio; | ||
943 | err = drv(file, VIDIOC_S_AUDIO, &aud2); | ||
944 | if (err < 0) { | ||
945 | dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %ld\n", err); | ||
946 | goto done; | ||
947 | } | ||
948 | |||
949 | set_v4l_control(file, V4L2_CID_AUDIO_VOLUME, | ||
950 | aud->volume, drv); | ||
951 | set_v4l_control(file, V4L2_CID_AUDIO_BASS, | ||
952 | aud->bass, drv); | ||
953 | set_v4l_control(file, V4L2_CID_AUDIO_TREBLE, | ||
954 | aud->treble, drv); | ||
955 | set_v4l_control(file, V4L2_CID_AUDIO_BALANCE, | ||
956 | aud->balance, drv); | ||
957 | set_v4l_control(file, V4L2_CID_AUDIO_MUTE, | ||
958 | !!(aud->flags & VIDEO_AUDIO_MUTE), drv); | ||
959 | |||
960 | err = drv(file, VIDIOC_G_TUNER, &tun2); | ||
961 | if (err < 0) | ||
962 | dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %ld\n", err); | ||
963 | if (err == 0) { | ||
964 | switch (aud->mode) { | ||
965 | default: | ||
966 | case VIDEO_SOUND_MONO: | ||
967 | case VIDEO_SOUND_LANG1: | ||
968 | tun2.audmode = V4L2_TUNER_MODE_MONO; | ||
969 | break; | ||
970 | case VIDEO_SOUND_STEREO: | ||
971 | tun2.audmode = V4L2_TUNER_MODE_STEREO; | ||
972 | break; | ||
973 | case VIDEO_SOUND_LANG2: | ||
974 | tun2.audmode = V4L2_TUNER_MODE_LANG2; | ||
975 | break; | ||
976 | } | ||
977 | err = drv(file, VIDIOC_S_TUNER, &tun2); | ||
978 | if (err < 0) | ||
979 | dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %ld\n", err); | ||
980 | } | ||
981 | err = 0; | ||
982 | done: | ||
983 | return err; | ||
984 | } | ||
985 | |||
986 | static noinline long v4l1_compat_capture_frame( | ||
987 | struct video_mmap *mm, | ||
988 | struct file *file, | ||
989 | v4l2_kioctl drv) | ||
990 | { | ||
991 | long err; | ||
992 | enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
993 | struct v4l2_buffer buf; | ||
994 | struct v4l2_format *fmt; | ||
995 | |||
996 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); | ||
997 | if (!fmt) { | ||
998 | err = -ENOMEM; | ||
999 | return err; | ||
1000 | } | ||
1001 | memset(&buf, 0, sizeof(buf)); | ||
1002 | |||
1003 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1004 | err = drv(file, VIDIOC_G_FMT, fmt); | ||
1005 | if (err < 0) { | ||
1006 | dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %ld\n", err); | ||
1007 | goto done; | ||
1008 | } | ||
1009 | if (mm->width != fmt->fmt.pix.width || | ||
1010 | mm->height != fmt->fmt.pix.height || | ||
1011 | palette_to_pixelformat(mm->format) != | ||
1012 | fmt->fmt.pix.pixelformat) { | ||
1013 | /* New capture format... */ | ||
1014 | fmt->fmt.pix.width = mm->width; | ||
1015 | fmt->fmt.pix.height = mm->height; | ||
1016 | fmt->fmt.pix.pixelformat = | ||
1017 | palette_to_pixelformat(mm->format); | ||
1018 | fmt->fmt.pix.field = V4L2_FIELD_ANY; | ||
1019 | fmt->fmt.pix.bytesperline = 0; | ||
1020 | err = drv(file, VIDIOC_S_FMT, fmt); | ||
1021 | if (err < 0) { | ||
1022 | dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %ld\n", err); | ||
1023 | goto done; | ||
1024 | } | ||
1025 | } | ||
1026 | buf.index = mm->frame; | ||
1027 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1028 | err = drv(file, VIDIOC_QUERYBUF, &buf); | ||
1029 | if (err < 0) { | ||
1030 | dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %ld\n", err); | ||
1031 | goto done; | ||
1032 | } | ||
1033 | err = drv(file, VIDIOC_QBUF, &buf); | ||
1034 | if (err < 0) { | ||
1035 | dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %ld\n", err); | ||
1036 | goto done; | ||
1037 | } | ||
1038 | err = drv(file, VIDIOC_STREAMON, &captype); | ||
1039 | if (err < 0) | ||
1040 | dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %ld\n", err); | ||
1041 | done: | ||
1042 | kfree(fmt); | ||
1043 | return err; | ||
1044 | } | ||
1045 | |||
1046 | static noinline long v4l1_compat_sync( | ||
1047 | int *i, | ||
1048 | struct file *file, | ||
1049 | v4l2_kioctl drv) | ||
1050 | { | ||
1051 | long err; | ||
1052 | enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1053 | struct v4l2_buffer buf; | ||
1054 | struct poll_wqueues *pwq; | ||
1055 | |||
1056 | memset(&buf, 0, sizeof(buf)); | ||
1057 | buf.index = *i; | ||
1058 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1059 | err = drv(file, VIDIOC_QUERYBUF, &buf); | ||
1060 | if (err < 0) { | ||
1061 | /* No such buffer */ | ||
1062 | dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %ld\n", err); | ||
1063 | goto done; | ||
1064 | } | ||
1065 | if (!(buf.flags & V4L2_BUF_FLAG_MAPPED)) { | ||
1066 | /* Buffer is not mapped */ | ||
1067 | err = -EINVAL; | ||
1068 | goto done; | ||
1069 | } | ||
1070 | |||
1071 | /* make sure capture actually runs so we don't block forever */ | ||
1072 | err = drv(file, VIDIOC_STREAMON, &captype); | ||
1073 | if (err < 0) { | ||
1074 | dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %ld\n", err); | ||
1075 | goto done; | ||
1076 | } | ||
1077 | |||
1078 | pwq = kmalloc(sizeof(*pwq), GFP_KERNEL); | ||
1079 | /* Loop as long as the buffer is queued, but not done */ | ||
1080 | while ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) | ||
1081 | == V4L2_BUF_FLAG_QUEUED) { | ||
1082 | err = poll_one(file, pwq); | ||
1083 | if (err < 0 || /* error or sleep was interrupted */ | ||
1084 | err == 0) /* timeout? Shouldn't occur. */ | ||
1085 | break; | ||
1086 | err = drv(file, VIDIOC_QUERYBUF, &buf); | ||
1087 | if (err < 0) | ||
1088 | dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %ld\n", err); | ||
1089 | } | ||
1090 | kfree(pwq); | ||
1091 | if (!(buf.flags & V4L2_BUF_FLAG_DONE)) /* not done */ | ||
1092 | goto done; | ||
1093 | do { | ||
1094 | err = drv(file, VIDIOC_DQBUF, &buf); | ||
1095 | if (err < 0) | ||
1096 | dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %ld\n", err); | ||
1097 | } while (err == 0 && buf.index != *i); | ||
1098 | done: | ||
1099 | return err; | ||
1100 | } | ||
1101 | |||
1102 | static noinline long v4l1_compat_get_vbi_format( | ||
1103 | struct vbi_format *fmt, | ||
1104 | struct file *file, | ||
1105 | v4l2_kioctl drv) | ||
1106 | { | ||
1107 | long err; | ||
1108 | struct v4l2_format *fmt2; | ||
1109 | |||
1110 | fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); | ||
1111 | if (!fmt2) { | ||
1112 | err = -ENOMEM; | ||
1113 | return err; | ||
1114 | } | ||
1115 | fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
1116 | |||
1117 | err = drv(file, VIDIOC_G_FMT, fmt2); | ||
1118 | if (err < 0) { | ||
1119 | dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %ld\n", err); | ||
1120 | goto done; | ||
1121 | } | ||
1122 | if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) { | ||
1123 | err = -EINVAL; | ||
1124 | goto done; | ||
1125 | } | ||
1126 | memset(fmt, 0, sizeof(*fmt)); | ||
1127 | fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line; | ||
1128 | fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate; | ||
1129 | fmt->sample_format = VIDEO_PALETTE_RAW; | ||
1130 | fmt->start[0] = fmt2->fmt.vbi.start[0]; | ||
1131 | fmt->count[0] = fmt2->fmt.vbi.count[0]; | ||
1132 | fmt->start[1] = fmt2->fmt.vbi.start[1]; | ||
1133 | fmt->count[1] = fmt2->fmt.vbi.count[1]; | ||
1134 | fmt->flags = fmt2->fmt.vbi.flags & 0x03; | ||
1135 | done: | ||
1136 | kfree(fmt2); | ||
1137 | return err; | ||
1138 | } | ||
1139 | |||
1140 | static noinline long v4l1_compat_set_vbi_format( | ||
1141 | struct vbi_format *fmt, | ||
1142 | struct file *file, | ||
1143 | v4l2_kioctl drv) | ||
1144 | { | ||
1145 | long err; | ||
1146 | struct v4l2_format *fmt2 = NULL; | ||
1147 | |||
1148 | if (VIDEO_PALETTE_RAW != fmt->sample_format) { | ||
1149 | err = -EINVAL; | ||
1150 | return err; | ||
1151 | } | ||
1152 | |||
1153 | fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); | ||
1154 | if (!fmt2) { | ||
1155 | err = -ENOMEM; | ||
1156 | return err; | ||
1157 | } | ||
1158 | fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
1159 | fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line; | ||
1160 | fmt2->fmt.vbi.sampling_rate = fmt->sampling_rate; | ||
1161 | fmt2->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
1162 | fmt2->fmt.vbi.start[0] = fmt->start[0]; | ||
1163 | fmt2->fmt.vbi.count[0] = fmt->count[0]; | ||
1164 | fmt2->fmt.vbi.start[1] = fmt->start[1]; | ||
1165 | fmt2->fmt.vbi.count[1] = fmt->count[1]; | ||
1166 | fmt2->fmt.vbi.flags = fmt->flags; | ||
1167 | err = drv(file, VIDIOC_TRY_FMT, fmt2); | ||
1168 | if (err < 0) { | ||
1169 | dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %ld\n", err); | ||
1170 | goto done; | ||
1171 | } | ||
1172 | |||
1173 | if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line || | ||
1174 | fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate || | ||
1175 | fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY || | ||
1176 | fmt2->fmt.vbi.start[0] != fmt->start[0] || | ||
1177 | fmt2->fmt.vbi.count[0] != fmt->count[0] || | ||
1178 | fmt2->fmt.vbi.start[1] != fmt->start[1] || | ||
1179 | fmt2->fmt.vbi.count[1] != fmt->count[1] || | ||
1180 | fmt2->fmt.vbi.flags != fmt->flags) { | ||
1181 | err = -EINVAL; | ||
1182 | goto done; | ||
1183 | } | ||
1184 | err = drv(file, VIDIOC_S_FMT, fmt2); | ||
1185 | if (err < 0) | ||
1186 | dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %ld\n", err); | ||
1187 | done: | ||
1188 | kfree(fmt2); | ||
1189 | return err; | ||
1190 | } | ||
1191 | |||
1192 | /* | ||
1193 | * This function is exported. | ||
1194 | */ | ||
1195 | long | ||
1196 | v4l_compat_translate_ioctl(struct file *file, | ||
1197 | int cmd, | ||
1198 | void *arg, | ||
1199 | v4l2_kioctl drv) | ||
1200 | { | ||
1201 | long err; | ||
1202 | |||
1203 | switch (cmd) { | ||
1204 | case VIDIOCGCAP: /* capability */ | ||
1205 | err = v4l1_compat_get_capabilities(arg, file, drv); | ||
1206 | break; | ||
1207 | case VIDIOCGFBUF: /* get frame buffer */ | ||
1208 | err = v4l1_compat_get_frame_buffer(arg, file, drv); | ||
1209 | break; | ||
1210 | case VIDIOCSFBUF: /* set frame buffer */ | ||
1211 | err = v4l1_compat_set_frame_buffer(arg, file, drv); | ||
1212 | break; | ||
1213 | case VIDIOCGWIN: /* get window or capture dimensions */ | ||
1214 | err = v4l1_compat_get_win_cap_dimensions(arg, file, drv); | ||
1215 | break; | ||
1216 | case VIDIOCSWIN: /* set window and/or capture dimensions */ | ||
1217 | err = v4l1_compat_set_win_cap_dimensions(arg, file, drv); | ||
1218 | break; | ||
1219 | case VIDIOCCAPTURE: /* turn on/off preview */ | ||
1220 | err = v4l1_compat_turn_preview_on_off(arg, file, drv); | ||
1221 | break; | ||
1222 | case VIDIOCGCHAN: /* get input information */ | ||
1223 | err = v4l1_compat_get_input_info(arg, file, drv); | ||
1224 | break; | ||
1225 | case VIDIOCSCHAN: /* set input */ | ||
1226 | err = v4l1_compat_set_input(arg, file, drv); | ||
1227 | break; | ||
1228 | case VIDIOCGPICT: /* get tone controls & partial capture format */ | ||
1229 | err = v4l1_compat_get_picture(arg, file, drv); | ||
1230 | break; | ||
1231 | case VIDIOCSPICT: /* set tone controls & partial capture format */ | ||
1232 | err = v4l1_compat_set_picture(arg, file, drv); | ||
1233 | break; | ||
1234 | case VIDIOCGTUNER: /* get tuner information */ | ||
1235 | err = v4l1_compat_get_tuner(arg, file, drv); | ||
1236 | break; | ||
1237 | case VIDIOCSTUNER: /* select a tuner input */ | ||
1238 | err = v4l1_compat_select_tuner(arg, file, drv); | ||
1239 | break; | ||
1240 | case VIDIOCGFREQ: /* get frequency */ | ||
1241 | err = v4l1_compat_get_frequency(arg, file, drv); | ||
1242 | break; | ||
1243 | case VIDIOCSFREQ: /* set frequency */ | ||
1244 | err = v4l1_compat_set_frequency(arg, file, drv); | ||
1245 | break; | ||
1246 | case VIDIOCGAUDIO: /* get audio properties/controls */ | ||
1247 | err = v4l1_compat_get_audio(arg, file, drv); | ||
1248 | break; | ||
1249 | case VIDIOCSAUDIO: /* set audio controls */ | ||
1250 | err = v4l1_compat_set_audio(arg, file, drv); | ||
1251 | break; | ||
1252 | case VIDIOCMCAPTURE: /* capture a frame */ | ||
1253 | err = v4l1_compat_capture_frame(arg, file, drv); | ||
1254 | break; | ||
1255 | case VIDIOCSYNC: /* wait for a frame */ | ||
1256 | err = v4l1_compat_sync(arg, file, drv); | ||
1257 | break; | ||
1258 | case VIDIOCGVBIFMT: /* query VBI data capture format */ | ||
1259 | err = v4l1_compat_get_vbi_format(arg, file, drv); | ||
1260 | break; | ||
1261 | case VIDIOCSVBIFMT: | ||
1262 | err = v4l1_compat_set_vbi_format(arg, file, drv); | ||
1263 | break; | ||
1264 | default: | ||
1265 | err = -ENOIOCTLCMD; | ||
1266 | break; | ||
1267 | } | ||
1268 | |||
1269 | return err; | ||
1270 | } | ||
1271 | EXPORT_SYMBOL(v4l_compat_translate_ioctl); | ||
1272 | |||
1273 | /* | ||
1274 | * Local variables: | ||
1275 | * c-basic-offset: 8 | ||
1276 | * End: | ||
1277 | */ | ||
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index b5eb1f3950b1..3f0871b550ad 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
@@ -150,7 +150,7 @@ EXPORT_SYMBOL(v4l2_prio_check); | |||
150 | struct v4l2_queryctrl and the available menu items. Note that | 150 | struct v4l2_queryctrl and the available menu items. Note that |
151 | menu_items may be NULL, in that case it is ignored. */ | 151 | menu_items may be NULL, in that case it is ignored. */ |
152 | int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, | 152 | int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, |
153 | const char **menu_items) | 153 | const char * const *menu_items) |
154 | { | 154 | { |
155 | if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED) | 155 | if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED) |
156 | return -EINVAL; | 156 | return -EINVAL; |
@@ -199,7 +199,7 @@ EXPORT_SYMBOL(v4l2_ctrl_query_fill); | |||
199 | If menu_items is NULL, then the menu items are retrieved using | 199 | If menu_items is NULL, then the menu items are retrieved using |
200 | v4l2_ctrl_get_menu. */ | 200 | v4l2_ctrl_get_menu. */ |
201 | int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl, | 201 | int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl, |
202 | const char **menu_items) | 202 | const char * const *menu_items) |
203 | { | 203 | { |
204 | int i; | 204 | int i; |
205 | 205 | ||
@@ -222,7 +222,7 @@ EXPORT_SYMBOL(v4l2_ctrl_query_menu); | |||
222 | Use this if there are 'holes' in the list of valid menu items. */ | 222 | Use this if there are 'holes' in the list of valid menu items. */ |
223 | int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids) | 223 | int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids) |
224 | { | 224 | { |
225 | const char **menu_items = v4l2_ctrl_get_menu(qmenu->id); | 225 | const char * const *menu_items = v4l2_ctrl_get_menu(qmenu->id); |
226 | 226 | ||
227 | qmenu->reserved = 0; | 227 | qmenu->reserved = 0; |
228 | if (menu_items == NULL || ids == NULL) | 228 | if (menu_items == NULL || ids == NULL) |
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c index e30e8dfb6205..dc82eb83c1d4 100644 --- a/drivers/media/video/v4l2-compat-ioctl32.c +++ b/drivers/media/video/v4l2-compat-ioctl32.c | |||
@@ -15,219 +15,12 @@ | |||
15 | 15 | ||
16 | #include <linux/compat.h> | 16 | #include <linux/compat.h> |
17 | #define __OLD_VIDIOC_ /* To allow fixing old calls*/ | 17 | #define __OLD_VIDIOC_ /* To allow fixing old calls*/ |
18 | #include <linux/videodev.h> | ||
19 | #include <linux/videodev2.h> | 18 | #include <linux/videodev2.h> |
20 | #include <linux/module.h> | 19 | #include <linux/module.h> |
21 | #include <media/v4l2-ioctl.h> | 20 | #include <media/v4l2-ioctl.h> |
22 | 21 | ||
23 | #ifdef CONFIG_COMPAT | 22 | #ifdef CONFIG_COMPAT |
24 | 23 | ||
25 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
26 | struct video_tuner32 { | ||
27 | compat_int_t tuner; | ||
28 | char name[32]; | ||
29 | compat_ulong_t rangelow, rangehigh; | ||
30 | u32 flags; /* It is really u32 in videodev.h */ | ||
31 | u16 mode, signal; | ||
32 | }; | ||
33 | |||
34 | static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) | ||
35 | { | ||
36 | if (!access_ok(VERIFY_READ, up, sizeof(struct video_tuner32)) || | ||
37 | get_user(kp->tuner, &up->tuner) || | ||
38 | copy_from_user(kp->name, up->name, 32) || | ||
39 | get_user(kp->rangelow, &up->rangelow) || | ||
40 | get_user(kp->rangehigh, &up->rangehigh) || | ||
41 | get_user(kp->flags, &up->flags) || | ||
42 | get_user(kp->mode, &up->mode) || | ||
43 | get_user(kp->signal, &up->signal)) | ||
44 | return -EFAULT; | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) | ||
49 | { | ||
50 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct video_tuner32)) || | ||
51 | put_user(kp->tuner, &up->tuner) || | ||
52 | copy_to_user(up->name, kp->name, 32) || | ||
53 | put_user(kp->rangelow, &up->rangelow) || | ||
54 | put_user(kp->rangehigh, &up->rangehigh) || | ||
55 | put_user(kp->flags, &up->flags) || | ||
56 | put_user(kp->mode, &up->mode) || | ||
57 | put_user(kp->signal, &up->signal)) | ||
58 | return -EFAULT; | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | struct video_buffer32 { | ||
63 | compat_caddr_t base; | ||
64 | compat_int_t height, width, depth, bytesperline; | ||
65 | }; | ||
66 | |||
67 | static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up) | ||
68 | { | ||
69 | u32 tmp; | ||
70 | |||
71 | if (!access_ok(VERIFY_READ, up, sizeof(struct video_buffer32)) || | ||
72 | get_user(tmp, &up->base) || | ||
73 | get_user(kp->height, &up->height) || | ||
74 | get_user(kp->width, &up->width) || | ||
75 | get_user(kp->depth, &up->depth) || | ||
76 | get_user(kp->bytesperline, &up->bytesperline)) | ||
77 | return -EFAULT; | ||
78 | |||
79 | /* This is actually a physical address stored | ||
80 | * as a void pointer. | ||
81 | */ | ||
82 | kp->base = (void *)(unsigned long) tmp; | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up) | ||
88 | { | ||
89 | u32 tmp = (u32)((unsigned long)kp->base); | ||
90 | |||
91 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct video_buffer32)) || | ||
92 | put_user(tmp, &up->base) || | ||
93 | put_user(kp->height, &up->height) || | ||
94 | put_user(kp->width, &up->width) || | ||
95 | put_user(kp->depth, &up->depth) || | ||
96 | put_user(kp->bytesperline, &up->bytesperline)) | ||
97 | return -EFAULT; | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | struct video_clip32 { | ||
102 | s32 x, y, width, height; /* It's really s32 in videodev.h */ | ||
103 | compat_caddr_t next; | ||
104 | }; | ||
105 | |||
106 | struct video_window32 { | ||
107 | u32 x, y, width, height, chromakey, flags; | ||
108 | compat_caddr_t clips; | ||
109 | compat_int_t clipcount; | ||
110 | }; | ||
111 | |||
112 | static int get_video_window32(struct video_window *kp, struct video_window32 __user *up) | ||
113 | { | ||
114 | struct video_clip __user *uclips; | ||
115 | struct video_clip __user *kclips; | ||
116 | compat_caddr_t p; | ||
117 | int nclips; | ||
118 | |||
119 | if (!access_ok(VERIFY_READ, up, sizeof(struct video_window32))) | ||
120 | return -EFAULT; | ||
121 | |||
122 | if (get_user(nclips, &up->clipcount)) | ||
123 | return -EFAULT; | ||
124 | |||
125 | if (!access_ok(VERIFY_READ, up, sizeof(struct video_window32)) || | ||
126 | get_user(kp->x, &up->x) || | ||
127 | get_user(kp->y, &up->y) || | ||
128 | get_user(kp->width, &up->width) || | ||
129 | get_user(kp->height, &up->height) || | ||
130 | get_user(kp->chromakey, &up->chromakey) || | ||
131 | get_user(kp->flags, &up->flags) || | ||
132 | get_user(kp->clipcount, &up->clipcount)) | ||
133 | return -EFAULT; | ||
134 | |||
135 | nclips = kp->clipcount; | ||
136 | kp->clips = NULL; | ||
137 | |||
138 | if (nclips == 0) | ||
139 | return 0; | ||
140 | if (get_user(p, &up->clips)) | ||
141 | return -EFAULT; | ||
142 | uclips = compat_ptr(p); | ||
143 | |||
144 | /* If nclips < 0, then it is a clipping bitmap of size | ||
145 | VIDEO_CLIPMAP_SIZE */ | ||
146 | if (nclips < 0) { | ||
147 | if (!access_ok(VERIFY_READ, uclips, VIDEO_CLIPMAP_SIZE)) | ||
148 | return -EFAULT; | ||
149 | kp->clips = compat_alloc_user_space(VIDEO_CLIPMAP_SIZE); | ||
150 | if (copy_in_user(kp->clips, uclips, VIDEO_CLIPMAP_SIZE)) | ||
151 | return -EFAULT; | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | /* Otherwise it is an array of video_clip structs. */ | ||
156 | if (!access_ok(VERIFY_READ, uclips, nclips * sizeof(struct video_clip))) | ||
157 | return -EFAULT; | ||
158 | |||
159 | kp->clips = compat_alloc_user_space(nclips * sizeof(struct video_clip)); | ||
160 | kclips = kp->clips; | ||
161 | while (nclips--) { | ||
162 | int err; | ||
163 | |||
164 | err = copy_in_user(&kclips->x, &uclips->x, sizeof(kclips->x)); | ||
165 | err |= copy_in_user(&kclips->y, &uclips->y, sizeof(kclips->y)); | ||
166 | err |= copy_in_user(&kclips->width, &uclips->width, sizeof(kclips->width)); | ||
167 | err |= copy_in_user(&kclips->height, &uclips->height, sizeof(kclips->height)); | ||
168 | kclips->next = NULL; | ||
169 | if (err) | ||
170 | return -EFAULT; | ||
171 | kclips++; | ||
172 | uclips++; | ||
173 | } | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | /* You get back everything except the clips... */ | ||
178 | static int put_video_window32(struct video_window *kp, struct video_window32 __user *up) | ||
179 | { | ||
180 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct video_window32)) || | ||
181 | put_user(kp->x, &up->x) || | ||
182 | put_user(kp->y, &up->y) || | ||
183 | put_user(kp->width, &up->width) || | ||
184 | put_user(kp->height, &up->height) || | ||
185 | put_user(kp->chromakey, &up->chromakey) || | ||
186 | put_user(kp->flags, &up->flags) || | ||
187 | put_user(kp->clipcount, &up->clipcount)) | ||
188 | return -EFAULT; | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | struct video_code32 { | ||
193 | char loadwhat[16]; /* name or tag of file being passed */ | ||
194 | compat_int_t datasize; | ||
195 | compat_uptr_t data; | ||
196 | }; | ||
197 | |||
198 | static struct video_code __user *get_microcode32(struct video_code32 *kp) | ||
199 | { | ||
200 | struct video_code __user *up; | ||
201 | |||
202 | up = compat_alloc_user_space(sizeof(*up)); | ||
203 | |||
204 | /* | ||
205 | * NOTE! We don't actually care if these fail. If the | ||
206 | * user address is invalid, the native ioctl will do | ||
207 | * the error handling for us | ||
208 | */ | ||
209 | (void) copy_to_user(up->loadwhat, kp->loadwhat, sizeof(up->loadwhat)); | ||
210 | (void) put_user(kp->datasize, &up->datasize); | ||
211 | (void) put_user(compat_ptr(kp->data), &up->data); | ||
212 | return up; | ||
213 | } | ||
214 | |||
215 | #define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32) | ||
216 | #define VIDIOCSTUNER32 _IOW('v', 5, struct video_tuner32) | ||
217 | #define VIDIOCGWIN32 _IOR('v', 9, struct video_window32) | ||
218 | #define VIDIOCSWIN32 _IOW('v', 10, struct video_window32) | ||
219 | #define VIDIOCGFBUF32 _IOR('v', 11, struct video_buffer32) | ||
220 | #define VIDIOCSFBUF32 _IOW('v', 12, struct video_buffer32) | ||
221 | #define VIDIOCGFREQ32 _IOR('v', 14, u32) | ||
222 | #define VIDIOCSFREQ32 _IOW('v', 15, u32) | ||
223 | #define VIDIOCSMICROCODE32 _IOW('v', 27, struct video_code32) | ||
224 | |||
225 | #define VIDIOCCAPTURE32 _IOW('v', 8, s32) | ||
226 | #define VIDIOCSYNC32 _IOW('v', 18, s32) | ||
227 | #define VIDIOCSWRITEMODE32 _IOW('v', 25, s32) | ||
228 | |||
229 | #endif | ||
230 | |||
231 | static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 24 | static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
232 | { | 25 | { |
233 | long ret = -ENOIOCTLCMD; | 26 | long ret = -ENOIOCTLCMD; |
@@ -372,8 +165,6 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user | |||
372 | if (copy_from_user(kp, up, sizeof(kp->fmt.raw_data))) | 165 | if (copy_from_user(kp, up, sizeof(kp->fmt.raw_data))) |
373 | return -EFAULT; | 166 | return -EFAULT; |
374 | return 0; | 167 | return 0; |
375 | case 0: | ||
376 | return -EINVAL; | ||
377 | default: | 168 | default: |
378 | printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n", | 169 | printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n", |
379 | kp->type); | 170 | kp->type); |
@@ -403,8 +194,6 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user | |||
403 | if (copy_to_user(up, kp, sizeof(up->fmt.raw_data))) | 194 | if (copy_to_user(up, kp, sizeof(up->fmt.raw_data))) |
404 | return -EFAULT; | 195 | return -EFAULT; |
405 | return 0; | 196 | return 0; |
406 | case 0: | ||
407 | return -EINVAL; | ||
408 | default: | 197 | default: |
409 | printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n", | 198 | printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n", |
410 | kp->type); | 199 | kp->type); |
@@ -741,13 +530,6 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext | |||
741 | static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 530 | static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
742 | { | 531 | { |
743 | union { | 532 | union { |
744 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
745 | struct video_tuner vt; | ||
746 | struct video_buffer vb; | ||
747 | struct video_window vw; | ||
748 | struct video_code32 vc; | ||
749 | struct video_audio va; | ||
750 | #endif | ||
751 | struct v4l2_format v2f; | 533 | struct v4l2_format v2f; |
752 | struct v4l2_buffer v2b; | 534 | struct v4l2_buffer v2b; |
753 | struct v4l2_framebuffer v2fb; | 535 | struct v4l2_framebuffer v2fb; |
@@ -763,17 +545,6 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar | |||
763 | 545 | ||
764 | /* First, convert the command. */ | 546 | /* First, convert the command. */ |
765 | switch (cmd) { | 547 | switch (cmd) { |
766 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
767 | case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break; | ||
768 | case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break; | ||
769 | case VIDIOCGWIN32: cmd = VIDIOCGWIN; break; | ||
770 | case VIDIOCSWIN32: cmd = VIDIOCSWIN; break; | ||
771 | case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break; | ||
772 | case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break; | ||
773 | case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break; | ||
774 | case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break; | ||
775 | case VIDIOCSMICROCODE32: cmd = VIDIOCSMICROCODE; break; | ||
776 | #endif | ||
777 | case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break; | 548 | case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break; |
778 | case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break; | 549 | case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break; |
779 | case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break; | 550 | case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break; |
@@ -800,46 +571,6 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar | |||
800 | } | 571 | } |
801 | 572 | ||
802 | switch (cmd) { | 573 | switch (cmd) { |
803 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
804 | case VIDIOCSTUNER: | ||
805 | case VIDIOCGTUNER: | ||
806 | err = get_video_tuner32(&karg.vt, up); | ||
807 | compatible_arg = 0; | ||
808 | break; | ||
809 | |||
810 | case VIDIOCSFBUF: | ||
811 | err = get_video_buffer32(&karg.vb, up); | ||
812 | compatible_arg = 0; | ||
813 | break; | ||
814 | |||
815 | case VIDIOCSWIN: | ||
816 | err = get_video_window32(&karg.vw, up); | ||
817 | compatible_arg = 0; | ||
818 | break; | ||
819 | |||
820 | case VIDIOCGWIN: | ||
821 | case VIDIOCGFBUF: | ||
822 | case VIDIOCGFREQ: | ||
823 | compatible_arg = 0; | ||
824 | break; | ||
825 | |||
826 | case VIDIOCSMICROCODE: | ||
827 | /* Copy the 32-bit "video_code32" to kernel space */ | ||
828 | if (copy_from_user(&karg.vc, up, sizeof(karg.vc))) | ||
829 | return -EFAULT; | ||
830 | /* Convert the 32-bit version to a 64-bit version in user space */ | ||
831 | up = get_microcode32(&karg.vc); | ||
832 | break; | ||
833 | |||
834 | case VIDIOCSFREQ: | ||
835 | err = get_user(karg.vx, (u32 __user *)up); | ||
836 | compatible_arg = 0; | ||
837 | break; | ||
838 | |||
839 | case VIDIOCCAPTURE: | ||
840 | case VIDIOCSYNC: | ||
841 | case VIDIOCSWRITEMODE: | ||
842 | #endif | ||
843 | case VIDIOC_OVERLAY: | 574 | case VIDIOC_OVERLAY: |
844 | case VIDIOC_STREAMON: | 575 | case VIDIOC_STREAMON: |
845 | case VIDIOC_STREAMOFF: | 576 | case VIDIOC_STREAMOFF: |
@@ -922,23 +653,6 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar | |||
922 | return err; | 653 | return err; |
923 | 654 | ||
924 | switch (cmd) { | 655 | switch (cmd) { |
925 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
926 | case VIDIOCGTUNER: | ||
927 | err = put_video_tuner32(&karg.vt, up); | ||
928 | break; | ||
929 | |||
930 | case VIDIOCGWIN: | ||
931 | err = put_video_window32(&karg.vw, up); | ||
932 | break; | ||
933 | |||
934 | case VIDIOCGFBUF: | ||
935 | err = put_video_buffer32(&karg.vb, up); | ||
936 | break; | ||
937 | |||
938 | case VIDIOCGFREQ: | ||
939 | err = put_user(((u32)karg.vx), (u32 __user *)up); | ||
940 | break; | ||
941 | #endif | ||
942 | case VIDIOC_S_INPUT: | 656 | case VIDIOC_S_INPUT: |
943 | case VIDIOC_S_OUTPUT: | 657 | case VIDIOC_S_OUTPUT: |
944 | case VIDIOC_G_INPUT: | 658 | case VIDIOC_G_INPUT: |
@@ -981,37 +695,6 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | |||
981 | return ret; | 695 | return ret; |
982 | 696 | ||
983 | switch (cmd) { | 697 | switch (cmd) { |
984 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
985 | case VIDIOCGCAP: | ||
986 | case VIDIOCGCHAN: | ||
987 | case VIDIOCSCHAN: | ||
988 | case VIDIOCGTUNER32: | ||
989 | case VIDIOCSTUNER32: | ||
990 | case VIDIOCGPICT: | ||
991 | case VIDIOCSPICT: | ||
992 | case VIDIOCCAPTURE32: | ||
993 | case VIDIOCGWIN32: | ||
994 | case VIDIOCSWIN32: | ||
995 | case VIDIOCGFBUF32: | ||
996 | case VIDIOCSFBUF32: | ||
997 | case VIDIOCKEY: | ||
998 | case VIDIOCGFREQ32: | ||
999 | case VIDIOCSFREQ32: | ||
1000 | case VIDIOCGAUDIO: | ||
1001 | case VIDIOCSAUDIO: | ||
1002 | case VIDIOCSYNC32: | ||
1003 | case VIDIOCMCAPTURE: | ||
1004 | case VIDIOCGMBUF: | ||
1005 | case VIDIOCGUNIT: | ||
1006 | case VIDIOCGCAPTURE: | ||
1007 | case VIDIOCSCAPTURE: | ||
1008 | case VIDIOCSPLAYMODE: | ||
1009 | case VIDIOCSWRITEMODE32: | ||
1010 | case VIDIOCGPLAYINFO: | ||
1011 | case VIDIOCSMICROCODE32: | ||
1012 | case VIDIOCGVBIFMT: | ||
1013 | case VIDIOCSVBIFMT: | ||
1014 | #endif | ||
1015 | #ifdef __OLD_VIDIOC_ | 698 | #ifdef __OLD_VIDIOC_ |
1016 | case VIDIOC_OVERLAY32_OLD: | 699 | case VIDIOC_OVERLAY32_OLD: |
1017 | case VIDIOC_S_PARM_OLD: | 700 | case VIDIOC_S_PARM_OLD: |
@@ -1096,19 +779,6 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | |||
1096 | ret = do_video_ioctl(file, cmd, arg); | 779 | ret = do_video_ioctl(file, cmd, arg); |
1097 | break; | 780 | break; |
1098 | 781 | ||
1099 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1100 | /* BTTV specific... */ | ||
1101 | case _IOW('v', BASE_VIDIOCPRIVATE+0, char [256]): | ||
1102 | case _IOR('v', BASE_VIDIOCPRIVATE+1, char [256]): | ||
1103 | case _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int): | ||
1104 | case _IOW('v' , BASE_VIDIOCPRIVATE+3, char [16]): /* struct bttv_pll_info */ | ||
1105 | case _IOR('v' , BASE_VIDIOCPRIVATE+4, int): | ||
1106 | case _IOR('v' , BASE_VIDIOCPRIVATE+5, int): | ||
1107 | case _IOR('v' , BASE_VIDIOCPRIVATE+6, int): | ||
1108 | case _IOR('v' , BASE_VIDIOCPRIVATE+7, int): | ||
1109 | ret = native_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); | ||
1110 | break; | ||
1111 | #endif | ||
1112 | default: | 782 | default: |
1113 | printk(KERN_WARNING "compat_ioctl32: " | 783 | printk(KERN_WARNING "compat_ioctl32: " |
1114 | "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n", | 784 | "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n", |
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c index 9d2502cd03ff..8f81efcfcf56 100644 --- a/drivers/media/video/v4l2-ctrls.c +++ b/drivers/media/video/v4l2-ctrls.c | |||
@@ -38,15 +38,15 @@ struct ctrl_helper { | |||
38 | the given control ID. The pointer array ends with a NULL pointer. | 38 | the given control ID. The pointer array ends with a NULL pointer. |
39 | An empty string signifies a menu entry that is invalid. This allows | 39 | An empty string signifies a menu entry that is invalid. This allows |
40 | drivers to disable certain options if it is not supported. */ | 40 | drivers to disable certain options if it is not supported. */ |
41 | const char **v4l2_ctrl_get_menu(u32 id) | 41 | const char * const *v4l2_ctrl_get_menu(u32 id) |
42 | { | 42 | { |
43 | static const char *mpeg_audio_sampling_freq[] = { | 43 | static const char * const mpeg_audio_sampling_freq[] = { |
44 | "44.1 kHz", | 44 | "44.1 kHz", |
45 | "48 kHz", | 45 | "48 kHz", |
46 | "32 kHz", | 46 | "32 kHz", |
47 | NULL | 47 | NULL |
48 | }; | 48 | }; |
49 | static const char *mpeg_audio_encoding[] = { | 49 | static const char * const mpeg_audio_encoding[] = { |
50 | "MPEG-1/2 Layer I", | 50 | "MPEG-1/2 Layer I", |
51 | "MPEG-1/2 Layer II", | 51 | "MPEG-1/2 Layer II", |
52 | "MPEG-1/2 Layer III", | 52 | "MPEG-1/2 Layer III", |
@@ -54,7 +54,7 @@ const char **v4l2_ctrl_get_menu(u32 id) | |||
54 | "AC-3", | 54 | "AC-3", |
55 | NULL | 55 | NULL |
56 | }; | 56 | }; |
57 | static const char *mpeg_audio_l1_bitrate[] = { | 57 | static const char * const mpeg_audio_l1_bitrate[] = { |
58 | "32 kbps", | 58 | "32 kbps", |
59 | "64 kbps", | 59 | "64 kbps", |
60 | "96 kbps", | 60 | "96 kbps", |
@@ -71,7 +71,7 @@ const char **v4l2_ctrl_get_menu(u32 id) | |||
71 | "448 kbps", | 71 | "448 kbps", |
72 | NULL | 72 | NULL |
73 | }; | 73 | }; |
74 | static const char *mpeg_audio_l2_bitrate[] = { | 74 | static const char * const mpeg_audio_l2_bitrate[] = { |
75 | "32 kbps", | 75 | "32 kbps", |
76 | "48 kbps", | 76 | "48 kbps", |
77 | "56 kbps", | 77 | "56 kbps", |
@@ -88,7 +88,7 @@ const char **v4l2_ctrl_get_menu(u32 id) | |||
88 | "384 kbps", | 88 | "384 kbps", |
89 | NULL | 89 | NULL |
90 | }; | 90 | }; |
91 | static const char *mpeg_audio_l3_bitrate[] = { | 91 | static const char * const mpeg_audio_l3_bitrate[] = { |
92 | "32 kbps", | 92 | "32 kbps", |
93 | "40 kbps", | 93 | "40 kbps", |
94 | "48 kbps", | 94 | "48 kbps", |
@@ -105,7 +105,7 @@ const char **v4l2_ctrl_get_menu(u32 id) | |||
105 | "320 kbps", | 105 | "320 kbps", |
106 | NULL | 106 | NULL |
107 | }; | 107 | }; |
108 | static const char *mpeg_audio_ac3_bitrate[] = { | 108 | static const char * const mpeg_audio_ac3_bitrate[] = { |
109 | "32 kbps", | 109 | "32 kbps", |
110 | "40 kbps", | 110 | "40 kbps", |
111 | "48 kbps", | 111 | "48 kbps", |
@@ -127,50 +127,50 @@ const char **v4l2_ctrl_get_menu(u32 id) | |||
127 | "640 kbps", | 127 | "640 kbps", |
128 | NULL | 128 | NULL |
129 | }; | 129 | }; |
130 | static const char *mpeg_audio_mode[] = { | 130 | static const char * const mpeg_audio_mode[] = { |
131 | "Stereo", | 131 | "Stereo", |
132 | "Joint Stereo", | 132 | "Joint Stereo", |
133 | "Dual", | 133 | "Dual", |
134 | "Mono", | 134 | "Mono", |
135 | NULL | 135 | NULL |
136 | }; | 136 | }; |
137 | static const char *mpeg_audio_mode_extension[] = { | 137 | static const char * const mpeg_audio_mode_extension[] = { |
138 | "Bound 4", | 138 | "Bound 4", |
139 | "Bound 8", | 139 | "Bound 8", |
140 | "Bound 12", | 140 | "Bound 12", |
141 | "Bound 16", | 141 | "Bound 16", |
142 | NULL | 142 | NULL |
143 | }; | 143 | }; |
144 | static const char *mpeg_audio_emphasis[] = { | 144 | static const char * const mpeg_audio_emphasis[] = { |
145 | "No Emphasis", | 145 | "No Emphasis", |
146 | "50/15 us", | 146 | "50/15 us", |
147 | "CCITT J17", | 147 | "CCITT J17", |
148 | NULL | 148 | NULL |
149 | }; | 149 | }; |
150 | static const char *mpeg_audio_crc[] = { | 150 | static const char * const mpeg_audio_crc[] = { |
151 | "No CRC", | 151 | "No CRC", |
152 | "16-bit CRC", | 152 | "16-bit CRC", |
153 | NULL | 153 | NULL |
154 | }; | 154 | }; |
155 | static const char *mpeg_video_encoding[] = { | 155 | static const char * const mpeg_video_encoding[] = { |
156 | "MPEG-1", | 156 | "MPEG-1", |
157 | "MPEG-2", | 157 | "MPEG-2", |
158 | "MPEG-4 AVC", | 158 | "MPEG-4 AVC", |
159 | NULL | 159 | NULL |
160 | }; | 160 | }; |
161 | static const char *mpeg_video_aspect[] = { | 161 | static const char * const mpeg_video_aspect[] = { |
162 | "1x1", | 162 | "1x1", |
163 | "4x3", | 163 | "4x3", |
164 | "16x9", | 164 | "16x9", |
165 | "2.21x1", | 165 | "2.21x1", |
166 | NULL | 166 | NULL |
167 | }; | 167 | }; |
168 | static const char *mpeg_video_bitrate_mode[] = { | 168 | static const char * const mpeg_video_bitrate_mode[] = { |
169 | "Variable Bitrate", | 169 | "Variable Bitrate", |
170 | "Constant Bitrate", | 170 | "Constant Bitrate", |
171 | NULL | 171 | NULL |
172 | }; | 172 | }; |
173 | static const char *mpeg_stream_type[] = { | 173 | static const char * const mpeg_stream_type[] = { |
174 | "MPEG-2 Program Stream", | 174 | "MPEG-2 Program Stream", |
175 | "MPEG-2 Transport Stream", | 175 | "MPEG-2 Transport Stream", |
176 | "MPEG-1 System Stream", | 176 | "MPEG-1 System Stream", |
@@ -179,25 +179,25 @@ const char **v4l2_ctrl_get_menu(u32 id) | |||
179 | "MPEG-2 SVCD-compatible Stream", | 179 | "MPEG-2 SVCD-compatible Stream", |
180 | NULL | 180 | NULL |
181 | }; | 181 | }; |
182 | static const char *mpeg_stream_vbi_fmt[] = { | 182 | static const char * const mpeg_stream_vbi_fmt[] = { |
183 | "No VBI", | 183 | "No VBI", |
184 | "Private packet, IVTV format", | 184 | "Private packet, IVTV format", |
185 | NULL | 185 | NULL |
186 | }; | 186 | }; |
187 | static const char *camera_power_line_frequency[] = { | 187 | static const char * const camera_power_line_frequency[] = { |
188 | "Disabled", | 188 | "Disabled", |
189 | "50 Hz", | 189 | "50 Hz", |
190 | "60 Hz", | 190 | "60 Hz", |
191 | NULL | 191 | NULL |
192 | }; | 192 | }; |
193 | static const char *camera_exposure_auto[] = { | 193 | static const char * const camera_exposure_auto[] = { |
194 | "Auto Mode", | 194 | "Auto Mode", |
195 | "Manual Mode", | 195 | "Manual Mode", |
196 | "Shutter Priority Mode", | 196 | "Shutter Priority Mode", |
197 | "Aperture Priority Mode", | 197 | "Aperture Priority Mode", |
198 | NULL | 198 | NULL |
199 | }; | 199 | }; |
200 | static const char *colorfx[] = { | 200 | static const char * const colorfx[] = { |
201 | "None", | 201 | "None", |
202 | "Black & White", | 202 | "Black & White", |
203 | "Sepia", | 203 | "Sepia", |
@@ -210,7 +210,7 @@ const char **v4l2_ctrl_get_menu(u32 id) | |||
210 | "Vivid", | 210 | "Vivid", |
211 | NULL | 211 | NULL |
212 | }; | 212 | }; |
213 | static const char *tune_preemphasis[] = { | 213 | static const char * const tune_preemphasis[] = { |
214 | "No preemphasis", | 214 | "No preemphasis", |
215 | "50 useconds", | 215 | "50 useconds", |
216 | "75 useconds", | 216 | "75 useconds", |
@@ -952,7 +952,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, | |||
952 | const struct v4l2_ctrl_ops *ops, | 952 | const struct v4l2_ctrl_ops *ops, |
953 | u32 id, const char *name, enum v4l2_ctrl_type type, | 953 | u32 id, const char *name, enum v4l2_ctrl_type type, |
954 | s32 min, s32 max, u32 step, s32 def, | 954 | s32 min, s32 max, u32 step, s32 def, |
955 | u32 flags, const char **qmenu, void *priv) | 955 | u32 flags, const char * const *qmenu, void *priv) |
956 | { | 956 | { |
957 | struct v4l2_ctrl *ctrl; | 957 | struct v4l2_ctrl *ctrl; |
958 | unsigned sz_extra = 0; | 958 | unsigned sz_extra = 0; |
@@ -962,13 +962,20 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, | |||
962 | 962 | ||
963 | /* Sanity checks */ | 963 | /* Sanity checks */ |
964 | if (id == 0 || name == NULL || id >= V4L2_CID_PRIVATE_BASE || | 964 | if (id == 0 || name == NULL || id >= V4L2_CID_PRIVATE_BASE || |
965 | def < min || def > max || max < min || | 965 | max < min || |
966 | (type == V4L2_CTRL_TYPE_INTEGER && step == 0) || | 966 | (type == V4L2_CTRL_TYPE_INTEGER && step == 0) || |
967 | (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) || | 967 | (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) || |
968 | (type == V4L2_CTRL_TYPE_STRING && max == 0)) { | 968 | (type == V4L2_CTRL_TYPE_STRING && max == 0)) { |
969 | handler_set_err(hdl, -ERANGE); | 969 | handler_set_err(hdl, -ERANGE); |
970 | return NULL; | 970 | return NULL; |
971 | } | 971 | } |
972 | if ((type == V4L2_CTRL_TYPE_INTEGER || | ||
973 | type == V4L2_CTRL_TYPE_MENU || | ||
974 | type == V4L2_CTRL_TYPE_BOOLEAN) && | ||
975 | (def < min || def > max)) { | ||
976 | handler_set_err(hdl, -ERANGE); | ||
977 | return NULL; | ||
978 | } | ||
972 | 979 | ||
973 | if (type == V4L2_CTRL_TYPE_BUTTON) | 980 | if (type == V4L2_CTRL_TYPE_BUTTON) |
974 | flags |= V4L2_CTRL_FLAG_WRITE_ONLY; | 981 | flags |= V4L2_CTRL_FLAG_WRITE_ONLY; |
@@ -1019,7 +1026,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl, | |||
1019 | bool is_menu; | 1026 | bool is_menu; |
1020 | struct v4l2_ctrl *ctrl; | 1027 | struct v4l2_ctrl *ctrl; |
1021 | const char *name = cfg->name; | 1028 | const char *name = cfg->name; |
1022 | const char **qmenu = cfg->qmenu; | 1029 | const char * const *qmenu = cfg->qmenu; |
1023 | enum v4l2_ctrl_type type = cfg->type; | 1030 | enum v4l2_ctrl_type type = cfg->type; |
1024 | u32 flags = cfg->flags; | 1031 | u32 flags = cfg->flags; |
1025 | s32 min = cfg->min; | 1032 | s32 min = cfg->min; |
@@ -1075,7 +1082,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl, | |||
1075 | const struct v4l2_ctrl_ops *ops, | 1082 | const struct v4l2_ctrl_ops *ops, |
1076 | u32 id, s32 max, s32 mask, s32 def) | 1083 | u32 id, s32 max, s32 mask, s32 def) |
1077 | { | 1084 | { |
1078 | const char **qmenu = v4l2_ctrl_get_menu(id); | 1085 | const char * const *qmenu = v4l2_ctrl_get_menu(id); |
1079 | const char *name; | 1086 | const char *name; |
1080 | enum v4l2_ctrl_type type; | 1087 | enum v4l2_ctrl_type type; |
1081 | s32 min; | 1088 | s32 min; |
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index dd9283fcb564..7e47f15f350d 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
@@ -18,12 +18,8 @@ | |||
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | 19 | ||
20 | #define __OLD_VIDIOC_ /* To allow fixing old calls */ | 20 | #define __OLD_VIDIOC_ /* To allow fixing old calls */ |
21 | #include <linux/videodev.h> | ||
22 | #include <linux/videodev2.h> | 21 | #include <linux/videodev2.h> |
23 | 22 | ||
24 | #ifdef CONFIG_VIDEO_V4L1 | ||
25 | #include <linux/videodev.h> | ||
26 | #endif | ||
27 | #include <media/v4l2-common.h> | 23 | #include <media/v4l2-common.h> |
28 | #include <media/v4l2-ioctl.h> | 24 | #include <media/v4l2-ioctl.h> |
29 | #include <media/v4l2-ctrls.h> | 25 | #include <media/v4l2-ctrls.h> |
@@ -183,42 +179,6 @@ static const char *v4l2_memory_names[] = { | |||
183 | 179 | ||
184 | /* ------------------------------------------------------------------ */ | 180 | /* ------------------------------------------------------------------ */ |
185 | /* debug help functions */ | 181 | /* debug help functions */ |
186 | |||
187 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
188 | static const char *v4l1_ioctls[] = { | ||
189 | [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", | ||
190 | [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", | ||
191 | [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN", | ||
192 | [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER", | ||
193 | [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER", | ||
194 | [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT", | ||
195 | [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT", | ||
196 | [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE", | ||
197 | [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN", | ||
198 | [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN", | ||
199 | [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF", | ||
200 | [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF", | ||
201 | [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY", | ||
202 | [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ", | ||
203 | [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ", | ||
204 | [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO", | ||
205 | [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO", | ||
206 | [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC", | ||
207 | [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE", | ||
208 | [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF", | ||
209 | [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT", | ||
210 | [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE", | ||
211 | [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE", | ||
212 | [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE", | ||
213 | [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE", | ||
214 | [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO", | ||
215 | [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE", | ||
216 | [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT", | ||
217 | [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT" | ||
218 | }; | ||
219 | #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) | ||
220 | #endif | ||
221 | |||
222 | static const char *v4l2_ioctls[] = { | 182 | static const char *v4l2_ioctls[] = { |
223 | [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", | 183 | [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", |
224 | [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", | 184 | [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", |
@@ -310,15 +270,6 @@ void v4l_printk_ioctl(unsigned int cmd) | |||
310 | case 'd': | 270 | case 'd': |
311 | type = "v4l2_int"; | 271 | type = "v4l2_int"; |
312 | break; | 272 | break; |
313 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
314 | case 'v': | ||
315 | if (_IOC_NR(cmd) >= V4L1_IOCTLS) { | ||
316 | type = "v4l1"; | ||
317 | break; | ||
318 | } | ||
319 | printk("%s", v4l1_ioctls[_IOC_NR(cmd)]); | ||
320 | return; | ||
321 | #endif | ||
322 | case 'V': | 273 | case 'V': |
323 | if (_IOC_NR(cmd) >= V4L2_IOCTLS) { | 274 | if (_IOC_NR(cmd) >= V4L2_IOCTLS) { |
324 | type = "v4l2"; | 275 | type = "v4l2"; |
@@ -622,20 +573,6 @@ static long __video_do_ioctl(struct file *file, | |||
622 | return -EINVAL; | 573 | return -EINVAL; |
623 | } | 574 | } |
624 | 575 | ||
625 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
626 | /******************************************************** | ||
627 | All other V4L1 calls are handled by v4l1_compat module. | ||
628 | Those calls will be translated into V4L2 calls, and | ||
629 | __video_do_ioctl will be called again, with one or more | ||
630 | V4L2 ioctls. | ||
631 | ********************************************************/ | ||
632 | if (_IOC_TYPE(cmd) == 'v' && cmd != VIDIOCGMBUF && | ||
633 | _IOC_NR(cmd) < BASE_VIDIOCPRIVATE) { | ||
634 | return v4l_compat_translate_ioctl(file, cmd, arg, | ||
635 | __video_do_ioctl); | ||
636 | } | ||
637 | #endif | ||
638 | |||
639 | if ((vfd->debug & V4L2_DEBUG_IOCTL) && | 576 | if ((vfd->debug & V4L2_DEBUG_IOCTL) && |
640 | !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { | 577 | !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { |
641 | v4l_print_ioctl(vfd->name, cmd); | 578 | v4l_print_ioctl(vfd->name, cmd); |
@@ -644,29 +581,6 @@ static long __video_do_ioctl(struct file *file, | |||
644 | 581 | ||
645 | switch (cmd) { | 582 | switch (cmd) { |
646 | 583 | ||
647 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
648 | /*********************************************************** | ||
649 | Handles calls to the obsoleted V4L1 API | ||
650 | Due to the nature of VIDIOCGMBUF, each driver that supports | ||
651 | V4L1 should implement its own handler for this ioctl. | ||
652 | ***********************************************************/ | ||
653 | |||
654 | /* --- streaming capture ------------------------------------- */ | ||
655 | case VIDIOCGMBUF: | ||
656 | { | ||
657 | struct video_mbuf *p = arg; | ||
658 | |||
659 | if (!ops->vidiocgmbuf) | ||
660 | break; | ||
661 | ret = ops->vidiocgmbuf(file, fh, p); | ||
662 | if (!ret) | ||
663 | dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n", | ||
664 | p->size, p->frames, | ||
665 | (unsigned long)p->offsets); | ||
666 | break; | ||
667 | } | ||
668 | #endif | ||
669 | |||
670 | /* --- capabilities ------------------------------------------ */ | 584 | /* --- capabilities ------------------------------------------ */ |
671 | case VIDIOC_QUERYCAP: | 585 | case VIDIOC_QUERYCAP: |
672 | { | 586 | { |
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c index 9eda7cc03121..e25aca5759fb 100644 --- a/drivers/media/video/via-camera.c +++ b/drivers/media/video/via-camera.c | |||
@@ -1161,16 +1161,6 @@ out: | |||
1161 | return ret; | 1161 | return ret; |
1162 | } | 1162 | } |
1163 | 1163 | ||
1164 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1165 | static int viacam_vidiocgmbuf(struct file *filp, void *priv, | ||
1166 | struct video_mbuf *mbuf) | ||
1167 | { | ||
1168 | struct via_camera *cam = priv; | ||
1169 | |||
1170 | return videobuf_cgmbuf(&cam->vb_queue, mbuf, 6); | ||
1171 | } | ||
1172 | #endif | ||
1173 | |||
1174 | /* G/S_PARM */ | 1164 | /* G/S_PARM */ |
1175 | 1165 | ||
1176 | static int viacam_g_parm(struct file *filp, void *priv, | 1166 | static int viacam_g_parm(struct file *filp, void *priv, |
@@ -1251,9 +1241,6 @@ static const struct v4l2_ioctl_ops viacam_ioctl_ops = { | |||
1251 | .vidioc_s_parm = viacam_s_parm, | 1241 | .vidioc_s_parm = viacam_s_parm, |
1252 | .vidioc_enum_framesizes = viacam_enum_framesizes, | 1242 | .vidioc_enum_framesizes = viacam_enum_framesizes, |
1253 | .vidioc_enum_frameintervals = viacam_enum_frameintervals, | 1243 | .vidioc_enum_frameintervals = viacam_enum_frameintervals, |
1254 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1255 | .vidiocgmbuf = viacam_vidiocgmbuf, | ||
1256 | #endif | ||
1257 | }; | 1244 | }; |
1258 | 1245 | ||
1259 | /*----------------------------------------------------------------------------*/ | 1246 | /*----------------------------------------------------------------------------*/ |
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index 8979f91fa8e5..de4fa4eb8844 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c | |||
@@ -1202,33 +1202,3 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma) | |||
1202 | return rc; | 1202 | return rc; |
1203 | } | 1203 | } |
1204 | EXPORT_SYMBOL_GPL(videobuf_mmap_mapper); | 1204 | EXPORT_SYMBOL_GPL(videobuf_mmap_mapper); |
1205 | |||
1206 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1207 | int videobuf_cgmbuf(struct videobuf_queue *q, | ||
1208 | struct video_mbuf *mbuf, int count) | ||
1209 | { | ||
1210 | struct v4l2_requestbuffers req; | ||
1211 | int rc, i; | ||
1212 | |||
1213 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | ||
1214 | |||
1215 | memset(&req, 0, sizeof(req)); | ||
1216 | req.type = q->type; | ||
1217 | req.count = count; | ||
1218 | req.memory = V4L2_MEMORY_MMAP; | ||
1219 | rc = videobuf_reqbufs(q, &req); | ||
1220 | if (rc < 0) | ||
1221 | return rc; | ||
1222 | |||
1223 | mbuf->frames = req.count; | ||
1224 | mbuf->size = 0; | ||
1225 | for (i = 0; i < mbuf->frames; i++) { | ||
1226 | mbuf->offsets[i] = q->bufs[i]->boff; | ||
1227 | mbuf->size += PAGE_ALIGN(q->bufs[i]->bsize); | ||
1228 | } | ||
1229 | |||
1230 | return 0; | ||
1231 | } | ||
1232 | EXPORT_SYMBOL_GPL(videobuf_cgmbuf); | ||
1233 | #endif | ||
1234 | |||
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 20f227ee2b3e..ddb8f4b46c03 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c | |||
@@ -69,10 +69,9 @@ static struct scatterlist *videobuf_vmalloc_to_sg(unsigned char *virt, | |||
69 | struct page *pg; | 69 | struct page *pg; |
70 | int i; | 70 | int i; |
71 | 71 | ||
72 | sglist = vmalloc(nr_pages * sizeof(*sglist)); | 72 | sglist = vzalloc(nr_pages * sizeof(*sglist)); |
73 | if (NULL == sglist) | 73 | if (NULL == sglist) |
74 | return NULL; | 74 | return NULL; |
75 | memset(sglist, 0, nr_pages * sizeof(*sglist)); | ||
76 | sg_init_table(sglist, nr_pages); | 75 | sg_init_table(sglist, nr_pages); |
77 | for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) { | 76 | for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) { |
78 | pg = vmalloc_to_page(virt); | 77 | pg = vmalloc_to_page(virt); |
@@ -544,14 +543,6 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, | |||
544 | 543 | ||
545 | retval = -EINVAL; | 544 | retval = -EINVAL; |
546 | 545 | ||
547 | /* This function maintains backwards compatibility with V4L1 and will | ||
548 | * map more than one buffer if the vma length is equal to the combined | ||
549 | * size of multiple buffers than it will map them together. See | ||
550 | * VIDIOCGMBUF in the v4l spec | ||
551 | * | ||
552 | * TODO: Allow drivers to specify if they support this mode | ||
553 | */ | ||
554 | |||
555 | BUG_ON(!mem); | 546 | BUG_ON(!mem); |
556 | MAGIC_CHECK(mem->magic, MAGIC_SG_MEM); | 547 | MAGIC_CHECK(mem->magic, MAGIC_SG_MEM); |
557 | 548 | ||
@@ -571,29 +562,6 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, | |||
571 | } | 562 | } |
572 | 563 | ||
573 | last = first; | 564 | last = first; |
574 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
575 | if (size != (vma->vm_end - vma->vm_start)) { | ||
576 | /* look for last buffer to map */ | ||
577 | for (last = first + 1; last < VIDEO_MAX_FRAME; last++) { | ||
578 | if (NULL == q->bufs[last]) | ||
579 | continue; | ||
580 | if (V4L2_MEMORY_MMAP != q->bufs[last]->memory) | ||
581 | continue; | ||
582 | if (q->bufs[last]->map) { | ||
583 | retval = -EBUSY; | ||
584 | goto done; | ||
585 | } | ||
586 | size += PAGE_ALIGN(q->bufs[last]->bsize); | ||
587 | if (size == (vma->vm_end - vma->vm_start)) | ||
588 | break; | ||
589 | } | ||
590 | if (VIDEO_MAX_FRAME == last) { | ||
591 | dprintk(1, "mmap app bug: size invalid [size=0x%lx]\n", | ||
592 | (vma->vm_end - vma->vm_start)); | ||
593 | goto done; | ||
594 | } | ||
595 | } | ||
596 | #endif | ||
597 | 565 | ||
598 | /* create mapping + update buffer list */ | 566 | /* create mapping + update buffer list */ |
599 | retval = -ENOMEM; | 567 | retval = -ENOMEM; |
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 7e7eec48f8b1..d63e9d978493 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
@@ -2954,9 +2954,6 @@ static int vino_enum_input(struct file *file, void *__fh, | |||
2954 | if (input == VINO_INPUT_NONE) | 2954 | if (input == VINO_INPUT_NONE) |
2955 | return -EINVAL; | 2955 | return -EINVAL; |
2956 | 2956 | ||
2957 | memset(i, 0, sizeof(struct v4l2_input)); | ||
2958 | |||
2959 | i->index = index; | ||
2960 | i->type = V4L2_INPUT_TYPE_CAMERA; | 2957 | i->type = V4L2_INPUT_TYPE_CAMERA; |
2961 | i->std = vino_inputs[input].std; | 2958 | i->std = vino_inputs[input].std; |
2962 | strcpy(i->name, vino_inputs[input].name); | 2959 | strcpy(i->name, vino_inputs[input].name); |
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 9797e5a69265..c49c39386bd0 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -870,15 +870,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) | |||
870 | file->f_flags & O_NONBLOCK); | 870 | file->f_flags & O_NONBLOCK); |
871 | } | 871 | } |
872 | 872 | ||
873 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
874 | static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | ||
875 | { | ||
876 | struct vivi_dev *dev = video_drvdata(file); | ||
877 | |||
878 | return videobuf_cgmbuf(&dev->vb_vidq, mbuf, 8); | ||
879 | } | ||
880 | #endif | ||
881 | |||
882 | static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | 873 | static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) |
883 | { | 874 | { |
884 | struct vivi_dev *dev = video_drvdata(file); | 875 | struct vivi_dev *dev = video_drvdata(file); |
@@ -1105,9 +1096,6 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = { | |||
1105 | .vidioc_queryctrl = vidioc_queryctrl, | 1096 | .vidioc_queryctrl = vidioc_queryctrl, |
1106 | .vidioc_g_ctrl = vidioc_g_ctrl, | 1097 | .vidioc_g_ctrl = vidioc_g_ctrl, |
1107 | .vidioc_s_ctrl = vidioc_s_ctrl, | 1098 | .vidioc_s_ctrl = vidioc_s_ctrl, |
1108 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1109 | .vidiocgmbuf = vidiocgmbuf, | ||
1110 | #endif | ||
1111 | }; | 1099 | }; |
1112 | 1100 | ||
1113 | static struct video_device vivi_template = { | 1101 | static struct video_device vivi_template = { |
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h index 27f05551183f..4bb368e6fd47 100644 --- a/drivers/media/video/zoran/zoran.h +++ b/drivers/media/video/zoran/zoran.h | |||
@@ -33,15 +33,6 @@ | |||
33 | 33 | ||
34 | #include <media/v4l2-device.h> | 34 | #include <media/v4l2-device.h> |
35 | 35 | ||
36 | #define ZORAN_VIDMODE_PAL 0 | ||
37 | #define ZORAN_VIDMODE_NTSC 1 | ||
38 | #define ZORAN_VIDMODE_SECAM 2 | ||
39 | |||
40 | struct zoran_requestbuffers { | ||
41 | unsigned long count; /* Number of buffers for MJPEG grabbing */ | ||
42 | unsigned long size; /* Size PER BUFFER in bytes */ | ||
43 | }; | ||
44 | |||
45 | struct zoran_sync { | 36 | struct zoran_sync { |
46 | unsigned long frame; /* number of buffer that has been free'd */ | 37 | unsigned long frame; /* number of buffer that has been free'd */ |
47 | unsigned long length; /* number of code bytes in buffer (capture only) */ | 38 | unsigned long length; /* number of code bytes in buffer (capture only) */ |
@@ -49,102 +40,6 @@ struct zoran_sync { | |||
49 | struct timeval timestamp; /* timestamp */ | 40 | struct timeval timestamp; /* timestamp */ |
50 | }; | 41 | }; |
51 | 42 | ||
52 | struct zoran_status { | ||
53 | int input; /* Input channel, has to be set prior to BUZIOC_G_STATUS */ | ||
54 | int signal; /* Returned: 1 if valid video signal detected */ | ||
55 | int norm; /* Returned: ZORAN_VIDMODE_PAL or ZORAN_VIDMODE_NTSC */ | ||
56 | int color; /* Returned: 1 if color signal detected */ | ||
57 | }; | ||
58 | |||
59 | struct zoran_params { | ||
60 | |||
61 | /* The following parameters can only be queried */ | ||
62 | |||
63 | int major_version; /* Major version number of driver */ | ||
64 | int minor_version; /* Minor version number of driver */ | ||
65 | |||
66 | /* Main control parameters */ | ||
67 | |||
68 | int input; /* Input channel: 0 = Composite, 1 = S-VHS */ | ||
69 | int norm; /* Norm: ZORAN_VIDMODE_PAL or ZORAN_VIDMODE_NTSC */ | ||
70 | int decimation; /* decimation of captured video, | ||
71 | * enlargement of video played back. | ||
72 | * Valid values are 1, 2, 4 or 0. | ||
73 | * 0 is a special value where the user | ||
74 | * has full control over video scaling */ | ||
75 | |||
76 | /* The following parameters only have to be set if decimation==0, | ||
77 | * for other values of decimation they provide the data how the image is captured */ | ||
78 | |||
79 | int HorDcm; /* Horizontal decimation: 1, 2 or 4 */ | ||
80 | int VerDcm; /* Vertical decimation: 1 or 2 */ | ||
81 | int TmpDcm; /* Temporal decimation: 1 or 2, | ||
82 | * if TmpDcm==2 in capture every second frame is dropped, | ||
83 | * in playback every frame is played twice */ | ||
84 | int field_per_buff; /* Number of fields per buffer: 1 or 2 */ | ||
85 | int img_x; /* start of image in x direction */ | ||
86 | int img_y; /* start of image in y direction */ | ||
87 | int img_width; /* image width BEFORE decimation, | ||
88 | * must be a multiple of HorDcm*16 */ | ||
89 | int img_height; /* image height BEFORE decimation, | ||
90 | * must be a multiple of VerDcm*8 */ | ||
91 | |||
92 | /* --- End of parameters for decimation==0 only --- */ | ||
93 | |||
94 | /* JPEG control parameters */ | ||
95 | |||
96 | int quality; /* Measure for quality of compressed images. | ||
97 | * Scales linearly with the size of the compressed images. | ||
98 | * Must be beetween 0 and 100, 100 is a compression | ||
99 | * ratio of 1:4 */ | ||
100 | |||
101 | int odd_even; /* Which field should come first ??? */ | ||
102 | |||
103 | int APPn; /* Number of APP segment to be written, must be 0..15 */ | ||
104 | int APP_len; /* Length of data in JPEG APPn segment */ | ||
105 | char APP_data[60]; /* Data in the JPEG APPn segment. */ | ||
106 | |||
107 | int COM_len; /* Length of data in JPEG COM segment */ | ||
108 | char COM_data[60]; /* Data in JPEG COM segment */ | ||
109 | |||
110 | unsigned long jpeg_markers; /* Which markers should go into the JPEG output. | ||
111 | * Unless you exactly know what you do, leave them untouched. | ||
112 | * Inluding less markers will make the resulting code | ||
113 | * smaller, but there will be fewer applications | ||
114 | * which can read it. | ||
115 | * The presence of the APP and COM marker is | ||
116 | * influenced by APP0_len and COM_len ONLY! */ | ||
117 | #define JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ | ||
118 | #define JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ | ||
119 | #define JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ | ||
120 | #define JPEG_MARKER_COM (1<<6) /* Comment segment */ | ||
121 | #define JPEG_MARKER_APP (1<<7) /* App segment, driver will allways use APP0 */ | ||
122 | |||
123 | int VFIFO_FB; /* Flag for enabling Video Fifo Feedback. | ||
124 | * If this flag is turned on and JPEG decompressing | ||
125 | * is going to the screen, the decompress process | ||
126 | * is stopped every time the Video Fifo is full. | ||
127 | * This enables a smooth decompress to the screen | ||
128 | * but the video output signal will get scrambled */ | ||
129 | |||
130 | /* Misc */ | ||
131 | |||
132 | char reserved[312]; /* Makes 512 bytes for this structure */ | ||
133 | }; | ||
134 | |||
135 | /* | ||
136 | Private IOCTL to set up for displaying MJPEG | ||
137 | */ | ||
138 | #define BUZIOC_G_PARAMS _IOR ('v', BASE_VIDIOC_PRIVATE+0, struct zoran_params) | ||
139 | #define BUZIOC_S_PARAMS _IOWR('v', BASE_VIDIOC_PRIVATE+1, struct zoran_params) | ||
140 | #define BUZIOC_REQBUFS _IOWR('v', BASE_VIDIOC_PRIVATE+2, struct zoran_requestbuffers) | ||
141 | #define BUZIOC_QBUF_CAPT _IOW ('v', BASE_VIDIOC_PRIVATE+3, int) | ||
142 | #define BUZIOC_QBUF_PLAY _IOW ('v', BASE_VIDIOC_PRIVATE+4, int) | ||
143 | #define BUZIOC_SYNC _IOR ('v', BASE_VIDIOC_PRIVATE+5, struct zoran_sync) | ||
144 | #define BUZIOC_G_STATUS _IOWR('v', BASE_VIDIOC_PRIVATE+6, struct zoran_status) | ||
145 | |||
146 | |||
147 | #ifdef __KERNEL__ | ||
148 | 43 | ||
149 | #define MAJOR_VERSION 0 /* driver major version */ | 44 | #define MAJOR_VERSION 0 /* driver major version */ |
150 | #define MINOR_VERSION 10 /* driver minor version */ | 45 | #define MINOR_VERSION 10 /* driver minor version */ |
@@ -507,6 +402,4 @@ static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev) | |||
507 | #define btor(dat,adr) btwrite((dat) | btread(adr), adr) | 402 | #define btor(dat,adr) btwrite((dat) | btread(adr), adr) |
508 | #define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr) | 403 | #define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr) |
509 | 404 | ||
510 | #endif /* __kernel__ */ | ||
511 | |||
512 | #endif | 405 | #endif |
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index e520abf9f4c3..9cdc3bb15b15 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c | |||
@@ -943,7 +943,7 @@ zoran_open_init_params (struct zoran *zr) | |||
943 | memset(zr->jpg_settings.jpg_comp.COM_data, 0, | 943 | memset(zr->jpg_settings.jpg_comp.COM_data, 0, |
944 | sizeof(zr->jpg_settings.jpg_comp.COM_data)); | 944 | sizeof(zr->jpg_settings.jpg_comp.COM_data)); |
945 | zr->jpg_settings.jpg_comp.jpeg_markers = | 945 | zr->jpg_settings.jpg_comp.jpeg_markers = |
946 | JPEG_MARKER_DHT | JPEG_MARKER_DQT; | 946 | V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT; |
947 | i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0); | 947 | i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0); |
948 | if (i) | 948 | if (i) |
949 | dprintk(1, KERN_ERR "%s: %s internal error\n", | 949 | dprintk(1, KERN_ERR "%s: %s internal error\n", |
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c index b02007e42150..e8a27844bf39 100644 --- a/drivers/media/video/zoran/zoran_device.c +++ b/drivers/media/video/zoran/zoran_device.c | |||
@@ -1523,7 +1523,7 @@ zoran_irq (int irq, | |||
1523 | zr->JPEG_missed > 25 || | 1523 | zr->JPEG_missed > 25 || |
1524 | zr->JPEG_error == 1 || | 1524 | zr->JPEG_error == 1 || |
1525 | ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) && | 1525 | ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) && |
1526 | (zr->frame_num & (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) { | 1526 | (zr->frame_num && (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) { |
1527 | error_handler(zr, astat, stat); | 1527 | error_handler(zr, astat, stat); |
1528 | } | 1528 | } |
1529 | 1529 | ||
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 67a52e844ae6..7c3921de9589 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c | |||
@@ -1528,323 +1528,6 @@ zoran_set_input (struct zoran *zr, | |||
1528 | * ioctl routine | 1528 | * ioctl routine |
1529 | */ | 1529 | */ |
1530 | 1530 | ||
1531 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1532 | static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) | ||
1533 | { | ||
1534 | struct zoran_fh *fh = __fh; | ||
1535 | struct zoran *zr = fh->zr; | ||
1536 | struct zoran_jpg_settings settings; | ||
1537 | |||
1538 | switch (cmd) { | ||
1539 | case BUZIOC_G_PARAMS: | ||
1540 | { | ||
1541 | struct zoran_params *bparams = arg; | ||
1542 | |||
1543 | dprintk(3, KERN_DEBUG "%s: BUZIOC_G_PARAMS\n", ZR_DEVNAME(zr)); | ||
1544 | |||
1545 | memset(bparams, 0, sizeof(struct zoran_params)); | ||
1546 | bparams->major_version = MAJOR_VERSION; | ||
1547 | bparams->minor_version = MINOR_VERSION; | ||
1548 | |||
1549 | mutex_lock(&zr->resource_lock); | ||
1550 | |||
1551 | if (zr->norm & V4L2_STD_NTSC) | ||
1552 | bparams->norm = ZORAN_VIDMODE_NTSC; | ||
1553 | else if (zr->norm & V4L2_STD_SECAM) | ||
1554 | bparams->norm = ZORAN_VIDMODE_SECAM; | ||
1555 | else | ||
1556 | bparams->norm = ZORAN_VIDMODE_PAL; | ||
1557 | |||
1558 | bparams->input = zr->input; | ||
1559 | |||
1560 | bparams->decimation = fh->jpg_settings.decimation; | ||
1561 | bparams->HorDcm = fh->jpg_settings.HorDcm; | ||
1562 | bparams->VerDcm = fh->jpg_settings.VerDcm; | ||
1563 | bparams->TmpDcm = fh->jpg_settings.TmpDcm; | ||
1564 | bparams->field_per_buff = fh->jpg_settings.field_per_buff; | ||
1565 | bparams->img_x = fh->jpg_settings.img_x; | ||
1566 | bparams->img_y = fh->jpg_settings.img_y; | ||
1567 | bparams->img_width = fh->jpg_settings.img_width; | ||
1568 | bparams->img_height = fh->jpg_settings.img_height; | ||
1569 | bparams->odd_even = fh->jpg_settings.odd_even; | ||
1570 | |||
1571 | bparams->quality = fh->jpg_settings.jpg_comp.quality; | ||
1572 | bparams->APPn = fh->jpg_settings.jpg_comp.APPn; | ||
1573 | bparams->APP_len = fh->jpg_settings.jpg_comp.APP_len; | ||
1574 | memcpy(bparams->APP_data, | ||
1575 | fh->jpg_settings.jpg_comp.APP_data, | ||
1576 | sizeof(bparams->APP_data)); | ||
1577 | bparams->COM_len = zr->jpg_settings.jpg_comp.COM_len; | ||
1578 | memcpy(bparams->COM_data, | ||
1579 | fh->jpg_settings.jpg_comp.COM_data, | ||
1580 | sizeof(bparams->COM_data)); | ||
1581 | bparams->jpeg_markers = | ||
1582 | fh->jpg_settings.jpg_comp.jpeg_markers; | ||
1583 | |||
1584 | mutex_unlock(&zr->resource_lock); | ||
1585 | |||
1586 | bparams->VFIFO_FB = 0; | ||
1587 | |||
1588 | return 0; | ||
1589 | } | ||
1590 | |||
1591 | case BUZIOC_S_PARAMS: | ||
1592 | { | ||
1593 | struct zoran_params *bparams = arg; | ||
1594 | int res = 0; | ||
1595 | |||
1596 | dprintk(3, KERN_DEBUG "%s: BUZIOC_S_PARAMS\n", ZR_DEVNAME(zr)); | ||
1597 | |||
1598 | settings.decimation = bparams->decimation; | ||
1599 | settings.HorDcm = bparams->HorDcm; | ||
1600 | settings.VerDcm = bparams->VerDcm; | ||
1601 | settings.TmpDcm = bparams->TmpDcm; | ||
1602 | settings.field_per_buff = bparams->field_per_buff; | ||
1603 | settings.img_x = bparams->img_x; | ||
1604 | settings.img_y = bparams->img_y; | ||
1605 | settings.img_width = bparams->img_width; | ||
1606 | settings.img_height = bparams->img_height; | ||
1607 | settings.odd_even = bparams->odd_even; | ||
1608 | |||
1609 | settings.jpg_comp.quality = bparams->quality; | ||
1610 | settings.jpg_comp.APPn = bparams->APPn; | ||
1611 | settings.jpg_comp.APP_len = bparams->APP_len; | ||
1612 | memcpy(settings.jpg_comp.APP_data, bparams->APP_data, | ||
1613 | sizeof(bparams->APP_data)); | ||
1614 | settings.jpg_comp.COM_len = bparams->COM_len; | ||
1615 | memcpy(settings.jpg_comp.COM_data, bparams->COM_data, | ||
1616 | sizeof(bparams->COM_data)); | ||
1617 | settings.jpg_comp.jpeg_markers = bparams->jpeg_markers; | ||
1618 | |||
1619 | mutex_lock(&zr->resource_lock); | ||
1620 | |||
1621 | if (zr->codec_mode != BUZ_MODE_IDLE) { | ||
1622 | dprintk(1, | ||
1623 | KERN_ERR | ||
1624 | "%s: BUZIOC_S_PARAMS called, but Buz in capture/playback mode\n", | ||
1625 | ZR_DEVNAME(zr)); | ||
1626 | res = -EINVAL; | ||
1627 | goto sparams_unlock_and_return; | ||
1628 | } | ||
1629 | |||
1630 | /* Check the params first before overwriting our | ||
1631 | * nternal values */ | ||
1632 | if (zoran_check_jpg_settings(zr, &settings, 0)) { | ||
1633 | res = -EINVAL; | ||
1634 | goto sparams_unlock_and_return; | ||
1635 | } | ||
1636 | |||
1637 | fh->jpg_settings = settings; | ||
1638 | sparams_unlock_and_return: | ||
1639 | mutex_unlock(&zr->resource_lock); | ||
1640 | |||
1641 | return res; | ||
1642 | } | ||
1643 | |||
1644 | case BUZIOC_REQBUFS: | ||
1645 | { | ||
1646 | struct zoran_requestbuffers *breq = arg; | ||
1647 | int res = 0; | ||
1648 | |||
1649 | dprintk(3, | ||
1650 | KERN_DEBUG | ||
1651 | "%s: BUZIOC_REQBUFS - count=%lu, size=%lu\n", | ||
1652 | ZR_DEVNAME(zr), breq->count, breq->size); | ||
1653 | |||
1654 | /* Enforce reasonable lower and upper limits */ | ||
1655 | if (breq->count < 4) | ||
1656 | breq->count = 4; /* Could be choosen smaller */ | ||
1657 | if (breq->count > jpg_nbufs) | ||
1658 | breq->count = jpg_nbufs; | ||
1659 | breq->size = PAGE_ALIGN(breq->size); | ||
1660 | if (breq->size < 8192) | ||
1661 | breq->size = 8192; /* Arbitrary */ | ||
1662 | /* breq->size is limited by 1 page for the stat_com | ||
1663 | * tables to a Maximum of 2 MB */ | ||
1664 | if (breq->size > jpg_bufsize) | ||
1665 | breq->size = jpg_bufsize; | ||
1666 | |||
1667 | mutex_lock(&zr->resource_lock); | ||
1668 | |||
1669 | if (fh->buffers.allocated) { | ||
1670 | dprintk(1, | ||
1671 | KERN_ERR | ||
1672 | "%s: BUZIOC_REQBUFS - buffers already allocated\n", | ||
1673 | ZR_DEVNAME(zr)); | ||
1674 | res = -EBUSY; | ||
1675 | goto jpgreqbuf_unlock_and_return; | ||
1676 | } | ||
1677 | |||
1678 | /* The next mmap will map the MJPEG buffers - could | ||
1679 | * also be *_PLAY, but it doesn't matter here */ | ||
1680 | map_mode_jpg(fh, 0); | ||
1681 | fh->buffers.num_buffers = breq->count; | ||
1682 | fh->buffers.buffer_size = breq->size; | ||
1683 | |||
1684 | if (jpg_fbuffer_alloc(fh)) { | ||
1685 | res = -ENOMEM; | ||
1686 | goto jpgreqbuf_unlock_and_return; | ||
1687 | } | ||
1688 | |||
1689 | jpgreqbuf_unlock_and_return: | ||
1690 | mutex_unlock(&zr->resource_lock); | ||
1691 | |||
1692 | return res; | ||
1693 | } | ||
1694 | |||
1695 | case BUZIOC_QBUF_CAPT: | ||
1696 | { | ||
1697 | int *frame = arg, res; | ||
1698 | |||
1699 | dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_CAPT - frame=%d\n", | ||
1700 | ZR_DEVNAME(zr), *frame); | ||
1701 | |||
1702 | mutex_lock(&zr->resource_lock); | ||
1703 | res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_COMPRESS); | ||
1704 | mutex_unlock(&zr->resource_lock); | ||
1705 | |||
1706 | return res; | ||
1707 | } | ||
1708 | |||
1709 | case BUZIOC_QBUF_PLAY: | ||
1710 | { | ||
1711 | int *frame = arg, res; | ||
1712 | |||
1713 | dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_PLAY - frame=%d\n", | ||
1714 | ZR_DEVNAME(zr), *frame); | ||
1715 | |||
1716 | mutex_lock(&zr->resource_lock); | ||
1717 | res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_DECOMPRESS); | ||
1718 | mutex_unlock(&zr->resource_lock); | ||
1719 | |||
1720 | return res; | ||
1721 | } | ||
1722 | |||
1723 | case BUZIOC_SYNC: | ||
1724 | { | ||
1725 | struct zoran_sync *bsync = arg; | ||
1726 | int res; | ||
1727 | |||
1728 | dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr)); | ||
1729 | |||
1730 | mutex_lock(&zr->resource_lock); | ||
1731 | |||
1732 | if (fh->map_mode == ZORAN_MAP_MODE_RAW) { | ||
1733 | dprintk(2, KERN_WARNING | ||
1734 | "%s: %s - not in jpg capture mode\n", | ||
1735 | ZR_DEVNAME(zr), __func__); | ||
1736 | res = -EINVAL; | ||
1737 | } else { | ||
1738 | res = jpg_sync(fh, bsync); | ||
1739 | } | ||
1740 | mutex_unlock(&zr->resource_lock); | ||
1741 | |||
1742 | return res; | ||
1743 | } | ||
1744 | |||
1745 | case BUZIOC_G_STATUS: | ||
1746 | { | ||
1747 | struct zoran_status *bstat = arg; | ||
1748 | int status = 0, res = 0; | ||
1749 | v4l2_std_id norm; | ||
1750 | |||
1751 | dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr)); | ||
1752 | |||
1753 | if (zr->codec_mode != BUZ_MODE_IDLE) { | ||
1754 | dprintk(1, | ||
1755 | KERN_ERR | ||
1756 | "%s: BUZIOC_G_STATUS called but Buz in capture/playback mode\n", | ||
1757 | ZR_DEVNAME(zr)); | ||
1758 | return -EINVAL; | ||
1759 | } | ||
1760 | |||
1761 | mutex_lock(&zr->resource_lock); | ||
1762 | |||
1763 | if (zr->codec_mode != BUZ_MODE_IDLE) { | ||
1764 | dprintk(1, | ||
1765 | KERN_ERR | ||
1766 | "%s: BUZIOC_G_STATUS called, but Buz in capture/playback mode\n", | ||
1767 | ZR_DEVNAME(zr)); | ||
1768 | res = -EINVAL; | ||
1769 | goto gstat_unlock_and_return; | ||
1770 | } | ||
1771 | |||
1772 | decoder_call(zr, video, s_routing, | ||
1773 | zr->card.input[bstat->input].muxsel, 0, 0); | ||
1774 | |||
1775 | /* sleep 1 second */ | ||
1776 | ssleep(1); | ||
1777 | |||
1778 | /* Get status of video decoder */ | ||
1779 | decoder_call(zr, video, querystd, &norm); | ||
1780 | decoder_call(zr, video, g_input_status, &status); | ||
1781 | |||
1782 | /* restore previous input and norm */ | ||
1783 | decoder_call(zr, video, s_routing, | ||
1784 | zr->card.input[zr->input].muxsel, 0, 0); | ||
1785 | gstat_unlock_and_return: | ||
1786 | mutex_unlock(&zr->resource_lock); | ||
1787 | |||
1788 | if (!res) { | ||
1789 | bstat->signal = | ||
1790 | (status & V4L2_IN_ST_NO_SIGNAL) ? 0 : 1; | ||
1791 | if (norm & V4L2_STD_NTSC) | ||
1792 | bstat->norm = ZORAN_VIDMODE_NTSC; | ||
1793 | else if (norm & V4L2_STD_SECAM) | ||
1794 | bstat->norm = ZORAN_VIDMODE_SECAM; | ||
1795 | else | ||
1796 | bstat->norm = ZORAN_VIDMODE_PAL; | ||
1797 | |||
1798 | bstat->color = | ||
1799 | (status & V4L2_IN_ST_NO_COLOR) ? 0 : 1; | ||
1800 | } | ||
1801 | |||
1802 | return res; | ||
1803 | } | ||
1804 | |||
1805 | default: | ||
1806 | return -EINVAL; | ||
1807 | } | ||
1808 | } | ||
1809 | |||
1810 | static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *vmbuf) | ||
1811 | { | ||
1812 | struct zoran_fh *fh = __fh; | ||
1813 | struct zoran *zr = fh->zr; | ||
1814 | int i, res = 0; | ||
1815 | |||
1816 | |||
1817 | mutex_lock(&zr->resource_lock); | ||
1818 | |||
1819 | if (fh->buffers.allocated) { | ||
1820 | dprintk(1, | ||
1821 | KERN_ERR | ||
1822 | "%s: VIDIOCGMBUF - buffers already allocated\n", | ||
1823 | ZR_DEVNAME(zr)); | ||
1824 | res = -EINVAL; | ||
1825 | goto v4l1reqbuf_unlock_and_return; | ||
1826 | } | ||
1827 | |||
1828 | /* The next mmap will map the V4L buffers */ | ||
1829 | map_mode_raw(fh); | ||
1830 | |||
1831 | if (v4l_fbuffer_alloc(fh)) { | ||
1832 | res = -ENOMEM; | ||
1833 | goto v4l1reqbuf_unlock_and_return; | ||
1834 | } | ||
1835 | |||
1836 | vmbuf->size = fh->buffers.num_buffers * fh->buffers.buffer_size; | ||
1837 | vmbuf->frames = fh->buffers.num_buffers; | ||
1838 | for (i = 0; i < vmbuf->frames; i++) | ||
1839 | vmbuf->offsets[i] = i * fh->buffers.buffer_size; | ||
1840 | |||
1841 | v4l1reqbuf_unlock_and_return: | ||
1842 | mutex_unlock(&zr->resource_lock); | ||
1843 | |||
1844 | return res; | ||
1845 | } | ||
1846 | #endif | ||
1847 | |||
1848 | static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap) | 1531 | static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap) |
1849 | { | 1532 | { |
1850 | struct zoran_fh *fh = __fh; | 1533 | struct zoran_fh *fh = __fh; |
@@ -2533,6 +2216,7 @@ static int zoran_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) | |||
2533 | res = -EAGAIN; | 2216 | res = -EAGAIN; |
2534 | goto dqbuf_unlock_and_return; | 2217 | goto dqbuf_unlock_and_return; |
2535 | } | 2218 | } |
2219 | bs.frame = 0; /* suppress compiler warning */ | ||
2536 | res = jpg_sync(fh, &bs); | 2220 | res = jpg_sync(fh, &bs); |
2537 | if (res) | 2221 | if (res) |
2538 | goto dqbuf_unlock_and_return; | 2222 | goto dqbuf_unlock_and_return; |
@@ -2766,11 +2450,6 @@ static int zoran_enum_input(struct file *file, void *__fh, | |||
2766 | 2450 | ||
2767 | if (inp->index >= zr->card.inputs) | 2451 | if (inp->index >= zr->card.inputs) |
2768 | return -EINVAL; | 2452 | return -EINVAL; |
2769 | else { | ||
2770 | int id = inp->index; | ||
2771 | memset(inp, 0, sizeof(*inp)); | ||
2772 | inp->index = id; | ||
2773 | } | ||
2774 | 2453 | ||
2775 | strncpy(inp->name, zr->card.input[inp->index].name, | 2454 | strncpy(inp->name, zr->card.input[inp->index].name, |
2776 | sizeof(inp->name) - 1); | 2455 | sizeof(inp->name) - 1); |
@@ -2820,7 +2499,6 @@ static int zoran_enum_output(struct file *file, void *__fh, | |||
2820 | if (outp->index != 0) | 2499 | if (outp->index != 0) |
2821 | return -EINVAL; | 2500 | return -EINVAL; |
2822 | 2501 | ||
2823 | memset(outp, 0, sizeof(*outp)); | ||
2824 | outp->index = 0; | 2502 | outp->index = 0; |
2825 | outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; | 2503 | outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; |
2826 | strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); | 2504 | strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); |
@@ -3364,10 +3042,6 @@ static const struct v4l2_ioctl_ops zoran_ioctl_ops = { | |||
3364 | .vidioc_queryctrl = zoran_queryctrl, | 3042 | .vidioc_queryctrl = zoran_queryctrl, |
3365 | .vidioc_s_ctrl = zoran_s_ctrl, | 3043 | .vidioc_s_ctrl = zoran_s_ctrl, |
3366 | .vidioc_g_ctrl = zoran_g_ctrl, | 3044 | .vidioc_g_ctrl = zoran_g_ctrl, |
3367 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
3368 | .vidioc_default = zoran_default, | ||
3369 | .vidiocgmbuf = zoran_vidiocgmbuf, | ||
3370 | #endif | ||
3371 | }; | 3045 | }; |
3372 | 3046 | ||
3373 | /* please use zr->resource_lock consistently and kill this wrapper */ | 3047 | /* please use zr->resource_lock consistently and kill this wrapper */ |