aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/media')
-rw-r--r--drivers/usb/media/Kconfig213
-rw-r--r--drivers/usb/media/Makefile17
-rw-r--r--drivers/usb/media/dabfirmware.h1408
-rw-r--r--drivers/usb/media/dabusb.c877
-rw-r--r--drivers/usb/media/dabusb.h85
-rw-r--r--drivers/usb/media/dsbr100.c429
-rw-r--r--drivers/usb/media/ibmcam.c3932
-rw-r--r--drivers/usb/media/konicawc.c947
-rw-r--r--drivers/usb/media/ov511.c6131
-rw-r--r--drivers/usb/media/ov511.h569
-rw-r--r--drivers/usb/media/pwc/ChangeLog143
-rw-r--r--drivers/usb/media/pwc/Makefile20
-rw-r--r--drivers/usb/media/pwc/philips.txt236
-rw-r--r--drivers/usb/media/pwc/pwc-ctrl.c1630
-rw-r--r--drivers/usb/media/pwc/pwc-dec1.c42
-rw-r--r--drivers/usb/media/pwc/pwc-dec1.h36
-rw-r--r--drivers/usb/media/pwc/pwc-dec23.c623
-rw-r--r--drivers/usb/media/pwc/pwc-dec23.h58
-rw-r--r--drivers/usb/media/pwc/pwc-if.c2212
-rw-r--r--drivers/usb/media/pwc/pwc-ioctl.h292
-rw-r--r--drivers/usb/media/pwc/pwc-kiara.c891
-rw-r--r--drivers/usb/media/pwc/pwc-kiara.h45
-rw-r--r--drivers/usb/media/pwc/pwc-misc.c140
-rw-r--r--drivers/usb/media/pwc/pwc-nala.h66
-rw-r--r--drivers/usb/media/pwc/pwc-timon.c1446
-rw-r--r--drivers/usb/media/pwc/pwc-timon.h61
-rw-r--r--drivers/usb/media/pwc/pwc-uncompress.c147
-rw-r--r--drivers/usb/media/pwc/pwc-uncompress.h41
-rw-r--r--drivers/usb/media/pwc/pwc.h278
-rw-r--r--drivers/usb/media/se401.c1436
-rw-r--r--drivers/usb/media/se401.h233
-rw-r--r--drivers/usb/media/sn9c102.h206
-rw-r--r--drivers/usb/media/sn9c102_core.c2744
-rw-r--r--drivers/usb/media/sn9c102_hv7131d.c271
-rw-r--r--drivers/usb/media/sn9c102_mi0343.c363
-rw-r--r--drivers/usb/media/sn9c102_pas106b.c307
-rw-r--r--drivers/usb/media/sn9c102_pas202bcb.c293
-rw-r--r--drivers/usb/media/sn9c102_sensor.h373
-rw-r--r--drivers/usb/media/sn9c102_tas5110c1b.c174
-rw-r--r--drivers/usb/media/sn9c102_tas5130d1b.c188
-rw-r--r--drivers/usb/media/stv680.c1506
-rw-r--r--drivers/usb/media/stv680.h222
-rw-r--r--drivers/usb/media/ultracam.c679
-rw-r--r--drivers/usb/media/usbvideo.c2192
-rw-r--r--drivers/usb/media/usbvideo.h393
-rw-r--r--drivers/usb/media/vicam.c1409
-rw-r--r--drivers/usb/media/w9968cf.c3822
-rw-r--r--drivers/usb/media/w9968cf.h339
-rw-r--r--drivers/usb/media/w9968cf_decoder.h86
-rw-r--r--drivers/usb/media/w9968cf_vpp.h43
50 files changed, 40294 insertions, 0 deletions
diff --git a/drivers/usb/media/Kconfig b/drivers/usb/media/Kconfig
new file mode 100644
index 000000000000..21232ee2974c
--- /dev/null
+++ b/drivers/usb/media/Kconfig
@@ -0,0 +1,213 @@
1#
2# USB Multimedia device configuration
3#
4comment "USB Multimedia devices"
5 depends on USB
6
7config USB_DABUSB
8 tristate "DABUSB driver"
9 depends on USB
10 ---help---
11 A Digital Audio Broadcasting (DAB) Receiver for USB and Linux
12 brought to you by the DAB-Team
13 <http://wwwbode.cs.tum.edu/Par/arch/dab/>. This driver can be taken
14 as an example for URB-based bulk, control, and isochronous
15 transactions. URB's are explained in
16 <file:Documentation/usb/URB.txt>.
17
18 To compile this driver as a module, choose M here: the
19 module will be called dabusb.
20
21comment "Video4Linux support is needed for USB Multimedia device support"
22 depends on USB && VIDEO_DEV=n
23
24config USB_VICAM
25 tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)"
26 depends on USB && VIDEO_DEV && EXPERIMENTAL
27 ---help---
28 Say Y here if you have 3com homeconnect camera (vicam).
29
30 This driver uses the Video For Linux API. You must say Y or M to
31 "Video For Linux" (under Multimedia Devices) to use this driver.
32 Information on this API and pointers to "v4l" programs may be found
33 at <file:Documentation/video4linux/API.html>.
34
35 To compile this driver as a module, choose M here: the
36 module will be called vicam.
37
38config USB_DSBR
39 tristate "D-Link USB FM radio support (EXPERIMENTAL)"
40 depends on USB && VIDEO_DEV && EXPERIMENTAL
41 ---help---
42 Say Y here if you want to connect this type of radio to your
43 computer's USB port. Note that the audio is not digital, and
44 you must connect the line out connector to a sound card or a
45 set of speakers.
46
47 This driver uses the Video For Linux API. You must enable
48 (Y or M in config) Video For Linux (under Character Devices)
49 to use this driver. Information on this API and pointers to
50 "v4l" programs may be found at
51 <file:Documentation/video4linux/API.html>.
52
53 To compile this driver as a module, choose M here: the
54 module will be called dsbr100.
55
56config USB_IBMCAM
57 tristate "USB IBM (Xirlink) C-it Camera support"
58 depends on USB && VIDEO_DEV
59 ---help---
60 Say Y here if you want to connect a IBM "C-It" camera, also known as
61 "Xirlink PC Camera" to your computer's USB port. For more
62 information, read <file:Documentation/usb/ibmcam.txt>.
63
64 This driver uses the Video For Linux API. You must enable
65 (Y or M in config) Video For Linux (under Character Devices)
66 to use this driver. Information on this API and pointers to
67 "v4l" programs may be found at
68 <file:Documentation/video4linux/API.html>.
69
70 To compile this driver as a module, choose M here: the
71 module will be called ibmcam.
72
73 This camera has several configuration options which
74 can be specified when you load the module. Read
75 <file:Documentation/usb/ibmcam.txt> to learn more.
76
77config USB_KONICAWC
78 tristate "USB Konica Webcam support"
79 depends on USB && VIDEO_DEV
80 ---help---
81 Say Y here if you want support for webcams based on a Konica
82 chipset. This is known to work with the Intel YC76 webcam.
83
84 This driver uses the Video For Linux API. You must enable
85 (Y or M in config) Video For Linux (under Character Devices)
86 to use this driver. Information on this API and pointers to
87 "v4l" programs may be found at
88 <file:Documentation/video4linux/API.html>.
89
90 To compile this driver as a module, choose M here: the
91 module will be called konicawc.
92
93config USB_OV511
94 tristate "USB OV511 Camera support"
95 depends on USB && VIDEO_DEV
96 ---help---
97 Say Y here if you want to connect this type of camera to your
98 computer's USB port. See <file:Documentation/usb/ov511.txt> for more
99 information and for a list of supported cameras.
100
101 This driver uses the Video For Linux API. You must say Y or M to
102 "Video For Linux" (under Character Devices) to use this driver.
103 Information on this API and pointers to "v4l" programs may be found
104 at <file:Documentation/video4linux/API.html>.
105
106 To compile this driver as a module, choose M here: the
107 module will be called ov511.
108
109config USB_SE401
110 tristate "USB SE401 Camera support"
111 depends on USB && VIDEO_DEV
112 ---help---
113 Say Y here if you want to connect this type of camera to your
114 computer's USB port. See <file:Documentation/usb/se401.txt> for more
115 information and for a list of supported cameras.
116
117 This driver uses the Video For Linux API. You must say Y or M to
118 "Video For Linux" (under Multimedia Devices) to use this driver.
119 Information on this API and pointers to "v4l" programs may be found
120 at <file:Documentation/video4linux/API.html>.
121
122 To compile this driver as a module, choose M here: the
123 module will be called se401.
124
125config USB_SN9C102
126 tristate "USB SN9C10x PC Camera Controller support"
127 depends on USB && VIDEO_DEV
128 ---help---
129 Say Y here if you want support for cameras based on SONiX SN9C101,
130 SN9C102 or SN9C103 PC Camera Controllers.
131
132 See <file:Documentation/usb/sn9c102.txt> for more informations.
133
134 This driver uses the Video For Linux API. You must say Y or M to
135 "Video For Linux" to use this driver.
136
137 To compile this driver as a module, choose M here: the
138 module will be called sn9c102.
139
140config USB_STV680
141 tristate "USB STV680 (Pencam) Camera support"
142 depends on USB && VIDEO_DEV
143 ---help---
144 Say Y here if you want to connect this type of camera to your
145 computer's USB port. This includes the Pencam line of cameras.
146 See <file:Documentation/usb/stv680.txt> for more information and for
147 a list of supported cameras.
148
149 This driver uses the Video For Linux API. You must say Y or M to
150 "Video For Linux" (under Multimedia Devices) to use this driver.
151 Information on this API and pointers to "v4l" programs may be found
152 at <file:Documentation/video4linux/API.html>.
153
154 To compile this driver as a module, choose M here: the
155 module will be called stv680.
156
157config USB_W9968CF
158 tristate "USB W996[87]CF JPEG Dual Mode Camera support"
159 depends on USB && VIDEO_DEV && I2C && VIDEO_OVCAMCHIP
160 ---help---
161 Say Y here if you want support for cameras based on OV681 or
162 Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
163
164 This driver has an optional plugin, which is distributed as a
165 separate module only (released under GPL). It allows to use higher
166 resolutions and framerates, but cannot be included in the official
167 Linux kernel for performance purposes.
168
169 See <file:Documentation/usb/w9968cf.txt> for more informations.
170
171 This driver uses the Video For Linux and the I2C APIs. It needs the
172 OmniVision Camera Chip support as well. You must say Y or M to
173 "Video For Linux", "I2C Support" and "OmniVision Camera Chip
174 support" to use this driver.
175
176 To compile this driver as a module, choose M here: the
177 module will be called w9968cf.
178
179config USB_PWC
180 tristate "USB Philips Cameras"
181 depends on USB && VIDEO_DEV
182 ---help---
183 Say Y or M here if you want to use one of these Philips & OEM
184 webcams:
185 * Philips PCA645, PCA646
186 * Philips PCVC675, PCVC680, PCVC690
187 * Philips PCVC720/40, PCVC730, PCVC740, PCVC750
188 * Askey VC010
189 * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro'
190 and 'Orbit'/'Sphere'
191 * Samsung MPC-C10, MPC-C30
192 * Creative Webcam 5, Pro Ex
193 * SOTEC Afina Eye
194 * Visionite VCS-UC300, VCS-UM100
195
196 The PCA635, PCVC665 and PCVC720/20 are not supported by this driver
197 and never will be, but the 665 and 720/20 are supported by other
198 drivers.
199
200 See <file:Documentation/usb/philips.txt> for more information and
201 installation instructions.
202
203 The built-in microphone is enabled by selecting USB Audio support.
204
205 This driver uses the Video For Linux API. You must say Y or M to
206 "Video For Linux" (under Character Devices) to use this driver.
207 Information on this API and pointers to "v4l" programs may be found
208 at <file:Documentation/video4linux/API.html>.
209
210 To compile this driver as a module, choose M here: the
211 module will be called pwc.
212
213
diff --git a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile
new file mode 100644
index 000000000000..2b76df7005fe
--- /dev/null
+++ b/drivers/usb/media/Makefile
@@ -0,0 +1,17 @@
1#
2# Makefile for USB Media drivers
3#
4
5sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o
6
7obj-$(CONFIG_USB_DABUSB) += dabusb.o
8obj-$(CONFIG_USB_DSBR) += dsbr100.o
9obj-$(CONFIG_USB_IBMCAM) += ibmcam.o usbvideo.o ultracam.o
10obj-$(CONFIG_USB_KONICAWC) += konicawc.o usbvideo.o
11obj-$(CONFIG_USB_OV511) += ov511.o
12obj-$(CONFIG_USB_SE401) += se401.o
13obj-$(CONFIG_USB_SN9C102) += sn9c102.o
14obj-$(CONFIG_USB_STV680) += stv680.o
15obj-$(CONFIG_USB_VICAM) += vicam.o usbvideo.o
16obj-$(CONFIG_USB_W9968CF) += w9968cf.o
17obj-$(CONFIG_USB_PWC) += pwc/
diff --git a/drivers/usb/media/dabfirmware.h b/drivers/usb/media/dabfirmware.h
new file mode 100644
index 000000000000..d14d803566a3
--- /dev/null
+++ b/drivers/usb/media/dabfirmware.h
@@ -0,0 +1,1408 @@
1/*
2 * dabdata.h - dab usb firmware and bitstream data
3 */
4
5static INTEL_HEX_RECORD firmware[] = {
6
7{ 2, 0x0000, 0, {0x21,0x57} },
8{ 3, 0x0003, 0, {0x02,0x01,0x66} },
9{ 3, 0x000b, 0, {0x02,0x01,0x66} },
10{ 3, 0x0013, 0, {0x02,0x01,0x66} },
11{ 3, 0x001b, 0, {0x02,0x01,0x66} },
12{ 3, 0x0023, 0, {0x02,0x01,0x66} },
13{ 3, 0x002b, 0, {0x02,0x01,0x66} },
14{ 3, 0x0033, 0, {0x02,0x03,0x0f} },
15{ 3, 0x003b, 0, {0x02,0x01,0x66} },
16{ 3, 0x0043, 0, {0x02,0x01,0x00} },
17{ 3, 0x004b, 0, {0x02,0x01,0x66} },
18{ 3, 0x0053, 0, {0x02,0x01,0x66} },
19{ 3, 0x005b, 0, {0x02,0x04,0xbd} },
20{ 3, 0x0063, 0, {0x02,0x01,0x67} },
21{ 3, 0x0100, 0, {0x02,0x0c,0x5a} },
22{ 3, 0x0104, 0, {0x02,0x01,0xed} },
23{ 3, 0x0108, 0, {0x02,0x02,0x51} },
24{ 3, 0x010c, 0, {0x02,0x02,0x7c} },
25{ 3, 0x0110, 0, {0x02,0x02,0xe4} },
26{ 1, 0x0114, 0, {0x32} },
27{ 1, 0x0118, 0, {0x32} },
28{ 3, 0x011c, 0, {0x02,0x05,0xfd} },
29{ 3, 0x0120, 0, {0x02,0x00,0x00} },
30{ 3, 0x0124, 0, {0x02,0x00,0x00} },
31{ 3, 0x0128, 0, {0x02,0x04,0x3c} },
32{ 3, 0x012c, 0, {0x02,0x04,0x6a} },
33{ 3, 0x0130, 0, {0x02,0x00,0x00} },
34{ 3, 0x0134, 0, {0x02,0x00,0x00} },
35{ 3, 0x0138, 0, {0x02,0x00,0x00} },
36{ 3, 0x013c, 0, {0x02,0x00,0x00} },
37{ 3, 0x0140, 0, {0x02,0x00,0x00} },
38{ 3, 0x0144, 0, {0x02,0x00,0x00} },
39{ 3, 0x0148, 0, {0x02,0x00,0x00} },
40{ 3, 0x014c, 0, {0x02,0x00,0x00} },
41{ 3, 0x0150, 0, {0x02,0x00,0x00} },
42{ 3, 0x0154, 0, {0x02,0x00,0x00} },
43{ 10, 0x0157, 0, {0x75,0x81,0x7f,0xe5,0x82,0x60,0x03,0x02,0x01,0x61} },
44{ 5, 0x0161, 0, {0x12,0x07,0x6f,0x21,0x64} },
45{ 1, 0x0166, 0, {0x32} },
46{ 14, 0x0167, 0, {0xc0,0xd0,0xc0,0x86,0xc0,0x82,0xc0,0x83,0xc0,0xe0,0x90,0x7f,0x97,0xe0} },
47{ 14, 0x0175, 0, {0x44,0x80,0xf0,0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} },
48{ 14, 0x0183, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} },
49{ 14, 0x0191, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x90,0x7f,0x97,0xe0} },
50{ 3, 0x019f, 0, {0x55,0x7f,0xf0} },
51{ 14, 0x01a2, 0, {0x90,0x7f,0x9a,0xe0,0x30,0xe4,0x23,0x90,0x7f,0x68,0xf0,0xf0,0xf0,0xf0} },
52{ 14, 0x01b0, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} },
53{ 14, 0x01be, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} },
54{ 14, 0x01cc, 0, {0xe5,0xd8,0xc2,0xe3,0xf5,0xd8,0xd0,0xe0,0xd0,0x83,0xd0,0x82,0xd0,0x86} },
55{ 3, 0x01da, 0, {0xd0,0xd0,0x32} },
56{ 8, 0x01dd, 0, {0x75,0x86,0x00,0x90,0xff,0xc3,0x7c,0x05} },
57{ 7, 0x01e5, 0, {0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9} },
58{ 1, 0x01ec, 0, {0x22} },
59{ 14, 0x01ed, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0xd0} },
60{ 14, 0x01fb, 0, {0x75,0xd0,0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91} },
61{ 13, 0x0209, 0, {0x90,0x88,0x00,0xe0,0xf5,0x41,0x90,0x7f,0xab,0x74,0x02,0xf0,0x90} },
62{ 9, 0x0216, 0, {0x7f,0xab,0x74,0x02,0xf0,0xe5,0x32,0x60,0x21} },
63{ 4, 0x021f, 0, {0x7a,0x00,0x7b,0x00} },
64{ 11, 0x0223, 0, {0xc3,0xea,0x94,0x18,0xeb,0x64,0x80,0x94,0x80,0x50,0x12} },
65{ 14, 0x022e, 0, {0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x0a,0xba,0x00} },
66{ 2, 0x023c, 0, {0x01,0x0b} },
67{ 2, 0x023e, 0, {0x80,0xe3} },
68{ 2, 0x0240, 0, {0xd0,0x86} },
69{ 14, 0x0242, 0, {0xd0,0xd0,0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0} },
70{ 1, 0x0250, 0, {0x32} },
71{ 14, 0x0251, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
72{ 14, 0x025f, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74} },
73{ 4, 0x026d, 0, {0x04,0xf0,0xd0,0x86} },
74{ 11, 0x0271, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
75{ 14, 0x027c, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} },
76{ 14, 0x028a, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} },
77{ 13, 0x0298, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} },
78{ 12, 0x02a5, 0, {0x7f,0xab,0x74,0x08,0xf0,0x75,0x6e,0x00,0x75,0x6f,0x02,0x12} },
79{ 6, 0x02b1, 0, {0x11,0x44,0x75,0x70,0x39,0x75} },
80{ 6, 0x02b7, 0, {0x71,0x0c,0x75,0x72,0x02,0x12} },
81{ 12, 0x02bd, 0, {0x11,0x75,0x90,0x7f,0xd6,0xe4,0xf0,0x75,0xd8,0x20,0xd0,0x86} },
82{ 14, 0x02c9, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} },
83{ 13, 0x02d7, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
84{ 14, 0x02e4, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
85{ 14, 0x02f2, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74} },
86{ 4, 0x0300, 0, {0x10,0xf0,0xd0,0x86} },
87{ 11, 0x0304, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
88{ 14, 0x030f, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} },
89{ 14, 0x031d, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} },
90{ 12, 0x032b, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0x75,0x6e,0x00,0x75,0x6f,0x02} },
91{ 7, 0x0337, 0, {0x12,0x11,0x44,0x75,0x70,0x40,0x75} },
92{ 6, 0x033e, 0, {0x71,0x0c,0x75,0x72,0x02,0x12} },
93{ 14, 0x0344, 0, {0x11,0x75,0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0} },
94{ 5, 0x0352, 0, {0x75,0xd8,0x10,0xd0,0x86} },
95{ 14, 0x0357, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} },
96{ 13, 0x0365, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
97{ 13, 0x0372, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12} },
98{ 12, 0x037f, 0, {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x42,0xf0,0x12,0x10,0x1b,0x90} },
99{ 13, 0x038b, 0, {0x7f,0xa6,0xe5,0x43,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40} },
100{ 1, 0x0398, 0, {0xf0} },
101{ 1, 0x0399, 0, {0x22} },
102{ 13, 0x039a, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12} },
103{ 12, 0x03a7, 0, {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x44,0xf0,0x12,0x10,0x1b,0x90} },
104{ 12, 0x03b3, 0, {0x7f,0xa6,0xe5,0x45,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0xe5} },
105{ 11, 0x03bf, 0, {0x46,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40,0xf0} },
106{ 1, 0x03ca, 0, {0x22} },
107{ 10, 0x03cb, 0, {0x75,0x44,0x02,0x75,0x45,0x00,0x75,0x46,0x00,0x12} },
108{ 9, 0x03d5, 0, {0x03,0x9a,0x75,0x42,0x03,0x75,0x43,0x00,0x12} },
109{ 2, 0x03de, 0, {0x03,0x72} },
110{ 1, 0x03e0, 0, {0x22} },
111{ 12, 0x03e1, 0, {0x90,0x88,0x00,0xe5,0x36,0xf0,0x90,0x88,0x00,0x74,0x10,0x25} },
112{ 9, 0x03ed, 0, {0x36,0xf0,0x12,0x01,0xdd,0x75,0x42,0x01,0x75} },
113{ 9, 0x03f6, 0, {0x43,0x18,0x12,0x03,0x72,0x75,0x44,0x02,0x75} },
114{ 9, 0x03ff, 0,{0x45,0x00,0x75,0x46,0x00,0x12,0x03,0x9a,0x75} },
115{ 8, 0x0408, 0,{0x42,0x03,0x75,0x43,0x44,0x12,0x03,0x72} },
116{ 1, 0x0410, 0,{0x22} },
117{ 14, 0x0411, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
118{ 14, 0x041f, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74} },
119{ 4, 0x042d, 0, {0x02,0xf0,0xd0,0x86} },
120{ 11, 0x0431, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
121{ 14, 0x043c, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
122{ 14, 0x044a, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xa9,0x74} },
123{ 7, 0x0458, 0, {0x04,0xf0,0x75,0x30,0x01,0xd0,0x86} },
124{ 11, 0x045f, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
125{ 14, 0x046a, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
126{ 14, 0x0478, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74} },
127{ 7, 0x0486, 0, {0x04,0xf0,0x75,0x31,0x01,0xd0,0x86} },
128{ 11, 0x048d, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
129{ 14, 0x0498, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
130{ 12, 0x04a6, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe5,0xf5,0x91,0xd0,0x86} },
131{ 11, 0x04b2, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
132{ 14, 0x04bd, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
133{ 12, 0x04cb, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe7,0xf5,0x91,0xd0,0x86} },
134{ 11, 0x04d7, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
135{ 12, 0x04e2, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x20,0x90,0x7f,0x96,0xe4,0xf0} },
136{ 1, 0x04ee, 0, {0x22} },
137{ 7, 0x04ef, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x21} },
138{ 1, 0x04f6, 0, {0x22} },
139{ 14, 0x04f7, 0, {0x90,0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xe0,0xfb,0x74,0x80,0x2a,0xfa} },
140{ 14, 0x0505, 0, {0x74,0x80,0x2b,0xfb,0xea,0x03,0x03,0x54,0x3f,0xfc,0xea,0xc4,0x23,0x54} },
141{ 14, 0x0513, 0, {0x1f,0xfa,0x2c,0xfa,0xeb,0x03,0x03,0x54,0x3f,0xfc,0xeb,0xc4,0x23,0x54} },
142{ 11, 0x0521, 0, {0x1f,0xfb,0x2c,0xfb,0x90,0x17,0x0a,0xe0,0xfc,0x60,0x02} },
143{ 2, 0x052c, 0, {0x7a,0x00} },
144{ 7, 0x052e, 0, {0x90,0x17,0x0c,0xe0,0xfc,0x60,0x02} },
145{ 2, 0x0535, 0, {0x7b,0x00} },
146{ 11, 0x0537, 0, {0xea,0x2b,0xfc,0xc3,0x13,0xf5,0x3a,0x75,0x44,0x02,0x8b} },
147{ 7, 0x0542, 0, {0x45,0x8a,0x46,0x12,0x03,0x9a,0x75} },
148{ 9, 0x0549, 0, {0x6e,0x08,0x75,0x6f,0x00,0x12,0x11,0x44,0x75} },
149{ 4, 0x0552, 0, {0x70,0x47,0x75,0x71} },
150{ 8, 0x0556, 0, {0x0c,0x75,0x72,0x02,0x12,0x11,0x75,0x85} },
151{ 5, 0x055e, 0, {0x3a,0x73,0x12,0x11,0xa0} },
152{ 1, 0x0563, 0, {0x22} },
153{ 14, 0x0564, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90} },
154{ 14, 0x0572, 0, {0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xef,0xe0,0xfc} },
155{ 14, 0x0580, 0, {0x33,0x95,0xe0,0xfd,0x8c,0x05,0x7c,0x00,0x90,0x7f,0xee,0xe0,0xfe,0x33} },
156{ 14, 0x058e, 0, {0x95,0xe0,0xff,0xec,0x2e,0xfc,0xed,0x3f,0xfd,0x90,0x7f,0xe9,0xe0,0xfe} },
157{ 5, 0x059c, 0, {0xbe,0x01,0x02,0x80,0x03} },
158{ 3, 0x05a1, 0, {0x02,0x05,0xf9} },
159{ 6, 0x05a4, 0, {0xbc,0x01,0x21,0xbd,0x00,0x1e} },
160{ 14, 0x05aa, 0, {0xea,0xc4,0x03,0x54,0xf8,0xfc,0xeb,0x25,0xe0,0xfd,0x2c,0x24,0x00,0xfc} },
161{ 14, 0x05b8, 0, {0xe4,0x34,0x17,0xfd,0x90,0x7e,0xc0,0xe0,0xfe,0x8c,0x82,0x8d,0x83,0xf0} },
162{ 2, 0x05c6, 0, {0x80,0x31} },
163{ 14, 0x05c8, 0, {0xea,0xc4,0x03,0x54,0xf8,0xfa,0xeb,0x25,0xe0,0xfb,0x2a,0xfa,0x24,0x00} },
164{ 14, 0x05d6, 0, {0xfb,0xe4,0x34,0x17,0xfc,0x90,0x7e,0xc0,0xe0,0xfd,0x8b,0x82,0x8c,0x83} },
165{ 14, 0x05e4, 0, {0xf0,0x74,0x01,0x2a,0x24,0x00,0xfa,0xe4,0x34,0x17,0xfb,0x90,0x7e,0xc1} },
166{ 7, 0x05f2, 0, {0xe0,0xfc,0x8a,0x82,0x8b,0x83,0xf0} },
167{ 3, 0x05f9, 0, {0x75,0x38,0x01} },
168{ 1, 0x05fc, 0, {0x22} },
169{ 14, 0x05fd, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} },
170{ 14, 0x060b, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} },
171{ 13, 0x0619, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} },
172{ 13, 0x0626, 0, {0x7f,0xaa,0x74,0x01,0xf0,0x12,0x05,0x64,0x75,0x37,0x00,0xd0,0x86} },
173{ 14, 0x0633, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} },
174{ 13, 0x0641, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
175{ 14, 0x064e, 0, {0x90,0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xee,0xe0} },
176{ 14, 0x065c, 0, {0xfc,0x33,0x95,0xe0,0xfd,0x90,0x7f,0x96,0xe0,0xfe,0x90,0x7f,0x96,0x74} },
177{ 14, 0x066a, 0, {0x80,0x65,0x06,0xf0,0x90,0x7f,0x00,0x74,0x01,0xf0,0xea,0xc4,0x03,0x54} },
178{ 14, 0x0678, 0, {0xf8,0xfe,0xeb,0x25,0xe0,0xfb,0x2e,0xfe,0x24,0x00,0xfb,0xe4,0x34,0x17} },
179{ 14, 0x0686, 0, {0xff,0x8b,0x82,0x8f,0x83,0xe0,0xfb,0x74,0x01,0x2e,0x24,0x00,0xfe,0xe4} },
180{ 14, 0x0694, 0, {0x34,0x17,0xff,0x8e,0x82,0x8f,0x83,0xe0,0xfe,0x90,0x7f,0xe9,0xe0,0xff} },
181{ 3, 0x06a2, 0, {0xbf,0x81,0x0a} },
182{ 10, 0x06a5, 0, {0x90,0x7f,0x00,0xeb,0xf0,0x90,0x7f,0x01,0xee,0xf0} },
183{ 8, 0x06af, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x82,0x1a} },
184{ 3, 0x06b7, 0, {0xba,0x01,0x0c} },
185{ 12, 0x06ba, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b} },
186{ 11, 0x06c6, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0xb5,0xf0} },
187{ 8, 0x06d1, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x83,0x1b} },
188{ 3, 0x06d9, 0, {0xba,0x01,0x0d} },
189{ 13, 0x06dc, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b} },
190{ 11, 0x06e9, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0x12,0xf0} },
191{ 8, 0x06f4, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x84,0x1c} },
192{ 3, 0x06fc, 0, {0xba,0x01,0x0d} },
193{ 13, 0x06ff, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0c} },
194{ 12, 0x070c, 0, {0x90,0x7f,0x00,0x74,0x80,0xf0,0x90,0x7f,0x01,0x74,0x01,0xf0} },
195{ 5, 0x0718, 0, {0x90,0x7f,0xb5,0xec,0xf0} },
196{ 1, 0x071d, 0, {0x22} },
197{ 12, 0x071e, 0, {0x75,0x36,0x0d,0x90,0x88,0x00,0x74,0x1d,0xf0,0x75,0x6b,0x80} },
198{ 10, 0x072a, 0, {0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} },
199{ 9, 0x0734, 0, {0x6c,0x0f,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} },
200{ 9, 0x073d, 0, {0x6c,0x06,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} },
201{ 7, 0x0746, 0, {0x6c,0x01,0x12,0x10,0xe2,0x7a,0x00} },
202{ 3, 0x074d, 0, {0xba,0xff,0x00} },
203{ 2, 0x0750, 0, {0x50,0x0a} },
204{ 10, 0x0752, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1} },
205{ 10, 0x075c, 0, {0x75,0x6b,0x80,0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75} },
206{ 8, 0x0766, 0, {0x6b,0x80,0x75,0x6c,0x0f,0x12,0x10,0xe2} },
207{ 1, 0x076e, 0, {0x22} },
208{ 14, 0x076f, 0, {0x90,0x7f,0xa1,0xe4,0xf0,0x90,0x7f,0xaf,0x74,0x01,0xf0,0x90,0x7f,0x92} },
209{ 14, 0x077d, 0, {0x74,0x02,0xf0,0x75,0x8e,0x31,0x75,0x89,0x21,0x75,0x88,0x00,0x75,0xc8} },
210{ 14, 0x078b, 0, {0x00,0x75,0x8d,0x40,0x75,0x98,0x40,0x75,0xc0,0x40,0x75,0x87,0x00,0x75} },
211{ 9, 0x0799, 0, {0x20,0x00,0x75,0x21,0x00,0x75,0x22,0x00,0x75} },
212{ 5, 0x07a2, 0, {0x23,0x00,0x75,0x47,0x00} },
213{ 7, 0x07a7, 0, {0xc3,0xe5,0x47,0x94,0x20,0x50,0x11} },
214{ 13, 0x07ae, 0, {0xe5,0x47,0x24,0x00,0xf5,0x82,0xe4,0x34,0x17,0xf5,0x83,0xe4,0xf0} },
215{ 4, 0x07bb, 0, {0x05,0x47,0x80,0xe8} },
216{ 9, 0x07bf, 0, {0xe4,0xf5,0x40,0xf5,0x3f,0xe4,0xf5,0x3c,0xf5} },
217{ 7, 0x07c8, 0, {0x3b,0xe4,0xf5,0x3e,0xf5,0x3d,0x75} },
218{ 11, 0x07cf, 0, {0x32,0x00,0x75,0x37,0x00,0x75,0x39,0x00,0x90,0x7f,0x93} },
219{ 14, 0x07da, 0, {0x74,0x3c,0xf0,0x90,0x7f,0x9c,0x74,0xff,0xf0,0x90,0x7f,0x96,0x74,0x80} },
220{ 14, 0x07e8, 0, {0xf0,0x90,0x7f,0x94,0x74,0x70,0xf0,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90} },
221{ 14, 0x07f6, 0, {0x7f,0x97,0xe4,0xf0,0x90,0x7f,0x95,0x74,0xc2,0xf0,0x90,0x7f,0x98,0x74} },
222{ 14, 0x0804, 0, {0x28,0xf0,0x90,0x7f,0x9e,0x74,0x28,0xf0,0x90,0x7f,0xf0,0xe4,0xf0,0x90} },
223{ 14, 0x0812, 0, {0x7f,0xf1,0xe4,0xf0,0x90,0x7f,0xf2,0xe4,0xf0,0x90,0x7f,0xf3,0xe4,0xf0} },
224{ 14, 0x0820, 0, {0x90,0x7f,0xf4,0xe4,0xf0,0x90,0x7f,0xf5,0xe4,0xf0,0x90,0x7f,0xf6,0xe4} },
225{ 14, 0x082e, 0, {0xf0,0x90,0x7f,0xf7,0xe4,0xf0,0x90,0x7f,0xf8,0xe4,0xf0,0x90,0x7f,0xf9} },
226{ 14, 0x083c, 0, {0x74,0x38,0xf0,0x90,0x7f,0xfa,0x74,0xa0,0xf0,0x90,0x7f,0xfb,0x74,0xa0} },
227{ 14, 0x084a, 0, {0xf0,0x90,0x7f,0xfc,0x74,0xa0,0xf0,0x90,0x7f,0xfd,0x74,0xa0,0xf0,0x90} },
228{ 14, 0x0858, 0, {0x7f,0xfe,0x74,0xa0,0xf0,0x90,0x7f,0xff,0x74,0xa0,0xf0,0x90,0x7f,0xe0} },
229{ 14, 0x0866, 0, {0x74,0x03,0xf0,0x90,0x7f,0xe1,0x74,0x01,0xf0,0x90,0x7f,0xdd,0x74,0x80} },
230{ 11, 0x0874, 0, {0xf0,0x12,0x12,0x43,0x12,0x07,0x1e,0x7a,0x00,0x7b,0x00} },
231{ 9, 0x087f, 0, {0xc3,0xea,0x94,0x1e,0xeb,0x94,0x00,0x50,0x17} },
232{ 12, 0x0888, 0, {0x90,0x88,0x00,0xe0,0xf5,0x47,0x90,0x88,0x0b,0xe0,0xf5,0x47} },
233{ 9, 0x0894, 0, {0x90,0x7f,0x68,0xf0,0x0a,0xba,0x00,0x01,0x0b} },
234{ 2, 0x089d, 0, {0x80,0xe0} },
235{ 12, 0x089f, 0, {0x12,0x03,0xe1,0x90,0x7f,0xd6,0xe4,0xf0,0x7a,0x00,0x7b,0x00} },
236{ 13, 0x08ab, 0, {0x8a,0x04,0x8b,0x05,0xc3,0xea,0x94,0xe0,0xeb,0x94,0x2e,0x50,0x1a} },
237{ 14, 0x08b8, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} },
238{ 10, 0x08c6, 0, {0x04,0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b} },
239{ 2, 0x08d0, 0, {0x80,0xd9} },
240{ 13, 0x08d2, 0, {0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0,0x90} },
241{ 14, 0x08df, 0, {0x7f,0xde,0x74,0x05,0xf0,0x90,0x7f,0xdf,0x74,0x05,0xf0,0x90,0x7f,0xac} },
242{ 14, 0x08ed, 0, {0xe4,0xf0,0x90,0x7f,0xad,0x74,0x05,0xf0,0x75,0xa8,0x80,0x75,0xf8,0x10} },
243{ 13, 0x08fb, 0, {0x90,0x7f,0xae,0x74,0x0b,0xf0,0x90,0x7f,0xe2,0x74,0x88,0xf0,0x90} },
244{ 12, 0x0908, 0, {0x7f,0xab,0x74,0x08,0xf0,0x75,0xe8,0x11,0x75,0x32,0x01,0x75} },
245{ 12, 0x0914, 0, {0x31,0x00,0x75,0x30,0x00,0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7} },
246{ 10, 0x0920, 0, {0xd0,0x05,0xd0,0x04,0x75,0x34,0x00,0x75,0x35,0x01} },
247{ 13, 0x092a, 0, {0x90,0x7f,0xae,0x74,0x03,0xf0,0x8c,0x02,0xba,0x00,0x02,0x80,0x03} },
248{ 3, 0x0937, 0, {0x02,0x0a,0x3f} },
249{ 12, 0x093a, 0, {0x85,0x33,0x34,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90,0x7f,0x97} },
250{ 14, 0x0946, 0, {0x74,0x08,0xf0,0x90,0x7f,0x9d,0x74,0x88,0xf0,0x90,0x7f,0x9a,0xe0,0xfa} },
251{ 12, 0x0954, 0, {0x74,0x05,0x5a,0xf5,0x33,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90} },
252{ 13, 0x0960, 0, {0x7f,0x97,0x74,0x02,0xf0,0x90,0x7f,0x9d,0x74,0x82,0xf0,0xe5,0x33} },
253{ 13, 0x096d, 0, {0x25,0xe0,0xfa,0x90,0x7f,0x9a,0xe0,0x54,0x05,0xfb,0x4a,0xf5,0x33} },
254{ 2, 0x097a, 0, {0x60,0x0c} },
255{ 12, 0x097c, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x4a,0xf0} },
256{ 11, 0x0988, 0, {0x75,0x6e,0x00,0x75,0x6f,0x00,0xc0,0x04,0xc0,0x05,0x12} },
257{ 14, 0x0993, 0, {0x11,0x44,0xd0,0x05,0xd0,0x04,0x90,0x17,0x13,0xe0,0xfa,0x74,0x80,0x2a} },
258{ 6, 0x09a1, 0, {0xfa,0xe5,0x33,0xb4,0x04,0x29} },
259{ 3, 0x09a7, 0, {0xba,0xa0,0x00} },
260{ 2, 0x09aa, 0, {0x50,0x24} },
261{ 13, 0x09ac, 0, {0x90,0x17,0x13,0xe0,0x04,0xfb,0x0b,0x90,0x17,0x13,0xeb,0xf0,0x90} },
262{ 14, 0x09b9, 0, {0x17,0x13,0xe0,0xfb,0x90,0x17,0x15,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05} },
263{ 9, 0x09c7, 0, {0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02} },
264{ 5, 0x09d0, 0, {0xe5,0x33,0xb4,0x02,0x26} },
265{ 6, 0x09d5, 0, {0xc3,0x74,0x04,0x9a,0x50,0x20} },
266{ 13, 0x09db, 0, {0x90,0x17,0x13,0xe0,0xfa,0x1a,0x1a,0x90,0x17,0x13,0xea,0xf0,0x90} },
267{ 13, 0x09e8, 0, {0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xf0,0xc0,0x04,0xc0,0x05,0x12} },
268{ 6, 0x09f5, 0, {0x04,0xf7,0xd0,0x05,0xd0,0x04} },
269{ 5, 0x09fb, 0, {0xe5,0x33,0xb4,0x08,0x1d} },
270{ 4, 0x0a00, 0, {0xe5,0x34,0x70,0x19} },
271{ 10, 0x0a04, 0, {0x74,0x01,0x25,0x35,0x54,0x0f,0xf5,0x35,0x85,0x35} },
272{ 12, 0x0a0e, 0, {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0} },
273{ 3, 0x0a1a, 0, {0x05,0xd0,0x04} },
274{ 5, 0x0a1d, 0, {0xe5,0x33,0xb4,0x01,0x1d} },
275{ 4, 0x0a22, 0, {0xe5,0x34,0x70,0x19} },
276{ 10, 0x0a26, 0, {0xe5,0x35,0x24,0xff,0x54,0x0f,0xf5,0x35,0x85,0x35} },
277{ 12, 0x0a30, 0, {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0} },
278{ 3, 0x0a3c, 0, {0x05,0xd0,0x04} },
279{ 14, 0x0a3f, 0, {0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0,0x04,0x90,0x7f,0x96} },
280{ 14, 0x0a4d, 0, {0xe0,0xfa,0x90,0x7f,0x96,0x74,0x7f,0x5a,0xf0,0x90,0x7f,0x97,0x74,0x08} },
281{ 10, 0x0a5b, 0, {0xf0,0xc3,0xec,0x94,0x00,0xed,0x94,0x02,0x40,0x08} },
282{ 8, 0x0a65, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x20,0xe6,0x08} },
283{ 8, 0x0a6d, 0, {0xc3,0xe4,0x9c,0x74,0x08,0x9d,0x50,0x13} },
284{ 14, 0x0a75, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x40,0x65,0x02,0xf0,0x7c} },
285{ 5, 0x0a83, 0, {0x00,0x7d,0x00,0x80,0x05} },
286{ 5, 0x0a88, 0, {0x0c,0xbc,0x00,0x01,0x0d} },
287{ 5, 0x0a8d, 0, {0xe5,0x38,0xb4,0x01,0x0e} },
288{ 13, 0x0a92, 0, {0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0x75,0x38} },
289{ 1, 0x0a9f, 0, {0x00} },
290{ 7, 0x0aa0, 0, {0xe5,0x31,0x70,0x03,0x02,0x09,0x2a} },
291{ 10, 0x0aa7, 0, {0x90,0x7f,0xc9,0xe0,0xfa,0x70,0x03,0x02,0x0c,0x2d} },
292{ 14, 0x0ab1, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90} },
293{ 9, 0x0abf, 0, {0x7d,0xc0,0xe0,0xfa,0xba,0x2c,0x02,0x80,0x03} },
294{ 3, 0x0ac8, 0, {0x02,0x0b,0x36} },
295{ 5, 0x0acb, 0, {0x75,0x32,0x00,0x7b,0x00} },
296{ 3, 0x0ad0, 0, {0xbb,0x64,0x00} },
297{ 2, 0x0ad3, 0, {0x50,0x1c} },
298{ 14, 0x0ad5, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} },
299{ 13, 0x0ae3, 0, {0x04,0xd0,0x03,0xd0,0x02,0x90,0x88,0x0f,0xe0,0xf5,0x47,0x0b,0x80} },
300{ 1, 0x0af0, 0, {0xdf} },
301{ 13, 0x0af1, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x07,0x1e,0x12,0x03,0xe1,0x12} },
302{ 12, 0x0afe, 0, {0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x75,0x6e,0x00,0x75} },
303{ 13, 0x0b0a, 0, {0x6f,0x01,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0x44,0xd0,0x05} },
304{ 9, 0x0b17, 0, {0xd0,0x04,0xd0,0x02,0x75,0x70,0x4d,0x75,0x71} },
305{ 11, 0x0b20, 0, {0x0c,0x75,0x72,0x02,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12} },
306{ 11, 0x0b2b, 0, {0x11,0x75,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x02,0x0c,0x2d} },
307{ 3, 0x0b36, 0, {0xba,0x2a,0x3b} },
308{ 13, 0x0b39, 0, {0x90,0x7f,0x98,0x74,0x20,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12} },
309{ 14, 0x0b46, 0, {0x01,0xdd,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x90,0x7f,0x98,0x74,0x28,0xf0} },
310{ 2, 0x0b54, 0, {0x7b,0x00} },
311{ 3, 0x0b56, 0, {0xbb,0x0a,0x00} },
312{ 5, 0x0b59, 0, {0x40,0x03,0x02,0x0c,0x2d} },
313{ 14, 0x0b5e, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} },
314{ 8, 0x0b6c, 0, {0x04,0xd0,0x03,0xd0,0x02,0x0b,0x80,0xe2} },
315{ 3, 0x0b74, 0, {0xba,0x2b,0x1a} },
316{ 8, 0x0b77, 0, {0x90,0x7f,0xc9,0xe0,0xfb,0xbb,0x40,0x12} },
317{ 14, 0x0b7f, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x12,0x05,0xd0,0x05,0xd0,0x04,0xd0} },
318{ 4, 0x0b8d, 0, {0x02,0x02,0x0c,0x2d} },
319{ 3, 0x0b91, 0, {0xba,0x10,0x1f} },
320{ 14, 0x0b94, 0, {0x90,0x7f,0x96,0xe0,0xfb,0x90,0x7f,0x96,0x74,0x80,0x65,0x03,0xf0,0xc0} },
321{ 14, 0x0ba2, 0, {0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x3d,0xd0,0x05,0xd0,0x04,0xd0,0x02} },
322{ 3, 0x0bb0, 0, {0x02,0x0c,0x2d} },
323{ 3, 0x0bb3, 0, {0xba,0x11,0x12} },
324{ 14, 0x0bb6, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x6a,0xd0,0x05,0xd0,0x04,0xd0} },
325{ 4, 0x0bc4, 0, {0x02,0x02,0x0c,0x2d} },
326{ 3, 0x0bc8, 0, {0xba,0x12,0x12} },
327{ 14, 0x0bcb, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x8f,0xd0,0x05,0xd0,0x04,0xd0} },
328{ 4, 0x0bd9, 0, {0x02,0x02,0x0c,0x2d} },
329{ 3, 0x0bdd, 0, {0xba,0x13,0x0b} },
330{ 11, 0x0be0, 0, {0x90,0x7d,0xc1,0xe0,0xfb,0x90,0x88,0x00,0xf0,0x80,0x42} },
331{ 3, 0x0beb, 0, {0xba,0x14,0x11} },
332{ 14, 0x0bee, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0xdd,0xd0,0x05,0xd0,0x04,0xd0} },
333{ 3, 0x0bfc, 0, {0x02,0x80,0x2e} },
334{ 3, 0x0bff, 0, {0xba,0x15,0x1d} },
335{ 12, 0x0c02, 0, {0x90,0x7d,0xc1,0xe0,0xf5,0x75,0x90,0x7d,0xc2,0xe0,0xf5,0x76} },
336{ 14, 0x0c0e, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0,0x05,0xd0,0x04,0xd0} },
337{ 3, 0x0c1c, 0, {0x02,0x80,0x0e} },
338{ 3, 0x0c1f, 0, {0xba,0x16,0x0b} },
339{ 11, 0x0c22, 0, {0xc0,0x04,0xc0,0x05,0x12,0x13,0xa3,0xd0,0x05,0xd0,0x04} },
340{ 11, 0x0c2d, 0, {0x90,0x7f,0xc9,0xe4,0xf0,0x75,0x31,0x00,0x02,0x09,0x2a} },
341{ 1, 0x0c38, 0, {0x22} },
342{ 7, 0x0c39, 0, {0x53,0x55,0x50,0x45,0x4e,0x44,0x00} },
343{ 7, 0x0c40, 0, {0x52,0x45,0x53,0x55,0x4d,0x45,0x00} },
344{ 6, 0x0c47, 0, {0x20,0x56,0x6f,0x6c,0x20,0x00} },
345{ 13, 0x0c4d, 0, {0x44,0x41,0x42,0x55,0x53,0x42,0x20,0x76,0x31,0x2e,0x30,0x30,0x00} },
346{ 14, 0x0c5a, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} },
347{ 14, 0x0c68, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} },
348{ 13, 0x0c76, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} },
349{ 14, 0x0c83, 0, {0x7f,0xab,0x74,0x01,0xf0,0x90,0x7f,0xe8,0xe0,0xfa,0x90,0x7f,0xe9,0xe0} },
350{ 6, 0x0c91, 0, {0xfb,0xbb,0x00,0x02,0x80,0x03} },
351{ 3, 0x0c97, 0, {0x02,0x0d,0x38} },
352{ 3, 0x0c9a, 0, {0xba,0x80,0x14} },
353{ 14, 0x0c9d, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5} },
354{ 6, 0x0cab, 0, {0x74,0x02,0xf0,0x02,0x0e,0xcd} },
355{ 5, 0x0cb1, 0, {0xba,0x82,0x02,0x80,0x03} },
356{ 3, 0x0cb6, 0, {0x02,0x0d,0x1d} },
357{ 8, 0x0cb9, 0, {0x90,0x7f,0xec,0xe0,0xfc,0xbc,0x01,0x00} },
358{ 2, 0x0cc1, 0, {0x40,0x21} },
359{ 6, 0x0cc3, 0, {0xc3,0x74,0x07,0x9c,0x40,0x1b} },
360{ 14, 0x0cc9, 0, {0xec,0x24,0xff,0x25,0xe0,0xfd,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x7f,0xf5} },
361{ 13, 0x0cd7, 0, {0x83,0xe0,0xfd,0x53,0x05,0x01,0x90,0x7f,0x00,0xed,0xf0,0x80,0x2b} },
362{ 3, 0x0ce4, 0, {0xbc,0x81,0x00} },
363{ 2, 0x0ce7, 0, {0x40,0x21} },
364{ 6, 0x0ce9, 0, {0xc3,0x74,0x87,0x9c,0x40,0x1b} },
365{ 14, 0x0cef, 0, {0xec,0x24,0x7f,0x25,0xe0,0xfc,0x24,0xb6,0xf5,0x82,0xe4,0x34,0x7f,0xf5} },
366{ 13, 0x0cfd, 0, {0x83,0xe0,0xfc,0x53,0x04,0x01,0x90,0x7f,0x00,0xec,0xf0,0x80,0x05} },
367{ 5, 0x0d0a, 0, {0x90,0x7f,0x00,0xe4,0xf0} },
368{ 14, 0x0d0f, 0, {0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x02,0x0e,0xcd} },
369{ 5, 0x0d1d, 0, {0xba,0x81,0x02,0x80,0x03} },
370{ 3, 0x0d22, 0, {0x02,0x0e,0xc5} },
371{ 14, 0x0d25, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74} },
372{ 5, 0x0d33, 0, {0x02,0xf0,0x02,0x0e,0xcd} },
373{ 3, 0x0d38, 0, {0xbb,0x01,0x2d} },
374{ 6, 0x0d3b, 0, {0xba,0x00,0x03,0x02,0x0e,0xcd} },
375{ 3, 0x0d41, 0, {0xba,0x02,0x11} },
376{ 13, 0x0d44, 0, {0x75,0x59,0x00,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0} },
377{ 4, 0x0d51, 0, {0x02,0x02,0x0e,0xcd} },
378{ 5, 0x0d55, 0, {0xba,0x21,0x02,0x80,0x03} },
379{ 3, 0x0d5a, 0, {0x02,0x0e,0xcd} },
380{ 11, 0x0d5d, 0, {0x75,0x37,0x01,0x90,0x7f,0xc5,0xe4,0xf0,0x02,0x0e,0xcd} },
381{ 3, 0x0d68, 0, {0xbb,0x03,0x1f} },
382{ 6, 0x0d6b, 0, {0xba,0x00,0x03,0x02,0x0e,0xcd} },
383{ 5, 0x0d71, 0, {0xba,0x02,0x02,0x80,0x03} },
384{ 3, 0x0d76, 0, {0x02,0x0e,0xcd} },
385{ 13, 0x0d79, 0, {0x75,0x59,0x01,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0} },
386{ 4, 0x0d86, 0, {0x02,0x02,0x0e,0xcd} },
387{ 3, 0x0d8a, 0, {0xbb,0x06,0x54} },
388{ 5, 0x0d8d, 0, {0xba,0x80,0x02,0x80,0x03} },
389{ 3, 0x0d92, 0, {0x02,0x0e,0xc5} },
390{ 8, 0x0d95, 0, {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x01,0x15} },
391{ 12, 0x0d9d, 0, {0x7c,0xfb,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee} },
392{ 9, 0x0da9, 0, {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd} },
393{ 10, 0x0db2, 0, {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x02,0x02,0x80,0x03} },
394{ 3, 0x0dbc, 0, {0x02,0x0e,0xc5} },
395{ 10, 0x0dbf, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x02,0x80,0x03} },
396{ 3, 0x0dc9, 0, {0x02,0x0e,0xc5} },
397{ 12, 0x0dcc, 0, {0x7c,0x3b,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee} },
398{ 9, 0x0dd8, 0, {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd} },
399{ 6, 0x0de1, 0, {0xbb,0x07,0x03,0x02,0x0e,0xc5} },
400{ 3, 0x0de7, 0, {0xbb,0x08,0x10} },
401{ 13, 0x0dea, 0, {0xac,0x48,0x90,0x7f,0x00,0xec,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} },
402{ 3, 0x0df7, 0, {0x02,0x0e,0xcd} },
403{ 3, 0x0dfa, 0, {0xbb,0x09,0x31} },
404{ 5, 0x0dfd, 0, {0xba,0x00,0x02,0x80,0x03} },
405{ 3, 0x0e02, 0, {0x02,0x0e,0xc5} },
406{ 14, 0x0e05, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xc3,0x74,0x01,0x9c,0x50,0x03,0x02,0x0e,0xc5} },
407{ 8, 0x0e13, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x0a} },
408{ 10, 0x0e1b, 0, {0x90,0x17,0x21,0xe4,0xf0,0x90,0x17,0x22,0xe4,0xf0} },
409{ 9, 0x0e25, 0, {0x90,0x7f,0xea,0xe0,0xf5,0x48,0x02,0x0e,0xcd} },
410{ 3, 0x0e2e, 0, {0xbb,0x0a,0x27} },
411{ 5, 0x0e31, 0, {0xba,0x81,0x02,0x80,0x03} },
412{ 3, 0x0e36, 0, {0x02,0x0e,0xc5} },
413{ 14, 0x0e39, 0, {0x90,0x7f,0xec,0xe0,0xfa,0x24,0x20,0xfa,0xe4,0x34,0x17,0xfc,0x8a,0x82} },
414{ 14, 0x0e47, 0, {0x8c,0x83,0xe0,0xfa,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} },
415{ 3, 0x0e55, 0, {0x02,0x0e,0xcd} },
416{ 5, 0x0e58, 0, {0xbb,0x0b,0x02,0x80,0x03} },
417{ 3, 0x0e5d, 0, {0x02,0x0e,0xa9} },
418{ 13, 0x0e60, 0, {0x90,0x17,0x20,0xe4,0xf0,0x90,0x7f,0xec,0xe0,0xfa,0xba,0x01,0x1a} },
419{ 8, 0x0e6d, 0, {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x12} },
420{ 14, 0x0e75, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x90,0x17,0x21,0xf0,0xc0,0x03,0x12,0x04,0xe2} },
421{ 4, 0x0e83, 0, {0xd0,0x03,0x80,0x46} },
422{ 8, 0x0e87, 0, {0x90,0x7f,0xec,0xe0,0xfa,0xba,0x02,0x3e} },
423{ 8, 0x0e8f, 0, {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x36} },
424{ 13, 0x0e97, 0, {0xc0,0x03,0x12,0x04,0xef,0xd0,0x03,0x90,0x7f,0xea,0xe0,0xfa,0x90} },
425{ 5, 0x0ea4, 0, {0x17,0x22,0xf0,0x80,0x24} },
426{ 5, 0x0ea9, 0, {0xbb,0x12,0x02,0x80,0x17} },
427{ 5, 0x0eae, 0, {0xbb,0x81,0x02,0x80,0x0d} },
428{ 5, 0x0eb3, 0, {0xbb,0x83,0x02,0x80,0x08} },
429{ 5, 0x0eb8, 0, {0xbb,0x82,0x02,0x80,0x03} },
430{ 3, 0x0ebd, 0, {0xbb,0x84,0x05} },
431{ 5, 0x0ec0, 0, {0x12,0x06,0x4e,0x80,0x08} },
432{ 8, 0x0ec5, 0, {0x90,0x7f,0xb4,0x74,0x03,0xf0,0x80,0x06} },
433{ 6, 0x0ecd, 0, {0x90,0x7f,0xb4,0x74,0x02,0xf0} },
434{ 2, 0x0ed3, 0, {0xd0,0x86} },
435{ 14, 0x0ed5, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} },
436{ 13, 0x0ee3, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
437{ 11, 0x0ef0, 0, {0x90,0x7f,0xec,0xe0,0xf5,0x5a,0xc3,0x94,0x01,0x40,0x1d} },
438{ 7, 0x0efb, 0, {0xc3,0x74,0x07,0x95,0x5a,0x40,0x16} },
439{ 13, 0x0f02, 0, {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xc6,0xf5,0x82,0xe4,0x34} },
440{ 9, 0x0f0f, 0, {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0,0x80,0x22} },
441{ 7, 0x0f18, 0, {0xc3,0xe5,0x5a,0x94,0x81,0x40,0x1b} },
442{ 7, 0x0f1f, 0, {0xc3,0x74,0x87,0x95,0x5a,0x40,0x14} },
443{ 13, 0x0f26, 0, {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xb6,0xf5,0x82,0xe4,0x34} },
444{ 7, 0x0f33, 0, {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0} },
445{ 1, 0x0f3a, 0, {0x22} },
446{ 14, 0x0f3b, 0, {0x09,0x02,0xba,0x00,0x03,0x01,0x00,0x40,0x00,0x09,0x04,0x00,0x00,0x00} },
447{ 14, 0x0f49, 0, {0x01,0x01,0x00,0x00,0x09,0x24,0x01,0x00,0x01,0x3d,0x00,0x01,0x01,0x0c} },
448{ 14, 0x0f57, 0, {0x24,0x02,0x01,0x10,0x07,0x00,0x02,0x03,0x00,0x00,0x00,0x0d,0x24,0x06} },
449{ 14, 0x0f65, 0, {0x03,0x01,0x02,0x15,0x00,0x03,0x00,0x03,0x00,0x00,0x09,0x24,0x03,0x02} },
450{ 14, 0x0f73, 0, {0x01,0x01,0x00,0x01,0x00,0x09,0x24,0x03,0x04,0x02,0x03,0x00,0x03,0x00} },
451{ 14, 0x0f81, 0, {0x09,0x24,0x03,0x05,0x03,0x06,0x00,0x01,0x00,0x09,0x04,0x01,0x00,0x00} },
452{ 14, 0x0f8f, 0, {0x01,0x02,0x00,0x00,0x09,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00,0x07} },
453{ 14, 0x0f9d, 0, {0x24,0x01,0x02,0x01,0x01,0x00,0x0b,0x24,0x02,0x01,0x02,0x02,0x10,0x01} },
454{ 14, 0x0fab, 0, {0x80,0xbb,0x00,0x09,0x05,0x88,0x05,0x00,0x01,0x01,0x00,0x00,0x07,0x25} },
455{ 14, 0x0fb9, 0, {0x01,0x00,0x00,0x00,0x00,0x09,0x04,0x02,0x00,0x02,0x00,0x00,0x00,0x00} },
456{ 14, 0x0fc7, 0, {0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00} },
457{ 14, 0x0fd5, 0, {0x09,0x04,0x02,0x01,0x03,0x00,0x00,0x00,0x00,0x07,0x05,0x82,0x02,0x40} },
458{ 14, 0x0fe3, 0, {0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00,0x09,0x05,0x89,0x05,0xa0} },
459{ 10, 0x0ff1, 0, {0x01,0x01,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00} },
460{ 14, 0x0ffb, 0, {0x12,0x01,0x00,0x01,0x00,0x00,0x00,0x40,0x47,0x05,0x99,0x99,0x00,0x01} },
461{ 14, 0x1009, 0, {0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x02,0xba} },
462{ 4, 0x1017, 0, {0x00,0x03,0x01,0x00} },
463{ 2, 0x101b, 0, {0x7a,0x00} },
464{ 3, 0x101d, 0, {0xba,0x05,0x00} },
465{ 2, 0x1020, 0, {0x50,0x17} },
466{ 8, 0x1022, 0, {0x90,0x7f,0xa5,0xe0,0xfb,0x30,0xe0,0x05} },
467{ 5, 0x102a, 0, {0x90,0x00,0x01,0x80,0x0d} },
468{ 10, 0x102f, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xe4} },
469{ 3, 0x1039, 0, {0x90,0x00,0x01} },
470{ 1, 0x103c, 0, {0x22} },
471{ 14, 0x103d, 0, {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0x00,0x7d} },
472{ 4, 0x104b, 0, {0x7e,0xeb,0x60,0x12} },
473{ 14, 0x104f, 0, {0x89,0x82,0x8a,0x83,0xe0,0xa3,0xa9,0x82,0xaa,0x83,0x8c,0x82,0x8d,0x83} },
474{ 4, 0x105d, 0, {0xf0,0x0c,0xdb,0xee} },
475{ 8, 0x1061, 0, {0x90,0x7d,0xc3,0xe0,0x90,0x7f,0xb9,0xf0} },
476{ 1, 0x1069, 0, {0x22} },
477{ 14, 0x106a, 0, {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0xc4,0x7d} },
478{ 4, 0x1078, 0, {0x7d,0xeb,0x60,0xe5} },
479{ 14, 0x107c, 0, {0x8c,0x82,0x8d,0x83,0xe0,0x0c,0x89,0x82,0x8a,0x83,0xf0,0xa3,0xa9,0x82} },
480{ 4, 0x108a, 0, {0xaa,0x83,0xdb,0xee} },
481{ 1, 0x108e, 0, {0x22} },
482{ 14, 0x108f, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x05,0x86,0x90,0x7d,0xc1,0xe0,0x05,0x86} },
483{ 14, 0x109d, 0, {0xa3,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0x05,0x86,0xa3,0xa3,0xe0,0xf9} },
484{ 5, 0x10ab, 0, {0x60,0x16,0xa3,0x05,0x86} },
485{ 13, 0x10b0, 0, {0x90,0x7f,0xa6,0x05,0x86,0xe0,0xa3,0x05,0x86,0xf0,0xc0,0x01,0x12} },
486{ 6, 0x10bd, 0, {0x10,0x1b,0xd0,0x01,0xd9,0xed} },
487{ 6, 0x10c3, 0, {0x90,0x7f,0xa5,0x74,0x40,0xf0} },
488{ 1, 0x10c9, 0, {0x22} },
489{ 8, 0x10ca, 0, {0x90,0x88,0x02,0x74,0x01,0xf0,0x7a,0x00} },
490{ 3, 0x10d2, 0, {0xba,0xff,0x00} },
491{ 2, 0x10d5, 0, {0x50,0x0a} },
492{ 10, 0x10d7, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1} },
493{ 1, 0x10e1, 0, {0x22} },
494{ 5, 0x10e2, 0, {0xe5,0x6b,0xb4,0xc0,0x08} },
495{ 8, 0x10e7, 0, {0x90,0x88,0x03,0xe5,0x6c,0xf0,0x80,0x06} },
496{ 6, 0x10ef, 0, {0x90,0x88,0x02,0xe5,0x6c,0xf0} },
497{ 4, 0x10f5, 0, {0x7a,0x00,0x7b,0x00} },
498{ 11, 0x10f9, 0, {0xc3,0xea,0x94,0x32,0xeb,0x64,0x80,0x94,0x80,0x50,0x07} },
499{ 5, 0x1104, 0, {0x0a,0xba,0x00,0x01,0x0b} },
500{ 2, 0x1109, 0, {0x80,0xee} },
501{ 1, 0x110b, 0, {0x22} },
502{ 10, 0x110c, 0, {0x90,0x88,0x03,0xe5,0x6d,0xf0,0x05,0x39,0x7a,0x00} },
503{ 3, 0x1116, 0, {0xba,0x28,0x00} },
504{ 2, 0x1119, 0, {0x50,0x03} },
505{ 3, 0x111b, 0, {0x0a,0x80,0xf8} },
506{ 5, 0x111e, 0, {0xe5,0x39,0xb4,0x10,0x08} },
507{ 8, 0x1123, 0, {0x90,0x88,0x02,0x74,0xc0,0xf0,0x80,0x0e} },
508{ 5, 0x112b, 0, {0xe5,0x39,0xb4,0x20,0x09} },
509{ 9, 0x1130, 0, {0x90,0x88,0x02,0x74,0x80,0xf0,0x75,0x39,0x00} },
510{ 2, 0x1139, 0, {0x7a,0x00} },
511{ 3, 0x113b, 0, {0xba,0x28,0x00} },
512{ 2, 0x113e, 0, {0x50,0x03} },
513{ 3, 0x1140, 0, {0x0a,0x80,0xf8} },
514{ 1, 0x1143, 0, {0x22} },
515{ 4, 0x1144, 0, {0xe5,0x6f,0x60,0x02} },
516{ 2, 0x1148, 0, {0x80,0x07} },
517{ 7, 0x114a, 0, {0x7a,0x00,0x75,0x39,0x00,0x80,0x05} },
518{ 5, 0x1151, 0, {0x7a,0x40,0x75,0x39,0x10} },
519{ 9, 0x1156, 0, {0xe5,0x6e,0x2a,0xfa,0xe5,0x6e,0x25,0x39,0xf5} },
520{ 10, 0x115f, 0, {0x39,0x90,0x88,0x02,0x74,0x80,0x2a,0xf0,0x7a,0x00} },
521{ 8, 0x1169, 0, {0xc3,0xea,0x64,0x80,0x94,0xa8,0x50,0x03} },
522{ 3, 0x1171, 0, {0x0a,0x80,0xf5} },
523{ 1, 0x1174, 0, {0x22} },
524{ 6, 0x1175, 0, {0xaa,0x70,0xab,0x71,0xac,0x72} },
525{ 12, 0x117b, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x12,0x14,0xee,0xfd,0x60,0x18} },
526{ 13, 0x1187, 0, {0x8d,0x6d,0xc0,0x02,0xc0,0x03,0xc0,0x04,0x12,0x11,0x0c,0xd0,0x04} },
527{ 9, 0x1194, 0, {0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b} },
528{ 2, 0x119d, 0, {0x80,0xdc} },
529{ 1, 0x119f, 0, {0x22} },
530{ 13, 0x11a0, 0, {0xe5,0x73,0xc4,0x54,0x0f,0xfa,0x53,0x02,0x0f,0xc3,0x74,0x09,0x9a} },
531{ 2, 0x11ad, 0, {0x50,0x06} },
532{ 6, 0x11af, 0, {0x74,0x37,0x2a,0xfb,0x80,0x04} },
533{ 4, 0x11b5, 0, {0x74,0x30,0x2a,0xfb} },
534{ 12, 0x11b9, 0, {0x8b,0x6d,0xc0,0x03,0x12,0x11,0x0c,0xd0,0x03,0xaa,0x73,0x53} },
535{ 8, 0x11c5, 0, {0x02,0x0f,0xc3,0x74,0x09,0x9a,0x50,0x06} },
536{ 6, 0x11cd, 0, {0x74,0x37,0x2a,0xfb,0x80,0x04} },
537{ 4, 0x11d3, 0, {0x74,0x30,0x2a,0xfb} },
538{ 5, 0x11d7, 0, {0x8b,0x6d,0x12,0x11,0x0c} },
539{ 1, 0x11dc, 0, {0x22} },
540{ 7, 0x11dd, 0, {0x90,0x7d,0xc3,0xe0,0xfa,0x60,0x0f} },
541{ 12, 0x11e4, 0, {0x90,0x7d,0xc1,0xe0,0xf5,0x6e,0x90,0x7d,0xc2,0xe0,0xf5,0x6f} },
542{ 3, 0x11f0, 0, {0x12,0x11,0x44} },
543{ 12, 0x11f3, 0, {0x90,0x7d,0xff,0xe4,0xf0,0x75,0x70,0xc4,0x75,0x71,0x7d,0x75} },
544{ 5, 0x11ff, 0, {0x72,0x01,0x12,0x11,0x75} },
545{ 1, 0x1204, 0, {0x22} },
546{ 2, 0x1205, 0, {0x7a,0x04} },
547{ 3, 0x1207, 0, {0xba,0x40,0x00} },
548{ 2, 0x120a, 0, {0x50,0x36} },
549{ 14, 0x120c, 0, {0xea,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfb,0x7c,0x00} },
550{ 3, 0x121a, 0, {0xbc,0x08,0x00} },
551{ 2, 0x121d, 0, {0x50,0x20} },
552{ 6, 0x121f, 0, {0x8b,0x05,0xed,0x30,0xe7,0x0b} },
553{ 11, 0x1225, 0, {0x90,0x7f,0x96,0x74,0x42,0xf0,0x74,0xc3,0xf0,0x80,0x08} },
554{ 8, 0x1230, 0, {0x90,0x7f,0x96,0xe4,0xf0,0x74,0x81,0xf0} },
555{ 7, 0x1238, 0, {0xeb,0x25,0xe0,0xfb,0x0c,0x80,0xdb} },
556{ 3, 0x123f, 0, {0x0a,0x80,0xc5} },
557{ 1, 0x1242, 0, {0x22} },
558{ 4, 0x1243, 0, {0x7a,0x00,0x7b,0xef} },
559{ 3, 0x1247, 0, {0xba,0x10,0x00} },
560{ 2, 0x124a, 0, {0x50,0x20} },
561{ 14, 0x124c, 0, {0x74,0x11,0x2b,0xfb,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0x8c,0x82,0x8d} },
562{ 14, 0x125a, 0, {0x83,0xe4,0xf0,0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe4} },
563{ 4, 0x1268, 0, {0xf0,0x0a,0x80,0xdb} },
564{ 1, 0x126c, 0, {0x22} },
565{ 14, 0x126d, 0, {0x74,0xf8,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
566{ 14, 0x127b, 0, {0x74,0xf9,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
567{ 14, 0x1289, 0, {0x74,0xfa,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
568{ 14, 0x1297, 0, {0x74,0xfb,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
569{ 14, 0x12a5, 0, {0x74,0xff,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
570{ 1, 0x12b3, 0, {0x22} },
571{ 14, 0x12b4, 0, {0x12,0x03,0xcb,0x12,0x12,0x6d,0x7a,0xc0,0x7b,0x87,0x7c,0x01,0x74,0x01} },
572{ 14, 0x12c2, 0, {0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74} },
573{ 14, 0x12d0, 0, {0x01,0x12,0x14,0xbf,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e} },
574{ 14, 0x12de, 0, {0x83,0x8f,0xf0,0x74,0x06,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b} },
575{ 14, 0x12ec, 0, {0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74} },
576{ 14, 0x12fa, 0, {0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0} },
577{ 14, 0x1308, 0, {0x74,0x0b,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07} },
578{ 14, 0x1316, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74,0x08,0x12,0x14,0xbf,0x74,0x01,0x2d} },
579{ 14, 0x1324, 0, {0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x01} },
580{ 14, 0x1332, 0, {0x12,0x14,0xbf,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83} },
581{ 14, 0x1340, 0, {0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74,0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f} },
582{ 14, 0x134e, 0, {0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x03,0x12,0x14,0xbf,0x7d,0x00} },
583{ 3, 0x135c, 0, {0xbd,0x06,0x00} },
584{ 2, 0x135f, 0, {0x50,0x12} },
585{ 11, 0x1361, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x0a,0xba,0x00,0x01,0x0b} },
586{ 7, 0x136c, 0, {0xe4,0x12,0x14,0xbf,0x0d,0x80,0xe9} },
587{ 13, 0x1373, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe5,0x74,0x12,0x14,0xbf,0x74,0xf9} },
588{ 14, 0x1380, 0, {0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x0f,0xf0,0x74} },
589{ 14, 0x138e, 0, {0xfe,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x01,0xf0} },
590{ 6, 0x139c, 0, {0x12,0x03,0xe1,0x12,0x04,0xf7} },
591{ 1, 0x13a2, 0, {0x22} },
592{ 13, 0x13a3, 0, {0x90,0x7d,0xc1,0xe0,0xfa,0x24,0x00,0xfb,0xe4,0x34,0x19,0xfc,0x90} },
593{ 14, 0x13b0, 0, {0x7d,0xc2,0xe0,0xfd,0x8b,0x82,0x8c,0x83,0xf0,0x75,0xf0,0x11,0xea,0xa4} },
594{ 3, 0x13be, 0, {0xfa,0x7b,0x00} },
595{ 3, 0x13c1, 0, {0xbb,0x10,0x00} },
596{ 2, 0x13c4, 0, {0x50,0x24} },
597{ 14, 0x13c6, 0, {0xea,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0xeb,0x2c,0xfc,0xe4,0x3d,0xfd} },
598{ 14, 0x13d4, 0, {0x74,0x04,0x2b,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfe} },
599{ 8, 0x13e2, 0, {0x8c,0x82,0x8d,0x83,0xf0,0x0b,0x80,0xd7} },
600{ 14, 0x13ea, 0, {0xea,0x24,0x00,0xfa,0xe4,0x34,0x18,0xfb,0x74,0x10,0x2a,0xf5,0x82,0xe4} },
601{ 5, 0x13f8, 0, {0x3b,0xf5,0x83,0xe4,0xf0} },
602{ 1, 0x13fd, 0, {0x22} },
603{ 4, 0x13fe, 0, {0xe5,0x76,0x60,0x02} },
604{ 2, 0x1402, 0, {0x80,0x16} },
605{ 12, 0x1404, 0, {0x74,0x0f,0x55,0x75,0xfa,0x8a,0x75,0x24,0x00,0xf5,0x82,0xe4} },
606{ 10, 0x1410, 0, {0x34,0x19,0xf5,0x83,0xe0,0xf5,0x74,0x12,0x12,0xb4} },
607{ 10, 0x141a, 0, {0x12,0x10,0xca,0x75,0x6e,0x00,0x75,0x6f,0x00,0x12} },
608{ 6, 0x1424, 0, {0x11,0x44,0x75,0x70,0xb9,0x75} },
609{ 6, 0x142a, 0, {0x71,0x14,0x75,0x72,0x02,0x12} },
610{ 11, 0x1430, 0, {0x11,0x75,0xe5,0x76,0xb4,0x02,0x04,0x74,0x01,0x80,0x01} },
611{ 1, 0x143b, 0, {0xe4} },
612{ 3, 0x143c, 0, {0xfa,0x70,0x0f} },
613{ 12, 0x143f, 0, {0x74,0x01,0x25,0x75,0xf5,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0} },
614{ 3, 0x144b, 0, {0x02,0x80,0x0a} },
615{ 10, 0x144e, 0, {0x85,0x75,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0,0x02} },
616{ 12, 0x1458, 0, {0x75,0x6e,0x00,0x75,0x6f,0x01,0xc0,0x02,0x12,0x11,0x44,0xd0} },
617{ 4, 0x1464, 0, {0x02,0xea,0x70,0x1a} },
618{ 13, 0x1468, 0, {0x75,0xf0,0x11,0xe5,0x75,0xa4,0xfa,0x24,0x00,0xfa,0xe4,0x34,0x18} },
619{ 9, 0x1475, 0, {0xfb,0x8a,0x70,0x8b,0x71,0x75,0x72,0x01,0x12} },
620{ 4, 0x147e, 0, {0x11,0x75,0x80,0x36} },
621{ 2, 0x1482, 0, {0x7a,0x00} },
622{ 3, 0x1484, 0, {0xba,0x10,0x00} },
623{ 2, 0x1487, 0, {0x50,0x2f} },
624{ 13, 0x1489, 0, {0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe0,0xfb,0xe5} },
625{ 4, 0x1496, 0, {0x75,0xb5,0x03,0x1b} },
626{ 14, 0x149a, 0, {0x75,0xf0,0x11,0xea,0xa4,0xfb,0x24,0x00,0xfb,0xe4,0x34,0x18,0xfc,0x8b} },
627{ 9, 0x14a8, 0, {0x70,0x8c,0x71,0x75,0x72,0x01,0xc0,0x02,0x12} },
628{ 4, 0x14b1, 0, {0x11,0x75,0xd0,0x02} },
629{ 3, 0x14b5, 0, {0x0a,0x80,0xcc} },
630{ 1, 0x14b8, 0, {0x22} },
631{ 6, 0x14b9, 0, {0x50,0x72,0x6f,0x67,0x20,0x00} },
632{ 14, 0x14bf, 0, {0xc8,0xc0,0xe0,0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0b,0x14,0x60,0x0f,0x14} },
633{ 7, 0x14cd, 0, {0x60,0x11,0x14,0x60,0x12,0x80,0x15} },
634{ 7, 0x14d4, 0, {0xd0,0xe0,0xa8,0x82,0xf6,0x80,0x0e} },
635{ 5, 0x14db, 0, {0xd0,0xe0,0xf0,0x80,0x09} },
636{ 4, 0x14e0, 0, {0xd0,0xe0,0x80,0x05} },
637{ 5, 0x14e4, 0, {0xd0,0xe0,0xa8,0x82,0xf2} },
638{ 4, 0x14e9, 0, {0xc8,0xd0,0xe0,0xc8} },
639{ 1, 0x14ed, 0, {0x22} },
640{ 14, 0x14ee, 0, {0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0d,0x14,0x60,0x0f,0x14,0x60,0x0f,0x14} },
641{ 6, 0x14fc, 0, {0x60,0x10,0x74,0xff,0x80,0x0f} },
642{ 5, 0x1502, 0, {0xa8,0x82,0xe6,0x80,0x0a} },
643{ 3, 0x1507, 0, {0xe0,0x80,0x07} },
644{ 4, 0x150a, 0, {0xe4,0x93,0x80,0x03} },
645{ 3, 0x150e, 0, {0xa8,0x82,0xe2} },
646{ 4, 0x1511, 0, {0xf8,0xd0,0xe0,0xc8} },
647{ 1, 0x1515, 0, {0x22} },
648{ 0, 0x0000, 1, {0} }
649
650};
651
652static unsigned char bitstream[] = {
653
6540x00,0x09,0x0F,0xF0,0x0F,0xF0,0x0F,0xF0, 0x0F,0xF0,0x00,0x00,0x01,0x61,0x00,0x0D,
6550x64,0x61,0x62,0x75,0x73,0x62,0x74,0x72, 0x2E,0x6E,0x63,0x64,0x00,0x62,0x00,0x0B,
6560x73,0x31,0x30,0x78,0x6C,0x76,0x71,0x31, 0x30,0x30,0x00,0x63,0x00,0x0B,0x31,0x39,
6570x39,0x39,0x2F,0x30,0x39,0x2F,0x32,0x34, 0x00,0x64,0x00,0x09,0x31,0x30,0x3A,0x34,
6580x32,0x3A,0x34,0x36,0x00,0x65,0x00,0x00, 0x2E,0xC0,0xFF,0x20,0x17,0x5F,0x9F,0x5B,
6590xFE,0xFB,0xBB,0xB7,0xBB,0xBB,0xFB,0xBF, 0xAF,0xEF,0xFB,0xDF,0xB7,0xFB,0xFB,0x7F,
6600xBF,0xB7,0xEF,0xF2,0xFF,0xFB,0xFE,0xFF, 0xFF,0xEF,0xFF,0xFE,0xFF,0xBF,0xFF,0xFF,
6610xFF,0xFF,0xAF,0xFF,0xFA,0xFF,0xFF,0xFF, 0xC9,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,
6620xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFB,0xFF,0xA3,0xFF,0xFB,
6630xFE,0xFF,0xBF,0xEF,0xE3,0xFE,0xFF,0xBF, 0xE3,0xFE,0xFF,0xBF,0x6F,0xFB,0xF6,0xFF,
6640xBF,0xFF,0x47,0xFF,0xFF,0x9F,0xEE,0xF9, 0xFE,0xCF,0x9F,0xEF,0xFB,0xCF,0x9B,0xEE,
6650xF8,0xFE,0xEF,0x8F,0xEE,0xFB,0xFE,0x0B, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
6660xFF,0xFF,0xBF,0xFF,0xFF,0xFB,0xFF,0xFF, 0xBF,0xFF,0xFF,0xFC,0x17,0xFF,0xFF,0xFF,
6670xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xFB,0xFF,0xFF,0x7F,0xFF,0xFF,
6680xFC,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,
6690xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0xFF, 0xFF,0xFD,0xFF,0xFF,0xDB,0xFF,0xFD,0xFF,
6700x77,0xFF,0xFD,0xFF,0xFF,0xDF,0xFE,0xFD, 0xFF,0xFF,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,
6710xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,
6720x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,
6730xFF,0xFF,0xFF,0xFF,0xE3,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,
6740xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x67,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
6750x7F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF, 0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0x2F,0xFF,
6760xF3,0xFD,0xFF,0x7F,0xDE,0xF7,0xFD,0xFF, 0x7F,0xF7,0x7D,0xFF,0x7F,0xDF,0xF7,0xBD,
6770xFF,0x7F,0xFF,0x1F,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xEF,0xFB,
6780xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF, 0x3F,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,
6790x9F,0xE7,0xFA,0x7F,0x9F,0xE7,0xF9,0xFE, 0x7F,0x9F,0xE7,0xFF,0xFC,0x7F,0xBF,0xBF,
6800xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xB7, 0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,
6810xFF,0xE0,0xFD,0xF9,0xFE,0x7F,0x9F,0xE7, 0xF9,0xFE,0x7F,0x9D,0xF9,0xFE,0x7D,0x9D,
6820xE7,0xF9,0xFE,0x7F,0x9F,0xED,0xED,0xFF, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,
6830xDF,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF, 0x7F,0xDF,0xFF,0x9B,0xFF,0xEF,0xFB,0xFE,
6840xFB,0xBF,0xEF,0xBB,0xFE,0xFF,0xAF,0xBB, 0xBE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF,
6850xB7,0xBF,0xDB,0xF6,0xBD,0xBF,0x6B,0xDB, 0xF6,0xF9,0xBF,0x5B,0xD6,0xF9,0xBF,0x6F,
6860xDB,0xF6,0xFD,0xBF,0xFF,0x0E,0xFF,0xFF, 0xFF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0x7F,
6870xF7,0xBD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xDF,0x9F,0xFF,0xFF,0xFF,0xFE,0xFF,
6880xFF,0xEF,0xFE,0xFE,0xFF,0xFF,0x77,0xFF, 0xFB,0xFB,0xFF,0xFF,0xFF,0xFF,0xF8,0x3F,
6890xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
6900xFF,0xFF,0xFF,0xF4,0x7F,0xFF,0xFE,0xFD, 0xBE,0xFF,0xDF,0xFE,0xFF,0xFF,0xEF,0x7F,
6910xFF,0xCF,0xFF,0xCF,0xFF,0xFF,0xFF,0xDF, 0xE6,0xFF,0xFF,0x7F,0xDF,0xF7,0xDD,0x7F,
6920x7F,0xDF,0xF7,0xFF,0x7F,0xDF,0xD7,0xFD, 0xFF,0x7F,0xDF,0xF7,0xFF,0xCD,0xFF,0xF2,
6930xFF,0xFF,0x4F,0x7F,0xF4,0xFF,0xFF,0xFF, 0xE7,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
6940xFF,0xFF,0xBB,0xFF,0xEF,0xFF,0xFE,0xFF, 0xFF,0xFF,0xEF,0xFF,0xFF,0xEF,0xFF,0xFB,
6950xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x65, 0xEF,0xFF,0xFF,0x7F,0xFF,0xFD,0xEF,0xFF,
6960xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xCF,0xDF,0xFE,0xFF,
6970xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xF3,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
6980xFE,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
6990xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBF,0xFF, 0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF,0xFF,
7000xFF,0xFF,0xEF,0xEB,0xFF,0xFE,0xBF,0xFF, 0xEB,0xFF,0xFC,0x7F,0xFF,0xFF,0xFF,0xEE,
7010xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF, 0xD6,0xFF,0xFD,0xBF,0xFF,0xFB,0xFF,0xFE,
7020xFD,0xFF,0xFF,0xFD,0xEF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xDE,0xFF,0xFF,0xFF,0xFF,
7030xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0x7F,0xBF, 0xFF,0x5F,0xDF,0xFF,0xFF,0xBF,0x77,0xFF,
7040xFF,0xFF,0x7F,0xD7,0xFF,0xFF,0xFF,0xFF, 0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xDF,0xEF,
7050xFF,0xFF,0xFE,0xFB,0xFF,0xFF,0xDF,0xBF, 0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xB7,0xFF,
7060xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
7070xFF,0xFF,0xFF,0xAF,0x7F,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
7080xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xDF,0xBF,0xDF,0xF3,0xFD,0xFB,0xFF,0x5B,
7090xFD,0xFF,0xBF,0xEF,0xF7,0xFF,0xFF,0x7D, 0xFF,0xFF,0xFF,0xFF,0xF8,0x3B,0xFF,0xBF,
7100x6F,0xFF,0xFE,0xFF,0xBF,0xFF,0xEB,0x7D, 0xFF,0xEF,0xFB,0xFE,0xFF,0xFF,0xFF,0xFF,
7110xFF,0xF2,0x7F,0xFC,0xFF,0x3F,0xDF,0xED, 0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0x5F,0xF7,
7120xB5,0xFF,0xEF,0xFF,0xFF,0xFF,0xE0,0x3F, 0x9F,0x9E,0xFF,0xFF,0xEF,0xFF,0xDF,0xFF,
7130xBF,0x5F,0xBF,0xCF,0xF3,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0x69,0xAF,0x33,0xFD,0xFF,
7140xFB,0xFF,0xFF,0xFF,0xFF,0xFC,0xFF,0x7F, 0xD9,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xF5,
7150xA3,0xDF,0x6E,0xDE,0xFF,0xFF,0xBD,0xFF, 0xFF,0xFE,0xFF,0xFF,0xFF,0xFE,0xE7,0xFD,
7160xFF,0xFF,0xFF,0xF9,0xEF,0xC6,0xFE,0xB7, 0xAD,0xE5,0xF9,0xFF,0xFF,0xFF,0xCF,0xFF,
7170xFF,0xFF,0xCD,0xFB,0x7F,0xFF,0xFF,0xFF, 0xF9,0xF6,0x0F,0xDF,0xEC,0xCF,0x7F,0xFF,
7180xFB,0x7F,0xFF,0xFF,0xFF,0xFD,0xFF,0xFE, 0xF9,0xFD,0x7F,0xFF,0x7F,0xFF,0xF9,0x5B,
7190xFF,0x73,0xDC,0xFD,0x7B,0xDF,0xFF,0xFF, 0xFF,0x7B,0xFF,0xFF,0xF7,0x53,0xD6,0xFF,
7200xFF,0xFF,0xFF,0xD8,0x9F,0xFE,0xFF,0xEF, 0x7F,0xEE,0xFF,0xFF,0xFF,0xFB,0xED,0xED,
7210xFD,0xFF,0xFE,0xFF,0xFF,0xFB,0x7F,0xFF, 0xE2,0x7F,0xFF,0x6F,0xD8,0x57,0xF7,0xFF,
7220xFF,0xFF,0xDF,0xFF,0xE8,0xFF,0xFF,0xFD, 0xFF,0xFF,0xFC,0x7F,0xFF,0xE4,0xFF,0xFB,
7230xEF,0xFB,0xFE,0xDF,0xB7,0xED,0xFF,0xFE, 0xDF,0x7F,0xFF,0xFE,0x7F,0xB7,0xFF,0xFF,
7240xFF,0xFF,0x89,0xFF,0xFF,0xCF,0xF3,0xFE, 0x7F,0xFF,0xEF,0xFF,0xFE,0x7E,0x7F,0xFB,
7250xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF1, 0xFF,0xEB,0x7A,0xD5,0xBF,0x6F,0xDB,0xBE,
7260xFD,0xB7,0xD8,0xF6,0xE5,0xBF,0x6F,0xFB, 0xFE,0xF5,0xBD,0x7E,0x06,0xFF,0xDF,0xF7,
7270xFB,0xF6,0xFF,0x3F,0xFF,0xDB,0xFF,0xFF, 0x6F,0xFB,0xF7,0xFF,0xFF,0xFF,0xFB,0xFE,
7280xF7,0xAF,0xFF,0xB7,0xED,0xEF,0xF7,0xFE, 0xFF,0xFF,0xDF,0xFF,0xFE,0xFF,0xEF,0xFF,
7290xFF,0xFF,0xFF,0xBF,0xF7,0xFC,0x1F,0xEE, 0xFB,0xFE,0xBD,0xFF,0x7F,0x5F,0xD7,0xFD,
7300xFB,0x43,0xFF,0xFF,0xFD,0xFF,0x5F,0xFF, 0xF7,0xFF,0xF9,0x3F,0xFF,0xCF,0xF3,0xFD,
7310xF7,0x7E,0xEF,0xA7,0xF9,0xFE,0x8F,0xA7, 0xE9,0xF3,0x7E,0x9F,0xFB,0xF8,0xFF,0xFF,
7320x3F,0xFD,0x7F,0x5F,0xDF,0xFD,0xFF,0xFF, 0x5F,0xFF,0xFD,0x5F,0xFF,0xFF,0x7F,0xFD,
7330x7F,0xFD,0x9F,0xFF,0xE0,0xFF,0xFA,0xF8, 0xBE,0x6F,0x9F,0xE6,0xF8,0xBE,0x3F,0x9A,
7340xF9,0xBE,0x6F,0x9F,0xE2,0xF9,0xFE,0x6F, 0x9F,0xF9,0xFF,0xF5,0xFD,0x7F,0xCF,0xDF,
7350xFD,0xFD,0x7F,0xFF,0xF5,0xFF,0xFF,0xFF, 0xF7,0xF5,0xFD,0x0F,0xDB,0xFF,0xD3,0xFF,
7360xEB,0xFA,0xFF,0xFF,0xBF,0xFF,0xFA,0xFF, 0xFF,0xCB,0xFB,0xFE,0xFF,0xFF,0xEB,0xFA,
7370xFE,0xFF,0xFF,0xB7,0xFF,0xFF,0xFF,0xFF, 0xBF,0xFF,0xDF,0xF5,0xFF,0xFF,0xD7,0xFF,
7380xFF,0xFF,0xDF,0xD7,0xF5,0xFF,0x7F,0xFE, 0x4F,0xFF,0xFD,0xFF,0x7F,0x7F,0xFF,0xAD,
7390xEB,0xFB,0xFF,0xAD,0xFF,0xFF,0xFF,0xFF, 0xAF,0xEB,0xFB,0xFF,0xFC,0x0D,0xFF,0xFF,
7400xDF,0xD2,0xFD,0xFF,0xFF,0xFD,0xF6,0xFF, 0xFF,0x7F,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,
7410xFF,0xFB,0x3F,0x7D,0xEB,0x32,0xFE,0xBF, 0x2F,0xEB,0xFA,0xAE,0xBD,0xE0,0xFA,0x7E,
7420xBF,0xAD,0xEB,0xFA,0xFE,0xBF,0xF5,0x7F, 0xFF,0xDE,0xFE,0xE3,0xFB,0xFF,0xFF,0xFF,
7430xDF,0xEF,0x4F,0xDF,0xFF,0x7F,0xDF,0xFF, 0xF7,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xEF,
7440xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xDF, 0xED,0xFB,0xDF,0xFF,0xBF,0xFF,0xFF,0xFF,
7450x81,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF, 0xFF,0xFF,0xFE,0xDD,0xFE,0xEF,0xFD,0xFF,
7460xFF,0xFB,0xFE,0xF7,0xFF,0x93,0xFD,0xFB, 0x7E,0xFF,0xFE,0x87,0xE9,0xFF,0x7F,0xB3,
7470x9F,0xFE,0xFE,0xFF,0xAF,0xFD,0xFE,0x7E, 0x3F,0xFE,0x67,0xFF,0xFF,0xF7,0xFF,0xFF,
7480xFC,0xF7,0xDF,0xFD,0xFF,0x7F,0xFF,0xFF, 0x7F,0x6D,0xFF,0xFF,0xFE,0xFF,0xFF,0x2F,
7490xFF,0xBF,0xFF,0xFF,0xEE,0xFF,0xBE,0xFF, 0xFF,0xFE,0xFF,0xEF,0xFF,0xFF,0xFE,0xFF,
7500xEF,0xFF,0xFF,0xFA,0x5F,0xFF,0xFF,0xFB, 0xFF,0xFF,0xEF,0xFF,0xFB,0xFE,0xFD,0xFF,
7510xFE,0xFF,0xFB,0xFF,0xFF,0xFF,0x7F,0xFF, 0xFE,0xBF,0xDF,0xFF,0xFB,0xFF,0xFF,0xF7,
7520xFC,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF2,0x7F,0xFF,
7530xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, 0xF3,0xFF,0xFF,0xFF,0xEF,0xFB,0xFF,0xFF,
7540xFF,0xDF,0xE2,0xFF,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFB,0xE7,0xFF,0xFD,
7550xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xED, 0xEF,0xFD,0xFF,0xFF,0xDF,0xD7,0xF5,0xFD,
7560x7F,0x5D,0xFD,0xFF,0x7F,0xDF,0x97,0xF4, 0xFD,0x7B,0x5F,0xFF,0xC9,0xFF,0xFB,0xFE,
7570xFF,0xBF,0xFF,0x5F,0xFF,0xFF,0xF7,0xFF, 0xEF,0xFD,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,
7580xFF,0xF7,0xFF,0xD7,0xFD,0x7D,0x7F,0xFF, 0xFF,0xFF,0xFF,0xEF,0xDF,0xF7,0xFD,0xFF,
7590xBB,0xFF,0xFF,0x7F,0xFF,0xFE,0xE3,0xFF, 0xF9,0xFE,0x7F,0xBF,0xEF,0xFB,0xFE,0xFF,
7600xBF,0xF9,0xFE,0xFF,0x9F,0xEF,0xF9,0xFE, 0xFF,0xBF,0xF3,0xDA,0xFF,0x37,0xCD,0xF3,
7610x7C,0xDF,0x37,0xCD,0xF3,0x7F,0x37,0xCD, 0xF3,0x7C,0xDF,0x37,0xCC,0xF3,0x7F,0x5A,
7620xBD,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFD, 0xBF,0x6F,0xDE,0xFD,0xBF,0x6F,0xDB,0xF6,
7630xFD,0xBF,0x6F,0xFE,0xF1,0x6F,0xEB,0x7A, 0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7,0xAF,
7640x7A,0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7, 0xFF,0x7E,0xFF,0xFE,0xCD,0xB3,0x6C,0xDB,
7650x36,0xCD,0xB3,0x6C,0xDE,0xCD,0xB3,0x6C, 0xDB,0x36,0xCD,0xB3,0x6C,0xDF,0xC9,0xBF,
7660xF7,0xBD,0xEF,0x7A,0x9E,0xA7,0xA9,0xEA, 0x7A,0xB7,0xBD,0xEA,0x7B,0xDE,0xA7,0xBD,
7670xCA,0x72,0x8D,0x91,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFE,0xF7,0xEF,0xFB,
7680xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFE, 0x87,0xFF,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,
7690xFD,0xBF,0x6F,0xF6,0xFD,0xBF,0x6F,0xDB, 0xF6,0xFD,0xBF,0x6F,0xFE,0x4F,0xFF,0xBF,
7700xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB,0xEF, 0xBE,0xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB,
7710xEF,0xFC,0x5F,0xFF,0xFF,0xFF,0x3F,0xCF, 0xF3,0xFC,0xFF,0x3F,0xCF,0xFC,0xFF,0x3F,
7720xCF,0xF3,0xFC,0xFF,0x3F,0xCF,0xFD,0x9F, 0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,
7730xEB,0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF, 0xAF,0xEB,0xFF,0xE1,0x6F,0xFD,0xFF,0x7F,
7740xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFD,0xFF, 0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,
7750x7A,0xBF,0xFB,0xFE,0xDF,0xB7,0xED,0xFB, 0x7E,0xDF,0xB7,0xFB,0x7E,0xDF,0xB7,0xED,
7760xFB,0x7E,0xDF,0xB7,0xFF,0xC9,0xFF,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,
7770xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEE, 0xFB,0xFE,0xBB,0xFF,0xFE,0xFF,0xBF,0xEF,
7780xFB,0xFE,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0x3F,0xCF,0xFF,0xE7,
7790xFE,0xFF,0xF5,0xFD,0x77,0x5D,0xD7,0x35, 0xDD,0x77,0xD7,0xF5,0xCD,0x7B,0x5D,0xD7,
7800xF5,0xDD,0x77,0xFE,0x27,0xFF,0xFF,0x8B, 0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9,0xAF,
7810x8B,0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9, 0xFE,0x1F,0xFF,0x5F,0xD7,0xF5,0xFD,0x7F,
7820x5F,0xD7,0xF5,0xFF,0x5F,0xD7,0xF5,0xFD, 0x7F,0x5F,0xD7,0xF5,0xFF,0xFA,0x3F,0xFE,
7830xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xEB, 0xEC,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,
7840xEB,0xFF,0xFE,0x7F,0xFD,0x7F,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
7850xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6, 0xFF,0xFA,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,
7860xF7,0xFC,0xFF,0xDF,0xF7,0xFD,0xFF,0x7F, 0xDF,0xF7,0xFD,0xFF,0xF5,0xFF,0xFF,0xFF,
7870xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
7880xFF,0x02,0xFF,0xFE,0xBF,0xAB,0xEB,0xFA, 0xBE,0xBF,0x23,0xEB,0xDE,0x1F,0xAF,0xEA,
7890xFA,0xFE,0xAF,0xAF,0xEB,0xFD,0x97,0xFF, 0xF3,0xFC,0x7B,0x1F,0xCF,0xF1,0xFC,0x7F,
7900x1F,0xF1,0xFC,0x77,0x1F,0xCD,0xF1,0xFC, 0xFF,0x1F,0xFE,0x87,0xFF,0xAF,0xEF,0xFA,
7910xFE,0xFF,0xAF,0xEF,0xFA,0xFD,0xBF,0x2B, 0xFB,0x7E,0xBF,0xBF,0xEB,0xFB,0xFB,0xFB,
7920xDF,0xFF,0xFB,0xF7,0xFF,0xFF,0x7F,0xF7, 0xF7,0xFF,0xFD,0xDF,0xFE,0xFC,0xDF,0xFF,
7930xDF,0xFF,0xFD,0xFF,0xDA,0xBF,0xFF,0xBB, 0xEF,0xFB,0xF9,0xFF,0xBE,0xEF,0xFB,0xFB,
7940xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xF7,0x7F,0xFD,0xD7,0xFF,0xFF,0x7F,
7950xFF,0xFF,0xFF,0xFE,0xF7,0xFF,0xFE,0xFF, 0xF7,0xFF,0xFF,0x7F,0xFF,0xFF,0xEC,0xFF,
7960xFF,0xFE,0xDF,0xBF,0xFF,0xFB,0xFE,0xFF, 0xBB,0x68,0xAE,0x1F,0xAE,0xFB,0xFB,0xFF,
7970xFF,0xBF,0xFF,0xD5,0xFF,0x7F,0xFF,0xFF, 0xF7,0xFE,0xFE,0xFF,0xBF,0xEF,0x9F,0xFD,
7980x7F,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF,0xFF, 0xBB,0xF7,0xBF,0xFF,0xFF,0xFF,0xFF,0xDF,
7990xFF,0xBF,0xFB,0xFF,0xFF,0xFF,0xDE,0x3F, 0xFF,0xFF,0xFF,0xFF,0xFF,0xA7,0xFF,0xFF,
8000xFF,0xFF,0xEF,0xFF,0x7F,0xFB,0xFD,0xFB, 0x7F,0xFF,0xFF,0xFF,0xFF,0xCF,0xF3,0x7C,
8010xFF,0x7F,0x8D,0x7F,0xFF,0xFF,0xFF,0xFF, 0xFB,0xFF,0xF7,0xFB,0xFE,0xFD,0xFF,0xFF,
8020xFF,0xFF,0xF7,0xFD,0xFF,0x7F,0xFD,0x1F, 0xFD,0xFF,0xFF,0xFF,0xFF,0xBF,0xDF,0xFF,
8030xFF,0xFE,0x5C,0xFF,0x6D,0xFF,0x7F,0xAB, 0xE7,0xF1,0xFF,0xFD,0x9F,0xFF,0xFF,0xAD,
8040xEB,0x7A,0x3F,0x1F,0xFF,0xFF,0xFE,0xBF, 0xAF,0xF3,0xDE,0xF5,0xFF,0x8F,0xFB,0xDF,
8050xE6,0x7F,0xFF,0xDF,0xF3,0xFD,0xFF,0x7E, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xF7,0xF3,
8060x7F,0xDF,0xF7,0xEF,0xFF,0xF6,0x3F,0x9F, 0xDF,0xFF,0xFF,0xEE,0xFF,0xFF,0xEF,0xFB,
8070xFF,0xFF,0xF9,0xFB,0xFE,0x4F,0xBF,0xEF, 0xBB,0xFF,0x69,0xAF,0xAF,0xFC,0xFF,0x3F,
8080xDD,0xFF,0xFC,0xBF,0x8F,0xFF,0xFD,0xF3, 0xBF,0xED,0x9E,0xFC,0xBF,0x6F,0xF5,0xD3,
8090xDF,0xFF,0xDB,0xD6,0xF5,0xEF,0xFD,0xFE, 0xFF,0xB9,0xFF,0x1F,0xD2,0xA9,0xAF,0xFF,
8100xDB,0xF7,0xBF,0xEF,0x46,0xFF,0xFF,0xAD, 0xEB,0x7A,0xDF,0xEF,0xF7,0xFF,0x7F,0xF7,
8110x9F,0xED,0xFF,0x7F,0xFF,0xAD,0xEB,0x7F, 0xF5,0x6F,0xFF,0xFD,0xFB,0xD6,0xF4,0xF7,
8120xFB,0xF9,0x7E,0x7F,0xFF,0x5F,0xC2,0xFE, 0xBF,0xFD,0xFB,0x33,0xDF,0xF9,0x5B,0xFF,
8130xFF,0xDD,0x67,0x7D,0xCF,0xEF,0xDB,0xEC, 0xFF,0x77,0xDD,0xF7,0xFD,0xFF,0xFF,0xDE,
8140xA7,0xBF,0xD4,0x9F,0xFF,0xFF,0xBF,0xEF, 0xFE,0xFF,0xDF,0xEF,0xBB,0xFF,0xFF,0xEF,
8150xEB,0xFA,0xFF,0xEF,0xBD,0xFB,0xFF,0xE2, 0x7F,0xFF,0xDF,0xDF,0xF7,0xFD,0xBF,0xBB,
8160x73,0xF7,0xFD,0x7F,0xDF,0xDE,0xF7,0xBF, 0xEA,0xDB,0xF6,0xFF,0xD6,0xFF,0xFF,0x66,
8170xFF,0xBE,0xFF,0xBF,0x6B,0xD9,0xF6,0xDF, 0xFF,0xFB,0x7E,0x7F,0xB7,0x7E,0xFF,0xFE,
8180xFF,0xCD,0xFF,0xFE,0x7F,0xFF,0xFC,0xFD, 0x3F,0xFB,0xFB,0xF7,0xFF,0xFF,0xFB,0xF6,
8190x7D,0xFE,0x7F,0xFF,0xFC,0xFF,0xB9,0xFF, 0xF9,0xFA,0xFE,0xBF,0xAF,0x5B,0xD6,0xED,
8200xAD,0x7B,0xF6,0xF9,0xBF,0xEF,0xF8,0xFA, 0xFE,0xBF,0xFE,0xE6,0xFF,0xFF,0xF7,0xFD,
8210xFF,0x7F,0xBF,0xEF,0xF3,0xFF,0xFF,0x6F, 0xF7,0xFE,0xFF,0xFF,0xF7,0xFD,0xFE,0xF7,
8220xEF,0xFF,0xFB,0xEF,0xFB,0x7E,0xDE,0xFE, 0xFF,0xBF,0xFF,0xFE,0xFF,0xFF,0xFB,0xFF,
8230xFF,0xEF,0xFB,0x6F,0xFC,0x1F,0xFE,0xE7, 0xFF,0xFF,0xFF,0xEF,0xFF,0xD3,0xB4,0xBB,
8240xFF,0xFF,0xFD,0xBF,0x6F,0xE3,0xFE,0xFF, 0xBF,0xFC,0xBF,0xF7,0xCF,0xF7,0xFD,0xFF,
8250x2F,0xDF,0xAB,0xEA,0xFF,0xDF,0xE7,0xEA, 0x9A,0xAF,0xEF,0xFB,0xFE,0xFF,0xF5,0x3F,
8260xFD,0x7E,0xFF,0xD7,0xF5,0xFB,0xFF,0xFD, 0xF7,0xFF,0x7F,0xFE,0xF7,0xFD,0xFF,0xD7,
8270xFF,0xD7,0x7F,0xEE,0x7F,0xFA,0x79,0xFE, 0x2F,0x8B,0xE6,0xF9,0xFE,0x3F,0x9E,0xF9,
8280xBE,0x2F,0x0B,0xE7,0xF9,0xFE,0x2F,0x9F, 0xFD,0xFF,0xFE,0x7D,0x7F,0x5F,0xD7,0xFF,
8290xFF,0x7F,0xFF,0xFD,0xFF,0x7F,0x5F,0x97, 0xFF,0xFD,0x7F,0x5F,0xFF,0xE3,0xFF,0xFF,
8300xFA,0xFE,0xBF,0xAF,0xFB,0xFB,0xFF,0xFF, 0xCF,0xEB,0xFE,0xBF,0xAF,0xFF,0xFA,0xFE,
8310xBF,0xFF,0x87,0xFF,0xFF,0xF5,0xFF,0xFF, 0xFF,0xFF,0xFD,0xFF,0x7F,0xFF,0xFF,0xFF,
8320xFB,0xFF,0xFF,0xF5,0xFF,0xFF,0xFE,0x0F, 0xFF,0xFD,0xEB,0xFF,0xFF,0xF7,0xFF,0xEF,
8330x7B,0xDF,0xFE,0xFF,0xFF,0xDF,0xF7,0xFD, 0xEB,0x7F,0xDF,0xFF,0x5F,0xFF,0xFF,0xFF,
8340xFF,0xFD,0xBF,0xFF,0x7E,0xFA,0xBF,0xC7, 0xDB,0xF7,0xBD,0x3F,0xFB,0xFF,0xF6,0xFF,
8350xFA,0xAF,0xFF,0xEB,0xFA,0xFE,0x3F,0x2F, 0xEA,0xFA,0x3E,0xAD,0xC9,0xBA,0xF6,0xAD,
8360xAF,0xEB,0xFA,0xF6,0xBF,0xFE,0x7F,0xFF, 0xFF,0xFD,0xFF,0xF1,0x7F,0x3F,0xCF,0xF1,
8370xEF,0xFF,0x7F,0xFF,0xBC,0xDF,0xDF,0xF7, 0xDD,0xFF,0xE0,0x7F,0xFF,0xFF,0xFE,0xFF,
8380xFA,0xEC,0xBB,0x7F,0x5F,0xFF,0xFB,0xEC, 0xFF,0xEF,0xB7,0xFF,0xF7,0xFF,0xFF,0xB5,
8390xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xEE,0xDF, 0x5F,0xDF,0xDE,0xFF,0xAE,0xE7,0x77,0xFF,
8400xFF,0xDF,0xF7,0xFF,0xE3,0xFF,0xFA,0xBB, 0xFE,0xFF,0xAF,0xFD,0xFB,0xFE,0xBF,0xAB,
8410xF9,0xFE,0xFF,0xBF,0x7F,0xBF,0xFE,0xBD, 0xFE,0xD7,0xFF,0x9F,0xFD,0xFF,0xBE,0xEF,
8420xFF,0xEE,0xFD,0xBB,0x5B,0xEF,0xFF,0x7F, 0xEF,0xFF,0xEF,0xFF,0x7F,0xFF,0x4F,0xFF,
8430xEF,0xFB,0xBC,0xFC,0xFF,0xFF,0xFF,0xFE, 0xFE,0xFD,0xFA,0xFE,0xFB,0xFF,0xFD,0xF3,
8440xFB,0xFF,0xF8,0x5F,0xFF,0xFF,0xD7,0xF5, 0xFD,0xDF,0xEF,0xFF,0xF3,0xDC,0x5F,0xCE,
8450xF5,0xBD,0xFF,0xFF,0xD7,0xFF,0xFF,0xF9, 0x3F,0xFF,0xDF,0xF7,0xFF,0xFE,0xFF,0xFD,
8460xFF,0xFB,0xFF,0xF7,0xB9,0x7D,0xFE,0xDF, 0xFF,0xFF,0xFF,0xFF,0xF9,0x7F,0xFF,0xFE,
8470xFF,0xFF,0x7F,0xFF,0xFE,0xFF,0xFF,0xF7, 0xF6,0xFF,0xBF,0xF1,0xF8,0xFF,0xFF,0xFF,
8480xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF, 0xFF,0xFF,0xFF,0xFF,0xEF,0xEF,0xFF,0xFF,
8490x9B,0xFB,0x7F,0xFF,0xFF,0xFF,0xC1,0xFF, 0xDF,0xFF,0x3F,0x5F,0xD7,0xBF,0xEF,0xBB,
8500xDE,0xEE,0xFF,0x7F,0xDF,0xFF,0xFE,0xF5, 0x7F,0xDF,0xFF,0x99,0xFF,0xFF,0xFA,0xFF,
8510xBF,0xFD,0xEB,0x7A,0xFF,0xB7,0xFE,0xFE, 0xFF,0xFF,0xEF,0xFF,0xFF,0xFD,0xBF,0xFF,
8520x97,0xFF,0xFD,0xF7,0xFF,0x7F,0xF7,0xFF, 0xFF,0xFD,0x5F,0xFE,0xF3,0xF9,0xDF,0xDF,
8530xFF,0xFF,0xFC,0xFF,0xFF,0x83,0xFF,0xFF, 0xFE,0xFF,0x9E,0xEC,0xFB,0xEE,0xFF,0x9F,
8540xBF,0xEF,0xFF,0xFE,0xED,0x7B,0xFF,0xFF, 0xFF,0xF1,0x5A,0xFF,0xFF,0xFD,0xFF,0x7C,
8550x69,0x3B,0xDF,0xFF,0x7F,0x1F,0xDF,0xFF, 0xFD,0xBA,0xFF,0xFF,0xFB,0xFF,0x5B,0xBD,
8560xFF,0xFF,0xFF,0xFF,0xD7,0xB6,0xED,0xE9, 0xFF,0xD6,0xBD,0x6F,0x5F,0xFB,0xFF,0xEF,
8570xFF,0x5F,0xFE,0xF6,0x6F,0xFF,0xFF,0xFF, 0xFF,0xF7,0xEB,0x7A,0xDF,0xFF,0x9F,0x7F,
8580x7F,0xFF,0xB7,0xFF,0xFF,0xFE,0xDF,0xFF, 0x6C,0xFF,0xFB,0xFF,0xBB,0x6F,0xEB,0xFE,
8590xCC,0xF7,0xA5,0xFA,0x5C,0xF5,0x75,0xBB, 0xB7,0xDF,0xFE,0x6F,0x5F,0xC5,0xBF,0xFD,
8600x7B,0xFE,0xFF,0x95,0xE7,0x29,0xCF,0x4F, 0xF5,0x91,0xEE,0x6B,0xDF,0xEF,0xFD,0x54,
8610xF5,0xBD,0xB1,0xFF,0xEF,0xEE,0xFB,0xBE, 0xBF,0xAF,0xFE,0xDE,0xBD,0x6F,0xDA,0xF2,
8620xFF,0xAF,0xBE,0xFF,0xFF,0xFD,0x7E,0xA7, 0xFF,0xF7,0xFF,0xBF,0xEF,0x7B,0xF6,0xFD,
8630xBD,0x4A,0xF2,0x85,0x85,0xBF,0x5B,0xFE, 0xB5,0xFD,0xFA,0xFF,0x4F,0xFF,0xFE,0xDF,
8640xFF,0xED,0xFF,0xBF,0xFF,0xBF,0x7F,0xFE, 0xFF,0xB7,0x6D,0xFF,0xF7,0xBF,0xBF,0xEF,
8650xFD,0x1F,0xFF,0xFE,0x7D,0xFF,0x67,0xFF, 0xFF,0xFF,0x3F,0x7F,0xFE,0xBF,0xFF,0xE7,
8660xDF,0xE7,0xFF,0xEF,0x6B,0xFC,0x1F,0xFF, 0xBF,0xEF,0xFB,0xFE,0xDE,0xBF,0xAF,0xFA,
8670xFF,0xB6,0xEF,0xF9,0xFE,0xFF,0x8F,0xEF, 0xDB,0xEF,0xAB,0x6F,0xFB,0xFE,0xFF,0xFF,
8680xEF,0xFD,0xFF,0x7F,0xFF,0xFF,0xDE,0xFF, 0xFF,0xEF,0xFF,0xFF,0xFF,0x3F,0xFF,0x6C,
8690xFF,0xBF,0xFB,0xFF,0xFE,0xFF,0xFB,0xFE, 0xDF,0xFF,0xFF,0xEF,0xFF,0xFF,0xBF,0xFF,
8700xFF,0xFE,0xFB,0xFF,0xD5,0x7F,0xFF,0xFF, 0xEF,0xFB,0xFF,0xFF,0xBF,0xEF,0x43,0xB5,
8710xFD,0x6F,0xCF,0xD6,0xBE,0x3F,0x7F,0xDB, 0xFE,0xC3,0xFF,0xFD,0xFF,0xAF,0xEB,0xFB,
8720xFC,0xFF,0x3E,0xEF,0xE8,0xFA,0xBD,0xCD, 0xAA,0xFE,0xFE,0x7D,0xCF,0xFF,0xB7,0xFF,
8730xF7,0xFF,0xFF,0xFF,0xFD,0xFF,0x75,0xCD, 0x52,0xD7,0xFD,0xFB,0xF7,0xDD,0xFB,0xEF,
8740xEB,0xFF,0xFF,0x4F,0xFF,0xBF,0x9F,0xE7, 0xF9,0xFC,0x7F,0x8B,0xC3,0xF9,0xAF,0x8F,
8750xE7,0xE9,0xBE,0x7F,0x9F,0xE6,0xF9,0xFC, 0x5F,0xFF,0xFF,0xF7,0xFD,0xFF,0x7A,0x5F,
8760xD7,0xED,0xFF,0xFF,0xD7,0xFF,0xDD,0x7F, 0xE7,0xFF,0xFC,0xFF,0xFC,0x3F,0xFF,0xFF,
8770xFF,0xFB,0xFF,0xFE,0xBF,0xAF,0xFF,0xFD, 0xFF,0xEF,0xFF,0xEB,0xFF,0xFF,0xFF,0xFF,
8780xFF,0xF7,0x7F,0xFF,0x7F,0xDF,0xFF,0xFD, 0xFD,0x7F,0xFE,0xF7,0xFD,0x7F,0xDF,0xFF,
8790xFD,0xFF,0xFF,0xDF,0xFB,0xFF,0xEE,0xFF, 0xFB,0xFF,0xF7,0xFD,0xFF,0x7A,0xDF,0xF5,
8800xFD,0xFA,0xDF,0xF7,0xFC,0xFF,0x7F,0xDF, 0xBF,0xED,0xFF,0xC9,0xFF,0xDF,0xFF,0xBF,
8810x2F,0xFB,0xFF,0xBC,0xAD,0xFF,0xF7,0xFF, 0xFF,0xEF,0xD3,0xFF,0x7D,0xBF,0x6F,0xFF,
8820xFA,0xFF,0xFE,0xBF,0xAE,0xEA,0xFA,0xBE, 0xAD,0xA5,0xEB,0xCE,0xBF,0xA7,0xEB,0x5A,
8830xDE,0xBD,0xAF,0x6B,0xFD,0x57,0xFF,0xFF, 0xF4,0x7F,0x1F,0x7F,0xFD,0xFF,0x7F,0x36,
8840xF0,0xDF,0x79,0xFF,0xFF,0xFF,0xF7,0xFD, 0xBF,0xFF,0x87,0xFF,0xFB,0xF3,0xFC,0xFF,
8850xFF,0xFF,0xFF,0x7E,0xFF,0xBF,0xDF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xF8,0x9F,
8860xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFD, 0xF7,0xFC,0xBD,0xFF,0xFE,0xFF,0xFF,0xFF,
8870xFF,0xFF,0xFB,0xF9,0xBF,0xFF,0xFF,0xEB, 0xE2,0xFE,0xFF,0xBF,0xEF,0xA9,0xBA,0x2F,
8880xEB,0xF9,0xFE,0x77,0xDF,0xF7,0xFF,0xFF, 0xF9,0x7F,0xFF,0xFF,0x7F,0xEF,0xD7,0xFF,
8890xFD,0xFF,0xFB,0xF5,0xFF,0xBF,0x6F,0xDF, 0xFF,0xFF,0xFD,0xFF,0xFF,0xF0,0xFF,0xFF,
8900xFF,0x3F,0xCF,0xFF,0xBA,0xEE,0x9B,0xBF, 0xEE,0xD7,0xFE,0xCD,0xEF,0xFF,0xDF,0xBF,
8910xFF,0xFF,0xC5,0xFF,0xFF,0xFD,0x7F,0x4F, 0xFD,0xF6,0xD9,0xFF,0x4F,0xD6,0xFD,0xBF,
8920x6E,0xFF,0xFF,0xF4,0x7F,0xFF,0x7F,0x8B, 0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xF9,0xFE,
8930x37,0xFF,0xD9,0xFB,0xF5,0xAF,0xFD,0xFF, 0xFF,0xFB,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,
8940xFB,0xF7,0xFF,0xFD,0xFF,0x7C,0xFA,0x7E, 0x4F,0xFC,0xDF,0x1D,0xC7,0xFF,0xFF,0xFF,
8950xFF,0xAE,0xFF,0xFF,0xFF,0xFF,0xFD,0xFB, 0xFF,0xFF,0xFE,0xFE,0xFC,0xFF,0x7F,0x7F,
8960xBF,0xEF,0xFE,0xFF,0xFF,0xFF,0x5F,0xFD, 0xFF,0xFF,0xFF,0xFD,0x6F,0x5A,0xD7,0x7B,
8970xBE,0x5F,0xFE,0x39,0xFF,0xF7,0xFF,0xF7, 0xFD,0xFE,0xAA,0x1F,0xFF,0xFF,0xFF,0xFF,
8980xFE,0xFE,0xAB,0xAF,0xFD,0xFE,0xBF,0xFF, 0xF7,0xFF,0x7F,0xFE,0x8F,0xE3,0xFB,0xEE,
8990x7F,0xFF,0xFF,0xFF,0xFF,0xEB,0xFB,0xFF, 0xFD,0xBF,0xEF,0xDF,0xFF,0xFF,0xFF,0xFF,
9000xFF,0xFF,0xFF,0xFB,0xE4,0x3F,0xFF,0xDF, 0xFF,0xFF,0xFF,0xFF,0xF3,0xEF,0xBB,0xFB,
9010xBF,0xEF,0xBB,0xFF,0xD7,0xBF,0xFF,0xFF, 0xFF,0x29,0xAF,0xF7,0xFF,0xFF,0xFB,0xFF,
9020xFB,0xE6,0xFF,0x0F,0xFB,0x3F,0xDF,0x0F, 0xFF,0xAF,0xFF,0xFF,0xFF,0xF5,0xC3,0xDF,
9030x5F,0xFF,0xFF,0xFF,0xFE,0x6B,0xCA,0xBE, 0xBC,0xFF,0x9F,0xF2,0xBF,0xFF,0xFE,0xFA,
9040xFF,0xFF,0xEF,0x16,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFC,0xDF,0x97,0xFD,0x79,0xFF,0x37,
9050xE7,0x7F,0xFF,0xFF,0xB5,0xFF,0xFF,0xF6, 0x2F,0xFF,0xFD,0xFB,0xFE,0xFF,0xFF,0xFD,
9060x5F,0x57,0x5F,0xFF,0xDB,0x52,0xDF,0xFF, 0xFD,0xBF,0xFF,0xFF,0xFC,0xDB,0xFF,0x7B,
9070xB5,0xFD,0x7F,0xFF,0x71,0x9C,0x6E,0xFF, 0xF6,0x35,0xA5,0x9B,0xFF,0xFF,0xFD,0xFF,
9080xFF,0xDB,0x9E,0x7F,0xFE,0xEF,0xFB,0xFF, 0xFF,0xBD,0xEF,0xFF,0xDE,0xB7,0xF9,0x4B,
9090xFF,0xF5,0xEF,0xFF,0xFF,0xFF,0xE8,0x7E, 0xFF,0xEA,0xDF,0xF7,0xFF,0xFD,0x69,0x5B,
9100xFC,0x9F,0xEF,0x78,0xD6,0xFF,0xEB,0xEF, 0xFF,0xFF,0xFF,0xE8,0xFF,0xFF,0xED,0xFF,
9110xFF,0xFF,0xFF,0xE3,0xF9,0xF6,0xBF,0xFF, 0xFF,0xFE,0xDF,0xFF,0x7F,0xFF,0xFF,0xFF,
9120xD1,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF, 0xE7,0xF9,0xFF,0xBF,0x7F,0xD9,0xFF,0xFD,
9130xFE,0x7F,0xFF,0xFE,0xFF,0xF9,0xFF,0xFB, 0xD6,0xDF,0xBF,0xEF,0x5B,0xD6,0xFF,0xBF,
9140xFB,0xF6,0xFF,0xBF,0xEF,0xF8,0xF6,0xDD, 0xBE,0xFE,0x16,0xFF,0xBF,0xEF,0xFF,0xFE,
9150xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0x6F,0xFB, 0xFF,0xFF,0xFF,0x6F,0xF3,0xFF,0xF7,0xEF,
9160xFB,0xFF,0xBF,0xFF,0xEF,0xFE,0xFF,0xBF, 0xFF,0xFF,0xFF,0xBE,0xBF,0xFF,0xEF,0xFF,
9170x7F,0xEF,0xFF,0xFD,0x17,0xFB,0x7B,0xFF, 0xFF,0xFD,0x7F,0xDB,0xF6,0xF4,0x7F,0xFA,
9180xFE,0xF5,0xBF,0xEB,0xE3,0xF7,0xFF,0xFF, 0xE9,0xBF,0xFF,0xAF,0xF7,0xFD,0xF3,0x7E,
9190x8F,0xA3,0xEA,0xFF,0xCB,0xF3,0xEE,0xFF, 0xBF,0xEF,0xF7,0xF9,0xFF,0xFE,0x7F,0xFF,
9200xFF,0xFF,0xFF,0xF5,0xFB,0xF6,0xFF,0xF5, 0x2F,0xFE,0xFB,0xD7,0xBF,0xFF,0xBE,0xDF,
9210x9F,0xFF,0xF0,0xFF,0xFF,0xF9,0xFE,0x7F, 0x8F,0xA3,0xF8,0xFE,0x6F,0x9F,0xF9,0xF6,
9220x2F,0x9F,0xE7,0xF9,0xFE,0x2F,0x9F,0xE1, 0xFF,0xFF,0xFF,0x7F,0xDF,0xF7,0xF5,0xFD,
9230x7F,0x7F,0xF5,0xFF,0x9F,0x5F,0xFB,0xFE, 0xFF,0x7F,0xFF,0xFF,0xCB,0xFF,0xFF,0xFB,
9240xFE,0xFF,0xBF,0xAF,0xFB,0xFE,0xFF,0xDF, 0xFE,0xFE,0xBF,0xF7,0xFF,0xFF,0xFF,0xFF,
9250xFF,0xC7,0xFF,0xFF,0xFD,0xFF,0x7F,0xDD, 0xF7,0xFD,0xFF,0xFF,0xD7,0xFF,0xFD,0x7F,
9260xFF,0xFB,0xFD,0xFF,0xFF,0xFE,0xEF,0x7F, 0xFD,0xEF,0xFB,0xFE,0xFB,0xFD,0xFF,0x7F,
9270xDF,0xFD,0xFF,0x7A,0xDF,0xF7,0xFD,0xFF, 0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xD3,0xF7,
9280xFF,0xFF,0x6F,0xDB,0xFF,0xFF,0xEF,0xCB, 0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
9290x29,0xFF,0xE8,0xDA,0x76,0x9F,0xAF,0x6A, 0xDA,0xFE,0x35,0xEB,0xDA,0xD6,0xBF,0xAB,
9300xEB,0x7A,0xDE,0xBF,0xD7,0x7F,0xFF,0xFE, 0xFF,0xBF,0xEF,0xFD,0xDF,0x77,0xBF,0xFD,
9310x37,0xEF,0xFF,0xEF,0xFF,0x3F,0xFF,0xFF, 0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xF7,0x7E,
9320xDF,0xFF,0xFF,0xFF,0xFA,0xB7,0x7F,0xFF, 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x89,0xFF,
9330xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x9F,0xFB,0xFF,0xFF,0xFF,0xE7,0xFF,
9340xFF,0xFF,0xFF,0xAA,0xFF,0xAB,0xFB,0xFA, 0xEF,0xBF,0xFF,0xDF,0xFA,0x7B,0xB9,0xFE,
9350xFE,0xFF,0xFD,0xFF,0xF7,0xFE,0x3F,0xFF, 0xB7,0xFF,0xF7,0xEE,0xFF,0x7F,0xEF,0xFF,
9360xFF,0x7F,0xFF,0x1F,0xFB,0xFF,0xBF,0xFB, 0xFE,0xFF,0xBD,0xFF,0xFF,0x2F,0xFF,0xBF,
9370xFF,0x7F,0xDF,0xFA,0xFF,0xFF,0xFC,0xEE, 0xF5,0xF3,0xBE,0xFB,0x0F,0xEF,0xF3,0xBE,
9380xEF,0xFC,0x5F,0xFF,0x5A,0xFF,0xF7,0xDF, 0xFF,0xFF,0xFE,0xD5,0xFC,0x5F,0xFB,0xF2,
9390xFF,0xFF,0x2F,0xBB,0xF3,0xFF,0xFF,0xBF, 0xFF,0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,
9400xBF,0xFF,0xFF,0xFD,0x7B,0xFF,0xDF,0xB9, 0xFF,0xFB,0xFF,0xD8,0x7F,0xFF,0xFF,0xFF,
9410xFB,0xFF,0xFC,0x7F,0x1F,0xBF,0xE0,0xDF, 0xF7,0xEF,0xFF,0xFD,0x7F,0xFE,0xDF,0xFF,
9420xE0,0xFF,0xFF,0xFD,0xEF,0xFB,0xFF,0xFE, 0xF7,0xDF,0xFF,0xEB,0x5F,0xFF,0xF7,0xFF,
9430xFF,0xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0xFD, 0xFF,0xFF,0xFF,0xF7,0xFD,0xFF,0x3B,0xDC,
9440xFD,0x6D,0x7B,0x5F,0x57,0xF5,0xFD,0x7F, 0x5F,0xFF,0xB1,0xFF,0xEB,0xFF,0xFF,0xFF,
9450xFB,0xFB,0xFE,0xFF,0xBF,0xFB,0xBE,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFF,0xAF,0xFE,0xF7,
9460xDF,0xDF,0xFF,0xFF,0xFF,0x7F,0xCF,0xF3, 0xF8,0xFF,0xD7,0xFB,0xFF,0x5F,0xBF,0xF7,
9470xFB,0xFF,0x7F,0xFE,0x23,0xFF,0xFF,0xFE, 0x7F,0xF3,0xFF,0xFB,0xFE,0xFF,0xFF,0xF3,
9480xFF,0xFF,0xF5,0xF9,0xFF,0x3F,0xFF,0xFF, 0xF0,0x9A,0xFF,0xBE,0x7F,0xFF,0xFC,0xF9,
9490xFF,0xFD,0xAF,0xEB,0xFE,0xBF,0xFF,0xCF, 0xF3,0xFE,0x7F,0xFF,0xFF,0x5B,0xBD,0xFF,
9500xBC,0xEB,0xFF,0xD7,0xD4,0xAF,0xAF,0xFD, 0xFF,0xCF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7,
9510xFD,0xFE,0xFF,0x6F,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFD,0x7F,0x5E,0xFD,0xBF,0xDB,0xF6,
9520xFD,0xBF,0x6F,0xFB,0xEE,0xFD,0xFF,0x7A, 0xFF,0xFA,0xFB,0xFF,0x3F,0xFB,0xB7,0x5F,
9530xD6,0xF7,0x1F,0x71,0xDC,0x77,0x1D,0xC7, 0x31,0xDC,0x77,0xDF,0xF9,0xBF,0xF5,0x5B,
9540xF4,0xD7,0x9D,0xAE,0xFF,0xBF,0xFD,0xBF, 0xDB,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFE,
9550x3D,0x81,0xFF,0xEB,0xFE,0xFE,0xFE,0xFF, 0xEB,0x7A,0xDF,0x7D,0x77,0x7D,0xF5,0x79,
9560xDF,0x57,0xDD,0xF5,0x7D,0x7E,0xE6,0xFF, 0xD6,0x3F,0xBF,0x7F,0xFF,0xD4,0xF5,0x3F,
9570xBF,0xFB,0xBE,0xEF,0xB3,0xEE,0xFB,0x9E, 0xEF,0xBB,0xFE,0x8B,0xFF,0xFE,0xDF,0xB7,
9580xED,0xFF,0xF7,0xFD,0xFE,0xFF,0xEF,0xBB, 0xEE,0xFF,0xBE,0xEF,0xBB,0xEE,0xEB,0xFC,
9590x1F,0xFF,0xFF,0xFD,0xFF,0xE7,0xFF,0xF7, 0xFD,0xFF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB,
9600xFE,0xFF,0xBF,0xEB,0xFA,0x1F,0xFF,0xB7, 0xEF,0x5B,0xFE,0xFF,0xAF,0xEB,0xDD,0xE7,
9610xDE,0x77,0x9D,0xE7,0x79,0xDE,0x77,0x9D, 0xBF,0xE6,0x6F,0xFF,0xFE,0xFF,0xBF,0xEF,
9620xFB,0xFE,0xFD,0xBF,0x6F,0xF6,0xFD,0xBF, 0x6F,0xDB,0xF6,0xFD,0xBF,0xFF,0x7E,0xFF,
9630xFF,0xFB,0xFE,0xFE,0xFF,0xEF,0xFB,0xFD, 0xEF,0x7E,0xF7,0xBD,0xEF,0x7B,0xDE,0xF7,
9640xBD,0xEF,0xFF,0xD5,0xFF,0xBF,0xFF,0xEF, 0xFE,0xFF,0xFC,0x3F,0x0F,0xE7,0xFE,0x7F,
9650x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFE, 0xF3,0xFF,0xFE,0xDF,0xAD,0xDF,0x67,0xEE,
9660xFB,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFE,0xFF,0xBF,0xEF,0xFF,0x23,0xFF,0xFF,
9670xFF,0xFF,0x7F,0xFF,0xF3,0xBC,0xDB,0xFE, 0xFB,0xFF,0xFB,0xBE,0xF7,0xFB,0xFF,0x7F,
9680xDF,0xFF,0xCF,0xFB,0xFF,0x9F,0xE3,0xF9, 0xBE,0x3F,0x8F,0xE7,0x79,0xFF,0x9D,0xE7,
9690xF9,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x5F, 0xFF,0xCF,0xF7,0xFF,0xFF,0xFF,0xDF,0xF7,
9700xFE,0x7F,0xE7,0xF9,0xFE,0x7F,0xFF,0xFF, 0xFB,0xFE,0xFF,0xFF,0xBF,0xFF,0xBF,0xBF,
9710xFF,0xFE,0xFF,0xBF,0xEF,0xFF,0xFD,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFD,0xFF,
9720xFF,0x3F,0xFF,0xBF,0xFF,0xF7,0xFF,0xFF, 0x7F,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
9730xFF,0xFF,0xFF,0xFF,0xFF,0xE8,0xEF,0xFF, 0x5F,0xF7,0xBF,0xF9,0xFE,0xDF,0xB7,0xFD,
9740xFF,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0xDD,0xFF,0xF2,0xFF,0xBF,0xFF,
9750xFF,0xBF,0xFF,0xFF,0x2F,0xF2,0xFF,0xBF, 0x2F,0x7B,0xD2,0xF7,0xBF,0x2F,0xFF,0xBB,
9760xFF,0xEE,0x8F,0xAF,0xEB,0xFA,0xFE,0x3F, 0xA7,0x69,0xCE,0x8F,0xA4,0xEA,0xFA,0xEE,
9770xB7,0xAE,0xEB,0xFD,0xC7,0xFF,0xF7,0xF7, 0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3E,0xF3,
9780x74,0xFF,0x3F,0x4F,0xFF,0xE7,0xFF,0x3F, 0xFE,0xA7,0xFF,0xFF,0xDF,0xF7,0xB7,0xFF,
9790xF7,0xFF,0xBA,0xEF,0x37,0xEB,0xFB,0xFE, 0xBF,0xFB,0xFE,0xF3,0xFF,0xF9,0xDF,0xFF,
9800xBF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF, 0xFD,0xDF,0xFF,0xFD,0xFF,0xFF,0xFB,0xFE,
9810xFD,0xFF,0xFB,0xBF,0xFE,0x3F,0xED,0xFF, 0xDF,0xBE,0x3D,0xA7,0xFB,0xFA,0x3F,0xE6,
9820xE1,0xFE,0xFE,0x3F,0xEF,0xE3,0xDF,0xF5, 0x7F,0xFE,0xFF,0x7E,0xFF,0xFF,0xFF,0xFF,
9830xEF,0x6F,0xF6,0xFF,0x7D,0xEF,0xD7,0xDE, 0xFF,0x7D,0xEF,0xFF,0xF2,0xFF,0xFF,0xFF,
9840xFF,0xFF,0xFF,0x7B,0xDE,0xFB,0xE6,0xEE, 0xEF,0x37,0x6E,0xF3,0x7E,0xEB,0x37,0xEF,
9850xFF,0xC1,0xFF,0xFE,0xFF,0xF7,0xEF,0xFF, 0xFF,0xFF,0xBF,0x3F,0xD2,0xDF,0xBF,0x2F,
9860x7B,0xE2,0xFF,0xFE,0x3B,0xBD,0xDB,0xFF, 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFE,
9870xFF,0xFB,0xFF,0xFF,0xBF,0xFF,0xFB,0xDF, 0xFF,0xBF,0xFF,0xB7,0xFF,0xFF,0xBF,0xEF,
9880xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF, 0x7F,0xFF,0x1F,0xEF,0xF1,0xFD,0xFF,0xF6,
9890xAF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF, 0xFF,0xFF,0xFE,0x9F,0xFF,0xFF,0xFF,0x77,
9900xEF,0xF7,0xFB,0xFF,0xFE,0x5F,0xFF,0xFF, 0xBF,0xCF,0xFB,0xF7,0xDD,0xF7,0xF5,0xFF,
9910x5F,0xD5,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5, 0xFF,0xFB,0x0F,0xFF,0xFF,0xA9,0xEA,0x7A,
9920xFF,0xAF,0x8F,0xFE,0xDF,0xAF,0xEF,0xFB, 0xFE,0xFF,0xBF,0xEF,0xFB,0xDF,0xE5,0x5F,
9930xFF,0xFF,0xFF,0xFF,0xFF,0xBD,0x57,0xFF, 0xFF,0x6F,0x77,0xBF,0xF7,0xFB,0xFF,0x7F,
9940xBF,0xF7,0xFF,0xFC,0xBF,0xFF,0x9F,0xFF, 0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF,0x1F,
9950xCF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFF,0xFB, 0x65,0xAF,0xF3,0x7C,0xFF,0x3F,0xDF,0xFF,
9960xFD,0xE9,0xFE,0x7F,0xE7,0xFF,0xFE,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFD,0xE3,0xDF,0xFB,
9970xDB,0xF6,0xFD,0xEF,0x5B,0xFB,0xFF,0xDF, 0xFC,0xFF,0x3F,0xDF,0xF3,0xFD,0xFF,0x7F,
9980xDF,0xEF,0x66,0xFF,0xDF,0xAD,0xEB,0x7A, 0xDE,0xF7,0xF7,0xE7,0xD9,0xFD,0x9F,0x67,
9990xD9,0xF6,0x7D,0x9F,0xE7,0xDF,0xF5,0x47, 0xFD,0x65,0x5B,0xD6,0xF4,0xFE,0xFF,0xEF,
10000xFF,0x6D,0xF6,0xDD,0xB7,0x6D,0xDB,0x76, 0xDC,0xB7,0x7D,0xFA,0x9B,0xF6,0x6D,0x9D,
10010x67,0x59,0xDF,0xF7,0xDD,0xFF,0xEB,0xFE, 0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xE3,
10020xD1,0x9F,0xFF,0xBD,0xBF,0xEF,0xFE,0xF7, 0xBF,0xBF,0xF7,0xD7,0x7F,0xDD,0xF7,0x9D,
10030xDF,0x7F,0xDF,0xF7,0xFF,0xE0,0x7F,0xFD, 0xC1,0xDF,0xF7,0xFD,0xC7,0x7F,0x7F,0xFB,
10040xFF,0xBB,0xEC,0xFB,0x3E,0xFF,0xBF,0xEC, 0xFB,0xFF,0xD8,0x7F,0xBF,0x6C,0xFF,0xBE,
10050xFF,0xBF,0xED,0xFF,0xEF,0xFE,0xFB,0xBF, 0xEF,0xFB,0xFE,0xFF,0xBF,0xEE,0xFF,0xC5,
10060xFF,0xAF,0x6F,0xFF,0xFC,0xFD,0x3F,0xE7, 0xFF,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF,
10070xEF,0xFB,0xFE,0xBF,0x89,0xFE,0xFA,0xBA, 0xFE,0xBF,0xAF,0xFB,0xF6,0xF5,0xD9,0x7D,
10080x97,0x65,0xD9,0x74,0x5D,0x97,0x65,0xD3, 0xFE,0xD6,0xFF,0xBF,0xF7,0xFD,0xFF,0x7F,
10090xBF,0xCF,0xFB,0xFE,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFF,0xF6,0x8F,0xFB,
10100xFF,0xEF,0xFB,0x7E,0xDB,0xFE,0xFF,0xBE, 0xEF,0xEE,0xFB,0xBE,0xEF,0xBB,0xEE,0xFB,
10110xBE,0xFF,0xFF,0xDF,0xFF,0x43,0xFF,0xFF, 0xFB,0xEF,0x5F,0xB7,0xFE,0x7F,0xE7,0xF9,
10120xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xF9, 0xBF,0xFE,0xAF,0x77,0xFD,0xFF,0x2F,0xAF,
10130xA7,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0xF1,0x7F,0xEF,0xDF,
10140xFF,0x97,0xF5,0xEF,0xFF,0xDF,0xFF,0xFF, 0xBF,0xFF,0xBF,0xFF,0xFF,0xFE,0xFF,0xFF,
10150xFF,0xE0,0xFF,0xFF,0xF9,0xFE,0x2F,0x8B, 0xE3,0xF8,0xBE,0x77,0x9F,0xF9,0xDA,0x77,
10160x9D,0xE7,0x79,0xDE,0x77,0x9F,0xDD,0xFF, 0xFD,0xFD,0x7F,0x5F,0xD7,0xFD,0xFF,0x7F,
10170xE7,0xFE,0x7F,0x97,0xE7,0xFB,0xFE,0xFF, 0xBF,0xEF,0xFF,0xAB,0xFF,0xEF,0xFA,0xFE,
10180xBF,0xAF,0xFF,0xFA,0xFF,0xFF,0xDF,0xFF, 0xFB,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,
10190x67,0xFF,0xF7,0xF5,0xFF,0xFF,0xFF,0xDF, 0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
10200xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xBD, 0xEB,0xFF,0xFF,0xF7,0xAD,0xEB,0xFF,0xDF,
10210xFD,0xFF,0x3F,0xDF,0xF7,0xFD,0xFF,0x7F, 0xDF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0xFD,
10220xBF,0xFF,0xCB,0xF4,0xFF,0x7F,0xD3,0xF7, 0xFD,0x3F,0x7F,0xD3,0xF7,0xFF,0xFC,0x3F,
10230xFF,0xEA,0xFA,0xBE,0xAF,0xAB,0xEB,0xBA, 0xF4,0x95,0x6B,0x52,0xD4,0xAD,0x2F,0x4A,
10240xD2,0xF6,0xBF,0xD2,0x7F,0xF7,0x3F,0xFF, 0xFF,0xF3,0x7F,0xFF,0xFF,0xF7,0xFF,0xBA,
10250xDF,0xFB,0xFD,0xFF,0xBF,0xFF,0xFB,0xFF, 0xF8,0x7F,0xEA,0xFF,0xFE,0xFE,0xDF,0xFF,
10260xF7,0xFF,0x7F,0xBB,0xFF,0xFF,0xBF,0xDF, 0xFB,0xFF,0xFF,0xBF,0xFF,0xB1,0x7F,0xFF,
10270xFB,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF, 0xCF,0xFE,0xFF,0xFF,0xEF,0xFF,0xF7,0xFF,
10280xFF,0xFF,0xF1,0xFF,0x69,0xBE,0xFA,0xBF, 0xAF,0xE2,0xFF,0xFE,0xFD,0xAF,0xF3,0xFE,
10290xFF,0xBF,0xEF,0xFB,0xFC,0xFF,0xFF,0x07, 0xFD,0x95,0xDB,0xDF,0x7F,0xDF,0xAF,0xFF,
10300xF7,0xAF,0x36,0xFE,0xBF,0x65,0xEB,0xF6, 0xFE,0x9F,0x6F,0xFE,0x07,0xFF,0xCF,0xFF,
10310xF8,0xFE,0xFF,0xCF,0xFF,0xF6,0xFA,0xE7, 0xFB,0xFE,0xFF,0xBB,0xED,0xF9,0xFF,0xFF,
10320xFF,0x5F,0xFF,0xFF,0xFF,0x75,0xFF,0xEF, 0x7E,0xFD,0xE0,0xE8,0x5E,0xD3,0xE5,0xF9,
10330x3E,0x5F,0xD7,0xF7,0xFF,0xFA,0x2F,0xFB, 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0x7F,
10340x7F,0xD7,0xF5,0x7D,0x5F,0x57,0xD5,0xF5, 0xEF,0xFF,0xF3,0x7F,0xFC,0x7F,0xFF,0xC7,
10350xF1,0xFF,0xFF,0x1F,0xCF,0xB0,0xFF,0x3F, 0xCF,0xF3,0xFC,0xFF,0x3F,0xCE,0xFF,0xE4,
10360xFF,0xDF,0x7F,0xFE,0xF7,0xBB,0xFF,0xFF, 0xDF,0xEF,0xEE,0xFF,0xBF,0xEF,0xFB,0xFE,
10370xBF,0xBF,0xEF,0xFF,0xD1,0xFF,0xFF,0xFF, 0xFD,0xFB,0xFF,0xFD,0xFF,0xFB,0x9F,0xE9,
10380xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xBF, 0xFF,0xB3,0xFF,0xFF,0xF7,0xFF,0xFF,0xAF,
10390xF7,0xFF,0xB6,0x3F,0xEB,0xFA,0xFE,0xBF, 0xAF,0xEB,0xFA,0xFE,0xBF,0xFE,0xA7,0xFF,
10400xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF, 0xFE,0x9F,0xF7,0xF9,0xFF,0x7F,0x9F,0xE7,
10410xFF,0xFF,0xFE,0xAF,0x6F,0xFF,0xFF,0xFF, 0x9F,0xFF,0xDF,0xFF,0x7D,0x5F,0xDD,0xFF,
10420xFB,0xBF,0xE7,0xBB,0xFF,0xFB,0xDF,0x6D, 0x5F,0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
10430xEB,0xF7,0xFF,0xE7,0xEF,0xF7,0xFF,0xFF, 0x7F,0xFF,0xF7,0xFF,0xFC,0x8F,0xFF,0xEF,
10440xFD,0xFE,0xFF,0xBE,0xF4,0xF2,0x7D,0xD7, 0xCF,0xFF,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,
10450xFF,0xCF,0x6B,0xFF,0xBF,0x3F,0xFB,0xF2, 0xFC,0x7F,0xEB,0xFF,0x9F,0xFA,0xFF,0xFF,
10460x3F,0xFF,0xF3,0xFF,0xFF,0xFD,0x70,0xF7, 0xFF,0xFF,0xBF,0xFF,0xFB,0xD7,0xFE,0xF5,
10470x77,0xFF,0x15,0xDD,0x77,0xFD,0xFF,0x7F, 0xDF,0xF7,0xFB,0xCD,0xBF,0xFF,0xFD,0xFF,
10480xFF,0xDF,0x37,0xCD,0xF9,0xEC,0xFE,0xEF, 0xBB,0xF4,0xFB,0x3F,0x4F,0xB3,0xFF,0xFD,
10490xCB,0xFF,0xE9,0x7E,0x54,0x9F,0xE5,0x4B, 0xB7,0xFF,0xDD,0x7D,0xC7,0x71,0xDD,0x77,
10500x5D,0xD7,0x75,0xCD,0x7F,0xD6,0xFF,0xD3, 0xF6,0xF9,0x3F,0x6D,0x95,0xAF,0x7F,0xFE,
10510xFF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFE,0xF6,0xC7,0xFF,0xAD,0x7B,0xCA,0xFF,
10520xBF,0xBF,0xEF,0xFD,0xE3,0xDF,0xB7,0xED, 0xFB,0x7E,0xDF,0x37,0xED,0xE3,0xFB,0xDF,
10530xFF,0x52,0x5C,0x15,0xFD,0xCF,0x7F,0xDF, 0xFE,0xEF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEC,
10540x7B,0xFE,0xFF,0xFE,0x3E,0x7F,0xDA,0xF7, 0xFD,0xFF,0x7F,0xFF,0xFF,0xFB,0xEF,0xBB,
10550x6F,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF, 0xF7,0x7D,0xFF,0xD8,0xFF,0xFD,0xBF,0x7F,
10560xFB,0xFF,0xFF,0x9F,0xFB,0xFE,0x7F,0x9F, 0xE7,0xF9,0xFE,0x7F,0x9F,0xEA,0x7F,0xF6,
10570xBF,0xBD,0x6A,0x5A,0xF6,0xE5,0xBF,0x77, 0x5F,0x6D,0xDD,0x77,0x5D,0xD7,0x75,0xDD,
10580x77,0xFF,0xA5,0xBF,0xCF,0xFB,0xFF,0xFF, 0xBF,0xCF,0xFB,0xFD,0xFF,0xBF,0xF3,0xFE,
10590xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD,0xAB, 0xFF,0xBF,0xBF,0xFF,0xFB,0xFF,0x7F,0xEF,
10600xFF,0xBE,0xFB,0xEE,0xFB,0xBE,0xEF,0xBB, 0xEE,0xFB,0xBF,0xFF,0xB5,0xFF,0xD0,0xBC,
10610xFD,0x2F,0x4B,0xF7,0xFF,0xFF,0x9F,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,
10620xFA,0x8F,0xFD,0xAB,0xFA,0xDA,0xBF,0xAF, 0xB3,0xFD,0xFF,0xBF,0xFB,0xFE,0xFF,0xBF,
10630xEF,0xFB,0xFE,0xF7,0xBF,0xFF,0x9F,0xFF, 0x77,0xF7,0xBD,0xFD,0x77,0xDF,0xFF,0x7E,
10640xDF,0xED,0xBB,0xFE,0xFF,0xBE,0xEF,0xFB, 0xFE,0xFF,0xFA,0x3F,0xFF,0xBE,0x6F,0x8F,
10650xE6,0xF9,0xFE,0x7F,0x9F,0xC7,0xFE,0x7F, 0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFB,
10660x7F,0xFF,0x7F,0xCF,0xFF,0xFD,0xFF,0xFF, 0xDF,0xFB,0xAF,0xBF,0xEF,0xFF,0xFE,0xFF,
10670x9F,0xEF,0xFB,0xFF,0xFC,0xFF,0xFB,0xFE, 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xF7,
10680xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xF5,0xFF,0xFF,0xFF,0x3F,0xDF,0xF7,
10690xFF,0xFF,0x7F,0xEF,0xFE,0xFF,0xBF,0xFF, 0xFB,0xFF,0xFF,0xBF,0xEF,0xFF,0xB3,0x7F,
10700xFF,0x7B,0x5E,0xF7,0xFD,0xFF,0x7B,0x7F, 0xF7,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,
10710xDF,0xF7,0xFF,0x17,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xDD,0xF6,0xFC,0xBF,0xCB,0xF2,
10720xBC,0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xFE, 0x8F,0xFF,0xFA,0x7E,0xBF,0xA7,0xEB,0xDA,
10730xFC,0xBF,0xAF,0x7A,0xFE,0xBF,0xAF,0xEA, 0xFA,0xFE,0xBF,0xAF,0xF4,0xDF,0xFE,0xFF,
10740xF3,0x3C,0x7F,0x3E,0xFF,0xCF,0xF8,0xBF, 0x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xE7,0xE8,
10750xFF,0xFC,0x9F,0xFF,0xFF,0xCF,0xEB,0xB3, 0xE7,0xFB,0x7B,0xF3,0xFE,0xFF,0xCF,0xDB,
10760xFB,0xFB,0xBF,0x6F,0x6F,0xDF,0xEC,0x7F, 0xFF,0xFF,0xF7,0xFD,0xFD,0xFF,0xFF,0xFF,
10770xFF,0xB2,0xBF,0xFF,0xDE,0xFD,0xBD,0xEF, 0xFB,0xF6,0xDF,0xEA,0xE7,0xDB,0xFE,0xBB,
10780xFF,0xEB,0xFB,0xBF,0x9F,0x8F,0xE8,0xFE, 0x3F,0x8F,0xA3,0xF8,0xFE,0x3F,0x8F,0xFF,
10790xF8,0x7E,0xFD,0xFD,0x7F,0xFF,0xFB,0xCD, 0xFF,0xFD,0xFF,0x5F,0xEF,0xFD,0xFF,0xFF,
10800xDF,0xF7,0xFD,0xFF,0xBE,0x90,0xFF,0xFF, 0xEE,0xFF,0x3F,0xBF,0xF3,0xBB,0xFE,0xB7,
10810xAB,0xFA,0xFE,0xAF,0xAD,0xEA,0xFA,0xDE, 0xAB,0xFF,0x63,0xFF,0xFE,0xF2,0xFF,0xB3,
10820xFF,0xDF,0xEE,0x7D,0xFF,0x03,0xF1,0xF4, 0x3F,0x1F,0xC3,0xF1,0xEC,0x7F,0xFE,0x6F,
10830xFF,0xFB,0xFB,0xFF,0x9F,0xFF,0xBF,0xFF, 0x7B,0x5F,0xFD,0xFF,0xDF,0xF7,0xFD,0xFD,
10840x7F,0x7F,0xDF,0xFE,0xCF,0xFB,0xFF,0xFF, 0xAF,0xFB,0xFF,0x1F,0xEF,0xA5,0xFD,0xBF,
10850xDF,0xFB,0x7D,0xFF,0xBF,0xDF,0xFB,0xFF, 0xFD,0x3B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,
10860xAF,0xF3,0xFF,0xFB,0x7F,0xBF,0xD7,0xFB, 0xBF,0x7F,0xBB,0xF7,0xFF,0xF8,0x7F,0xFF,
10870xFA,0x5F,0xD7,0xFF,0xDF,0x7F,0xEF,0xFF, 0xFF,0x7F,0xDB,0xF7,0xFD,0xFF,0x7F,0xDF,
10880xB7,0xFB,0xEC,0xFF,0xFF,0xF7,0xBF,0xEF, 0xFD,0xFC,0xFB,0xFF,0xEF,0xF0,0xFE,0x3F,
10890x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xEF,0x8D, 0xFF,0xFF,0xEF,0x7F,0xBF,0xFF,0xFB,0xFF,
10900xDB,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xEF,0xD8,0xFF,0x2E,0x7F,
10910xBE,0xEF,0xFE,0x6E,0xFF,0xBF,0xF9,0xFF, 0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
10920xFC,0x66,0xBE,0x47,0xF3,0x7F,0xDF,0xFE, 0x87,0x9F,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,
10930xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x6F,0x7C, 0xFB,0x4F,0xD2,0xFF,0xFD,0x2B,0xFE,0xFF,
10940xFF,0xFD,0x5F,0xD7,0xD5,0xF5,0x7D,0xFF, 0xFF,0xFF,0xBF,0x9B,0xFF,0xFF,0xDF,0xB7,
10950xFF,0xFF,0xDF,0xFF,0x3F,0xCF,0xFE,0x7F, 0xBF,0xEF,0xFB,0xFC,0xFF,0x3F,0xFF,0xD9,
10960xBF,0xFE,0x97,0xEC,0x8F,0xB7,0xFE,0x9B, 0x7D,0xFD,0xB7,0xDD,0x77,0x1D,0xC7,0x71,
10970xDD,0x77,0x5D,0xD7,0xF3,0x6F,0xFD,0x3F, 0x73,0xDD,0xAF,0xFD,0x7A,0xFF,0xFF,0xAF,
10980xFE,0xFD,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF, 0xEF,0x66,0x7F,0xFF,0xFF,0xBF,0xBF,0xFF,
10990xFB,0xFF,0xF7,0xDF,0xFD,0xFB,0x7D,0xDF, 0xB7,0xCD,0xF3,0x7C,0x5F,0x3F,0x91,0x3F,
11000xFF,0x3D,0xEF,0x7B,0xFF,0xFC,0xFF,0xCA, 0xEF,0xFE,0xFF,0xBD,0xEF,0xFB,0x1E,0xE7,
11010xBB,0xEC,0x7F,0xB3,0xFF,0xFD,0x9F,0xFF, 0xFF,0xFE,0xFF,0xFF,0x7F,0xBF,0xFB,0xFE,
11020xFF,0xBF,0xEF,0xFB,0xEE,0xFB,0xBF,0xDF, 0x67,0xFF,0xFF,0xBF,0xEF,0xDB,0xFF,0xBC,
11030xFE,0x7F,0xFB,0xFF,0x9F,0xEF,0xF9,0xFE, 0x7F,0x9F,0xE7,0xF9,0xFE,0x87,0xFF,0xEE,
11040xFB,0xBE,0xE5,0xBF,0xEF,0xF9,0xD7,0x65, 0xF7,0xDD,0xE7,0x7D,0xDF,0x77,0x5D,0xD7,
11050x7F,0xF8,0x9B,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xFF,0xBF,0xEF,0xFB,0xFF,0x7F,0xCF,
11060xF3,0xFC,0xFF,0xBF,0xEF,0xFF,0xDB,0x3F, 0xEF,0xFB,0xFE,0xFF,0xDF,0xFF,0xFE,0xFB,
11070xBB,0xEF,0xBF,0xEF,0xBB,0xEE,0xFB,0xBE, 0xEF,0xBB,0xFF,0xFC,0x7F,0xFD,0x3B,0x5B,
11080xD6,0xE5,0xFD,0x4F,0xC3,0xFB,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF,
11090xB4,0xFF,0xFA,0xBC,0x8F,0xB2,0xE9,0xD2, 0x2E,0xCF,0xFB,0xFF,0xBF,0xEF,0xFB,0xFE,
11100xFF,0xBF,0xEF,0xFB,0xFF,0xEC,0xFF,0xFD, 0xFD,0x7F,0xDF,0xF7,0xE4,0xDF,0x5F,0xFF,
11110xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xC3,0xFF,0xEF,0xE6,0xF8,0xFE,
11120x3F,0x8B,0x83,0xF9,0xFE,0x7F,0xE7,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x17,
11130xFD,0xFF,0xFF,0xFF,0x7F,0x5F,0xF7,0x2C, 0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xE7,0xF9,
11140xFE,0x7F,0x9F,0xFE,0x2F,0xFF,0xFF,0xEF, 0xFF,0xFE,0xBF,0xEF,0xAD,0xFF,0xFF,0x7F,
11150xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFE,0xDF,0xFF,0xDF,0xFF,0xFD,0xFD,0x7F,
11160xDF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0x3F,0xFE,
11170xF7,0xFD,0xEF,0x7A,0xFF,0xB1,0xBD,0xFF, 0x7F,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,
11180xFF,0x7F,0xF3,0x27,0xFF,0xDF,0xFF,0xDD, 0xFF,0xFC,0x9B,0xFF,0xCB,0xFC,0xBF,0x2F,
11190xCB,0xF2,0xFC,0xBF,0x2F,0xC9,0xFF,0xDE, 0xFF,0xDF,0xAF,0xEB,0xDA,0xFE,0xBB,0xAF,
11200xEB,0xF8,0xF7,0xAF,0xE8,0xFA,0xFE,0xBF, 0xAF,0xEB,0xF2,0xFF,0xFD,0xFF,0xFF,0xEF,
11210xBD,0xD7,0xBF,0xFF,0xFF,0xDE,0x8F,0xB8, 0xDE,0x37,0x8D,0xA3,0x78,0xDA,0x3F,0x8F,
11220xFF,0xA1,0xFF,0xFF,0xFB,0xFB,0xFF,0xFF, 0xFF,0xFF,0xA7,0xBD,0xFB,0x76,0xFD,0xBF,
11230xEF,0xDB,0xFE,0xBB,0xBF,0xFE,0x27,0x7F, 0xFF,0xFE,0xFE,0xFD,0xF5,0xFF,0xEF,0xF5,
11240xDF,0x1F,0xE7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0xFF,0xCD,0xFD,0xAE,0xFF,0xFA,
11250x3E,0x3F,0xAB,0xFD,0xF8,0x7E,0x8F,0xE3, 0xF8,0xFE,0x3E,0x8F,0xE3,0xF8,0xFF,0xFE,
11260x1F,0xEF,0xDF,0xBF,0xFE,0xDE,0xDF,0xD9, 0xFF,0xDF,0xBC,0xFF,0xFF,0x7F,0xFF,0xEF,
11270xFD,0x7F,0xDF,0xF7,0xF9,0x3F,0xFE,0xFF, 0xFF,0x6F,0xFE,0xDE,0xBF,0xF7,0xED,0xEA,
11280xFD,0x8F,0x83,0xF8,0xEA,0x3F,0x8F,0xEF, 0xFF,0xF4,0x7F,0xFF,0xEF,0xEF,0x7B,0xF3,
11290xF1,0x5F,0xFF,0xFF,0xF1,0x3B,0x7F,0xDF, 0xF7,0xFD,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,
11300xFF,0xFF,0xF7,0xFF,0x6F,0xFF,0x7F,0xFF, 0xFF,0xF7,0xDE,0xF7,0xBF,0xEF,0xFB,0xF7,
11310xFD,0xFF,0xFF,0xF5,0xFA,0xFF,0xFF,0xFB, 0xE7,0xFF,0xF3,0xF8,0x7F,0xF3,0xDF,0xFF,
11320xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0xEF, 0xBB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,
11330xFF,0x7F,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xCF,0xFF,0x37,0xFF,0xFF,
11340x7F,0xDF,0x77,0x5D,0xE7,0xFC,0xFF,0xBF, 0xF7,0xF5,0xFB,0xFF,0xFF,0xD7,0xF5,0xFB,
11350xFF,0xFF,0x45,0xFD,0x7F,0xEA,0xFD,0xBE, 0xBF,0xDF,0xF7,0xFF,0xFF,0xDB,0xFB,0xFE,
11360xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0xFB,0x5F, 0x7F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
11370xFF,0xFE,0xFF,0xEF,0xFD,0xFF,0x7F,0xDF, 0xFF,0xEF,0xFB,0xF8,0x0F,0xF3,0xFF,0xF9,
11380x2E,0xFB,0xFE,0xFC,0xF3,0xEF,0xFF,0xFF, 0xBF,0xFF,0xFB,0xE7,0xFF,0xFE,0x7E,0xFF,
11390xC0,0x6B,0xCF,0xFF,0x34,0xDF,0xF1,0xFD, 0xFF,0xEF,0xFF,0xFF,0xFF,0xDF,0xF7,0xFD,
11400xCF,0x7F,0x9C,0xFD,0xFD,0x6C,0xF7,0xFF, 0xF6,0xFD,0xEB,0x2B,0x9F,0xFF,0xFC,0xFE,
11410x7E,0xFF,0xFF,0xFF,0xFF,0xD7,0xF3,0xF7, 0xFF,0xFB,0xE1,0xBF,0xFF,0xEB,0x7A,0xDE,
11420xD7,0xFB,0xFF,0xF9,0xFE,0xFF,0xFF,0xF3, 0xDE,0x7F,0xFD,0xE7,0x7F,0xFF,0xFD,0xBB,
11430xFF,0xFF,0x7E,0xCC,0xF6,0xAF,0x5F,0x7F, 0xFE,0xF4,0x7D,0xF7,0xFD,0xBB,0x6E,0xDB,
11440xB7,0xFF,0xF7,0xDF,0x66,0xFF,0xFF,0xF7, 0x3D,0xCF,0xDE,0xBD,0xFF,0xFF,0xDE,0xDB,
11450x8D,0xF7,0x7E,0xDF,0xB7,0xEF,0x7F,0xFF, 0xF6,0x87,0xFF,0xFF,0xEF,0xFE,0xDE,0xBF,
11460xFF,0xFF,0xFF,0xBB,0xEF,0xFD,0xFF,0x7B, 0xDE,0xF7,0x3F,0xFF,0xBF,0xFB,0xDB,0xFF,
11470xF2,0xB6,0xFD,0xBD,0x7F,0xE7,0xFF,0xFF, 0xFF,0x6F,0xF7,0xFF,0xFF,0xFF,0xFE,0x77,
11480xFF,0xBF,0xF8,0xAF,0xFF,0xDF,0xBF,0xFF, 0xBF,0x7F,0xFB,0xFF,0xFF,0xFF,0xDB,0xFE,
11490xFF,0xBF,0xFF,0xFA,0xFF,0xFD,0xFF,0xF6, 0x7F,0xFF,0x9F,0xFF,0xFF,0x3F,0xEF,0xF8,
11500xEE,0x7E,0x9F,0xBA,0xFE,0xBF,0x8F,0xEF, 0xFE,0xFE,0xF9,0xFF,0xFA,0x7F,0xFE,0x7E,
11510xBF,0xAF,0xFB,0x96,0xFD,0x9F,0xEF,0x5E, 0x65,0xBE,0xEF,0x5B,0xB6,0xFF,0xBE,0xE3,
11520xFF,0xB5,0xBF,0xFF,0xFD,0xFF,0x7F,0xFF, 0xEF,0xDF,0xFE,0xFF,0xBF,0xFB,0xFE,0xFF,
11530xBF,0xCF,0xFF,0xFF,0xFF,0xFD,0x9B,0xFF, 0xFE,0xFB,0xFE,0xDF,0xFF,0x7F,0xFF,0xF7,
11540xFE,0xFF,0xDF,0xFB,0xFB,0xFE,0xFF,0xFF, 0xFF,0xFF,0xFF,0xB7,0xFE,0xFA,0xFF,0xAB,
11550xEF,0xFF,0xFD,0xB5,0x7B,0x7F,0xFB,0xF7, 0xFD,0xFF,0xFF,0xDD,0xFF,0xEF,0x8F,0xFF,
11560x2F,0xFF,0xFB,0x7C,0xFF,0x3F,0xDF,0x73, 0xEB,0xFE,0x3F,0xFF,0xEF,0xFB,0xFE,0xFF,
11570xEF,0xFD,0xFF,0xBF,0xFD,0x0F,0xFF,0xFF, 0xFF,0xF5,0xF9,0xFF,0x7F,0xD7,0xFD,0xFF,
11580xDF,0xFF,0xF7,0xFB,0xFF,0x7F,0xBF,0xFF, 0xFF,0xF0,0x9F,0xFF,0xFE,0x7F,0x8B,0xE3,
11590xF9,0xDE,0x27,0x9B,0xE6,0xBE,0x7F,0x9B, 0xC3,0xF8,0xDE,0x7F,0x9D,0xE7,0xFE,0x7F,
11600xFF,0xFF,0x5F,0xD7,0xFF,0xFF,0xFF,0x4F, 0xFB,0xFF,0xFF,0x7F,0xFF,0xAF,0xFF,0x9F,
11610x7F,0xFB,0xFF,0xE8,0xFF,0xFF,0xFE,0xBF, 0xAF,0xFF,0xFF,0xFE,0xBF,0xEF,0xF7,0xFF,
11620xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF, 0xFC,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF,
11630xFD,0x3F,0xCF,0xFF,0xFF,0xFF,0xFF,0xF7, 0xFF,0xFD,0x7F,0xFF,0xFF,0x93,0xFF,0xFF,
11640x7A,0xDF,0xF7,0xFF,0xFF,0x7B,0x7F,0xB7, 0xEF,0xFF,0xFF,0xFD,0xBF,0xFD,0xFB,0xFF,
11650xF7,0xFF,0xD7,0xFF,0xFF,0xFF,0xFC,0x9F, 0x6F,0xCB,0xFF,0xF4,0xBB,0xDF,0xD6,0xFD,
11660xBF,0x2F,0xD3,0xF7,0xFF,0xDF,0xFF,0xCF, 0xFF,0xFA,0xBE,0xBD,0xAF,0x6A,0xDA,0xBE,
11670xBB,0xAB,0x3A,0xBE,0x2D,0xAE,0xEB,0xDA, 0xF6,0x3F,0xAD,0xF5,0xDD,0xFF,0xCF,0xF1,
11680xFF,0xF9,0x7F,0xFF,0x73,0xFE,0xFF,0xCF, 0xC3,0xF4,0xF7,0x2F,0xF3,0xFF,0xFC,0xFF,
11690x7C,0x1F,0xFF,0x3F,0x4F,0xFF,0x7E,0xFF, 0xEF,0xBD,0xF6,0xFE,0xFF,0x2B,0xEF,0xDC,
11700xFB,0xFD,0xFF,0xFB,0xFF,0xEA,0x7B,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFB,0xF7,0xDF,0xFF,
11710xE3,0x7D,0xFF,0xB7,0xFF,0xBF,0xFF,0xFF, 0xDF,0xFF,0xF8,0xFF,0xBF,0xFF,0xBF,0xEB,
11720xE7,0xFA,0xFE,0x3D,0xBF,0xE9,0xFC,0xBF, 0xFF,0xFA,0xFB,0xFE,0xFF,0xFF,0xFF,0xD9,
11730xFF,0xFF,0xFF,0xF6,0x7F,0xFF,0xF6,0x7D, 0xFF,0xDF,0xCF,0xFD,0xBF,0xFB,0xEF,0x7E,
11740xFF,0x7F,0xFF,0xFF,0xD3,0xFF,0xFD,0xFB, 0xFF,0xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xBF,
11750xFE,0xFF,0xF7,0xEF,0xFF,0xFF,0xFF,0xFB, 0xFF,0x87,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,
11760x7B,0xFE,0xFF,0xFE,0x3B,0xF7,0xF7,0xFF, 0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,
11770xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xF7, 0xFF,0xFF,0xAD,0xFF,0xFE,0xF7,0xFF,0xFF,
11780x5F,0xFF,0xFF,0xDF,0xFF,0xFD,0xFF,0xF5, 0xFF,0xDF,0xFF,0xBD,0xFF,0xE9,0xFF,0xC7,
11790xF3,0xFF,0xFF,0xF7,0xFF,0xF3,0xFF,0xF8, 0x3B,0xFF,0xFF,0x7B,0xDF,0xBF,0xFB,0xEF,
11800xFB,0xFF,0xFB,0xF7,0xF7,0xBB,0xFF,0xFF, 0xFF,0xFF,0xFB,0xFF,0xFE,0x7F,0xF3,0x7F,
11810x5E,0xB7,0xBF,0xFD,0x7F,0xFF,0xF9,0x7F, 0xFB,0xFF,0xEB,0xFD,0x7F,0x7F,0xFF,0xEF,
11820xFB,0xE0,0x3F,0xFE,0xBF,0xBF,0xDF,0xFF, 0x7E,0xFF,0xF7,0xFF,0xFF,0xFE,0xBF,0xFF,
11830xDB,0x78,0xFF,0xFF,0xFF,0xEE,0xA1,0xBF, 0xF5,0xDE,0xFB,0xF7,0xFF,0xFB,0xFF,0xFF,
11840xFF,0xFF,0xFB,0xFF,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xEF,0xF0,0xFF,0xFF,0xFF,0xF3,
11850xF7,0xFF,0xEF,0xFF,0xE7,0xCF,0xFF,0xFB, 0xFF,0xEF,0xFF,0xFF,0x9F,0x9F,0xEF,0xFC,
11860x16,0xBF,0xFE,0xF3,0xE4,0xFF,0xFF,0xC6, 0xFF,0xE7,0xFF,0xFF,0xFD,0xFF,0xBF,0xFF,
11870xFF,0x3F,0xFF,0xBF,0xD6,0xAF,0x7F,0xFE, 0x6B,0x7E,0x7F,0xFF,0xAF,0xFF,0xFF,0xBF,
11880xFF,0x5F,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF, 0xFF,0xBD,0xDB,0xFF,0xFE,0x5F,0xF2,0xFF,
11890xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xEF,0x7F,0xFF,0xFF,0xFF,0xFF,0xDE,0xBF,
11900xFF,0xFF,0xEF,0xFB,0x77,0xFE,0xBD,0x7F, 0x5F,0xFF,0xFF,0xFF,0xDF,0x6F,0xED,0xFF,
11910xFD,0xFF,0x7F,0xFD,0x6F,0xFF,0xFF,0x77, 0xDA,0xCF,0xFD,0x5F,0xFF,0xBF,0xFF,0xFF,
11920xDF,0x7F,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF, 0x66,0x7F,0xFF,0xFE,0xBF,0xE7,0xBF,0xFA,
11930xFF,0xFE,0xFF,0xFF,0xFF,0xDF,0xFF,0x59, 0xEF,0xFF,0xEF,0xFB,0x7F,0x89,0xFF,0xFF,
11940xE9,0xFF,0x6F,0xFF,0xF5,0xFF,0xFF,0xFF, 0xFF,0xFF,0x7F,0xF2,0xF7,0xFF,0xFF,0xEF,
11950xF8,0x7F,0xFB,0xFF,0xFD,0xFF,0xFF,0xD9, 0xFF,0xEF,0xBB,0xFF,0xFF,0xFF,0xBF,0xEF,
11960xDE,0xFF,0xFF,0x9F,0x7F,0xDF,0xFF,0xF7, 0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xAF,
11970xFF,0xFF,0xF7,0x3F,0xEB,0x9F,0xFE,0x7F, 0x9E,0x7F,0x9F,0xFE,0x87,0xFF,0xED,0xDB,
11980x56,0xFF,0xBF,0xAF,0x0B,0xD2,0xFF,0xEF, 0xDB,0x6E,0x7D,0xBD,0x6F,0xF8,0xFE,0x3F,
11990xFA,0x5B,0xFF,0xFD,0xBF,0xEF,0xFF,0xBF, 0x6F,0xDB,0xE6,0xFF,0xFF,0x3F,0xFF,0xDF,
12000xFE,0xFF,0xFF,0xFF,0xFF,0xDA,0x3F,0xFF, 0xFB,0xFE,0xFE,0xFF,0xFF,0xDF,0xF7,0xBD,
12010xFF,0xFD,0xFF,0xFE,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFF,0xF1,0x5F,0xFD,0x9F,0xDF,0xFD,
12020xFF,0xFD,0x7F,0xFF,0xFF,0xFF,0xFF,0x76, 0xFA,0xFF,0xFF,0x7F,0xE3,0xF8,0xFF,0xAE,
12030xFF,0xFB,0x7E,0x9D,0x73,0xFF,0xFA,0x7F, 0xDF,0xFF,0xFF,0x7F,0xFF,0xFB,0xCD,0xFF,
12040x7F,0xEF,0xFB,0xFF,0xFD,0xFF,0xF7,0x7F, 0x7F,0xEF,0xFF,0xED,0xFF,0xFF,0xFF,0xB5,
12050xFF,0xBF,0xFF,0xBF,0xFD,0xEF,0xDB,0xF7, 0xFF,0x93,0xFF,0xEF,0xE2,0xF9,0xBE,0x7F,
12060x8B,0xE7,0xF9,0xFE,0x6B,0xE7,0xF9,0xFE, 0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x47,0xFF,
12070xFF,0xFD,0xFF,0x9F,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xF5,0xFF,0x9F,0xFF,0xF7,0xFE,
12080xFF,0xBF,0xFE,0x6F,0xFF,0xFF,0xFB,0xFF, 0xFF,0xFF,0xAF,0xFF,0xFF,0xFF,0x7F,0xFB,
12090xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, 0xDF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xDF,
12100xFF,0xFF,0xFF,0x5F,0xFF,0xFF,0xFF,0xFF, 0x5F,0xFB,0xFE,0xFF,0xF8,0x37,0xFF,0xFF,
12110xEF,0xFF,0x7F,0xFE,0xBF,0xFF,0xFF,0xFE, 0xBF,0xFF,0xFF,0x7F,0xFF,0xBF,0xFD,0xFF,
12120x7F,0xFA,0x7F,0xFF,0xFF,0x6F,0xFF,0xFF, 0x7D,0xFF,0xCF,0xFF,0xFF,0xFF,0x4F,0xFF,
12130xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0xBF, 0xFF,0xAE,0xEB,0xFA,0xFE,0xBB,0xAD,0xEB,
12140xFA,0xF7,0xAF,0x6B,0xFA,0xF6,0xBF,0x25, 0xE9,0xF2,0x7F,0x45,0xFF,0xFF,0xFD,0xF7,
12150xF7,0xBF,0xFF,0xDF,0xFF,0xFF,0xBF,0xFB, 0xFF,0xDF,0xF3,0xFF,0xF7,0x3F,0xCF,0xFF,
12160xA1,0xFF,0xFF,0xBF,0xE7,0xFF,0xFF,0x7F, 0xFF,0x3D,0xFF,0xFF,0xFF,0xF7,0xFF,0x2F,
12170xFF,0xFB,0xF5,0x7F,0xFE,0x57,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,
12180x3F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD,0xFE, 0xF7,0xEE,0xAF,0xFE,0xEE,0xE7,0xFA,0xFF,
12190xFE,0x9D,0xF9,0x5E,0xFE,0xFF,0xEB,0xFF, 0xFF,0xDF,0xA7,0xFF,0xFF,0xFF,0xFC,0xDB,
12200xFF,0xFF,0xFF,0x7E,0xFB,0xFF,0xFF,0xEF, 0xFB,0xFD,0xFF,0xDB,0xFF,0xFF,0xFF,0xEF,
12210xFF,0xFF,0xFF,0xFD,0xBF,0xFE,0xBF,0xFF, 0x6F,0x7F,0xFF,0xF7,0xFF,0xFF,0xF9,0xFF,
12220xF7,0xFF,0xBF,0xDE,0xF7,0xFF,0xFF,0xFF, 0xFA,0x7F,0xFD,0xBF,0x5F,0xFF,0xFF,0xBF,
12230xFF,0xED,0xFF,0xF7,0xBF,0xFF,0xFF,0xEF, 0xFF,0xDF,0xFF,0xFF,0xFF,0xE6,0xFF,0xFB,
12240x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,
12250xFD,0xFF,0xF5,0xFF,0xF6,0x7F,0xDF,0xBD, 0xCF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,
12260xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3, 0xFF,0xEE,0xBF,0xFF,0x7D,0xEF,0xFE,0xFF,
12270xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFE, 0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xB5,0xAE,
12280xFF,0xFF,0xB6,0xFE,0xBF,0xFF,0xFF,0xBF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
12290xFF,0x27,0xFF,0xEF,0xFE,0x7F,0xDF,0xFF, 0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
12300xFF,0xFF,0xFD,0xFF,0xF7,0xF9,0x9F,0xFF, 0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,
12310xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0x0F,0xFF,0xE7,0xBF,0xFE,
12320xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFC,0xBF, 0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xC4,
12330x6B,0xFF,0x29,0x1F,0xFB,0xAF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xEF,0x1B,0xFE,0xFF,0xFC,
12340x6F,0xFF,0xFF,0xFD,0x6A,0xF7,0xD7,0xF5, 0xBF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
12350xFE,0xBF,0xFF,0xFF,0xFA,0xFF,0xFF,0xF7, 0xFB,0xDD,0xBF,0xFF,0xE7,0xFF,0xFF,0xFF,
12360xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x7F,0xFF, 0xFF,0xF5,0xFF,0xFF,0xF7,0xFD,0xB3,0xEF,
12370xFD,0x7E,0x5D,0xFF,0xFD,0xFF,0xFF,0xFF, 0xFD,0x7F,0xD2,0xF5,0xFB,0x7E,0xCB,0xB7,
12380xFF,0xFF,0xFF,0xC6,0xFF,0xFD,0xEE,0x63, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xFD,0x65,
12390x5B,0xDF,0xFF,0xD5,0xFF,0xFF,0xFF,0xF6, 0xE7,0xBF,0xF7,0xA9,0xFF,0xFF,0xED,0xFF,
12400xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFF,0xFF, 0xAF,0xFF,0xFF,0xFF,0xF8,0x1B,0xFF,0xE3,
12410xD0,0xBF,0xFF,0xE1,0xFF,0xFF,0xFF,0xFF, 0xFF,0xD7,0xFF,0xFF,0xFF,0x5F,0xFF,0xFF,
12420xFF,0xFF,0xAF,0xFF,0xDB,0x76,0xBF,0xFF, 0x7F,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF,
12430xFB,0xFE,0xFF,0xFF,0xFF,0xBF,0xF2,0x7F, 0xFF,0x9F,0xFE,0xBD,0xFE,0x7F,0xFF,0xFF,
12440xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xF7,0x3F,0xEC,0x7F,0xF6,0x95,0xBB,
12450xEF,0xF8,0xFE,0xFC,0xBF,0x2F,0xDA,0xFC, 0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xEF,0xFF,
12460xA9,0xBF,0xCF,0xFB,0xFF,0xFF,0xFF,0xFE, 0xDD,0xB7,0x6D,0xF6,0xD9,0xB6,0x6D,0x9B,
12470x76,0xD9,0xBF,0xFB,0xFD,0xA3,0xFF,0xBF, 0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0x7F,0xDF,
12480xFD,0xEF,0x7B,0xDE,0xF7,0xFD,0xEF,0x7F, 0xFF,0xFF,0x05,0xFF,0xFA,0xFE,0x7F,0xEF,
12490xE3,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF, 0xFF,0x5F,0xFF,0xFF,0xFD,0x7F,0xFB,0xAF,
12500xFF,0x63,0xC8,0xFF,0xBF,0xEF,0xFF,0xFF, 0xFA,0x7F,0xFF,0xFF,0xFF,0xFE,0x9F,0xF7,
12510xFF,0xFA,0xBF,0xFE,0x9F,0xFB,0x7F,0xFF, 0xFF,0xEF,0xD7,0xFF,0xFF,0xF5,0xFF,0xFF,
12520xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xBF,0xFF, 0xF9,0xBF,0xFF,0xBE,0x27,0x9F,0xE7,0xF9,
12530xFE,0x7F,0x8B,0xE7,0xFE,0x7F,0x9F,0xE2, 0xF9,0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF,
12540xFF,0xFF,0xFB,0xFE,0xFF,0xFF,0xFF,0xD7, 0xFF,0xFF,0xFF,0xFF,0xF5,0xFF,0xFF,0xFF,
12550xD7,0xFF,0xFA,0xFF,0xFE,0xFF,0xFF,0xFF, 0xFD,0xFF,0xFF,0xFF,0xAF,0xF7,0xFF,0xFF,
12560xFF,0xEB,0xFF,0xFF,0xFF,0xAF,0xFF,0xC4, 0xFF,0xF7,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,
12570xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xD7,0xFF, 0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFB,0x7A,
12580xDF,0xF7,0xFD,0xFF,0xFF,0xFE,0xBF,0xFF, 0xFF,0x7F,0xFF,0xAF,0xFF,0xFF,0xFF,0xF7,
12590xEF,0xE3,0xFF,0xDD,0xD2,0xFF,0xDF,0xFF, 0xFF,0xF2,0xFC,0xBF,0xCB,0xF6,0xFD,0xBF,
12600x2F,0xCB,0xFF,0x7F,0xDF,0xDE,0xAF,0xFF, 0xDA,0xEE,0xBF,0xAF,0xE9,0xFA,0xF4,0xBD,
12610xAF,0x5A,0xAE,0xBB,0xAB,0x6B,0xDA,0xDE, 0xBF,0xAD,0xD7,0x5E,0xFF,0xFF,0xBF,0xFC,
12620xFF,0xDF,0xFD,0xFF,0xFF,0xFF,0xFF,0xDF, 0xF7,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFA,
12630x1F,0xFF,0xFE,0xFB,0xEF,0xBF,0xFD,0xFF, 0xFD,0xBD,0x77,0xFF,0xFF,0xFF,0xFF,0x9D,
12640xEF,0xFF,0xFF,0xFF,0xEF,0x7D,0xFF,0xFB, 0xFE,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,
12650xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEE, 0xBF,0xE4,0xFB,0xFF,0xFE,0x3F,0xFE,0xFF,
12660xFF,0xFF,0xFF,0xAF,0xEA,0xFE,0xBF,0xAF, 0xEB,0xFA,0xFE,0xFF,0xFF,0xFF,0x55,0xF6,
12670xFF,0xFE,0xF7,0xFF,0x7F,0xFF,0xEB,0xF7, 0x5F,0xC5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF,
12680x6F,0xFB,0xFF,0x8A,0xFF,0xFF,0xFF,0xFF, 0xEB,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0xBF,
12690xEF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF, 0x77,0xDF,0xFB,0xFF,0xFD,0x7F,0xEF,0xFF,
12700xFF,0xFF,0xBF,0x7F,0xFF,0xDF,0xBF,0xFF, 0xFB,0xFF,0xFF,0xFF,0xFE,0xEF,0xDF,0xFF,
12710xFE,0xFF,0x9F,0xEF,0x7D,0xFF,0xF7,0xFF, 0x7F,0xFF,0xFF,0xDF,0xF7,0xFD,0xFF,0xEF,
12720xDF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFB,
12730xFD,0xFF,0xBF,0xDF,0xD1,0xFF,0xF8,0x3B, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
12740x7E,0xDB,0xFD,0xFF,0x77,0xDB,0xB7,0x7D, 0xBF,0xFB,0xFF,0xF8,0x7F,0xED,0x7B,0x5E,
12750xFF,0xFE,0xFF,0xFF,0x4F,0xD7,0xFD,0x7F, 0xDF,0xD7,0xF5,0xFF,0x7F,0xFF,0xFF,0xFF,
12760xF2,0x3F,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF, 0xFF,0xBF,0xEF,0xFE,0xFF,0x3B,0xEE,0xFF,
12770xFC,0xEF,0xFF,0xFF,0xFF,0x85,0xFF,0xFD, 0xFE,0xFF,0xF5,0xFF,0xFF,0xFE,0xFF,0xDF,
12780xFB,0xFF,0x5F,0xBF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xA8,0xFF,0xFF,0x9F,0x9E,0xFF,
12790xFF,0xFF,0x7F,0xF3,0xFF,0xFF,0xCF,0xFF, 0xF7,0xFD,0xFF,0x7F,0xFF,0xFF,0xFC,0x16,
12800xBF,0xCF,0xA3,0xE5,0xEF,0x7F,0xFF,0xF3, 0xE4,0xFF,0xCF,0x93,0xFC,0xFF,0x3F,0xCF,
12810xFF,0xFF,0xFF,0xD6,0x0F,0x7D,0xBF,0x6E, 0xFB,0xF4,0xFC,0xAF,0x6D,0xDB,0x77,0xB7,
12820x6D,0xDB,0xF6,0xFD,0xBF,0xFF,0xFF,0xFF, 0xBF,0x9B,0xFA,0xDE,0xB7,0xB7,0xED,0xF9,
12830x7E,0xB7,0xAC,0xEB,0xD6,0xB3,0xAD,0xEB, 0x7A,0xDF,0xFF,0xFF,0xFF,0xD8,0xBF,0xFF,
12840xB7,0xED,0x9F,0x6F,0xDD,0xF7,0x68,0xDB, 0x37,0xB3,0x6C,0xDB,0x36,0xCD,0xB3,0x7F,
12850xFF,0x7F,0xF5,0x6F,0xFD,0xEF,0x79,0x3D, 0xF7,0x93,0xE4,0x7A,0x9E,0xAD,0xEA,0x7A,
12860x9E,0xF7,0xBD,0xEF,0xFF,0xFF,0xFF,0x76, 0x7F,0xFB,0xC6,0xFF,0xBB,0xEF,0xDA,0xFE,
12870xFD,0xBF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xFF,0xFB,0xFF,0xA5,0xFF,0xFD,0xAB,
12880x6F,0x78,0xDE,0x17,0x8F,0x79,0xDF,0xFD, 0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xFF,0xFB,
12890xFF,0xFB,0xFF,0xEF,0xFB,0xEF,0xFB,0xFE, 0xFF,0xBB,0xDA,0xF3,0xEF,0x3B,0xCE,0xF3,
12900xBC,0xEF,0x3F,0xCF,0xDF,0xFF,0xB7,0xFF, 0xFF,0xFF,0xCF,0x73,0xFF,0xBF,0xEF,0xFF,
12910xF3,0xFF,0x3F,0xCF,0xF3,0xFC,0xFF,0x3D, 0xCF,0x9F,0xFE,0x07,0xFF,0xAF,0xEB,0xFE,
12920xFD,0xBF,0xEF,0xEB,0xFA,0xFF,0xAF,0xEB, 0xFA,0xFE,0xBF,0xAF,0xFB,0xFE,0x3F,0xFB,
12930x9B,0xFF,0x7F,0xDF,0xFF,0xF3,0xFE,0xFF, 0xDE,0xF7,0xBF,0x7B,0xDE,0xF7,0xBD,0xEF,
12940x7B,0xFE,0xFF,0xFF,0xDF,0x3F,0xFE,0xFF, 0xB7,0xFF,0xEF,0xF7,0xFF,0xBF,0xED,0xFE,
12950xDF,0xB7,0xED,0xFB,0x7E,0xDF,0xFF,0xFF, 0xFF,0xFD,0x5F,0xEF,0xEB,0xFA,0xFE,0xF5,
12960xBF,0x6F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xF8,0xFF,0xA8,0xFF,
12970xFF,0xBF,0xEF,0xFB,0x6A,0xFB,0xB7,0xEF, 0xFB,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,
12980xEF,0xFB,0xFF,0xE0,0xFF,0xFF,0xFD,0x7F, 0x5C,0xD7,0x7D,0xDF,0xF3,0x5C,0xF5,0xCD,
12990x73,0x5E,0xD7,0xB5,0xFD,0x7F,0xEF,0xFF, 0xDB,0xFF,0xFF,0xE2,0xF8,0xBE,0x2F,0x8F,
13000xE7,0xF8,0xBE,0x6B,0xE2,0xF8,0xBE,0x2F, 0x8B,0xE2,0xF9,0xFE,0x7F,0xE7,0xFF,0xD7,
13010xF5,0xFD,0x7F,0xFF,0xF7,0xF5,0xFD,0x7F, 0xD7,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF,
13020xFF,0xFF,0x8F,0xFF,0xAF,0xEB,0xFA,0xFF, 0xFF,0xBF,0xEB,0xFA,0xFF,0x2F,0xEB,0xFA,
13030xFE,0xBF,0xAF,0xEB,0xFF,0xFF,0xFE,0x5F, 0xFF,0x5F,0xFF,0xFF,0xFD,0xFF,0xFF,0xD7,
13040xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xBF,0xFE,0xB7,0xFD,
13050xFF,0x7E,0xDF,0xF7,0xAD,0xFF,0x7F,0xF7, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,
13060xF6,0x7F,0xFF,0xFF,0xFF,0xDB,0xF6,0xFC, 0xAF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,
13070xFF,0xFF,0xFF,0xFF,0xFF,0xEC,0xBF,0xFF, 0xAF,0xEB,0xFA,0xF6,0xAB,0x8F,0xEB,0xFA,
13080xF7,0xA5,0xEB,0xFA,0xBE,0xBF,0xAF,0xEB, 0xFA,0xFF,0x6D,0xFF,0xFF,0x7F,0xDF,0x33,
13090xDD,0xFF,0x7F,0xFE,0xF7,0xFC,0x7F,0xFB, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA9,
13100xFF,0xFD,0xFF,0xFF,0xFE,0xFF,0xFF,0xDF, 0xFF,0xFF,0xEF,0xEF,0xFD,0xFF,0x7F,0xFF,
13110xFF,0xFF,0xFF,0xFE,0xA7,0xFF,0xFF,0xFF, 0x77,0xDF,0xF7,0xFD,0x9F,0x7F,0xFE,0x77,
13120xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xAF,0xBF,0xAF,0xFF,0xF9,0xBE,0xBF,
13130x8F,0xFB,0xFE,0xFE,0xEF,0xFB,0xFE,0xFF, 0xBF,0xEF,0xFB,0xFF,0xFF,0xFD,0xDF,0x6F,
13140xEF,0xFF,0x7F,0xFF,0xBF,0xBF,0xDF,0xFF, 0xFC,0xFF,0xDF,0xF7,0xFD,0xEF,0x7F,0xDF,
13150xFF,0xFF,0xFF,0x3F,0xF6,0xFF,0xCF,0xFF, 0xDB,0xFB,0xF7,0xFF,0xEB,0x7A,0xFF,0xFF,
13160xFF,0xBF,0xEF,0xFB,0xFF,0xFF,0xFF,0xFE, 0x6D,0xFD,0xFF,0x5F,0xFB,0xFF,0xFF,0xF7,
13170xFF,0x5F,0xF5,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFB,0xFF,
13180xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xE7,0xF6, 0xBF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,
13190xFF,0xC9,0xFF,0xFF,0xFF,0xBD,0xFF,0xBF, 0xAF,0xEF,0xEF,0x3F,0xD1,0xFC,0x7F,0xFB,
13200xC7,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3,0xFF, 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0x77,0xFF,
13210xDF,0xB7,0xFD,0xF7,0xFD,0xF7,0xFF,0xFF, 0xFF,0xFF,0xFF,0x57,0xFF,0xF7,0xA5,0xFD,
13220x3F,0xDF,0xBF,0xBF,0xFE,0x7F,0xFF,0xFF, 0xFF,0xDF,0xFA,0xFD,0xFF,0xFF,0xFF,0xFE,
13230x87,0xFF,0xE9,0xFF,0xFE,0xEF,0xBF,0xEF, 0xFE,0xFE,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,
13240xFF,0xFF,0xFF,0xFF,0xFA,0x9F,0xFF,0x3F, 0xFF,0xFD,0xFD,0x57,0xDF,0xFD,0xF3,0xFF,
13250xDF,0xFD,0xFF,0x5F,0xDF,0xF5,0xFD,0xFF, 0xFF,0xF9,0x8F,0xFF,0xFF,0xFF,0xEE,0x7F,
13260xFF,0xFF,0xBF,0x5E,0xFE,0xEC,0xFB,0x3F, 0x7F,0x9F,0xEF,0xF9,0xFF,0xFF,0xCD,0x6B,
13270xFF,0xFF,0xFF,0xC5,0xF3,0xFC,0xFA,0x38, 0xFF,0xAF,0x3F,0xEE,0x7F,0x9F,0xFF,0xD9,
13280xFF,0xFF,0xFD,0x7A,0xF7,0xFF,0xF3,0xFF, 0xAF,0x6F,0xDB,0xF2,0xB9,0xE9,0xFB,0xFF,
13290xFF,0xFF,0xFE,0xFF,0xFF,0xEF,0xFF,0xFB, 0xC5,0xBF,0xFF,0xEF,0xFF,0x5E,0xB7,0xAD,
13300xCD,0x79,0x7C,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0x93,0xFF,0xEF,
13310xEA,0xFE,0xBF,0xEF,0x5B,0xD2,0xCD,0xF5, 0x6D,0x77,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,
13320xFF,0xFF,0x66,0xFF,0xD5,0x65,0x7D,0x5F, 0x75,0x9D,0x65,0x7F,0xD6,0xFB,0x4F,0xFF,
13330xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xC7, 0xFF,0xBF,0xEF,0xFA,0xFE,0xFF,0xBF,0xEB,
13340xFF,0xDF,0xFF,0x7E,0xFF,0xFF,0xEF,0xFD, 0x7E,0xD7,0xFF,0x78,0xDF,0xFF,0x5F,0xDF,
13350xF5,0xBF,0x7F,0xDF,0xC5,0xFF,0x3F,0xF6, 0x7E,0xFF,0x0F,0xEF,0xF2,0x3E,0xBF,0xFF,
13360xFB,0x3F,0xFF,0xFB,0x7F,0xFF,0xB3,0xFE, 0xFB,0xF6,0xFD,0xFF,0xDA,0xF7,0xFD,0xFF,
13370x7F,0xDF,0xF7,0xBF,0xFF,0xFA,0x7F,0xFF, 0xFF,0xFF,0xFF,0x9F,0xFF,0xF3,0xDC,0xF9,
13380xBF,0xCE,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7, 0xFF,0xFF,0xE2,0x7F,0xFE,0xFF,0xBF,0xEF,
13390xEB,0xFA,0xFF,0x9F,0x67,0x1E,0xFF,0x8F, 0xE7,0xF8,0xFE,0x7F,0x8F,0xEF,0xFF,0xBD,
13400xBF,0xFF,0xFB,0xFF,0xFF,0xDF,0xF7,0xFF, 0xFC,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,
13410xFF,0xFF,0xFF,0xFD,0xB3,0xFF,0xFF,0xEF, 0xFF,0xFF,0xBF,0xED,0xFF,0xFB,0xEE,0xFE,
13420xFF,0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF, 0xFF,0xB5,0xFF,0xB7,0xFD,0xFD,0x6E,0xFF,
13430xFF,0xFE,0xFD,0x2F,0xD8,0xFE,0xBF,0x8F, 0xEB,0xF9,0xFE,0x3F,0xFF,0xFA,0xCF,0xFF,
13440xE7,0xD9,0xFA,0xBF,0xDF,0x77,0xFC,0xFB, 0x3F,0xAB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,
13450xFF,0xFF,0xEE,0x1F,0xFF,0xDF,0xF7,0xFF, 0xFF,0xFF,0x5F,0x97,0x35,0xBF,0x5E,0xFE,
13460xBF,0xEF,0xFF,0xF7,0xFD,0xFF,0xFF,0xFA, 0xBF,0xFF,0xBE,0x6F,0x9F,0xE7,0xF8,0xBE,
13470x2F,0x8B,0x66,0x94,0x7D,0x9D,0xE7,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF,0xFF,
13480xFF,0xF7,0xF5,0xFD,0x7F,0x5F,0xFB,0xFD, 0x9E,0xFF,0xFB,0xFE,0xFF,0xFF,0xEF,0xFF,
13490xFF,0xA0,0xFF,0xFF,0xFF,0xBF,0xEF,0xEB, 0xFA,0xFE,0xBF,0xB7,0xF7,0xF7,0xFF,0xFF,
13500xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF, 0xFD,0xFF,0xFF,0xFF,0xD7,0xFF,0xFF,0xFF,
13510x7F,0xF5,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF, 0xBF,0xFF,0xFF,0xAB,0xFE,0xFB,0xFE,0xFF,
13520xF7,0xAF,0xFF,0xFF,0xDE,0xF7,0xEB,0x5F, 0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,0xFF,
13530xB3,0xFF,0xC9,0xFE,0xFF,0xFF,0xFF,0xFF, 0xD6,0xFF,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF,
13540xFF,0xFF,0xFF,0xFF,0xFC,0x8F,0xFF,0xBA, 0xBE,0xBF,0xAF,0xEB,0x78,0xFE,0xB7,0xAD,
13550x3A,0xFE,0xB7,0xAF,0xEB,0x7A,0xFE,0xBF, 0xAF,0xFF,0x9F,0xFF,0xFF,0xDF,0xFC,0xFF,
13560xFF,0xFE,0xC3,0xFE,0xFF,0xFF,0x33,0xFC, 0xFF,0xBF,0xDF,0xF3,0xFF,0xFF,0xBB,0x9F,
13570xFF,0xFF,0xFF,0xEB,0xDF,0xFF,0xFF,0xAF, 0xF7,0x6F,0xF9,0xBF,0xEF,0xFD,0xFF,0xFF,
13580xFF,0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF, 0xFB,0xFF,0xFF,0xBF,0xFD,0xFB,0xF7,0xFF,
13590xDF,0xF7,0xFF,0xFE,0xEF,0x5F,0xBD,0xFF, 0xFA,0xFF,0xF8,0xFF,0xBF,0xAF,0xFB,0xFE,
13600xFE,0x3F,0xEF,0xE8,0xFF,0xDF,0xF3,0xFD, 0xFF,0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xFB,
13610xFD,0xFF,0xAF,0xFF,0xFF,0xFE,0xFE,0xBF, 0xDB,0xFF,0xFF,0xFF,0xBF,0xFF,0xDF,0xFF,
13620xFD,0xFF,0xCB,0xFF,0xFF,0xFF,0xFF,0xFF, 0xBF,0x6F,0xFF,0x7F,0xB7,0xB3,0xFF,0xFF,
13630xDF,0xFF,0xFB,0xEF,0xFF,0xFF,0xFF,0x07, 0xFF,0xFB,0xFF,0xFF,0xFF,0xED,0xFF,0xF5,
13640x7C,0xFF,0x7F,0xFE,0xFF,0xFF,0xEF,0xCF, 0xFF,0xFB,0xFF,0xFF,0x2F,0xFF,0xFF,0xFF,
13650xFF,0xF3,0xFF,0xFB,0xFF,0xFE,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,
13660xFD,0x1B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFE,0x7C,0xFF,0xFF,0xFF,0xFF,
13670xEF,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0x7F, 0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
13680xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, 0xFF,0xFF,0xF0,0x7F,0xFF,0xFF,0xFF,0xFF,
13690xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xDF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xFE,
13700x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xEF,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF,
13710xFF,0xFF,0xEF,0xFA,0xB5,0xFF,0xFF,0xFF, 0xF7,0xF7,0xFF,0xFF,0xFF,0xFF,0xDF,0xFB,
13720xFC,0xFF,0xFF,0xFE,0xFF,0x7F,0xDF,0xBF, 0xFF,0xCB,0xBF,0xF9,0xFE,0x7F,0x9F,0xE7,
13730xF9,0xFE,0x7F,0x97,0xE1,0xFE,0x79,0x9F, 0xE7,0xFD,0xFE,0x7F,0xDF,0xFE,0x37,0xFF,
13740xFB,0xDE,0xDE,0xBD,0xEF,0xF3,0xFE,0xFB, 0xAF,0xEB,0xFE,0xFF,0xFF,0xCF,0xFF,0xFE,
13750xFF,0xBF,0xFF,0x8F,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xE7,0xF9,0x5E,0x7F,0xEF,0xFB,
13760xDA,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD, 0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,
13770xFF,0xFF,0x7F,0xFF,0xFF,0xF7,0xFB,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFC,0x3F,0xFF,0xBF,
13780xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0x7B,0x7F, 0xBF,0xEF,0xFB,0xFE,0xFF,0xB5,0xEF,0xFB,
13790xBF,0xFA,0x7F,0xFC,0xFF,0x3F,0xCF,0xF3, 0xFC,0xFF,0x3F,0xCF,0xBC,0xFF,0x3F,0xEF,
13800xF3,0xFC,0xFE,0x3F,0xCF,0xFF,0xEE,0xEF, 0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0x6A,0xD7,
13810xB7,0xFB,0xF8,0xFF,0xB7,0xEF,0xBA,0xFE, 0xFF,0xBF,0x7F,0xE9,0xFF,0xF9,0x7E,0x5F,
13820x97,0xE5,0xF9,0xFE,0x7F,0xBF,0xF9,0x7E, 0x5F,0x9F,0xE5,0xFB,0xFE,0x5F,0xB7,0xFF,
13830xA3,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0x5E,0xF7,0x7D,0xFF,0x77,0xDF,
13840xF7,0xFD,0xFF,0x7F,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xDF,0xFB,0x7F,
13850xFF,0xFF,0xEF,0xFF,0xFE,0xFB,0xFF,0xFF, 0xBF,0xFE,0x8F,0xFF,0xDF,0xF7,0xFD,0xFD,
13860x7F,0xDF,0xF7,0xFD,0x3E,0xDF,0xF5,0xBD, 0xFF,0x7F,0xDF,0xF7,0xFD,0xF7,0xFF,0x9F,
13870xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFD,0xFF,0xBE,0xFF,0xFF,0xFF,0xFF,
13880xFF,0xFF,0xFF,0xFD,0x3F,0xFF,0xDF,0xF7, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xCF,
13890x77,0xFC,0xFF,0x5F,0xDF,0xF7,0xFD,0xFF, 0xF4,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
13900xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFD,0xFF,0xFF,0xFF,0xEE,0xFF,0xFF,
13910xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xED,0xFB,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,
13920xFF,0xFF,0xE9,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFB,0xFF,0xFF,0xFF,0xD3,0xFF,0xFF,
13930xBF,0x3F,0xFB,0xFF,0xFF,0xFF,0xFB,0xF3, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
13940xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xF7, 0xFF,0xFF,0xFF,0xFF,0x17,0xFF,0xFF,0xFF,
13950xDF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF, 0xDF,0xDF,0xFF,0xFD,0xFF,0xFF,0xDF,0xF7,
13960xFF,0x4F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD,
13970xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0x9F,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
13980xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF, 0xFF,0xFF,0x7A,0x3F,0xFF,0xFF,0xFF,0xFF,
13990xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF2,
14000x7F,0xFF,0xFB,0xFE,0xFF,0xBF,0xEF,0xF8, 0xFE,0xFF,0xBF,0xFB,0xFE,0xFF,0x8F,0xEC,
14010xFB,0xFE,0xFF,0xBF,0xF8,0xF7,0xFE,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFD,0xBF,0xCF,0xEC,
14020xFF,0x3F,0xEF,0xDB,0xF8,0xFF,0xBF,0xCF, 0xFF,0xF9,0xFF,0xFF,0xBF,0xFF,0xFB,0xFF,
14030xFF,0xFF,0xEF,0xFB,0xDF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xBB,0xFF,
14040xEF,0xFB,0xFE,0xEF,0xBF,0xEE,0xEB,0xFB, 0xFE,0xFF,0xEF,0xFE,0xEE,0xBF,0xFE,0xEB,
14050xFF,0xEF,0xFF,0x17,0xFF,0x7E,0xEB,0xBB, 0xFE,0xBF,0xBE,0xFB,0xEF,0x5B,0xF7,0xBD,
14060xFB,0xCF,0xBF,0xBF,0xBB,0xFB,0x7E,0xCC, 0xEF,0xFF
1407
1408};
diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c
new file mode 100644
index 000000000000..8823297d2191
--- /dev/null
+++ b/drivers/usb/media/dabusb.c
@@ -0,0 +1,877 @@
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/smp_lock.h>
41
42#include "dabusb.h"
43#include "dabfirmware.h"
44
45/*
46 * Version Information
47 */
48#define DRIVER_VERSION "v1.54"
49#define DRIVER_AUTHOR "Deti Fliegl, deti@fliegl.de"
50#define DRIVER_DESC "DAB-USB Interface Driver for Linux (c)1999"
51
52/* --------------------------------------------------------------------- */
53
54#ifdef CONFIG_USB_DYNAMIC_MINORS
55#define NRDABUSB 256
56#else
57#define NRDABUSB 4
58#endif
59
60/*-------------------------------------------------------------------*/
61
62static dabusb_t dabusb[NRDABUSB];
63static int buffers = 256;
64static struct usb_driver dabusb_driver;
65
66/*-------------------------------------------------------------------*/
67
68static int dabusb_add_buf_tail (pdabusb_t s, struct list_head *dst, struct list_head *src)
69{
70 unsigned long flags;
71 struct list_head *tmp;
72 int ret = 0;
73
74 spin_lock_irqsave (&s->lock, flags);
75
76 if (list_empty (src)) {
77 // no elements in source buffer
78 ret = -1;
79 goto err;
80 }
81 tmp = src->next;
82 list_move_tail (tmp, dst);
83
84 err: spin_unlock_irqrestore (&s->lock, flags);
85 return ret;
86}
87/*-------------------------------------------------------------------*/
88#ifdef DEBUG
89static void dump_urb (struct urb *urb)
90{
91 dbg("urb :%p", urb);
92 dbg("dev :%p", urb->dev);
93 dbg("pipe :%08X", urb->pipe);
94 dbg("status :%d", urb->status);
95 dbg("transfer_flags :%08X", urb->transfer_flags);
96 dbg("transfer_buffer :%p", urb->transfer_buffer);
97 dbg("transfer_buffer_length:%d", urb->transfer_buffer_length);
98 dbg("actual_length :%d", urb->actual_length);
99 dbg("setup_packet :%p", urb->setup_packet);
100 dbg("start_frame :%d", urb->start_frame);
101 dbg("number_of_packets :%d", urb->number_of_packets);
102 dbg("interval :%d", urb->interval);
103 dbg("error_count :%d", urb->error_count);
104 dbg("context :%p", urb->context);
105 dbg("complete :%p", urb->complete);
106}
107#endif
108/*-------------------------------------------------------------------*/
109static int dabusb_cancel_queue (pdabusb_t s, struct list_head *q)
110{
111 unsigned long flags;
112 pbuff_t b;
113
114 dbg("dabusb_cancel_queue");
115
116 spin_lock_irqsave (&s->lock, flags);
117
118 list_for_each_entry(b, q, buff_list) {
119#ifdef DEBUG
120 dump_urb(b->purb);
121#endif
122 usb_unlink_urb (b->purb);
123 }
124 spin_unlock_irqrestore (&s->lock, flags);
125 return 0;
126}
127/*-------------------------------------------------------------------*/
128static int dabusb_free_queue (struct list_head *q)
129{
130 struct list_head *tmp;
131 struct list_head *p;
132 pbuff_t b;
133
134 dbg("dabusb_free_queue");
135 for (p = q->next; p != q;) {
136 b = list_entry (p, buff_t, buff_list);
137
138#ifdef DEBUG
139 dump_urb(b->purb);
140#endif
141 if (b->purb->transfer_buffer)
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/*-------------------------------------------------------------------*/
153static 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/*-------------------------------------------------------------------*/
169static void dabusb_iso_complete (struct urb *purb, struct pt_regs *regs)
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 err("dabusb_iso_complete: invalid len %d", len);
193 }
194 else
195 warn("dabusb_iso_complete: corrupted packet status: %d", purb->iso_frame_desc[i].status);
196 if (dst != purb->actual_length)
197 err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length);
198 }
199
200 if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) {
201 s->overruns++;
202 err("overrun (%d)", s->overruns);
203 }
204 wake_up (&s->wait);
205}
206/*-------------------------------------------------------------------*/
207static int dabusb_alloc_buffers (pdabusb_t s)
208{
209 int buffers = 0;
210 pbuff_t b;
211 unsigned int pipe = usb_rcvisocpipe (s->usbdev, _DABUSB_ISOPIPE);
212 int pipesize = usb_maxpacket (s->usbdev, pipe, usb_pipeout (pipe));
213 int packets = _ISOPIPESIZE / pipesize;
214 int transfer_buffer_length = packets * pipesize;
215 int i;
216
217 dbg("dabusb_alloc_buffers pipesize:%d packets:%d transfer_buffer_len:%d",
218 pipesize, packets, transfer_buffer_length);
219
220 while (buffers < (s->total_buffer_size << 10)) {
221 b = (pbuff_t) kmalloc (sizeof (buff_t), GFP_KERNEL);
222 if (!b) {
223 err("kmalloc(sizeof(buff_t))==NULL");
224 goto err;
225 }
226 memset (b, 0, sizeof (buff_t));
227 b->s = s;
228 b->purb = usb_alloc_urb(packets, GFP_KERNEL);
229 if (!b->purb) {
230 err("usb_alloc_urb == NULL");
231 kfree (b);
232 goto err;
233 }
234
235 b->purb->transfer_buffer = kmalloc (transfer_buffer_length, GFP_KERNEL);
236 if (!b->purb->transfer_buffer) {
237 kfree (b->purb);
238 kfree (b);
239 err("kmalloc(%d)==NULL", transfer_buffer_length);
240 goto err;
241 }
242
243 b->purb->transfer_buffer_length = transfer_buffer_length;
244 b->purb->number_of_packets = packets;
245 b->purb->complete = dabusb_iso_complete;
246 b->purb->context = b;
247 b->purb->dev = s->usbdev;
248 b->purb->pipe = pipe;
249 b->purb->transfer_flags = URB_ISO_ASAP;
250
251 for (i = 0; i < packets; i++) {
252 b->purb->iso_frame_desc[i].offset = i * pipesize;
253 b->purb->iso_frame_desc[i].length = pipesize;
254 }
255
256 buffers += transfer_buffer_length;
257 list_add_tail (&b->buff_list, &s->free_buff_list);
258 }
259 s->got_mem = buffers;
260
261 return 0;
262
263 err:
264 dabusb_free_buffers (s);
265 return -ENOMEM;
266}
267/*-------------------------------------------------------------------*/
268static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
269{
270 int ret;
271 unsigned int pipe;
272 int actual_length;
273
274 dbg("dabusb_bulk");
275
276 if (!pb->pipe)
277 pipe = usb_rcvbulkpipe (s->usbdev, 2);
278 else
279 pipe = usb_sndbulkpipe (s->usbdev, 2);
280
281 ret=usb_bulk_msg(s->usbdev, pipe, pb->data, pb->size, &actual_length, 100);
282 if(ret<0) {
283 err("dabusb: usb_bulk_msg failed(%d)",ret);
284
285 if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
286 err("set_interface failed");
287 return -EINVAL;
288 }
289
290 }
291
292 if( ret == -EPIPE ) {
293 warn("CLEAR_FEATURE request to remove STALL condition.");
294 if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
295 err("request failed");
296 }
297
298 pb->size = actual_length;
299 return ret;
300}
301/* --------------------------------------------------------------------- */
302static int dabusb_writemem (pdabusb_t s, int pos, unsigned char *data, int len)
303{
304 int ret;
305 unsigned char *transfer_buffer = kmalloc (len, GFP_KERNEL);
306
307 if (!transfer_buffer) {
308 err("dabusb_writemem: kmalloc(%d) failed.", len);
309 return -ENOMEM;
310 }
311
312 memcpy (transfer_buffer, data, len);
313
314 ret=usb_control_msg(s->usbdev, usb_sndctrlpipe( s->usbdev, 0 ), 0xa0, 0x40, pos, 0, transfer_buffer, len, 300);
315
316 kfree (transfer_buffer);
317 return ret;
318}
319/* --------------------------------------------------------------------- */
320static int dabusb_8051_reset (pdabusb_t s, unsigned char reset_bit)
321{
322 dbg("dabusb_8051_reset: %d",reset_bit);
323 return dabusb_writemem (s, CPUCS_REG, &reset_bit, 1);
324}
325/* --------------------------------------------------------------------- */
326static int dabusb_loadmem (pdabusb_t s, const char *fname)
327{
328 int ret;
329 PINTEL_HEX_RECORD ptr = firmware;
330
331 dbg("Enter dabusb_loadmem (internal)");
332
333 ret = dabusb_8051_reset (s, 1);
334 while (ptr->Type == 0) {
335
336 dbg("dabusb_writemem: %04X %p %d)", ptr->Address, ptr->Data, ptr->Length);
337
338 ret = dabusb_writemem (s, ptr->Address, ptr->Data, ptr->Length);
339 if (ret < 0) {
340 err("dabusb_writemem failed (%d %04X %p %d)", ret, ptr->Address, ptr->Data, ptr->Length);
341 break;
342 }
343 ptr++;
344 }
345 ret = dabusb_8051_reset (s, 0);
346
347 dbg("dabusb_loadmem: exit");
348
349 return ret;
350}
351/* --------------------------------------------------------------------- */
352static int dabusb_fpga_clear (pdabusb_t s, pbulk_transfer_t b)
353{
354 b->size = 4;
355 b->data[0] = 0x2a;
356 b->data[1] = 0;
357 b->data[2] = 0;
358 b->data[3] = 0;
359
360 dbg("dabusb_fpga_clear");
361
362 return dabusb_bulk (s, b);
363}
364/* --------------------------------------------------------------------- */
365static int dabusb_fpga_init (pdabusb_t s, pbulk_transfer_t b)
366{
367 b->size = 4;
368 b->data[0] = 0x2c;
369 b->data[1] = 0;
370 b->data[2] = 0;
371 b->data[3] = 0;
372
373 dbg("dabusb_fpga_init");
374
375 return dabusb_bulk (s, b);
376}
377/* --------------------------------------------------------------------- */
378static int dabusb_fpga_download (pdabusb_t s, const char *fname)
379{
380 pbulk_transfer_t b = kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL);
381 unsigned int blen, n;
382 int ret;
383 unsigned char *buf = bitstream;
384
385 dbg("Enter dabusb_fpga_download (internal)");
386
387 if (!b) {
388 err("kmalloc(sizeof(bulk_transfer_t))==NULL");
389 return -ENOMEM;
390 }
391
392 b->pipe = 1;
393 ret = dabusb_fpga_clear (s, b);
394 mdelay (10);
395 blen = buf[73] + (buf[72] << 8);
396
397 dbg("Bitstream len: %i", blen);
398
399 b->data[0] = 0x2b;
400 b->data[1] = 0;
401 b->data[2] = 0;
402 b->data[3] = 60;
403
404 for (n = 0; n <= blen + 60; n += 60) {
405 // some cclks for startup
406 b->size = 64;
407 memcpy (b->data + 4, buf + 74 + n, 60);
408 ret = dabusb_bulk (s, b);
409 if (ret < 0) {
410 err("dabusb_bulk failed.");
411 break;
412 }
413 mdelay (1);
414 }
415
416 ret = dabusb_fpga_init (s, b);
417 kfree (b);
418
419 dbg("exit dabusb_fpga_download");
420
421 return ret;
422}
423
424static int dabusb_stop (pdabusb_t s)
425{
426 dbg("dabusb_stop");
427
428 s->state = _stopped;
429 dabusb_cancel_queue (s, &s->rec_buff_list);
430
431 dbg("pending_io: %d", s->pending_io.counter);
432
433 s->pending_io.counter = 0;
434 return 0;
435}
436
437static int dabusb_startrek (pdabusb_t s)
438{
439 if (!s->got_mem && s->state != _started) {
440
441 dbg("dabusb_startrek");
442
443 if (dabusb_alloc_buffers (s) < 0)
444 return -ENOMEM;
445 dabusb_stop (s);
446 s->state = _started;
447 s->readptr = 0;
448 }
449
450 if (!list_empty (&s->free_buff_list)) {
451 pbuff_t end;
452 int ret;
453
454 while (!dabusb_add_buf_tail (s, &s->rec_buff_list, &s->free_buff_list)) {
455
456 dbg("submitting: end:%p s->rec_buff_list:%p", s->rec_buff_list.prev, &s->rec_buff_list);
457
458 end = list_entry (s->rec_buff_list.prev, buff_t, buff_list);
459
460 ret = usb_submit_urb (end->purb, GFP_KERNEL);
461 if (ret) {
462 err("usb_submit_urb returned:%d", ret);
463 if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
464 err("startrek: dabusb_add_buf_tail failed");
465 break;
466 }
467 else
468 atomic_inc (&s->pending_io);
469 }
470 dbg("pending_io: %d",s->pending_io.counter);
471 }
472
473 return 0;
474}
475
476static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, loff_t * ppos)
477{
478 pdabusb_t s = (pdabusb_t) file->private_data;
479 unsigned long flags;
480 unsigned ret = 0;
481 int rem;
482 int cnt;
483 pbuff_t b;
484 struct urb *purb = NULL;
485
486 dbg("dabusb_read");
487
488 if (*ppos)
489 return -ESPIPE;
490
491 if (s->remove_pending)
492 return -EIO;
493
494
495 if (!s->usbdev)
496 return -EIO;
497
498 while (count > 0) {
499 dabusb_startrek (s);
500
501 spin_lock_irqsave (&s->lock, flags);
502
503 if (list_empty (&s->rec_buff_list)) {
504
505 spin_unlock_irqrestore(&s->lock, flags);
506
507 err("error: rec_buf_list is empty");
508 goto err;
509 }
510
511 b = list_entry (s->rec_buff_list.next, buff_t, buff_list);
512 purb = b->purb;
513
514 spin_unlock_irqrestore(&s->lock, flags);
515
516 if (purb->status == -EINPROGRESS) {
517 if (file->f_flags & O_NONBLOCK) // return nonblocking
518 {
519 if (!ret)
520 ret = -EAGAIN;
521 goto err;
522 }
523
524 interruptible_sleep_on (&s->wait);
525
526 if (signal_pending (current)) {
527 if (!ret)
528 ret = -ERESTARTSYS;
529 goto err;
530 }
531
532 spin_lock_irqsave (&s->lock, flags);
533
534 if (list_empty (&s->rec_buff_list)) {
535 spin_unlock_irqrestore(&s->lock, flags);
536 err("error: still no buffer available.");
537 goto err;
538 }
539 spin_unlock_irqrestore(&s->lock, flags);
540 s->readptr = 0;
541 }
542 if (s->remove_pending) {
543 ret = -EIO;
544 goto err;
545 }
546
547 rem = purb->actual_length - s->readptr; // set remaining bytes to copy
548
549 if (count >= rem)
550 cnt = rem;
551 else
552 cnt = count;
553
554 dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt);
555
556 if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) {
557 err("read: copy_to_user failed");
558 if (!ret)
559 ret = -EFAULT;
560 goto err;
561 }
562
563 s->readptr += cnt;
564 count -= cnt;
565 buf += cnt;
566 ret += cnt;
567
568 if (s->readptr == purb->actual_length) {
569 // finished, take next buffer
570 if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
571 err("read: dabusb_add_buf_tail failed");
572 s->readptr = 0;
573 }
574 }
575 err: //up(&s->mutex);
576 return ret;
577}
578
579static int dabusb_open (struct inode *inode, struct file *file)
580{
581 int devnum = iminor(inode);
582 pdabusb_t s;
583
584 if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB))
585 return -EIO;
586
587 s = &dabusb[devnum - DABUSB_MINOR];
588
589 dbg("dabusb_open");
590 down (&s->mutex);
591
592 while (!s->usbdev || s->opened) {
593 up (&s->mutex);
594
595 if (file->f_flags & O_NONBLOCK) {
596 return -EBUSY;
597 }
598 msleep_interruptible(500);
599
600 if (signal_pending (current)) {
601 return -EAGAIN;
602 }
603 down (&s->mutex);
604 }
605 if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
606 up(&s->mutex);
607 err("set_interface failed");
608 return -EINVAL;
609 }
610 s->opened = 1;
611 up (&s->mutex);
612
613 file->f_pos = 0;
614 file->private_data = s;
615
616 return nonseekable_open(inode, file);
617}
618
619static int dabusb_release (struct inode *inode, struct file *file)
620{
621 pdabusb_t s = (pdabusb_t) file->private_data;
622
623 dbg("dabusb_release");
624
625 down (&s->mutex);
626 dabusb_stop (s);
627 dabusb_free_buffers (s);
628 up (&s->mutex);
629
630 if (!s->remove_pending) {
631 if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)
632 err("set_interface failed");
633 }
634 else
635 wake_up (&s->remove_ok);
636
637 s->opened = 0;
638 return 0;
639}
640
641static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
642{
643 pdabusb_t s = (pdabusb_t) file->private_data;
644 pbulk_transfer_t pbulk;
645 int ret = 0;
646 int version = DABUSB_VERSION;
647
648 dbg("dabusb_ioctl");
649
650 if (s->remove_pending)
651 return -EIO;
652
653 down (&s->mutex);
654
655 if (!s->usbdev) {
656 up (&s->mutex);
657 return -EIO;
658 }
659
660 switch (cmd) {
661
662 case IOCTL_DAB_BULK:
663 pbulk = (pbulk_transfer_t) kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL);
664
665 if (!pbulk) {
666 ret = -ENOMEM;
667 break;
668 }
669
670 if (copy_from_user (pbulk, (void __user *) arg, sizeof (bulk_transfer_t))) {
671 ret = -EFAULT;
672 kfree (pbulk);
673 break;
674 }
675
676 ret=dabusb_bulk (s, pbulk);
677 if(ret==0)
678 if (copy_to_user((void __user *)arg, pbulk,
679 sizeof(bulk_transfer_t)))
680 ret = -EFAULT;
681 kfree (pbulk);
682 break;
683
684 case IOCTL_DAB_OVERRUNS:
685 ret = put_user (s->overruns, (unsigned int __user *) arg);
686 break;
687
688 case IOCTL_DAB_VERSION:
689 ret = put_user (version, (unsigned int __user *) arg);
690 break;
691
692 default:
693 ret = -ENOIOCTLCMD;
694 break;
695 }
696 up (&s->mutex);
697 return ret;
698}
699
700static struct file_operations dabusb_fops =
701{
702 .owner = THIS_MODULE,
703 .llseek = no_llseek,
704 .read = dabusb_read,
705 .ioctl = dabusb_ioctl,
706 .open = dabusb_open,
707 .release = dabusb_release,
708};
709
710static struct usb_class_driver dabusb_class = {
711 .name = "usb/dabusb%d",
712 .fops = &dabusb_fops,
713 .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
714 .minor_base = DABUSB_MINOR,
715};
716
717
718/* --------------------------------------------------------------------- */
719static int dabusb_probe (struct usb_interface *intf,
720 const struct usb_device_id *id)
721{
722 struct usb_device *usbdev = interface_to_usbdev(intf);
723 int retval;
724 pdabusb_t s;
725
726 dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
727 le16_to_cpu(usbdev->descriptor.idVendor),
728 le16_to_cpu(usbdev->descriptor.idProduct),
729 intf->altsetting->desc.bInterfaceNumber);
730
731 /* We don't handle multiple configurations */
732 if (usbdev->descriptor.bNumConfigurations != 1)
733 return -ENODEV;
734
735 if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF &&
736 le16_to_cpu(usbdev->descriptor.idProduct) == 0x9999)
737 return -ENODEV;
738
739
740
741 s = &dabusb[intf->minor];
742
743 down (&s->mutex);
744 s->remove_pending = 0;
745 s->usbdev = usbdev;
746 s->devnum = intf->minor;
747
748 if (usb_reset_configuration (usbdev) < 0) {
749 err("reset_configuration failed");
750 goto reject;
751 }
752 if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) {
753 dabusb_loadmem (s, NULL);
754 goto reject;
755 }
756 else {
757 dabusb_fpga_download (s, NULL);
758
759 if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) {
760 err("set_interface failed");
761 goto reject;
762 }
763 }
764 dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber);
765 usb_set_intfdata (intf, s);
766 up (&s->mutex);
767
768 retval = usb_register_dev(intf, &dabusb_class);
769 if (retval) {
770 usb_set_intfdata (intf, NULL);
771 return -ENOMEM;
772 }
773
774 return 0;
775
776 reject:
777 up (&s->mutex);
778 s->usbdev = NULL;
779 return -ENODEV;
780}
781
782static void dabusb_disconnect (struct usb_interface *intf)
783{
784 wait_queue_t __wait;
785 pdabusb_t s = usb_get_intfdata (intf);
786
787 dbg("dabusb_disconnect");
788
789 init_waitqueue_entry(&__wait, current);
790
791 usb_set_intfdata (intf, NULL);
792 if (s) {
793 usb_deregister_dev (intf, &dabusb_class);
794 s->remove_pending = 1;
795 wake_up (&s->wait);
796 add_wait_queue(&s->remove_ok, &__wait);
797 set_current_state(TASK_UNINTERRUPTIBLE);
798 if (s->state == _started)
799 schedule();
800 current->state = TASK_RUNNING;
801 remove_wait_queue(&s->remove_ok, &__wait);
802
803 s->usbdev = NULL;
804 s->overruns = 0;
805 }
806}
807
808static struct usb_device_id dabusb_ids [] = {
809 // { USB_DEVICE(0x0547, 0x2131) }, /* An2131 chip, no boot ROM */
810 { USB_DEVICE(0x0547, 0x9999) },
811 { } /* Terminating entry */
812};
813
814MODULE_DEVICE_TABLE (usb, dabusb_ids);
815
816static struct usb_driver dabusb_driver = {
817 .owner = THIS_MODULE,
818 .name = "dabusb",
819 .probe = dabusb_probe,
820 .disconnect = dabusb_disconnect,
821 .id_table = dabusb_ids,
822};
823
824/* --------------------------------------------------------------------- */
825
826static int __init dabusb_init (void)
827{
828 int retval;
829 unsigned u;
830
831 /* initialize struct */
832 for (u = 0; u < NRDABUSB; u++) {
833 pdabusb_t s = &dabusb[u];
834 memset (s, 0, sizeof (dabusb_t));
835 init_MUTEX (&s->mutex);
836 s->usbdev = NULL;
837 s->total_buffer_size = buffers;
838 init_waitqueue_head (&s->wait);
839 init_waitqueue_head (&s->remove_ok);
840 spin_lock_init (&s->lock);
841 INIT_LIST_HEAD (&s->free_buff_list);
842 INIT_LIST_HEAD (&s->rec_buff_list);
843 }
844
845 /* register misc device */
846 retval = usb_register(&dabusb_driver);
847 if (retval)
848 goto out;
849
850 dbg("dabusb_init: driver registered");
851
852 info(DRIVER_VERSION ":" DRIVER_DESC);
853
854out:
855 return retval;
856}
857
858static void __exit dabusb_cleanup (void)
859{
860 dbg("dabusb_cleanup");
861
862 usb_deregister (&dabusb_driver);
863}
864
865/* --------------------------------------------------------------------- */
866
867MODULE_AUTHOR( DRIVER_AUTHOR );
868MODULE_DESCRIPTION( DRIVER_DESC );
869MODULE_LICENSE("GPL");
870
871module_param(buffers, int, 0);
872MODULE_PARM_DESC (buffers, "Number of buffers (default=256)");
873
874module_init (dabusb_init);
875module_exit (dabusb_cleanup);
876
877/* --------------------------------------------------------------------- */
diff --git a/drivers/usb/media/dabusb.h b/drivers/usb/media/dabusb.h
new file mode 100644
index 000000000000..10b666e43abc
--- /dev/null
+++ b/drivers/usb/media/dabusb.h
@@ -0,0 +1,85 @@
1#define _BULK_DATA_LEN 64
2typedef 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
17typedef enum { _stopped=0, _started } driver_state_t;
18
19typedef struct
20{
21 struct semaphore 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
39typedef struct
40{
41 pdabusb_t s;
42 struct urb *purb;
43 struct list_head buff_list;
44} buff_t,*pbuff_t;
45
46typedef 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
69typedef unsigned char BYTE;
70#endif // !_BYTE_DEFINED
71
72#ifndef _WORD_DEFINED
73#define _WORD_DEFINED
74typedef unsigned short WORD;
75#endif // !_WORD_DEFINED
76
77typedef 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/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c
new file mode 100644
index 000000000000..7503f5b96f59
--- /dev/null
+++ b/drivers/usb/media/dsbr100.c
@@ -0,0 +1,429 @@
1/* A driver for the D-Link DSB-R100 USB radio. The R100 plugs
2 into both the USB and an analog audio input, so this thing
3 only deals with initialisation and frequency setting, the
4 audio data has to be handled by a sound driver.
5
6 Major issue: I can't find out where the device reports the signal
7 strength, and indeed the windows software appearantly just looks
8 at the stereo indicator as well. So, scanning will only find
9 stereo stations. Sad, but I can't help it.
10
11 Also, the windows program sends oodles of messages over to the
12 device, and I couldn't figure out their meaning. My suspicion
13 is that they don't have any:-)
14
15 You might find some interesting stuff about this module at
16 http://unimut.fsk.uni-heidelberg.de/unimut/demi/dsbr
17
18 Copyright (c) 2000 Markus Demleitner <msdemlei@cl.uni-heidelberg.de>
19
20 This program is free software; you can redistribute it and/or modify
21 it under the terms of the GNU General Public License as published by
22 the Free Software Foundation; either version 2 of the License, or
23 (at your option) any later version.
24
25 This program is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 GNU General Public License for more details.
29
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33
34 History:
35
36 Version 0.40:
37 Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing
38
39 Version 0.30:
40 Markus: Updates for 2.5.x kernel and more ISO compliant source
41
42 Version 0.25:
43 PSL and Markus: Cleanup, radio now doesn't stop on device close
44
45 Version 0.24:
46 Markus: Hope I got these silly VIDEO_TUNER_LOW issues finally
47 right. Some minor cleanup, improved standalone compilation
48
49 Version 0.23:
50 Markus: Sign extension bug fixed by declaring transfer_buffer unsigned
51
52 Version 0.22:
53 Markus: Some (brown bag) cleanup in what VIDIOCSTUNER returns,
54 thanks to Mike Cox for pointing the problem out.
55
56 Version 0.21:
57 Markus: Minor cleanup, warnings if something goes wrong, lame attempt
58 to adhere to Documentation/CodingStyle
59
60 Version 0.2:
61 Brad Hards <bradh@dynamite.com.au>: Fixes to make it work as non-module
62 Markus: Copyright clarification
63
64 Version 0.01: Markus: initial release
65
66*/
67
68
69#include <linux/kernel.h>
70#include <linux/module.h>
71#include <linux/init.h>
72#include <linux/slab.h>
73#include <linux/input.h>
74#include <linux/videodev.h>
75#include <linux/usb.h>
76#include <linux/smp_lock.h>
77
78/*
79 * Version Information
80 */
81#define DRIVER_VERSION "v0.40"
82#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
83#define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver"
84
85#define DSB100_VENDOR 0x04b4
86#define DSB100_PRODUCT 0x1002
87
88/* Commands the device appears to understand */
89#define DSB100_TUNE 1
90#define DSB100_ONOFF 2
91
92#define TB_LEN 16
93
94/* Frequency limits in MHz -- these are European values. For Japanese
95devices, that would be 76 and 91. */
96#define FREQ_MIN 87.5
97#define FREQ_MAX 108.0
98#define FREQ_MUL 16000
99
100
101static int usb_dsbr100_probe(struct usb_interface *intf,
102 const struct usb_device_id *id);
103static void usb_dsbr100_disconnect(struct usb_interface *intf);
104static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
105 unsigned int cmd, unsigned long arg);
106static int usb_dsbr100_open(struct inode *inode, struct file *file);
107static int usb_dsbr100_close(struct inode *inode, struct file *file);
108
109static int radio_nr = -1;
110module_param(radio_nr, int, 0);
111
112/* Data for one (physical) device */
113typedef struct {
114 struct usb_device *usbdev;
115 struct video_device *videodev;
116 unsigned char transfer_buffer[TB_LEN];
117 int curfreq;
118 int stereo;
119 int users;
120 int removed;
121} dsbr100_device;
122
123
124/* File system interface */
125static struct file_operations usb_dsbr100_fops = {
126 .owner = THIS_MODULE,
127 .open = usb_dsbr100_open,
128 .release = usb_dsbr100_close,
129 .ioctl = usb_dsbr100_ioctl,
130 .llseek = no_llseek,
131};
132
133/* V4L interface */
134static struct video_device dsbr100_videodev_template=
135{
136 .owner = THIS_MODULE,
137 .name = "D-Link DSB-R 100",
138 .type = VID_TYPE_TUNER,
139 .hardware = VID_HARDWARE_AZTECH,
140 .fops = &usb_dsbr100_fops,
141 .release = video_device_release,
142};
143
144static struct usb_device_id usb_dsbr100_device_table [] = {
145 { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
146 { } /* Terminating entry */
147};
148
149MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table);
150
151/* USB subsystem interface */
152static struct usb_driver usb_dsbr100_driver = {
153 .owner = THIS_MODULE,
154 .name = "dsbr100",
155 .probe = usb_dsbr100_probe,
156 .disconnect = usb_dsbr100_disconnect,
157 .id_table = usb_dsbr100_device_table,
158};
159
160/* Low-level device interface begins here */
161
162/* switch on radio */
163static int dsbr100_start(dsbr100_device *radio)
164{
165 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
166 USB_REQ_GET_STATUS,
167 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
168 0x00, 0xC7, radio->transfer_buffer, 8, 300)<0 ||
169 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
170 DSB100_ONOFF,
171 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
172 0x01, 0x00, radio->transfer_buffer, 8, 300)<0)
173 return -1;
174 return (radio->transfer_buffer)[0];
175}
176
177
178/* switch off radio */
179static int dsbr100_stop(dsbr100_device *radio)
180{
181 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
182 USB_REQ_GET_STATUS,
183 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
184 0x16, 0x1C, radio->transfer_buffer, 8, 300)<0 ||
185 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
186 DSB100_ONOFF,
187 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
188 0x00, 0x00, radio->transfer_buffer, 8, 300)<0)
189 return -1;
190 return (radio->transfer_buffer)[0];
191}
192
193/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
194static int dsbr100_setfreq(dsbr100_device *radio, int freq)
195{
196 freq = (freq/16*80)/1000+856;
197 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
198 DSB100_TUNE,
199 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
200 (freq>>8)&0x00ff, freq&0xff,
201 radio->transfer_buffer, 8, 300)<0 ||
202 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
203 USB_REQ_GET_STATUS,
204 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
205 0x96, 0xB7, radio->transfer_buffer, 8, 300)<0 ||
206 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
207 USB_REQ_GET_STATUS,
208 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
209 0x00, 0x24, radio->transfer_buffer, 8, 300)<0) {
210 radio->stereo = -1;
211 return -1;
212 }
213 radio->stereo = ! ((radio->transfer_buffer)[0]&0x01);
214 return (radio->transfer_buffer)[0];
215}
216
217/* return the device status. This is, in effect, just whether it
218sees a stereo signal or not. Pity. */
219static void dsbr100_getstat(dsbr100_device *radio)
220{
221 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
222 USB_REQ_GET_STATUS,
223 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
224 0x00 , 0x24, radio->transfer_buffer, 8, 300)<0)
225 radio->stereo = -1;
226 else
227 radio->stereo = ! (radio->transfer_buffer[0]&0x01);
228}
229
230
231/* USB subsystem interface begins here */
232
233/* check if the device is present and register with v4l and
234usb if it is */
235static int usb_dsbr100_probe(struct usb_interface *intf,
236 const struct usb_device_id *id)
237{
238 dsbr100_device *radio;
239
240 if (!(radio = kmalloc(sizeof(dsbr100_device), GFP_KERNEL)))
241 return -ENOMEM;
242 if (!(radio->videodev = video_device_alloc())) {
243 kfree(radio);
244 return -ENOMEM;
245 }
246 memcpy(radio->videodev, &dsbr100_videodev_template,
247 sizeof(dsbr100_videodev_template));
248 radio->removed = 0;
249 radio->users = 0;
250 radio->usbdev = interface_to_usbdev(intf);
251 radio->curfreq = FREQ_MIN*FREQ_MUL;
252 video_set_drvdata(radio->videodev, radio);
253 if (video_register_device(radio->videodev, VFL_TYPE_RADIO,
254 radio_nr)) {
255 warn("Could not register video device");
256 video_device_release(radio->videodev);
257 kfree(radio);
258 return -EIO;
259 }
260 usb_set_intfdata(intf, radio);
261 return 0;
262}
263
264/* handle unplugging of the device, release data structures
265if nothing keeps us from doing it. If something is still
266keeping us busy, the release callback of v4l will take care
267of releasing it. stv680.c does not relase its private
268data, so I don't do this here either. Checking out the
269code I'd expect I better did that, but if there's a memory
270leak here it's tiny (~50 bytes per disconnect) */
271static void usb_dsbr100_disconnect(struct usb_interface *intf)
272{
273 dsbr100_device *radio = usb_get_intfdata(intf);
274
275 usb_set_intfdata (intf, NULL);
276 if (radio) {
277 video_unregister_device(radio->videodev);
278 radio->videodev = NULL;
279 if (radio->users) {
280 kfree(radio);
281 } else {
282 radio->removed = 1;
283 }
284 }
285}
286
287
288/* Video for Linux interface */
289
290static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file,
291 unsigned int cmd, void *arg)
292{
293 dsbr100_device *radio=video_get_drvdata(video_devdata(file));
294
295 if (!radio)
296 return -EIO;
297
298 switch(cmd) {
299 case VIDIOCGCAP: {
300 struct video_capability *v = arg;
301
302 memset(v, 0, sizeof(*v));
303 v->type = VID_TYPE_TUNER;
304 v->channels = 1;
305 v->audios = 1;
306 strcpy(v->name, "D-Link R-100 USB FM Radio");
307 return 0;
308 }
309 case VIDIOCGTUNER: {
310 struct video_tuner *v = arg;
311
312 dsbr100_getstat(radio);
313 if(v->tuner) /* Only 1 tuner */
314 return -EINVAL;
315 v->rangelow = FREQ_MIN*FREQ_MUL;
316 v->rangehigh = FREQ_MAX*FREQ_MUL;
317 v->flags = VIDEO_TUNER_LOW;
318 v->mode = VIDEO_MODE_AUTO;
319 v->signal = radio->stereo*0x7000;
320 /* Don't know how to get signal strength */
321 v->flags |= VIDEO_TUNER_STEREO_ON*radio->stereo;
322 strcpy(v->name, "DSB R-100");
323 return 0;
324 }
325 case VIDIOCSTUNER: {
326 struct video_tuner *v = arg;
327
328 if(v->tuner!=0)
329 return -EINVAL;
330 /* Only 1 tuner so no setting needed ! */
331 return 0;
332 }
333 case VIDIOCGFREQ: {
334 int *freq = arg;
335
336 if (radio->curfreq==-1)
337 return -EINVAL;
338 *freq = radio->curfreq;
339 return 0;
340 }
341 case VIDIOCSFREQ: {
342 int *freq = arg;
343
344 radio->curfreq = *freq;
345 if (dsbr100_setfreq(radio, radio->curfreq)==-1)
346 warn("Set frequency failed");
347 return 0;
348 }
349 case VIDIOCGAUDIO: {
350 struct video_audio *v = arg;
351
352 memset(v, 0, sizeof(*v));
353 v->flags |= VIDEO_AUDIO_MUTABLE;
354 v->mode = VIDEO_SOUND_STEREO;
355 v->volume = 1;
356 v->step = 1;
357 strcpy(v->name, "Radio");
358 return 0;
359 }
360 case VIDIOCSAUDIO: {
361 struct video_audio *v = arg;
362
363 if (v->audio)
364 return -EINVAL;
365 if (v->flags&VIDEO_AUDIO_MUTE) {
366 if (dsbr100_stop(radio)==-1)
367 warn("Radio did not respond properly");
368 }
369 else
370 if (dsbr100_start(radio)==-1)
371 warn("Radio did not respond properly");
372 return 0;
373 }
374 default:
375 return -ENOIOCTLCMD;
376 }
377}
378
379static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
380 unsigned int cmd, unsigned long arg)
381{
382 return video_usercopy(inode, file, cmd, arg, usb_dsbr100_do_ioctl);
383}
384
385static int usb_dsbr100_open(struct inode *inode, struct file *file)
386{
387 dsbr100_device *radio=video_get_drvdata(video_devdata(file));
388
389 radio->users = 1;
390 if (dsbr100_start(radio)<0) {
391 warn("Radio did not start up properly");
392 radio->users = 0;
393 return -EIO;
394 }
395 dsbr100_setfreq(radio, radio->curfreq);
396 return 0;
397}
398
399static int usb_dsbr100_close(struct inode *inode, struct file *file)
400{
401 dsbr100_device *radio=video_get_drvdata(video_devdata(file));
402
403 if (!radio)
404 return -ENODEV;
405 radio->users = 0;
406 if (radio->removed) {
407 kfree(radio);
408 }
409 return 0;
410}
411
412static int __init dsbr100_init(void)
413{
414 int retval = usb_register(&usb_dsbr100_driver);
415 info(DRIVER_VERSION ":" DRIVER_DESC);
416 return retval;
417}
418
419static void __exit dsbr100_exit(void)
420{
421 usb_deregister(&usb_dsbr100_driver);
422}
423
424module_init (dsbr100_init);
425module_exit (dsbr100_exit);
426
427MODULE_AUTHOR( DRIVER_AUTHOR );
428MODULE_DESCRIPTION( DRIVER_DESC );
429MODULE_LICENSE("GPL");
diff --git a/drivers/usb/media/ibmcam.c b/drivers/usb/media/ibmcam.c
new file mode 100644
index 000000000000..ba41fc7b95c2
--- /dev/null
+++ b/drivers/usb/media/ibmcam.c
@@ -0,0 +1,3932 @@
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/sched.h>
19#include <linux/module.h>
20#include <linux/init.h>
21
22#include "usbvideo.h"
23
24#define IBMCAM_VENDOR_ID 0x0545
25#define IBMCAM_PRODUCT_ID 0x8080
26#define NETCAM_PRODUCT_ID 0x8002 /* IBM NetCamera, close to model 2 */
27#define VEO_800C_PRODUCT_ID 0x800C /* Veo Stingray, repackaged Model 2 */
28#define VEO_800D_PRODUCT_ID 0x800D /* Veo Stingray, repackaged Model 4 */
29
30#define MAX_IBMCAM 4 /* How many devices we allow to connect */
31#define USES_IBMCAM_PUTPIXEL 0 /* 0=Fast/oops 1=Slow/secure */
32
33/* Header signatures */
34
35/* Model 1 header: 00 FF 00 xx */
36#define HDRSIG_MODEL1_128x96 0x06 /* U Y V Y ... */
37#define HDRSIG_MODEL1_176x144 0x0e /* U Y V Y ... */
38#define HDRSIG_MODEL1_352x288 0x00 /* V Y U Y ... */
39
40#define IBMCAM_MODEL_1 1 /* XVP-501, 3 interfaces, rev. 0.02 */
41#define IBMCAM_MODEL_2 2 /* KSX-X9903, 2 interfaces, rev. 3.0a */
42#define IBMCAM_MODEL_3 3 /* KSX-X9902, 2 interfaces, rev. 3.01 */
43#define IBMCAM_MODEL_4 4 /* IBM NetCamera, 0545/8002/3.0a */
44
45/* Video sizes supported */
46#define VIDEOSIZE_128x96 VIDEOSIZE(128, 96)
47#define VIDEOSIZE_176x144 VIDEOSIZE(176,144)
48#define VIDEOSIZE_352x288 VIDEOSIZE(352,288)
49#define VIDEOSIZE_320x240 VIDEOSIZE(320,240)
50#define VIDEOSIZE_352x240 VIDEOSIZE(352,240)
51#define VIDEOSIZE_640x480 VIDEOSIZE(640,480)
52#define VIDEOSIZE_160x120 VIDEOSIZE(160,120)
53
54/* Video sizes supported */
55enum {
56 SIZE_128x96 = 0,
57 SIZE_160x120,
58 SIZE_176x144,
59 SIZE_320x240,
60 SIZE_352x240,
61 SIZE_352x288,
62 SIZE_640x480,
63 /* Add/remove/rearrange items before this line */
64 SIZE_LastItem
65};
66
67/*
68 * This structure lives in uvd->user field.
69 */
70typedef struct {
71 int initialized; /* Had we already sent init sequence? */
72 int camera_model; /* What type of IBM camera we got? */
73 int has_hdr;
74} ibmcam_t;
75#define IBMCAM_T(uvd) ((ibmcam_t *)((uvd)->user_data))
76
77static struct usbvideo *cams;
78
79static int debug;
80
81static int flags; /* = FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */
82
83static const int min_canvasWidth = 8;
84static const int min_canvasHeight = 4;
85
86static int lighting = 1; /* Medium */
87
88#define SHARPNESS_MIN 0
89#define SHARPNESS_MAX 6
90static int sharpness = 4; /* Low noise, good details */
91
92#define FRAMERATE_MIN 0
93#define FRAMERATE_MAX 6
94static int framerate = -1;
95
96static int size = SIZE_352x288;
97
98/*
99 * Here we define several initialization variables. They may
100 * be used to automatically set color, hue, brightness and
101 * contrast to desired values. This is particularly useful in
102 * case of webcams (which have no controls and no on-screen
103 * output) and also when a client V4L software is used that
104 * does not have some of those controls. In any case it's
105 * good to have startup values as options.
106 *
107 * These values are all in [0..255] range. This simplifies
108 * operation. Note that actual values of V4L variables may
109 * be scaled up (as much as << 8). User can see that only
110 * on overlay output, however, or through a V4L client.
111 */
112static int init_brightness = 128;
113static int init_contrast = 192;
114static int init_color = 128;
115static int init_hue = 128;
116static int hue_correction = 128;
117
118/* Settings for camera model 2 */
119static int init_model2_rg2 = -1;
120static int init_model2_sat = -1;
121static int init_model2_yb = -1;
122
123/* 01.01.08 - Added for RCA video in support -LO */
124/* Settings for camera model 3 */
125static int init_model3_input = 0;
126
127module_param(debug, int, 0);
128MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
129module_param(flags, int, 0);
130MODULE_PARM_DESC(flags, "Bitfield: 0=VIDIOCSYNC, 1=B/W, 2=show hints, 3=show stats, 4=test pattern, 5=separate frames, 6=clean frames");
131module_param(framerate, int, 0);
132MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)");
133module_param(lighting, int, 0);
134MODULE_PARM_DESC(lighting, "Photosensitivity: 0=bright, 1=medium (default), 2=low light");
135module_param(sharpness, int, 0);
136MODULE_PARM_DESC(sharpness, "Model1 noise reduction: 0=smooth, 6=sharp (default=4)");
137module_param(size, int, 0);
138MODULE_PARM_DESC(size, "Image size: 0=128x96 1=160x120 2=176x144 3=320x240 4=352x240 5=352x288 6=640x480 (default=5)");
139module_param(init_brightness, int, 0);
140MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)");
141module_param(init_contrast, int, 0);
142MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)");
143module_param(init_color, int, 0);
144MODULE_PARM_DESC(init_color, "Color preconfiguration: 0-255 (default=128)");
145module_param(init_hue, int, 0);
146MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)");
147module_param(hue_correction, int, 0);
148MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)");
149
150module_param(init_model2_rg2, int, 0);
151MODULE_PARM_DESC(init_model2_rg2, "Model2 preconfiguration: 0-255 (default=47)");
152module_param(init_model2_sat, int, 0);
153MODULE_PARM_DESC(init_model2_sat, "Model2 preconfiguration: 0-255 (default=52)");
154module_param(init_model2_yb, int, 0);
155MODULE_PARM_DESC(init_model2_yb, "Model2 preconfiguration: 0-255 (default=160)");
156
157/* 01.01.08 - Added for RCA video in support -LO */
158module_param(init_model3_input, int, 0);
159MODULE_PARM_DESC(init_model3_input, "Model3 input: 0=CCD 1=RCA");
160
161MODULE_AUTHOR ("Dmitri");
162MODULE_DESCRIPTION ("IBM/Xirlink C-it USB Camera Driver for Linux (c) 2000");
163MODULE_LICENSE("GPL");
164
165/* Still mysterious i2c commands */
166static const unsigned short unknown_88 = 0x0088;
167static const unsigned short unknown_89 = 0x0089;
168static const unsigned short bright_3x[3] = { 0x0031, 0x0032, 0x0033 };
169static const unsigned short contrast_14 = 0x0014;
170static const unsigned short light_27 = 0x0027;
171static const unsigned short sharp_13 = 0x0013;
172
173/* i2c commands for Model 2 cameras */
174static const unsigned short mod2_brightness = 0x001a; /* $5b .. $ee; default=$5a */
175static const unsigned short mod2_set_framerate = 0x001c; /* 0 (fast).. $1F (slow) */
176static const unsigned short mod2_color_balance_rg2 = 0x001e; /* 0 (red) .. $7F (green) */
177static const unsigned short mod2_saturation = 0x0020; /* 0 (b/w) - $7F (full color) */
178static const unsigned short mod2_color_balance_yb = 0x0022; /* 0..$7F, $50 is about right */
179static const unsigned short mod2_hue = 0x0024; /* 0..$7F, $70 is about right */
180static const unsigned short mod2_sensitivity = 0x0028; /* 0 (min) .. $1F (max) */
181
182struct struct_initData {
183 unsigned char req;
184 unsigned short value;
185 unsigned short index;
186};
187
188/*
189 * ibmcam_size_to_videosize()
190 *
191 * This procedure converts module option 'size' into the actual
192 * videosize_t that defines the image size in pixels. We need
193 * simplified 'size' because user wants a simple enumerated list
194 * of choices, not an infinite set of possibilities.
195 */
196static videosize_t ibmcam_size_to_videosize(int size)
197{
198 videosize_t vs = VIDEOSIZE_352x288;
199 RESTRICT_TO_RANGE(size, 0, (SIZE_LastItem-1));
200 switch (size) {
201 case SIZE_128x96:
202 vs = VIDEOSIZE_128x96;
203 break;
204 case SIZE_160x120:
205 vs = VIDEOSIZE_160x120;
206 break;
207 case SIZE_176x144:
208 vs = VIDEOSIZE_176x144;
209 break;
210 case SIZE_320x240:
211 vs = VIDEOSIZE_320x240;
212 break;
213 case SIZE_352x240:
214 vs = VIDEOSIZE_352x240;
215 break;
216 case SIZE_352x288:
217 vs = VIDEOSIZE_352x288;
218 break;
219 case SIZE_640x480:
220 vs = VIDEOSIZE_640x480;
221 break;
222 default:
223 err("size=%d. is not valid", size);
224 break;
225 }
226 return vs;
227}
228
229/*
230 * ibmcam_find_header()
231 *
232 * Locate one of supported header markers in the queue.
233 * Once found, remove all preceding bytes AND the marker (4 bytes)
234 * from the data pump queue. Whatever follows must be video lines.
235 *
236 * History:
237 * 1/21/00 Created.
238 */
239static enum ParseState ibmcam_find_header(struct uvd *uvd) /* FIXME: Add frame here */
240{
241 struct usbvideo_frame *frame;
242 ibmcam_t *icam;
243
244 if ((uvd->curframe) < 0 || (uvd->curframe >= USBVIDEO_NUMFRAMES)) {
245 err("ibmcam_find_header: Illegal frame %d.", uvd->curframe);
246 return scan_EndParse;
247 }
248 icam = IBMCAM_T(uvd);
249 assert(icam != NULL);
250 frame = &uvd->frame[uvd->curframe];
251 icam->has_hdr = 0;
252 switch (icam->camera_model) {
253 case IBMCAM_MODEL_1:
254 {
255 const int marker_len = 4;
256 while (RingQueue_GetLength(&uvd->dp) >= marker_len) {
257 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
258 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF) &&
259 (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00))
260 {
261#if 0 /* This code helps to detect new frame markers */
262 info("Header sig: 00 FF 00 %02X", RING_QUEUE_PEEK(&uvd->dp, 3));
263#endif
264 frame->header = RING_QUEUE_PEEK(&uvd->dp, 3);
265 if ((frame->header == HDRSIG_MODEL1_128x96) ||
266 (frame->header == HDRSIG_MODEL1_176x144) ||
267 (frame->header == HDRSIG_MODEL1_352x288))
268 {
269#if 0
270 info("Header found.");
271#endif
272 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len);
273 icam->has_hdr = 1;
274 break;
275 }
276 }
277 /* If we are still here then this doesn't look like a header */
278 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
279 }
280 break;
281 }
282 case IBMCAM_MODEL_2:
283case IBMCAM_MODEL_4:
284 {
285 int marker_len = 0;
286 switch (uvd->videosize) {
287 case VIDEOSIZE_176x144:
288 marker_len = 10;
289 break;
290 default:
291 marker_len = 2;
292 break;
293 }
294 while (RingQueue_GetLength(&uvd->dp) >= marker_len) {
295 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
296 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF))
297 {
298#if 0
299 info("Header found.");
300#endif
301 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len);
302 icam->has_hdr = 1;
303 frame->header = HDRSIG_MODEL1_176x144;
304 break;
305 }
306 /* If we are still here then this doesn't look like a header */
307 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
308 }
309 break;
310 }
311 case IBMCAM_MODEL_3:
312 { /*
313 * Headers: (one precedes every frame). nc=no compression,
314 * bq=best quality bf=best frame rate.
315 *
316 * 176x144: 00 FF 02 { 0A=nc CA=bq EA=bf }
317 * 320x240: 00 FF 02 { 08=nc 28=bq 68=bf }
318 * 640x480: 00 FF 03 { 08=nc 28=bq 68=bf }
319 *
320 * Bytes '00 FF' seem to indicate header. Other two bytes
321 * encode the frame type. This is a set of bit fields that
322 * encode image size, compression type etc. These fields
323 * do NOT contain frame number because all frames carry
324 * the same header.
325 */
326 const int marker_len = 4;
327 while (RingQueue_GetLength(&uvd->dp) >= marker_len) {
328 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
329 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF) &&
330 (RING_QUEUE_PEEK(&uvd->dp, 2) != 0xFF))
331 {
332 /*
333 * Combine 2 bytes of frame type into one
334 * easy to use value
335 */
336 unsigned long byte3, byte4;
337
338 byte3 = RING_QUEUE_PEEK(&uvd->dp, 2);
339 byte4 = RING_QUEUE_PEEK(&uvd->dp, 3);
340 frame->header = (byte3 << 8) | byte4;
341#if 0
342 info("Header found.");
343#endif
344 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len);
345 icam->has_hdr = 1;
346 break;
347 }
348 /* If we are still here then this doesn't look like a header */
349 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
350 }
351 break;
352 }
353 default:
354 break;
355 }
356 if (!icam->has_hdr) {
357 if (uvd->debug > 2)
358 info("Skipping frame, no header");
359 return scan_EndParse;
360 }
361
362 /* Header found */
363 icam->has_hdr = 1;
364 uvd->stats.header_count++;
365 frame->scanstate = ScanState_Lines;
366 frame->curline = 0;
367
368 if (flags & FLAGS_FORCE_TESTPATTERN) {
369 usbvideo_TestPattern(uvd, 1, 1);
370 return scan_NextFrame;
371 }
372 return scan_Continue;
373}
374
375/*
376 * ibmcam_parse_lines()
377 *
378 * Parse one line (interlaced) from the buffer, put
379 * decoded RGB value into the current frame buffer
380 * and add the written number of bytes (RGB) to
381 * the *pcopylen.
382 *
383 * History:
384 * 21-Jan-2000 Created.
385 * 12-Oct-2000 Reworked to reflect interlaced nature of the data.
386 */
387static enum ParseState ibmcam_parse_lines(
388 struct uvd *uvd,
389 struct usbvideo_frame *frame,
390 long *pcopylen)
391{
392 unsigned char *f;
393 ibmcam_t *icam;
394 unsigned int len, scanLength, scanHeight, order_uv, order_yc;
395 int v4l_linesize; /* V4L line offset */
396 const int hue_corr = (uvd->vpic.hue - 0x8000) >> 10; /* -32..+31 */
397 const int hue2_corr = (hue_correction - 128) / 4; /* -32..+31 */
398 const int ccm = 128; /* Color correction median - see below */
399 int y, u, v, i, frame_done=0, color_corr;
400 static unsigned char lineBuffer[640*3];
401 unsigned const char *chromaLine, *lumaLine;
402
403 assert(uvd != NULL);
404 assert(frame != NULL);
405 icam = IBMCAM_T(uvd);
406 assert(icam != NULL);
407 color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
408 RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1);
409
410 v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
411
412 if (IBMCAM_T(uvd)->camera_model == IBMCAM_MODEL_4) {
413 /* Model 4 frame markers do not carry image size identification */
414 switch (uvd->videosize) {
415 case VIDEOSIZE_128x96:
416 case VIDEOSIZE_160x120:
417 case VIDEOSIZE_176x144:
418 scanLength = VIDEOSIZE_X(uvd->videosize);
419 scanHeight = VIDEOSIZE_Y(uvd->videosize);
420 break;
421 default:
422 err("ibmcam_parse_lines: Wrong mode.");
423 return scan_Out;
424 }
425 order_yc = 1; /* order_yc: true=Yc false=cY ('c'=either U or V) */
426 order_uv = 1; /* Always true in this algorithm */
427 } else {
428 switch (frame->header) {
429 case HDRSIG_MODEL1_128x96:
430 scanLength = 128;
431 scanHeight = 96;
432 order_uv = 1; /* U Y V Y ... */
433 break;
434 case HDRSIG_MODEL1_176x144:
435 scanLength = 176;
436 scanHeight = 144;
437 order_uv = 1; /* U Y V Y ... */
438 break;
439 case HDRSIG_MODEL1_352x288:
440 scanLength = 352;
441 scanHeight = 288;
442 order_uv = 0; /* Y V Y V ... */
443 break;
444 default:
445 err("Unknown header signature 00 FF 00 %02lX", frame->header);
446 return scan_NextFrame;
447 }
448 /* order_yc: true=Yc false=cY ('c'=either U or V) */
449 order_yc = (IBMCAM_T(uvd)->camera_model == IBMCAM_MODEL_2);
450 }
451
452 len = scanLength * 3;
453 assert(len <= sizeof(lineBuffer));
454
455 /*
456 * Lines are organized this way:
457 *
458 * I420:
459 * ~~~~
460 * <scanLength->
461 * ___________________________________
462 * |-----Y-----|---UVUVUV...UVUV-----| \
463 * |-----------+---------------------| \
464 * |<-- 176 -->|<------ 176*2 ------>| Total 72. lines (interlaced)
465 * |... ... | ... | /
466 * |<-- 352 -->|<------ 352*2 ------>| Total 144. lines (interlaced)
467 * |___________|_____________________| /
468 * \ \
469 * lumaLine chromaLine
470 */
471
472 /* Make sure there's enough data for the entire line */
473 if (RingQueue_GetLength(&uvd->dp) < len)
474 return scan_Out;
475
476 /* Suck one line out of the ring queue */
477 RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
478
479 /*
480 * Make sure that our writing into output buffer
481 * will not exceed the buffer. Mind that we may write
482 * not into current output scanline but in several after
483 * it as well (if we enlarge image vertically.)
484 */
485 if ((frame->curline + 2) >= VIDEOSIZE_Y(frame->request))
486 return scan_NextFrame;
487
488 /*
489 * Now we are sure that entire line (representing all 'scanLength'
490 * pixels from the camera) is available in the buffer. We
491 * start copying the line left-aligned to the V4L buffer.
492 * If the camera line is shorter then we should pad the V4L
493 * buffer with something (black) to complete the line.
494 */
495 assert(frame->data != NULL);
496 f = frame->data + (v4l_linesize * frame->curline);
497
498 /*
499 * To obtain chrominance data from the 'chromaLine' use this:
500 * v = chromaLine[0]; // 0-1:[0], 2-3:[4], 4-5:[8]...
501 * u = chromaLine[2]; // 0-1:[2], 2-3:[6], 4-5:[10]...
502 *
503 * Indices must be calculated this way:
504 * v_index = (i >> 1) << 2;
505 * u_index = (i >> 1) << 2 + 2;
506 *
507 * where 'i' is the column number [0..VIDEOSIZE_X(frame->request)-1]
508 */
509 lumaLine = lineBuffer;
510 chromaLine = lineBuffer + scanLength;
511 for (i = 0; i < VIDEOSIZE_X(frame->request); i++)
512 {
513 unsigned char rv, gv, bv; /* RGB components */
514
515 /* Check for various visual debugging hints (colorized pixels) */
516 if ((flags & FLAGS_DISPLAY_HINTS) && (icam->has_hdr)) {
517 /*
518 * This is bad and should not happen. This means that
519 * we somehow overshoot the line and encountered new
520 * frame! Obviously our camera/V4L frame size is out
521 * of whack. This cyan dot will help you to figure
522 * out where exactly the new frame arrived.
523 */
524 if (icam->has_hdr == 1) {
525 bv = 0; /* Yellow marker */
526 gv = 0xFF;
527 rv = 0xFF;
528 } else {
529 bv = 0xFF; /* Cyan marker */
530 gv = 0xFF;
531 rv = 0;
532 }
533 icam->has_hdr = 0;
534 goto make_pixel;
535 }
536
537 /*
538 * Check if we are still in range. We may be out of range if our
539 * V4L canvas is wider or taller than the camera "native" image.
540 * Then we quickly fill the remainder of the line with zeros to
541 * make black color and quit the horizontal scanning loop.
542 */
543 if (((frame->curline + 2) >= scanHeight) || (i >= scanLength)) {
544 const int j = i * V4L_BYTES_PER_PIXEL;
545#if USES_IBMCAM_PUTPIXEL
546 /* Refresh 'f' because we don't use it much with PUTPIXEL */
547 f = frame->data + (v4l_linesize * frame->curline) + j;
548#endif
549 memset(f, 0, v4l_linesize - j);
550 break;
551 }
552
553 y = lumaLine[i];
554 if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */
555 rv = gv = bv = y;
556 else {
557 int off_0, off_2;
558
559 off_0 = (i >> 1) << 2;
560 off_2 = off_0 + 2;
561
562 if (order_yc) {
563 off_0++;
564 off_2++;
565 }
566 if (!order_uv) {
567 off_0 += 2;
568 off_2 -= 2;
569 }
570 u = chromaLine[off_0] + hue_corr;
571 v = chromaLine[off_2] + hue2_corr;
572
573 /* Apply color correction */
574 if (color_corr != 0) {
575 /* Magnify up to 2 times, reduce down to zero saturation */
576 u = 128 + ((ccm + color_corr) * (u - 128)) / ccm;
577 v = 128 + ((ccm + color_corr) * (v - 128)) / ccm;
578 }
579 YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv);
580 }
581
582 make_pixel:
583 /*
584 * The purpose of creating the pixel here, in one,
585 * dedicated place is that we may need to make the
586 * pixel wider and taller than it actually is. This
587 * may be used if camera generates small frames for
588 * sake of frame rate (or any other reason.)
589 *
590 * The output data consists of B, G, R bytes
591 * (in this order).
592 */
593#if USES_IBMCAM_PUTPIXEL
594 RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
595#else
596 *f++ = bv;
597 *f++ = gv;
598 *f++ = rv;
599#endif
600 /*
601 * Typically we do not decide within a legitimate frame
602 * that we want to end the frame. However debugging code
603 * may detect marker of new frame within the data. Then
604 * this condition activates. The 'data' pointer is already
605 * pointing at the new marker, so we'd better leave it as is.
606 */
607 if (frame_done)
608 break; /* End scanning of lines */
609 }
610 /*
611 * Account for number of bytes that we wrote into output V4L frame.
612 * We do it here, after we are done with the scanline, because we
613 * may fill more than one output scanline if we do vertical
614 * enlargement.
615 */
616 frame->curline += 2;
617 if (pcopylen != NULL)
618 *pcopylen += 2 * v4l_linesize;
619 frame->deinterlace = Deinterlace_FillOddLines;
620
621 if (frame_done || (frame->curline >= VIDEOSIZE_Y(frame->request)))
622 return scan_NextFrame;
623 else
624 return scan_Continue;
625}
626
627/*
628 * ibmcam_model2_320x240_parse_lines()
629 *
630 * This procedure deals with a weird RGB format that is produced by IBM
631 * camera model 2 in modes 320x240 and above; 'x' below is 159 or 175,
632 * depending on horizontal size of the picture:
633 *
634 * <--- 160 or 176 pairs of RA,RB bytes ----->
635 * *-----------------------------------------* \
636 * | RA0 | RB0 | RA1 | RB1 | ... | RAx | RBx | \ This is pair of horizontal lines,
637 * |-----+-----+-----+-----+ ... +-----+-----| *- or one interlaced line, total
638 * | B0 | G0 | B1 | G1 | ... | Bx | Gx | / 120 or 144 such pairs which yield
639 * |=====+=====+=====+=====+ ... +=====+=====| / 240 or 288 lines after deinterlacing.
640 *
641 * Each group of FOUR bytes (RAi, RBi, Bi, Gi) where i=0..frame_width/2-1
642 * defines ONE pixel. Therefore this format yields 176x144 "decoded"
643 * resolution at best. I do not know why camera sends such format - the
644 * previous model (1) just used interlaced I420 and everyone was happy.
645 *
646 * I do not know what is the difference between RAi and RBi bytes. Both
647 * seemingly represent R component, but slightly vary in value (so that
648 * the picture looks a bit colored if one or another is used). I use
649 * them both as R component in attempt to at least partially recover the
650 * lost resolution.
651 */
652static enum ParseState ibmcam_model2_320x240_parse_lines(
653 struct uvd *uvd,
654 struct usbvideo_frame *frame,
655 long *pcopylen)
656{
657 unsigned char *f, *la, *lb;
658 unsigned int len;
659 int v4l_linesize; /* V4L line offset */
660 int i, j, frame_done=0, color_corr;
661 int scanLength, scanHeight;
662 static unsigned char lineBuffer[352*2];
663
664 switch (uvd->videosize) {
665 case VIDEOSIZE_320x240:
666 case VIDEOSIZE_352x240:
667 case VIDEOSIZE_352x288:
668 scanLength = VIDEOSIZE_X(uvd->videosize);
669 scanHeight = VIDEOSIZE_Y(uvd->videosize);
670 break;
671 default:
672 err("ibmcam_model2_320x240_parse_lines: Wrong mode.");
673 return scan_Out;
674 }
675
676 color_corr = (uvd->vpic.colour) >> 8; /* 0..+255 */
677 v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
678
679 len = scanLength * 2; /* See explanation above */
680 assert(len <= sizeof(lineBuffer));
681
682 /* Make sure there's enough data for the entire line */
683 if (RingQueue_GetLength(&uvd->dp) < len)
684 return scan_Out;
685
686 /* Suck one line out of the ring queue */
687 RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
688
689 /*
690 * Make sure that our writing into output buffer
691 * will not exceed the buffer. Mind that we may write
692 * not into current output scanline but in several after
693 * it as well (if we enlarge image vertically.)
694 */
695 if ((frame->curline + 2) >= VIDEOSIZE_Y(frame->request))
696 return scan_NextFrame;
697
698 la = lineBuffer;
699 lb = lineBuffer + scanLength;
700
701 /*
702 * Now we are sure that entire line (representing all
703 * VIDEOSIZE_X(frame->request)
704 * pixels from the camera) is available in the scratch buffer. We
705 * start copying the line left-aligned to the V4L buffer (which
706 * might be larger - not smaller, hopefully). If the camera
707 * line is shorter then we should pad the V4L buffer with something
708 * (black in this case) to complete the line.
709 */
710 f = frame->data + (v4l_linesize * frame->curline);
711
712 /* Fill the 2-line strip */
713 for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
714 int y, rv, gv, bv; /* RGB components */
715
716 j = i & (~1);
717
718 /* Check for various visual debugging hints (colorized pixels) */
719 if ((flags & FLAGS_DISPLAY_HINTS) && (IBMCAM_T(uvd)->has_hdr)) {
720 if (IBMCAM_T(uvd)->has_hdr == 1) {
721 bv = 0; /* Yellow marker */
722 gv = 0xFF;
723 rv = 0xFF;
724 } else {
725 bv = 0xFF; /* Cyan marker */
726 gv = 0xFF;
727 rv = 0;
728 }
729 IBMCAM_T(uvd)->has_hdr = 0;
730 goto make_pixel;
731 }
732
733 /*
734 * Check if we are still in range. We may be out of range if our
735 * V4L canvas is wider or taller than the camera "native" image.
736 * Then we quickly fill the remainder of the line with zeros to
737 * make black color and quit the horizontal scanning loop.
738 */
739 if (((frame->curline + 2) >= scanHeight) || (i >= scanLength)) {
740 const int j = i * V4L_BYTES_PER_PIXEL;
741#if USES_IBMCAM_PUTPIXEL
742 /* Refresh 'f' because we don't use it much with PUTPIXEL */
743 f = frame->data + (v4l_linesize * frame->curline) + j;
744#endif
745 memset(f, 0, v4l_linesize - j);
746 break;
747 }
748
749 /*
750 * Here I use RA and RB components, one per physical pixel.
751 * This causes fine vertical grid on the picture but may improve
752 * horizontal resolution. If you prefer replicating, use this:
753 * rv = la[j + 0]; ... or ... rv = la[j + 1];
754 * then the pixel will be replicated.
755 */
756 rv = la[i];
757 gv = lb[j + 1];
758 bv = lb[j + 0];
759
760 y = (rv + gv + bv) / 3; /* Brightness (badly calculated) */
761
762 if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */
763 rv = gv = bv = y;
764 else if (color_corr != 128) {
765
766 /* Calculate difference between color and brightness */
767 rv -= y;
768 gv -= y;
769 bv -= y;
770
771 /* Scale differences */
772 rv = (rv * color_corr) / 128;
773 gv = (gv * color_corr) / 128;
774 bv = (bv * color_corr) / 128;
775
776 /* Reapply brightness */
777 rv += y;
778 gv += y;
779 bv += y;
780
781 /* Watch for overflows */
782 RESTRICT_TO_RANGE(rv, 0, 255);
783 RESTRICT_TO_RANGE(gv, 0, 255);
784 RESTRICT_TO_RANGE(bv, 0, 255);
785 }
786
787 make_pixel:
788 RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
789 }
790 /*
791 * Account for number of bytes that we wrote into output V4L frame.
792 * We do it here, after we are done with the scanline, because we
793 * may fill more than one output scanline if we do vertical
794 * enlargement.
795 */
796 frame->curline += 2;
797 *pcopylen += v4l_linesize * 2;
798 frame->deinterlace = Deinterlace_FillOddLines;
799
800 if (frame_done || (frame->curline >= VIDEOSIZE_Y(frame->request)))
801 return scan_NextFrame;
802 else
803 return scan_Continue;
804}
805
806static enum ParseState ibmcam_model3_parse_lines(
807 struct uvd *uvd,
808 struct usbvideo_frame *frame,
809 long *pcopylen)
810{
811 unsigned char *data;
812 const unsigned char *color;
813 unsigned int len;
814 int v4l_linesize; /* V4L line offset */
815 const int hue_corr = (uvd->vpic.hue - 0x8000) >> 10; /* -32..+31 */
816 const int hue2_corr = (hue_correction - 128) / 4; /* -32..+31 */
817 const int ccm = 128; /* Color correction median - see below */
818 int i, u, v, rw, data_w=0, data_h=0, color_corr;
819 static unsigned char lineBuffer[640*3];
820
821 color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
822 RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1);
823
824 v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
825
826 /* The header tells us what sort of data is in this frame */
827 switch (frame->header) {
828 /*
829 * Uncompressed modes (that are easy to decode).
830 */
831 case 0x0308:
832 data_w = 640;
833 data_h = 480;
834 break;
835 case 0x0208:
836 data_w = 320;
837 data_h = 240;
838 break;
839 case 0x020A:
840 data_w = 160;
841 data_h = 120;
842 break;
843 /*
844 * Compressed modes (ViCE - that I don't know how to decode).
845 */
846 case 0x0328: /* 640x480, best quality compression */
847 case 0x0368: /* 640x480, best frame rate compression */
848 case 0x0228: /* 320x240, best quality compression */
849 case 0x0268: /* 320x240, best frame rate compression */
850 case 0x02CA: /* 160x120, best quality compression */
851 case 0x02EA: /* 160x120, best frame rate compression */
852 /* Do nothing with this - not supported */
853 err("Unsupported mode $%04lx", frame->header);
854 return scan_NextFrame;
855 default:
856 /* Catch unknown headers, may help in learning new headers */
857 err("Strange frame->header=$%08lx", frame->header);
858 return scan_NextFrame;
859 }
860
861 /*
862 * Make sure that our writing into output buffer
863 * will not exceed the buffer. Note that we may write
864 * not into current output scanline but in several after
865 * it as well (if we enlarge image vertically.)
866 */
867 if ((frame->curline + 1) >= data_h) {
868 if (uvd->debug >= 3)
869 info("Reached line %d. (frame is done)", frame->curline);
870 return scan_NextFrame;
871 }
872
873 /* Make sure there's enough data for the entire line */
874 len = 3 * data_w; /* <y-data> <uv-data> */
875 assert(len <= sizeof(lineBuffer));
876
877 /* Make sure there's enough data for the entire line */
878 if (RingQueue_GetLength(&uvd->dp) < len)
879 return scan_Out;
880
881 /* Suck one line out of the ring queue */
882 RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
883
884 data = lineBuffer;
885 color = data + data_w; /* Point to where color planes begin */
886
887 /* Bottom-to-top scanning */
888 rw = (int)VIDEOSIZE_Y(frame->request) - (int)(frame->curline) - 1;
889 RESTRICT_TO_RANGE(rw, 0, VIDEOSIZE_Y(frame->request)-1);
890
891 for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
892 int y, rv, gv, bv; /* RGB components */
893
894 if (i < data_w) {
895 y = data[i]; /* Luminosity is the first line */
896
897 /* Apply static color correction */
898 u = color[i*2] + hue_corr;
899 v = color[i*2 + 1] + hue2_corr;
900
901 /* Apply color correction */
902 if (color_corr != 0) {
903 /* Magnify up to 2 times, reduce down to zero saturation */
904 u = 128 + ((ccm + color_corr) * (u - 128)) / ccm;
905 v = 128 + ((ccm + color_corr) * (v - 128)) / ccm;
906 }
907 } else
908 y = 0, u = v = 128;
909
910 YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv);
911 RGB24_PUTPIXEL(frame, i, rw, rv, gv, bv); /* Done by deinterlacing now */
912 }
913 frame->deinterlace = Deinterlace_FillEvenLines;
914
915 /*
916 * Account for number of bytes that we wrote into output V4L frame.
917 * We do it here, after we are done with the scanline, because we
918 * may fill more than one output scanline if we do vertical
919 * enlargement.
920 */
921 frame->curline += 2;
922 *pcopylen += 2 * v4l_linesize;
923
924 if (frame->curline >= VIDEOSIZE_Y(frame->request)) {
925 if (uvd->debug >= 3) {
926 info("All requested lines (%ld.) done.",
927 VIDEOSIZE_Y(frame->request));
928 }
929 return scan_NextFrame;
930 } else
931 return scan_Continue;
932}
933
934/*
935 * ibmcam_model4_128x96_parse_lines()
936 *
937 * This decoder is for one strange data format that is produced by Model 4
938 * camera only in 128x96 mode. This is RGB format and here is its description.
939 * First of all, this is non-interlaced stream, meaning that all scan lines
940 * are present in the datastream. There are 96 consecutive blocks of data
941 * that describe all 96 lines of the image. Each block is 5*128 bytes long
942 * and carries R, G, B components. The format of the block is shown in the
943 * code below. First 128*2 bytes are interleaved R and G components. Then
944 * we have a gap (junk data) 64 bytes long. Then follow B and something
945 * else, also interleaved (this makes another 128*2 bytes). After that
946 * probably another 64 bytes of junk follow.
947 *
948 * History:
949 * 10-Feb-2001 Created.
950 */
951static enum ParseState ibmcam_model4_128x96_parse_lines(
952 struct uvd *uvd,
953 struct usbvideo_frame *frame,
954 long *pcopylen)
955{
956 const unsigned char *data_rv, *data_gv, *data_bv;
957 unsigned int len;
958 int i, v4l_linesize; /* V4L line offset */
959 const int data_w=128, data_h=96;
960 static unsigned char lineBuffer[128*5];
961
962 v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
963
964 /*
965 * Make sure that our writing into output buffer
966 * will not exceed the buffer. Note that we may write
967 * not into current output scanline but in several after
968 * it as well (if we enlarge image vertically.)
969 */
970 if ((frame->curline + 1) >= data_h) {
971 if (uvd->debug >= 3)
972 info("Reached line %d. (frame is done)", frame->curline);
973 return scan_NextFrame;
974 }
975
976 /*
977 * RGRGRG .... RGRG_____________B?B?B? ... B?B?____________
978 * <---- 128*2 ---><---- 64 ---><--- 128*2 ---><--- 64 --->
979 */
980
981 /* Make sure there's enough data for the entire line */
982 len = 5 * data_w;
983 assert(len <= sizeof(lineBuffer));
984
985 /* Make sure there's enough data for the entire line */
986 if (RingQueue_GetLength(&uvd->dp) < len)
987 return scan_Out;
988
989 /* Suck one line out of the ring queue */
990 RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
991
992 data_rv = lineBuffer;
993 data_gv = lineBuffer + 1;
994 data_bv = lineBuffer + data_w*2 + data_w/2;
995 for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
996 int rv, gv, bv; /* RGB components */
997 if (i < data_w) {
998 const int j = i * 2;
999 gv = data_rv[j];
1000 rv = data_gv[j];
1001 bv = data_bv[j];
1002 if (flags & FLAGS_MONOCHROME) {
1003 unsigned long y;
1004 y = rv + gv + bv;
1005 y /= 3;
1006 if (y > 0xFF)
1007 y = 0xFF;
1008 rv = gv = bv = (unsigned char) y;
1009 }
1010 } else {
1011 rv = gv = bv = 0;
1012 }
1013 RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
1014 }
1015 frame->deinterlace = Deinterlace_None;
1016 frame->curline++;
1017 *pcopylen += v4l_linesize;
1018
1019 if (frame->curline >= VIDEOSIZE_Y(frame->request)) {
1020 if (uvd->debug >= 3) {
1021 info("All requested lines (%ld.) done.",
1022 VIDEOSIZE_Y(frame->request));
1023 }
1024 return scan_NextFrame;
1025 } else
1026 return scan_Continue;
1027}
1028
1029/*
1030 * ibmcam_ProcessIsocData()
1031 *
1032 * Generic routine to parse the ring queue data. It employs either
1033 * ibmcam_find_header() or ibmcam_parse_lines() to do most
1034 * of work.
1035 *
1036 * History:
1037 * 1/21/00 Created.
1038 */
1039static void ibmcam_ProcessIsocData(struct uvd *uvd,
1040 struct usbvideo_frame *frame)
1041{
1042 enum ParseState newstate;
1043 long copylen = 0;
1044 int mod = IBMCAM_T(uvd)->camera_model;
1045
1046 while (1) {
1047 newstate = scan_Out;
1048 if (RingQueue_GetLength(&uvd->dp) > 0) {
1049 if (frame->scanstate == ScanState_Scanning) {
1050 newstate = ibmcam_find_header(uvd);
1051 } else if (frame->scanstate == ScanState_Lines) {
1052 if ((mod == IBMCAM_MODEL_2) &&
1053 ((uvd->videosize == VIDEOSIZE_352x288) ||
1054 (uvd->videosize == VIDEOSIZE_320x240) ||
1055 (uvd->videosize == VIDEOSIZE_352x240)))
1056 {
1057 newstate = ibmcam_model2_320x240_parse_lines(
1058 uvd, frame, &copylen);
1059 } else if (mod == IBMCAM_MODEL_4) {
1060 /*
1061 * Model 4 cameras (IBM NetCamera) use Model 2 decoder (RGB)
1062 * for 320x240 and above; 160x120 and 176x144 uses Model 1
1063 * decoder (YUV), and 128x96 mode uses ???
1064 */
1065 if ((uvd->videosize == VIDEOSIZE_352x288) ||
1066 (uvd->videosize == VIDEOSIZE_320x240) ||
1067 (uvd->videosize == VIDEOSIZE_352x240))
1068 {
1069 newstate = ibmcam_model2_320x240_parse_lines(uvd, frame, &copylen);
1070 } else if (uvd->videosize == VIDEOSIZE_128x96) {
1071 newstate = ibmcam_model4_128x96_parse_lines(uvd, frame, &copylen);
1072 } else {
1073 newstate = ibmcam_parse_lines(uvd, frame, &copylen);
1074 }
1075 } else if (mod == IBMCAM_MODEL_3) {
1076 newstate = ibmcam_model3_parse_lines(uvd, frame, &copylen);
1077 } else {
1078 newstate = ibmcam_parse_lines(uvd, frame, &copylen);
1079 }
1080 }
1081 }
1082 if (newstate == scan_Continue)
1083 continue;
1084 else if ((newstate == scan_NextFrame) || (newstate == scan_Out))
1085 break;
1086 else
1087 return; /* scan_EndParse */
1088 }
1089
1090 if (newstate == scan_NextFrame) {
1091 frame->frameState = FrameState_Done;
1092 uvd->curframe = -1;
1093 uvd->stats.frame_num++;
1094 if ((mod == IBMCAM_MODEL_2) || (mod == IBMCAM_MODEL_4)) {
1095 /* Need software contrast adjustment for those cameras */
1096 frame->flags |= USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST;
1097 }
1098 }
1099
1100 /* Update the frame's uncompressed length. */
1101 frame->seqRead_Length += copylen;
1102
1103#if 0
1104 {
1105 static unsigned char j=0;
1106 memset(frame->data, j++, uvd->max_frame_size);
1107 frame->frameState = FrameState_Ready;
1108 }
1109#endif
1110}
1111
1112/*
1113 * ibmcam_veio()
1114 *
1115 * History:
1116 * 1/27/00 Added check for dev == NULL; this happens if camera is unplugged.
1117 */
1118static int ibmcam_veio(
1119 struct uvd *uvd,
1120 unsigned char req,
1121 unsigned short value,
1122 unsigned short index)
1123{
1124 static const char proc[] = "ibmcam_veio";
1125 unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */;
1126 int i;
1127
1128 if (!CAMERA_IS_OPERATIONAL(uvd))
1129 return 0;
1130
1131 if (req == 1) {
1132 i = usb_control_msg(
1133 uvd->dev,
1134 usb_rcvctrlpipe(uvd->dev, 0),
1135 req,
1136 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
1137 value,
1138 index,
1139 cp,
1140 sizeof(cp),
1141 1000);
1142#if 0
1143 info("USB => %02x%02x%02x%02x%02x%02x%02x%02x "
1144 "(req=$%02x val=$%04x ind=$%04x)",
1145 cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7],
1146 req, value, index);
1147#endif
1148 } else {
1149 i = usb_control_msg(
1150 uvd->dev,
1151 usb_sndctrlpipe(uvd->dev, 0),
1152 req,
1153 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
1154 value,
1155 index,
1156 NULL,
1157 0,
1158 1000);
1159 }
1160 if (i < 0) {
1161 err("%s: ERROR=%d. Camera stopped; Reconnect or reload driver.",
1162 proc, i);
1163 uvd->last_error = i;
1164 }
1165 return i;
1166}
1167
1168/*
1169 * ibmcam_calculate_fps()
1170 *
1171 * This procedure roughly calculates the real frame rate based
1172 * on FPS code (framerate=NNN option). Actual FPS differs
1173 * slightly depending on lighting conditions, so that actual frame
1174 * rate is determined by the camera. Since I don't know how to ask
1175 * the camera what FPS is now I have to use the FPS code instead.
1176 *
1177 * The FPS code is in range [0..6], 0 is slowest, 6 is fastest.
1178 * Corresponding real FPS should be in range [3..30] frames per second.
1179 * The conversion formula is obvious:
1180 *
1181 * real_fps = 3 + (fps_code * 4.5)
1182 *
1183 * History:
1184 * 1/18/00 Created.
1185 */
1186static int ibmcam_calculate_fps(struct uvd *uvd)
1187{
1188 return 3 + framerate*4 + framerate/2;
1189}
1190
1191/*
1192 * ibmcam_send_FF_04_02()
1193 *
1194 * This procedure sends magic 3-command prefix to the camera.
1195 * The purpose of this prefix is not known.
1196 *
1197 * History:
1198 * 1/2/00 Created.
1199 */
1200static void ibmcam_send_FF_04_02(struct uvd *uvd)
1201{
1202 ibmcam_veio(uvd, 0, 0x00FF, 0x0127);
1203 ibmcam_veio(uvd, 0, 0x0004, 0x0124);
1204 ibmcam_veio(uvd, 0, 0x0002, 0x0124);
1205}
1206
1207static void ibmcam_send_00_04_06(struct uvd *uvd)
1208{
1209 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
1210 ibmcam_veio(uvd, 0, 0x0004, 0x0124);
1211 ibmcam_veio(uvd, 0, 0x0006, 0x0124);
1212}
1213
1214static void ibmcam_send_x_00(struct uvd *uvd, unsigned short x)
1215{
1216 ibmcam_veio(uvd, 0, x, 0x0127);
1217 ibmcam_veio(uvd, 0, 0x0000, 0x0124);
1218}
1219
1220static void ibmcam_send_x_00_05(struct uvd *uvd, unsigned short x)
1221{
1222 ibmcam_send_x_00(uvd, x);
1223 ibmcam_veio(uvd, 0, 0x0005, 0x0124);
1224}
1225
1226static void ibmcam_send_x_00_05_02(struct uvd *uvd, unsigned short x)
1227{
1228 ibmcam_veio(uvd, 0, x, 0x0127);
1229 ibmcam_veio(uvd, 0, 0x0000, 0x0124);
1230 ibmcam_veio(uvd, 0, 0x0005, 0x0124);
1231 ibmcam_veio(uvd, 0, 0x0002, 0x0124);
1232}
1233
1234static void ibmcam_send_x_01_00_05(struct uvd *uvd, unsigned short x)
1235{
1236 ibmcam_veio(uvd, 0, x, 0x0127);
1237 ibmcam_veio(uvd, 0, 0x0001, 0x0124);
1238 ibmcam_veio(uvd, 0, 0x0000, 0x0124);
1239 ibmcam_veio(uvd, 0, 0x0005, 0x0124);
1240}
1241
1242static void ibmcam_send_x_00_05_02_01(struct uvd *uvd, unsigned short x)
1243{
1244 ibmcam_veio(uvd, 0, x, 0x0127);
1245 ibmcam_veio(uvd, 0, 0x0000, 0x0124);
1246 ibmcam_veio(uvd, 0, 0x0005, 0x0124);
1247 ibmcam_veio(uvd, 0, 0x0002, 0x0124);
1248 ibmcam_veio(uvd, 0, 0x0001, 0x0124);
1249}
1250
1251static void ibmcam_send_x_00_05_02_08_01(struct uvd *uvd, unsigned short x)
1252{
1253 ibmcam_veio(uvd, 0, x, 0x0127);
1254 ibmcam_veio(uvd, 0, 0x0000, 0x0124);
1255 ibmcam_veio(uvd, 0, 0x0005, 0x0124);
1256 ibmcam_veio(uvd, 0, 0x0002, 0x0124);
1257 ibmcam_veio(uvd, 0, 0x0008, 0x0124);
1258 ibmcam_veio(uvd, 0, 0x0001, 0x0124);
1259}
1260
1261static void ibmcam_Packet_Format1(struct uvd *uvd, unsigned char fkey, unsigned char val)
1262{
1263 ibmcam_send_x_01_00_05(uvd, unknown_88);
1264 ibmcam_send_x_00_05(uvd, fkey);
1265 ibmcam_send_x_00_05_02_08_01(uvd, val);
1266 ibmcam_send_x_00_05(uvd, unknown_88);
1267 ibmcam_send_x_00_05_02_01(uvd, fkey);
1268 ibmcam_send_x_00_05(uvd, unknown_89);
1269 ibmcam_send_x_00(uvd, fkey);
1270 ibmcam_send_00_04_06(uvd);
1271 ibmcam_veio(uvd, 1, 0x0000, 0x0126);
1272 ibmcam_send_FF_04_02(uvd);
1273}
1274
1275static void ibmcam_PacketFormat2(struct uvd *uvd, unsigned char fkey, unsigned char val)
1276{
1277 ibmcam_send_x_01_00_05 (uvd, unknown_88);
1278 ibmcam_send_x_00_05 (uvd, fkey);
1279 ibmcam_send_x_00_05_02 (uvd, val);
1280}
1281
1282static void ibmcam_model2_Packet2(struct uvd *uvd)
1283{
1284 ibmcam_veio(uvd, 0, 0x00ff, 0x012d);
1285 ibmcam_veio(uvd, 0, 0xfea3, 0x0124);
1286}
1287
1288static void ibmcam_model2_Packet1(struct uvd *uvd, unsigned short v1, unsigned short v2)
1289{
1290 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
1291 ibmcam_veio(uvd, 0, 0x00ff, 0x012e);
1292 ibmcam_veio(uvd, 0, v1, 0x012f);
1293 ibmcam_veio(uvd, 0, 0x00ff, 0x0130);
1294 ibmcam_veio(uvd, 0, 0xc719, 0x0124);
1295 ibmcam_veio(uvd, 0, v2, 0x0127);
1296
1297 ibmcam_model2_Packet2(uvd);
1298}
1299
1300/*
1301 * ibmcam_model3_Packet1()
1302 *
1303 * 00_0078_012d
1304 * 00_0097_012f
1305 * 00_d141_0124
1306 * 00_0096_0127
1307 * 00_fea8_0124
1308*/
1309static void ibmcam_model3_Packet1(struct uvd *uvd, unsigned short v1, unsigned short v2)
1310{
1311 ibmcam_veio(uvd, 0, 0x0078, 0x012d);
1312 ibmcam_veio(uvd, 0, v1, 0x012f);
1313 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
1314 ibmcam_veio(uvd, 0, v2, 0x0127);
1315 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
1316}
1317
1318static void ibmcam_model4_BrightnessPacket(struct uvd *uvd, int i)
1319{
1320 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
1321 ibmcam_veio(uvd, 0, 0x0026, 0x012f);
1322 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
1323 ibmcam_veio(uvd, 0, i, 0x0127);
1324 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
1325 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
1326 ibmcam_veio(uvd, 0, 0x0038, 0x012d);
1327 ibmcam_veio(uvd, 0, 0x0004, 0x012f);
1328 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
1329 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
1330}
1331
1332/*
1333 * ibmcam_adjust_contrast()
1334 *
1335 * The contrast value changes from 0 (high contrast) to 15 (low contrast).
1336 * This is in reverse to usual order of things (such as TV controls), so
1337 * we reverse it again here.
1338 *
1339 * TODO: we probably don't need to send the setup 5 times...
1340 *
1341 * History:
1342 * 1/2/00 Created.
1343 */
1344static void ibmcam_adjust_contrast(struct uvd *uvd)
1345{
1346 unsigned char a_contrast = uvd->vpic.contrast >> 12;
1347 unsigned char new_contrast;
1348
1349 if (a_contrast >= 16)
1350 a_contrast = 15;
1351 new_contrast = 15 - a_contrast;
1352 if (new_contrast == uvd->vpic_old.contrast)
1353 return;
1354 uvd->vpic_old.contrast = new_contrast;
1355 switch (IBMCAM_T(uvd)->camera_model) {
1356 case IBMCAM_MODEL_1:
1357 {
1358 const int ntries = 5;
1359 int i;
1360 for (i=0; i < ntries; i++) {
1361 ibmcam_Packet_Format1(uvd, contrast_14, new_contrast);
1362 ibmcam_send_FF_04_02(uvd);
1363 }
1364 break;
1365 }
1366 case IBMCAM_MODEL_2:
1367 case IBMCAM_MODEL_4:
1368 /* Models 2, 4 do not have this control; implemented in software. */
1369 break;
1370 case IBMCAM_MODEL_3:
1371 { /* Preset hardware values */
1372 static const struct {
1373 unsigned short cv1;
1374 unsigned short cv2;
1375 unsigned short cv3;
1376 } cv[7] = {
1377 { 0x05, 0x05, 0x0f }, /* Minimum */
1378 { 0x04, 0x04, 0x16 },
1379 { 0x02, 0x03, 0x16 },
1380 { 0x02, 0x08, 0x16 },
1381 { 0x01, 0x0c, 0x16 },
1382 { 0x01, 0x0e, 0x16 },
1383 { 0x01, 0x10, 0x16 } /* Maximum */
1384 };
1385 int i = a_contrast / 2;
1386 RESTRICT_TO_RANGE(i, 0, 6);
1387 ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */
1388 ibmcam_model3_Packet1(uvd, 0x0067, cv[i].cv1);
1389 ibmcam_model3_Packet1(uvd, 0x005b, cv[i].cv2);
1390 ibmcam_model3_Packet1(uvd, 0x005c, cv[i].cv3);
1391 ibmcam_veio(uvd, 0, 0x0001, 0x0114);
1392 ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */
1393 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
1394 break;
1395 }
1396 default:
1397 break;
1398 }
1399}
1400
1401/*
1402 * ibmcam_change_lighting_conditions()
1403 *
1404 * Camera model 1:
1405 * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low.
1406 *
1407 * Camera model 2:
1408 * We have 16 levels of lighting, 0 for bright light and up to 15 for
1409 * low light. But values above 5 or so are useless because camera is
1410 * not really capable to produce anything worth viewing at such light.
1411 * This setting may be altered only in certain camera state.
1412 *
1413 * Low lighting forces slower FPS. Lighting is set as a module parameter.
1414 *
1415 * History:
1416 * 1/5/00 Created.
1417 * 2/20/00 Added support for Model 2 cameras.
1418 */
1419static void ibmcam_change_lighting_conditions(struct uvd *uvd)
1420{
1421 static const char proc[] = "ibmcam_change_lighting_conditions";
1422
1423 if (debug > 0)
1424 info("%s: Set lighting to %hu.", proc, lighting);
1425
1426 switch (IBMCAM_T(uvd)->camera_model) {
1427 case IBMCAM_MODEL_1:
1428 {
1429 const int ntries = 5;
1430 int i;
1431 for (i=0; i < ntries; i++)
1432 ibmcam_Packet_Format1(uvd, light_27, (unsigned short) lighting);
1433 break;
1434 }
1435 case IBMCAM_MODEL_2:
1436#if 0
1437 /*
1438 * This command apparently requires camera to be stopped. My
1439 * experiments showed that it -is- possible to alter the lighting
1440 * conditions setting "on the fly", but why bother? This setting does
1441 * not work reliably in all cases, so I decided simply to leave the
1442 * setting where Xirlink put it - in the camera setup phase. This code
1443 * is commented out because it does not work at -any- moment, so its
1444 * presence makes no sense. You may use it for experiments.
1445 */
1446 ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop camera */
1447 ibmcam_model2_Packet1(uvd, mod2_sensitivity, lighting);
1448 ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Start camera */
1449#endif
1450 break;
1451 case IBMCAM_MODEL_3:
1452 case IBMCAM_MODEL_4:
1453 default:
1454 break;
1455 }
1456}
1457
1458/*
1459 * ibmcam_set_sharpness()
1460 *
1461 * Cameras model 1 have internal smoothing feature. It is controlled by value in
1462 * range [0..6], where 0 is most smooth and 6 is most sharp (raw image, I guess).
1463 * Recommended value is 4. Cameras model 2 do not have this feature at all.
1464 */
1465static void ibmcam_set_sharpness(struct uvd *uvd)
1466{
1467 static const char proc[] = "ibmcam_set_sharpness";
1468
1469 switch (IBMCAM_T(uvd)->camera_model) {
1470 case IBMCAM_MODEL_1:
1471 {
1472 static const unsigned short sa[] = { 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a };
1473 unsigned short i, sv;
1474
1475 RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX);
1476 if (debug > 0)
1477 info("%s: Set sharpness to %hu.", proc, sharpness);
1478
1479 sv = sa[sharpness - SHARPNESS_MIN];
1480 for (i=0; i < 2; i++) {
1481 ibmcam_send_x_01_00_05 (uvd, unknown_88);
1482 ibmcam_send_x_00_05 (uvd, sharp_13);
1483 ibmcam_send_x_00_05_02 (uvd, sv);
1484 }
1485 break;
1486 }
1487 case IBMCAM_MODEL_2:
1488 case IBMCAM_MODEL_4:
1489 /* Models 2, 4 do not have this control */
1490 break;
1491 case IBMCAM_MODEL_3:
1492 { /*
1493 * "Use a table of magic numbers.
1494 * This setting doesn't really change much.
1495 * But that's how Windows does it."
1496 */
1497 static const struct {
1498 unsigned short sv1;
1499 unsigned short sv2;
1500 unsigned short sv3;
1501 unsigned short sv4;
1502 } sv[7] = {
1503 { 0x00, 0x00, 0x05, 0x14 }, /* Smoothest */
1504 { 0x01, 0x04, 0x05, 0x14 },
1505 { 0x02, 0x04, 0x05, 0x14 },
1506 { 0x03, 0x04, 0x05, 0x14 },
1507 { 0x03, 0x05, 0x05, 0x14 },
1508 { 0x03, 0x06, 0x05, 0x14 },
1509 { 0x03, 0x07, 0x05, 0x14 } /* Sharpest */
1510 };
1511 RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX);
1512 RESTRICT_TO_RANGE(sharpness, 0, 6);
1513 ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */
1514 ibmcam_model3_Packet1(uvd, 0x0060, sv[sharpness].sv1);
1515 ibmcam_model3_Packet1(uvd, 0x0061, sv[sharpness].sv2);
1516 ibmcam_model3_Packet1(uvd, 0x0062, sv[sharpness].sv3);
1517 ibmcam_model3_Packet1(uvd, 0x0063, sv[sharpness].sv4);
1518 ibmcam_veio(uvd, 0, 0x0001, 0x0114);
1519 ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */
1520 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
1521 ibmcam_veio(uvd, 0, 0x0001, 0x0113);
1522 break;
1523 }
1524 default:
1525 break;
1526 }
1527}
1528
1529/*
1530 * ibmcam_set_brightness()
1531 *
1532 * This procedure changes brightness of the picture.
1533 */
1534static void ibmcam_set_brightness(struct uvd *uvd)
1535{
1536 static const char proc[] = "ibmcam_set_brightness";
1537 static const unsigned short n = 1;
1538
1539 if (debug > 0)
1540 info("%s: Set brightness to %hu.", proc, uvd->vpic.brightness);
1541
1542 switch (IBMCAM_T(uvd)->camera_model) {
1543 case IBMCAM_MODEL_1:
1544 {
1545 unsigned short i, j, bv[3];
1546 bv[0] = bv[1] = bv[2] = uvd->vpic.brightness >> 10;
1547 if (bv[0] == (uvd->vpic_old.brightness >> 10))
1548 return;
1549 uvd->vpic_old.brightness = bv[0];
1550 for (j=0; j < 3; j++)
1551 for (i=0; i < n; i++)
1552 ibmcam_Packet_Format1(uvd, bright_3x[j], bv[j]);
1553 break;
1554 }
1555 case IBMCAM_MODEL_2:
1556 {
1557 unsigned short i, j;
1558 i = uvd->vpic.brightness >> 12; /* 0 .. 15 */
1559 j = 0x60 + i * ((0xee - 0x60) / 16); /* 0x60 .. 0xee or so */
1560 if (uvd->vpic_old.brightness == j)
1561 break;
1562 uvd->vpic_old.brightness = j;
1563 ibmcam_model2_Packet1(uvd, mod2_brightness, j);
1564 break;
1565 }
1566 case IBMCAM_MODEL_3:
1567 {
1568 /* Model 3: Brightness range 'i' in [0x0C..0x3F] */
1569 unsigned short i =
1570 0x0C + (uvd->vpic.brightness / (0xFFFF / (0x3F - 0x0C + 1)));
1571 RESTRICT_TO_RANGE(i, 0x0C, 0x3F);
1572 if (uvd->vpic_old.brightness == i)
1573 break;
1574 uvd->vpic_old.brightness = i;
1575 ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */
1576 ibmcam_model3_Packet1(uvd, 0x0036, i);
1577 ibmcam_veio(uvd, 0, 0x0001, 0x0114);
1578 ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */
1579 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
1580 ibmcam_veio(uvd, 0, 0x0001, 0x0113);
1581 break;
1582 }
1583 case IBMCAM_MODEL_4:
1584 {
1585 /* Model 4: Brightness range 'i' in [0x04..0xb4] */
1586 unsigned short i = 0x04 + (uvd->vpic.brightness / (0xFFFF / (0xb4 - 0x04 + 1)));
1587 RESTRICT_TO_RANGE(i, 0x04, 0xb4);
1588 if (uvd->vpic_old.brightness == i)
1589 break;
1590 uvd->vpic_old.brightness = i;
1591 ibmcam_model4_BrightnessPacket(uvd, i);
1592 break;
1593 }
1594 default:
1595 break;
1596 }
1597}
1598
1599static void ibmcam_set_hue(struct uvd *uvd)
1600{
1601 switch (IBMCAM_T(uvd)->camera_model) {
1602 case IBMCAM_MODEL_2:
1603 {
1604 unsigned short hue = uvd->vpic.hue >> 9; /* 0 .. 7F */
1605 if (uvd->vpic_old.hue == hue)
1606 return;
1607 uvd->vpic_old.hue = hue;
1608 ibmcam_model2_Packet1(uvd, mod2_hue, hue);
1609 /* ibmcam_model2_Packet1(uvd, mod2_saturation, sat); */
1610 break;
1611 }
1612 case IBMCAM_MODEL_3:
1613 {
1614#if 0 /* This seems not to work. No problem, will fix programmatically */
1615 unsigned short hue = 0x05 + (uvd->vpic.hue / (0xFFFF / (0x37 - 0x05 + 1)));
1616 RESTRICT_TO_RANGE(hue, 0x05, 0x37);
1617 if (uvd->vpic_old.hue == hue)
1618 return;
1619 uvd->vpic_old.hue = hue;
1620 ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */
1621 ibmcam_model3_Packet1(uvd, 0x007e, hue);
1622 ibmcam_veio(uvd, 0, 0x0001, 0x0114);
1623 ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */
1624 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
1625 ibmcam_veio(uvd, 0, 0x0001, 0x0113);
1626#endif
1627 break;
1628 }
1629 case IBMCAM_MODEL_4:
1630 {
1631 unsigned short r_gain, g_gain, b_gain, hue;
1632
1633 /*
1634 * I am not sure r/g/b_gain variables exactly control gain
1635 * of those channels. Most likely they subtly change some
1636 * very internal image processing settings in the camera.
1637 * In any case, here is what they do, and feel free to tweak:
1638 *
1639 * r_gain: seriously affects red gain
1640 * g_gain: seriously affects green gain
1641 * b_gain: seriously affects blue gain
1642 * hue: changes average color from violet (0) to red (0xFF)
1643 *
1644 * These settings are preset for a decent white balance in
1645 * 320x240, 352x288 modes. Low-res modes exhibit higher contrast
1646 * and therefore may need different values here.
1647 */
1648 hue = 20 + (uvd->vpic.hue >> 9);
1649 switch (uvd->videosize) {
1650 case VIDEOSIZE_128x96:
1651 r_gain = 90;
1652 g_gain = 166;
1653 b_gain = 175;
1654 break;
1655 case VIDEOSIZE_160x120:
1656 r_gain = 70;
1657 g_gain = 166;
1658 b_gain = 185;
1659 break;
1660 case VIDEOSIZE_176x144:
1661 r_gain = 160;
1662 g_gain = 175;
1663 b_gain = 185;
1664 break;
1665 default:
1666 r_gain = 120;
1667 g_gain = 166;
1668 b_gain = 175;
1669 break;
1670 }
1671 RESTRICT_TO_RANGE(hue, 1, 0x7f);
1672
1673 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
1674 ibmcam_veio(uvd, 0, 0x001e, 0x012f);
1675 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
1676 ibmcam_veio(uvd, 0, g_gain, 0x0127); /* Green gain */
1677 ibmcam_veio(uvd, 0, r_gain, 0x012e); /* Red gain */
1678 ibmcam_veio(uvd, 0, b_gain, 0x0130); /* Blue gain */
1679 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
1680 ibmcam_veio(uvd, 0, hue, 0x012d); /* Hue */
1681 ibmcam_veio(uvd, 0, 0xf545, 0x0124);
1682 break;
1683 }
1684 default:
1685 break;
1686 }
1687}
1688
1689/*
1690 * ibmcam_adjust_picture()
1691 *
1692 * This procedure gets called from V4L interface to update picture settings.
1693 * Here we change brightness and contrast.
1694 */
1695static void ibmcam_adjust_picture(struct uvd *uvd)
1696{
1697 ibmcam_adjust_contrast(uvd);
1698 ibmcam_set_brightness(uvd);
1699 ibmcam_set_hue(uvd);
1700}
1701
1702static int ibmcam_model1_setup(struct uvd *uvd)
1703{
1704 const int ntries = 5;
1705 int i;
1706
1707 ibmcam_veio(uvd, 1, 0x00, 0x0128);
1708 ibmcam_veio(uvd, 1, 0x00, 0x0100);
1709 ibmcam_veio(uvd, 0, 0x01, 0x0100); /* LED On */
1710 ibmcam_veio(uvd, 1, 0x00, 0x0100);
1711 ibmcam_veio(uvd, 0, 0x81, 0x0100); /* LED Off */
1712 ibmcam_veio(uvd, 1, 0x00, 0x0100);
1713 ibmcam_veio(uvd, 0, 0x01, 0x0100); /* LED On */
1714 ibmcam_veio(uvd, 0, 0x01, 0x0108);
1715
1716 ibmcam_veio(uvd, 0, 0x03, 0x0112);
1717 ibmcam_veio(uvd, 1, 0x00, 0x0115);
1718 ibmcam_veio(uvd, 0, 0x06, 0x0115);
1719 ibmcam_veio(uvd, 1, 0x00, 0x0116);
1720 ibmcam_veio(uvd, 0, 0x44, 0x0116);
1721 ibmcam_veio(uvd, 1, 0x00, 0x0116);
1722 ibmcam_veio(uvd, 0, 0x40, 0x0116);
1723 ibmcam_veio(uvd, 1, 0x00, 0x0115);
1724 ibmcam_veio(uvd, 0, 0x0e, 0x0115);
1725 ibmcam_veio(uvd, 0, 0x19, 0x012c);
1726
1727 ibmcam_Packet_Format1(uvd, 0x00, 0x1e);
1728 ibmcam_Packet_Format1(uvd, 0x39, 0x0d);
1729 ibmcam_Packet_Format1(uvd, 0x39, 0x09);
1730 ibmcam_Packet_Format1(uvd, 0x3b, 0x00);
1731 ibmcam_Packet_Format1(uvd, 0x28, 0x22);
1732 ibmcam_Packet_Format1(uvd, light_27, 0);
1733 ibmcam_Packet_Format1(uvd, 0x2b, 0x1f);
1734 ibmcam_Packet_Format1(uvd, 0x39, 0x08);
1735
1736 for (i=0; i < ntries; i++)
1737 ibmcam_Packet_Format1(uvd, 0x2c, 0x00);
1738
1739 for (i=0; i < ntries; i++)
1740 ibmcam_Packet_Format1(uvd, 0x30, 0x14);
1741
1742 ibmcam_PacketFormat2(uvd, 0x39, 0x02);
1743 ibmcam_PacketFormat2(uvd, 0x01, 0xe1);
1744 ibmcam_PacketFormat2(uvd, 0x02, 0xcd);
1745 ibmcam_PacketFormat2(uvd, 0x03, 0xcd);
1746 ibmcam_PacketFormat2(uvd, 0x04, 0xfa);
1747 ibmcam_PacketFormat2(uvd, 0x3f, 0xff);
1748 ibmcam_PacketFormat2(uvd, 0x39, 0x00);
1749
1750 ibmcam_PacketFormat2(uvd, 0x39, 0x02);
1751 ibmcam_PacketFormat2(uvd, 0x0a, 0x37);
1752 ibmcam_PacketFormat2(uvd, 0x0b, 0xb8);
1753 ibmcam_PacketFormat2(uvd, 0x0c, 0xf3);
1754 ibmcam_PacketFormat2(uvd, 0x0d, 0xe3);
1755 ibmcam_PacketFormat2(uvd, 0x0e, 0x0d);
1756 ibmcam_PacketFormat2(uvd, 0x0f, 0xf2);
1757 ibmcam_PacketFormat2(uvd, 0x10, 0xd5);
1758 ibmcam_PacketFormat2(uvd, 0x11, 0xba);
1759 ibmcam_PacketFormat2(uvd, 0x12, 0x53);
1760 ibmcam_PacketFormat2(uvd, 0x3f, 0xff);
1761 ibmcam_PacketFormat2(uvd, 0x39, 0x00);
1762
1763 ibmcam_PacketFormat2(uvd, 0x39, 0x02);
1764 ibmcam_PacketFormat2(uvd, 0x16, 0x00);
1765 ibmcam_PacketFormat2(uvd, 0x17, 0x28);
1766 ibmcam_PacketFormat2(uvd, 0x18, 0x7d);
1767 ibmcam_PacketFormat2(uvd, 0x19, 0xbe);
1768 ibmcam_PacketFormat2(uvd, 0x3f, 0xff);
1769 ibmcam_PacketFormat2(uvd, 0x39, 0x00);
1770
1771 for (i=0; i < ntries; i++)
1772 ibmcam_Packet_Format1(uvd, 0x00, 0x18);
1773 for (i=0; i < ntries; i++)
1774 ibmcam_Packet_Format1(uvd, 0x13, 0x18);
1775 for (i=0; i < ntries; i++)
1776 ibmcam_Packet_Format1(uvd, 0x14, 0x06);
1777
1778 /* This is default brightness */
1779 for (i=0; i < ntries; i++)
1780 ibmcam_Packet_Format1(uvd, 0x31, 0x37);
1781 for (i=0; i < ntries; i++)
1782 ibmcam_Packet_Format1(uvd, 0x32, 0x46);
1783 for (i=0; i < ntries; i++)
1784 ibmcam_Packet_Format1(uvd, 0x33, 0x55);
1785
1786 ibmcam_Packet_Format1(uvd, 0x2e, 0x04);
1787 for (i=0; i < ntries; i++)
1788 ibmcam_Packet_Format1(uvd, 0x2d, 0x04);
1789 for (i=0; i < ntries; i++)
1790 ibmcam_Packet_Format1(uvd, 0x29, 0x80);
1791 ibmcam_Packet_Format1(uvd, 0x2c, 0x01);
1792 ibmcam_Packet_Format1(uvd, 0x30, 0x17);
1793 ibmcam_Packet_Format1(uvd, 0x39, 0x08);
1794 for (i=0; i < ntries; i++)
1795 ibmcam_Packet_Format1(uvd, 0x34, 0x00);
1796
1797 ibmcam_veio(uvd, 0, 0x00, 0x0101);
1798 ibmcam_veio(uvd, 0, 0x00, 0x010a);
1799
1800 switch (uvd->videosize) {
1801 case VIDEOSIZE_128x96:
1802 ibmcam_veio(uvd, 0, 0x80, 0x0103);
1803 ibmcam_veio(uvd, 0, 0x60, 0x0105);
1804 ibmcam_veio(uvd, 0, 0x0c, 0x010b);
1805 ibmcam_veio(uvd, 0, 0x04, 0x011b); /* Same everywhere */
1806 ibmcam_veio(uvd, 0, 0x0b, 0x011d);
1807 ibmcam_veio(uvd, 0, 0x00, 0x011e); /* Same everywhere */
1808 ibmcam_veio(uvd, 0, 0x00, 0x0129);
1809 break;
1810 case VIDEOSIZE_176x144:
1811 ibmcam_veio(uvd, 0, 0xb0, 0x0103);
1812 ibmcam_veio(uvd, 0, 0x8f, 0x0105);
1813 ibmcam_veio(uvd, 0, 0x06, 0x010b);
1814 ibmcam_veio(uvd, 0, 0x04, 0x011b); /* Same everywhere */
1815 ibmcam_veio(uvd, 0, 0x0d, 0x011d);
1816 ibmcam_veio(uvd, 0, 0x00, 0x011e); /* Same everywhere */
1817 ibmcam_veio(uvd, 0, 0x03, 0x0129);
1818 break;
1819 case VIDEOSIZE_352x288:
1820 ibmcam_veio(uvd, 0, 0xb0, 0x0103);
1821 ibmcam_veio(uvd, 0, 0x90, 0x0105);
1822 ibmcam_veio(uvd, 0, 0x02, 0x010b);
1823 ibmcam_veio(uvd, 0, 0x04, 0x011b); /* Same everywhere */
1824 ibmcam_veio(uvd, 0, 0x05, 0x011d);
1825 ibmcam_veio(uvd, 0, 0x00, 0x011e); /* Same everywhere */
1826 ibmcam_veio(uvd, 0, 0x00, 0x0129);
1827 break;
1828 }
1829
1830 ibmcam_veio(uvd, 0, 0xff, 0x012b);
1831
1832 /* This is another brightness - don't know why */
1833 for (i=0; i < ntries; i++)
1834 ibmcam_Packet_Format1(uvd, 0x31, 0xc3);
1835 for (i=0; i < ntries; i++)
1836 ibmcam_Packet_Format1(uvd, 0x32, 0xd2);
1837 for (i=0; i < ntries; i++)
1838 ibmcam_Packet_Format1(uvd, 0x33, 0xe1);
1839
1840 /* Default contrast */
1841 for (i=0; i < ntries; i++)
1842 ibmcam_Packet_Format1(uvd, contrast_14, 0x0a);
1843
1844 /* Default sharpness */
1845 for (i=0; i < 2; i++)
1846 ibmcam_PacketFormat2(uvd, sharp_13, 0x1a); /* Level 4 FIXME */
1847
1848 /* Default lighting conditions */
1849 ibmcam_Packet_Format1(uvd, light_27, lighting); /* 0=Bright 2=Low */
1850
1851 /* Assorted init */
1852
1853 switch (uvd->videosize) {
1854 case VIDEOSIZE_128x96:
1855 ibmcam_Packet_Format1(uvd, 0x2b, 0x1e);
1856 ibmcam_veio(uvd, 0, 0xc9, 0x0119); /* Same everywhere */
1857 ibmcam_veio(uvd, 0, 0x80, 0x0109); /* Same everywhere */
1858 ibmcam_veio(uvd, 0, 0x36, 0x0102);
1859 ibmcam_veio(uvd, 0, 0x1a, 0x0104);
1860 ibmcam_veio(uvd, 0, 0x04, 0x011a); /* Same everywhere */
1861 ibmcam_veio(uvd, 0, 0x2b, 0x011c);
1862 ibmcam_veio(uvd, 0, 0x23, 0x012a); /* Same everywhere */
1863#if 0
1864 ibmcam_veio(uvd, 0, 0x00, 0x0106);
1865 ibmcam_veio(uvd, 0, 0x38, 0x0107);
1866#else
1867 ibmcam_veio(uvd, 0, 0x02, 0x0106);
1868 ibmcam_veio(uvd, 0, 0x2a, 0x0107);
1869#endif
1870 break;
1871 case VIDEOSIZE_176x144:
1872 ibmcam_Packet_Format1(uvd, 0x2b, 0x1e);
1873 ibmcam_veio(uvd, 0, 0xc9, 0x0119); /* Same everywhere */
1874 ibmcam_veio(uvd, 0, 0x80, 0x0109); /* Same everywhere */
1875 ibmcam_veio(uvd, 0, 0x04, 0x0102);
1876 ibmcam_veio(uvd, 0, 0x02, 0x0104);
1877 ibmcam_veio(uvd, 0, 0x04, 0x011a); /* Same everywhere */
1878 ibmcam_veio(uvd, 0, 0x2b, 0x011c);
1879 ibmcam_veio(uvd, 0, 0x23, 0x012a); /* Same everywhere */
1880 ibmcam_veio(uvd, 0, 0x01, 0x0106);
1881 ibmcam_veio(uvd, 0, 0xca, 0x0107);
1882 break;
1883 case VIDEOSIZE_352x288:
1884 ibmcam_Packet_Format1(uvd, 0x2b, 0x1f);
1885 ibmcam_veio(uvd, 0, 0xc9, 0x0119); /* Same everywhere */
1886 ibmcam_veio(uvd, 0, 0x80, 0x0109); /* Same everywhere */
1887 ibmcam_veio(uvd, 0, 0x08, 0x0102);
1888 ibmcam_veio(uvd, 0, 0x01, 0x0104);
1889 ibmcam_veio(uvd, 0, 0x04, 0x011a); /* Same everywhere */
1890 ibmcam_veio(uvd, 0, 0x2f, 0x011c);
1891 ibmcam_veio(uvd, 0, 0x23, 0x012a); /* Same everywhere */
1892 ibmcam_veio(uvd, 0, 0x03, 0x0106);
1893 ibmcam_veio(uvd, 0, 0xf6, 0x0107);
1894 break;
1895 }
1896 return (CAMERA_IS_OPERATIONAL(uvd) ? 0 : -EFAULT);
1897}
1898
1899static int ibmcam_model2_setup(struct uvd *uvd)
1900{
1901 ibmcam_veio(uvd, 0, 0x0000, 0x0100); /* LED on */
1902 ibmcam_veio(uvd, 1, 0x0000, 0x0116);
1903 ibmcam_veio(uvd, 0, 0x0060, 0x0116);
1904 ibmcam_veio(uvd, 0, 0x0002, 0x0112);
1905 ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
1906 ibmcam_veio(uvd, 0, 0x0008, 0x012b);
1907 ibmcam_veio(uvd, 0, 0x0000, 0x0108);
1908 ibmcam_veio(uvd, 0, 0x0001, 0x0133);
1909 ibmcam_veio(uvd, 0, 0x0001, 0x0102);
1910 switch (uvd->videosize) {
1911 case VIDEOSIZE_176x144:
1912 ibmcam_veio(uvd, 0, 0x002c, 0x0103); /* All except 320x240 */
1913 ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */
1914 ibmcam_veio(uvd, 0, 0x0024, 0x0105); /* 176x144, 352x288 */
1915 ibmcam_veio(uvd, 0, 0x00b9, 0x010a); /* Unique to this mode */
1916 ibmcam_veio(uvd, 0, 0x0038, 0x0119); /* Unique to this mode */
1917 ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */
1918 ibmcam_veio(uvd, 0, 0x0090, 0x0107); /* Unique to every mode*/
1919 break;
1920 case VIDEOSIZE_320x240:
1921 ibmcam_veio(uvd, 0, 0x0028, 0x0103); /* Unique to this mode */
1922 ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */
1923 ibmcam_veio(uvd, 0, 0x001e, 0x0105); /* 320x240, 352x240 */
1924 ibmcam_veio(uvd, 0, 0x0039, 0x010a); /* All except 176x144 */
1925 ibmcam_veio(uvd, 0, 0x0070, 0x0119); /* All except 176x144 */
1926 ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */
1927 ibmcam_veio(uvd, 0, 0x0098, 0x0107); /* Unique to every mode*/
1928 break;
1929 case VIDEOSIZE_352x240:
1930 ibmcam_veio(uvd, 0, 0x002c, 0x0103); /* All except 320x240 */
1931 ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */
1932 ibmcam_veio(uvd, 0, 0x001e, 0x0105); /* 320x240, 352x240 */
1933 ibmcam_veio(uvd, 0, 0x0039, 0x010a); /* All except 176x144 */
1934 ibmcam_veio(uvd, 0, 0x0070, 0x0119); /* All except 176x144 */
1935 ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */
1936 ibmcam_veio(uvd, 0, 0x00da, 0x0107); /* Unique to every mode*/
1937 break;
1938 case VIDEOSIZE_352x288:
1939 ibmcam_veio(uvd, 0, 0x002c, 0x0103); /* All except 320x240 */
1940 ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */
1941 ibmcam_veio(uvd, 0, 0x0024, 0x0105); /* 176x144, 352x288 */
1942 ibmcam_veio(uvd, 0, 0x0039, 0x010a); /* All except 176x144 */
1943 ibmcam_veio(uvd, 0, 0x0070, 0x0119); /* All except 176x144 */
1944 ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */
1945 ibmcam_veio(uvd, 0, 0x00fe, 0x0107); /* Unique to every mode*/
1946 break;
1947 }
1948 return (CAMERA_IS_OPERATIONAL(uvd) ? 0 : -EFAULT);
1949}
1950
1951/*
1952 * ibmcam_model1_setup_after_video_if()
1953 *
1954 * This code adds finishing touches to the video data interface.
1955 * Here we configure the frame rate and turn on the LED.
1956 */
1957static void ibmcam_model1_setup_after_video_if(struct uvd *uvd)
1958{
1959 unsigned short internal_frame_rate;
1960
1961 RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX);
1962 internal_frame_rate = FRAMERATE_MAX - framerate; /* 0=Fast 6=Slow */
1963 ibmcam_veio(uvd, 0, 0x01, 0x0100); /* LED On */
1964 ibmcam_veio(uvd, 0, internal_frame_rate, 0x0111);
1965 ibmcam_veio(uvd, 0, 0x01, 0x0114);
1966 ibmcam_veio(uvd, 0, 0xc0, 0x010c);
1967}
1968
1969static void ibmcam_model2_setup_after_video_if(struct uvd *uvd)
1970{
1971 unsigned short setup_model2_rg2, setup_model2_sat, setup_model2_yb;
1972
1973 ibmcam_veio(uvd, 0, 0x0000, 0x0100); /* LED on */
1974
1975 switch (uvd->videosize) {
1976 case VIDEOSIZE_176x144:
1977 ibmcam_veio(uvd, 0, 0x0050, 0x0111);
1978 ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
1979 break;
1980 case VIDEOSIZE_320x240:
1981 case VIDEOSIZE_352x240:
1982 case VIDEOSIZE_352x288:
1983 ibmcam_veio(uvd, 0, 0x0040, 0x0111);
1984 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
1985 break;
1986 }
1987 ibmcam_veio(uvd, 0, 0x009b, 0x010f);
1988 ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
1989
1990 /*
1991 * Hardware settings, may affect CMOS sensor; not user controls!
1992 * -------------------------------------------------------------
1993 * 0x0004: no effect
1994 * 0x0006: hardware effect
1995 * 0x0008: no effect
1996 * 0x000a: stops video stream, probably important h/w setting
1997 * 0x000c: changes color in hardware manner (not user setting)
1998 * 0x0012: changes number of colors (does not affect speed)
1999 * 0x002a: no effect
2000 * 0x002c: hardware setting (related to scan lines)
2001 * 0x002e: stops video stream, probably important h/w setting
2002 */
2003 ibmcam_model2_Packet1(uvd, 0x000a, 0x005c);
2004 ibmcam_model2_Packet1(uvd, 0x0004, 0x0000);
2005 ibmcam_model2_Packet1(uvd, 0x0006, 0x00fb);
2006 ibmcam_model2_Packet1(uvd, 0x0008, 0x0000);
2007 ibmcam_model2_Packet1(uvd, 0x000c, 0x0009);
2008 ibmcam_model2_Packet1(uvd, 0x0012, 0x000a);
2009 ibmcam_model2_Packet1(uvd, 0x002a, 0x0000);
2010 ibmcam_model2_Packet1(uvd, 0x002c, 0x0000);
2011 ibmcam_model2_Packet1(uvd, 0x002e, 0x0008);
2012
2013 /*
2014 * Function 0x0030 pops up all over the place. Apparently
2015 * it is a hardware control register, with every bit assigned to
2016 * do something.
2017 */
2018 ibmcam_model2_Packet1(uvd, 0x0030, 0x0000);
2019
2020 /*
2021 * Magic control of CMOS sensor. Only lower values like
2022 * 0-3 work, and picture shifts left or right. Don't change.
2023 */
2024 switch (uvd->videosize) {
2025 case VIDEOSIZE_176x144:
2026 ibmcam_model2_Packet1(uvd, 0x0014, 0x0002);
2027 ibmcam_model2_Packet1(uvd, 0x0016, 0x0002); /* Horizontal shift */
2028 ibmcam_model2_Packet1(uvd, 0x0018, 0x004a); /* Another hardware setting */
2029 break;
2030 case VIDEOSIZE_320x240:
2031 ibmcam_model2_Packet1(uvd, 0x0014, 0x0009);
2032 ibmcam_model2_Packet1(uvd, 0x0016, 0x0005); /* Horizontal shift */
2033 ibmcam_model2_Packet1(uvd, 0x0018, 0x0044); /* Another hardware setting */
2034 break;
2035 case VIDEOSIZE_352x240:
2036 /* This mode doesn't work as Windows programs it; changed to work */
2037 ibmcam_model2_Packet1(uvd, 0x0014, 0x0009); /* Windows sets this to 8 */
2038 ibmcam_model2_Packet1(uvd, 0x0016, 0x0003); /* Horizontal shift */
2039 ibmcam_model2_Packet1(uvd, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
2040 break;
2041 case VIDEOSIZE_352x288:
2042 ibmcam_model2_Packet1(uvd, 0x0014, 0x0003);
2043 ibmcam_model2_Packet1(uvd, 0x0016, 0x0002); /* Horizontal shift */
2044 ibmcam_model2_Packet1(uvd, 0x0018, 0x004a); /* Another hardware setting */
2045 break;
2046 }
2047
2048 ibmcam_model2_Packet1(uvd, mod2_brightness, 0x005a);
2049
2050 /*
2051 * We have our own frame rate setting varying from 0 (slowest) to 6 (fastest).
2052 * The camera model 2 allows frame rate in range [0..0x1F] where 0 is also the
2053 * slowest setting. However for all practical reasons high settings make no
2054 * sense because USB is not fast enough to support high FPS. Be aware that
2055 * the picture datastream will be severely disrupted if you ask for
2056 * frame rate faster than allowed for the video size - see below:
2057 *
2058 * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz):
2059 * -----------------------------------------------------------------
2060 * 176x144: [6..31]
2061 * 320x240: [8..31]
2062 * 352x240: [10..31]
2063 * 352x288: [16..31] I have to raise lower threshold for stability...
2064 *
2065 * As usual, slower FPS provides better sensitivity.
2066 */
2067 {
2068 short hw_fps=31, i_framerate;
2069
2070 RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX);
2071 i_framerate = FRAMERATE_MAX - framerate + FRAMERATE_MIN;
2072 switch (uvd->videosize) {
2073 case VIDEOSIZE_176x144:
2074 hw_fps = 6 + i_framerate*4;
2075 break;
2076 case VIDEOSIZE_320x240:
2077 hw_fps = 8 + i_framerate*3;
2078 break;
2079 case VIDEOSIZE_352x240:
2080 hw_fps = 10 + i_framerate*2;
2081 break;
2082 case VIDEOSIZE_352x288:
2083 hw_fps = 28 + i_framerate/2;
2084 break;
2085 }
2086 if (uvd->debug > 0)
2087 info("Framerate (hardware): %hd.", hw_fps);
2088 RESTRICT_TO_RANGE(hw_fps, 0, 31);
2089 ibmcam_model2_Packet1(uvd, mod2_set_framerate, hw_fps);
2090 }
2091
2092 /*
2093 * This setting does not visibly affect pictures; left it here
2094 * because it was present in Windows USB data stream. This function
2095 * does not allow arbitrary values and apparently is a bit mask, to
2096 * be activated only at appropriate time. Don't change it randomly!
2097 */
2098 switch (uvd->videosize) {
2099 case VIDEOSIZE_176x144:
2100 ibmcam_model2_Packet1(uvd, 0x0026, 0x00c2);
2101 break;
2102 case VIDEOSIZE_320x240:
2103 ibmcam_model2_Packet1(uvd, 0x0026, 0x0044);
2104 break;
2105 case VIDEOSIZE_352x240:
2106 ibmcam_model2_Packet1(uvd, 0x0026, 0x0046);
2107 break;
2108 case VIDEOSIZE_352x288:
2109 ibmcam_model2_Packet1(uvd, 0x0026, 0x0048);
2110 break;
2111 }
2112
2113 ibmcam_model2_Packet1(uvd, mod2_sensitivity, lighting);
2114
2115 if (init_model2_rg2 >= 0) {
2116 RESTRICT_TO_RANGE(init_model2_rg2, 0, 255);
2117 setup_model2_rg2 = init_model2_rg2;
2118 } else
2119 setup_model2_rg2 = 0x002f;
2120
2121 if (init_model2_sat >= 0) {
2122 RESTRICT_TO_RANGE(init_model2_sat, 0, 255);
2123 setup_model2_sat = init_model2_sat;
2124 } else
2125 setup_model2_sat = 0x0034;
2126
2127 if (init_model2_yb >= 0) {
2128 RESTRICT_TO_RANGE(init_model2_yb, 0, 255);
2129 setup_model2_yb = init_model2_yb;
2130 } else
2131 setup_model2_yb = 0x00a0;
2132
2133 ibmcam_model2_Packet1(uvd, mod2_color_balance_rg2, setup_model2_rg2);
2134 ibmcam_model2_Packet1(uvd, mod2_saturation, setup_model2_sat);
2135 ibmcam_model2_Packet1(uvd, mod2_color_balance_yb, setup_model2_yb);
2136 ibmcam_model2_Packet1(uvd, mod2_hue, uvd->vpic.hue >> 9); /* 0 .. 7F */;
2137
2138 /* Hardware control command */
2139 ibmcam_model2_Packet1(uvd, 0x0030, 0x0004);
2140
2141 ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go camera, go! */
2142 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
2143}
2144
2145static void ibmcam_model4_setup_after_video_if(struct uvd *uvd)
2146{
2147 switch (uvd->videosize) {
2148 case VIDEOSIZE_128x96:
2149 ibmcam_veio(uvd, 0, 0x0000, 0x0100);
2150 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
2151 ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
2152 ibmcam_veio(uvd, 0, 0x0080, 0x012b);
2153 ibmcam_veio(uvd, 0, 0x0000, 0x0108);
2154 ibmcam_veio(uvd, 0, 0x0001, 0x0133);
2155 ibmcam_veio(uvd, 0, 0x009b, 0x010f);
2156 ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
2157 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2158 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2159 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2160 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2161 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2162 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2163 ibmcam_veio(uvd, 0, 0x000a, 0x012f);
2164 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2165 ibmcam_veio(uvd, 0, 0x005c, 0x0127);
2166 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2167 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2168 ibmcam_veio(uvd, 0, 0x0004, 0x012f);
2169 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2170 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2171 ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
2172 ibmcam_veio(uvd, 0, 0x0000, 0x0130);
2173 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2174 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2175 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2176 ibmcam_veio(uvd, 0, 0x000c, 0x0127);
2177 ibmcam_veio(uvd, 0, 0x0009, 0x012e);
2178 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2179 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2180 ibmcam_veio(uvd, 0, 0x0012, 0x012f);
2181 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2182 ibmcam_veio(uvd, 0, 0x0008, 0x0127);
2183 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2184 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2185 ibmcam_veio(uvd, 0, 0x002a, 0x012d);
2186 ibmcam_veio(uvd, 0, 0x0000, 0x012f);
2187 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2188 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2189 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2190 ibmcam_veio(uvd, 0, 0x0034, 0x012f);
2191 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2192 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2193 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2194 ibmcam_veio(uvd, 0, 0x0070, 0x0119);
2195 ibmcam_veio(uvd, 0, 0x00d2, 0x0107);
2196 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2197 ibmcam_veio(uvd, 0, 0x005e, 0x0107);
2198 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2199 ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
2200 ibmcam_veio(uvd, 0, 0x0039, 0x010a);
2201 ibmcam_veio(uvd, 0, 0x0001, 0x0102);
2202 ibmcam_veio(uvd, 0, 0x0028, 0x0103);
2203 ibmcam_veio(uvd, 0, 0x0000, 0x0104);
2204 ibmcam_veio(uvd, 0, 0x001e, 0x0105);
2205 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2206 ibmcam_veio(uvd, 0, 0x0016, 0x012f);
2207 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2208 ibmcam_veio(uvd, 0, 0x000a, 0x0127);
2209 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2210 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2211 ibmcam_veio(uvd, 0, 0x0014, 0x012d);
2212 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2213 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2214 ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
2215 ibmcam_veio(uvd, 0, 0x001a, 0x0130);
2216 ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
2217 ibmcam_veio(uvd, 0, 0x005a, 0x012d);
2218 ibmcam_veio(uvd, 0, 0x9545, 0x0124);
2219 ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
2220 ibmcam_veio(uvd, 0, 0x0018, 0x012e);
2221 ibmcam_veio(uvd, 0, 0x0043, 0x0130);
2222 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2223 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2224 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2225 ibmcam_veio(uvd, 0, 0x001c, 0x0127);
2226 ibmcam_veio(uvd, 0, 0x00eb, 0x012e);
2227 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2228 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2229 ibmcam_veio(uvd, 0, 0x0032, 0x012f);
2230 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2231 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2232 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2233 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2234 ibmcam_veio(uvd, 0, 0x0036, 0x012d);
2235 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2236 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2237 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2238 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2239 ibmcam_veio(uvd, 0, 0x001e, 0x012f);
2240 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2241 ibmcam_veio(uvd, 0, 0x0017, 0x0127);
2242 ibmcam_veio(uvd, 0, 0x0013, 0x012e);
2243 ibmcam_veio(uvd, 0, 0x0031, 0x0130);
2244 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2245 ibmcam_veio(uvd, 0, 0x0017, 0x012d);
2246 ibmcam_veio(uvd, 0, 0x0078, 0x012f);
2247 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2248 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2249 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2250 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2251 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2252 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2253 ibmcam_veio(uvd, 0, 0x0004, 0x0127);
2254 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2255 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
2256 break;
2257 case VIDEOSIZE_160x120:
2258 ibmcam_veio(uvd, 0, 0x0000, 0x0100);
2259 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
2260 ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
2261 ibmcam_veio(uvd, 0, 0x0080, 0x012b);
2262 ibmcam_veio(uvd, 0, 0x0000, 0x0108);
2263 ibmcam_veio(uvd, 0, 0x0001, 0x0133);
2264 ibmcam_veio(uvd, 0, 0x009b, 0x010f);
2265 ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
2266 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2267 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2268 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2269 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2270 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2271 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2272 ibmcam_veio(uvd, 0, 0x000a, 0x012f);
2273 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2274 ibmcam_veio(uvd, 0, 0x005c, 0x0127);
2275 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2276 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2277 ibmcam_veio(uvd, 0, 0x0004, 0x012f);
2278 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2279 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2280 ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
2281 ibmcam_veio(uvd, 0, 0x0000, 0x0130);
2282 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2283 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2284 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2285 ibmcam_veio(uvd, 0, 0x000c, 0x0127);
2286 ibmcam_veio(uvd, 0, 0x0009, 0x012e);
2287 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2288 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2289 ibmcam_veio(uvd, 0, 0x0012, 0x012f);
2290 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2291 ibmcam_veio(uvd, 0, 0x0008, 0x0127);
2292 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2293 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2294 ibmcam_veio(uvd, 0, 0x002a, 0x012d);
2295 ibmcam_veio(uvd, 0, 0x0000, 0x012f);
2296 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2297 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2298 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2299 ibmcam_veio(uvd, 0, 0x0034, 0x012f);
2300 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2301 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2302 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2303 ibmcam_veio(uvd, 0, 0x0038, 0x0119);
2304 ibmcam_veio(uvd, 0, 0x00d8, 0x0107);
2305 ibmcam_veio(uvd, 0, 0x0002, 0x0106);
2306 ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
2307 ibmcam_veio(uvd, 0, 0x00b9, 0x010a);
2308 ibmcam_veio(uvd, 0, 0x0001, 0x0102);
2309 ibmcam_veio(uvd, 0, 0x0028, 0x0103);
2310 ibmcam_veio(uvd, 0, 0x0000, 0x0104);
2311 ibmcam_veio(uvd, 0, 0x001e, 0x0105);
2312 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2313 ibmcam_veio(uvd, 0, 0x0016, 0x012f);
2314 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2315 ibmcam_veio(uvd, 0, 0x000b, 0x0127);
2316 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2317 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2318 ibmcam_veio(uvd, 0, 0x0014, 0x012d);
2319 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2320 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2321 ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
2322 ibmcam_veio(uvd, 0, 0x001a, 0x0130);
2323 ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
2324 ibmcam_veio(uvd, 0, 0x005a, 0x012d);
2325 ibmcam_veio(uvd, 0, 0x9545, 0x0124);
2326 ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
2327 ibmcam_veio(uvd, 0, 0x0018, 0x012e);
2328 ibmcam_veio(uvd, 0, 0x0043, 0x0130);
2329 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2330 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2331 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2332 ibmcam_veio(uvd, 0, 0x001c, 0x0127);
2333 ibmcam_veio(uvd, 0, 0x00c7, 0x012e);
2334 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2335 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2336 ibmcam_veio(uvd, 0, 0x0032, 0x012f);
2337 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2338 ibmcam_veio(uvd, 0, 0x0025, 0x0127);
2339 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2340 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2341 ibmcam_veio(uvd, 0, 0x0036, 0x012d);
2342 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2343 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2344 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2345 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2346 ibmcam_veio(uvd, 0, 0x001e, 0x012f);
2347 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2348 ibmcam_veio(uvd, 0, 0x0048, 0x0127);
2349 ibmcam_veio(uvd, 0, 0x0035, 0x012e);
2350 ibmcam_veio(uvd, 0, 0x00d0, 0x0130);
2351 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2352 ibmcam_veio(uvd, 0, 0x0048, 0x012d);
2353 ibmcam_veio(uvd, 0, 0x0090, 0x012f);
2354 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2355 ibmcam_veio(uvd, 0, 0x0001, 0x0127);
2356 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2357 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2358 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2359 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2360 ibmcam_veio(uvd, 0, 0x0004, 0x0127);
2361 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2362 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
2363 break;
2364 case VIDEOSIZE_176x144:
2365 ibmcam_veio(uvd, 0, 0x0000, 0x0100);
2366 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
2367 ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
2368 ibmcam_veio(uvd, 0, 0x0080, 0x012b);
2369 ibmcam_veio(uvd, 0, 0x0000, 0x0108);
2370 ibmcam_veio(uvd, 0, 0x0001, 0x0133);
2371 ibmcam_veio(uvd, 0, 0x009b, 0x010f);
2372 ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
2373 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2374 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2375 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2376 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2377 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2378 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2379 ibmcam_veio(uvd, 0, 0x000a, 0x012f);
2380 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2381 ibmcam_veio(uvd, 0, 0x005c, 0x0127);
2382 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2383 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2384 ibmcam_veio(uvd, 0, 0x0004, 0x012f);
2385 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2386 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2387 ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
2388 ibmcam_veio(uvd, 0, 0x0000, 0x0130);
2389 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2390 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2391 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2392 ibmcam_veio(uvd, 0, 0x000c, 0x0127);
2393 ibmcam_veio(uvd, 0, 0x0009, 0x012e);
2394 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2395 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2396 ibmcam_veio(uvd, 0, 0x0012, 0x012f);
2397 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2398 ibmcam_veio(uvd, 0, 0x0008, 0x0127);
2399 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2400 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2401 ibmcam_veio(uvd, 0, 0x002a, 0x012d);
2402 ibmcam_veio(uvd, 0, 0x0000, 0x012f);
2403 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2404 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2405 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2406 ibmcam_veio(uvd, 0, 0x0034, 0x012f);
2407 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2408 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2409 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2410 ibmcam_veio(uvd, 0, 0x0038, 0x0119);
2411 ibmcam_veio(uvd, 0, 0x00d6, 0x0107);
2412 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2413 ibmcam_veio(uvd, 0, 0x0018, 0x0107);
2414 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2415 ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
2416 ibmcam_veio(uvd, 0, 0x00b9, 0x010a);
2417 ibmcam_veio(uvd, 0, 0x0001, 0x0102);
2418 ibmcam_veio(uvd, 0, 0x002c, 0x0103);
2419 ibmcam_veio(uvd, 0, 0x0000, 0x0104);
2420 ibmcam_veio(uvd, 0, 0x0024, 0x0105);
2421 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2422 ibmcam_veio(uvd, 0, 0x0016, 0x012f);
2423 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2424 ibmcam_veio(uvd, 0, 0x0007, 0x0127);
2425 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2426 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2427 ibmcam_veio(uvd, 0, 0x0014, 0x012d);
2428 ibmcam_veio(uvd, 0, 0x0001, 0x012f);
2429 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2430 ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
2431 ibmcam_veio(uvd, 0, 0x001a, 0x0130);
2432 ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
2433 ibmcam_veio(uvd, 0, 0x005e, 0x012d);
2434 ibmcam_veio(uvd, 0, 0x9545, 0x0124);
2435 ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
2436 ibmcam_veio(uvd, 0, 0x0018, 0x012e);
2437 ibmcam_veio(uvd, 0, 0x0049, 0x0130);
2438 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2439 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2440 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2441 ibmcam_veio(uvd, 0, 0x001c, 0x0127);
2442 ibmcam_veio(uvd, 0, 0x00c7, 0x012e);
2443 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2444 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2445 ibmcam_veio(uvd, 0, 0x0032, 0x012f);
2446 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2447 ibmcam_veio(uvd, 0, 0x0028, 0x0127);
2448 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2449 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2450 ibmcam_veio(uvd, 0, 0x0036, 0x012d);
2451 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2452 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2453 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2454 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2455 ibmcam_veio(uvd, 0, 0x001e, 0x012f);
2456 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2457 ibmcam_veio(uvd, 0, 0x0010, 0x0127);
2458 ibmcam_veio(uvd, 0, 0x0013, 0x012e);
2459 ibmcam_veio(uvd, 0, 0x002a, 0x0130);
2460 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2461 ibmcam_veio(uvd, 0, 0x0010, 0x012d);
2462 ibmcam_veio(uvd, 0, 0x006d, 0x012f);
2463 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2464 ibmcam_veio(uvd, 0, 0x0001, 0x0127);
2465 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2466 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2467 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2468 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2469 ibmcam_veio(uvd, 0, 0x0004, 0x0127);
2470 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2471 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
2472 break;
2473 case VIDEOSIZE_320x240:
2474 ibmcam_veio(uvd, 0, 0x0000, 0x0100);
2475 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
2476 ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
2477 ibmcam_veio(uvd, 0, 0x0080, 0x012b);
2478 ibmcam_veio(uvd, 0, 0x0000, 0x0108);
2479 ibmcam_veio(uvd, 0, 0x0001, 0x0133);
2480 ibmcam_veio(uvd, 0, 0x009b, 0x010f);
2481 ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
2482 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2483 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2484 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2485 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2486 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2487 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2488 ibmcam_veio(uvd, 0, 0x000a, 0x012f);
2489 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2490 ibmcam_veio(uvd, 0, 0x005c, 0x0127);
2491 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2492 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2493 ibmcam_veio(uvd, 0, 0x0004, 0x012f);
2494 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2495 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2496 ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
2497 ibmcam_veio(uvd, 0, 0x0000, 0x0130);
2498 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2499 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2500 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2501 ibmcam_veio(uvd, 0, 0x000c, 0x0127);
2502 ibmcam_veio(uvd, 0, 0x0009, 0x012e);
2503 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2504 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2505 ibmcam_veio(uvd, 0, 0x0012, 0x012f);
2506 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2507 ibmcam_veio(uvd, 0, 0x0008, 0x0127);
2508 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2509 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2510 ibmcam_veio(uvd, 0, 0x002a, 0x012d);
2511 ibmcam_veio(uvd, 0, 0x0000, 0x012f);
2512 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2513 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2514 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2515 ibmcam_veio(uvd, 0, 0x0034, 0x012f);
2516 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2517 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2518 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2519 ibmcam_veio(uvd, 0, 0x0070, 0x0119);
2520 ibmcam_veio(uvd, 0, 0x00d2, 0x0107);
2521 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2522 ibmcam_veio(uvd, 0, 0x005e, 0x0107);
2523 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2524 ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
2525 ibmcam_veio(uvd, 0, 0x0039, 0x010a);
2526 ibmcam_veio(uvd, 0, 0x0001, 0x0102);
2527 ibmcam_veio(uvd, 0, 0x0028, 0x0103);
2528 ibmcam_veio(uvd, 0, 0x0000, 0x0104);
2529 ibmcam_veio(uvd, 0, 0x001e, 0x0105);
2530 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2531 ibmcam_veio(uvd, 0, 0x0016, 0x012f);
2532 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2533 ibmcam_veio(uvd, 0, 0x000a, 0x0127);
2534 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2535 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2536 ibmcam_veio(uvd, 0, 0x0014, 0x012d);
2537 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2538 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2539 ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
2540 ibmcam_veio(uvd, 0, 0x001a, 0x0130);
2541 ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
2542 ibmcam_veio(uvd, 0, 0x005a, 0x012d);
2543 ibmcam_veio(uvd, 0, 0x9545, 0x0124);
2544 ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
2545 ibmcam_veio(uvd, 0, 0x0018, 0x012e);
2546 ibmcam_veio(uvd, 0, 0x0043, 0x0130);
2547 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2548 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2549 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2550 ibmcam_veio(uvd, 0, 0x001c, 0x0127);
2551 ibmcam_veio(uvd, 0, 0x00eb, 0x012e);
2552 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2553 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2554 ibmcam_veio(uvd, 0, 0x0032, 0x012f);
2555 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2556 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2557 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2558 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2559 ibmcam_veio(uvd, 0, 0x0036, 0x012d);
2560 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2561 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2562 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2563 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2564 ibmcam_veio(uvd, 0, 0x001e, 0x012f);
2565 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2566 ibmcam_veio(uvd, 0, 0x0017, 0x0127);
2567 ibmcam_veio(uvd, 0, 0x0013, 0x012e);
2568 ibmcam_veio(uvd, 0, 0x0031, 0x0130);
2569 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2570 ibmcam_veio(uvd, 0, 0x0017, 0x012d);
2571 ibmcam_veio(uvd, 0, 0x0078, 0x012f);
2572 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2573 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2574 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2575 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2576 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2577 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2578 ibmcam_veio(uvd, 0, 0x0004, 0x0127);
2579 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2580 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
2581 break;
2582 case VIDEOSIZE_352x288:
2583 ibmcam_veio(uvd, 0, 0x0000, 0x0100);
2584 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
2585 ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
2586 ibmcam_veio(uvd, 0, 0x0080, 0x012b);
2587 ibmcam_veio(uvd, 0, 0x0000, 0x0108);
2588 ibmcam_veio(uvd, 0, 0x0001, 0x0133);
2589 ibmcam_veio(uvd, 0, 0x009b, 0x010f);
2590 ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
2591 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2592 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2593 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2594 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2595 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2596 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2597 ibmcam_veio(uvd, 0, 0x000a, 0x012f);
2598 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2599 ibmcam_veio(uvd, 0, 0x005c, 0x0127);
2600 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2601 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2602 ibmcam_veio(uvd, 0, 0x0004, 0x012f);
2603 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2604 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2605 ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
2606 ibmcam_veio(uvd, 0, 0x0000, 0x0130);
2607 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2608 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2609 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2610 ibmcam_veio(uvd, 0, 0x000c, 0x0127);
2611 ibmcam_veio(uvd, 0, 0x0009, 0x012e);
2612 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2613 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2614 ibmcam_veio(uvd, 0, 0x0012, 0x012f);
2615 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2616 ibmcam_veio(uvd, 0, 0x0008, 0x0127);
2617 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2618 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2619 ibmcam_veio(uvd, 0, 0x002a, 0x012d);
2620 ibmcam_veio(uvd, 0, 0x0000, 0x012f);
2621 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2622 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2623 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2624 ibmcam_veio(uvd, 0, 0x0034, 0x012f);
2625 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2626 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2627 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2628 ibmcam_veio(uvd, 0, 0x0070, 0x0119);
2629 ibmcam_veio(uvd, 0, 0x00f2, 0x0107);
2630 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2631 ibmcam_veio(uvd, 0, 0x008c, 0x0107);
2632 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2633 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
2634 ibmcam_veio(uvd, 0, 0x0039, 0x010a);
2635 ibmcam_veio(uvd, 0, 0x0001, 0x0102);
2636 ibmcam_veio(uvd, 0, 0x002c, 0x0103);
2637 ibmcam_veio(uvd, 0, 0x0000, 0x0104);
2638 ibmcam_veio(uvd, 0, 0x0024, 0x0105);
2639 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2640 ibmcam_veio(uvd, 0, 0x0016, 0x012f);
2641 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2642 ibmcam_veio(uvd, 0, 0x0006, 0x0127);
2643 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2644 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2645 ibmcam_veio(uvd, 0, 0x0014, 0x012d);
2646 ibmcam_veio(uvd, 0, 0x0002, 0x012f);
2647 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2648 ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
2649 ibmcam_veio(uvd, 0, 0x001a, 0x0130);
2650 ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
2651 ibmcam_veio(uvd, 0, 0x005e, 0x012d);
2652 ibmcam_veio(uvd, 0, 0x9545, 0x0124);
2653 ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
2654 ibmcam_veio(uvd, 0, 0x0018, 0x012e);
2655 ibmcam_veio(uvd, 0, 0x0049, 0x0130);
2656 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2657 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2658 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2659 ibmcam_veio(uvd, 0, 0x001c, 0x0127);
2660 ibmcam_veio(uvd, 0, 0x00cf, 0x012e);
2661 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2662 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2663 ibmcam_veio(uvd, 0, 0x0032, 0x012f);
2664 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2665 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2666 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2667 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2668 ibmcam_veio(uvd, 0, 0x0036, 0x012d);
2669 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2670 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2671 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2672 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2673 ibmcam_veio(uvd, 0, 0x001e, 0x012f);
2674 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2675 ibmcam_veio(uvd, 0, 0x0010, 0x0127);
2676 ibmcam_veio(uvd, 0, 0x0013, 0x012e);
2677 ibmcam_veio(uvd, 0, 0x0025, 0x0130);
2678 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2679 ibmcam_veio(uvd, 0, 0x0010, 0x012d);
2680 ibmcam_veio(uvd, 0, 0x0048, 0x012f);
2681 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2682 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2683 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2684 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2685 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2686 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2687 ibmcam_veio(uvd, 0, 0x0004, 0x0127);
2688 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2689 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
2690 break;
2691 }
2692 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
2693}
2694
2695static void ibmcam_model3_setup_after_video_if(struct uvd *uvd)
2696{
2697 int i;
2698 /*
2699 * 01.01.08 - Added for RCA video in support -LO
2700 * This struct is used to init the Model3 cam to use the RCA video in port
2701 * instead of the CCD sensor.
2702 */
2703 static const struct struct_initData initData[] = {
2704 {0, 0x0000, 0x010c},
2705 {0, 0x0006, 0x012c},
2706 {0, 0x0078, 0x012d},
2707 {0, 0x0046, 0x012f},
2708 {0, 0xd141, 0x0124},
2709 {0, 0x0000, 0x0127},
2710 {0, 0xfea8, 0x0124},
2711 {1, 0x0000, 0x0116},
2712 {0, 0x0064, 0x0116},
2713 {1, 0x0000, 0x0115},
2714 {0, 0x0003, 0x0115},
2715 {0, 0x0008, 0x0123},
2716 {0, 0x0000, 0x0117},
2717 {0, 0x0000, 0x0112},
2718 {0, 0x0080, 0x0100},
2719 {0, 0x0000, 0x0100},
2720 {1, 0x0000, 0x0116},
2721 {0, 0x0060, 0x0116},
2722 {0, 0x0002, 0x0112},
2723 {0, 0x0000, 0x0123},
2724 {0, 0x0001, 0x0117},
2725 {0, 0x0040, 0x0108},
2726 {0, 0x0019, 0x012c},
2727 {0, 0x0040, 0x0116},
2728 {0, 0x000a, 0x0115},
2729 {0, 0x000b, 0x0115},
2730 {0, 0x0078, 0x012d},
2731 {0, 0x0046, 0x012f},
2732 {0, 0xd141, 0x0124},
2733 {0, 0x0000, 0x0127},
2734 {0, 0xfea8, 0x0124},
2735 {0, 0x0064, 0x0116},
2736 {0, 0x0000, 0x0115},
2737 {0, 0x0001, 0x0115},
2738 {0, 0xffff, 0x0124},
2739 {0, 0xfff9, 0x0124},
2740 {0, 0x0086, 0x0127},
2741 {0, 0xfff8, 0x0124},
2742 {0, 0xfffd, 0x0124},
2743 {0, 0x00aa, 0x0127},
2744 {0, 0xfff8, 0x0124},
2745 {0, 0xfffd, 0x0124},
2746 {0, 0x0000, 0x0127},
2747 {0, 0xfff8, 0x0124},
2748 {0, 0xfffd, 0x0124},
2749 {0, 0xfffa, 0x0124},
2750 {0, 0xffff, 0x0124},
2751 {0, 0xfff9, 0x0124},
2752 {0, 0x0086, 0x0127},
2753 {0, 0xfff8, 0x0124},
2754 {0, 0xfffd, 0x0124},
2755 {0, 0x00f2, 0x0127},
2756 {0, 0xfff8, 0x0124},
2757 {0, 0xfffd, 0x0124},
2758 {0, 0x000f, 0x0127},
2759 {0, 0xfff8, 0x0124},
2760 {0, 0xfffd, 0x0124},
2761 {0, 0xfffa, 0x0124},
2762 {0, 0xffff, 0x0124},
2763 {0, 0xfff9, 0x0124},
2764 {0, 0x0086, 0x0127},
2765 {0, 0xfff8, 0x0124},
2766 {0, 0xfffd, 0x0124},
2767 {0, 0x00f8, 0x0127},
2768 {0, 0xfff8, 0x0124},
2769 {0, 0xfffd, 0x0124},
2770 {0, 0x00fc, 0x0127},
2771 {0, 0xfff8, 0x0124},
2772 {0, 0xfffd, 0x0124},
2773 {0, 0xfffa, 0x0124},
2774 {0, 0xffff, 0x0124},
2775 {0, 0xfff9, 0x0124},
2776 {0, 0x0086, 0x0127},
2777 {0, 0xfff8, 0x0124},
2778 {0, 0xfffd, 0x0124},
2779 {0, 0x00f9, 0x0127},
2780 {0, 0xfff8, 0x0124},
2781 {0, 0xfffd, 0x0124},
2782 {0, 0x003c, 0x0127},
2783 {0, 0xfff8, 0x0124},
2784 {0, 0xfffd, 0x0124},
2785 {0, 0xfffa, 0x0124},
2786 {0, 0xffff, 0x0124},
2787 {0, 0xfff9, 0x0124},
2788 {0, 0x0086, 0x0127},
2789 {0, 0xfff8, 0x0124},
2790 {0, 0xfffd, 0x0124},
2791 {0, 0x0027, 0x0127},
2792 {0, 0xfff8, 0x0124},
2793 {0, 0xfffd, 0x0124},
2794 {0, 0x0019, 0x0127},
2795 {0, 0xfff8, 0x0124},
2796 {0, 0xfffd, 0x0124},
2797 {0, 0xfffa, 0x0124},
2798 {0, 0xfff9, 0x0124},
2799 {0, 0x0086, 0x0127},
2800 {0, 0xfff8, 0x0124},
2801 {0, 0xfffd, 0x0124},
2802 {0, 0x0037, 0x0127},
2803 {0, 0xfff8, 0x0124},
2804 {0, 0xfffd, 0x0124},
2805 {0, 0x0000, 0x0127},
2806 {0, 0xfff8, 0x0124},
2807 {0, 0xfffd, 0x0124},
2808 {0, 0x0021, 0x0127},
2809 {0, 0xfff8, 0x0124},
2810 {0, 0xfffd, 0x0124},
2811 {0, 0xfffa, 0x0124},
2812 {0, 0xfff9, 0x0124},
2813 {0, 0x0086, 0x0127},
2814 {0, 0xfff8, 0x0124},
2815 {0, 0xfffd, 0x0124},
2816 {0, 0x0038, 0x0127},
2817 {0, 0xfff8, 0x0124},
2818 {0, 0xfffd, 0x0124},
2819 {0, 0x0006, 0x0127},
2820 {0, 0xfff8, 0x0124},
2821 {0, 0xfffd, 0x0124},
2822 {0, 0x0045, 0x0127},
2823 {0, 0xfff8, 0x0124},
2824 {0, 0xfffd, 0x0124},
2825 {0, 0xfffa, 0x0124},
2826 {0, 0xfff9, 0x0124},
2827 {0, 0x0086, 0x0127},
2828 {0, 0xfff8, 0x0124},
2829 {0, 0xfffd, 0x0124},
2830 {0, 0x0037, 0x0127},
2831 {0, 0xfff8, 0x0124},
2832 {0, 0xfffd, 0x0124},
2833 {0, 0x0001, 0x0127},
2834 {0, 0xfff8, 0x0124},
2835 {0, 0xfffd, 0x0124},
2836 {0, 0x002a, 0x0127},
2837 {0, 0xfff8, 0x0124},
2838 {0, 0xfffd, 0x0124},
2839 {0, 0xfffa, 0x0124},
2840 {0, 0xfff9, 0x0124},
2841 {0, 0x0086, 0x0127},
2842 {0, 0xfff8, 0x0124},
2843 {0, 0xfffd, 0x0124},
2844 {0, 0x0038, 0x0127},
2845 {0, 0xfff8, 0x0124},
2846 {0, 0xfffd, 0x0124},
2847 {0, 0x0000, 0x0127},
2848 {0, 0xfff8, 0x0124},
2849 {0, 0xfffd, 0x0124},
2850 {0, 0x000e, 0x0127},
2851 {0, 0xfff8, 0x0124},
2852 {0, 0xfffd, 0x0124},
2853 {0, 0xfffa, 0x0124},
2854 {0, 0xfff9, 0x0124},
2855 {0, 0x0086, 0x0127},
2856 {0, 0xfff8, 0x0124},
2857 {0, 0xfffd, 0x0124},
2858 {0, 0x0037, 0x0127},
2859 {0, 0xfff8, 0x0124},
2860 {0, 0xfffd, 0x0124},
2861 {0, 0x0001, 0x0127},
2862 {0, 0xfff8, 0x0124},
2863 {0, 0xfffd, 0x0124},
2864 {0, 0x002b, 0x0127},
2865 {0, 0xfff8, 0x0124},
2866 {0, 0xfffd, 0x0124},
2867 {0, 0xfffa, 0x0124},
2868 {0, 0xfff9, 0x0124},
2869 {0, 0x0086, 0x0127},
2870 {0, 0xfff8, 0x0124},
2871 {0, 0xfffd, 0x0124},
2872 {0, 0x0038, 0x0127},
2873 {0, 0xfff8, 0x0124},
2874 {0, 0xfffd, 0x0124},
2875 {0, 0x0001, 0x0127},
2876 {0, 0xfff8, 0x0124},
2877 {0, 0xfffd, 0x0124},
2878 {0, 0x00f4, 0x0127},
2879 {0, 0xfff8, 0x0124},
2880 {0, 0xfffd, 0x0124},
2881 {0, 0xfffa, 0x0124},
2882 {0, 0xfff9, 0x0124},
2883 {0, 0x0086, 0x0127},
2884 {0, 0xfff8, 0x0124},
2885 {0, 0xfffd, 0x0124},
2886 {0, 0x0037, 0x0127},
2887 {0, 0xfff8, 0x0124},
2888 {0, 0xfffd, 0x0124},
2889 {0, 0x0001, 0x0127},
2890 {0, 0xfff8, 0x0124},
2891 {0, 0xfffd, 0x0124},
2892 {0, 0x002c, 0x0127},
2893 {0, 0xfff8, 0x0124},
2894 {0, 0xfffd, 0x0124},
2895 {0, 0xfffa, 0x0124},
2896 {0, 0xfff9, 0x0124},
2897 {0, 0x0086, 0x0127},
2898 {0, 0xfff8, 0x0124},
2899 {0, 0xfffd, 0x0124},
2900 {0, 0x0038, 0x0127},
2901 {0, 0xfff8, 0x0124},
2902 {0, 0xfffd, 0x0124},
2903 {0, 0x0001, 0x0127},
2904 {0, 0xfff8, 0x0124},
2905 {0, 0xfffd, 0x0124},
2906 {0, 0x0004, 0x0127},
2907 {0, 0xfff8, 0x0124},
2908 {0, 0xfffd, 0x0124},
2909 {0, 0xfffa, 0x0124},
2910 {0, 0xfff9, 0x0124},
2911 {0, 0x0086, 0x0127},
2912 {0, 0xfff8, 0x0124},
2913 {0, 0xfffd, 0x0124},
2914 {0, 0x0037, 0x0127},
2915 {0, 0xfff8, 0x0124},
2916 {0, 0xfffd, 0x0124},
2917 {0, 0x0001, 0x0127},
2918 {0, 0xfff8, 0x0124},
2919 {0, 0xfffd, 0x0124},
2920 {0, 0x002d, 0x0127},
2921 {0, 0xfff8, 0x0124},
2922 {0, 0xfffd, 0x0124},
2923 {0, 0xfffa, 0x0124},
2924 {0, 0xfff9, 0x0124},
2925 {0, 0x0086, 0x0127},
2926 {0, 0xfff8, 0x0124},
2927 {0, 0xfffd, 0x0124},
2928 {0, 0x0038, 0x0127},
2929 {0, 0xfff8, 0x0124},
2930 {0, 0xfffd, 0x0124},
2931 {0, 0x0000, 0x0127},
2932 {0, 0xfff8, 0x0124},
2933 {0, 0xfffd, 0x0124},
2934 {0, 0x0014, 0x0127},
2935 {0, 0xfff8, 0x0124},
2936 {0, 0xfffd, 0x0124},
2937 {0, 0xfffa, 0x0124},
2938 {0, 0xfff9, 0x0124},
2939 {0, 0x0086, 0x0127},
2940 {0, 0xfff8, 0x0124},
2941 {0, 0xfffd, 0x0124},
2942 {0, 0x0037, 0x0127},
2943 {0, 0xfff8, 0x0124},
2944 {0, 0xfffd, 0x0124},
2945 {0, 0x0001, 0x0127},
2946 {0, 0xfff8, 0x0124},
2947 {0, 0xfffd, 0x0124},
2948 {0, 0x002e, 0x0127},
2949 {0, 0xfff8, 0x0124},
2950 {0, 0xfffd, 0x0124},
2951 {0, 0xfffa, 0x0124},
2952 {0, 0xfff9, 0x0124},
2953 {0, 0x0086, 0x0127},
2954 {0, 0xfff8, 0x0124},
2955 {0, 0xfffd, 0x0124},
2956 {0, 0x0038, 0x0127},
2957 {0, 0xfff8, 0x0124},
2958 {0, 0xfffd, 0x0124},
2959 {0, 0x0003, 0x0127},
2960 {0, 0xfff8, 0x0124},
2961 {0, 0xfffd, 0x0124},
2962 {0, 0x0000, 0x0127},
2963 {0, 0xfff8, 0x0124},
2964 {0, 0xfffd, 0x0124},
2965 {0, 0xfffa, 0x0124},
2966 {0, 0xfff9, 0x0124},
2967 {0, 0x0086, 0x0127},
2968 {0, 0xfff8, 0x0124},
2969 {0, 0xfffd, 0x0124},
2970 {0, 0x0037, 0x0127},
2971 {0, 0xfff8, 0x0124},
2972 {0, 0xfffd, 0x0124},
2973 {0, 0x0001, 0x0127},
2974 {0, 0xfff8, 0x0124},
2975 {0, 0xfffd, 0x0124},
2976 {0, 0x002f, 0x0127},
2977 {0, 0xfff8, 0x0124},
2978 {0, 0xfffd, 0x0124},
2979 {0, 0xfffa, 0x0124},
2980 {0, 0xfff9, 0x0124},
2981 {0, 0x0086, 0x0127},
2982 {0, 0xfff8, 0x0124},
2983 {0, 0xfffd, 0x0124},
2984 {0, 0x0038, 0x0127},
2985 {0, 0xfff8, 0x0124},
2986 {0, 0xfffd, 0x0124},
2987 {0, 0x0003, 0x0127},
2988 {0, 0xfff8, 0x0124},
2989 {0, 0xfffd, 0x0124},
2990 {0, 0x0014, 0x0127},
2991 {0, 0xfff8, 0x0124},
2992 {0, 0xfffd, 0x0124},
2993 {0, 0xfffa, 0x0124},
2994 {0, 0xfff9, 0x0124},
2995 {0, 0x0086, 0x0127},
2996 {0, 0xfff8, 0x0124},
2997 {0, 0xfffd, 0x0124},
2998 {0, 0x0037, 0x0127},
2999 {0, 0xfff8, 0x0124},
3000 {0, 0xfffd, 0x0124},
3001 {0, 0x0001, 0x0127},
3002 {0, 0xfff8, 0x0124},
3003 {0, 0xfffd, 0x0124},
3004 {0, 0x0040, 0x0127},
3005 {0, 0xfff8, 0x0124},
3006 {0, 0xfffd, 0x0124},
3007 {0, 0xfffa, 0x0124},
3008 {0, 0xfff9, 0x0124},
3009 {0, 0x0086, 0x0127},
3010 {0, 0xfff8, 0x0124},
3011 {0, 0xfffd, 0x0124},
3012 {0, 0x0038, 0x0127},
3013 {0, 0xfff8, 0x0124},
3014 {0, 0xfffd, 0x0124},
3015 {0, 0x0000, 0x0127},
3016 {0, 0xfff8, 0x0124},
3017 {0, 0xfffd, 0x0124},
3018 {0, 0x0040, 0x0127},
3019 {0, 0xfff8, 0x0124},
3020 {0, 0xfffd, 0x0124},
3021 {0, 0xfffa, 0x0124},
3022 {0, 0xfff9, 0x0124},
3023 {0, 0x0086, 0x0127},
3024 {0, 0xfff8, 0x0124},
3025 {0, 0xfffd, 0x0124},
3026 {0, 0x0037, 0x0127},
3027 {0, 0xfff8, 0x0124},
3028 {0, 0xfffd, 0x0124},
3029 {0, 0x0001, 0x0127},
3030 {0, 0xfff8, 0x0124},
3031 {0, 0xfffd, 0x0124},
3032 {0, 0x0053, 0x0127},
3033 {0, 0xfff8, 0x0124},
3034 {0, 0xfffd, 0x0124},
3035 {0, 0xfffa, 0x0124},
3036 {0, 0xfff9, 0x0124},
3037 {0, 0x0086, 0x0127},
3038 {0, 0xfff8, 0x0124},
3039 {0, 0xfffd, 0x0124},
3040 {0, 0x0038, 0x0127},
3041 {0, 0xfff8, 0x0124},
3042 {0, 0xfffd, 0x0124},
3043 {0, 0x0000, 0x0127},
3044 {0, 0xfff8, 0x0124},
3045 {0, 0xfffd, 0x0124},
3046 {0, 0x0038, 0x0127},
3047 {0, 0xfff8, 0x0124},
3048 {0, 0xfffd, 0x0124},
3049 {0, 0xfffa, 0x0124},
3050 {0, 0x0000, 0x0101},
3051 {0, 0x00a0, 0x0103},
3052 {0, 0x0078, 0x0105},
3053 {0, 0x0000, 0x010a},
3054 {0, 0x0024, 0x010b},
3055 {0, 0x0028, 0x0119},
3056 {0, 0x0088, 0x011b},
3057 {0, 0x0002, 0x011d},
3058 {0, 0x0003, 0x011e},
3059 {0, 0x0000, 0x0129},
3060 {0, 0x00fc, 0x012b},
3061 {0, 0x0008, 0x0102},
3062 {0, 0x0000, 0x0104},
3063 {0, 0x0008, 0x011a},
3064 {0, 0x0028, 0x011c},
3065 {0, 0x0021, 0x012a},
3066 {0, 0x0000, 0x0118},
3067 {0, 0x0000, 0x0132},
3068 {0, 0x0000, 0x0109},
3069 {0, 0xfff9, 0x0124},
3070 {0, 0x0086, 0x0127},
3071 {0, 0xfff8, 0x0124},
3072 {0, 0xfffd, 0x0124},
3073 {0, 0x0037, 0x0127},
3074 {0, 0xfff8, 0x0124},
3075 {0, 0xfffd, 0x0124},
3076 {0, 0x0001, 0x0127},
3077 {0, 0xfff8, 0x0124},
3078 {0, 0xfffd, 0x0124},
3079 {0, 0x0031, 0x0127},
3080 {0, 0xfff8, 0x0124},
3081 {0, 0xfffd, 0x0124},
3082 {0, 0xfffa, 0x0124},
3083 {0, 0xfff9, 0x0124},
3084 {0, 0x0086, 0x0127},
3085 {0, 0xfff8, 0x0124},
3086 {0, 0xfffd, 0x0124},
3087 {0, 0x0038, 0x0127},
3088 {0, 0xfff8, 0x0124},
3089 {0, 0xfffd, 0x0124},
3090 {0, 0x0000, 0x0127},
3091 {0, 0xfff8, 0x0124},
3092 {0, 0xfffd, 0x0124},
3093 {0, 0x0000, 0x0127},
3094 {0, 0xfff8, 0x0124},
3095 {0, 0xfffd, 0x0124},
3096 {0, 0xfffa, 0x0124},
3097 {0, 0xfff9, 0x0124},
3098 {0, 0x0086, 0x0127},
3099 {0, 0xfff8, 0x0124},
3100 {0, 0xfffd, 0x0124},
3101 {0, 0x0037, 0x0127},
3102 {0, 0xfff8, 0x0124},
3103 {0, 0xfffd, 0x0124},
3104 {0, 0x0001, 0x0127},
3105 {0, 0xfff8, 0x0124},
3106 {0, 0xfffd, 0x0124},
3107 {0, 0x0040, 0x0127},
3108 {0, 0xfff8, 0x0124},
3109 {0, 0xfffd, 0x0124},
3110 {0, 0xfffa, 0x0124},
3111 {0, 0xfff9, 0x0124},
3112 {0, 0x0086, 0x0127},
3113 {0, 0xfff8, 0x0124},
3114 {0, 0xfffd, 0x0124},
3115 {0, 0x0038, 0x0127},
3116 {0, 0xfff8, 0x0124},
3117 {0, 0xfffd, 0x0124},
3118 {0, 0x0000, 0x0127},
3119 {0, 0xfff8, 0x0124},
3120 {0, 0xfffd, 0x0124},
3121 {0, 0x0040, 0x0127},
3122 {0, 0xfff8, 0x0124},
3123 {0, 0xfffd, 0x0124},
3124 {0, 0xfffa, 0x0124},
3125 {0, 0xfff9, 0x0124},
3126 {0, 0x0086, 0x0127},
3127 {0, 0xfff8, 0x0124},
3128 {0, 0xfffd, 0x0124},
3129 {0, 0x0037, 0x0127},
3130 {0, 0xfff8, 0x0124},
3131 {0, 0xfffd, 0x0124},
3132 {0, 0x0000, 0x0127},
3133 {0, 0xfff8, 0x0124},
3134 {0, 0xfffd, 0x0124},
3135 {0, 0x00dc, 0x0127},
3136 {0, 0xfff8, 0x0124},
3137 {0, 0xfffd, 0x0124},
3138 {0, 0xfffa, 0x0124},
3139 {0, 0xfff9, 0x0124},
3140 {0, 0x0086, 0x0127},
3141 {0, 0xfff8, 0x0124},
3142 {0, 0xfffd, 0x0124},
3143 {0, 0x0038, 0x0127},
3144 {0, 0xfff8, 0x0124},
3145 {0, 0xfffd, 0x0124},
3146 {0, 0x0000, 0x0127},
3147 {0, 0xfff8, 0x0124},
3148 {0, 0xfffd, 0x0124},
3149 {0, 0x0000, 0x0127},
3150 {0, 0xfff8, 0x0124},
3151 {0, 0xfffd, 0x0124},
3152 {0, 0xfffa, 0x0124},
3153 {0, 0xfff9, 0x0124},
3154 {0, 0x0086, 0x0127},
3155 {0, 0xfff8, 0x0124},
3156 {0, 0xfffd, 0x0124},
3157 {0, 0x0037, 0x0127},
3158 {0, 0xfff8, 0x0124},
3159 {0, 0xfffd, 0x0124},
3160 {0, 0x0001, 0x0127},
3161 {0, 0xfff8, 0x0124},
3162 {0, 0xfffd, 0x0124},
3163 {0, 0x0032, 0x0127},
3164 {0, 0xfff8, 0x0124},
3165 {0, 0xfffd, 0x0124},
3166 {0, 0xfffa, 0x0124},
3167 {0, 0xfff9, 0x0124},
3168 {0, 0x0086, 0x0127},
3169 {0, 0xfff8, 0x0124},
3170 {0, 0xfffd, 0x0124},
3171 {0, 0x0038, 0x0127},
3172 {0, 0xfff8, 0x0124},
3173 {0, 0xfffd, 0x0124},
3174 {0, 0x0001, 0x0127},
3175 {0, 0xfff8, 0x0124},
3176 {0, 0xfffd, 0x0124},
3177 {0, 0x0020, 0x0127},
3178 {0, 0xfff8, 0x0124},
3179 {0, 0xfffd, 0x0124},
3180 {0, 0xfffa, 0x0124},
3181 {0, 0xfff9, 0x0124},
3182 {0, 0x0086, 0x0127},
3183 {0, 0xfff8, 0x0124},
3184 {0, 0xfffd, 0x0124},
3185 {0, 0x0037, 0x0127},
3186 {0, 0xfff8, 0x0124},
3187 {0, 0xfffd, 0x0124},
3188 {0, 0x0001, 0x0127},
3189 {0, 0xfff8, 0x0124},
3190 {0, 0xfffd, 0x0124},
3191 {0, 0x0040, 0x0127},
3192 {0, 0xfff8, 0x0124},
3193 {0, 0xfffd, 0x0124},
3194 {0, 0xfffa, 0x0124},
3195 {0, 0xfff9, 0x0124},
3196 {0, 0x0086, 0x0127},
3197 {0, 0xfff8, 0x0124},
3198 {0, 0xfffd, 0x0124},
3199 {0, 0x0038, 0x0127},
3200 {0, 0xfff8, 0x0124},
3201 {0, 0xfffd, 0x0124},
3202 {0, 0x0000, 0x0127},
3203 {0, 0xfff8, 0x0124},
3204 {0, 0xfffd, 0x0124},
3205 {0, 0x0040, 0x0127},
3206 {0, 0xfff8, 0x0124},
3207 {0, 0xfffd, 0x0124},
3208 {0, 0xfffa, 0x0124},
3209 {0, 0xfff9, 0x0124},
3210 {0, 0x0086, 0x0127},
3211 {0, 0xfff8, 0x0124},
3212 {0, 0xfffd, 0x0124},
3213 {0, 0x0037, 0x0127},
3214 {0, 0xfff8, 0x0124},
3215 {0, 0xfffd, 0x0124},
3216 {0, 0x0000, 0x0127},
3217 {0, 0xfff8, 0x0124},
3218 {0, 0xfffd, 0x0124},
3219 {0, 0x0030, 0x0127},
3220 {0, 0xfff8, 0x0124},
3221 {0, 0xfffd, 0x0124},
3222 {0, 0xfffa, 0x0124},
3223 {0, 0xfff9, 0x0124},
3224 {0, 0x0086, 0x0127},
3225 {0, 0xfff8, 0x0124},
3226 {0, 0xfffd, 0x0124},
3227 {0, 0x0038, 0x0127},
3228 {0, 0xfff8, 0x0124},
3229 {0, 0xfffd, 0x0124},
3230 {0, 0x0008, 0x0127},
3231 {0, 0xfff8, 0x0124},
3232 {0, 0xfffd, 0x0124},
3233 {0, 0x0000, 0x0127},
3234 {0, 0xfff8, 0x0124},
3235 {0, 0xfffd, 0x0124},
3236 {0, 0xfffa, 0x0124},
3237 {0, 0x0003, 0x0106},
3238 {0, 0x0062, 0x0107},
3239 {0, 0x0003, 0x0111},
3240 };
3241#define NUM_INIT_DATA
3242
3243 unsigned short compression = 0; /* 0=none, 7=best frame rate */
3244 int f_rate; /* 0=Fastest 7=slowest */
3245
3246 if (IBMCAM_T(uvd)->initialized)
3247 return;
3248
3249 /* Internal frame rate is controlled by f_rate value */
3250 f_rate = 7 - framerate;
3251 RESTRICT_TO_RANGE(f_rate, 0, 7);
3252
3253 ibmcam_veio(uvd, 0, 0x0000, 0x0100);
3254 ibmcam_veio(uvd, 1, 0x0000, 0x0116);
3255 ibmcam_veio(uvd, 0, 0x0060, 0x0116);
3256 ibmcam_veio(uvd, 0, 0x0002, 0x0112);
3257 ibmcam_veio(uvd, 0, 0x0000, 0x0123);
3258 ibmcam_veio(uvd, 0, 0x0001, 0x0117);
3259 ibmcam_veio(uvd, 0, 0x0040, 0x0108);
3260 ibmcam_veio(uvd, 0, 0x0019, 0x012c);
3261 ibmcam_veio(uvd, 0, 0x0060, 0x0116);
3262 ibmcam_veio(uvd, 0, 0x0002, 0x0115);
3263 ibmcam_veio(uvd, 0, 0x0003, 0x0115);
3264 ibmcam_veio(uvd, 1, 0x0000, 0x0115);
3265 ibmcam_veio(uvd, 0, 0x000b, 0x0115);
3266 ibmcam_model3_Packet1(uvd, 0x000a, 0x0040);
3267 ibmcam_model3_Packet1(uvd, 0x000b, 0x00f6);
3268 ibmcam_model3_Packet1(uvd, 0x000c, 0x0002);
3269 ibmcam_model3_Packet1(uvd, 0x000d, 0x0020);
3270 ibmcam_model3_Packet1(uvd, 0x000e, 0x0033);
3271 ibmcam_model3_Packet1(uvd, 0x000f, 0x0007);
3272 ibmcam_model3_Packet1(uvd, 0x0010, 0x0000);
3273 ibmcam_model3_Packet1(uvd, 0x0011, 0x0070);
3274 ibmcam_model3_Packet1(uvd, 0x0012, 0x0030);
3275 ibmcam_model3_Packet1(uvd, 0x0013, 0x0000);
3276 ibmcam_model3_Packet1(uvd, 0x0014, 0x0001);
3277 ibmcam_model3_Packet1(uvd, 0x0015, 0x0001);
3278 ibmcam_model3_Packet1(uvd, 0x0016, 0x0001);
3279 ibmcam_model3_Packet1(uvd, 0x0017, 0x0001);
3280 ibmcam_model3_Packet1(uvd, 0x0018, 0x0000);
3281 ibmcam_model3_Packet1(uvd, 0x001e, 0x00c3);
3282 ibmcam_model3_Packet1(uvd, 0x0020, 0x0000);
3283 ibmcam_model3_Packet1(uvd, 0x0028, 0x0010);
3284 ibmcam_model3_Packet1(uvd, 0x0029, 0x0054);
3285 ibmcam_model3_Packet1(uvd, 0x002a, 0x0013);
3286 ibmcam_model3_Packet1(uvd, 0x002b, 0x0007);
3287 ibmcam_model3_Packet1(uvd, 0x002d, 0x0028);
3288 ibmcam_model3_Packet1(uvd, 0x002e, 0x0000);
3289 ibmcam_model3_Packet1(uvd, 0x0031, 0x0000);
3290 ibmcam_model3_Packet1(uvd, 0x0032, 0x0000);
3291 ibmcam_model3_Packet1(uvd, 0x0033, 0x0000);
3292 ibmcam_model3_Packet1(uvd, 0x0034, 0x0000);
3293 ibmcam_model3_Packet1(uvd, 0x0035, 0x0038);
3294 ibmcam_model3_Packet1(uvd, 0x003a, 0x0001);
3295 ibmcam_model3_Packet1(uvd, 0x003c, 0x001e);
3296 ibmcam_model3_Packet1(uvd, 0x003f, 0x000a);
3297 ibmcam_model3_Packet1(uvd, 0x0041, 0x0000);
3298 ibmcam_model3_Packet1(uvd, 0x0046, 0x003f);
3299 ibmcam_model3_Packet1(uvd, 0x0047, 0x0000);
3300 ibmcam_model3_Packet1(uvd, 0x0050, 0x0005);
3301 ibmcam_model3_Packet1(uvd, 0x0052, 0x001a);
3302 ibmcam_model3_Packet1(uvd, 0x0053, 0x0003);
3303 ibmcam_model3_Packet1(uvd, 0x005a, 0x006b);
3304 ibmcam_model3_Packet1(uvd, 0x005d, 0x001e);
3305 ibmcam_model3_Packet1(uvd, 0x005e, 0x0030);
3306 ibmcam_model3_Packet1(uvd, 0x005f, 0x0041);
3307 ibmcam_model3_Packet1(uvd, 0x0064, 0x0008);
3308 ibmcam_model3_Packet1(uvd, 0x0065, 0x0015);
3309 ibmcam_model3_Packet1(uvd, 0x0068, 0x000f);
3310 ibmcam_model3_Packet1(uvd, 0x0079, 0x0000);
3311 ibmcam_model3_Packet1(uvd, 0x007a, 0x0000);
3312 ibmcam_model3_Packet1(uvd, 0x007c, 0x003f);
3313 ibmcam_model3_Packet1(uvd, 0x0082, 0x000f);
3314 ibmcam_model3_Packet1(uvd, 0x0085, 0x0000);
3315 ibmcam_model3_Packet1(uvd, 0x0099, 0x0000);
3316 ibmcam_model3_Packet1(uvd, 0x009b, 0x0023);
3317 ibmcam_model3_Packet1(uvd, 0x009c, 0x0022);
3318 ibmcam_model3_Packet1(uvd, 0x009d, 0x0096);
3319 ibmcam_model3_Packet1(uvd, 0x009e, 0x0096);
3320 ibmcam_model3_Packet1(uvd, 0x009f, 0x000a);
3321
3322 switch (uvd->videosize) {
3323 case VIDEOSIZE_160x120:
3324 ibmcam_veio(uvd, 0, 0x0000, 0x0101); /* Same on 176x144, 320x240 */
3325 ibmcam_veio(uvd, 0, 0x00a0, 0x0103); /* Same on 176x144, 320x240 */
3326 ibmcam_veio(uvd, 0, 0x0078, 0x0105); /* Same on 176x144, 320x240 */
3327 ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */
3328 ibmcam_veio(uvd, 0, 0x0024, 0x010b); /* Differs everywhere */
3329 ibmcam_veio(uvd, 0, 0x00a9, 0x0119);
3330 ibmcam_veio(uvd, 0, 0x0016, 0x011b);
3331 ibmcam_veio(uvd, 0, 0x0002, 0x011d); /* Same on 176x144, 320x240 */
3332 ibmcam_veio(uvd, 0, 0x0003, 0x011e); /* Same on 176x144, 640x480 */
3333 ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */
3334 ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */
3335 ibmcam_veio(uvd, 0, 0x0018, 0x0102);
3336 ibmcam_veio(uvd, 0, 0x0004, 0x0104);
3337 ibmcam_veio(uvd, 0, 0x0004, 0x011a);
3338 ibmcam_veio(uvd, 0, 0x0028, 0x011c);
3339 ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */
3340 ibmcam_veio(uvd, 0, 0x0000, 0x0118);
3341 ibmcam_veio(uvd, 0, 0x0000, 0x0132);
3342 ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */
3343 ibmcam_veio(uvd, 0, compression, 0x0109);
3344 break;
3345 case VIDEOSIZE_320x240:
3346 ibmcam_veio(uvd, 0, 0x0000, 0x0101); /* Same on 176x144, 320x240 */
3347 ibmcam_veio(uvd, 0, 0x00a0, 0x0103); /* Same on 176x144, 320x240 */
3348 ibmcam_veio(uvd, 0, 0x0078, 0x0105); /* Same on 176x144, 320x240 */
3349 ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */
3350 ibmcam_veio(uvd, 0, 0x0028, 0x010b); /* Differs everywhere */
3351 ibmcam_veio(uvd, 0, 0x0002, 0x011d); /* Same */
3352 ibmcam_veio(uvd, 0, 0x0000, 0x011e);
3353 ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */
3354 ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */
3355 /* 4 commands from 160x120 skipped */
3356 ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */
3357 ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */
3358 ibmcam_veio(uvd, 0, compression, 0x0109);
3359 ibmcam_veio(uvd, 0, 0x00d9, 0x0119);
3360 ibmcam_veio(uvd, 0, 0x0006, 0x011b);
3361 ibmcam_veio(uvd, 0, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
3362 ibmcam_veio(uvd, 0, 0x0010, 0x0104);
3363 ibmcam_veio(uvd, 0, 0x0004, 0x011a);
3364 ibmcam_veio(uvd, 0, 0x003f, 0x011c);
3365 ibmcam_veio(uvd, 0, 0x001c, 0x0118);
3366 ibmcam_veio(uvd, 0, 0x0000, 0x0132);
3367 break;
3368 case VIDEOSIZE_640x480:
3369 ibmcam_veio(uvd, 0, 0x00f0, 0x0105);
3370 ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */
3371 ibmcam_veio(uvd, 0, 0x0038, 0x010b); /* Differs everywhere */
3372 ibmcam_veio(uvd, 0, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */
3373 ibmcam_veio(uvd, 0, 0x0006, 0x011b); /* Same on 320x240, 640x480 */
3374 ibmcam_veio(uvd, 0, 0x0004, 0x011d); /* NC */
3375 ibmcam_veio(uvd, 0, 0x0003, 0x011e); /* Same on 176x144, 640x480 */
3376 ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */
3377 ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */
3378 ibmcam_veio(uvd, 0, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
3379 ibmcam_veio(uvd, 0, 0x0016, 0x0104); /* NC */
3380 ibmcam_veio(uvd, 0, 0x0004, 0x011a); /* Same on 320x240, 640x480 */
3381 ibmcam_veio(uvd, 0, 0x003f, 0x011c); /* Same on 320x240, 640x480 */
3382 ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */
3383 ibmcam_veio(uvd, 0, 0x001c, 0x0118); /* Same on 320x240, 640x480 */
3384 ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */
3385 ibmcam_veio(uvd, 0, compression, 0x0109);
3386 ibmcam_veio(uvd, 0, 0x0040, 0x0101);
3387 ibmcam_veio(uvd, 0, 0x0040, 0x0103);
3388 ibmcam_veio(uvd, 0, 0x0000, 0x0132); /* Same on 320x240, 640x480 */
3389 break;
3390 }
3391 ibmcam_model3_Packet1(uvd, 0x007e, 0x000e); /* Hue */
3392 ibmcam_model3_Packet1(uvd, 0x0036, 0x0011); /* Brightness */
3393 ibmcam_model3_Packet1(uvd, 0x0060, 0x0002); /* Sharpness */
3394 ibmcam_model3_Packet1(uvd, 0x0061, 0x0004); /* Sharpness */
3395 ibmcam_model3_Packet1(uvd, 0x0062, 0x0005); /* Sharpness */
3396 ibmcam_model3_Packet1(uvd, 0x0063, 0x0014); /* Sharpness */
3397 ibmcam_model3_Packet1(uvd, 0x0096, 0x00a0); /* Red gain */
3398 ibmcam_model3_Packet1(uvd, 0x0097, 0x0096); /* Blue gain */
3399 ibmcam_model3_Packet1(uvd, 0x0067, 0x0001); /* Contrast */
3400 ibmcam_model3_Packet1(uvd, 0x005b, 0x000c); /* Contrast */
3401 ibmcam_model3_Packet1(uvd, 0x005c, 0x0016); /* Contrast */
3402 ibmcam_model3_Packet1(uvd, 0x0098, 0x000b);
3403 ibmcam_model3_Packet1(uvd, 0x002c, 0x0003); /* Was 1, broke 640x480 */
3404 ibmcam_model3_Packet1(uvd, 0x002f, 0x002a);
3405 ibmcam_model3_Packet1(uvd, 0x0030, 0x0029);
3406 ibmcam_model3_Packet1(uvd, 0x0037, 0x0002);
3407 ibmcam_model3_Packet1(uvd, 0x0038, 0x0059);
3408 ibmcam_model3_Packet1(uvd, 0x003d, 0x002e);
3409 ibmcam_model3_Packet1(uvd, 0x003e, 0x0028);
3410 ibmcam_model3_Packet1(uvd, 0x0078, 0x0005);
3411 ibmcam_model3_Packet1(uvd, 0x007b, 0x0011);
3412 ibmcam_model3_Packet1(uvd, 0x007d, 0x004b);
3413 ibmcam_model3_Packet1(uvd, 0x007f, 0x0022);
3414 ibmcam_model3_Packet1(uvd, 0x0080, 0x000c);
3415 ibmcam_model3_Packet1(uvd, 0x0081, 0x000b);
3416 ibmcam_model3_Packet1(uvd, 0x0083, 0x00fd);
3417 ibmcam_model3_Packet1(uvd, 0x0086, 0x000b);
3418 ibmcam_model3_Packet1(uvd, 0x0087, 0x000b);
3419 ibmcam_model3_Packet1(uvd, 0x007e, 0x000e);
3420 ibmcam_model3_Packet1(uvd, 0x0096, 0x00a0); /* Red gain */
3421 ibmcam_model3_Packet1(uvd, 0x0097, 0x0096); /* Blue gain */
3422 ibmcam_model3_Packet1(uvd, 0x0098, 0x000b);
3423
3424 switch (uvd->videosize) {
3425 case VIDEOSIZE_160x120:
3426 ibmcam_veio(uvd, 0, 0x0002, 0x0106);
3427 ibmcam_veio(uvd, 0, 0x0008, 0x0107);
3428 ibmcam_veio(uvd, 0, f_rate, 0x0111); /* Frame rate */
3429 ibmcam_model3_Packet1(uvd, 0x001f, 0x0000); /* Same */
3430 ibmcam_model3_Packet1(uvd, 0x0039, 0x001f); /* Same */
3431 ibmcam_model3_Packet1(uvd, 0x003b, 0x003c); /* Same */
3432 ibmcam_model3_Packet1(uvd, 0x0040, 0x000a);
3433 ibmcam_model3_Packet1(uvd, 0x0051, 0x000a);
3434 break;
3435 case VIDEOSIZE_320x240:
3436 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
3437 ibmcam_veio(uvd, 0, 0x0062, 0x0107);
3438 ibmcam_veio(uvd, 0, f_rate, 0x0111); /* Frame rate */
3439 ibmcam_model3_Packet1(uvd, 0x001f, 0x0000); /* Same */
3440 ibmcam_model3_Packet1(uvd, 0x0039, 0x001f); /* Same */
3441 ibmcam_model3_Packet1(uvd, 0x003b, 0x003c); /* Same */
3442 ibmcam_model3_Packet1(uvd, 0x0040, 0x0008);
3443 ibmcam_model3_Packet1(uvd, 0x0051, 0x000b);
3444 break;
3445 case VIDEOSIZE_640x480:
3446 ibmcam_veio(uvd, 0, 0x0002, 0x0106); /* Adjustments */
3447 ibmcam_veio(uvd, 0, 0x00b4, 0x0107); /* Adjustments */
3448 ibmcam_veio(uvd, 0, f_rate, 0x0111); /* Frame rate */
3449 ibmcam_model3_Packet1(uvd, 0x001f, 0x0002); /* !Same */
3450 ibmcam_model3_Packet1(uvd, 0x0039, 0x003e); /* !Same */
3451 ibmcam_model3_Packet1(uvd, 0x0040, 0x0008);
3452 ibmcam_model3_Packet1(uvd, 0x0051, 0x000a);
3453 break;
3454 }
3455
3456 /* 01.01.08 - Added for RCA video in support -LO */
3457 if(init_model3_input) {
3458 if (debug > 0)
3459 info("Setting input to RCA.");
3460 for (i=0; i < (sizeof(initData)/sizeof(initData[0])); i++) {
3461 ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index);
3462 }
3463 }
3464
3465 ibmcam_veio(uvd, 0, 0x0001, 0x0114);
3466 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
3467 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
3468}
3469
3470/*
3471 * ibmcam_video_stop()
3472 *
3473 * This code tells camera to stop streaming. The interface remains
3474 * configured and bandwidth - claimed.
3475 */
3476static void ibmcam_video_stop(struct uvd *uvd)
3477{
3478 switch (IBMCAM_T(uvd)->camera_model) {
3479 case IBMCAM_MODEL_1:
3480 ibmcam_veio(uvd, 0, 0x00, 0x010c);
3481 ibmcam_veio(uvd, 0, 0x00, 0x010c);
3482 ibmcam_veio(uvd, 0, 0x01, 0x0114);
3483 ibmcam_veio(uvd, 0, 0xc0, 0x010c);
3484 ibmcam_veio(uvd, 0, 0x00, 0x010c);
3485 ibmcam_send_FF_04_02(uvd);
3486 ibmcam_veio(uvd, 1, 0x00, 0x0100);
3487 ibmcam_veio(uvd, 0, 0x81, 0x0100); /* LED Off */
3488 break;
3489 case IBMCAM_MODEL_2:
3490case IBMCAM_MODEL_4:
3491 ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop the camera */
3492
3493 ibmcam_model2_Packet1(uvd, 0x0030, 0x0004);
3494
3495 ibmcam_veio(uvd, 0, 0x0080, 0x0100); /* LED Off */
3496 ibmcam_veio(uvd, 0, 0x0020, 0x0111);
3497 ibmcam_veio(uvd, 0, 0x00a0, 0x0111);
3498
3499 ibmcam_model2_Packet1(uvd, 0x0030, 0x0002);
3500
3501 ibmcam_veio(uvd, 0, 0x0020, 0x0111);
3502 ibmcam_veio(uvd, 0, 0x0000, 0x0112);
3503 break;
3504 case IBMCAM_MODEL_3:
3505#if 1
3506 ibmcam_veio(uvd, 0, 0x0000, 0x010c);
3507
3508 /* Here we are supposed to select video interface alt. setting 0 */
3509 ibmcam_veio(uvd, 0, 0x0006, 0x012c);
3510
3511 ibmcam_model3_Packet1(uvd, 0x0046, 0x0000);
3512
3513 ibmcam_veio(uvd, 1, 0x0000, 0x0116);
3514 ibmcam_veio(uvd, 0, 0x0064, 0x0116);
3515 ibmcam_veio(uvd, 1, 0x0000, 0x0115);
3516 ibmcam_veio(uvd, 0, 0x0003, 0x0115);
3517 ibmcam_veio(uvd, 0, 0x0008, 0x0123);
3518 ibmcam_veio(uvd, 0, 0x0000, 0x0117);
3519 ibmcam_veio(uvd, 0, 0x0000, 0x0112);
3520 ibmcam_veio(uvd, 0, 0x0080, 0x0100);
3521 IBMCAM_T(uvd)->initialized = 0;
3522#endif
3523 break;
3524 } /* switch */
3525}
3526
3527/*
3528 * ibmcam_reinit_iso()
3529 *
3530 * This procedure sends couple of commands to the camera and then
3531 * resets the video pipe. This sequence was observed to reinit the
3532 * camera or, at least, to initiate ISO data stream.
3533 *
3534 * History:
3535 * 1/2/00 Created.
3536 */
3537static void ibmcam_reinit_iso(struct uvd *uvd, int do_stop)
3538{
3539 switch (IBMCAM_T(uvd)->camera_model) {
3540 case IBMCAM_MODEL_1:
3541 if (do_stop)
3542 ibmcam_video_stop(uvd);
3543 ibmcam_veio(uvd, 0, 0x0001, 0x0114);
3544 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
3545 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
3546 ibmcam_model1_setup_after_video_if(uvd);
3547 break;
3548 case IBMCAM_MODEL_2:
3549 ibmcam_model2_setup_after_video_if(uvd);
3550 break;
3551 case IBMCAM_MODEL_3:
3552 ibmcam_video_stop(uvd);
3553 ibmcam_model3_setup_after_video_if(uvd);
3554 break;
3555 case IBMCAM_MODEL_4:
3556 ibmcam_model4_setup_after_video_if(uvd);
3557 break;
3558 }
3559}
3560
3561static void ibmcam_video_start(struct uvd *uvd)
3562{
3563 ibmcam_change_lighting_conditions(uvd);
3564 ibmcam_set_sharpness(uvd);
3565 ibmcam_reinit_iso(uvd, 0);
3566}
3567
3568/*
3569 * Return negative code on failure, 0 on success.
3570 */
3571static int ibmcam_setup_on_open(struct uvd *uvd)
3572{
3573 int setup_ok = 0; /* Success by default */
3574 /* Send init sequence only once, it's large! */
3575 if (!IBMCAM_T(uvd)->initialized) { /* FIXME rename */
3576 switch (IBMCAM_T(uvd)->camera_model) {
3577 case IBMCAM_MODEL_1:
3578 setup_ok = ibmcam_model1_setup(uvd);
3579 break;
3580 case IBMCAM_MODEL_2:
3581 setup_ok = ibmcam_model2_setup(uvd);
3582 break;
3583 case IBMCAM_MODEL_3:
3584 case IBMCAM_MODEL_4:
3585 /* We do all setup when Isoc stream is requested */
3586 break;
3587 }
3588 IBMCAM_T(uvd)->initialized = (setup_ok != 0);
3589 }
3590 return setup_ok;
3591}
3592
3593static void ibmcam_configure_video(struct uvd *uvd)
3594{
3595 if (uvd == NULL)
3596 return;
3597
3598 RESTRICT_TO_RANGE(init_brightness, 0, 255);
3599 RESTRICT_TO_RANGE(init_contrast, 0, 255);
3600 RESTRICT_TO_RANGE(init_color, 0, 255);
3601 RESTRICT_TO_RANGE(init_hue, 0, 255);
3602 RESTRICT_TO_RANGE(hue_correction, 0, 255);
3603
3604 memset(&uvd->vpic, 0, sizeof(uvd->vpic));
3605 memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
3606
3607 uvd->vpic.colour = init_color << 8;
3608 uvd->vpic.hue = init_hue << 8;
3609 uvd->vpic.brightness = init_brightness << 8;
3610 uvd->vpic.contrast = init_contrast << 8;
3611 uvd->vpic.whiteness = 105 << 8; /* This one isn't used */
3612 uvd->vpic.depth = 24;
3613 uvd->vpic.palette = VIDEO_PALETTE_RGB24;
3614
3615 memset(&uvd->vcap, 0, sizeof(uvd->vcap));
3616 strcpy(uvd->vcap.name, "IBM USB Camera");
3617 uvd->vcap.type = VID_TYPE_CAPTURE;
3618 uvd->vcap.channels = 1;
3619 uvd->vcap.audios = 0;
3620 uvd->vcap.maxwidth = VIDEOSIZE_X(uvd->canvas);
3621 uvd->vcap.maxheight = VIDEOSIZE_Y(uvd->canvas);
3622 uvd->vcap.minwidth = min_canvasWidth;
3623 uvd->vcap.minheight = min_canvasHeight;
3624
3625 memset(&uvd->vchan, 0, sizeof(uvd->vchan));
3626 uvd->vchan.flags = 0;
3627 uvd->vchan.tuners = 0;
3628 uvd->vchan.channel = 0;
3629 uvd->vchan.type = VIDEO_TYPE_CAMERA;
3630 strcpy(uvd->vchan.name, "Camera");
3631}
3632
3633/*
3634 * ibmcam_probe()
3635 *
3636 * This procedure queries device descriptor and accepts the interface
3637 * if it looks like IBM C-it camera.
3638 *
3639 * History:
3640 * 22-Jan-2000 Moved camera init code to ibmcam_open()
3641 * 27=Jan-2000 Changed to use static structures, added locking.
3642 * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
3643 * 03-Jul-2000 Fixed endianness bug.
3644 * 12-Nov-2000 Reworked to comply with new probe() signature.
3645 * 23-Jan-2001 Added compatibility with 2.2.x kernels.
3646 */
3647static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id *devid)
3648{
3649 struct usb_device *dev = interface_to_usbdev(intf);
3650 struct uvd *uvd = NULL;
3651 int ix, i, nas, model=0, canvasX=0, canvasY=0;
3652 int actInterface=-1, inactInterface=-1, maxPS=0;
3653 __u8 ifnum = intf->altsetting->desc.bInterfaceNumber;
3654 unsigned char video_ep = 0;
3655
3656 if (debug >= 1)
3657 info("ibmcam_probe(%p,%u.)", intf, ifnum);
3658
3659 /* We don't handle multi-config cameras */
3660 if (dev->descriptor.bNumConfigurations != 1)
3661 return -ENODEV;
3662
3663 /* Check the version/revision */
3664 switch (le16_to_cpu(dev->descriptor.bcdDevice)) {
3665 case 0x0002:
3666 if (ifnum != 2)
3667 return -ENODEV;
3668 model = IBMCAM_MODEL_1;
3669 break;
3670 case 0x030A:
3671 if (ifnum != 0)
3672 return -ENODEV;
3673 if ((le16_to_cpu(dev->descriptor.idProduct) == NETCAM_PRODUCT_ID) ||
3674 (le16_to_cpu(dev->descriptor.idProduct) == VEO_800D_PRODUCT_ID))
3675 model = IBMCAM_MODEL_4;
3676 else
3677 model = IBMCAM_MODEL_2;
3678 break;
3679 case 0x0301:
3680 if (ifnum != 0)
3681 return -ENODEV;
3682 model = IBMCAM_MODEL_3;
3683 break;
3684 default:
3685 err("IBM camera with revision 0x%04x is not supported.",
3686 le16_to_cpu(dev->descriptor.bcdDevice));
3687 return -ENODEV;
3688 }
3689
3690 /* Print detailed info on what we found so far */
3691 do {
3692 char *brand = NULL;
3693 switch (le16_to_cpu(dev->descriptor.idProduct)) {
3694 case NETCAM_PRODUCT_ID:
3695 brand = "IBM NetCamera";
3696 break;
3697 case VEO_800C_PRODUCT_ID:
3698 brand = "Veo Stingray [800C]";
3699 break;
3700 case VEO_800D_PRODUCT_ID:
3701 brand = "Veo Stingray [800D]";
3702 break;
3703 case IBMCAM_PRODUCT_ID:
3704 default:
3705 brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */
3706 break;
3707 }
3708 info("%s USB camera found (model %d, rev. 0x%04x)",
3709 brand, model, le16_to_cpu(dev->descriptor.bcdDevice));
3710 } while (0);
3711
3712 /* Validate found interface: must have one ISO endpoint */
3713 nas = intf->num_altsetting;
3714 if (debug > 0)
3715 info("Number of alternate settings=%d.", nas);
3716 if (nas < 2) {
3717 err("Too few alternate settings for this camera!");
3718 return -ENODEV;
3719 }
3720 /* Validate all alternate settings */
3721 for (ix=0; ix < nas; ix++) {
3722 const struct usb_host_interface *interface;
3723 const struct usb_endpoint_descriptor *endpoint;
3724
3725 interface = &intf->altsetting[ix];
3726 i = interface->desc.bAlternateSetting;
3727 if (interface->desc.bNumEndpoints != 1) {
3728 err("Interface %d. has %u. endpoints!",
3729 ifnum, (unsigned)(interface->desc.bNumEndpoints));
3730 return -ENODEV;
3731 }
3732 endpoint = &interface->endpoint[0].desc;
3733 if (video_ep == 0)
3734 video_ep = endpoint->bEndpointAddress;
3735 else if (video_ep != endpoint->bEndpointAddress) {
3736 err("Alternate settings have different endpoint addresses!");
3737 return -ENODEV;
3738 }
3739 if ((endpoint->bmAttributes & 0x03) != 0x01) {
3740 err("Interface %d. has non-ISO endpoint!", ifnum);
3741 return -ENODEV;
3742 }
3743 if ((endpoint->bEndpointAddress & 0x80) == 0) {
3744 err("Interface %d. has ISO OUT endpoint!", ifnum);
3745 return -ENODEV;
3746 }
3747 if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
3748 if (inactInterface < 0)
3749 inactInterface = i;
3750 else {
3751 err("More than one inactive alt. setting!");
3752 return -ENODEV;
3753 }
3754 } else {
3755 if (actInterface < 0) {
3756 actInterface = i;
3757 maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
3758 if (debug > 0)
3759 info("Active setting=%d. maxPS=%d.", i, maxPS);
3760 } else
3761 err("More than one active alt. setting! Ignoring #%d.", i);
3762 }
3763 }
3764 if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) {
3765 err("Failed to recognize the camera!");
3766 return -ENODEV;
3767 }
3768
3769 /* Validate options */
3770 switch (model) {
3771 case IBMCAM_MODEL_1:
3772 RESTRICT_TO_RANGE(lighting, 0, 2);
3773 RESTRICT_TO_RANGE(size, SIZE_128x96, SIZE_352x288);
3774 if (framerate < 0)
3775 framerate = 2;
3776 canvasX = 352;
3777 canvasY = 288;
3778 break;
3779 case IBMCAM_MODEL_2:
3780 RESTRICT_TO_RANGE(lighting, 0, 15);
3781 RESTRICT_TO_RANGE(size, SIZE_176x144, SIZE_352x240);
3782 if (framerate < 0)
3783 framerate = 2;
3784 canvasX = 352;
3785 canvasY = 240;
3786 break;
3787 case IBMCAM_MODEL_3:
3788 RESTRICT_TO_RANGE(lighting, 0, 15); /* FIXME */
3789 switch (size) {
3790 case SIZE_160x120:
3791 canvasX = 160;
3792 canvasY = 120;
3793 if (framerate < 0)
3794 framerate = 2;
3795 RESTRICT_TO_RANGE(framerate, 0, 5);
3796 break;
3797 default:
3798 info("IBM camera: using 320x240");
3799 size = SIZE_320x240;
3800 /* No break here */
3801 case SIZE_320x240:
3802 canvasX = 320;
3803 canvasY = 240;
3804 if (framerate < 0)
3805 framerate = 3;
3806 RESTRICT_TO_RANGE(framerate, 0, 5);
3807 break;
3808 case SIZE_640x480:
3809 canvasX = 640;
3810 canvasY = 480;
3811 framerate = 0; /* Slowest, and maybe even that is too fast */
3812 break;
3813 }
3814 break;
3815 case IBMCAM_MODEL_4:
3816 RESTRICT_TO_RANGE(lighting, 0, 2);
3817 switch (size) {
3818 case SIZE_128x96:
3819 canvasX = 128;
3820 canvasY = 96;
3821 break;
3822 case SIZE_160x120:
3823 canvasX = 160;
3824 canvasY = 120;
3825 break;
3826 default:
3827 info("IBM NetCamera: using 176x144");
3828 size = SIZE_176x144;
3829 /* No break here */
3830 case SIZE_176x144:
3831 canvasX = 176;
3832 canvasY = 144;
3833 break;
3834 case SIZE_320x240:
3835 canvasX = 320;
3836 canvasY = 240;
3837 break;
3838 case SIZE_352x288:
3839 canvasX = 352;
3840 canvasY = 288;
3841 break;
3842 }
3843 break;
3844 default:
3845 err("IBM camera: Model %d. not supported!", model);
3846 return -ENODEV;
3847 }
3848
3849 uvd = usbvideo_AllocateDevice(cams);
3850 if (uvd != NULL) {
3851 /* Here uvd is a fully allocated uvd object */
3852 uvd->flags = flags;
3853 uvd->debug = debug;
3854 uvd->dev = dev;
3855 uvd->iface = ifnum;
3856 uvd->ifaceAltInactive = inactInterface;
3857 uvd->ifaceAltActive = actInterface;
3858 uvd->video_endp = video_ep;
3859 uvd->iso_packet_len = maxPS;
3860 uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
3861 uvd->defaultPalette = VIDEO_PALETTE_RGB24;
3862 uvd->canvas = VIDEOSIZE(canvasX, canvasY);
3863 uvd->videosize = ibmcam_size_to_videosize(size);
3864
3865 /* Initialize ibmcam-specific data */
3866 assert(IBMCAM_T(uvd) != NULL);
3867 IBMCAM_T(uvd)->camera_model = model;
3868 IBMCAM_T(uvd)->initialized = 0;
3869
3870 ibmcam_configure_video(uvd);
3871
3872 i = usbvideo_RegisterVideoDevice(uvd);
3873 if (i != 0) {
3874 err("usbvideo_RegisterVideoDevice() failed.");
3875 uvd = NULL;
3876 }
3877 }
3878 usb_set_intfdata (intf, uvd);
3879 return 0;
3880}
3881
3882
3883static struct usb_device_id id_table[] = {
3884 { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0002, 0x0002) }, /* Model 1 */
3885 { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */
3886 { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0301, 0x0301) }, /* Model 3 */
3887 { USB_DEVICE_VER(IBMCAM_VENDOR_ID, NETCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */
3888 { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800C_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */
3889 { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800D_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */
3890 { } /* Terminating entry */
3891};
3892
3893/*
3894 * ibmcam_init()
3895 *
3896 * This code is run to initialize the driver.
3897 *
3898 * History:
3899 * 1/27/00 Reworked to use statically allocated ibmcam structures.
3900 * 21/10/00 Completely redesigned to use usbvideo services.
3901 */
3902static int __init ibmcam_init(void)
3903{
3904 struct usbvideo_cb cbTbl;
3905 memset(&cbTbl, 0, sizeof(cbTbl));
3906 cbTbl.probe = ibmcam_probe;
3907 cbTbl.setupOnOpen = ibmcam_setup_on_open;
3908 cbTbl.videoStart = ibmcam_video_start;
3909 cbTbl.videoStop = ibmcam_video_stop;
3910 cbTbl.processData = ibmcam_ProcessIsocData;
3911 cbTbl.postProcess = usbvideo_DeinterlaceFrame;
3912 cbTbl.adjustPicture = ibmcam_adjust_picture;
3913 cbTbl.getFPS = ibmcam_calculate_fps;
3914 return usbvideo_register(
3915 &cams,
3916 MAX_IBMCAM,
3917 sizeof(ibmcam_t),
3918 "ibmcam",
3919 &cbTbl,
3920 THIS_MODULE,
3921 id_table);
3922}
3923
3924static void __exit ibmcam_cleanup(void)
3925{
3926 usbvideo_Deregister(&cams);
3927}
3928
3929MODULE_DEVICE_TABLE(usb, id_table);
3930
3931module_init(ibmcam_init);
3932module_exit(ibmcam_cleanup);
diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c
new file mode 100644
index 000000000000..08521a2b4f3d
--- /dev/null
+++ b/drivers/usb/media/konicawc.c
@@ -0,0 +1,947 @@
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/input.h>
19
20#include "usbvideo.h"
21
22#define MAX_BRIGHTNESS 108
23#define MAX_CONTRAST 108
24#define MAX_SATURATION 108
25#define MAX_SHARPNESS 108
26#define MAX_WHITEBAL 372
27#define MAX_SPEED 6
28
29
30#define MAX_CAMERAS 1
31
32#define DRIVER_VERSION "v1.4"
33#define DRIVER_DESC "Konica Webcam driver"
34
35enum ctrl_req {
36 SetWhitebal = 0x01,
37 SetBrightness = 0x02,
38 SetSharpness = 0x03,
39 SetContrast = 0x04,
40 SetSaturation = 0x05,
41};
42
43
44enum frame_sizes {
45 SIZE_160X120 = 0,
46 SIZE_160X136 = 1,
47 SIZE_176X144 = 2,
48 SIZE_320X240 = 3,
49
50};
51
52#define MAX_FRAME_SIZE SIZE_320X240
53
54static struct usbvideo *cams;
55
56#ifdef CONFIG_USB_DEBUG
57static int debug;
58#define DEBUG(n, format, arg...) \
59 if (n <= debug) { \
60 printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \
61 }
62#else
63#define DEBUG(n, arg...)
64static const int debug = 0;
65#endif
66
67
68/* Some default values for initial camera settings,
69 can be set by modprobe */
70
71static int size;
72static int speed = 6; /* Speed (fps) 0 (slowest) to 6 (fastest) */
73static int brightness = MAX_BRIGHTNESS/2;
74static int contrast = MAX_CONTRAST/2;
75static int saturation = MAX_SATURATION/2;
76static int sharpness = MAX_SHARPNESS/2;
77static int whitebal = 3*(MAX_WHITEBAL/4);
78
79static int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 };
80
81/* These FPS speeds are from the windows config box. They are
82 * indexed on size (0-2) and speed (0-6). Divide by 3 to get the
83 * real fps.
84 */
85
86static int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 },
87 { 24, 40, 48, 60, 72, 80, 100 },
88 { 18, 30, 36, 45, 54, 60, 75 },
89 { 6, 10, 12, 15, 18, 21, 25 } };
90
91struct cam_size {
92 u16 width;
93 u16 height;
94 u8 cmd;
95};
96
97static struct cam_size camera_sizes[] = { { 160, 120, 0x7 },
98 { 160, 136, 0xa },
99 { 176, 144, 0x4 },
100 { 320, 240, 0x5 } };
101
102struct konicawc {
103 u8 brightness; /* camera uses 0 - 9, x11 for real value */
104 u8 contrast; /* as above */
105 u8 saturation; /* as above */
106 u8 sharpness; /* as above */
107 u8 white_bal; /* 0 - 33, x11 for real value */
108 u8 speed; /* Stored as 0 - 6, used as index in spd_to_* (above) */
109 u8 size; /* Frame Size */
110 int height;
111 int width;
112 struct urb *sts_urb[USBVIDEO_NUMSBUF];
113 u8 sts_buf[USBVIDEO_NUMSBUF][FRAMES_PER_DESC];
114 struct urb *last_data_urb;
115 int lastframe;
116 int cur_frame_size; /* number of bytes in current frame size */
117 int maxline; /* number of lines per frame */
118 int yplanesz; /* Number of bytes in the Y plane */
119 unsigned int buttonsts:1;
120#ifdef CONFIG_INPUT
121 struct input_dev input;
122 char input_physname[64];
123#endif
124};
125
126
127#define konicawc_set_misc(uvd, req, value, index) konicawc_ctrl_msg(uvd, USB_DIR_OUT, req, value, index, NULL, 0)
128#define konicawc_get_misc(uvd, req, value, index, buf, sz) konicawc_ctrl_msg(uvd, USB_DIR_IN, req, value, index, buf, sz)
129#define konicawc_set_value(uvd, value, index) konicawc_ctrl_msg(uvd, USB_DIR_OUT, 2, value, index, NULL, 0)
130
131
132static int konicawc_ctrl_msg(struct uvd *uvd, u8 dir, u8 request, u16 value, u16 index, void *buf, int len)
133{
134 int retval = usb_control_msg(uvd->dev,
135 dir ? usb_rcvctrlpipe(uvd->dev, 0) : usb_sndctrlpipe(uvd->dev, 0),
136 request, 0x40 | dir, value, index, buf, len, 1000);
137 return retval < 0 ? retval : 0;
138}
139
140
141static inline void konicawc_camera_on(struct uvd *uvd)
142{
143 DEBUG(0, "camera on");
144 konicawc_set_misc(uvd, 0x2, 1, 0x0b);
145}
146
147
148static inline void konicawc_camera_off(struct uvd *uvd)
149{
150 DEBUG(0, "camera off");
151 konicawc_set_misc(uvd, 0x2, 0, 0x0b);
152}
153
154
155static void konicawc_set_camera_size(struct uvd *uvd)
156{
157 struct konicawc *cam = (struct konicawc *)uvd->user_data;
158
159 konicawc_set_misc(uvd, 0x2, camera_sizes[cam->size].cmd, 0x08);
160 cam->width = camera_sizes[cam->size].width;
161 cam->height = camera_sizes[cam->size].height;
162 cam->yplanesz = cam->height * cam->width;
163 cam->cur_frame_size = (cam->yplanesz * 3) / 2;
164 cam->maxline = cam->yplanesz / 256;
165 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
166}
167
168
169static int konicawc_setup_on_open(struct uvd *uvd)
170{
171 struct konicawc *cam = (struct konicawc *)uvd->user_data;
172
173 DEBUG(1, "setting brightness to %d (%d)", cam->brightness,
174 cam->brightness * 11);
175 konicawc_set_value(uvd, cam->brightness, SetBrightness);
176 DEBUG(1, "setting white balance to %d (%d)", cam->white_bal,
177 cam->white_bal * 11);
178 konicawc_set_value(uvd, cam->white_bal, SetWhitebal);
179 DEBUG(1, "setting contrast to %d (%d)", cam->contrast,
180 cam->contrast * 11);
181 konicawc_set_value(uvd, cam->contrast, SetContrast);
182 DEBUG(1, "setting saturation to %d (%d)", cam->saturation,
183 cam->saturation * 11);
184 konicawc_set_value(uvd, cam->saturation, SetSaturation);
185 DEBUG(1, "setting sharpness to %d (%d)", cam->sharpness,
186 cam->sharpness * 11);
187 konicawc_set_value(uvd, cam->sharpness, SetSharpness);
188 konicawc_set_camera_size(uvd);
189 cam->lastframe = -2;
190 cam->buttonsts = 0;
191 return 0;
192}
193
194
195static void konicawc_adjust_picture(struct uvd *uvd)
196{
197 struct konicawc *cam = (struct konicawc *)uvd->user_data;
198
199 konicawc_camera_off(uvd);
200 DEBUG(1, "new brightness: %d", uvd->vpic.brightness);
201 uvd->vpic.brightness = (uvd->vpic.brightness > MAX_BRIGHTNESS) ? MAX_BRIGHTNESS : uvd->vpic.brightness;
202 if(cam->brightness != uvd->vpic.brightness / 11) {
203 cam->brightness = uvd->vpic.brightness / 11;
204 DEBUG(1, "setting brightness to %d (%d)", cam->brightness,
205 cam->brightness * 11);
206 konicawc_set_value(uvd, cam->brightness, SetBrightness);
207 }
208
209 DEBUG(1, "new contrast: %d", uvd->vpic.contrast);
210 uvd->vpic.contrast = (uvd->vpic.contrast > MAX_CONTRAST) ? MAX_CONTRAST : uvd->vpic.contrast;
211 if(cam->contrast != uvd->vpic.contrast / 11) {
212 cam->contrast = uvd->vpic.contrast / 11;
213 DEBUG(1, "setting contrast to %d (%d)", cam->contrast,
214 cam->contrast * 11);
215 konicawc_set_value(uvd, cam->contrast, SetContrast);
216 }
217 konicawc_camera_on(uvd);
218}
219
220
221static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct urb *stsurb)
222{
223 char *cdata;
224 int i, totlen = 0;
225 unsigned char *status = stsurb->transfer_buffer;
226 int keep = 0, discard = 0, bad = 0;
227 struct konicawc *cam = (struct konicawc *)uvd->user_data;
228
229 for (i = 0; i < dataurb->number_of_packets; i++) {
230 int button = cam->buttonsts;
231 unsigned char sts;
232 int n = dataurb->iso_frame_desc[i].actual_length;
233 int st = dataurb->iso_frame_desc[i].status;
234 cdata = dataurb->transfer_buffer +
235 dataurb->iso_frame_desc[i].offset;
236
237 /* Detect and ignore errored packets */
238 if (st < 0) {
239 DEBUG(1, "Data error: packet=%d. len=%d. status=%d.",
240 i, n, st);
241 uvd->stats.iso_err_count++;
242 continue;
243 }
244
245 /* Detect and ignore empty packets */
246 if (n <= 0) {
247 uvd->stats.iso_skip_count++;
248 continue;
249 }
250
251 /* See what the status data said about the packet */
252 sts = *(status+stsurb->iso_frame_desc[i].offset);
253
254 /* sts: 0x80-0xff: frame start with frame number (ie 0-7f)
255 * otherwise:
256 * bit 0 0: keep packet
257 * 1: drop packet (padding data)
258 *
259 * bit 4 0 button not clicked
260 * 1 button clicked
261 * button is used to `take a picture' (in software)
262 */
263
264 if(sts < 0x80) {
265 button = !!(sts & 0x40);
266 sts &= ~0x40;
267 }
268
269 /* work out the button status, but don't do
270 anything with it for now */
271
272 if(button != cam->buttonsts) {
273 DEBUG(2, "button: %sclicked", button ? "" : "un");
274 cam->buttonsts = button;
275#ifdef CONFIG_INPUT
276 input_report_key(&cam->input, BTN_0, cam->buttonsts);
277 input_sync(&cam->input);
278#endif
279 }
280
281 if(sts == 0x01) { /* drop frame */
282 discard++;
283 continue;
284 }
285
286 if((sts > 0x01) && (sts < 0x80)) {
287 info("unknown status %2.2x", sts);
288 bad++;
289 continue;
290 }
291 if(!sts && cam->lastframe == -2) {
292 DEBUG(2, "dropping frame looking for image start");
293 continue;
294 }
295
296 keep++;
297 if(sts & 0x80) { /* frame start */
298 unsigned char marker[] = { 0, 0xff, 0, 0x00 };
299
300 if(cam->lastframe == -2) {
301 DEBUG(2, "found initial image");
302 cam->lastframe = -1;
303 }
304
305 marker[3] = sts & 0x7F;
306 RingQueue_Enqueue(&uvd->dp, marker, 4);
307 totlen += 4;
308 }
309
310 totlen += n; /* Little local accounting */
311 RingQueue_Enqueue(&uvd->dp, cdata, n);
312 }
313 DEBUG(8, "finished: keep = %d discard = %d bad = %d added %d bytes",
314 keep, discard, bad, totlen);
315 return totlen;
316}
317
318
319static void resubmit_urb(struct uvd *uvd, struct urb *urb)
320{
321 int i, ret;
322 for (i = 0; i < FRAMES_PER_DESC; i++) {
323 urb->iso_frame_desc[i].status = 0;
324 }
325 urb->dev = uvd->dev;
326 urb->status = 0;
327 ret = usb_submit_urb(urb, GFP_ATOMIC);
328 DEBUG(3, "submitting urb of length %d", urb->transfer_buffer_length);
329 if(ret)
330 err("usb_submit_urb error (%d)", ret);
331
332}
333
334
335static void konicawc_isoc_irq(struct urb *urb, struct pt_regs *regs)
336{
337 struct uvd *uvd = urb->context;
338 struct konicawc *cam = (struct konicawc *)uvd->user_data;
339
340 /* We don't want to do anything if we are about to be removed! */
341 if (!CAMERA_IS_OPERATIONAL(uvd))
342 return;
343
344 if (!uvd->streaming) {
345 DEBUG(1, "Not streaming, but interrupt!");
346 return;
347 }
348
349 DEBUG(3, "got frame %d len = %d buflen =%d", urb->start_frame, urb->actual_length, urb->transfer_buffer_length);
350
351 uvd->stats.urb_count++;
352
353 if (urb->transfer_buffer_length > 32) {
354 cam->last_data_urb = urb;
355 return;
356 }
357 /* Copy the data received into ring queue */
358 if(cam->last_data_urb) {
359 int len = 0;
360 if(urb->start_frame != cam->last_data_urb->start_frame)
361 err("Lost sync on frames");
362 else if (!urb->status && !cam->last_data_urb->status)
363 len = konicawc_compress_iso(uvd, cam->last_data_urb, urb);
364
365 resubmit_urb(uvd, cam->last_data_urb);
366 resubmit_urb(uvd, urb);
367 cam->last_data_urb = NULL;
368 uvd->stats.urb_length = len;
369 uvd->stats.data_count += len;
370 if(len)
371 RingQueue_WakeUpInterruptible(&uvd->dp);
372 return;
373 }
374 return;
375}
376
377
378static int konicawc_start_data(struct uvd *uvd)
379{
380 struct usb_device *dev = uvd->dev;
381 int i, errFlag;
382 struct konicawc *cam = (struct konicawc *)uvd->user_data;
383 int pktsz;
384 struct usb_interface *intf;
385 struct usb_host_interface *interface = NULL;
386
387 intf = usb_ifnum_to_if(dev, uvd->iface);
388 if (intf)
389 interface = usb_altnum_to_altsetting(intf,
390 spd_to_iface[cam->speed]);
391 if (!interface)
392 return -ENXIO;
393 pktsz = le16_to_cpu(interface->endpoint[1].desc.wMaxPacketSize);
394 DEBUG(1, "pktsz = %d", pktsz);
395 if (!CAMERA_IS_OPERATIONAL(uvd)) {
396 err("Camera is not operational");
397 return -EFAULT;
398 }
399 uvd->curframe = -1;
400 konicawc_camera_on(uvd);
401 /* Alternate interface 1 is is the biggest frame size */
402 i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive);
403 if (i < 0) {
404 err("usb_set_interface error");
405 uvd->last_error = i;
406 return -EBUSY;
407 }
408
409 /* We double buffer the Iso lists */
410 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
411 int j, k;
412 struct urb *urb = uvd->sbuf[i].urb;
413 urb->dev = dev;
414 urb->context = uvd;
415 urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp);
416 urb->interval = 1;
417 urb->transfer_flags = URB_ISO_ASAP;
418 urb->transfer_buffer = uvd->sbuf[i].data;
419 urb->complete = konicawc_isoc_irq;
420 urb->number_of_packets = FRAMES_PER_DESC;
421 urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
422 for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
423 urb->iso_frame_desc[j].offset = k;
424 urb->iso_frame_desc[j].length = pktsz;
425 }
426
427 urb = cam->sts_urb[i];
428 urb->dev = dev;
429 urb->context = uvd;
430 urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp-1);
431 urb->interval = 1;
432 urb->transfer_flags = URB_ISO_ASAP;
433 urb->transfer_buffer = cam->sts_buf[i];
434 urb->complete = konicawc_isoc_irq;
435 urb->number_of_packets = FRAMES_PER_DESC;
436 urb->transfer_buffer_length = FRAMES_PER_DESC;
437 for (j=0; j < FRAMES_PER_DESC; j++) {
438 urb->iso_frame_desc[j].offset = j;
439 urb->iso_frame_desc[j].length = 1;
440 }
441 }
442
443 cam->last_data_urb = NULL;
444
445 /* Submit all URBs */
446 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
447 errFlag = usb_submit_urb(cam->sts_urb[i], GFP_KERNEL);
448 if (errFlag)
449 err("usb_submit_isoc(%d) ret %d", i, errFlag);
450
451 errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
452 if (errFlag)
453 err ("usb_submit_isoc(%d) ret %d", i, errFlag);
454 }
455
456 uvd->streaming = 1;
457 DEBUG(1, "streaming=1 video_endp=$%02x", uvd->video_endp);
458 return 0;
459}
460
461
462static void konicawc_stop_data(struct uvd *uvd)
463{
464 int i, j;
465 struct konicawc *cam;
466
467 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
468 return;
469
470 konicawc_camera_off(uvd);
471 uvd->streaming = 0;
472 cam = (struct konicawc *)uvd->user_data;
473 cam->last_data_urb = NULL;
474
475 /* Unschedule all of the iso td's */
476 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
477 usb_kill_urb(uvd->sbuf[i].urb);
478 usb_kill_urb(cam->sts_urb[i]);
479 }
480
481 if (!uvd->remove_pending) {
482 /* Set packet size to 0 */
483 j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive);
484 if (j < 0) {
485 err("usb_set_interface() error %d.", j);
486 uvd->last_error = j;
487 }
488 }
489}
490
491
492static void konicawc_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
493{
494 struct konicawc *cam = (struct konicawc *)uvd->user_data;
495 int maxline = cam->maxline;
496 int yplanesz = cam->yplanesz;
497
498 assert(frame != NULL);
499
500 DEBUG(5, "maxline = %d yplanesz = %d", maxline, yplanesz);
501 DEBUG(3, "Frame state = %d", frame->scanstate);
502
503 if(frame->scanstate == ScanState_Scanning) {
504 int drop = 0;
505 int curframe;
506 int fdrops = 0;
507 DEBUG(3, "Searching for marker, queue len = %d", RingQueue_GetLength(&uvd->dp));
508 while(RingQueue_GetLength(&uvd->dp) >= 4) {
509 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
510 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
511 (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
512 (RING_QUEUE_PEEK(&uvd->dp, 3) < 0x80)) {
513 curframe = RING_QUEUE_PEEK(&uvd->dp, 3);
514 if(cam->lastframe >= 0) {
515 fdrops = (0x80 + curframe - cam->lastframe) & 0x7F;
516 fdrops--;
517 if(fdrops) {
518 info("Dropped %d frames (%d -> %d)", fdrops,
519 cam->lastframe, curframe);
520 }
521 }
522 cam->lastframe = curframe;
523 frame->curline = 0;
524 frame->scanstate = ScanState_Lines;
525 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
526 break;
527 }
528 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
529 drop++;
530 }
531 if(drop)
532 DEBUG(2, "dropped %d bytes looking for new frame", drop);
533 }
534
535 if(frame->scanstate == ScanState_Scanning)
536 return;
537
538 /* Try to move data from queue into frame buffer
539 * We get data in blocks of 384 bytes made up of:
540 * 256 Y, 64 U, 64 V.
541 * This needs to be written out as a Y plane, a U plane and a V plane.
542 */
543
544 while ( frame->curline < maxline && (RingQueue_GetLength(&uvd->dp) >= 384)) {
545 /* Y */
546 RingQueue_Dequeue(&uvd->dp, frame->data + (frame->curline * 256), 256);
547 /* U */
548 RingQueue_Dequeue(&uvd->dp, frame->data + yplanesz + (frame->curline * 64), 64);
549 /* V */
550 RingQueue_Dequeue(&uvd->dp, frame->data + (5 * yplanesz)/4 + (frame->curline * 64), 64);
551 frame->seqRead_Length += 384;
552 frame->curline++;
553 }
554 /* See if we filled the frame */
555 if (frame->curline == maxline) {
556 DEBUG(5, "got whole frame");
557
558 frame->frameState = FrameState_Done_Hold;
559 frame->curline = 0;
560 uvd->curframe = -1;
561 uvd->stats.frame_num++;
562 }
563}
564
565
566static int konicawc_find_fps(int size, int fps)
567{
568 int i;
569
570 fps *= 3;
571 DEBUG(1, "konica_find_fps: size = %d fps = %d", size, fps);
572 if(fps <= spd_to_fps[size][0])
573 return 0;
574
575 if(fps >= spd_to_fps[size][MAX_SPEED])
576 return MAX_SPEED;
577
578 for(i = 0; i < MAX_SPEED; i++) {
579 if((fps >= spd_to_fps[size][i]) && (fps <= spd_to_fps[size][i+1])) {
580 DEBUG(2, "fps %d between %d and %d", fps, i, i+1);
581 if( (fps - spd_to_fps[size][i]) < (spd_to_fps[size][i+1] - fps))
582 return i;
583 else
584 return i+1;
585 }
586 }
587 return MAX_SPEED+1;
588}
589
590
591static int konicawc_set_video_mode(struct uvd *uvd, struct video_window *vw)
592{
593 struct konicawc *cam = (struct konicawc *)uvd->user_data;
594 int newspeed = cam->speed;
595 int newsize;
596 int x = vw->width;
597 int y = vw->height;
598 int fps = vw->flags;
599
600 if(x > 0 && y > 0) {
601 DEBUG(2, "trying to find size %d,%d", x, y);
602 for(newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
603 if((camera_sizes[newsize].width == x) && (camera_sizes[newsize].height == y))
604 break;
605 }
606 } else {
607 newsize = cam->size;
608 }
609
610 if(newsize > MAX_FRAME_SIZE) {
611 DEBUG(1, "couldn't find size %d,%d", x, y);
612 return -EINVAL;
613 }
614
615 if(fps > 0) {
616 DEBUG(1, "trying to set fps to %d", fps);
617 newspeed = konicawc_find_fps(newsize, fps);
618 DEBUG(1, "find_fps returned %d (%d)", newspeed, spd_to_fps[newsize][newspeed]);
619 }
620
621 if(newspeed > MAX_SPEED)
622 return -EINVAL;
623
624 DEBUG(1, "setting size to %d speed to %d", newsize, newspeed);
625 if((newsize == cam->size) && (newspeed == cam->speed)) {
626 DEBUG(1, "Nothing to do");
627 return 0;
628 }
629 DEBUG(0, "setting to %dx%d @ %d fps", camera_sizes[newsize].width,
630 camera_sizes[newsize].height, spd_to_fps[newsize][newspeed]/3);
631
632 konicawc_stop_data(uvd);
633 uvd->ifaceAltActive = spd_to_iface[newspeed];
634 DEBUG(1, "new interface = %d", uvd->ifaceAltActive);
635 cam->speed = newspeed;
636
637 if(cam->size != newsize) {
638 cam->size = newsize;
639 konicawc_set_camera_size(uvd);
640 }
641
642 /* Flush the input queue and clear any current frame in progress */
643
644 RingQueue_Flush(&uvd->dp);
645 cam->lastframe = -2;
646 if(uvd->curframe != -1) {
647 uvd->frame[uvd->curframe].curline = 0;
648 uvd->frame[uvd->curframe].seqRead_Length = 0;
649 uvd->frame[uvd->curframe].seqRead_Index = 0;
650 }
651
652 konicawc_start_data(uvd);
653 return 0;
654}
655
656
657static int konicawc_calculate_fps(struct uvd *uvd)
658{
659 struct konicawc *cam = uvd->user_data;
660 return spd_to_fps[cam->size][cam->speed]/3;
661}
662
663
664static void konicawc_configure_video(struct uvd *uvd)
665{
666 struct konicawc *cam = (struct konicawc *)uvd->user_data;
667 u8 buf[2];
668
669 memset(&uvd->vpic, 0, sizeof(uvd->vpic));
670 memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
671
672 RESTRICT_TO_RANGE(brightness, 0, MAX_BRIGHTNESS);
673 RESTRICT_TO_RANGE(contrast, 0, MAX_CONTRAST);
674 RESTRICT_TO_RANGE(saturation, 0, MAX_SATURATION);
675 RESTRICT_TO_RANGE(sharpness, 0, MAX_SHARPNESS);
676 RESTRICT_TO_RANGE(whitebal, 0, MAX_WHITEBAL);
677
678 cam->brightness = brightness / 11;
679 cam->contrast = contrast / 11;
680 cam->saturation = saturation / 11;
681 cam->sharpness = sharpness / 11;
682 cam->white_bal = whitebal / 11;
683
684 uvd->vpic.colour = 108;
685 uvd->vpic.hue = 108;
686 uvd->vpic.brightness = brightness;
687 uvd->vpic.contrast = contrast;
688 uvd->vpic.whiteness = whitebal;
689 uvd->vpic.depth = 6;
690 uvd->vpic.palette = VIDEO_PALETTE_YUV420P;
691
692 memset(&uvd->vcap, 0, sizeof(uvd->vcap));
693 strcpy(uvd->vcap.name, "Konica Webcam");
694 uvd->vcap.type = VID_TYPE_CAPTURE;
695 uvd->vcap.channels = 1;
696 uvd->vcap.audios = 0;
697 uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
698 uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
699 uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
700 uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
701
702 memset(&uvd->vchan, 0, sizeof(uvd->vchan));
703 uvd->vchan.flags = 0 ;
704 uvd->vchan.tuners = 0;
705 uvd->vchan.channel = 0;
706 uvd->vchan.type = VIDEO_TYPE_CAMERA;
707 strcpy(uvd->vchan.name, "Camera");
708
709 /* Talk to device */
710 DEBUG(1, "device init");
711 if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2))
712 DEBUG(2, "3,10 -> %2.2x %2.2x", buf[0], buf[1]);
713 if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2))
714 DEBUG(2, "3,10 -> %2.2x %2.2x", buf[0], buf[1]);
715 if(konicawc_set_misc(uvd, 0x2, 0, 0xd))
716 DEBUG(2, "2,0,d failed");
717 DEBUG(1, "setting initial values");
718}
719
720
721static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id *devid)
722{
723 struct usb_device *dev = interface_to_usbdev(intf);
724 struct uvd *uvd = NULL;
725 int ix, i, nas;
726 int actInterface=-1, inactInterface=-1, maxPS=0;
727 unsigned char video_ep = 0;
728
729 DEBUG(1, "konicawc_probe(%p)", intf);
730
731 /* We don't handle multi-config cameras */
732 if (dev->descriptor.bNumConfigurations != 1)
733 return -ENODEV;
734
735 info("Konica Webcam (rev. 0x%04x)", le16_to_cpu(dev->descriptor.bcdDevice));
736 RESTRICT_TO_RANGE(speed, 0, MAX_SPEED);
737
738 /* Validate found interface: must have one ISO endpoint */
739 nas = intf->num_altsetting;
740 if (nas != 8) {
741 err("Incorrect number of alternate settings (%d) for this camera!", nas);
742 return -ENODEV;
743 }
744 /* Validate all alternate settings */
745 for (ix=0; ix < nas; ix++) {
746 const struct usb_host_interface *interface;
747 const struct usb_endpoint_descriptor *endpoint;
748
749 interface = &intf->altsetting[ix];
750 i = interface->desc.bAlternateSetting;
751 if (interface->desc.bNumEndpoints != 2) {
752 err("Interface %d. has %u. endpoints!",
753 interface->desc.bInterfaceNumber,
754 (unsigned)(interface->desc.bNumEndpoints));
755 return -ENODEV;
756 }
757 endpoint = &interface->endpoint[1].desc;
758 DEBUG(1, "found endpoint: addr: 0x%2.2x maxps = 0x%4.4x",
759 endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize));
760 if (video_ep == 0)
761 video_ep = endpoint->bEndpointAddress;
762 else if (video_ep != endpoint->bEndpointAddress) {
763 err("Alternate settings have different endpoint addresses!");
764 return -ENODEV;
765 }
766 if ((endpoint->bmAttributes & 0x03) != 0x01) {
767 err("Interface %d. has non-ISO endpoint!",
768 interface->desc.bInterfaceNumber);
769 return -ENODEV;
770 }
771 if ((endpoint->bEndpointAddress & 0x80) == 0) {
772 err("Interface %d. has ISO OUT endpoint!",
773 interface->desc.bInterfaceNumber);
774 return -ENODEV;
775 }
776 if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
777 if (inactInterface < 0)
778 inactInterface = i;
779 else {
780 err("More than one inactive alt. setting!");
781 return -ENODEV;
782 }
783 } else {
784 if (i == spd_to_iface[speed]) {
785 /* This one is the requested one */
786 actInterface = i;
787 }
788 }
789 if (le16_to_cpu(endpoint->wMaxPacketSize) > maxPS)
790 maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
791 }
792 if(actInterface == -1) {
793 err("Cant find required endpoint");
794 return -ENODEV;
795 }
796
797 DEBUG(1, "Selecting requested active setting=%d. maxPS=%d.", actInterface, maxPS);
798
799 uvd = usbvideo_AllocateDevice(cams);
800 if (uvd != NULL) {
801 struct konicawc *cam = (struct konicawc *)(uvd->user_data);
802 /* Here uvd is a fully allocated uvd object */
803 for(i = 0; i < USBVIDEO_NUMSBUF; i++) {
804 cam->sts_urb[i] = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
805 if(cam->sts_urb[i] == NULL) {
806 while(i--) {
807 usb_free_urb(cam->sts_urb[i]);
808 }
809 err("can't allocate urbs");
810 return -ENOMEM;
811 }
812 }
813 cam->speed = speed;
814 RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
815 cam->width = camera_sizes[size].width;
816 cam->height = camera_sizes[size].height;
817 cam->size = size;
818
819 uvd->flags = 0;
820 uvd->debug = debug;
821 uvd->dev = dev;
822 uvd->iface = intf->altsetting->desc.bInterfaceNumber;
823 uvd->ifaceAltInactive = inactInterface;
824 uvd->ifaceAltActive = actInterface;
825 uvd->video_endp = video_ep;
826 uvd->iso_packet_len = maxPS;
827 uvd->paletteBits = 1L << VIDEO_PALETTE_YUV420P;
828 uvd->defaultPalette = VIDEO_PALETTE_YUV420P;
829 uvd->canvas = VIDEOSIZE(320, 240);
830 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
831
832 /* Initialize konicawc specific data */
833 konicawc_configure_video(uvd);
834
835 i = usbvideo_RegisterVideoDevice(uvd);
836 uvd->max_frame_size = (320 * 240 * 3)/2;
837 if (i != 0) {
838 err("usbvideo_RegisterVideoDevice() failed.");
839 uvd = NULL;
840 }
841#ifdef CONFIG_INPUT
842 /* Register input device for button */
843 memset(&cam->input, 0, sizeof(struct input_dev));
844 cam->input.name = "Konicawc snapshot button";
845 cam->input.private = cam;
846 cam->input.evbit[0] = BIT(EV_KEY);
847 cam->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
848 cam->input.id.bustype = BUS_USB;
849 cam->input.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
850 cam->input.id.product = le16_to_cpu(dev->descriptor.idProduct);
851 cam->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
852 input_register_device(&cam->input);
853
854 usb_make_path(dev, cam->input_physname, 56);
855 strcat(cam->input_physname, "/input0");
856 cam->input.phys = cam->input_physname;
857 info("konicawc: %s on %s\n", cam->input.name, cam->input.phys);
858#endif
859 }
860
861 if (uvd) {
862 usb_set_intfdata (intf, uvd);
863 return 0;
864 }
865 return -EIO;
866}
867
868
869static void konicawc_free_uvd(struct uvd *uvd)
870{
871 int i;
872 struct konicawc *cam = (struct konicawc *)uvd->user_data;
873
874#ifdef CONFIG_INPUT
875 input_unregister_device(&cam->input);
876#endif
877 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
878 usb_free_urb(cam->sts_urb[i]);
879 cam->sts_urb[i] = NULL;
880 }
881}
882
883
884static struct usb_device_id id_table[] = {
885 { USB_DEVICE(0x04c8, 0x0720) }, /* Intel YC 76 */
886 { } /* Terminating entry */
887};
888
889
890static int __init konicawc_init(void)
891{
892 struct usbvideo_cb cbTbl;
893 info(DRIVER_DESC " " DRIVER_VERSION);
894 memset(&cbTbl, 0, sizeof(cbTbl));
895 cbTbl.probe = konicawc_probe;
896 cbTbl.setupOnOpen = konicawc_setup_on_open;
897 cbTbl.processData = konicawc_process_isoc;
898 cbTbl.getFPS = konicawc_calculate_fps;
899 cbTbl.setVideoMode = konicawc_set_video_mode;
900 cbTbl.startDataPump = konicawc_start_data;
901 cbTbl.stopDataPump = konicawc_stop_data;
902 cbTbl.adjustPicture = konicawc_adjust_picture;
903 cbTbl.userFree = konicawc_free_uvd;
904 return usbvideo_register(
905 &cams,
906 MAX_CAMERAS,
907 sizeof(struct konicawc),
908 "konicawc",
909 &cbTbl,
910 THIS_MODULE,
911 id_table);
912}
913
914
915static void __exit konicawc_cleanup(void)
916{
917 usbvideo_Deregister(&cams);
918}
919
920
921MODULE_DEVICE_TABLE(usb, id_table);
922
923MODULE_LICENSE("GPL");
924MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
925MODULE_DESCRIPTION(DRIVER_DESC);
926module_param(speed, int, 0);
927MODULE_PARM_DESC(speed, "Initial speed: 0 (slowest) - 6 (fastest)");
928module_param(size, int, 0);
929MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 160x136 2: 176x144 3: 320x240");
930module_param(brightness, int, 0);
931MODULE_PARM_DESC(brightness, "Initial brightness 0 - 108");
932module_param(contrast, int, 0);
933MODULE_PARM_DESC(contrast, "Initial contrast 0 - 108");
934module_param(saturation, int, 0);
935MODULE_PARM_DESC(saturation, "Initial saturation 0 - 108");
936module_param(sharpness, int, 0);
937MODULE_PARM_DESC(sharpness, "Initial brightness 0 - 108");
938module_param(whitebal, int, 0);
939MODULE_PARM_DESC(whitebal, "Initial white balance 0 - 363");
940
941#ifdef CONFIG_USB_DEBUG
942module_param(debug, int, S_IRUGO | S_IWUSR);
943MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
944#endif
945
946module_init(konicawc_init);
947module_exit(konicawc_cleanup);
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
new file mode 100644
index 000000000000..0fd7ffed3a98
--- /dev/null
+++ b/drivers/usb/media/ov511.c
@@ -0,0 +1,6131 @@
1/*
2 * OmniVision OV511 Camera-to-USB Bridge Driver
3 *
4 * Copyright (c) 1999-2003 Mark W. McClelland
5 * Original decompression code Copyright 1998-2000 OmniVision Technologies
6 * Many improvements by Bret Wallach <bwallac1@san.rr.com>
7 * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
8 * Snapshot code by Kevin Moore
9 * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
10 * Changes by Claudio Matsuoka <claudio@conectiva.com>
11 * Original SAA7111A code by Dave Perks <dperks@ibm.net>
12 * URB error messages from pwc driver by Nemosoft
13 * generic_ioctl() code from videodev.c by Gerd Knorr and Alan Cox
14 * Memory management (rvmalloc) code from bttv driver, by Gerd Knorr and others
15 *
16 * Based on the Linux CPiA driver written by Peter Pregler,
17 * Scott J. Bertin and Johannes Erdfelt.
18 *
19 * Please see the file: Documentation/usb/ov511.txt
20 * and the website at: http://alpha.dyndns.org/ov511
21 * for more info.
22 *
23 * This program is free software; you can redistribute it and/or modify it
24 * under the terms of the GNU General Public License as published by the
25 * Free Software Foundation; either version 2 of the License, or (at your
26 * option) any later version.
27 *
28 * This program is distributed in the hope that it will be useful, but
29 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
31 * for more details.
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software Foundation,
35 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
36 */
37
38#include <linux/config.h>
39#include <linux/module.h>
40#include <linux/init.h>
41#include <linux/vmalloc.h>
42#include <linux/slab.h>
43#include <linux/ctype.h>
44#include <linux/pagemap.h>
45#include <asm/semaphore.h>
46#include <asm/processor.h>
47#include <linux/mm.h>
48#include <linux/device.h>
49
50#if defined (__i386__)
51 #include <asm/cpufeature.h>
52#endif
53
54#include "ov511.h"
55
56/*
57 * Version Information
58 */
59#define DRIVER_VERSION "v1.64 for Linux 2.5"
60#define EMAIL "mark@alpha.dyndns.org"
61#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org> & Bret Wallach \
62 & Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \
63 <cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>"
64#define DRIVER_DESC "ov511 USB Camera Driver"
65
66#define OV511_I2C_RETRIES 3
67#define ENABLE_Y_QUANTABLE 1
68#define ENABLE_UV_QUANTABLE 1
69
70#define OV511_MAX_UNIT_VIDEO 16
71
72/* Pixel count * bytes per YUV420 pixel (1.5) */
73#define MAX_FRAME_SIZE(w, h) ((w) * (h) * 3 / 2)
74
75#define MAX_DATA_SIZE(w, h) (MAX_FRAME_SIZE(w, h) + sizeof(struct timeval))
76
77/* Max size * bytes per YUV420 pixel (1.5) + one extra isoc frame for safety */
78#define MAX_RAW_DATA_SIZE(w, h) ((w) * (h) * 3 / 2 + 1024)
79
80#define FATAL_ERROR(rc) ((rc) < 0 && (rc) != -EPERM)
81
82/**********************************************************************
83 * Module Parameters
84 * (See ov511.txt for detailed descriptions of these)
85 **********************************************************************/
86
87/* These variables (and all static globals) default to zero */
88static int autobright = 1;
89static int autogain = 1;
90static int autoexp = 1;
91static int debug;
92static int snapshot;
93static int cams = 1;
94static int compress;
95static int testpat;
96static int dumppix;
97static int led = 1;
98static int dump_bridge;
99static int dump_sensor;
100static int printph;
101static int phy = 0x1f;
102static int phuv = 0x05;
103static int pvy = 0x06;
104static int pvuv = 0x06;
105static int qhy = 0x14;
106static int qhuv = 0x03;
107static int qvy = 0x04;
108static int qvuv = 0x04;
109static int lightfreq;
110static int bandingfilter;
111static int clockdiv = -1;
112static int packetsize = -1;
113static int framedrop = -1;
114static int fastset;
115static int force_palette;
116static int backlight;
117static int unit_video[OV511_MAX_UNIT_VIDEO];
118static int remove_zeros;
119static int mirror;
120static int ov518_color;
121
122module_param(autobright, int, 0);
123MODULE_PARM_DESC(autobright, "Sensor automatically changes brightness");
124module_param(autogain, int, 0);
125MODULE_PARM_DESC(autogain, "Sensor automatically changes gain");
126module_param(autoexp, int, 0);
127MODULE_PARM_DESC(autoexp, "Sensor automatically changes exposure");
128module_param(debug, int, 0);
129MODULE_PARM_DESC(debug,
130 "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=max");
131module_param(snapshot, int, 0);
132MODULE_PARM_DESC(snapshot, "Enable snapshot mode");
133module_param(cams, int, 0);
134MODULE_PARM_DESC(cams, "Number of simultaneous cameras");
135module_param(compress, int, 0);
136MODULE_PARM_DESC(compress, "Turn on compression");
137module_param(testpat, int, 0);
138MODULE_PARM_DESC(testpat,
139 "Replace image with vertical bar testpattern (only partially working)");
140module_param(dumppix, int, 0);
141MODULE_PARM_DESC(dumppix, "Dump raw pixel data");
142module_param(led, int, 0);
143MODULE_PARM_DESC(led,
144 "LED policy (OV511+ or later). 0=off, 1=on (default), 2=auto (on when open)");
145module_param(dump_bridge, int, 0);
146MODULE_PARM_DESC(dump_bridge, "Dump the bridge registers");
147module_param(dump_sensor, int, 0);
148MODULE_PARM_DESC(dump_sensor, "Dump the sensor registers");
149module_param(printph, int, 0);
150MODULE_PARM_DESC(printph, "Print frame start/end headers");
151module_param(phy, int, 0);
152MODULE_PARM_DESC(phy, "Prediction range (horiz. Y)");
153module_param(phuv, int, 0);
154MODULE_PARM_DESC(phuv, "Prediction range (horiz. UV)");
155module_param(pvy, int, 0);
156MODULE_PARM_DESC(pvy, "Prediction range (vert. Y)");
157module_param(pvuv, int, 0);
158MODULE_PARM_DESC(pvuv, "Prediction range (vert. UV)");
159module_param(qhy, int, 0);
160MODULE_PARM_DESC(qhy, "Quantization threshold (horiz. Y)");
161module_param(qhuv, int, 0);
162MODULE_PARM_DESC(qhuv, "Quantization threshold (horiz. UV)");
163module_param(qvy, int, 0);
164MODULE_PARM_DESC(qvy, "Quantization threshold (vert. Y)");
165module_param(qvuv, int, 0);
166MODULE_PARM_DESC(qvuv, "Quantization threshold (vert. UV)");
167module_param(lightfreq, int, 0);
168MODULE_PARM_DESC(lightfreq,
169 "Light frequency. Set to 50 or 60 Hz, or zero for default settings");
170module_param(bandingfilter, int, 0);
171MODULE_PARM_DESC(bandingfilter,
172 "Enable banding filter (to reduce effects of fluorescent lighting)");
173module_param(clockdiv, int, 0);
174MODULE_PARM_DESC(clockdiv, "Force pixel clock divisor to a specific value");
175module_param(packetsize, int, 0);
176MODULE_PARM_DESC(packetsize, "Force a specific isoc packet size");
177module_param(framedrop, int, 0);
178MODULE_PARM_DESC(framedrop, "Force a specific frame drop register setting");
179module_param(fastset, int, 0);
180MODULE_PARM_DESC(fastset, "Allows picture settings to take effect immediately");
181module_param(force_palette, int, 0);
182MODULE_PARM_DESC(force_palette, "Force the palette to a specific value");
183module_param(backlight, int, 0);
184MODULE_PARM_DESC(backlight, "For objects that are lit from behind");
185static int num_uv;
186module_param_array(unit_video, int, &num_uv, 0);
187MODULE_PARM_DESC(unit_video,
188 "Force use of specific minor number(s). 0 is not allowed.");
189module_param(remove_zeros, int, 0);
190MODULE_PARM_DESC(remove_zeros,
191 "Remove zero-padding from uncompressed incoming data");
192module_param(mirror, int, 0);
193MODULE_PARM_DESC(mirror, "Reverse image horizontally");
194module_param(ov518_color, int, 0);
195MODULE_PARM_DESC(ov518_color, "Enable OV518 color (experimental)");
196
197MODULE_AUTHOR(DRIVER_AUTHOR);
198MODULE_DESCRIPTION(DRIVER_DESC);
199MODULE_LICENSE("GPL");
200
201/**********************************************************************
202 * Miscellaneous Globals
203 **********************************************************************/
204
205static struct usb_driver ov511_driver;
206
207static struct ov51x_decomp_ops *ov511_decomp_ops;
208static struct ov51x_decomp_ops *ov511_mmx_decomp_ops;
209static struct ov51x_decomp_ops *ov518_decomp_ops;
210static struct ov51x_decomp_ops *ov518_mmx_decomp_ops;
211
212/* Number of times to retry a failed I2C transaction. Increase this if you
213 * are getting "Failed to read sensor ID..." */
214static int i2c_detect_tries = 5;
215
216/* MMX support is present in kernel and CPU. Checked upon decomp module load. */
217#if defined(__i386__) || defined(__x86_64__)
218#define ov51x_mmx_available (cpu_has_mmx)
219#else
220#define ov51x_mmx_available (0)
221#endif
222
223static struct usb_device_id device_table [] = {
224 { USB_DEVICE(VEND_OMNIVISION, PROD_OV511) },
225 { USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) },
226 { USB_DEVICE(VEND_OMNIVISION, PROD_OV518) },
227 { USB_DEVICE(VEND_OMNIVISION, PROD_OV518PLUS) },
228 { USB_DEVICE(VEND_MATTEL, PROD_ME2CAM) },
229 { } /* Terminating entry */
230};
231
232MODULE_DEVICE_TABLE (usb, device_table);
233
234static unsigned char yQuanTable511[] = OV511_YQUANTABLE;
235static unsigned char uvQuanTable511[] = OV511_UVQUANTABLE;
236static unsigned char yQuanTable518[] = OV518_YQUANTABLE;
237static unsigned char uvQuanTable518[] = OV518_UVQUANTABLE;
238
239/**********************************************************************
240 * Symbolic Names
241 **********************************************************************/
242
243/* Known OV511-based cameras */
244static struct symbolic_list camlist[] = {
245 { 0, "Generic Camera (no ID)" },
246 { 1, "Mustek WCam 3X" },
247 { 3, "D-Link DSB-C300" },
248 { 4, "Generic OV511/OV7610" },
249 { 5, "Puretek PT-6007" },
250 { 6, "Lifeview USB Life TV (NTSC)" },
251 { 21, "Creative Labs WebCam 3" },
252 { 22, "Lifeview USB Life TV (PAL D/K+B/G)" },
253 { 36, "Koala-Cam" },
254 { 38, "Lifeview USB Life TV (PAL)" },
255 { 41, "Samsung Anycam MPC-M10" },
256 { 43, "Mtekvision Zeca MV402" },
257 { 46, "Suma eON" },
258 { 70, "Lifeview USB Life TV (PAL/SECAM)" },
259 { 100, "Lifeview RoboCam" },
260 { 102, "AverMedia InterCam Elite" },
261 { 112, "MediaForte MV300" }, /* or OV7110 evaluation kit */
262 { 134, "Ezonics EZCam II" },
263 { 192, "Webeye 2000B" },
264 { 253, "Alpha Vision Tech. AlphaCam SE" },
265 { -1, NULL }
266};
267
268/* Video4Linux1 Palettes */
269static struct symbolic_list v4l1_plist[] = {
270 { VIDEO_PALETTE_GREY, "GREY" },
271 { VIDEO_PALETTE_HI240, "HI240" },
272 { VIDEO_PALETTE_RGB565, "RGB565" },
273 { VIDEO_PALETTE_RGB24, "RGB24" },
274 { VIDEO_PALETTE_RGB32, "RGB32" },
275 { VIDEO_PALETTE_RGB555, "RGB555" },
276 { VIDEO_PALETTE_YUV422, "YUV422" },
277 { VIDEO_PALETTE_YUYV, "YUYV" },
278 { VIDEO_PALETTE_UYVY, "UYVY" },
279 { VIDEO_PALETTE_YUV420, "YUV420" },
280 { VIDEO_PALETTE_YUV411, "YUV411" },
281 { VIDEO_PALETTE_RAW, "RAW" },
282 { VIDEO_PALETTE_YUV422P,"YUV422P" },
283 { VIDEO_PALETTE_YUV411P,"YUV411P" },
284 { VIDEO_PALETTE_YUV420P,"YUV420P" },
285 { VIDEO_PALETTE_YUV410P,"YUV410P" },
286 { -1, NULL }
287};
288
289static struct symbolic_list brglist[] = {
290 { BRG_OV511, "OV511" },
291 { BRG_OV511PLUS, "OV511+" },
292 { BRG_OV518, "OV518" },
293 { BRG_OV518PLUS, "OV518+" },
294 { -1, NULL }
295};
296
297static struct symbolic_list senlist[] = {
298 { SEN_OV76BE, "OV76BE" },
299 { SEN_OV7610, "OV7610" },
300 { SEN_OV7620, "OV7620" },
301 { SEN_OV7620AE, "OV7620AE" },
302 { SEN_OV6620, "OV6620" },
303 { SEN_OV6630, "OV6630" },
304 { SEN_OV6630AE, "OV6630AE" },
305 { SEN_OV6630AF, "OV6630AF" },
306 { SEN_OV8600, "OV8600" },
307 { SEN_KS0127, "KS0127" },
308 { SEN_KS0127B, "KS0127B" },
309 { SEN_SAA7111A, "SAA7111A" },
310 { -1, NULL }
311};
312
313/* URB error codes: */
314static struct symbolic_list urb_errlist[] = {
315 { -ENOSR, "Buffer error (overrun)" },
316 { -EPIPE, "Stalled (device not responding)" },
317 { -EOVERFLOW, "Babble (bad cable?)" },
318 { -EPROTO, "Bit-stuff error (bad cable?)" },
319 { -EILSEQ, "CRC/Timeout" },
320 { -ETIMEDOUT, "NAK (device does not respond)" },
321 { -1, NULL }
322};
323
324/**********************************************************************
325 * Memory management
326 **********************************************************************/
327static void *
328rvmalloc(unsigned long size)
329{
330 void *mem;
331 unsigned long adr;
332
333 size = PAGE_ALIGN(size);
334 mem = vmalloc_32(size);
335 if (!mem)
336 return NULL;
337
338 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
339 adr = (unsigned long) mem;
340 while (size > 0) {
341 SetPageReserved(vmalloc_to_page((void *)adr));
342 adr += PAGE_SIZE;
343 size -= PAGE_SIZE;
344 }
345
346 return mem;
347}
348
349static void
350rvfree(void *mem, unsigned long size)
351{
352 unsigned long adr;
353
354 if (!mem)
355 return;
356
357 adr = (unsigned long) mem;
358 while ((long) size > 0) {
359 ClearPageReserved(vmalloc_to_page((void *)adr));
360 adr += PAGE_SIZE;
361 size -= PAGE_SIZE;
362 }
363 vfree(mem);
364}
365
366/**********************************************************************
367 *
368 * Register I/O
369 *
370 **********************************************************************/
371
372/* Write an OV51x register */
373static int
374reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
375{
376 int rc;
377
378 PDEBUG(5, "0x%02X:0x%02X", reg, value);
379
380 down(&ov->cbuf_lock);
381 ov->cbuf[0] = value;
382 rc = usb_control_msg(ov->dev,
383 usb_sndctrlpipe(ov->dev, 0),
384 (ov->bclass == BCL_OV518)?1:2 /* REG_IO */,
385 USB_TYPE_VENDOR | USB_RECIP_DEVICE,
386 0, (__u16)reg, &ov->cbuf[0], 1, 1000);
387 up(&ov->cbuf_lock);
388
389 if (rc < 0)
390 err("reg write: error %d: %s", rc, symbolic(urb_errlist, rc));
391
392 return rc;
393}
394
395/* Read from an OV51x register */
396/* returns: negative is error, pos or zero is data */
397static int
398reg_r(struct usb_ov511 *ov, unsigned char reg)
399{
400 int rc;
401
402 down(&ov->cbuf_lock);
403 rc = usb_control_msg(ov->dev,
404 usb_rcvctrlpipe(ov->dev, 0),
405 (ov->bclass == BCL_OV518)?1:3 /* REG_IO */,
406 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
407 0, (__u16)reg, &ov->cbuf[0], 1, 1000);
408
409 if (rc < 0) {
410 err("reg read: error %d: %s", rc, symbolic(urb_errlist, rc));
411 } else {
412 rc = ov->cbuf[0];
413 PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]);
414 }
415
416 up(&ov->cbuf_lock);
417
418 return rc;
419}
420
421/*
422 * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
423 * the same position as 1's in "mask" are cleared and set to "value". Bits
424 * that are in the same position as 0's in "mask" are preserved, regardless
425 * of their respective state in "value".
426 */
427static int
428reg_w_mask(struct usb_ov511 *ov,
429 unsigned char reg,
430 unsigned char value,
431 unsigned char mask)
432{
433 int ret;
434 unsigned char oldval, newval;
435
436 ret = reg_r(ov, reg);
437 if (ret < 0)
438 return ret;
439
440 oldval = (unsigned char) ret;
441 oldval &= (~mask); /* Clear the masked bits */
442 value &= mask; /* Enforce mask on value */
443 newval = oldval | value; /* Set the desired bits */
444
445 return (reg_w(ov, reg, newval));
446}
447
448/*
449 * Writes multiple (n) byte value to a single register. Only valid with certain
450 * registers (0x30 and 0xc4 - 0xce).
451 */
452static int
453ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n)
454{
455 int rc;
456
457 PDEBUG(5, "0x%02X:%7d, n=%d", reg, val, n);
458
459 down(&ov->cbuf_lock);
460
461 *((__le32 *)ov->cbuf) = __cpu_to_le32(val);
462
463 rc = usb_control_msg(ov->dev,
464 usb_sndctrlpipe(ov->dev, 0),
465 1 /* REG_IO */,
466 USB_TYPE_VENDOR | USB_RECIP_DEVICE,
467 0, (__u16)reg, ov->cbuf, n, 1000);
468 up(&ov->cbuf_lock);
469
470 if (rc < 0)
471 err("reg write multiple: error %d: %s", rc,
472 symbolic(urb_errlist, rc));
473
474 return rc;
475}
476
477static int
478ov511_upload_quan_tables(struct usb_ov511 *ov)
479{
480 unsigned char *pYTable = yQuanTable511;
481 unsigned char *pUVTable = uvQuanTable511;
482 unsigned char val0, val1;
483 int i, rc, reg = R511_COMP_LUT_BEGIN;
484
485 PDEBUG(4, "Uploading quantization tables");
486
487 for (i = 0; i < OV511_QUANTABLESIZE / 2; i++) {
488 if (ENABLE_Y_QUANTABLE) {
489 val0 = *pYTable++;
490 val1 = *pYTable++;
491 val0 &= 0x0f;
492 val1 &= 0x0f;
493 val0 |= val1 << 4;
494 rc = reg_w(ov, reg, val0);
495 if (rc < 0)
496 return rc;
497 }
498
499 if (ENABLE_UV_QUANTABLE) {
500 val0 = *pUVTable++;
501 val1 = *pUVTable++;
502 val0 &= 0x0f;
503 val1 &= 0x0f;
504 val0 |= val1 << 4;
505 rc = reg_w(ov, reg + OV511_QUANTABLESIZE/2, val0);
506 if (rc < 0)
507 return rc;
508 }
509
510 reg++;
511 }
512
513 return 0;
514}
515
516/* OV518 quantization tables are 8x4 (instead of 8x8) */
517static int
518ov518_upload_quan_tables(struct usb_ov511 *ov)
519{
520 unsigned char *pYTable = yQuanTable518;
521 unsigned char *pUVTable = uvQuanTable518;
522 unsigned char val0, val1;
523 int i, rc, reg = R511_COMP_LUT_BEGIN;
524
525 PDEBUG(4, "Uploading quantization tables");
526
527 for (i = 0; i < OV518_QUANTABLESIZE / 2; i++) {
528 if (ENABLE_Y_QUANTABLE) {
529 val0 = *pYTable++;
530 val1 = *pYTable++;
531 val0 &= 0x0f;
532 val1 &= 0x0f;
533 val0 |= val1 << 4;
534 rc = reg_w(ov, reg, val0);
535 if (rc < 0)
536 return rc;
537 }
538
539 if (ENABLE_UV_QUANTABLE) {
540 val0 = *pUVTable++;
541 val1 = *pUVTable++;
542 val0 &= 0x0f;
543 val1 &= 0x0f;
544 val0 |= val1 << 4;
545 rc = reg_w(ov, reg + OV518_QUANTABLESIZE/2, val0);
546 if (rc < 0)
547 return rc;
548 }
549
550 reg++;
551 }
552
553 return 0;
554}
555
556static int
557ov51x_reset(struct usb_ov511 *ov, unsigned char reset_type)
558{
559 int rc;
560
561 /* Setting bit 0 not allowed on 518/518Plus */
562 if (ov->bclass == BCL_OV518)
563 reset_type &= 0xfe;
564
565 PDEBUG(4, "Reset: type=0x%02X", reset_type);
566
567 rc = reg_w(ov, R51x_SYS_RESET, reset_type);
568 rc = reg_w(ov, R51x_SYS_RESET, 0);
569
570 if (rc < 0)
571 err("reset: command failed");
572
573 return rc;
574}
575
576/**********************************************************************
577 *
578 * Low-level I2C I/O functions
579 *
580 **********************************************************************/
581
582/* NOTE: Do not call this function directly!
583 * The OV518 I2C I/O procedure is different, hence, this function.
584 * This is normally only called from i2c_w(). Note that this function
585 * always succeeds regardless of whether the sensor is present and working.
586 */
587static int
588ov518_i2c_write_internal(struct usb_ov511 *ov,
589 unsigned char reg,
590 unsigned char value)
591{
592 int rc;
593
594 PDEBUG(5, "0x%02X:0x%02X", reg, value);
595
596 /* Select camera register */
597 rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
598 if (rc < 0)
599 return rc;
600
601 /* Write "value" to I2C data port of OV511 */
602 rc = reg_w(ov, R51x_I2C_DATA, value);
603 if (rc < 0)
604 return rc;
605
606 /* Initiate 3-byte write cycle */
607 rc = reg_w(ov, R518_I2C_CTL, 0x01);
608 if (rc < 0)
609 return rc;
610
611 return 0;
612}
613
614/* NOTE: Do not call this function directly! */
615static int
616ov511_i2c_write_internal(struct usb_ov511 *ov,
617 unsigned char reg,
618 unsigned char value)
619{
620 int rc, retries;
621
622 PDEBUG(5, "0x%02X:0x%02X", reg, value);
623
624 /* Three byte write cycle */
625 for (retries = OV511_I2C_RETRIES; ; ) {
626 /* Select camera register */
627 rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
628 if (rc < 0)
629 break;
630
631 /* Write "value" to I2C data port of OV511 */
632 rc = reg_w(ov, R51x_I2C_DATA, value);
633 if (rc < 0)
634 break;
635
636 /* Initiate 3-byte write cycle */
637 rc = reg_w(ov, R511_I2C_CTL, 0x01);
638 if (rc < 0)
639 break;
640
641 /* Retry until idle */
642 do
643 rc = reg_r(ov, R511_I2C_CTL);
644 while (rc > 0 && ((rc&1) == 0));
645 if (rc < 0)
646 break;
647
648 /* Ack? */
649 if ((rc&2) == 0) {
650 rc = 0;
651 break;
652 }
653#if 0
654 /* I2C abort */
655 reg_w(ov, R511_I2C_CTL, 0x10);
656#endif
657 if (--retries < 0) {
658 err("i2c write retries exhausted");
659 rc = -1;
660 break;
661 }
662 }
663
664 return rc;
665}
666
667/* NOTE: Do not call this function directly!
668 * The OV518 I2C I/O procedure is different, hence, this function.
669 * This is normally only called from i2c_r(). Note that this function
670 * always succeeds regardless of whether the sensor is present and working.
671 */
672static int
673ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
674{
675 int rc, value;
676
677 /* Select camera register */
678 rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
679 if (rc < 0)
680 return rc;
681
682 /* Initiate 2-byte write cycle */
683 rc = reg_w(ov, R518_I2C_CTL, 0x03);
684 if (rc < 0)
685 return rc;
686
687 /* Initiate 2-byte read cycle */
688 rc = reg_w(ov, R518_I2C_CTL, 0x05);
689 if (rc < 0)
690 return rc;
691
692 value = reg_r(ov, R51x_I2C_DATA);
693
694 PDEBUG(5, "0x%02X:0x%02X", reg, value);
695
696 return value;
697}
698
699/* NOTE: Do not call this function directly!
700 * returns: negative is error, pos or zero is data */
701static int
702ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
703{
704 int rc, value, retries;
705
706 /* Two byte write cycle */
707 for (retries = OV511_I2C_RETRIES; ; ) {
708 /* Select camera register */
709 rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
710 if (rc < 0)
711 return rc;
712
713 /* Initiate 2-byte write cycle */
714 rc = reg_w(ov, R511_I2C_CTL, 0x03);
715 if (rc < 0)
716 return rc;
717
718 /* Retry until idle */
719 do
720 rc = reg_r(ov, R511_I2C_CTL);
721 while (rc > 0 && ((rc&1) == 0));
722 if (rc < 0)
723 return rc;
724
725 if ((rc&2) == 0) /* Ack? */
726 break;
727
728 /* I2C abort */
729 reg_w(ov, R511_I2C_CTL, 0x10);
730
731 if (--retries < 0) {
732 err("i2c write retries exhausted");
733 return -1;
734 }
735 }
736
737 /* Two byte read cycle */
738 for (retries = OV511_I2C_RETRIES; ; ) {
739 /* Initiate 2-byte read cycle */
740 rc = reg_w(ov, R511_I2C_CTL, 0x05);
741 if (rc < 0)
742 return rc;
743
744 /* Retry until idle */
745 do
746 rc = reg_r(ov, R511_I2C_CTL);
747 while (rc > 0 && ((rc&1) == 0));
748 if (rc < 0)
749 return rc;
750
751 if ((rc&2) == 0) /* Ack? */
752 break;
753
754 /* I2C abort */
755 rc = reg_w(ov, R511_I2C_CTL, 0x10);
756 if (rc < 0)
757 return rc;
758
759 if (--retries < 0) {
760 err("i2c read retries exhausted");
761 return -1;
762 }
763 }
764
765 value = reg_r(ov, R51x_I2C_DATA);
766
767 PDEBUG(5, "0x%02X:0x%02X", reg, value);
768
769 /* This is needed to make i2c_w() work */
770 rc = reg_w(ov, R511_I2C_CTL, 0x05);
771 if (rc < 0)
772 return rc;
773
774 return value;
775}
776
777/* returns: negative is error, pos or zero is data */
778static int
779i2c_r(struct usb_ov511 *ov, unsigned char reg)
780{
781 int rc;
782
783 down(&ov->i2c_lock);
784
785 if (ov->bclass == BCL_OV518)
786 rc = ov518_i2c_read_internal(ov, reg);
787 else
788 rc = ov511_i2c_read_internal(ov, reg);
789
790 up(&ov->i2c_lock);
791
792 return rc;
793}
794
795static int
796i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
797{
798 int rc;
799
800 down(&ov->i2c_lock);
801
802 if (ov->bclass == BCL_OV518)
803 rc = ov518_i2c_write_internal(ov, reg, value);
804 else
805 rc = ov511_i2c_write_internal(ov, reg, value);
806
807 up(&ov->i2c_lock);
808
809 return rc;
810}
811
812/* Do not call this function directly! */
813static int
814ov51x_i2c_write_mask_internal(struct usb_ov511 *ov,
815 unsigned char reg,
816 unsigned char value,
817 unsigned char mask)
818{
819 int rc;
820 unsigned char oldval, newval;
821
822 if (mask == 0xff) {
823 newval = value;
824 } else {
825 if (ov->bclass == BCL_OV518)
826 rc = ov518_i2c_read_internal(ov, reg);
827 else
828 rc = ov511_i2c_read_internal(ov, reg);
829 if (rc < 0)
830 return rc;
831
832 oldval = (unsigned char) rc;
833 oldval &= (~mask); /* Clear the masked bits */
834 value &= mask; /* Enforce mask on value */
835 newval = oldval | value; /* Set the desired bits */
836 }
837
838 if (ov->bclass == BCL_OV518)
839 return (ov518_i2c_write_internal(ov, reg, newval));
840 else
841 return (ov511_i2c_write_internal(ov, reg, newval));
842}
843
844/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
845 * the same position as 1's in "mask" are cleared and set to "value". Bits
846 * that are in the same position as 0's in "mask" are preserved, regardless
847 * of their respective state in "value".
848 */
849static int
850i2c_w_mask(struct usb_ov511 *ov,
851 unsigned char reg,
852 unsigned char value,
853 unsigned char mask)
854{
855 int rc;
856
857 down(&ov->i2c_lock);
858 rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
859 up(&ov->i2c_lock);
860
861 return rc;
862}
863
864/* Set the read and write slave IDs. The "slave" argument is the write slave,
865 * and the read slave will be set to (slave + 1). ov->i2c_lock should be held
866 * when calling this. This should not be called from outside the i2c I/O
867 * functions.
868 */
869static int
870i2c_set_slave_internal(struct usb_ov511 *ov, unsigned char slave)
871{
872 int rc;
873
874 rc = reg_w(ov, R51x_I2C_W_SID, slave);
875 if (rc < 0)
876 return rc;
877
878 rc = reg_w(ov, R51x_I2C_R_SID, slave + 1);
879 if (rc < 0)
880 return rc;
881
882 return 0;
883}
884
885/* Write to a specific I2C slave ID and register, using the specified mask */
886static int
887i2c_w_slave(struct usb_ov511 *ov,
888 unsigned char slave,
889 unsigned char reg,
890 unsigned char value,
891 unsigned char mask)
892{
893 int rc = 0;
894
895 down(&ov->i2c_lock);
896
897 /* Set new slave IDs */
898 rc = i2c_set_slave_internal(ov, slave);
899 if (rc < 0)
900 goto out;
901
902 rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
903
904out:
905 /* Restore primary IDs */
906 if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0)
907 err("Couldn't restore primary I2C slave");
908
909 up(&ov->i2c_lock);
910 return rc;
911}
912
913/* Read from a specific I2C slave ID and register */
914static int
915i2c_r_slave(struct usb_ov511 *ov,
916 unsigned char slave,
917 unsigned char reg)
918{
919 int rc;
920
921 down(&ov->i2c_lock);
922
923 /* Set new slave IDs */
924 rc = i2c_set_slave_internal(ov, slave);
925 if (rc < 0)
926 goto out;
927
928 if (ov->bclass == BCL_OV518)
929 rc = ov518_i2c_read_internal(ov, reg);
930 else
931 rc = ov511_i2c_read_internal(ov, reg);
932
933out:
934 /* Restore primary IDs */
935 if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0)
936 err("Couldn't restore primary I2C slave");
937
938 up(&ov->i2c_lock);
939 return rc;
940}
941
942/* Sets I2C read and write slave IDs. Returns <0 for error */
943static int
944ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid)
945{
946 int rc;
947
948 down(&ov->i2c_lock);
949
950 rc = i2c_set_slave_internal(ov, sid);
951 if (rc < 0)
952 goto out;
953
954 // FIXME: Is this actually necessary?
955 rc = ov51x_reset(ov, OV511_RESET_NOREGS);
956out:
957 up(&ov->i2c_lock);
958 return rc;
959}
960
961static int
962write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals)
963{
964 int rc;
965
966 while (pRegvals->bus != OV511_DONE_BUS) {
967 if (pRegvals->bus == OV511_REG_BUS) {
968 if ((rc = reg_w(ov, pRegvals->reg, pRegvals->val)) < 0)
969 return rc;
970 } else if (pRegvals->bus == OV511_I2C_BUS) {
971 if ((rc = i2c_w(ov, pRegvals->reg, pRegvals->val)) < 0)
972 return rc;
973 } else {
974 err("Bad regval array");
975 return -1;
976 }
977 pRegvals++;
978 }
979 return 0;
980}
981
982#ifdef OV511_DEBUG
983static void
984dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn)
985{
986 int i, rc;
987
988 for (i = reg1; i <= regn; i++) {
989 rc = i2c_r(ov, i);
990 info("Sensor[0x%02X] = 0x%02X", i, rc);
991 }
992}
993
994static void
995dump_i2c_regs(struct usb_ov511 *ov)
996{
997 info("I2C REGS");
998 dump_i2c_range(ov, 0x00, 0x7C);
999}
1000
1001static void
1002dump_reg_range(struct usb_ov511 *ov, int reg1, int regn)
1003{
1004 int i, rc;
1005
1006 for (i = reg1; i <= regn; i++) {
1007 rc = reg_r(ov, i);
1008 info("OV511[0x%02X] = 0x%02X", i, rc);
1009 }
1010}
1011
1012static void
1013ov511_dump_regs(struct usb_ov511 *ov)
1014{
1015 info("CAMERA INTERFACE REGS");
1016 dump_reg_range(ov, 0x10, 0x1f);
1017 info("DRAM INTERFACE REGS");
1018 dump_reg_range(ov, 0x20, 0x23);
1019 info("ISO FIFO REGS");
1020 dump_reg_range(ov, 0x30, 0x31);
1021 info("PIO REGS");
1022 dump_reg_range(ov, 0x38, 0x39);
1023 dump_reg_range(ov, 0x3e, 0x3e);
1024 info("I2C REGS");
1025 dump_reg_range(ov, 0x40, 0x49);
1026 info("SYSTEM CONTROL REGS");
1027 dump_reg_range(ov, 0x50, 0x55);
1028 dump_reg_range(ov, 0x5e, 0x5f);
1029 info("OmniCE REGS");
1030 dump_reg_range(ov, 0x70, 0x79);
1031 /* NOTE: Quantization tables are not readable. You will get the value
1032 * in reg. 0x79 for every table register */
1033 dump_reg_range(ov, 0x80, 0x9f);
1034 dump_reg_range(ov, 0xa0, 0xbf);
1035
1036}
1037
1038static void
1039ov518_dump_regs(struct usb_ov511 *ov)
1040{
1041 info("VIDEO MODE REGS");
1042 dump_reg_range(ov, 0x20, 0x2f);
1043 info("DATA PUMP AND SNAPSHOT REGS");
1044 dump_reg_range(ov, 0x30, 0x3f);
1045 info("I2C REGS");
1046 dump_reg_range(ov, 0x40, 0x4f);
1047 info("SYSTEM CONTROL AND VENDOR REGS");
1048 dump_reg_range(ov, 0x50, 0x5f);
1049 info("60 - 6F");
1050 dump_reg_range(ov, 0x60, 0x6f);
1051 info("70 - 7F");
1052 dump_reg_range(ov, 0x70, 0x7f);
1053 info("Y QUANTIZATION TABLE");
1054 dump_reg_range(ov, 0x80, 0x8f);
1055 info("UV QUANTIZATION TABLE");
1056 dump_reg_range(ov, 0x90, 0x9f);
1057 info("A0 - BF");
1058 dump_reg_range(ov, 0xa0, 0xbf);
1059 info("CBR");
1060 dump_reg_range(ov, 0xc0, 0xcf);
1061}
1062#endif
1063
1064/*****************************************************************************/
1065
1066/* Temporarily stops OV511 from functioning. Must do this before changing
1067 * registers while the camera is streaming */
1068static inline int
1069ov51x_stop(struct usb_ov511 *ov)
1070{
1071 PDEBUG(4, "stopping");
1072 ov->stopped = 1;
1073 if (ov->bclass == BCL_OV518)
1074 return (reg_w_mask(ov, R51x_SYS_RESET, 0x3a, 0x3a));
1075 else
1076 return (reg_w(ov, R51x_SYS_RESET, 0x3d));
1077}
1078
1079/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
1080 * actually stopped (for performance). */
1081static inline int
1082ov51x_restart(struct usb_ov511 *ov)
1083{
1084 if (ov->stopped) {
1085 PDEBUG(4, "restarting");
1086 ov->stopped = 0;
1087
1088 /* Reinitialize the stream */
1089 if (ov->bclass == BCL_OV518)
1090 reg_w(ov, 0x2f, 0x80);
1091
1092 return (reg_w(ov, R51x_SYS_RESET, 0x00));
1093 }
1094
1095 return 0;
1096}
1097
1098/* Sleeps until no frames are active. Returns !0 if got signal */
1099static int
1100ov51x_wait_frames_inactive(struct usb_ov511 *ov)
1101{
1102 return wait_event_interruptible(ov->wq, ov->curframe < 0);
1103}
1104
1105/* Resets the hardware snapshot button */
1106static void
1107ov51x_clear_snapshot(struct usb_ov511 *ov)
1108{
1109 if (ov->bclass == BCL_OV511) {
1110 reg_w(ov, R51x_SYS_SNAP, 0x00);
1111 reg_w(ov, R51x_SYS_SNAP, 0x02);
1112 reg_w(ov, R51x_SYS_SNAP, 0x00);
1113 } else if (ov->bclass == BCL_OV518) {
1114 warn("snapshot reset not supported yet on OV518(+)");
1115 } else {
1116 err("clear snap: invalid bridge type");
1117 }
1118}
1119
1120#if 0
1121/* Checks the status of the snapshot button. Returns 1 if it was pressed since
1122 * it was last cleared, and zero in all other cases (including errors) */
1123static int
1124ov51x_check_snapshot(struct usb_ov511 *ov)
1125{
1126 int ret, status = 0;
1127
1128 if (ov->bclass == BCL_OV511) {
1129 ret = reg_r(ov, R51x_SYS_SNAP);
1130 if (ret < 0) {
1131 err("Error checking snspshot status (%d)", ret);
1132 } else if (ret & 0x08) {
1133 status = 1;
1134 }
1135 } else if (ov->bclass == BCL_OV518) {
1136 warn("snapshot check not supported yet on OV518(+)");
1137 } else {
1138 err("check snap: invalid bridge type");
1139 }
1140
1141 return status;
1142}
1143#endif
1144
1145/* This does an initial reset of an OmniVision sensor and ensures that I2C
1146 * is synchronized. Returns <0 for failure.
1147 */
1148static int
1149init_ov_sensor(struct usb_ov511 *ov)
1150{
1151 int i, success;
1152
1153 /* Reset the sensor */
1154 if (i2c_w(ov, 0x12, 0x80) < 0)
1155 return -EIO;
1156
1157 /* Wait for it to initialize */
1158 msleep(150);
1159
1160 for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
1161 if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
1162 (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
1163 success = 1;
1164 continue;
1165 }
1166
1167 /* Reset the sensor */
1168 if (i2c_w(ov, 0x12, 0x80) < 0)
1169 return -EIO;
1170 /* Wait for it to initialize */
1171 msleep(150);
1172 /* Dummy read to sync I2C */
1173 if (i2c_r(ov, 0x00) < 0)
1174 return -EIO;
1175 }
1176
1177 if (!success)
1178 return -EIO;
1179
1180 PDEBUG(1, "I2C synced in %d attempt(s)", i);
1181
1182 return 0;
1183}
1184
1185static int
1186ov511_set_packet_size(struct usb_ov511 *ov, int size)
1187{
1188 int alt, mult;
1189
1190 if (ov51x_stop(ov) < 0)
1191 return -EIO;
1192
1193 mult = size >> 5;
1194
1195 if (ov->bridge == BRG_OV511) {
1196 if (size == 0)
1197 alt = OV511_ALT_SIZE_0;
1198 else if (size == 257)
1199 alt = OV511_ALT_SIZE_257;
1200 else if (size == 513)
1201 alt = OV511_ALT_SIZE_513;
1202 else if (size == 769)
1203 alt = OV511_ALT_SIZE_769;
1204 else if (size == 993)
1205 alt = OV511_ALT_SIZE_993;
1206 else {
1207 err("Set packet size: invalid size (%d)", size);
1208 return -EINVAL;
1209 }
1210 } else if (ov->bridge == BRG_OV511PLUS) {
1211 if (size == 0)
1212 alt = OV511PLUS_ALT_SIZE_0;
1213 else if (size == 33)
1214 alt = OV511PLUS_ALT_SIZE_33;
1215 else if (size == 129)
1216 alt = OV511PLUS_ALT_SIZE_129;
1217 else if (size == 257)
1218 alt = OV511PLUS_ALT_SIZE_257;
1219 else if (size == 385)
1220 alt = OV511PLUS_ALT_SIZE_385;
1221 else if (size == 513)
1222 alt = OV511PLUS_ALT_SIZE_513;
1223 else if (size == 769)
1224 alt = OV511PLUS_ALT_SIZE_769;
1225 else if (size == 961)
1226 alt = OV511PLUS_ALT_SIZE_961;
1227 else {
1228 err("Set packet size: invalid size (%d)", size);
1229 return -EINVAL;
1230 }
1231 } else {
1232 err("Set packet size: Invalid bridge type");
1233 return -EINVAL;
1234 }
1235
1236 PDEBUG(3, "%d, mult=%d, alt=%d", size, mult, alt);
1237
1238 if (reg_w(ov, R51x_FIFO_PSIZE, mult) < 0)
1239 return -EIO;
1240
1241 if (usb_set_interface(ov->dev, ov->iface, alt) < 0) {
1242 err("Set packet size: set interface error");
1243 return -EBUSY;
1244 }
1245
1246 if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
1247 return -EIO;
1248
1249 ov->packet_size = size;
1250
1251 if (ov51x_restart(ov) < 0)
1252 return -EIO;
1253
1254 return 0;
1255}
1256
1257/* Note: Unlike the OV511/OV511+, the size argument does NOT include the
1258 * optional packet number byte. The actual size *is* stored in ov->packet_size,
1259 * though. */
1260static int
1261ov518_set_packet_size(struct usb_ov511 *ov, int size)
1262{
1263 int alt;
1264
1265 if (ov51x_stop(ov) < 0)
1266 return -EIO;
1267
1268 if (ov->bclass == BCL_OV518) {
1269 if (size == 0)
1270 alt = OV518_ALT_SIZE_0;
1271 else if (size == 128)
1272 alt = OV518_ALT_SIZE_128;
1273 else if (size == 256)
1274 alt = OV518_ALT_SIZE_256;
1275 else if (size == 384)
1276 alt = OV518_ALT_SIZE_384;
1277 else if (size == 512)
1278 alt = OV518_ALT_SIZE_512;
1279 else if (size == 640)
1280 alt = OV518_ALT_SIZE_640;
1281 else if (size == 768)
1282 alt = OV518_ALT_SIZE_768;
1283 else if (size == 896)
1284 alt = OV518_ALT_SIZE_896;
1285 else {
1286 err("Set packet size: invalid size (%d)", size);
1287 return -EINVAL;
1288 }
1289 } else {
1290 err("Set packet size: Invalid bridge type");
1291 return -EINVAL;
1292 }
1293
1294 PDEBUG(3, "%d, alt=%d", size, alt);
1295
1296 ov->packet_size = size;
1297 if (size > 0) {
1298 /* Program ISO FIFO size reg (packet number isn't included) */
1299 ov518_reg_w32(ov, 0x30, size, 2);
1300
1301 if (ov->packet_numbering)
1302 ++ov->packet_size;
1303 }
1304
1305 if (usb_set_interface(ov->dev, ov->iface, alt) < 0) {
1306 err("Set packet size: set interface error");
1307 return -EBUSY;
1308 }
1309
1310 /* Initialize the stream */
1311 if (reg_w(ov, 0x2f, 0x80) < 0)
1312 return -EIO;
1313
1314 if (ov51x_restart(ov) < 0)
1315 return -EIO;
1316
1317 if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
1318 return -EIO;
1319
1320 return 0;
1321}
1322
1323/* Upload compression params and quantization tables. Returns 0 for success. */
1324static int
1325ov511_init_compression(struct usb_ov511 *ov)
1326{
1327 int rc = 0;
1328
1329 if (!ov->compress_inited) {
1330 reg_w(ov, 0x70, phy);
1331 reg_w(ov, 0x71, phuv);
1332 reg_w(ov, 0x72, pvy);
1333 reg_w(ov, 0x73, pvuv);
1334 reg_w(ov, 0x74, qhy);
1335 reg_w(ov, 0x75, qhuv);
1336 reg_w(ov, 0x76, qvy);
1337 reg_w(ov, 0x77, qvuv);
1338
1339 if (ov511_upload_quan_tables(ov) < 0) {
1340 err("Error uploading quantization tables");
1341 rc = -EIO;
1342 goto out;
1343 }
1344 }
1345
1346 ov->compress_inited = 1;
1347out:
1348 return rc;
1349}
1350
1351/* Upload compression params and quantization tables. Returns 0 for success. */
1352static int
1353ov518_init_compression(struct usb_ov511 *ov)
1354{
1355 int rc = 0;
1356
1357 if (!ov->compress_inited) {
1358 if (ov518_upload_quan_tables(ov) < 0) {
1359 err("Error uploading quantization tables");
1360 rc = -EIO;
1361 goto out;
1362 }
1363 }
1364
1365 ov->compress_inited = 1;
1366out:
1367 return rc;
1368}
1369
1370/* -------------------------------------------------------------------------- */
1371
1372/* Sets sensor's contrast setting to "val" */
1373static int
1374sensor_set_contrast(struct usb_ov511 *ov, unsigned short val)
1375{
1376 int rc;
1377
1378 PDEBUG(3, "%d", val);
1379
1380 if (ov->stop_during_set)
1381 if (ov51x_stop(ov) < 0)
1382 return -EIO;
1383
1384 switch (ov->sensor) {
1385 case SEN_OV7610:
1386 case SEN_OV6620:
1387 {
1388 rc = i2c_w(ov, OV7610_REG_CNT, val >> 8);
1389 if (rc < 0)
1390 goto out;
1391 break;
1392 }
1393 case SEN_OV6630:
1394 {
1395 rc = i2c_w_mask(ov, OV7610_REG_CNT, val >> 12, 0x0f);
1396 if (rc < 0)
1397 goto out;
1398 break;
1399 }
1400 case SEN_OV7620:
1401 {
1402 unsigned char ctab[] = {
1403 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
1404 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
1405 };
1406
1407 /* Use Y gamma control instead. Bit 0 enables it. */
1408 rc = i2c_w(ov, 0x64, ctab[val>>12]);
1409 if (rc < 0)
1410 goto out;
1411 break;
1412 }
1413 case SEN_SAA7111A:
1414 {
1415 rc = i2c_w(ov, 0x0b, val >> 9);
1416 if (rc < 0)
1417 goto out;
1418 break;
1419 }
1420 default:
1421 {
1422 PDEBUG(3, "Unsupported with this sensor");
1423 rc = -EPERM;
1424 goto out;
1425 }
1426 }
1427
1428 rc = 0; /* Success */
1429 ov->contrast = val;
1430out:
1431 if (ov51x_restart(ov) < 0)
1432 return -EIO;
1433
1434 return rc;
1435}
1436
1437/* Gets sensor's contrast setting */
1438static int
1439sensor_get_contrast(struct usb_ov511 *ov, unsigned short *val)
1440{
1441 int rc;
1442
1443 switch (ov->sensor) {
1444 case SEN_OV7610:
1445 case SEN_OV6620:
1446 rc = i2c_r(ov, OV7610_REG_CNT);
1447 if (rc < 0)
1448 return rc;
1449 else
1450 *val = rc << 8;
1451 break;
1452 case SEN_OV6630:
1453 rc = i2c_r(ov, OV7610_REG_CNT);
1454 if (rc < 0)
1455 return rc;
1456 else
1457 *val = rc << 12;
1458 break;
1459 case SEN_OV7620:
1460 /* Use Y gamma reg instead. Bit 0 is the enable bit. */
1461 rc = i2c_r(ov, 0x64);
1462 if (rc < 0)
1463 return rc;
1464 else
1465 *val = (rc & 0xfe) << 8;
1466 break;
1467 case SEN_SAA7111A:
1468 *val = ov->contrast;
1469 break;
1470 default:
1471 PDEBUG(3, "Unsupported with this sensor");
1472 return -EPERM;
1473 }
1474
1475 PDEBUG(3, "%d", *val);
1476 ov->contrast = *val;
1477
1478 return 0;
1479}
1480
1481/* -------------------------------------------------------------------------- */
1482
1483/* Sets sensor's brightness setting to "val" */
1484static int
1485sensor_set_brightness(struct usb_ov511 *ov, unsigned short val)
1486{
1487 int rc;
1488
1489 PDEBUG(4, "%d", val);
1490
1491 if (ov->stop_during_set)
1492 if (ov51x_stop(ov) < 0)
1493 return -EIO;
1494
1495 switch (ov->sensor) {
1496 case SEN_OV7610:
1497 case SEN_OV76BE:
1498 case SEN_OV6620:
1499 case SEN_OV6630:
1500 rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
1501 if (rc < 0)
1502 goto out;
1503 break;
1504 case SEN_OV7620:
1505 /* 7620 doesn't like manual changes when in auto mode */
1506 if (!ov->auto_brt) {
1507 rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
1508 if (rc < 0)
1509 goto out;
1510 }
1511 break;
1512 case SEN_SAA7111A:
1513 rc = i2c_w(ov, 0x0a, val >> 8);
1514 if (rc < 0)
1515 goto out;
1516 break;
1517 default:
1518 PDEBUG(3, "Unsupported with this sensor");
1519 rc = -EPERM;
1520 goto out;
1521 }
1522
1523 rc = 0; /* Success */
1524 ov->brightness = val;
1525out:
1526 if (ov51x_restart(ov) < 0)
1527 return -EIO;
1528
1529 return rc;
1530}
1531
1532/* Gets sensor's brightness setting */
1533static int
1534sensor_get_brightness(struct usb_ov511 *ov, unsigned short *val)
1535{
1536 int rc;
1537
1538 switch (ov->sensor) {
1539 case SEN_OV7610:
1540 case SEN_OV76BE:
1541 case SEN_OV7620:
1542 case SEN_OV6620:
1543 case SEN_OV6630:
1544 rc = i2c_r(ov, OV7610_REG_BRT);
1545 if (rc < 0)
1546 return rc;
1547 else
1548 *val = rc << 8;
1549 break;
1550 case SEN_SAA7111A:
1551 *val = ov->brightness;
1552 break;
1553 default:
1554 PDEBUG(3, "Unsupported with this sensor");
1555 return -EPERM;
1556 }
1557
1558 PDEBUG(3, "%d", *val);
1559 ov->brightness = *val;
1560
1561 return 0;
1562}
1563
1564/* -------------------------------------------------------------------------- */
1565
1566/* Sets sensor's saturation (color intensity) setting to "val" */
1567static int
1568sensor_set_saturation(struct usb_ov511 *ov, unsigned short val)
1569{
1570 int rc;
1571
1572 PDEBUG(3, "%d", val);
1573
1574 if (ov->stop_during_set)
1575 if (ov51x_stop(ov) < 0)
1576 return -EIO;
1577
1578 switch (ov->sensor) {
1579 case SEN_OV7610:
1580 case SEN_OV76BE:
1581 case SEN_OV6620:
1582 case SEN_OV6630:
1583 rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
1584 if (rc < 0)
1585 goto out;
1586 break;
1587 case SEN_OV7620:
1588// /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
1589// rc = ov_i2c_write(ov->dev, 0x62, (val >> 9) & 0x7e);
1590// if (rc < 0)
1591// goto out;
1592 rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
1593 if (rc < 0)
1594 goto out;
1595 break;
1596 case SEN_SAA7111A:
1597 rc = i2c_w(ov, 0x0c, val >> 9);
1598 if (rc < 0)
1599 goto out;
1600 break;
1601 default:
1602 PDEBUG(3, "Unsupported with this sensor");
1603 rc = -EPERM;
1604 goto out;
1605 }
1606
1607 rc = 0; /* Success */
1608 ov->colour = val;
1609out:
1610 if (ov51x_restart(ov) < 0)
1611 return -EIO;
1612
1613 return rc;
1614}
1615
1616/* Gets sensor's saturation (color intensity) setting */
1617static int
1618sensor_get_saturation(struct usb_ov511 *ov, unsigned short *val)
1619{
1620 int rc;
1621
1622 switch (ov->sensor) {
1623 case SEN_OV7610:
1624 case SEN_OV76BE:
1625 case SEN_OV6620:
1626 case SEN_OV6630:
1627 rc = i2c_r(ov, OV7610_REG_SAT);
1628 if (rc < 0)
1629 return rc;
1630 else
1631 *val = rc << 8;
1632 break;
1633 case SEN_OV7620:
1634// /* Use UV gamma reg instead. Bits 0 & 7 are reserved. */
1635// rc = i2c_r(ov, 0x62);
1636// if (rc < 0)
1637// return rc;
1638// else
1639// *val = (rc & 0x7e) << 9;
1640 rc = i2c_r(ov, OV7610_REG_SAT);
1641 if (rc < 0)
1642 return rc;
1643 else
1644 *val = rc << 8;
1645 break;
1646 case SEN_SAA7111A:
1647 *val = ov->colour;
1648 break;
1649 default:
1650 PDEBUG(3, "Unsupported with this sensor");
1651 return -EPERM;
1652 }
1653
1654 PDEBUG(3, "%d", *val);
1655 ov->colour = *val;
1656
1657 return 0;
1658}
1659
1660/* -------------------------------------------------------------------------- */
1661
1662/* Sets sensor's hue (red/blue balance) setting to "val" */
1663static int
1664sensor_set_hue(struct usb_ov511 *ov, unsigned short val)
1665{
1666 int rc;
1667
1668 PDEBUG(3, "%d", val);
1669
1670 if (ov->stop_during_set)
1671 if (ov51x_stop(ov) < 0)
1672 return -EIO;
1673
1674 switch (ov->sensor) {
1675 case SEN_OV7610:
1676 case SEN_OV6620:
1677 case SEN_OV6630:
1678 rc = i2c_w(ov, OV7610_REG_RED, 0xFF - (val >> 8));
1679 if (rc < 0)
1680 goto out;
1681
1682 rc = i2c_w(ov, OV7610_REG_BLUE, val >> 8);
1683 if (rc < 0)
1684 goto out;
1685 break;
1686 case SEN_OV7620:
1687// Hue control is causing problems. I will enable it once it's fixed.
1688#if 0
1689 rc = i2c_w(ov, 0x7a, (unsigned char)(val >> 8) + 0xb);
1690 if (rc < 0)
1691 goto out;
1692
1693 rc = i2c_w(ov, 0x79, (unsigned char)(val >> 8) + 0xb);
1694 if (rc < 0)
1695 goto out;
1696#endif
1697 break;
1698 case SEN_SAA7111A:
1699 rc = i2c_w(ov, 0x0d, (val + 32768) >> 8);
1700 if (rc < 0)
1701 goto out;
1702 break;
1703 default:
1704 PDEBUG(3, "Unsupported with this sensor");
1705 rc = -EPERM;
1706 goto out;
1707 }
1708
1709 rc = 0; /* Success */
1710 ov->hue = val;
1711out:
1712 if (ov51x_restart(ov) < 0)
1713 return -EIO;
1714
1715 return rc;
1716}
1717
1718/* Gets sensor's hue (red/blue balance) setting */
1719static int
1720sensor_get_hue(struct usb_ov511 *ov, unsigned short *val)
1721{
1722 int rc;
1723
1724 switch (ov->sensor) {
1725 case SEN_OV7610:
1726 case SEN_OV6620:
1727 case SEN_OV6630:
1728 rc = i2c_r(ov, OV7610_REG_BLUE);
1729 if (rc < 0)
1730 return rc;
1731 else
1732 *val = rc << 8;
1733 break;
1734 case SEN_OV7620:
1735 rc = i2c_r(ov, 0x7a);
1736 if (rc < 0)
1737 return rc;
1738 else
1739 *val = rc << 8;
1740 break;
1741 case SEN_SAA7111A:
1742 *val = ov->hue;
1743 break;
1744 default:
1745 PDEBUG(3, "Unsupported with this sensor");
1746 return -EPERM;
1747 }
1748
1749 PDEBUG(3, "%d", *val);
1750 ov->hue = *val;
1751
1752 return 0;
1753}
1754
1755/* -------------------------------------------------------------------------- */
1756
1757static int
1758sensor_set_picture(struct usb_ov511 *ov, struct video_picture *p)
1759{
1760 int rc;
1761
1762 PDEBUG(4, "sensor_set_picture");
1763
1764 ov->whiteness = p->whiteness;
1765
1766 /* Don't return error if a setting is unsupported, or rest of settings
1767 * will not be performed */
1768
1769 rc = sensor_set_contrast(ov, p->contrast);
1770 if (FATAL_ERROR(rc))
1771 return rc;
1772
1773 rc = sensor_set_brightness(ov, p->brightness);
1774 if (FATAL_ERROR(rc))
1775 return rc;
1776
1777 rc = sensor_set_saturation(ov, p->colour);
1778 if (FATAL_ERROR(rc))
1779 return rc;
1780
1781 rc = sensor_set_hue(ov, p->hue);
1782 if (FATAL_ERROR(rc))
1783 return rc;
1784
1785 return 0;
1786}
1787
1788static int
1789sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p)
1790{
1791 int rc;
1792
1793 PDEBUG(4, "sensor_get_picture");
1794
1795 /* Don't return error if a setting is unsupported, or rest of settings
1796 * will not be performed */
1797
1798 rc = sensor_get_contrast(ov, &(p->contrast));
1799 if (FATAL_ERROR(rc))
1800 return rc;
1801
1802 rc = sensor_get_brightness(ov, &(p->brightness));
1803 if (FATAL_ERROR(rc))
1804 return rc;
1805
1806 rc = sensor_get_saturation(ov, &(p->colour));
1807 if (FATAL_ERROR(rc))
1808 return rc;
1809
1810 rc = sensor_get_hue(ov, &(p->hue));
1811 if (FATAL_ERROR(rc))
1812 return rc;
1813
1814 p->whiteness = 105 << 8;
1815
1816 return 0;
1817}
1818
1819#if 0
1820// FIXME: Exposure range is only 0x00-0x7f in interlace mode
1821/* Sets current exposure for sensor. This only has an effect if auto-exposure
1822 * is off */
1823static inline int
1824sensor_set_exposure(struct usb_ov511 *ov, unsigned char val)
1825{
1826 int rc;
1827
1828 PDEBUG(3, "%d", val);
1829
1830 if (ov->stop_during_set)
1831 if (ov51x_stop(ov) < 0)
1832 return -EIO;
1833
1834 switch (ov->sensor) {
1835 case SEN_OV6620:
1836 case SEN_OV6630:
1837 case SEN_OV7610:
1838 case SEN_OV7620:
1839 case SEN_OV76BE:
1840 case SEN_OV8600:
1841 rc = i2c_w(ov, 0x10, val);
1842 if (rc < 0)
1843 goto out;
1844
1845 break;
1846 case SEN_KS0127:
1847 case SEN_KS0127B:
1848 case SEN_SAA7111A:
1849 PDEBUG(3, "Unsupported with this sensor");
1850 return -EPERM;
1851 default:
1852 err("Sensor not supported for set_exposure");
1853 return -EINVAL;
1854 }
1855
1856 rc = 0; /* Success */
1857 ov->exposure = val;
1858out:
1859 if (ov51x_restart(ov) < 0)
1860 return -EIO;
1861
1862 return rc;
1863}
1864#endif
1865
1866/* Gets current exposure level from sensor, regardless of whether it is under
1867 * manual control. */
1868static int
1869sensor_get_exposure(struct usb_ov511 *ov, unsigned char *val)
1870{
1871 int rc;
1872
1873 switch (ov->sensor) {
1874 case SEN_OV7610:
1875 case SEN_OV6620:
1876 case SEN_OV6630:
1877 case SEN_OV7620:
1878 case SEN_OV76BE:
1879 case SEN_OV8600:
1880 rc = i2c_r(ov, 0x10);
1881 if (rc < 0)
1882 return rc;
1883 else
1884 *val = rc;
1885 break;
1886 case SEN_KS0127:
1887 case SEN_KS0127B:
1888 case SEN_SAA7111A:
1889 val = NULL;
1890 PDEBUG(3, "Unsupported with this sensor");
1891 return -EPERM;
1892 default:
1893 err("Sensor not supported for get_exposure");
1894 return -EINVAL;
1895 }
1896
1897 PDEBUG(3, "%d", *val);
1898 ov->exposure = *val;
1899
1900 return 0;
1901}
1902
1903/* Turns on or off the LED. Only has an effect with OV511+/OV518(+) */
1904static void
1905ov51x_led_control(struct usb_ov511 *ov, int enable)
1906{
1907 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
1908
1909 if (ov->bridge == BRG_OV511PLUS)
1910 reg_w(ov, R511_SYS_LED_CTL, enable ? 1 : 0);
1911 else if (ov->bclass == BCL_OV518)
1912 reg_w_mask(ov, R518_GPIO_OUT, enable ? 0x02 : 0x00, 0x02);
1913
1914 return;
1915}
1916
1917/* Matches the sensor's internal frame rate to the lighting frequency.
1918 * Valid frequencies are:
1919 * 50 - 50Hz, for European and Asian lighting
1920 * 60 - 60Hz, for American lighting
1921 *
1922 * Tested with: OV7610, OV7620, OV76BE, OV6620
1923 * Unsupported: KS0127, KS0127B, SAA7111A
1924 * Returns: 0 for success
1925 */
1926static int
1927sensor_set_light_freq(struct usb_ov511 *ov, int freq)
1928{
1929 int sixty;
1930
1931 PDEBUG(4, "%d Hz", freq);
1932
1933 if (freq == 60)
1934 sixty = 1;
1935 else if (freq == 50)
1936 sixty = 0;
1937 else {
1938 err("Invalid light freq (%d Hz)", freq);
1939 return -EINVAL;
1940 }
1941
1942 switch (ov->sensor) {
1943 case SEN_OV7610:
1944 i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
1945 i2c_w(ov, 0x2b, sixty?0x00:0xac);
1946 i2c_w_mask(ov, 0x13, 0x10, 0x10);
1947 i2c_w_mask(ov, 0x13, 0x00, 0x10);
1948 break;
1949 case SEN_OV7620:
1950 case SEN_OV76BE:
1951 case SEN_OV8600:
1952 i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
1953 i2c_w(ov, 0x2b, sixty?0x00:0xac);
1954 i2c_w_mask(ov, 0x76, 0x01, 0x01);
1955 break;
1956 case SEN_OV6620:
1957 case SEN_OV6630:
1958 i2c_w(ov, 0x2b, sixty?0xa8:0x28);
1959 i2c_w(ov, 0x2a, sixty?0x84:0xa4);
1960 break;
1961 case SEN_KS0127:
1962 case SEN_KS0127B:
1963 case SEN_SAA7111A:
1964 PDEBUG(5, "Unsupported with this sensor");
1965 return -EPERM;
1966 default:
1967 err("Sensor not supported for set_light_freq");
1968 return -EINVAL;
1969 }
1970
1971 ov->lightfreq = freq;
1972
1973 return 0;
1974}
1975
1976/* If enable is true, turn on the sensor's banding filter, otherwise turn it
1977 * off. This filter tries to reduce the pattern of horizontal light/dark bands
1978 * caused by some (usually fluorescent) lighting. The light frequency must be
1979 * set either before or after enabling it with ov51x_set_light_freq().
1980 *
1981 * Tested with: OV7610, OV7620, OV76BE, OV6620.
1982 * Unsupported: KS0127, KS0127B, SAA7111A
1983 * Returns: 0 for success
1984 */
1985static int
1986sensor_set_banding_filter(struct usb_ov511 *ov, int enable)
1987{
1988 int rc;
1989
1990 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
1991
1992 if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
1993 || ov->sensor == SEN_SAA7111A) {
1994 PDEBUG(5, "Unsupported with this sensor");
1995 return -EPERM;
1996 }
1997
1998 rc = i2c_w_mask(ov, 0x2d, enable?0x04:0x00, 0x04);
1999 if (rc < 0)
2000 return rc;
2001
2002 ov->bandfilt = enable;
2003
2004 return 0;
2005}
2006
2007/* If enable is true, turn on the sensor's auto brightness control, otherwise
2008 * turn it off.
2009 *
2010 * Unsupported: KS0127, KS0127B, SAA7111A
2011 * Returns: 0 for success
2012 */
2013static int
2014sensor_set_auto_brightness(struct usb_ov511 *ov, int enable)
2015{
2016 int rc;
2017
2018 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2019
2020 if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
2021 || ov->sensor == SEN_SAA7111A) {
2022 PDEBUG(5, "Unsupported with this sensor");
2023 return -EPERM;
2024 }
2025
2026 rc = i2c_w_mask(ov, 0x2d, enable?0x10:0x00, 0x10);
2027 if (rc < 0)
2028 return rc;
2029
2030 ov->auto_brt = enable;
2031
2032 return 0;
2033}
2034
2035/* If enable is true, turn on the sensor's auto exposure control, otherwise
2036 * turn it off.
2037 *
2038 * Unsupported: KS0127, KS0127B, SAA7111A
2039 * Returns: 0 for success
2040 */
2041static int
2042sensor_set_auto_exposure(struct usb_ov511 *ov, int enable)
2043{
2044 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2045
2046 switch (ov->sensor) {
2047 case SEN_OV7610:
2048 i2c_w_mask(ov, 0x29, enable?0x00:0x80, 0x80);
2049 break;
2050 case SEN_OV6620:
2051 case SEN_OV7620:
2052 case SEN_OV76BE:
2053 case SEN_OV8600:
2054 i2c_w_mask(ov, 0x13, enable?0x01:0x00, 0x01);
2055 break;
2056 case SEN_OV6630:
2057 i2c_w_mask(ov, 0x28, enable?0x00:0x10, 0x10);
2058 break;
2059 case SEN_KS0127:
2060 case SEN_KS0127B:
2061 case SEN_SAA7111A:
2062 PDEBUG(5, "Unsupported with this sensor");
2063 return -EPERM;
2064 default:
2065 err("Sensor not supported for set_auto_exposure");
2066 return -EINVAL;
2067 }
2068
2069 ov->auto_exp = enable;
2070
2071 return 0;
2072}
2073
2074/* Modifies the sensor's exposure algorithm to allow proper exposure of objects
2075 * that are illuminated from behind.
2076 *
2077 * Tested with: OV6620, OV7620
2078 * Unsupported: OV7610, OV76BE, KS0127, KS0127B, SAA7111A
2079 * Returns: 0 for success
2080 */
2081static int
2082sensor_set_backlight(struct usb_ov511 *ov, int enable)
2083{
2084 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2085
2086 switch (ov->sensor) {
2087 case SEN_OV7620:
2088 case SEN_OV8600:
2089 i2c_w_mask(ov, 0x68, enable?0xe0:0xc0, 0xe0);
2090 i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
2091 i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
2092 break;
2093 case SEN_OV6620:
2094 i2c_w_mask(ov, 0x4e, enable?0xe0:0xc0, 0xe0);
2095 i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
2096 i2c_w_mask(ov, 0x0e, enable?0x80:0x00, 0x80);
2097 break;
2098 case SEN_OV6630:
2099 i2c_w_mask(ov, 0x4e, enable?0x80:0x60, 0xe0);
2100 i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
2101 i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
2102 break;
2103 case SEN_OV7610:
2104 case SEN_OV76BE:
2105 case SEN_KS0127:
2106 case SEN_KS0127B:
2107 case SEN_SAA7111A:
2108 PDEBUG(5, "Unsupported with this sensor");
2109 return -EPERM;
2110 default:
2111 err("Sensor not supported for set_backlight");
2112 return -EINVAL;
2113 }
2114
2115 ov->backlight = enable;
2116
2117 return 0;
2118}
2119
2120static int
2121sensor_set_mirror(struct usb_ov511 *ov, int enable)
2122{
2123 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2124
2125 switch (ov->sensor) {
2126 case SEN_OV6620:
2127 case SEN_OV6630:
2128 case SEN_OV7610:
2129 case SEN_OV7620:
2130 case SEN_OV76BE:
2131 case SEN_OV8600:
2132 i2c_w_mask(ov, 0x12, enable?0x40:0x00, 0x40);
2133 break;
2134 case SEN_KS0127:
2135 case SEN_KS0127B:
2136 case SEN_SAA7111A:
2137 PDEBUG(5, "Unsupported with this sensor");
2138 return -EPERM;
2139 default:
2140 err("Sensor not supported for set_mirror");
2141 return -EINVAL;
2142 }
2143
2144 ov->mirror = enable;
2145
2146 return 0;
2147}
2148
2149/* Returns number of bits per pixel (regardless of where they are located;
2150 * planar or not), or zero for unsupported format.
2151 */
2152static inline int
2153get_depth(int palette)
2154{
2155 switch (palette) {
2156 case VIDEO_PALETTE_GREY: return 8;
2157 case VIDEO_PALETTE_YUV420: return 12;
2158 case VIDEO_PALETTE_YUV420P: return 12; /* Planar */
2159 default: return 0; /* Invalid format */
2160 }
2161}
2162
2163/* Bytes per frame. Used by read(). Return of 0 indicates error */
2164static inline long int
2165get_frame_length(struct ov511_frame *frame)
2166{
2167 if (!frame)
2168 return 0;
2169 else
2170 return ((frame->width * frame->height
2171 * get_depth(frame->format)) >> 3);
2172}
2173
2174static int
2175mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height,
2176 int mode, int sub_flag, int qvga)
2177{
2178 int clock;
2179
2180 /******** Mode (VGA/QVGA) and sensor specific regs ********/
2181
2182 switch (ov->sensor) {
2183 case SEN_OV7610:
2184 i2c_w(ov, 0x14, qvga?0x24:0x04);
2185// FIXME: Does this improve the image quality or frame rate?
2186#if 0
2187 i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
2188 i2c_w(ov, 0x24, 0x10);
2189 i2c_w(ov, 0x25, qvga?0x40:0x8a);
2190 i2c_w(ov, 0x2f, qvga?0x30:0xb0);
2191 i2c_w(ov, 0x35, qvga?0x1c:0x9c);
2192#endif
2193 break;
2194 case SEN_OV7620:
2195// i2c_w(ov, 0x2b, 0x00);
2196 i2c_w(ov, 0x14, qvga?0xa4:0x84);
2197 i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
2198 i2c_w(ov, 0x24, qvga?0x20:0x3a);
2199 i2c_w(ov, 0x25, qvga?0x30:0x60);
2200 i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
2201 i2c_w_mask(ov, 0x67, qvga?0xf0:0x90, 0xf0);
2202 i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
2203 break;
2204 case SEN_OV76BE:
2205// i2c_w(ov, 0x2b, 0x00);
2206 i2c_w(ov, 0x14, qvga?0xa4:0x84);
2207// FIXME: Enable this once 7620AE uses 7620 initial settings
2208#if 0
2209 i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
2210 i2c_w(ov, 0x24, qvga?0x20:0x3a);
2211 i2c_w(ov, 0x25, qvga?0x30:0x60);
2212 i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
2213 i2c_w_mask(ov, 0x67, qvga?0xb0:0x90, 0xf0);
2214 i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
2215#endif
2216 break;
2217 case SEN_OV6620:
2218 i2c_w(ov, 0x14, qvga?0x24:0x04);
2219 break;
2220 case SEN_OV6630:
2221 i2c_w(ov, 0x14, qvga?0xa0:0x80);
2222 break;
2223 default:
2224 err("Invalid sensor");
2225 return -EINVAL;
2226 }
2227
2228 /******** Palette-specific regs ********/
2229
2230 if (mode == VIDEO_PALETTE_GREY) {
2231 if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) {
2232 /* these aren't valid on the OV6620/OV7620/6630? */
2233 i2c_w_mask(ov, 0x0e, 0x40, 0x40);
2234 }
2235
2236 if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518
2237 && ov518_color) {
2238 i2c_w_mask(ov, 0x12, 0x00, 0x10);
2239 i2c_w_mask(ov, 0x13, 0x00, 0x20);
2240 } else {
2241 i2c_w_mask(ov, 0x13, 0x20, 0x20);
2242 }
2243 } else {
2244 if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) {
2245 /* not valid on the OV6620/OV7620/6630? */
2246 i2c_w_mask(ov, 0x0e, 0x00, 0x40);
2247 }
2248
2249 /* The OV518 needs special treatment. Although both the OV518
2250 * and the OV6630 support a 16-bit video bus, only the 8 bit Y
2251 * bus is actually used. The UV bus is tied to ground.
2252 * Therefore, the OV6630 needs to be in 8-bit multiplexed
2253 * output mode */
2254
2255 if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518
2256 && ov518_color) {
2257 i2c_w_mask(ov, 0x12, 0x10, 0x10);
2258 i2c_w_mask(ov, 0x13, 0x20, 0x20);
2259 } else {
2260 i2c_w_mask(ov, 0x13, 0x00, 0x20);
2261 }
2262 }
2263
2264 /******** Clock programming ********/
2265
2266 /* The OV6620 needs special handling. This prevents the
2267 * severe banding that normally occurs */
2268 if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630)
2269 {
2270 /* Clock down */
2271
2272 i2c_w(ov, 0x2a, 0x04);
2273
2274 if (ov->compress) {
2275// clock = 0; /* This ensures the highest frame rate */
2276 clock = 3;
2277 } else if (clockdiv == -1) { /* If user didn't override it */
2278 clock = 3; /* Gives better exposure time */
2279 } else {
2280 clock = clockdiv;
2281 }
2282
2283 PDEBUG(4, "Setting clock divisor to %d", clock);
2284
2285 i2c_w(ov, 0x11, clock);
2286
2287 i2c_w(ov, 0x2a, 0x84);
2288 /* This next setting is critical. It seems to improve
2289 * the gain or the contrast. The "reserved" bits seem
2290 * to have some effect in this case. */
2291 i2c_w(ov, 0x2d, 0x85);
2292 }
2293 else
2294 {
2295 if (ov->compress) {
2296 clock = 1; /* This ensures the highest frame rate */
2297 } else if (clockdiv == -1) { /* If user didn't override it */
2298 /* Calculate and set the clock divisor */
2299 clock = ((sub_flag ? ov->subw * ov->subh
2300 : width * height)
2301 * (mode == VIDEO_PALETTE_GREY ? 2 : 3) / 2)
2302 / 66000;
2303 } else {
2304 clock = clockdiv;
2305 }
2306
2307 PDEBUG(4, "Setting clock divisor to %d", clock);
2308
2309 i2c_w(ov, 0x11, clock);
2310 }
2311
2312 /******** Special Features ********/
2313
2314 if (framedrop >= 0)
2315 i2c_w(ov, 0x16, framedrop);
2316
2317 /* Test Pattern */
2318 i2c_w_mask(ov, 0x12, (testpat?0x02:0x00), 0x02);
2319
2320 /* Enable auto white balance */
2321 i2c_w_mask(ov, 0x12, 0x04, 0x04);
2322
2323 // This will go away as soon as ov51x_mode_init_sensor_regs()
2324 // is fully tested.
2325 /* 7620/6620/6630? don't have register 0x35, so play it safe */
2326 if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) {
2327 if (width == 640 && height == 480)
2328 i2c_w(ov, 0x35, 0x9e);
2329 else
2330 i2c_w(ov, 0x35, 0x1e);
2331 }
2332
2333 return 0;
2334}
2335
2336static int
2337set_ov_sensor_window(struct usb_ov511 *ov, int width, int height, int mode,
2338 int sub_flag)
2339{
2340 int ret;
2341 int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize;
2342 int hoffset, voffset, hwscale = 0, vwscale = 0;
2343
2344 /* The different sensor ICs handle setting up of window differently.
2345 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!!! */
2346 switch (ov->sensor) {
2347 case SEN_OV7610:
2348 case SEN_OV76BE:
2349 hwsbase = 0x38;
2350 hwebase = 0x3a;
2351 vwsbase = vwebase = 0x05;
2352 break;
2353 case SEN_OV6620:
2354 case SEN_OV6630:
2355 hwsbase = 0x38;
2356 hwebase = 0x3a;
2357 vwsbase = 0x05;
2358 vwebase = 0x06;
2359 break;
2360 case SEN_OV7620:
2361 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
2362 hwebase = 0x2f;
2363 vwsbase = vwebase = 0x05;
2364 break;
2365 default:
2366 err("Invalid sensor");
2367 return -EINVAL;
2368 }
2369
2370 if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630) {
2371 /* Note: OV518(+) does downsample on its own) */
2372 if ((width > 176 && height > 144)
2373 || ov->bclass == BCL_OV518) { /* CIF */
2374 ret = mode_init_ov_sensor_regs(ov, width, height,
2375 mode, sub_flag, 0);
2376 if (ret < 0)
2377 return ret;
2378 hwscale = 1;
2379 vwscale = 1; /* The datasheet says 0; it's wrong */
2380 hwsize = 352;
2381 vwsize = 288;
2382 } else if (width > 176 || height > 144) {
2383 err("Illegal dimensions");
2384 return -EINVAL;
2385 } else { /* QCIF */
2386 ret = mode_init_ov_sensor_regs(ov, width, height,
2387 mode, sub_flag, 1);
2388 if (ret < 0)
2389 return ret;
2390 hwsize = 176;
2391 vwsize = 144;
2392 }
2393 } else {
2394 if (width > 320 && height > 240) { /* VGA */
2395 ret = mode_init_ov_sensor_regs(ov, width, height,
2396 mode, sub_flag, 0);
2397 if (ret < 0)
2398 return ret;
2399 hwscale = 2;
2400 vwscale = 1;
2401 hwsize = 640;
2402 vwsize = 480;
2403 } else if (width > 320 || height > 240) {
2404 err("Illegal dimensions");
2405 return -EINVAL;
2406 } else { /* QVGA */
2407 ret = mode_init_ov_sensor_regs(ov, width, height,
2408 mode, sub_flag, 1);
2409 if (ret < 0)
2410 return ret;
2411 hwscale = 1;
2412 hwsize = 320;
2413 vwsize = 240;
2414 }
2415 }
2416
2417 /* Center the window */
2418 hoffset = ((hwsize - width) / 2) >> hwscale;
2419 voffset = ((vwsize - height) / 2) >> vwscale;
2420
2421 /* FIXME! - This needs to be changed to support 160x120 and 6620!!! */
2422 if (sub_flag) {
2423 i2c_w(ov, 0x17, hwsbase+(ov->subx>>hwscale));
2424 i2c_w(ov, 0x18, hwebase+((ov->subx+ov->subw)>>hwscale));
2425 i2c_w(ov, 0x19, vwsbase+(ov->suby>>vwscale));
2426 i2c_w(ov, 0x1a, vwebase+((ov->suby+ov->subh)>>vwscale));
2427 } else {
2428 i2c_w(ov, 0x17, hwsbase + hoffset);
2429 i2c_w(ov, 0x18, hwebase + hoffset + (hwsize>>hwscale));
2430 i2c_w(ov, 0x19, vwsbase + voffset);
2431 i2c_w(ov, 0x1a, vwebase + voffset + (vwsize>>vwscale));
2432 }
2433
2434#ifdef OV511_DEBUG
2435 if (dump_sensor)
2436 dump_i2c_regs(ov);
2437#endif
2438
2439 return 0;
2440}
2441
2442/* Set up the OV511/OV511+ with the given image parameters.
2443 *
2444 * Do not put any sensor-specific code in here (including I2C I/O functions)
2445 */
2446static int
2447ov511_mode_init_regs(struct usb_ov511 *ov,
2448 int width, int height, int mode, int sub_flag)
2449{
2450 int hsegs, vsegs;
2451
2452 if (sub_flag) {
2453 width = ov->subw;
2454 height = ov->subh;
2455 }
2456
2457 PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
2458 width, height, mode, sub_flag);
2459
2460 // FIXME: This should be moved to a 7111a-specific function once
2461 // subcapture is dealt with properly
2462 if (ov->sensor == SEN_SAA7111A) {
2463 if (width == 320 && height == 240) {
2464 /* No need to do anything special */
2465 } else if (width == 640 && height == 480) {
2466 /* Set the OV511 up as 320x480, but keep the
2467 * V4L resolution as 640x480 */
2468 width = 320;
2469 } else {
2470 err("SAA7111A only allows 320x240 or 640x480");
2471 return -EINVAL;
2472 }
2473 }
2474
2475 /* Make sure width and height are a multiple of 8 */
2476 if (width % 8 || height % 8) {
2477 err("Invalid size (%d, %d) (mode = %d)", width, height, mode);
2478 return -EINVAL;
2479 }
2480
2481 if (width < ov->minwidth || height < ov->minheight) {
2482 err("Requested dimensions are too small");
2483 return -EINVAL;
2484 }
2485
2486 if (ov51x_stop(ov) < 0)
2487 return -EIO;
2488
2489 if (mode == VIDEO_PALETTE_GREY) {
2490 reg_w(ov, R511_CAM_UV_EN, 0x00);
2491 reg_w(ov, R511_SNAP_UV_EN, 0x00);
2492 reg_w(ov, R511_SNAP_OPTS, 0x01);
2493 } else {
2494 reg_w(ov, R511_CAM_UV_EN, 0x01);
2495 reg_w(ov, R511_SNAP_UV_EN, 0x01);
2496 reg_w(ov, R511_SNAP_OPTS, 0x03);
2497 }
2498
2499 /* Here I'm assuming that snapshot size == image size.
2500 * I hope that's always true. --claudio
2501 */
2502 hsegs = (width >> 3) - 1;
2503 vsegs = (height >> 3) - 1;
2504
2505 reg_w(ov, R511_CAM_PXCNT, hsegs);
2506 reg_w(ov, R511_CAM_LNCNT, vsegs);
2507 reg_w(ov, R511_CAM_PXDIV, 0x00);
2508 reg_w(ov, R511_CAM_LNDIV, 0x00);
2509
2510 /* YUV420, low pass filter on */
2511 reg_w(ov, R511_CAM_OPTS, 0x03);
2512
2513 /* Snapshot additions */
2514 reg_w(ov, R511_SNAP_PXCNT, hsegs);
2515 reg_w(ov, R511_SNAP_LNCNT, vsegs);
2516 reg_w(ov, R511_SNAP_PXDIV, 0x00);
2517 reg_w(ov, R511_SNAP_LNDIV, 0x00);
2518
2519 if (ov->compress) {
2520 /* Enable Y and UV quantization and compression */
2521 reg_w(ov, R511_COMP_EN, 0x07);
2522 reg_w(ov, R511_COMP_LUT_EN, 0x03);
2523 ov51x_reset(ov, OV511_RESET_OMNICE);
2524 }
2525
2526 if (ov51x_restart(ov) < 0)
2527 return -EIO;
2528
2529 return 0;
2530}
2531
2532/* Sets up the OV518/OV518+ with the given image parameters
2533 *
2534 * OV518 needs a completely different approach, until we can figure out what
2535 * the individual registers do. Also, only 15 FPS is supported now.
2536 *
2537 * Do not put any sensor-specific code in here (including I2C I/O functions)
2538 */
2539static int
2540ov518_mode_init_regs(struct usb_ov511 *ov,
2541 int width, int height, int mode, int sub_flag)
2542{
2543 int hsegs, vsegs, hi_res;
2544
2545 if (sub_flag) {
2546 width = ov->subw;
2547 height = ov->subh;
2548 }
2549
2550 PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
2551 width, height, mode, sub_flag);
2552
2553 if (width % 16 || height % 8) {
2554 err("Invalid size (%d, %d)", width, height);
2555 return -EINVAL;
2556 }
2557
2558 if (width < ov->minwidth || height < ov->minheight) {
2559 err("Requested dimensions are too small");
2560 return -EINVAL;
2561 }
2562
2563 if (width >= 320 && height >= 240) {
2564 hi_res = 1;
2565 } else if (width >= 320 || height >= 240) {
2566 err("Invalid width/height combination (%d, %d)", width, height);
2567 return -EINVAL;
2568 } else {
2569 hi_res = 0;
2570 }
2571
2572 if (ov51x_stop(ov) < 0)
2573 return -EIO;
2574
2575 /******** Set the mode ********/
2576
2577 reg_w(ov, 0x2b, 0);
2578 reg_w(ov, 0x2c, 0);
2579 reg_w(ov, 0x2d, 0);
2580 reg_w(ov, 0x2e, 0);
2581 reg_w(ov, 0x3b, 0);
2582 reg_w(ov, 0x3c, 0);
2583 reg_w(ov, 0x3d, 0);
2584 reg_w(ov, 0x3e, 0);
2585
2586 if (ov->bridge == BRG_OV518 && ov518_color) {
2587 /* OV518 needs U and V swapped */
2588 i2c_w_mask(ov, 0x15, 0x00, 0x01);
2589
2590 if (mode == VIDEO_PALETTE_GREY) {
2591 /* Set 16-bit input format (UV data are ignored) */
2592 reg_w_mask(ov, 0x20, 0x00, 0x08);
2593
2594 /* Set 8-bit (4:0:0) output format */
2595 reg_w_mask(ov, 0x28, 0x00, 0xf0);
2596 reg_w_mask(ov, 0x38, 0x00, 0xf0);
2597 } else {
2598 /* Set 8-bit (YVYU) input format */
2599 reg_w_mask(ov, 0x20, 0x08, 0x08);
2600
2601 /* Set 12-bit (4:2:0) output format */
2602 reg_w_mask(ov, 0x28, 0x80, 0xf0);
2603 reg_w_mask(ov, 0x38, 0x80, 0xf0);
2604 }
2605 } else {
2606 reg_w(ov, 0x28, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80);
2607 reg_w(ov, 0x38, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80);
2608 }
2609
2610 hsegs = width / 16;
2611 vsegs = height / 4;
2612
2613 reg_w(ov, 0x29, hsegs);
2614 reg_w(ov, 0x2a, vsegs);
2615
2616 reg_w(ov, 0x39, hsegs);
2617 reg_w(ov, 0x3a, vsegs);
2618
2619 /* Windows driver does this here; who knows why */
2620 reg_w(ov, 0x2f, 0x80);
2621
2622 /******** Set the framerate (to 15 FPS) ********/
2623
2624 /* Mode independent, but framerate dependent, regs */
2625 reg_w(ov, 0x51, 0x02); /* Clock divider; lower==faster */
2626 reg_w(ov, 0x22, 0x18);
2627 reg_w(ov, 0x23, 0xff);
2628
2629 if (ov->bridge == BRG_OV518PLUS)
2630 reg_w(ov, 0x21, 0x19);
2631 else
2632 reg_w(ov, 0x71, 0x19); /* Compression-related? */
2633
2634 // FIXME: Sensor-specific
2635 /* Bit 5 is what matters here. Of course, it is "reserved" */
2636 i2c_w(ov, 0x54, 0x23);
2637
2638 reg_w(ov, 0x2f, 0x80);
2639
2640 if (ov->bridge == BRG_OV518PLUS) {
2641 reg_w(ov, 0x24, 0x94);
2642 reg_w(ov, 0x25, 0x90);
2643 ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */
2644 ov518_reg_w32(ov, 0xc6, 540, 2); /* 21ch */
2645 ov518_reg_w32(ov, 0xc7, 540, 2); /* 21ch */
2646 ov518_reg_w32(ov, 0xc8, 108, 2); /* 6ch */
2647 ov518_reg_w32(ov, 0xca, 131098, 3); /* 2001ah */
2648 ov518_reg_w32(ov, 0xcb, 532, 2); /* 214h */
2649 ov518_reg_w32(ov, 0xcc, 2400, 2); /* 960h */
2650 ov518_reg_w32(ov, 0xcd, 32, 2); /* 20h */
2651 ov518_reg_w32(ov, 0xce, 608, 2); /* 260h */
2652 } else {
2653 reg_w(ov, 0x24, 0x9f);
2654 reg_w(ov, 0x25, 0x90);
2655 ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */
2656 ov518_reg_w32(ov, 0xc6, 500, 2); /* 1f4h */
2657 ov518_reg_w32(ov, 0xc7, 500, 2); /* 1f4h */
2658 ov518_reg_w32(ov, 0xc8, 142, 2); /* 8eh */
2659 ov518_reg_w32(ov, 0xca, 131098, 3); /* 2001ah */
2660 ov518_reg_w32(ov, 0xcb, 532, 2); /* 214h */
2661 ov518_reg_w32(ov, 0xcc, 2000, 2); /* 7d0h */
2662 ov518_reg_w32(ov, 0xcd, 32, 2); /* 20h */
2663 ov518_reg_w32(ov, 0xce, 608, 2); /* 260h */
2664 }
2665
2666 reg_w(ov, 0x2f, 0x80);
2667
2668 if (ov51x_restart(ov) < 0)
2669 return -EIO;
2670
2671 /* Reset it just for good measure */
2672 if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
2673 return -EIO;
2674
2675 return 0;
2676}
2677
2678/* This is a wrapper around the OV511, OV518, and sensor specific functions */
2679static int
2680mode_init_regs(struct usb_ov511 *ov,
2681 int width, int height, int mode, int sub_flag)
2682{
2683 int rc = 0;
2684
2685 if (!ov || !ov->dev)
2686 return -EFAULT;
2687
2688 if (ov->bclass == BCL_OV518) {
2689 rc = ov518_mode_init_regs(ov, width, height, mode, sub_flag);
2690 } else {
2691 rc = ov511_mode_init_regs(ov, width, height, mode, sub_flag);
2692 }
2693
2694 if (FATAL_ERROR(rc))
2695 return rc;
2696
2697 switch (ov->sensor) {
2698 case SEN_OV7610:
2699 case SEN_OV7620:
2700 case SEN_OV76BE:
2701 case SEN_OV8600:
2702 case SEN_OV6620:
2703 case SEN_OV6630:
2704 rc = set_ov_sensor_window(ov, width, height, mode, sub_flag);
2705 break;
2706 case SEN_KS0127:
2707 case SEN_KS0127B:
2708 err("KS0127-series decoders not supported yet");
2709 rc = -EINVAL;
2710 break;
2711 case SEN_SAA7111A:
2712// rc = mode_init_saa_sensor_regs(ov, width, height, mode,
2713// sub_flag);
2714
2715 PDEBUG(1, "SAA status = 0x%02X", i2c_r(ov, 0x1f));
2716 break;
2717 default:
2718 err("Unknown sensor");
2719 rc = -EINVAL;
2720 }
2721
2722 if (FATAL_ERROR(rc))
2723 return rc;
2724
2725 /* Sensor-independent settings */
2726 rc = sensor_set_auto_brightness(ov, ov->auto_brt);
2727 if (FATAL_ERROR(rc))
2728 return rc;
2729
2730 rc = sensor_set_auto_exposure(ov, ov->auto_exp);
2731 if (FATAL_ERROR(rc))
2732 return rc;
2733
2734 rc = sensor_set_banding_filter(ov, bandingfilter);
2735 if (FATAL_ERROR(rc))
2736 return rc;
2737
2738 if (ov->lightfreq) {
2739 rc = sensor_set_light_freq(ov, lightfreq);
2740 if (FATAL_ERROR(rc))
2741 return rc;
2742 }
2743
2744 rc = sensor_set_backlight(ov, ov->backlight);
2745 if (FATAL_ERROR(rc))
2746 return rc;
2747
2748 rc = sensor_set_mirror(ov, ov->mirror);
2749 if (FATAL_ERROR(rc))
2750 return rc;
2751
2752 return 0;
2753}
2754
2755/* This sets the default image parameters. This is useful for apps that use
2756 * read() and do not set these.
2757 */
2758static int
2759ov51x_set_default_params(struct usb_ov511 *ov)
2760{
2761 int i;
2762
2763 /* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used
2764 * (using read() instead). */
2765 for (i = 0; i < OV511_NUMFRAMES; i++) {
2766 ov->frame[i].width = ov->maxwidth;
2767 ov->frame[i].height = ov->maxheight;
2768 ov->frame[i].bytes_read = 0;
2769 if (force_palette)
2770 ov->frame[i].format = force_palette;
2771 else
2772 ov->frame[i].format = VIDEO_PALETTE_YUV420;
2773
2774 ov->frame[i].depth = get_depth(ov->frame[i].format);
2775 }
2776
2777 PDEBUG(3, "%dx%d, %s", ov->maxwidth, ov->maxheight,
2778 symbolic(v4l1_plist, ov->frame[0].format));
2779
2780 /* Initialize to max width/height, YUV420 or RGB24 (if supported) */
2781 if (mode_init_regs(ov, ov->maxwidth, ov->maxheight,
2782 ov->frame[0].format, 0) < 0)
2783 return -EINVAL;
2784
2785 return 0;
2786}
2787
2788/**********************************************************************
2789 *
2790 * Video decoder stuff
2791 *
2792 **********************************************************************/
2793
2794/* Set analog input port of decoder */
2795static int
2796decoder_set_input(struct usb_ov511 *ov, int input)
2797{
2798 PDEBUG(4, "port %d", input);
2799
2800 switch (ov->sensor) {
2801 case SEN_SAA7111A:
2802 {
2803 /* Select mode */
2804 i2c_w_mask(ov, 0x02, input, 0x07);
2805 /* Bypass chrominance trap for modes 4..7 */
2806 i2c_w_mask(ov, 0x09, (input > 3) ? 0x80:0x00, 0x80);
2807 break;
2808 }
2809 default:
2810 return -EINVAL;
2811 }
2812
2813 return 0;
2814}
2815
2816/* Get ASCII name of video input */
2817static int
2818decoder_get_input_name(struct usb_ov511 *ov, int input, char *name)
2819{
2820 switch (ov->sensor) {
2821 case SEN_SAA7111A:
2822 {
2823 if (input < 0 || input > 7)
2824 return -EINVAL;
2825 else if (input < 4)
2826 sprintf(name, "CVBS-%d", input);
2827 else // if (input < 8)
2828 sprintf(name, "S-Video-%d", input - 4);
2829 break;
2830 }
2831 default:
2832 sprintf(name, "%s", "Camera");
2833 }
2834
2835 return 0;
2836}
2837
2838/* Set norm (NTSC, PAL, SECAM, AUTO) */
2839static int
2840decoder_set_norm(struct usb_ov511 *ov, int norm)
2841{
2842 PDEBUG(4, "%d", norm);
2843
2844 switch (ov->sensor) {
2845 case SEN_SAA7111A:
2846 {
2847 int reg_8, reg_e;
2848
2849 if (norm == VIDEO_MODE_NTSC) {
2850 reg_8 = 0x40; /* 60 Hz */
2851 reg_e = 0x00; /* NTSC M / PAL BGHI */
2852 } else if (norm == VIDEO_MODE_PAL) {
2853 reg_8 = 0x00; /* 50 Hz */
2854 reg_e = 0x00; /* NTSC M / PAL BGHI */
2855 } else if (norm == VIDEO_MODE_AUTO) {
2856 reg_8 = 0x80; /* Auto field detect */
2857 reg_e = 0x00; /* NTSC M / PAL BGHI */
2858 } else if (norm == VIDEO_MODE_SECAM) {
2859 reg_8 = 0x00; /* 50 Hz */
2860 reg_e = 0x50; /* SECAM / PAL 4.43 */
2861 } else {
2862 return -EINVAL;
2863 }
2864
2865 i2c_w_mask(ov, 0x08, reg_8, 0xc0);
2866 i2c_w_mask(ov, 0x0e, reg_e, 0x70);
2867 break;
2868 }
2869 default:
2870 return -EINVAL;
2871 }
2872
2873 return 0;
2874}
2875
2876/**********************************************************************
2877 *
2878 * Raw data parsing
2879 *
2880 **********************************************************************/
2881
2882/* Copies a 64-byte segment at pIn to an 8x8 block at pOut. The width of the
2883 * image at pOut is specified by w.
2884 */
2885static inline void
2886make_8x8(unsigned char *pIn, unsigned char *pOut, int w)
2887{
2888 unsigned char *pOut1 = pOut;
2889 int x, y;
2890
2891 for (y = 0; y < 8; y++) {
2892 pOut1 = pOut;
2893 for (x = 0; x < 8; x++) {
2894 *pOut1++ = *pIn++;
2895 }
2896 pOut += w;
2897 }
2898}
2899
2900/*
2901 * For RAW BW (YUV 4:0:0) images, data show up in 256 byte segments.
2902 * The segments represent 4 squares of 8x8 pixels as follows:
2903 *
2904 * 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199
2905 * 8 9 ... 15 72 73 ... 79 200 201 ... 207
2906 * ... ... ...
2907 * 56 57 ... 63 120 121 ... 127 248 249 ... 255
2908 *
2909 */
2910static void
2911yuv400raw_to_yuv400p(struct ov511_frame *frame,
2912 unsigned char *pIn0, unsigned char *pOut0)
2913{
2914 int x, y;
2915 unsigned char *pIn, *pOut, *pOutLine;
2916
2917 /* Copy Y */
2918 pIn = pIn0;
2919 pOutLine = pOut0;
2920 for (y = 0; y < frame->rawheight - 1; y += 8) {
2921 pOut = pOutLine;
2922 for (x = 0; x < frame->rawwidth - 1; x += 8) {
2923 make_8x8(pIn, pOut, frame->rawwidth);
2924 pIn += 64;
2925 pOut += 8;
2926 }
2927 pOutLine += 8 * frame->rawwidth;
2928 }
2929}
2930
2931/*
2932 * For YUV 4:2:0 images, the data show up in 384 byte segments.
2933 * The first 64 bytes of each segment are U, the next 64 are V. The U and
2934 * V are arranged as follows:
2935 *
2936 * 0 1 ... 7
2937 * 8 9 ... 15
2938 * ...
2939 * 56 57 ... 63
2940 *
2941 * U and V are shipped at half resolution (1 U,V sample -> one 2x2 block).
2942 *
2943 * The next 256 bytes are full resolution Y data and represent 4 squares
2944 * of 8x8 pixels as follows:
2945 *
2946 * 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199
2947 * 8 9 ... 15 72 73 ... 79 200 201 ... 207
2948 * ... ... ...
2949 * 56 57 ... 63 120 121 ... 127 ... 248 249 ... 255
2950 *
2951 * Note that the U and V data in one segment represent a 16 x 16 pixel
2952 * area, but the Y data represent a 32 x 8 pixel area. If the width is not an
2953 * even multiple of 32, the extra 8x8 blocks within a 32x8 block belong to the
2954 * next horizontal stripe.
2955 *
2956 * If dumppix module param is set, _parse_data just dumps the incoming segments,
2957 * verbatim, in order, into the frame. When used with vidcat -f ppm -s 640x480
2958 * this puts the data on the standard output and can be analyzed with the
2959 * parseppm.c utility I wrote. That's a much faster way for figuring out how
2960 * these data are scrambled.
2961 */
2962
2963/* Converts from raw, uncompressed segments at pIn0 to a YUV420P frame at pOut0.
2964 *
2965 * FIXME: Currently only handles width and height that are multiples of 16
2966 */
2967static void
2968yuv420raw_to_yuv420p(struct ov511_frame *frame,
2969 unsigned char *pIn0, unsigned char *pOut0)
2970{
2971 int k, x, y;
2972 unsigned char *pIn, *pOut, *pOutLine;
2973 const unsigned int a = frame->rawwidth * frame->rawheight;
2974 const unsigned int w = frame->rawwidth / 2;
2975
2976 /* Copy U and V */
2977 pIn = pIn0;
2978 pOutLine = pOut0 + a;
2979 for (y = 0; y < frame->rawheight - 1; y += 16) {
2980 pOut = pOutLine;
2981 for (x = 0; x < frame->rawwidth - 1; x += 16) {
2982 make_8x8(pIn, pOut, w);
2983 make_8x8(pIn + 64, pOut + a/4, w);
2984 pIn += 384;
2985 pOut += 8;
2986 }
2987 pOutLine += 8 * w;
2988 }
2989
2990 /* Copy Y */
2991 pIn = pIn0 + 128;
2992 pOutLine = pOut0;
2993 k = 0;
2994 for (y = 0; y < frame->rawheight - 1; y += 8) {
2995 pOut = pOutLine;
2996 for (x = 0; x < frame->rawwidth - 1; x += 8) {
2997 make_8x8(pIn, pOut, frame->rawwidth);
2998 pIn += 64;
2999 pOut += 8;
3000 if ((++k) > 3) {
3001 k = 0;
3002 pIn += 128;
3003 }
3004 }
3005 pOutLine += 8 * frame->rawwidth;
3006 }
3007}
3008
3009/**********************************************************************
3010 *
3011 * Decompression
3012 *
3013 **********************************************************************/
3014
3015/* Chooses a decompression module, locks it, and sets ov->decomp_ops
3016 * accordingly. Returns -ENXIO if decompressor is not available, otherwise
3017 * returns 0 if no other error.
3018 */
3019static int
3020request_decompressor(struct usb_ov511 *ov)
3021{
3022 if (!ov)
3023 return -ENODEV;
3024
3025 if (ov->decomp_ops) {
3026 err("ERROR: Decompressor already requested!");
3027 return -EINVAL;
3028 }
3029
3030 lock_kernel();
3031
3032 /* Try to get MMX, and fall back on no-MMX if necessary */
3033 if (ov->bclass == BCL_OV511) {
3034 if (ov511_mmx_decomp_ops) {
3035 PDEBUG(3, "Using OV511 MMX decompressor");
3036 ov->decomp_ops = ov511_mmx_decomp_ops;
3037 } else if (ov511_decomp_ops) {
3038 PDEBUG(3, "Using OV511 decompressor");
3039 ov->decomp_ops = ov511_decomp_ops;
3040 } else {
3041 err("No decompressor available");
3042 }
3043 } else if (ov->bclass == BCL_OV518) {
3044 if (ov518_mmx_decomp_ops) {
3045 PDEBUG(3, "Using OV518 MMX decompressor");
3046 ov->decomp_ops = ov518_mmx_decomp_ops;
3047 } else if (ov518_decomp_ops) {
3048 PDEBUG(3, "Using OV518 decompressor");
3049 ov->decomp_ops = ov518_decomp_ops;
3050 } else {
3051 err("No decompressor available");
3052 }
3053 } else {
3054 err("Unknown bridge");
3055 }
3056
3057 if (!ov->decomp_ops)
3058 goto nosys;
3059
3060 if (!ov->decomp_ops->owner) {
3061 ov->decomp_ops = NULL;
3062 goto nosys;
3063 }
3064
3065 if (!try_module_get(ov->decomp_ops->owner))
3066 goto nosys;
3067
3068 unlock_kernel();
3069 return 0;
3070
3071 nosys:
3072 unlock_kernel();
3073 return -ENOSYS;
3074}
3075
3076/* Unlocks decompression module and nulls ov->decomp_ops. Safe to call even
3077 * if ov->decomp_ops is NULL.
3078 */
3079static void
3080release_decompressor(struct usb_ov511 *ov)
3081{
3082 int released = 0; /* Did we actually do anything? */
3083
3084 if (!ov)
3085 return;
3086
3087 lock_kernel();
3088
3089 if (ov->decomp_ops) {
3090 module_put(ov->decomp_ops->owner);
3091 released = 1;
3092 }
3093
3094 ov->decomp_ops = NULL;
3095
3096 unlock_kernel();
3097
3098 if (released)
3099 PDEBUG(3, "Decompressor released");
3100}
3101
3102static void
3103decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
3104 unsigned char *pIn0, unsigned char *pOut0)
3105{
3106 if (!ov->decomp_ops)
3107 if (request_decompressor(ov))
3108 return;
3109
3110 PDEBUG(4, "Decompressing %d bytes", frame->bytes_recvd);
3111
3112 if (frame->format == VIDEO_PALETTE_GREY
3113 && ov->decomp_ops->decomp_400) {
3114 int ret = ov->decomp_ops->decomp_400(
3115 pIn0,
3116 pOut0,
3117 frame->compbuf,
3118 frame->rawwidth,
3119 frame->rawheight,
3120 frame->bytes_recvd);
3121 PDEBUG(4, "DEBUG: decomp_400 returned %d", ret);
3122 } else if (frame->format != VIDEO_PALETTE_GREY
3123 && ov->decomp_ops->decomp_420) {
3124 int ret = ov->decomp_ops->decomp_420(
3125 pIn0,
3126 pOut0,
3127 frame->compbuf,
3128 frame->rawwidth,
3129 frame->rawheight,
3130 frame->bytes_recvd);
3131 PDEBUG(4, "DEBUG: decomp_420 returned %d", ret);
3132 } else {
3133 err("Decompressor does not support this format");
3134 }
3135}
3136
3137/**********************************************************************
3138 *
3139 * Format conversion
3140 *
3141 **********************************************************************/
3142
3143/* Fuses even and odd fields together, and doubles width.
3144 * INPUT: an odd field followed by an even field at pIn0, in YUV planar format
3145 * OUTPUT: a normal YUV planar image, with correct aspect ratio
3146 */
3147static void
3148deinterlace(struct ov511_frame *frame, int rawformat,
3149 unsigned char *pIn0, unsigned char *pOut0)
3150{
3151 const int fieldheight = frame->rawheight / 2;
3152 const int fieldpix = fieldheight * frame->rawwidth;
3153 const int w = frame->width;
3154 int x, y;
3155 unsigned char *pInEven, *pInOdd, *pOut;
3156
3157 PDEBUG(5, "fieldheight=%d", fieldheight);
3158
3159 if (frame->rawheight != frame->height) {
3160 err("invalid height");
3161 return;
3162 }
3163
3164 if ((frame->rawwidth * 2) != frame->width) {
3165 err("invalid width");
3166 return;
3167 }
3168
3169 /* Y */
3170 pInOdd = pIn0;
3171 pInEven = pInOdd + fieldpix;
3172 pOut = pOut0;
3173 for (y = 0; y < fieldheight; y++) {
3174 for (x = 0; x < frame->rawwidth; x++) {
3175 *pOut = *pInEven;
3176 *(pOut+1) = *pInEven++;
3177 *(pOut+w) = *pInOdd;
3178 *(pOut+w+1) = *pInOdd++;
3179 pOut += 2;
3180 }
3181 pOut += w;
3182 }
3183
3184 if (rawformat == RAWFMT_YUV420) {
3185 /* U */
3186 pInOdd = pIn0 + fieldpix * 2;
3187 pInEven = pInOdd + fieldpix / 4;
3188 for (y = 0; y < fieldheight / 2; y++) {
3189 for (x = 0; x < frame->rawwidth / 2; x++) {
3190 *pOut = *pInEven;
3191 *(pOut+1) = *pInEven++;
3192 *(pOut+w/2) = *pInOdd;
3193 *(pOut+w/2+1) = *pInOdd++;
3194 pOut += 2;
3195 }
3196 pOut += w/2;
3197 }
3198 /* V */
3199 pInOdd = pIn0 + fieldpix * 2 + fieldpix / 2;
3200 pInEven = pInOdd + fieldpix / 4;
3201 for (y = 0; y < fieldheight / 2; y++) {
3202 for (x = 0; x < frame->rawwidth / 2; x++) {
3203 *pOut = *pInEven;
3204 *(pOut+1) = *pInEven++;
3205 *(pOut+w/2) = *pInOdd;
3206 *(pOut+w/2+1) = *pInOdd++;
3207 pOut += 2;
3208 }
3209 pOut += w/2;
3210 }
3211 }
3212}
3213
3214static void
3215ov51x_postprocess_grey(struct usb_ov511 *ov, struct ov511_frame *frame)
3216{
3217 /* Deinterlace frame, if necessary */
3218 if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) {
3219 if (frame->compressed)
3220 decompress(ov, frame, frame->rawdata,
3221 frame->tempdata);
3222 else
3223 yuv400raw_to_yuv400p(frame, frame->rawdata,
3224 frame->tempdata);
3225
3226 deinterlace(frame, RAWFMT_YUV400, frame->tempdata,
3227 frame->data);
3228 } else {
3229 if (frame->compressed)
3230 decompress(ov, frame, frame->rawdata,
3231 frame->data);
3232 else
3233 yuv400raw_to_yuv400p(frame, frame->rawdata,
3234 frame->data);
3235 }
3236}
3237
3238/* Process raw YUV420 data into standard YUV420P */
3239static void
3240ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame)
3241{
3242 /* Deinterlace frame, if necessary */
3243 if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) {
3244 if (frame->compressed)
3245 decompress(ov, frame, frame->rawdata, frame->tempdata);
3246 else
3247 yuv420raw_to_yuv420p(frame, frame->rawdata,
3248 frame->tempdata);
3249
3250 deinterlace(frame, RAWFMT_YUV420, frame->tempdata,
3251 frame->data);
3252 } else {
3253 if (frame->compressed)
3254 decompress(ov, frame, frame->rawdata, frame->data);
3255 else
3256 yuv420raw_to_yuv420p(frame, frame->rawdata,
3257 frame->data);
3258 }
3259}
3260
3261/* Post-processes the specified frame. This consists of:
3262 * 1. Decompress frame, if necessary
3263 * 2. Deinterlace frame and scale to proper size, if necessary
3264 * 3. Convert from YUV planar to destination format, if necessary
3265 * 4. Fix the RGB offset, if necessary
3266 */
3267static void
3268ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
3269{
3270 if (dumppix) {
3271 memset(frame->data, 0,
3272 MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
3273 PDEBUG(4, "Dumping %d bytes", frame->bytes_recvd);
3274 memcpy(frame->data, frame->rawdata, frame->bytes_recvd);
3275 } else {
3276 switch (frame->format) {
3277 case VIDEO_PALETTE_GREY:
3278 ov51x_postprocess_grey(ov, frame);
3279 break;
3280 case VIDEO_PALETTE_YUV420:
3281 case VIDEO_PALETTE_YUV420P:
3282 ov51x_postprocess_yuv420(ov, frame);
3283 break;
3284 default:
3285 err("Cannot convert data to %s",
3286 symbolic(v4l1_plist, frame->format));
3287 }
3288 }
3289}
3290
3291/**********************************************************************
3292 *
3293 * OV51x data transfer, IRQ handler
3294 *
3295 **********************************************************************/
3296
3297static inline void
3298ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n)
3299{
3300 int num, offset;
3301 int pnum = in[ov->packet_size - 1]; /* Get packet number */
3302 int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight);
3303 struct ov511_frame *frame = &ov->frame[ov->curframe];
3304 struct timeval *ts;
3305
3306 /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
3307 * byte non-zero. The EOF packet has image width/height in the
3308 * 10th and 11th bytes. The 9th byte is given as follows:
3309 *
3310 * bit 7: EOF
3311 * 6: compression enabled
3312 * 5: 422/420/400 modes
3313 * 4: 422/420/400 modes
3314 * 3: 1
3315 * 2: snapshot button on
3316 * 1: snapshot frame
3317 * 0: even/odd field
3318 */
3319
3320 if (printph) {
3321 info("ph(%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x",
3322 pnum, in[0], in[1], in[2], in[3], in[4], in[5], in[6],
3323 in[7], in[8], in[9], in[10], in[11]);
3324 }
3325
3326 /* Check for SOF/EOF packet */
3327 if ((in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) ||
3328 (~in[8] & 0x08))
3329 goto check_middle;
3330
3331 /* Frame end */
3332 if (in[8] & 0x80) {
3333 ts = (struct timeval *)(frame->data
3334 + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
3335 do_gettimeofday(ts);
3336
3337 /* Get the actual frame size from the EOF header */
3338 frame->rawwidth = ((int)(in[9]) + 1) * 8;
3339 frame->rawheight = ((int)(in[10]) + 1) * 8;
3340
3341 PDEBUG(4, "Frame end, frame=%d, pnum=%d, w=%d, h=%d, recvd=%d",
3342 ov->curframe, pnum, frame->rawwidth, frame->rawheight,
3343 frame->bytes_recvd);
3344
3345 /* Validate the header data */
3346 RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
3347 RESTRICT_TO_RANGE(frame->rawheight, ov->minheight,
3348 ov->maxheight);
3349
3350 /* Don't allow byte count to exceed buffer size */
3351 RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw);
3352
3353 if (frame->scanstate == STATE_LINES) {
3354 int nextf;
3355
3356 frame->grabstate = FRAME_DONE;
3357 wake_up_interruptible(&frame->wq);
3358
3359 /* If next frame is ready or grabbing,
3360 * point to it */
3361 nextf = (ov->curframe + 1) % OV511_NUMFRAMES;
3362 if (ov->frame[nextf].grabstate == FRAME_READY
3363 || ov->frame[nextf].grabstate == FRAME_GRABBING) {
3364 ov->curframe = nextf;
3365 ov->frame[nextf].scanstate = STATE_SCANNING;
3366 } else {
3367 if (frame->grabstate == FRAME_DONE) {
3368 PDEBUG(4, "** Frame done **");
3369 } else {
3370 PDEBUG(4, "Frame not ready? state = %d",
3371 ov->frame[nextf].grabstate);
3372 }
3373
3374 ov->curframe = -1;
3375 }
3376 } else {
3377 PDEBUG(5, "Frame done, but not scanning");
3378 }
3379 /* Image corruption caused by misplaced frame->segment = 0
3380 * fixed by carlosf@conectiva.com.br
3381 */
3382 } else {
3383 /* Frame start */
3384 PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
3385
3386 /* Check to see if it's a snapshot frame */
3387 /* FIXME?? Should the snapshot reset go here? Performance? */
3388 if (in[8] & 0x02) {
3389 frame->snapshot = 1;
3390 PDEBUG(3, "snapshot detected");
3391 }
3392
3393 frame->scanstate = STATE_LINES;
3394 frame->bytes_recvd = 0;
3395 frame->compressed = in[8] & 0x40;
3396 }
3397
3398check_middle:
3399 /* Are we in a frame? */
3400 if (frame->scanstate != STATE_LINES) {
3401 PDEBUG(5, "Not in a frame; packet skipped");
3402 return;
3403 }
3404
3405 /* If frame start, skip header */
3406 if (frame->bytes_recvd == 0)
3407 offset = 9;
3408 else
3409 offset = 0;
3410
3411 num = n - offset - 1;
3412
3413 /* Dump all data exactly as received */
3414 if (dumppix == 2) {
3415 frame->bytes_recvd += n - 1;
3416 if (frame->bytes_recvd <= max_raw)
3417 memcpy(frame->rawdata + frame->bytes_recvd - (n - 1),
3418 in, n - 1);
3419 else
3420 PDEBUG(3, "Raw data buffer overrun!! (%d)",
3421 frame->bytes_recvd - max_raw);
3422 } else if (!frame->compressed && !remove_zeros) {
3423 frame->bytes_recvd += num;
3424 if (frame->bytes_recvd <= max_raw)
3425 memcpy(frame->rawdata + frame->bytes_recvd - num,
3426 in + offset, num);
3427 else
3428 PDEBUG(3, "Raw data buffer overrun!! (%d)",
3429 frame->bytes_recvd - max_raw);
3430 } else { /* Remove all-zero FIFO lines (aligned 32-byte blocks) */
3431 int b, read = 0, allzero, copied = 0;
3432 if (offset) {
3433 frame->bytes_recvd += 32 - offset; // Bytes out
3434 memcpy(frame->rawdata, in + offset, 32 - offset);
3435 read += 32;
3436 }
3437
3438 while (read < n - 1) {
3439 allzero = 1;
3440 for (b = 0; b < 32; b++) {
3441 if (in[read + b]) {
3442 allzero = 0;
3443 break;
3444 }
3445 }
3446
3447 if (allzero) {
3448 /* Don't copy it */
3449 } else {
3450 if (frame->bytes_recvd + copied + 32 <= max_raw)
3451 {
3452 memcpy(frame->rawdata
3453 + frame->bytes_recvd + copied,
3454 in + read, 32);
3455 copied += 32;
3456 } else {
3457 PDEBUG(3, "Raw data buffer overrun!!");
3458 }
3459 }
3460 read += 32;
3461 }
3462
3463 frame->bytes_recvd += copied;
3464 }
3465}
3466
3467static inline void
3468ov518_move_data(struct usb_ov511 *ov, unsigned char *in, int n)
3469{
3470 int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight);
3471 struct ov511_frame *frame = &ov->frame[ov->curframe];
3472 struct timeval *ts;
3473
3474 /* Don't copy the packet number byte */
3475 if (ov->packet_numbering)
3476 --n;
3477
3478 /* A false positive here is likely, until OVT gives me
3479 * the definitive SOF/EOF format */
3480 if ((!(in[0] | in[1] | in[2] | in[3] | in[5])) && in[6]) {
3481 if (printph) {
3482 info("ph: %2x %2x %2x %2x %2x %2x %2x %2x", in[0],
3483 in[1], in[2], in[3], in[4], in[5], in[6], in[7]);
3484 }
3485
3486 if (frame->scanstate == STATE_LINES) {
3487 PDEBUG(4, "Detected frame end/start");
3488 goto eof;
3489 } else { //scanstate == STATE_SCANNING
3490 /* Frame start */
3491 PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
3492 goto sof;
3493 }
3494 } else {
3495 goto check_middle;
3496 }
3497
3498eof:
3499 ts = (struct timeval *)(frame->data
3500 + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
3501 do_gettimeofday(ts);
3502
3503 PDEBUG(4, "Frame end, curframe = %d, hw=%d, vw=%d, recvd=%d",
3504 ov->curframe,
3505 (int)(in[9]), (int)(in[10]), frame->bytes_recvd);
3506
3507 // FIXME: Since we don't know the header formats yet,
3508 // there is no way to know what the actual image size is
3509 frame->rawwidth = frame->width;
3510 frame->rawheight = frame->height;
3511
3512 /* Validate the header data */
3513 RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
3514 RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight);
3515
3516 /* Don't allow byte count to exceed buffer size */
3517 RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw);
3518
3519 if (frame->scanstate == STATE_LINES) {
3520 int nextf;
3521
3522 frame->grabstate = FRAME_DONE;
3523 wake_up_interruptible(&frame->wq);
3524
3525 /* If next frame is ready or grabbing,
3526 * point to it */
3527 nextf = (ov->curframe + 1) % OV511_NUMFRAMES;
3528 if (ov->frame[nextf].grabstate == FRAME_READY
3529 || ov->frame[nextf].grabstate == FRAME_GRABBING) {
3530 ov->curframe = nextf;
3531 ov->frame[nextf].scanstate = STATE_SCANNING;
3532 frame = &ov->frame[nextf];
3533 } else {
3534 if (frame->grabstate == FRAME_DONE) {
3535 PDEBUG(4, "** Frame done **");
3536 } else {
3537 PDEBUG(4, "Frame not ready? state = %d",
3538 ov->frame[nextf].grabstate);
3539 }
3540
3541 ov->curframe = -1;
3542 PDEBUG(4, "SOF dropped (no active frame)");
3543 return; /* Nowhere to store this frame */
3544 }
3545 }
3546sof:
3547 PDEBUG(4, "Starting capture on frame %d", frame->framenum);
3548
3549// Snapshot not reverse-engineered yet.
3550#if 0
3551 /* Check to see if it's a snapshot frame */
3552 /* FIXME?? Should the snapshot reset go here? Performance? */
3553 if (in[8] & 0x02) {
3554 frame->snapshot = 1;
3555 PDEBUG(3, "snapshot detected");
3556 }
3557#endif
3558 frame->scanstate = STATE_LINES;
3559 frame->bytes_recvd = 0;
3560 frame->compressed = 1;
3561
3562check_middle:
3563 /* Are we in a frame? */
3564 if (frame->scanstate != STATE_LINES) {
3565 PDEBUG(4, "scanstate: no SOF yet");
3566 return;
3567 }
3568
3569 /* Dump all data exactly as received */
3570 if (dumppix == 2) {
3571 frame->bytes_recvd += n;
3572 if (frame->bytes_recvd <= max_raw)
3573 memcpy(frame->rawdata + frame->bytes_recvd - n, in, n);
3574 else
3575 PDEBUG(3, "Raw data buffer overrun!! (%d)",
3576 frame->bytes_recvd - max_raw);
3577 } else {
3578 /* All incoming data are divided into 8-byte segments. If the
3579 * segment contains all zero bytes, it must be skipped. These
3580 * zero-segments allow the OV518 to mainain a constant data rate
3581 * regardless of the effectiveness of the compression. Segments
3582 * are aligned relative to the beginning of each isochronous
3583 * packet. The first segment in each image is a header (the
3584 * decompressor skips it later).
3585 */
3586
3587 int b, read = 0, allzero, copied = 0;
3588
3589 while (read < n) {
3590 allzero = 1;
3591 for (b = 0; b < 8; b++) {
3592 if (in[read + b]) {
3593 allzero = 0;
3594 break;
3595 }
3596 }
3597
3598 if (allzero) {
3599 /* Don't copy it */
3600 } else {
3601 if (frame->bytes_recvd + copied + 8 <= max_raw)
3602 {
3603 memcpy(frame->rawdata
3604 + frame->bytes_recvd + copied,
3605 in + read, 8);
3606 copied += 8;
3607 } else {
3608 PDEBUG(3, "Raw data buffer overrun!!");
3609 }
3610 }
3611 read += 8;
3612 }
3613 frame->bytes_recvd += copied;
3614 }
3615}
3616
3617static void
3618ov51x_isoc_irq(struct urb *urb, struct pt_regs *regs)
3619{
3620 int i;
3621 struct usb_ov511 *ov;
3622 struct ov511_sbuf *sbuf;
3623
3624 if (!urb->context) {
3625 PDEBUG(4, "no context");
3626 return;
3627 }
3628
3629 sbuf = urb->context;
3630 ov = sbuf->ov;
3631
3632 if (!ov || !ov->dev || !ov->user) {
3633 PDEBUG(4, "no device, or not open");
3634 return;
3635 }
3636
3637 if (!ov->streaming) {
3638 PDEBUG(4, "hmmm... not streaming, but got interrupt");
3639 return;
3640 }
3641
3642 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
3643 PDEBUG(4, "URB unlinked");
3644 return;
3645 }
3646
3647 if (urb->status != -EINPROGRESS && urb->status != 0) {
3648 err("ERROR: urb->status=%d: %s", urb->status,
3649 symbolic(urb_errlist, urb->status));
3650 }
3651
3652 /* Copy the data received into our frame buffer */
3653 PDEBUG(5, "sbuf[%d]: Moving %d packets", sbuf->n,
3654 urb->number_of_packets);
3655 for (i = 0; i < urb->number_of_packets; i++) {
3656 /* Warning: Don't call *_move_data() if no frame active! */
3657 if (ov->curframe >= 0) {
3658 int n = urb->iso_frame_desc[i].actual_length;
3659 int st = urb->iso_frame_desc[i].status;
3660 unsigned char *cdata;
3661
3662 urb->iso_frame_desc[i].actual_length = 0;
3663 urb->iso_frame_desc[i].status = 0;
3664
3665 cdata = urb->transfer_buffer
3666 + urb->iso_frame_desc[i].offset;
3667
3668 if (!n) {
3669 PDEBUG(4, "Zero-length packet");
3670 continue;
3671 }
3672
3673 if (st)
3674 PDEBUG(2, "data error: [%d] len=%d, status=%d",
3675 i, n, st);
3676
3677 if (ov->bclass == BCL_OV511)
3678 ov511_move_data(ov, cdata, n);
3679 else if (ov->bclass == BCL_OV518)
3680 ov518_move_data(ov, cdata, n);
3681 else
3682 err("Unknown bridge device (%d)", ov->bridge);
3683
3684 } else if (waitqueue_active(&ov->wq)) {
3685 wake_up_interruptible(&ov->wq);
3686 }
3687 }
3688
3689 /* Resubmit this URB */
3690 urb->dev = ov->dev;
3691 if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0)
3692 err("usb_submit_urb() ret %d", i);
3693
3694 return;
3695}
3696
3697/****************************************************************************
3698 *
3699 * Stream initialization and termination
3700 *
3701 ***************************************************************************/
3702
3703static int
3704ov51x_init_isoc(struct usb_ov511 *ov)
3705{
3706 struct urb *urb;
3707 int fx, err, n, size;
3708
3709 PDEBUG(3, "*** Initializing capture ***");
3710
3711 ov->curframe = -1;
3712
3713 if (ov->bridge == BRG_OV511) {
3714 if (cams == 1)
3715 size = 993;
3716 else if (cams == 2)
3717 size = 513;
3718 else if (cams == 3 || cams == 4)
3719 size = 257;
3720 else {
3721 err("\"cams\" parameter too high!");
3722 return -1;
3723 }
3724 } else if (ov->bridge == BRG_OV511PLUS) {
3725 if (cams == 1)
3726 size = 961;
3727 else if (cams == 2)
3728 size = 513;
3729 else if (cams == 3 || cams == 4)
3730 size = 257;
3731 else if (cams >= 5 && cams <= 8)
3732 size = 129;
3733 else if (cams >= 9 && cams <= 31)
3734 size = 33;
3735 else {
3736 err("\"cams\" parameter too high!");
3737 return -1;
3738 }
3739 } else if (ov->bclass == BCL_OV518) {
3740 if (cams == 1)
3741 size = 896;
3742 else if (cams == 2)
3743 size = 512;
3744 else if (cams == 3 || cams == 4)
3745 size = 256;
3746 else if (cams >= 5 && cams <= 8)
3747 size = 128;
3748 else {
3749 err("\"cams\" parameter too high!");
3750 return -1;
3751 }
3752 } else {
3753 err("invalid bridge type");
3754 return -1;
3755 }
3756
3757 // FIXME: OV518 is hardcoded to 15 FPS (alternate 5) for now
3758 if (ov->bclass == BCL_OV518) {
3759 if (packetsize == -1) {
3760 ov518_set_packet_size(ov, 640);
3761 } else {
3762 info("Forcing packet size to %d", packetsize);
3763 ov518_set_packet_size(ov, packetsize);
3764 }
3765 } else {
3766 if (packetsize == -1) {
3767 ov511_set_packet_size(ov, size);
3768 } else {
3769 info("Forcing packet size to %d", packetsize);
3770 ov511_set_packet_size(ov, packetsize);
3771 }
3772 }
3773
3774 for (n = 0; n < OV511_NUMSBUF; n++) {
3775 urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
3776 if (!urb) {
3777 err("init isoc: usb_alloc_urb ret. NULL");
3778 return -ENOMEM;
3779 }
3780 ov->sbuf[n].urb = urb;
3781 urb->dev = ov->dev;
3782 urb->context = &ov->sbuf[n];
3783 urb->pipe = usb_rcvisocpipe(ov->dev, OV511_ENDPOINT_ADDRESS);
3784 urb->transfer_flags = URB_ISO_ASAP;
3785 urb->transfer_buffer = ov->sbuf[n].data;
3786 urb->complete = ov51x_isoc_irq;
3787 urb->number_of_packets = FRAMES_PER_DESC;
3788 urb->transfer_buffer_length = ov->packet_size * FRAMES_PER_DESC;
3789 urb->interval = 1;
3790 for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
3791 urb->iso_frame_desc[fx].offset = ov->packet_size * fx;
3792 urb->iso_frame_desc[fx].length = ov->packet_size;
3793 }
3794 }
3795
3796 ov->streaming = 1;
3797
3798 for (n = 0; n < OV511_NUMSBUF; n++) {
3799 ov->sbuf[n].urb->dev = ov->dev;
3800 err = usb_submit_urb(ov->sbuf[n].urb, GFP_KERNEL);
3801 if (err) {
3802 err("init isoc: usb_submit_urb(%d) ret %d", n, err);
3803 return err;
3804 }
3805 }
3806
3807 return 0;
3808}
3809
3810static void
3811ov51x_unlink_isoc(struct usb_ov511 *ov)
3812{
3813 int n;
3814
3815 /* Unschedule all of the iso td's */
3816 for (n = OV511_NUMSBUF - 1; n >= 0; n--) {
3817 if (ov->sbuf[n].urb) {
3818 usb_kill_urb(ov->sbuf[n].urb);
3819 usb_free_urb(ov->sbuf[n].urb);
3820 ov->sbuf[n].urb = NULL;
3821 }
3822 }
3823}
3824
3825static void
3826ov51x_stop_isoc(struct usb_ov511 *ov)
3827{
3828 if (!ov->streaming || !ov->dev)
3829 return;
3830
3831 PDEBUG(3, "*** Stopping capture ***");
3832
3833 if (ov->bclass == BCL_OV518)
3834 ov518_set_packet_size(ov, 0);
3835 else
3836 ov511_set_packet_size(ov, 0);
3837
3838 ov->streaming = 0;
3839
3840 ov51x_unlink_isoc(ov);
3841}
3842
3843static int
3844ov51x_new_frame(struct usb_ov511 *ov, int framenum)
3845{
3846 struct ov511_frame *frame;
3847 int newnum;
3848
3849 PDEBUG(4, "ov->curframe = %d, framenum = %d", ov->curframe, framenum);
3850
3851 if (!ov->dev)
3852 return -1;
3853
3854 /* If we're not grabbing a frame right now and the other frame is */
3855 /* ready to be grabbed into, then use it instead */
3856 if (ov->curframe == -1) {
3857 newnum = (framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES;
3858 if (ov->frame[newnum].grabstate == FRAME_READY)
3859 framenum = newnum;
3860 } else
3861 return 0;
3862
3863 frame = &ov->frame[framenum];
3864
3865 PDEBUG(4, "framenum = %d, width = %d, height = %d", framenum,
3866 frame->width, frame->height);
3867
3868 frame->grabstate = FRAME_GRABBING;
3869 frame->scanstate = STATE_SCANNING;
3870 frame->snapshot = 0;
3871
3872 ov->curframe = framenum;
3873
3874 /* Make sure it's not too big */
3875 if (frame->width > ov->maxwidth)
3876 frame->width = ov->maxwidth;
3877
3878 frame->width &= ~7L; /* Multiple of 8 */
3879
3880 if (frame->height > ov->maxheight)
3881 frame->height = ov->maxheight;
3882
3883 frame->height &= ~3L; /* Multiple of 4 */
3884
3885 return 0;
3886}
3887
3888/****************************************************************************
3889 *
3890 * Buffer management
3891 *
3892 ***************************************************************************/
3893
3894/*
3895 * - You must acquire buf_lock before entering this function.
3896 * - Because this code will free any non-null pointer, you must be sure to null
3897 * them if you explicitly free them somewhere else!
3898 */
3899static void
3900ov51x_do_dealloc(struct usb_ov511 *ov)
3901{
3902 int i;
3903 PDEBUG(4, "entered");
3904
3905 if (ov->fbuf) {
3906 rvfree(ov->fbuf, OV511_NUMFRAMES
3907 * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
3908 ov->fbuf = NULL;
3909 }
3910
3911 vfree(ov->rawfbuf);
3912 ov->rawfbuf = NULL;
3913
3914 vfree(ov->tempfbuf);
3915 ov->tempfbuf = NULL;
3916
3917 for (i = 0; i < OV511_NUMSBUF; i++) {
3918 if (ov->sbuf[i].data) {
3919 kfree(ov->sbuf[i].data);
3920 ov->sbuf[i].data = NULL;
3921 }
3922 }
3923
3924 for (i = 0; i < OV511_NUMFRAMES; i++) {
3925 ov->frame[i].data = NULL;
3926 ov->frame[i].rawdata = NULL;
3927 ov->frame[i].tempdata = NULL;
3928 if (ov->frame[i].compbuf) {
3929 free_page((unsigned long) ov->frame[i].compbuf);
3930 ov->frame[i].compbuf = NULL;
3931 }
3932 }
3933
3934 PDEBUG(4, "buffer memory deallocated");
3935 ov->buf_state = BUF_NOT_ALLOCATED;
3936 PDEBUG(4, "leaving");
3937}
3938
3939static int
3940ov51x_alloc(struct usb_ov511 *ov)
3941{
3942 int i;
3943 const int w = ov->maxwidth;
3944 const int h = ov->maxheight;
3945 const int data_bufsize = OV511_NUMFRAMES * MAX_DATA_SIZE(w, h);
3946 const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h);
3947
3948 PDEBUG(4, "entered");
3949 down(&ov->buf_lock);
3950
3951 if (ov->buf_state == BUF_ALLOCATED)
3952 goto out;
3953
3954 ov->fbuf = rvmalloc(data_bufsize);
3955 if (!ov->fbuf)
3956 goto error;
3957
3958 ov->rawfbuf = vmalloc(raw_bufsize);
3959 if (!ov->rawfbuf)
3960 goto error;
3961
3962 memset(ov->rawfbuf, 0, raw_bufsize);
3963
3964 ov->tempfbuf = vmalloc(raw_bufsize);
3965 if (!ov->tempfbuf)
3966 goto error;
3967
3968 memset(ov->tempfbuf, 0, raw_bufsize);
3969
3970 for (i = 0; i < OV511_NUMSBUF; i++) {
3971 ov->sbuf[i].data = kmalloc(FRAMES_PER_DESC *
3972 MAX_FRAME_SIZE_PER_DESC, GFP_KERNEL);
3973 if (!ov->sbuf[i].data)
3974 goto error;
3975
3976 PDEBUG(4, "sbuf[%d] @ %p", i, ov->sbuf[i].data);
3977 }
3978
3979 for (i = 0; i < OV511_NUMFRAMES; i++) {
3980 ov->frame[i].data = ov->fbuf + i * MAX_DATA_SIZE(w, h);
3981 ov->frame[i].rawdata = ov->rawfbuf
3982 + i * MAX_RAW_DATA_SIZE(w, h);
3983 ov->frame[i].tempdata = ov->tempfbuf
3984 + i * MAX_RAW_DATA_SIZE(w, h);
3985
3986 ov->frame[i].compbuf =
3987 (unsigned char *) __get_free_page(GFP_KERNEL);
3988 if (!ov->frame[i].compbuf)
3989 goto error;
3990
3991 PDEBUG(4, "frame[%d] @ %p", i, ov->frame[i].data);
3992 }
3993
3994 ov->buf_state = BUF_ALLOCATED;
3995out:
3996 up(&ov->buf_lock);
3997 PDEBUG(4, "leaving");
3998 return 0;
3999error:
4000 ov51x_do_dealloc(ov);
4001 up(&ov->buf_lock);
4002 PDEBUG(4, "errored");
4003 return -ENOMEM;
4004}
4005
4006static void
4007ov51x_dealloc(struct usb_ov511 *ov)
4008{
4009 PDEBUG(4, "entered");
4010 down(&ov->buf_lock);
4011 ov51x_do_dealloc(ov);
4012 up(&ov->buf_lock);
4013 PDEBUG(4, "leaving");
4014}
4015
4016/****************************************************************************
4017 *
4018 * V4L 1 API
4019 *
4020 ***************************************************************************/
4021
4022static int
4023ov51x_v4l1_open(struct inode *inode, struct file *file)
4024{
4025 struct video_device *vdev = video_devdata(file);
4026 struct usb_ov511 *ov = video_get_drvdata(vdev);
4027 int err, i;
4028
4029 PDEBUG(4, "opening");
4030
4031 down(&ov->lock);
4032
4033 err = -EBUSY;
4034 if (ov->user)
4035 goto out;
4036
4037 ov->sub_flag = 0;
4038
4039 /* In case app doesn't set them... */
4040 err = ov51x_set_default_params(ov);
4041 if (err < 0)
4042 goto out;
4043
4044 /* Make sure frames are reset */
4045 for (i = 0; i < OV511_NUMFRAMES; i++) {
4046 ov->frame[i].grabstate = FRAME_UNUSED;
4047 ov->frame[i].bytes_read = 0;
4048 }
4049
4050 /* If compression is on, make sure now that a
4051 * decompressor can be loaded */
4052 if (ov->compress && !ov->decomp_ops) {
4053 err = request_decompressor(ov);
4054 if (err && !dumppix)
4055 goto out;
4056 }
4057
4058 err = ov51x_alloc(ov);
4059 if (err < 0)
4060 goto out;
4061
4062 err = ov51x_init_isoc(ov);
4063 if (err) {
4064 ov51x_dealloc(ov);
4065 goto out;
4066 }
4067
4068 ov->user++;
4069 file->private_data = vdev;
4070
4071 if (ov->led_policy == LED_AUTO)
4072 ov51x_led_control(ov, 1);
4073
4074out:
4075 up(&ov->lock);
4076 return err;
4077}
4078
4079static int
4080ov51x_v4l1_close(struct inode *inode, struct file *file)
4081{
4082 struct video_device *vdev = file->private_data;
4083 struct usb_ov511 *ov = video_get_drvdata(vdev);
4084
4085 PDEBUG(4, "ov511_close");
4086
4087 down(&ov->lock);
4088
4089 ov->user--;
4090 ov51x_stop_isoc(ov);
4091
4092 release_decompressor(ov);
4093
4094 if (ov->led_policy == LED_AUTO)
4095 ov51x_led_control(ov, 0);
4096
4097 if (ov->dev)
4098 ov51x_dealloc(ov);
4099
4100 up(&ov->lock);
4101
4102 /* Device unplugged while open. Only a minimum of unregistration is done
4103 * here; the disconnect callback already did the rest. */
4104 if (!ov->dev) {
4105 down(&ov->cbuf_lock);
4106 kfree(ov->cbuf);
4107 ov->cbuf = NULL;
4108 up(&ov->cbuf_lock);
4109
4110 ov51x_dealloc(ov);
4111 kfree(ov);
4112 ov = NULL;
4113 }
4114
4115 file->private_data = NULL;
4116 return 0;
4117}
4118
4119/* Do not call this function directly! */
4120static int
4121ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file,
4122 unsigned int cmd, void *arg)
4123{
4124 struct video_device *vdev = file->private_data;
4125 struct usb_ov511 *ov = video_get_drvdata(vdev);
4126 PDEBUG(5, "IOCtl: 0x%X", cmd);
4127
4128 if (!ov->dev)
4129 return -EIO;
4130
4131 switch (cmd) {
4132 case VIDIOCGCAP:
4133 {
4134 struct video_capability *b = arg;
4135
4136 PDEBUG(4, "VIDIOCGCAP");
4137
4138 memset(b, 0, sizeof(struct video_capability));
4139 sprintf(b->name, "%s USB Camera",
4140 symbolic(brglist, ov->bridge));
4141 b->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
4142 b->channels = ov->num_inputs;
4143 b->audios = 0;
4144 b->maxwidth = ov->maxwidth;
4145 b->maxheight = ov->maxheight;
4146 b->minwidth = ov->minwidth;
4147 b->minheight = ov->minheight;
4148
4149 return 0;
4150 }
4151 case VIDIOCGCHAN:
4152 {
4153 struct video_channel *v = arg;
4154
4155 PDEBUG(4, "VIDIOCGCHAN");
4156
4157 if ((unsigned)(v->channel) >= ov->num_inputs) {
4158 err("Invalid channel (%d)", v->channel);
4159 return -EINVAL;
4160 }
4161
4162 v->norm = ov->norm;
4163 v->type = VIDEO_TYPE_CAMERA;
4164 v->flags = 0;
4165// v->flags |= (ov->has_decoder) ? VIDEO_VC_NORM : 0;
4166 v->tuners = 0;
4167 decoder_get_input_name(ov, v->channel, v->name);
4168
4169 return 0;
4170 }
4171 case VIDIOCSCHAN:
4172 {
4173 struct video_channel *v = arg;
4174 int err;
4175
4176 PDEBUG(4, "VIDIOCSCHAN");
4177
4178 /* Make sure it's not a camera */
4179 if (!ov->has_decoder) {
4180 if (v->channel == 0)
4181 return 0;
4182 else
4183 return -EINVAL;
4184 }
4185
4186 if (v->norm != VIDEO_MODE_PAL &&
4187 v->norm != VIDEO_MODE_NTSC &&
4188 v->norm != VIDEO_MODE_SECAM &&
4189 v->norm != VIDEO_MODE_AUTO) {
4190 err("Invalid norm (%d)", v->norm);
4191 return -EINVAL;
4192 }
4193
4194 if ((unsigned)(v->channel) >= ov->num_inputs) {
4195 err("Invalid channel (%d)", v->channel);
4196 return -EINVAL;
4197 }
4198
4199 err = decoder_set_input(ov, v->channel);
4200 if (err)
4201 return err;
4202
4203 err = decoder_set_norm(ov, v->norm);
4204 if (err)
4205 return err;
4206
4207 return 0;
4208 }
4209 case VIDIOCGPICT:
4210 {
4211 struct video_picture *p = arg;
4212
4213 PDEBUG(4, "VIDIOCGPICT");
4214
4215 memset(p, 0, sizeof(struct video_picture));
4216 if (sensor_get_picture(ov, p))
4217 return -EIO;
4218
4219 /* Can we get these from frame[0]? -claudio? */
4220 p->depth = ov->frame[0].depth;
4221 p->palette = ov->frame[0].format;
4222
4223 return 0;
4224 }
4225 case VIDIOCSPICT:
4226 {
4227 struct video_picture *p = arg;
4228 int i, rc;
4229
4230 PDEBUG(4, "VIDIOCSPICT");
4231
4232 if (!get_depth(p->palette))
4233 return -EINVAL;
4234
4235 if (sensor_set_picture(ov, p))
4236 return -EIO;
4237
4238 if (force_palette && p->palette != force_palette) {
4239 info("Palette rejected (%s)",
4240 symbolic(v4l1_plist, p->palette));
4241 return -EINVAL;
4242 }
4243
4244 // FIXME: Format should be independent of frames
4245 if (p->palette != ov->frame[0].format) {
4246 PDEBUG(4, "Detected format change");
4247
4248 rc = ov51x_wait_frames_inactive(ov);
4249 if (rc)
4250 return rc;
4251
4252 mode_init_regs(ov, ov->frame[0].width,
4253 ov->frame[0].height, p->palette, ov->sub_flag);
4254 }
4255
4256 PDEBUG(4, "Setting depth=%d, palette=%s",
4257 p->depth, symbolic(v4l1_plist, p->palette));
4258
4259 for (i = 0; i < OV511_NUMFRAMES; i++) {
4260 ov->frame[i].depth = p->depth;
4261 ov->frame[i].format = p->palette;
4262 }
4263
4264 return 0;
4265 }
4266 case VIDIOCGCAPTURE:
4267 {
4268 int *vf = arg;
4269
4270 PDEBUG(4, "VIDIOCGCAPTURE");
4271
4272 ov->sub_flag = *vf;
4273 return 0;
4274 }
4275 case VIDIOCSCAPTURE:
4276 {
4277 struct video_capture *vc = arg;
4278
4279 PDEBUG(4, "VIDIOCSCAPTURE");
4280
4281 if (vc->flags)
4282 return -EINVAL;
4283 if (vc->decimation)
4284 return -EINVAL;
4285
4286 vc->x &= ~3L;
4287 vc->y &= ~1L;
4288 vc->y &= ~31L;
4289
4290 if (vc->width == 0)
4291 vc->width = 32;
4292
4293 vc->height /= 16;
4294 vc->height *= 16;
4295 if (vc->height == 0)
4296 vc->height = 16;
4297
4298 ov->subx = vc->x;
4299 ov->suby = vc->y;
4300 ov->subw = vc->width;
4301 ov->subh = vc->height;
4302
4303 return 0;
4304 }
4305 case VIDIOCSWIN:
4306 {
4307 struct video_window *vw = arg;
4308 int i, rc;
4309
4310 PDEBUG(4, "VIDIOCSWIN: %dx%d", vw->width, vw->height);
4311
4312#if 0
4313 if (vw->flags)
4314 return -EINVAL;
4315 if (vw->clipcount)
4316 return -EINVAL;
4317 if (vw->height != ov->maxheight)
4318 return -EINVAL;
4319 if (vw->width != ov->maxwidth)
4320 return -EINVAL;
4321#endif
4322
4323 rc = ov51x_wait_frames_inactive(ov);
4324 if (rc)
4325 return rc;
4326
4327 rc = mode_init_regs(ov, vw->width, vw->height,
4328 ov->frame[0].format, ov->sub_flag);
4329 if (rc < 0)
4330 return rc;
4331
4332 for (i = 0; i < OV511_NUMFRAMES; i++) {
4333 ov->frame[i].width = vw->width;
4334 ov->frame[i].height = vw->height;
4335 }
4336
4337 return 0;
4338 }
4339 case VIDIOCGWIN:
4340 {
4341 struct video_window *vw = arg;
4342
4343 memset(vw, 0, sizeof(struct video_window));
4344 vw->x = 0; /* FIXME */
4345 vw->y = 0;
4346 vw->width = ov->frame[0].width;
4347 vw->height = ov->frame[0].height;
4348 vw->flags = 30;
4349
4350 PDEBUG(4, "VIDIOCGWIN: %dx%d", vw->width, vw->height);
4351
4352 return 0;
4353 }
4354 case VIDIOCGMBUF:
4355 {
4356 struct video_mbuf *vm = arg;
4357 int i;
4358
4359 PDEBUG(4, "VIDIOCGMBUF");
4360
4361 memset(vm, 0, sizeof(struct video_mbuf));
4362 vm->size = OV511_NUMFRAMES
4363 * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
4364 vm->frames = OV511_NUMFRAMES;
4365
4366 vm->offsets[0] = 0;
4367 for (i = 1; i < OV511_NUMFRAMES; i++) {
4368 vm->offsets[i] = vm->offsets[i-1]
4369 + MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
4370 }
4371
4372 return 0;
4373 }
4374 case VIDIOCMCAPTURE:
4375 {
4376 struct video_mmap *vm = arg;
4377 int rc, depth;
4378 unsigned int f = vm->frame;
4379
4380 PDEBUG(4, "VIDIOCMCAPTURE: frame: %d, %dx%d, %s", f, vm->width,
4381 vm->height, symbolic(v4l1_plist, vm->format));
4382
4383 depth = get_depth(vm->format);
4384 if (!depth) {
4385 PDEBUG(2, "VIDIOCMCAPTURE: invalid format (%s)",
4386 symbolic(v4l1_plist, vm->format));
4387 return -EINVAL;
4388 }
4389
4390 if (f >= OV511_NUMFRAMES) {
4391 err("VIDIOCMCAPTURE: invalid frame (%d)", f);
4392 return -EINVAL;
4393 }
4394
4395 if (vm->width > ov->maxwidth
4396 || vm->height > ov->maxheight) {
4397 err("VIDIOCMCAPTURE: requested dimensions too big");
4398 return -EINVAL;
4399 }
4400
4401 if (ov->frame[f].grabstate == FRAME_GRABBING) {
4402 PDEBUG(4, "VIDIOCMCAPTURE: already grabbing");
4403 return -EBUSY;
4404 }
4405
4406 if (force_palette && (vm->format != force_palette)) {
4407 PDEBUG(2, "palette rejected (%s)",
4408 symbolic(v4l1_plist, vm->format));
4409 return -EINVAL;
4410 }
4411
4412 if ((ov->frame[f].width != vm->width) ||
4413 (ov->frame[f].height != vm->height) ||
4414 (ov->frame[f].format != vm->format) ||
4415 (ov->frame[f].sub_flag != ov->sub_flag) ||
4416 (ov->frame[f].depth != depth)) {
4417 PDEBUG(4, "VIDIOCMCAPTURE: change in image parameters");
4418
4419 rc = ov51x_wait_frames_inactive(ov);
4420 if (rc)
4421 return rc;
4422
4423 rc = mode_init_regs(ov, vm->width, vm->height,
4424 vm->format, ov->sub_flag);
4425#if 0
4426 if (rc < 0) {
4427 PDEBUG(1, "Got error while initializing regs ");
4428 return ret;
4429 }
4430#endif
4431 ov->frame[f].width = vm->width;
4432 ov->frame[f].height = vm->height;
4433 ov->frame[f].format = vm->format;
4434 ov->frame[f].sub_flag = ov->sub_flag;
4435 ov->frame[f].depth = depth;
4436 }
4437
4438 /* Mark it as ready */
4439 ov->frame[f].grabstate = FRAME_READY;
4440
4441 PDEBUG(4, "VIDIOCMCAPTURE: renewing frame %d", f);
4442
4443 return ov51x_new_frame(ov, f);
4444 }
4445 case VIDIOCSYNC:
4446 {
4447 unsigned int fnum = *((unsigned int *) arg);
4448 struct ov511_frame *frame;
4449 int rc;
4450
4451 if (fnum >= OV511_NUMFRAMES) {
4452 err("VIDIOCSYNC: invalid frame (%d)", fnum);
4453 return -EINVAL;
4454 }
4455
4456 frame = &ov->frame[fnum];
4457
4458 PDEBUG(4, "syncing to frame %d, grabstate = %d", fnum,
4459 frame->grabstate);
4460
4461 switch (frame->grabstate) {
4462 case FRAME_UNUSED:
4463 return -EINVAL;
4464 case FRAME_READY:
4465 case FRAME_GRABBING:
4466 case FRAME_ERROR:
4467redo:
4468 if (!ov->dev)
4469 return -EIO;
4470
4471 rc = wait_event_interruptible(frame->wq,
4472 (frame->grabstate == FRAME_DONE)
4473 || (frame->grabstate == FRAME_ERROR));
4474
4475 if (rc)
4476 return rc;
4477
4478 if (frame->grabstate == FRAME_ERROR) {
4479 if ((rc = ov51x_new_frame(ov, fnum)) < 0)
4480 return rc;
4481 goto redo;
4482 }
4483 /* Fall through */
4484 case FRAME_DONE:
4485 if (ov->snap_enabled && !frame->snapshot) {
4486 if ((rc = ov51x_new_frame(ov, fnum)) < 0)
4487 return rc;
4488 goto redo;
4489 }
4490
4491 frame->grabstate = FRAME_UNUSED;
4492
4493 /* Reset the hardware snapshot button */
4494 /* FIXME - Is this the best place for this? */
4495 if ((ov->snap_enabled) && (frame->snapshot)) {
4496 frame->snapshot = 0;
4497 ov51x_clear_snapshot(ov);
4498 }
4499
4500 /* Decompression, format conversion, etc... */
4501 ov51x_postprocess(ov, frame);
4502
4503 break;
4504 } /* end switch */
4505
4506 return 0;
4507 }
4508 case VIDIOCGFBUF:
4509 {
4510 struct video_buffer *vb = arg;
4511
4512 PDEBUG(4, "VIDIOCGFBUF");
4513
4514 memset(vb, 0, sizeof(struct video_buffer));
4515
4516 return 0;
4517 }
4518 case VIDIOCGUNIT:
4519 {
4520 struct video_unit *vu = arg;
4521
4522 PDEBUG(4, "VIDIOCGUNIT");
4523
4524 memset(vu, 0, sizeof(struct video_unit));
4525
4526 vu->video = ov->vdev->minor;
4527 vu->vbi = VIDEO_NO_UNIT;
4528 vu->radio = VIDEO_NO_UNIT;
4529 vu->audio = VIDEO_NO_UNIT;
4530 vu->teletext = VIDEO_NO_UNIT;
4531
4532 return 0;
4533 }
4534 case OV511IOC_WI2C:
4535 {
4536 struct ov511_i2c_struct *w = arg;
4537
4538 return i2c_w_slave(ov, w->slave, w->reg, w->value, w->mask);
4539 }
4540 case OV511IOC_RI2C:
4541 {
4542 struct ov511_i2c_struct *r = arg;
4543 int rc;
4544
4545 rc = i2c_r_slave(ov, r->slave, r->reg);
4546 if (rc < 0)
4547 return rc;
4548
4549 r->value = rc;
4550 return 0;
4551 }
4552 default:
4553 PDEBUG(3, "Unsupported IOCtl: 0x%X", cmd);
4554 return -ENOIOCTLCMD;
4555 } /* end switch */
4556
4557 return 0;
4558}
4559
4560static int
4561ov51x_v4l1_ioctl(struct inode *inode, struct file *file,
4562 unsigned int cmd, unsigned long arg)
4563{
4564 struct video_device *vdev = file->private_data;
4565 struct usb_ov511 *ov = video_get_drvdata(vdev);
4566 int rc;
4567
4568 if (down_interruptible(&ov->lock))
4569 return -EINTR;
4570
4571 rc = video_usercopy(inode, file, cmd, arg, ov51x_v4l1_ioctl_internal);
4572
4573 up(&ov->lock);
4574 return rc;
4575}
4576
4577static ssize_t
4578ov51x_v4l1_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos)
4579{
4580 struct video_device *vdev = file->private_data;
4581 int noblock = file->f_flags&O_NONBLOCK;
4582 unsigned long count = cnt;
4583 struct usb_ov511 *ov = video_get_drvdata(vdev);
4584 int i, rc = 0, frmx = -1;
4585 struct ov511_frame *frame;
4586
4587 if (down_interruptible(&ov->lock))
4588 return -EINTR;
4589
4590 PDEBUG(4, "%ld bytes, noblock=%d", count, noblock);
4591
4592 if (!vdev || !buf) {
4593 rc = -EFAULT;
4594 goto error;
4595 }
4596
4597 if (!ov->dev) {
4598 rc = -EIO;
4599 goto error;
4600 }
4601
4602// FIXME: Only supports two frames
4603 /* See if a frame is completed, then use it. */
4604 if (ov->frame[0].grabstate >= FRAME_DONE) /* _DONE or _ERROR */
4605 frmx = 0;
4606 else if (ov->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */
4607 frmx = 1;
4608
4609 /* If nonblocking we return immediately */
4610 if (noblock && (frmx == -1)) {
4611 rc = -EAGAIN;
4612 goto error;
4613 }
4614
4615 /* If no FRAME_DONE, look for a FRAME_GRABBING state. */
4616 /* See if a frame is in process (grabbing), then use it. */
4617 if (frmx == -1) {
4618 if (ov->frame[0].grabstate == FRAME_GRABBING)
4619 frmx = 0;
4620 else if (ov->frame[1].grabstate == FRAME_GRABBING)
4621 frmx = 1;
4622 }
4623
4624 /* If no frame is active, start one. */
4625 if (frmx == -1) {
4626 if ((rc = ov51x_new_frame(ov, frmx = 0))) {
4627 err("read: ov51x_new_frame error");
4628 goto error;
4629 }
4630 }
4631
4632 frame = &ov->frame[frmx];
4633
4634restart:
4635 if (!ov->dev) {
4636 rc = -EIO;
4637 goto error;
4638 }
4639
4640 /* Wait while we're grabbing the image */
4641 PDEBUG(4, "Waiting image grabbing");
4642 rc = wait_event_interruptible(frame->wq,
4643 (frame->grabstate == FRAME_DONE)
4644 || (frame->grabstate == FRAME_ERROR));
4645
4646 if (rc)
4647 goto error;
4648
4649 PDEBUG(4, "Got image, frame->grabstate = %d", frame->grabstate);
4650 PDEBUG(4, "bytes_recvd = %d", frame->bytes_recvd);
4651
4652 if (frame->grabstate == FRAME_ERROR) {
4653 frame->bytes_read = 0;
4654 err("** ick! ** Errored frame %d", ov->curframe);
4655 if (ov51x_new_frame(ov, frmx)) {
4656 err("read: ov51x_new_frame error");
4657 goto error;
4658 }
4659 goto restart;
4660 }
4661
4662
4663 /* Repeat until we get a snapshot frame */
4664 if (ov->snap_enabled)
4665 PDEBUG(4, "Waiting snapshot frame");
4666 if (ov->snap_enabled && !frame->snapshot) {
4667 frame->bytes_read = 0;
4668 if ((rc = ov51x_new_frame(ov, frmx))) {
4669 err("read: ov51x_new_frame error");
4670 goto error;
4671 }
4672 goto restart;
4673 }
4674
4675 /* Clear the snapshot */
4676 if (ov->snap_enabled && frame->snapshot) {
4677 frame->snapshot = 0;
4678 ov51x_clear_snapshot(ov);
4679 }
4680
4681 /* Decompression, format conversion, etc... */
4682 ov51x_postprocess(ov, frame);
4683
4684 PDEBUG(4, "frmx=%d, bytes_read=%ld, length=%ld", frmx,
4685 frame->bytes_read,
4686 get_frame_length(frame));
4687
4688 /* copy bytes to user space; we allow for partials reads */
4689// if ((count + frame->bytes_read)
4690// > get_frame_length((struct ov511_frame *)frame))
4691// count = frame->scanlength - frame->bytes_read;
4692
4693 /* FIXME - count hardwired to be one frame... */
4694 count = get_frame_length(frame);
4695
4696 PDEBUG(4, "Copy to user space: %ld bytes", count);
4697 if ((i = copy_to_user(buf, frame->data + frame->bytes_read, count))) {
4698 PDEBUG(4, "Copy failed! %d bytes not copied", i);
4699 rc = -EFAULT;
4700 goto error;
4701 }
4702
4703 frame->bytes_read += count;
4704 PDEBUG(4, "{copy} count used=%ld, new bytes_read=%ld",
4705 count, frame->bytes_read);
4706
4707 /* If all data have been read... */
4708 if (frame->bytes_read
4709 >= get_frame_length(frame)) {
4710 frame->bytes_read = 0;
4711
4712// FIXME: Only supports two frames
4713 /* Mark it as available to be used again. */
4714 ov->frame[frmx].grabstate = FRAME_UNUSED;
4715 if ((rc = ov51x_new_frame(ov, !frmx))) {
4716 err("ov51x_new_frame returned error");
4717 goto error;
4718 }
4719 }
4720
4721 PDEBUG(4, "read finished, returning %ld (sweet)", count);
4722
4723 up(&ov->lock);
4724 return count;
4725
4726error:
4727 up(&ov->lock);
4728 return rc;
4729}
4730
4731static int
4732ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma)
4733{
4734 struct video_device *vdev = file->private_data;
4735 unsigned long start = vma->vm_start;
4736 unsigned long size = vma->vm_end - vma->vm_start;
4737 struct usb_ov511 *ov = video_get_drvdata(vdev);
4738 unsigned long page, pos;
4739
4740 if (ov->dev == NULL)
4741 return -EIO;
4742
4743 PDEBUG(4, "mmap: %ld (%lX) bytes", size, size);
4744
4745 if (size > (((OV511_NUMFRAMES
4746 * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)
4747 + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))))
4748 return -EINVAL;
4749
4750 if (down_interruptible(&ov->lock))
4751 return -EINTR;
4752
4753 pos = (unsigned long)ov->fbuf;
4754 while (size > 0) {
4755 page = vmalloc_to_pfn((void *)pos);
4756 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
4757 up(&ov->lock);
4758 return -EAGAIN;
4759 }
4760 start += PAGE_SIZE;
4761 pos += PAGE_SIZE;
4762 if (size > PAGE_SIZE)
4763 size -= PAGE_SIZE;
4764 else
4765 size = 0;
4766 }
4767
4768 up(&ov->lock);
4769 return 0;
4770}
4771
4772static struct file_operations ov511_fops = {
4773 .owner = THIS_MODULE,
4774 .open = ov51x_v4l1_open,
4775 .release = ov51x_v4l1_close,
4776 .read = ov51x_v4l1_read,
4777 .mmap = ov51x_v4l1_mmap,
4778 .ioctl = ov51x_v4l1_ioctl,
4779 .llseek = no_llseek,
4780};
4781
4782static struct video_device vdev_template = {
4783 .owner = THIS_MODULE,
4784 .name = "OV511 USB Camera",
4785 .type = VID_TYPE_CAPTURE,
4786 .hardware = VID_HARDWARE_OV511,
4787 .fops = &ov511_fops,
4788 .release = video_device_release,
4789 .minor = -1,
4790};
4791
4792/****************************************************************************
4793 *
4794 * OV511 and sensor configuration
4795 *
4796 ***************************************************************************/
4797
4798/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
4799 * the same register settings as the OV7610, since they are very similar.
4800 */
4801static int
4802ov7xx0_configure(struct usb_ov511 *ov)
4803{
4804 int i, success;
4805 int rc;
4806
4807 /* Lawrence Glaister <lg@jfm.bc.ca> reports:
4808 *
4809 * Register 0x0f in the 7610 has the following effects:
4810 *
4811 * 0x85 (AEC method 1): Best overall, good contrast range
4812 * 0x45 (AEC method 2): Very overexposed
4813 * 0xa5 (spec sheet default): Ok, but the black level is
4814 * shifted resulting in loss of contrast
4815 * 0x05 (old driver setting): very overexposed, too much
4816 * contrast
4817 */
4818 static struct ov511_regvals aRegvalsNorm7610[] = {
4819 { OV511_I2C_BUS, 0x10, 0xff },
4820 { OV511_I2C_BUS, 0x16, 0x06 },
4821 { OV511_I2C_BUS, 0x28, 0x24 },
4822 { OV511_I2C_BUS, 0x2b, 0xac },
4823 { OV511_I2C_BUS, 0x12, 0x00 },
4824 { OV511_I2C_BUS, 0x38, 0x81 },
4825 { OV511_I2C_BUS, 0x28, 0x24 }, /* 0c */
4826 { OV511_I2C_BUS, 0x0f, 0x85 }, /* lg's setting */
4827 { OV511_I2C_BUS, 0x15, 0x01 },
4828 { OV511_I2C_BUS, 0x20, 0x1c },
4829 { OV511_I2C_BUS, 0x23, 0x2a },
4830 { OV511_I2C_BUS, 0x24, 0x10 },
4831 { OV511_I2C_BUS, 0x25, 0x8a },
4832 { OV511_I2C_BUS, 0x26, 0xa2 },
4833 { OV511_I2C_BUS, 0x27, 0xc2 },
4834 { OV511_I2C_BUS, 0x2a, 0x04 },
4835 { OV511_I2C_BUS, 0x2c, 0xfe },
4836 { OV511_I2C_BUS, 0x2d, 0x93 },
4837 { OV511_I2C_BUS, 0x30, 0x71 },
4838 { OV511_I2C_BUS, 0x31, 0x60 },
4839 { OV511_I2C_BUS, 0x32, 0x26 },
4840 { OV511_I2C_BUS, 0x33, 0x20 },
4841 { OV511_I2C_BUS, 0x34, 0x48 },
4842 { OV511_I2C_BUS, 0x12, 0x24 },
4843 { OV511_I2C_BUS, 0x11, 0x01 },
4844 { OV511_I2C_BUS, 0x0c, 0x24 },
4845 { OV511_I2C_BUS, 0x0d, 0x24 },
4846 { OV511_DONE_BUS, 0x0, 0x00 },
4847 };
4848
4849 static struct ov511_regvals aRegvalsNorm7620[] = {
4850 { OV511_I2C_BUS, 0x00, 0x00 },
4851 { OV511_I2C_BUS, 0x01, 0x80 },
4852 { OV511_I2C_BUS, 0x02, 0x80 },
4853 { OV511_I2C_BUS, 0x03, 0xc0 },
4854 { OV511_I2C_BUS, 0x06, 0x60 },
4855 { OV511_I2C_BUS, 0x07, 0x00 },
4856 { OV511_I2C_BUS, 0x0c, 0x24 },
4857 { OV511_I2C_BUS, 0x0c, 0x24 },
4858 { OV511_I2C_BUS, 0x0d, 0x24 },
4859 { OV511_I2C_BUS, 0x11, 0x01 },
4860 { OV511_I2C_BUS, 0x12, 0x24 },
4861 { OV511_I2C_BUS, 0x13, 0x01 },
4862 { OV511_I2C_BUS, 0x14, 0x84 },
4863 { OV511_I2C_BUS, 0x15, 0x01 },
4864 { OV511_I2C_BUS, 0x16, 0x03 },
4865 { OV511_I2C_BUS, 0x17, 0x2f },
4866 { OV511_I2C_BUS, 0x18, 0xcf },
4867 { OV511_I2C_BUS, 0x19, 0x06 },
4868 { OV511_I2C_BUS, 0x1a, 0xf5 },
4869 { OV511_I2C_BUS, 0x1b, 0x00 },
4870 { OV511_I2C_BUS, 0x20, 0x18 },
4871 { OV511_I2C_BUS, 0x21, 0x80 },
4872 { OV511_I2C_BUS, 0x22, 0x80 },
4873 { OV511_I2C_BUS, 0x23, 0x00 },
4874 { OV511_I2C_BUS, 0x26, 0xa2 },
4875 { OV511_I2C_BUS, 0x27, 0xea },
4876 { OV511_I2C_BUS, 0x28, 0x20 },
4877 { OV511_I2C_BUS, 0x29, 0x00 },
4878 { OV511_I2C_BUS, 0x2a, 0x10 },
4879 { OV511_I2C_BUS, 0x2b, 0x00 },
4880 { OV511_I2C_BUS, 0x2c, 0x88 },
4881 { OV511_I2C_BUS, 0x2d, 0x91 },
4882 { OV511_I2C_BUS, 0x2e, 0x80 },
4883 { OV511_I2C_BUS, 0x2f, 0x44 },
4884 { OV511_I2C_BUS, 0x60, 0x27 },
4885 { OV511_I2C_BUS, 0x61, 0x02 },
4886 { OV511_I2C_BUS, 0x62, 0x5f },
4887 { OV511_I2C_BUS, 0x63, 0xd5 },
4888 { OV511_I2C_BUS, 0x64, 0x57 },
4889 { OV511_I2C_BUS, 0x65, 0x83 },
4890 { OV511_I2C_BUS, 0x66, 0x55 },
4891 { OV511_I2C_BUS, 0x67, 0x92 },
4892 { OV511_I2C_BUS, 0x68, 0xcf },
4893 { OV511_I2C_BUS, 0x69, 0x76 },
4894 { OV511_I2C_BUS, 0x6a, 0x22 },
4895 { OV511_I2C_BUS, 0x6b, 0x00 },
4896 { OV511_I2C_BUS, 0x6c, 0x02 },
4897 { OV511_I2C_BUS, 0x6d, 0x44 },
4898 { OV511_I2C_BUS, 0x6e, 0x80 },
4899 { OV511_I2C_BUS, 0x6f, 0x1d },
4900 { OV511_I2C_BUS, 0x70, 0x8b },
4901 { OV511_I2C_BUS, 0x71, 0x00 },
4902 { OV511_I2C_BUS, 0x72, 0x14 },
4903 { OV511_I2C_BUS, 0x73, 0x54 },
4904 { OV511_I2C_BUS, 0x74, 0x00 },
4905 { OV511_I2C_BUS, 0x75, 0x8e },
4906 { OV511_I2C_BUS, 0x76, 0x00 },
4907 { OV511_I2C_BUS, 0x77, 0xff },
4908 { OV511_I2C_BUS, 0x78, 0x80 },
4909 { OV511_I2C_BUS, 0x79, 0x80 },
4910 { OV511_I2C_BUS, 0x7a, 0x80 },
4911 { OV511_I2C_BUS, 0x7b, 0xe2 },
4912 { OV511_I2C_BUS, 0x7c, 0x00 },
4913 { OV511_DONE_BUS, 0x0, 0x00 },
4914 };
4915
4916 PDEBUG(4, "starting configuration");
4917
4918 /* This looks redundant, but is necessary for WebCam 3 */
4919 ov->primary_i2c_slave = OV7xx0_SID;
4920 if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
4921 return -1;
4922
4923 if (init_ov_sensor(ov) >= 0) {
4924 PDEBUG(1, "OV7xx0 sensor initalized (method 1)");
4925 } else {
4926 /* Reset the 76xx */
4927 if (i2c_w(ov, 0x12, 0x80) < 0)
4928 return -1;
4929
4930 /* Wait for it to initialize */
4931 msleep(150);
4932
4933 i = 0;
4934 success = 0;
4935 while (i <= i2c_detect_tries) {
4936 if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
4937 (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
4938 success = 1;
4939 break;
4940 } else {
4941 i++;
4942 }
4943 }
4944
4945// Was (i == i2c_detect_tries) previously. This obviously used to always report
4946// success. Whether anyone actually depended on that bug is unknown
4947 if ((i >= i2c_detect_tries) && (success == 0)) {
4948 err("Failed to read sensor ID. You might not have an");
4949 err("OV7610/20, or it may be not responding. Report");
4950 err("this to " EMAIL);
4951 err("This is only a warning. You can attempt to use");
4952 err("your camera anyway");
4953// Only issue a warning for now
4954// return -1;
4955 } else {
4956 PDEBUG(1, "OV7xx0 initialized (method 2, %dx)", i+1);
4957 }
4958 }
4959
4960 /* Detect sensor (sub)type */
4961 rc = i2c_r(ov, OV7610_REG_COM_I);
4962
4963 if (rc < 0) {
4964 err("Error detecting sensor type");
4965 return -1;
4966 } else if ((rc & 3) == 3) {
4967 info("Sensor is an OV7610");
4968 ov->sensor = SEN_OV7610;
4969 } else if ((rc & 3) == 1) {
4970 /* I don't know what's different about the 76BE yet. */
4971 if (i2c_r(ov, 0x15) & 1)
4972 info("Sensor is an OV7620AE");
4973 else
4974 info("Sensor is an OV76BE");
4975
4976 /* OV511+ will return all zero isoc data unless we
4977 * configure the sensor as a 7620. Someone needs to
4978 * find the exact reg. setting that causes this. */
4979 if (ov->bridge == BRG_OV511PLUS) {
4980 info("Enabling 511+/7620AE workaround");
4981 ov->sensor = SEN_OV7620;
4982 } else {
4983 ov->sensor = SEN_OV76BE;
4984 }
4985 } else if ((rc & 3) == 0) {
4986 info("Sensor is an OV7620");
4987 ov->sensor = SEN_OV7620;
4988 } else {
4989 err("Unknown image sensor version: %d", rc & 3);
4990 return -1;
4991 }
4992
4993 if (ov->sensor == SEN_OV7620) {
4994 PDEBUG(4, "Writing 7620 registers");
4995 if (write_regvals(ov, aRegvalsNorm7620))
4996 return -1;
4997 } else {
4998 PDEBUG(4, "Writing 7610 registers");
4999 if (write_regvals(ov, aRegvalsNorm7610))
5000 return -1;
5001 }
5002
5003 /* Set sensor-specific vars */
5004 ov->maxwidth = 640;
5005 ov->maxheight = 480;
5006 ov->minwidth = 64;
5007 ov->minheight = 48;
5008
5009 // FIXME: These do not match the actual settings yet
5010 ov->brightness = 0x80 << 8;
5011 ov->contrast = 0x80 << 8;
5012 ov->colour = 0x80 << 8;
5013 ov->hue = 0x80 << 8;
5014
5015 return 0;
5016}
5017
5018/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
5019static int
5020ov6xx0_configure(struct usb_ov511 *ov)
5021{
5022 int rc;
5023
5024 static struct ov511_regvals aRegvalsNorm6x20[] = {
5025 { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */
5026 { OV511_I2C_BUS, 0x11, 0x01 },
5027 { OV511_I2C_BUS, 0x03, 0x60 },
5028 { OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */
5029 { OV511_I2C_BUS, 0x07, 0xa8 },
5030 /* The ratio of 0x0c and 0x0d controls the white point */
5031 { OV511_I2C_BUS, 0x0c, 0x24 },
5032 { OV511_I2C_BUS, 0x0d, 0x24 },
5033 { OV511_I2C_BUS, 0x0f, 0x15 }, /* COMS */
5034 { OV511_I2C_BUS, 0x10, 0x75 }, /* AEC Exposure time */
5035 { OV511_I2C_BUS, 0x12, 0x24 }, /* Enable AGC */
5036 { OV511_I2C_BUS, 0x14, 0x04 },
5037 /* 0x16: 0x06 helps frame stability with moving objects */
5038 { OV511_I2C_BUS, 0x16, 0x06 },
5039// { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */
5040 { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */
5041 /* 0x28: 0x05 Selects RGB format if RGB on */
5042 { OV511_I2C_BUS, 0x28, 0x05 },
5043 { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */
5044// { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */
5045 { OV511_I2C_BUS, 0x2d, 0x99 },
5046 { OV511_I2C_BUS, 0x33, 0xa0 }, /* Color Procesing Parameter */
5047 { OV511_I2C_BUS, 0x34, 0xd2 }, /* Max A/D range */
5048 { OV511_I2C_BUS, 0x38, 0x8b },
5049 { OV511_I2C_BUS, 0x39, 0x40 },
5050
5051 { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */
5052 { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */
5053 { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */
5054
5055 { OV511_I2C_BUS, 0x3d, 0x80 },
5056 /* These next two registers (0x4a, 0x4b) are undocumented. They
5057 * control the color balance */
5058 { OV511_I2C_BUS, 0x4a, 0x80 },
5059 { OV511_I2C_BUS, 0x4b, 0x80 },
5060 { OV511_I2C_BUS, 0x4d, 0xd2 }, /* This reduces noise a bit */
5061 { OV511_I2C_BUS, 0x4e, 0xc1 },
5062 { OV511_I2C_BUS, 0x4f, 0x04 },
5063// Do 50-53 have any effect?
5064// Toggle 0x12[2] off and on here?
5065 { OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */
5066 };
5067
5068 static struct ov511_regvals aRegvalsNorm6x30[] = {
5069 /*OK*/ { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */
5070 { OV511_I2C_BUS, 0x11, 0x00 },
5071 /*OK*/ { OV511_I2C_BUS, 0x03, 0x60 },
5072 /*0A?*/ { OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */
5073 { OV511_I2C_BUS, 0x07, 0xa8 },
5074 /* The ratio of 0x0c and 0x0d controls the white point */
5075 /*OK*/ { OV511_I2C_BUS, 0x0c, 0x24 },
5076 /*OK*/ { OV511_I2C_BUS, 0x0d, 0x24 },
5077 /*A*/ { OV511_I2C_BUS, 0x0e, 0x20 },
5078// /*04?*/ { OV511_I2C_BUS, 0x14, 0x80 },
5079 { OV511_I2C_BUS, 0x16, 0x03 },
5080// /*OK*/ { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */
5081 // 21 & 22? The suggested values look wrong. Go with default
5082 /*A*/ { OV511_I2C_BUS, 0x23, 0xc0 },
5083 /*A*/ { OV511_I2C_BUS, 0x25, 0x9a }, // Check this against default
5084// /*OK*/ { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */
5085
5086 /* 0x28: 0x05 Selects RGB format if RGB on */
5087// /*04?*/ { OV511_I2C_BUS, 0x28, 0x05 },
5088// /*04?*/ { OV511_I2C_BUS, 0x28, 0x45 }, // DEBUG: Tristate UV bus
5089
5090 /*OK*/ { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */
5091// /*OK*/ { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */
5092 { OV511_I2C_BUS, 0x2d, 0x99 },
5093// /*A*/ { OV511_I2C_BUS, 0x33, 0x26 }, // Reserved bits on 6620
5094// /*d2?*/ { OV511_I2C_BUS, 0x34, 0x03 }, /* Max A/D range */
5095// /*8b?*/ { OV511_I2C_BUS, 0x38, 0x83 },
5096// /*40?*/ { OV511_I2C_BUS, 0x39, 0xc0 }, // 6630 adds bit 7
5097// { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */
5098// { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */
5099// { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */
5100 { OV511_I2C_BUS, 0x3d, 0x80 },
5101// /*A*/ { OV511_I2C_BUS, 0x3f, 0x0e },
5102
5103 /* These next two registers (0x4a, 0x4b) are undocumented. They
5104 * control the color balance */
5105// /*OK?*/ { OV511_I2C_BUS, 0x4a, 0x80 }, // Check these
5106// /*OK?*/ { OV511_I2C_BUS, 0x4b, 0x80 },
5107 { OV511_I2C_BUS, 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
5108 /*c1?*/ { OV511_I2C_BUS, 0x4e, 0x40 },
5109
5110 /* UV average mode, color killer: strongest */
5111 { OV511_I2C_BUS, 0x4f, 0x07 },
5112
5113 { OV511_I2C_BUS, 0x54, 0x23 }, /* Max AGC gain: 18dB */
5114 { OV511_I2C_BUS, 0x57, 0x81 }, /* (default) */
5115 { OV511_I2C_BUS, 0x59, 0x01 }, /* AGC dark current comp: +1 */
5116 { OV511_I2C_BUS, 0x5a, 0x2c }, /* (undocumented) */
5117 { OV511_I2C_BUS, 0x5b, 0x0f }, /* AWB chrominance levels */
5118// { OV511_I2C_BUS, 0x5c, 0x10 },
5119 { OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */
5120 };
5121
5122 PDEBUG(4, "starting sensor configuration");
5123
5124 if (init_ov_sensor(ov) < 0) {
5125 err("Failed to read sensor ID. You might not have an OV6xx0,");
5126 err("or it may be not responding. Report this to " EMAIL);
5127 return -1;
5128 } else {
5129 PDEBUG(1, "OV6xx0 sensor detected");
5130 }
5131
5132 /* Detect sensor (sub)type */
5133 rc = i2c_r(ov, OV7610_REG_COM_I);
5134
5135 if (rc < 0) {
5136 err("Error detecting sensor type");
5137 return -1;
5138 }
5139
5140 if ((rc & 3) == 0) {
5141 ov->sensor = SEN_OV6630;
5142 info("Sensor is an OV6630");
5143 } else if ((rc & 3) == 1) {
5144 ov->sensor = SEN_OV6620;
5145 info("Sensor is an OV6620");
5146 } else if ((rc & 3) == 2) {
5147 ov->sensor = SEN_OV6630;
5148 info("Sensor is an OV6630AE");
5149 } else if ((rc & 3) == 3) {
5150 ov->sensor = SEN_OV6630;
5151 info("Sensor is an OV6630AF");
5152 }
5153
5154 /* Set sensor-specific vars */
5155 ov->maxwidth = 352;
5156 ov->maxheight = 288;
5157 ov->minwidth = 64;
5158 ov->minheight = 48;
5159
5160 // FIXME: These do not match the actual settings yet
5161 ov->brightness = 0x80 << 8;
5162 ov->contrast = 0x80 << 8;
5163 ov->colour = 0x80 << 8;
5164 ov->hue = 0x80 << 8;
5165
5166 if (ov->sensor == SEN_OV6620) {
5167 PDEBUG(4, "Writing 6x20 registers");
5168 if (write_regvals(ov, aRegvalsNorm6x20))
5169 return -1;
5170 } else {
5171 PDEBUG(4, "Writing 6x30 registers");
5172 if (write_regvals(ov, aRegvalsNorm6x30))
5173 return -1;
5174 }
5175
5176 return 0;
5177}
5178
5179/* This initializes the KS0127 and KS0127B video decoders. */
5180static int
5181ks0127_configure(struct usb_ov511 *ov)
5182{
5183 int rc;
5184
5185// FIXME: I don't know how to sync or reset it yet
5186#if 0
5187 if (ov51x_init_ks_sensor(ov) < 0) {
5188 err("Failed to initialize the KS0127");
5189 return -1;
5190 } else {
5191 PDEBUG(1, "KS012x(B) sensor detected");
5192 }
5193#endif
5194
5195 /* Detect decoder subtype */
5196 rc = i2c_r(ov, 0x00);
5197 if (rc < 0) {
5198 err("Error detecting sensor type");
5199 return -1;
5200 } else if (rc & 0x08) {
5201 rc = i2c_r(ov, 0x3d);
5202 if (rc < 0) {
5203 err("Error detecting sensor type");
5204 return -1;
5205 } else if ((rc & 0x0f) == 0) {
5206 info("Sensor is a KS0127");
5207 ov->sensor = SEN_KS0127;
5208 } else if ((rc & 0x0f) == 9) {
5209 info("Sensor is a KS0127B Rev. A");
5210 ov->sensor = SEN_KS0127B;
5211 }
5212 } else {
5213 err("Error: Sensor is an unsupported KS0122");
5214 return -1;
5215 }
5216
5217 /* Set sensor-specific vars */
5218 ov->maxwidth = 640;
5219 ov->maxheight = 480;
5220 ov->minwidth = 64;
5221 ov->minheight = 48;
5222
5223 // FIXME: These do not match the actual settings yet
5224 ov->brightness = 0x80 << 8;
5225 ov->contrast = 0x80 << 8;
5226 ov->colour = 0x80 << 8;
5227 ov->hue = 0x80 << 8;
5228
5229 /* This device is not supported yet. Bail out now... */
5230 err("This sensor is not supported yet.");
5231 return -1;
5232
5233 return 0;
5234}
5235
5236/* This initializes the SAA7111A video decoder. */
5237static int
5238saa7111a_configure(struct usb_ov511 *ov)
5239{
5240 int rc;
5241
5242 /* Since there is no register reset command, all registers must be
5243 * written, otherwise gives erratic results */
5244 static struct ov511_regvals aRegvalsNormSAA7111A[] = {
5245 { OV511_I2C_BUS, 0x06, 0xce },
5246 { OV511_I2C_BUS, 0x07, 0x00 },
5247 { OV511_I2C_BUS, 0x10, 0x44 }, /* YUV422, 240/286 lines */
5248 { OV511_I2C_BUS, 0x0e, 0x01 }, /* NTSC M or PAL BGHI */
5249 { OV511_I2C_BUS, 0x00, 0x00 },
5250 { OV511_I2C_BUS, 0x01, 0x00 },
5251 { OV511_I2C_BUS, 0x03, 0x23 },
5252 { OV511_I2C_BUS, 0x04, 0x00 },
5253 { OV511_I2C_BUS, 0x05, 0x00 },
5254 { OV511_I2C_BUS, 0x08, 0xc8 }, /* Auto field freq */
5255 { OV511_I2C_BUS, 0x09, 0x01 }, /* Chrom. trap off, APER=0.25 */
5256 { OV511_I2C_BUS, 0x0a, 0x80 }, /* BRIG=128 */
5257 { OV511_I2C_BUS, 0x0b, 0x40 }, /* CONT=1.0 */
5258 { OV511_I2C_BUS, 0x0c, 0x40 }, /* SATN=1.0 */
5259 { OV511_I2C_BUS, 0x0d, 0x00 }, /* HUE=0 */
5260 { OV511_I2C_BUS, 0x0f, 0x00 },
5261 { OV511_I2C_BUS, 0x11, 0x0c },
5262 { OV511_I2C_BUS, 0x12, 0x00 },
5263 { OV511_I2C_BUS, 0x13, 0x00 },
5264 { OV511_I2C_BUS, 0x14, 0x00 },
5265 { OV511_I2C_BUS, 0x15, 0x00 },
5266 { OV511_I2C_BUS, 0x16, 0x00 },
5267 { OV511_I2C_BUS, 0x17, 0x00 },
5268 { OV511_I2C_BUS, 0x02, 0xc0 }, /* Composite input 0 */
5269 { OV511_DONE_BUS, 0x0, 0x00 },
5270 };
5271
5272// FIXME: I don't know how to sync or reset it yet
5273#if 0
5274 if (ov51x_init_saa_sensor(ov) < 0) {
5275 err("Failed to initialize the SAA7111A");
5276 return -1;
5277 } else {
5278 PDEBUG(1, "SAA7111A sensor detected");
5279 }
5280#endif
5281
5282 /* 640x480 not supported with PAL */
5283 if (ov->pal) {
5284 ov->maxwidth = 320;
5285 ov->maxheight = 240; /* Even field only */
5286 } else {
5287 ov->maxwidth = 640;
5288 ov->maxheight = 480; /* Even/Odd fields */
5289 }
5290
5291 ov->minwidth = 320;
5292 ov->minheight = 240; /* Even field only */
5293
5294 ov->has_decoder = 1;
5295 ov->num_inputs = 8;
5296 ov->norm = VIDEO_MODE_AUTO;
5297 ov->stop_during_set = 0; /* Decoder guarantees stable image */
5298
5299 /* Decoder doesn't change these values, so we use these instead of
5300 * acutally reading the registers (which doesn't work) */
5301 ov->brightness = 0x80 << 8;
5302 ov->contrast = 0x40 << 9;
5303 ov->colour = 0x40 << 9;
5304 ov->hue = 32768;
5305
5306 PDEBUG(4, "Writing SAA7111A registers");
5307 if (write_regvals(ov, aRegvalsNormSAA7111A))
5308 return -1;
5309
5310 /* Detect version of decoder. This must be done after writing the
5311 * initial regs or the decoder will lock up. */
5312 rc = i2c_r(ov, 0x00);
5313
5314 if (rc < 0) {
5315 err("Error detecting sensor version");
5316 return -1;
5317 } else {
5318 info("Sensor is an SAA7111A (version 0x%x)", rc);
5319 ov->sensor = SEN_SAA7111A;
5320 }
5321
5322 // FIXME: Fix this for OV518(+)
5323 /* Latch to negative edge of clock. Otherwise, we get incorrect
5324 * colors and jitter in the digital signal. */
5325 if (ov->bclass == BCL_OV511)
5326 reg_w(ov, 0x11, 0x00);
5327 else
5328 warn("SAA7111A not yet supported with OV518/OV518+");
5329
5330 return 0;
5331}
5332
5333/* This initializes the OV511/OV511+ and the sensor */
5334static int
5335ov511_configure(struct usb_ov511 *ov)
5336{
5337 static struct ov511_regvals aRegvalsInit511[] = {
5338 { OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
5339 { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
5340 { OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
5341 { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
5342 { OV511_REG_BUS, R51x_SYS_RESET, 0x3f },
5343 { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
5344 { OV511_REG_BUS, R51x_SYS_RESET, 0x3d },
5345 { OV511_DONE_BUS, 0x0, 0x00},
5346 };
5347
5348 static struct ov511_regvals aRegvalsNorm511[] = {
5349 { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0x01 },
5350 { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
5351 { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 },
5352 { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
5353 { OV511_REG_BUS, R511_FIFO_OPTS, 0x1f },
5354 { OV511_REG_BUS, R511_COMP_EN, 0x00 },
5355 { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 },
5356 { OV511_DONE_BUS, 0x0, 0x00 },
5357 };
5358
5359 static struct ov511_regvals aRegvalsNorm511Plus[] = {
5360 { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0xff },
5361 { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
5362 { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 },
5363 { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
5364 { OV511_REG_BUS, R511_FIFO_OPTS, 0xff },
5365 { OV511_REG_BUS, R511_COMP_EN, 0x00 },
5366 { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 },
5367 { OV511_DONE_BUS, 0x0, 0x00 },
5368 };
5369
5370 PDEBUG(4, "");
5371
5372 ov->customid = reg_r(ov, R511_SYS_CUST_ID);
5373 if (ov->customid < 0) {
5374 err("Unable to read camera bridge registers");
5375 goto error;
5376 }
5377
5378 PDEBUG (1, "CustomID = %d", ov->customid);
5379 ov->desc = symbolic(camlist, ov->customid);
5380 info("model: %s", ov->desc);
5381
5382 if (0 == strcmp(ov->desc, NOT_DEFINED_STR)) {
5383 err("Camera type (%d) not recognized", ov->customid);
5384 err("Please notify " EMAIL " of the name,");
5385 err("manufacturer, model, and this number of your camera.");
5386 err("Also include the output of the detection process.");
5387 }
5388
5389 if (ov->customid == 70) /* USB Life TV (PAL/SECAM) */
5390 ov->pal = 1;
5391
5392 if (write_regvals(ov, aRegvalsInit511))
5393 goto error;
5394
5395 if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
5396 ov51x_led_control(ov, 0);
5397
5398 /* The OV511+ has undocumented bits in the flow control register.
5399 * Setting it to 0xff fixes the corruption with moving objects. */
5400 if (ov->bridge == BRG_OV511) {
5401 if (write_regvals(ov, aRegvalsNorm511))
5402 goto error;
5403 } else if (ov->bridge == BRG_OV511PLUS) {
5404 if (write_regvals(ov, aRegvalsNorm511Plus))
5405 goto error;
5406 } else {
5407 err("Invalid bridge");
5408 }
5409
5410 if (ov511_init_compression(ov))
5411 goto error;
5412
5413 ov->packet_numbering = 1;
5414 ov511_set_packet_size(ov, 0);
5415
5416 ov->snap_enabled = snapshot;
5417
5418 /* Test for 7xx0 */
5419 PDEBUG(3, "Testing for 0V7xx0");
5420 ov->primary_i2c_slave = OV7xx0_SID;
5421 if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
5422 goto error;
5423
5424 if (i2c_w(ov, 0x12, 0x80) < 0) {
5425 /* Test for 6xx0 */
5426 PDEBUG(3, "Testing for 0V6xx0");
5427 ov->primary_i2c_slave = OV6xx0_SID;
5428 if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
5429 goto error;
5430
5431 if (i2c_w(ov, 0x12, 0x80) < 0) {
5432 /* Test for 8xx0 */
5433 PDEBUG(3, "Testing for 0V8xx0");
5434 ov->primary_i2c_slave = OV8xx0_SID;
5435 if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0)
5436 goto error;
5437
5438 if (i2c_w(ov, 0x12, 0x80) < 0) {
5439 /* Test for SAA7111A */
5440 PDEBUG(3, "Testing for SAA7111A");
5441 ov->primary_i2c_slave = SAA7111A_SID;
5442 if (ov51x_set_slave_ids(ov, SAA7111A_SID) < 0)
5443 goto error;
5444
5445 if (i2c_w(ov, 0x0d, 0x00) < 0) {
5446 /* Test for KS0127 */
5447 PDEBUG(3, "Testing for KS0127");
5448 ov->primary_i2c_slave = KS0127_SID;
5449 if (ov51x_set_slave_ids(ov, KS0127_SID) < 0)
5450 goto error;
5451
5452 if (i2c_w(ov, 0x10, 0x00) < 0) {
5453 err("Can't determine sensor slave IDs");
5454 goto error;
5455 } else {
5456 if (ks0127_configure(ov) < 0) {
5457 err("Failed to configure KS0127");
5458 goto error;
5459 }
5460 }
5461 } else {
5462 if (saa7111a_configure(ov) < 0) {
5463 err("Failed to configure SAA7111A");
5464 goto error;
5465 }
5466 }
5467 } else {
5468 err("Detected unsupported OV8xx0 sensor");
5469 goto error;
5470 }
5471 } else {
5472 if (ov6xx0_configure(ov) < 0) {
5473 err("Failed to configure OV6xx0");
5474 goto error;
5475 }
5476 }
5477 } else {
5478 if (ov7xx0_configure(ov) < 0) {
5479 err("Failed to configure OV7xx0");
5480 goto error;
5481 }
5482 }
5483
5484 return 0;
5485
5486error:
5487 err("OV511 Config failed");
5488
5489 return -EBUSY;
5490}
5491
5492/* This initializes the OV518/OV518+ and the sensor */
5493static int
5494ov518_configure(struct usb_ov511 *ov)
5495{
5496 /* For 518 and 518+ */
5497 static struct ov511_regvals aRegvalsInit518[] = {
5498 { OV511_REG_BUS, R51x_SYS_RESET, 0x40 },
5499 { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
5500 { OV511_REG_BUS, R51x_SYS_RESET, 0x3e },
5501 { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
5502 { OV511_REG_BUS, R51x_SYS_RESET, 0x00 },
5503 { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
5504 { OV511_REG_BUS, 0x46, 0x00 },
5505 { OV511_REG_BUS, 0x5d, 0x03 },
5506 { OV511_DONE_BUS, 0x0, 0x00},
5507 };
5508
5509 static struct ov511_regvals aRegvalsNorm518[] = {
5510 { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */
5511 { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */
5512 { OV511_REG_BUS, 0x31, 0x0f },
5513 { OV511_REG_BUS, 0x5d, 0x03 },
5514 { OV511_REG_BUS, 0x24, 0x9f },
5515 { OV511_REG_BUS, 0x25, 0x90 },
5516 { OV511_REG_BUS, 0x20, 0x00 },
5517 { OV511_REG_BUS, 0x51, 0x04 },
5518 { OV511_REG_BUS, 0x71, 0x19 },
5519 { OV511_DONE_BUS, 0x0, 0x00 },
5520 };
5521
5522 static struct ov511_regvals aRegvalsNorm518Plus[] = {
5523 { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */
5524 { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */
5525 { OV511_REG_BUS, 0x31, 0x0f },
5526 { OV511_REG_BUS, 0x5d, 0x03 },
5527 { OV511_REG_BUS, 0x24, 0x9f },
5528 { OV511_REG_BUS, 0x25, 0x90 },
5529 { OV511_REG_BUS, 0x20, 0x60 },
5530 { OV511_REG_BUS, 0x51, 0x02 },
5531 { OV511_REG_BUS, 0x71, 0x19 },
5532 { OV511_REG_BUS, 0x40, 0xff },
5533 { OV511_REG_BUS, 0x41, 0x42 },
5534 { OV511_REG_BUS, 0x46, 0x00 },
5535 { OV511_REG_BUS, 0x33, 0x04 },
5536 { OV511_REG_BUS, 0x21, 0x19 },
5537 { OV511_REG_BUS, 0x3f, 0x10 },
5538 { OV511_DONE_BUS, 0x0, 0x00 },
5539 };
5540
5541 PDEBUG(4, "");
5542
5543 /* First 5 bits of custom ID reg are a revision ID on OV518 */
5544 info("Device revision %d", 0x1F & reg_r(ov, R511_SYS_CUST_ID));
5545
5546 /* Give it the default description */
5547 ov->desc = symbolic(camlist, 0);
5548
5549 if (write_regvals(ov, aRegvalsInit518))
5550 goto error;
5551
5552 /* Set LED GPIO pin to output mode */
5553 if (reg_w_mask(ov, 0x57, 0x00, 0x02) < 0)
5554 goto error;
5555
5556 /* LED is off by default with OV518; have to explicitly turn it on */
5557 if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
5558 ov51x_led_control(ov, 0);
5559 else
5560 ov51x_led_control(ov, 1);
5561
5562 /* Don't require compression if dumppix is enabled; otherwise it's
5563 * required. OV518 has no uncompressed mode, to save RAM. */
5564 if (!dumppix && !ov->compress) {
5565 ov->compress = 1;
5566 warn("Compression required with OV518...enabling");
5567 }
5568
5569 if (ov->bridge == BRG_OV518) {
5570 if (write_regvals(ov, aRegvalsNorm518))
5571 goto error;
5572 } else if (ov->bridge == BRG_OV518PLUS) {
5573 if (write_regvals(ov, aRegvalsNorm518Plus))
5574 goto error;
5575 } else {
5576 err("Invalid bridge");
5577 }
5578
5579 if (reg_w(ov, 0x2f, 0x80) < 0)
5580 goto error;
5581
5582 if (ov518_init_compression(ov))
5583 goto error;
5584
5585 if (ov->bridge == BRG_OV518)
5586 {
5587 struct usb_interface *ifp;
5588 struct usb_host_interface *alt;
5589 __u16 mxps = 0;
5590
5591 ifp = usb_ifnum_to_if(ov->dev, 0);
5592 if (ifp) {
5593 alt = usb_altnum_to_altsetting(ifp, 7);
5594 if (alt)
5595 mxps = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
5596 }
5597
5598 /* Some OV518s have packet numbering by default, some don't */
5599 if (mxps == 897)
5600 ov->packet_numbering = 1;
5601 else
5602 ov->packet_numbering = 0;
5603 } else {
5604 /* OV518+ has packet numbering turned on by default */
5605 ov->packet_numbering = 1;
5606 }
5607
5608 ov518_set_packet_size(ov, 0);
5609
5610 ov->snap_enabled = snapshot;
5611
5612 /* Test for 76xx */
5613 ov->primary_i2c_slave = OV7xx0_SID;
5614 if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
5615 goto error;
5616
5617 /* The OV518 must be more aggressive about sensor detection since
5618 * I2C write will never fail if the sensor is not present. We have
5619 * to try to initialize the sensor to detect its presence */
5620
5621 if (init_ov_sensor(ov) < 0) {
5622 /* Test for 6xx0 */
5623 ov->primary_i2c_slave = OV6xx0_SID;
5624 if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
5625 goto error;
5626
5627 if (init_ov_sensor(ov) < 0) {
5628 /* Test for 8xx0 */
5629 ov->primary_i2c_slave = OV8xx0_SID;
5630 if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0)
5631 goto error;
5632
5633 if (init_ov_sensor(ov) < 0) {
5634 err("Can't determine sensor slave IDs");
5635 goto error;
5636 } else {
5637 err("Detected unsupported OV8xx0 sensor");
5638 goto error;
5639 }
5640 } else {
5641 if (ov6xx0_configure(ov) < 0) {
5642 err("Failed to configure OV6xx0");
5643 goto error;
5644 }
5645 }
5646 } else {
5647 if (ov7xx0_configure(ov) < 0) {
5648 err("Failed to configure OV7xx0");
5649 goto error;
5650 }
5651 }
5652
5653 ov->maxwidth = 352;
5654 ov->maxheight = 288;
5655
5656 // The OV518 cannot go as low as the sensor can
5657 ov->minwidth = 160;
5658 ov->minheight = 120;
5659
5660 return 0;
5661
5662error:
5663 err("OV518 Config failed");
5664
5665 return -EBUSY;
5666}
5667
5668/****************************************************************************
5669 * sysfs
5670 ***************************************************************************/
5671
5672static inline struct usb_ov511 *cd_to_ov(struct class_device *cd)
5673{
5674 struct video_device *vdev = to_video_device(cd);
5675 return video_get_drvdata(vdev);
5676}
5677
5678static ssize_t show_custom_id(struct class_device *cd, char *buf)
5679{
5680 struct usb_ov511 *ov = cd_to_ov(cd);
5681 return sprintf(buf, "%d\n", ov->customid);
5682}
5683static CLASS_DEVICE_ATTR(custom_id, S_IRUGO, show_custom_id, NULL);
5684
5685static ssize_t show_model(struct class_device *cd, char *buf)
5686{
5687 struct usb_ov511 *ov = cd_to_ov(cd);
5688 return sprintf(buf, "%s\n", ov->desc);
5689}
5690static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
5691
5692static ssize_t show_bridge(struct class_device *cd, char *buf)
5693{
5694 struct usb_ov511 *ov = cd_to_ov(cd);
5695 return sprintf(buf, "%s\n", symbolic(brglist, ov->bridge));
5696}
5697static CLASS_DEVICE_ATTR(bridge, S_IRUGO, show_bridge, NULL);
5698
5699static ssize_t show_sensor(struct class_device *cd, char *buf)
5700{
5701 struct usb_ov511 *ov = cd_to_ov(cd);
5702 return sprintf(buf, "%s\n", symbolic(senlist, ov->sensor));
5703}
5704static CLASS_DEVICE_ATTR(sensor, S_IRUGO, show_sensor, NULL);
5705
5706static ssize_t show_brightness(struct class_device *cd, char *buf)
5707{
5708 struct usb_ov511 *ov = cd_to_ov(cd);
5709 unsigned short x;
5710
5711 if (!ov->dev)
5712 return -ENODEV;
5713 sensor_get_brightness(ov, &x);
5714 return sprintf(buf, "%d\n", x >> 8);
5715}
5716static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
5717
5718static ssize_t show_saturation(struct class_device *cd, char *buf)
5719{
5720 struct usb_ov511 *ov = cd_to_ov(cd);
5721 unsigned short x;
5722
5723 if (!ov->dev)
5724 return -ENODEV;
5725 sensor_get_saturation(ov, &x);
5726 return sprintf(buf, "%d\n", x >> 8);
5727}
5728static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
5729
5730static ssize_t show_contrast(struct class_device *cd, char *buf)
5731{
5732 struct usb_ov511 *ov = cd_to_ov(cd);
5733 unsigned short x;
5734
5735 if (!ov->dev)
5736 return -ENODEV;
5737 sensor_get_contrast(ov, &x);
5738 return sprintf(buf, "%d\n", x >> 8);
5739}
5740static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
5741
5742static ssize_t show_hue(struct class_device *cd, char *buf)
5743{
5744 struct usb_ov511 *ov = cd_to_ov(cd);
5745 unsigned short x;
5746
5747 if (!ov->dev)
5748 return -ENODEV;
5749 sensor_get_hue(ov, &x);
5750 return sprintf(buf, "%d\n", x >> 8);
5751}
5752static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
5753
5754static ssize_t show_exposure(struct class_device *cd, char *buf)
5755{
5756 struct usb_ov511 *ov = cd_to_ov(cd);
5757 unsigned char exp;
5758
5759 if (!ov->dev)
5760 return -ENODEV;
5761 sensor_get_exposure(ov, &exp);
5762 return sprintf(buf, "%d\n", exp >> 8);
5763}
5764static CLASS_DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL);
5765
5766static void ov_create_sysfs(struct video_device *vdev)
5767{
5768 video_device_create_file(vdev, &class_device_attr_custom_id);
5769 video_device_create_file(vdev, &class_device_attr_model);
5770 video_device_create_file(vdev, &class_device_attr_bridge);
5771 video_device_create_file(vdev, &class_device_attr_sensor);
5772 video_device_create_file(vdev, &class_device_attr_brightness);
5773 video_device_create_file(vdev, &class_device_attr_saturation);
5774 video_device_create_file(vdev, &class_device_attr_contrast);
5775 video_device_create_file(vdev, &class_device_attr_hue);
5776 video_device_create_file(vdev, &class_device_attr_exposure);
5777}
5778
5779/****************************************************************************
5780 * USB routines
5781 ***************************************************************************/
5782
5783static int
5784ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
5785{
5786 struct usb_device *dev = interface_to_usbdev(intf);
5787 struct usb_interface_descriptor *idesc;
5788 struct usb_ov511 *ov;
5789 int i;
5790
5791 PDEBUG(1, "probing for device...");
5792
5793 /* We don't handle multi-config cameras */
5794 if (dev->descriptor.bNumConfigurations != 1)
5795 return -ENODEV;
5796
5797 idesc = &intf->cur_altsetting->desc;
5798
5799 if (idesc->bInterfaceClass != 0xFF)
5800 return -ENODEV;
5801 if (idesc->bInterfaceSubClass != 0x00)
5802 return -ENODEV;
5803
5804 if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) {
5805 err("couldn't kmalloc ov struct");
5806 goto error_out;
5807 }
5808
5809 memset(ov, 0, sizeof(*ov));
5810
5811 ov->dev = dev;
5812 ov->iface = idesc->bInterfaceNumber;
5813 ov->led_policy = led;
5814 ov->compress = compress;
5815 ov->lightfreq = lightfreq;
5816 ov->num_inputs = 1; /* Video decoder init functs. change this */
5817 ov->stop_during_set = !fastset;
5818 ov->backlight = backlight;
5819 ov->mirror = mirror;
5820 ov->auto_brt = autobright;
5821 ov->auto_gain = autogain;
5822 ov->auto_exp = autoexp;
5823
5824 switch (le16_to_cpu(dev->descriptor.idProduct)) {
5825 case PROD_OV511:
5826 ov->bridge = BRG_OV511;
5827 ov->bclass = BCL_OV511;
5828 break;
5829 case PROD_OV511PLUS:
5830 ov->bridge = BRG_OV511PLUS;
5831 ov->bclass = BCL_OV511;
5832 break;
5833 case PROD_OV518:
5834 ov->bridge = BRG_OV518;
5835 ov->bclass = BCL_OV518;
5836 break;
5837 case PROD_OV518PLUS:
5838 ov->bridge = BRG_OV518PLUS;
5839 ov->bclass = BCL_OV518;
5840 break;
5841 case PROD_ME2CAM:
5842 if (le16_to_cpu(dev->descriptor.idVendor) != VEND_MATTEL)
5843 goto error;
5844 ov->bridge = BRG_OV511PLUS;
5845 ov->bclass = BCL_OV511;
5846 break;
5847 default:
5848 err("Unknown product ID 0x%04x", le16_to_cpu(dev->descriptor.idProduct));
5849 goto error;
5850 }
5851
5852 info("USB %s video device found", symbolic(brglist, ov->bridge));
5853
5854 init_waitqueue_head(&ov->wq);
5855
5856 init_MUTEX(&ov->lock); /* to 1 == available */
5857 init_MUTEX(&ov->buf_lock);
5858 init_MUTEX(&ov->param_lock);
5859 init_MUTEX(&ov->i2c_lock);
5860 init_MUTEX(&ov->cbuf_lock);
5861
5862 ov->buf_state = BUF_NOT_ALLOCATED;
5863
5864 if (usb_make_path(dev, ov->usb_path, OV511_USB_PATH_LEN) < 0) {
5865 err("usb_make_path error");
5866 goto error;
5867 }
5868
5869 /* Allocate control transfer buffer. */
5870 /* Must be kmalloc()'ed, for DMA compatibility */
5871 ov->cbuf = kmalloc(OV511_CBUF_SIZE, GFP_KERNEL);
5872 if (!ov->cbuf)
5873 goto error;
5874
5875 if (ov->bclass == BCL_OV518) {
5876 if (ov518_configure(ov) < 0)
5877 goto error;
5878 } else {
5879 if (ov511_configure(ov) < 0)
5880 goto error;
5881 }
5882
5883 for (i = 0; i < OV511_NUMFRAMES; i++) {
5884 ov->frame[i].framenum = i;
5885 init_waitqueue_head(&ov->frame[i].wq);
5886 }
5887
5888 for (i = 0; i < OV511_NUMSBUF; i++) {
5889 ov->sbuf[i].ov = ov;
5890 spin_lock_init(&ov->sbuf[i].lock);
5891 ov->sbuf[i].n = i;
5892 }
5893
5894 /* Unnecessary? (This is done on open(). Need to make sure variables
5895 * are properly initialized without this before removing it, though). */
5896 if (ov51x_set_default_params(ov) < 0)
5897 goto error;
5898
5899#ifdef OV511_DEBUG
5900 if (dump_bridge) {
5901 if (ov->bclass == BCL_OV511)
5902 ov511_dump_regs(ov);
5903 else
5904 ov518_dump_regs(ov);
5905 }
5906#endif
5907
5908 ov->vdev = video_device_alloc();
5909 if (!ov->vdev)
5910 goto error;
5911
5912 memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev));
5913 ov->vdev->dev = &dev->dev;
5914 video_set_drvdata(ov->vdev, ov);
5915
5916 for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) {
5917 /* Minor 0 cannot be specified; assume user wants autodetect */
5918 if (unit_video[i] == 0)
5919 break;
5920
5921 if (video_register_device(ov->vdev, VFL_TYPE_GRABBER,
5922 unit_video[i]) >= 0) {
5923 break;
5924 }
5925 }
5926
5927 /* Use the next available one */
5928 if ((ov->vdev->minor == -1) &&
5929 video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1) < 0) {
5930 err("video_register_device failed");
5931 goto error;
5932 }
5933
5934 info("Device at %s registered to minor %d", ov->usb_path,
5935 ov->vdev->minor);
5936
5937 usb_set_intfdata(intf, ov);
5938 ov_create_sysfs(ov->vdev);
5939 return 0;
5940
5941error:
5942 if (ov->vdev) {
5943 if (-1 == ov->vdev->minor)
5944 video_device_release(ov->vdev);
5945 else
5946 video_unregister_device(ov->vdev);
5947 ov->vdev = NULL;
5948 }
5949
5950 if (ov->cbuf) {
5951 down(&ov->cbuf_lock);
5952 kfree(ov->cbuf);
5953 ov->cbuf = NULL;
5954 up(&ov->cbuf_lock);
5955 }
5956
5957 if (ov) {
5958 kfree(ov);
5959 ov = NULL;
5960 }
5961
5962error_out:
5963 err("Camera initialization failed");
5964 return -EIO;
5965}
5966
5967static void
5968ov51x_disconnect(struct usb_interface *intf)
5969{
5970 struct usb_ov511 *ov = usb_get_intfdata(intf);
5971 int n;
5972
5973 PDEBUG(3, "");
5974
5975 usb_set_intfdata (intf, NULL);
5976
5977 if (!ov)
5978 return;
5979
5980 if (ov->vdev)
5981 video_unregister_device(ov->vdev);
5982
5983 for (n = 0; n < OV511_NUMFRAMES; n++)
5984 ov->frame[n].grabstate = FRAME_ERROR;
5985
5986 ov->curframe = -1;
5987
5988 /* This will cause the process to request another frame */
5989 for (n = 0; n < OV511_NUMFRAMES; n++)
5990 wake_up_interruptible(&ov->frame[n].wq);
5991
5992 wake_up_interruptible(&ov->wq);
5993
5994 ov->streaming = 0;
5995 ov51x_unlink_isoc(ov);
5996
5997 ov->dev = NULL;
5998
5999 /* Free the memory */
6000 if (ov && !ov->user) {
6001 down(&ov->cbuf_lock);
6002 kfree(ov->cbuf);
6003 ov->cbuf = NULL;
6004 up(&ov->cbuf_lock);
6005
6006 ov51x_dealloc(ov);
6007 kfree(ov);
6008 ov = NULL;
6009 }
6010
6011 PDEBUG(3, "Disconnect complete");
6012}
6013
6014static struct usb_driver ov511_driver = {
6015 .owner = THIS_MODULE,
6016 .name = "ov511",
6017 .id_table = device_table,
6018 .probe = ov51x_probe,
6019 .disconnect = ov51x_disconnect
6020};
6021
6022/****************************************************************************
6023 *
6024 * Module routines
6025 *
6026 ***************************************************************************/
6027
6028/* Returns 0 for success */
6029int
6030ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops, int ov518,
6031 int mmx)
6032{
6033 if (ver != DECOMP_INTERFACE_VER) {
6034 err("Decompression module has incompatible");
6035 err("interface version %d", ver);
6036 err("Interface version %d is required", DECOMP_INTERFACE_VER);
6037 return -EINVAL;
6038 }
6039
6040 if (!ops)
6041 return -EFAULT;
6042
6043 if (mmx && !ov51x_mmx_available) {
6044 err("MMX not available on this system or kernel");
6045 return -EINVAL;
6046 }
6047
6048 lock_kernel();
6049
6050 if (ov518) {
6051 if (mmx) {
6052 if (ov518_mmx_decomp_ops)
6053 goto err_in_use;
6054 else
6055 ov518_mmx_decomp_ops = ops;
6056 } else {
6057 if (ov518_decomp_ops)
6058 goto err_in_use;
6059 else
6060 ov518_decomp_ops = ops;
6061 }
6062 } else {
6063 if (mmx) {
6064 if (ov511_mmx_decomp_ops)
6065 goto err_in_use;
6066 else
6067 ov511_mmx_decomp_ops = ops;
6068 } else {
6069 if (ov511_decomp_ops)
6070 goto err_in_use;
6071 else
6072 ov511_decomp_ops = ops;
6073 }
6074 }
6075
6076 unlock_kernel();
6077 return 0;
6078
6079err_in_use:
6080 unlock_kernel();
6081 return -EBUSY;
6082}
6083
6084void
6085ov511_deregister_decomp_module(int ov518, int mmx)
6086{
6087 lock_kernel();
6088
6089 if (ov518) {
6090 if (mmx)
6091 ov518_mmx_decomp_ops = NULL;
6092 else
6093 ov518_decomp_ops = NULL;
6094 } else {
6095 if (mmx)
6096 ov511_mmx_decomp_ops = NULL;
6097 else
6098 ov511_decomp_ops = NULL;
6099 }
6100
6101 unlock_kernel();
6102}
6103
6104static int __init
6105usb_ov511_init(void)
6106{
6107 int retval;
6108
6109 retval = usb_register(&ov511_driver);
6110 if (retval)
6111 goto out;
6112
6113 info(DRIVER_VERSION " : " DRIVER_DESC);
6114
6115out:
6116 return retval;
6117}
6118
6119static void __exit
6120usb_ov511_exit(void)
6121{
6122 usb_deregister(&ov511_driver);
6123 info("driver deregistered");
6124
6125}
6126
6127module_init(usb_ov511_init);
6128module_exit(usb_ov511_exit);
6129
6130EXPORT_SYMBOL(ov511_register_decomp_module);
6131EXPORT_SYMBOL(ov511_deregister_decomp_module);
diff --git a/drivers/usb/media/ov511.h b/drivers/usb/media/ov511.h
new file mode 100644
index 000000000000..086509a137c6
--- /dev/null
+++ b/drivers/usb/media/ov511.h
@@ -0,0 +1,569 @@
1#ifndef __LINUX_OV511_H
2#define __LINUX_OV511_H
3
4#include <asm/uaccess.h>
5#include <linux/videodev.h>
6#include <linux/smp_lock.h>
7#include <linux/usb.h>
8
9#define OV511_DEBUG /* Turn on debug messages */
10
11#ifdef OV511_DEBUG
12 #define PDEBUG(level, fmt, args...) \
13 if (debug >= (level)) info("[%s:%d] " fmt, \
14 __FUNCTION__, __LINE__ , ## args)
15#else
16 #define PDEBUG(level, fmt, args...) do {} while(0)
17#endif
18
19/* This macro restricts an int variable to an inclusive range */
20#define RESTRICT_TO_RANGE(v,mi,ma) { \
21 if ((v) < (mi)) (v) = (mi); \
22 else if ((v) > (ma)) (v) = (ma); \
23}
24
25/* --------------------------------- */
26/* DEFINES FOR OV511 AND OTHER CHIPS */
27/* --------------------------------- */
28
29/* USB IDs */
30#define VEND_OMNIVISION 0x05A9
31#define PROD_OV511 0x0511
32#define PROD_OV511PLUS 0xA511
33#define PROD_OV518 0x0518
34#define PROD_OV518PLUS 0xA518
35
36#define VEND_MATTEL 0x0813
37#define PROD_ME2CAM 0x0002
38
39/* --------------------------------- */
40/* OV51x REGISTER MNEMONICS */
41/* --------------------------------- */
42
43/* Camera interface register numbers */
44#define R511_CAM_DELAY 0x10
45#define R511_CAM_EDGE 0x11
46#define R511_CAM_PXCNT 0x12
47#define R511_CAM_LNCNT 0x13
48#define R511_CAM_PXDIV 0x14
49#define R511_CAM_LNDIV 0x15
50#define R511_CAM_UV_EN 0x16
51#define R511_CAM_LINE_MODE 0x17
52#define R511_CAM_OPTS 0x18
53
54/* Snapshot mode camera interface register numbers */
55#define R511_SNAP_FRAME 0x19
56#define R511_SNAP_PXCNT 0x1A
57#define R511_SNAP_LNCNT 0x1B
58#define R511_SNAP_PXDIV 0x1C
59#define R511_SNAP_LNDIV 0x1D
60#define R511_SNAP_UV_EN 0x1E
61#define R511_SNAP_OPTS 0x1F
62
63/* DRAM register numbers */
64#define R511_DRAM_FLOW_CTL 0x20
65#define R511_DRAM_ARCP 0x21
66#define R511_DRAM_MRC 0x22
67#define R511_DRAM_RFC 0x23
68
69/* ISO FIFO register numbers */
70#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
71#define R511_FIFO_OPTS 0x31
72
73/* Parallel IO register numbers */
74#define R511_PIO_OPTS 0x38
75#define R511_PIO_DATA 0x39
76#define R511_PIO_BIST 0x3E
77#define R518_GPIO_IN 0x55 /* OV518(+) only */
78#define R518_GPIO_OUT 0x56 /* OV518(+) only */
79#define R518_GPIO_CTL 0x57 /* OV518(+) only */
80#define R518_GPIO_PULSE_IN 0x58 /* OV518(+) only */
81#define R518_GPIO_PULSE_CLEAR 0x59 /* OV518(+) only */
82#define R518_GPIO_PULSE_POL 0x5a /* OV518(+) only */
83#define R518_GPIO_PULSE_EN 0x5b /* OV518(+) only */
84#define R518_GPIO_RESET 0x5c /* OV518(+) only */
85
86/* I2C registers */
87#define R511_I2C_CTL 0x40
88#define R518_I2C_CTL 0x47 /* OV518(+) only */
89#define R51x_I2C_W_SID 0x41
90#define R51x_I2C_SADDR_3 0x42
91#define R51x_I2C_SADDR_2 0x43
92#define R51x_I2C_R_SID 0x44
93#define R51x_I2C_DATA 0x45
94#define R51x_I2C_CLOCK 0x46
95#define R51x_I2C_TIMEOUT 0x47
96
97/* I2C snapshot registers */
98#define R511_SI2C_SADDR_3 0x48
99#define R511_SI2C_DATA 0x49
100
101/* System control registers */
102#define R51x_SYS_RESET 0x50
103 /* Reset type definitions */
104#define OV511_RESET_UDC 0x01
105#define OV511_RESET_I2C 0x02
106#define OV511_RESET_FIFO 0x04
107#define OV511_RESET_OMNICE 0x08
108#define OV511_RESET_DRAM 0x10
109#define OV511_RESET_CAM_INT 0x20
110#define OV511_RESET_OV511 0x40
111#define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */
112#define OV511_RESET_ALL 0x7F
113
114#define R511_SYS_CLOCK_DIV 0x51
115#define R51x_SYS_SNAP 0x52
116#define R51x_SYS_INIT 0x53
117#define R511_SYS_PWR_CLK 0x54 /* OV511+/OV518(+) only */
118#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
119#define R511_SYS_USER 0x5E
120#define R511_SYS_CUST_ID 0x5F
121
122/* OmniCE (compression) registers */
123#define R511_COMP_PHY 0x70
124#define R511_COMP_PHUV 0x71
125#define R511_COMP_PVY 0x72
126#define R511_COMP_PVUV 0x73
127#define R511_COMP_QHY 0x74
128#define R511_COMP_QHUV 0x75
129#define R511_COMP_QVY 0x76
130#define R511_COMP_QVUV 0x77
131#define R511_COMP_EN 0x78
132#define R511_COMP_LUT_EN 0x79
133#define R511_COMP_LUT_BEGIN 0x80
134
135/* --------------------------------- */
136/* ALTERNATE NUMBERS */
137/* --------------------------------- */
138
139/* Alternate numbers for various max packet sizes (OV511 only) */
140#define OV511_ALT_SIZE_992 0
141#define OV511_ALT_SIZE_993 1
142#define OV511_ALT_SIZE_768 2
143#define OV511_ALT_SIZE_769 3
144#define OV511_ALT_SIZE_512 4
145#define OV511_ALT_SIZE_513 5
146#define OV511_ALT_SIZE_257 6
147#define OV511_ALT_SIZE_0 7
148
149/* Alternate numbers for various max packet sizes (OV511+ only) */
150#define OV511PLUS_ALT_SIZE_0 0
151#define OV511PLUS_ALT_SIZE_33 1
152#define OV511PLUS_ALT_SIZE_129 2
153#define OV511PLUS_ALT_SIZE_257 3
154#define OV511PLUS_ALT_SIZE_385 4
155#define OV511PLUS_ALT_SIZE_513 5
156#define OV511PLUS_ALT_SIZE_769 6
157#define OV511PLUS_ALT_SIZE_961 7
158
159/* Alternate numbers for various max packet sizes (OV518(+) only) */
160#define OV518_ALT_SIZE_0 0
161#define OV518_ALT_SIZE_128 1
162#define OV518_ALT_SIZE_256 2
163#define OV518_ALT_SIZE_384 3
164#define OV518_ALT_SIZE_512 4
165#define OV518_ALT_SIZE_640 5
166#define OV518_ALT_SIZE_768 6
167#define OV518_ALT_SIZE_896 7
168
169/* --------------------------------- */
170/* OV7610 REGISTER MNEMONICS */
171/* --------------------------------- */
172
173/* OV7610 registers */
174#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
175#define OV7610_REG_BLUE 0x01 /* blue channel balance */
176#define OV7610_REG_RED 0x02 /* red channel balance */
177#define OV7610_REG_SAT 0x03 /* saturation */
178 /* 04 reserved */
179#define OV7610_REG_CNT 0x05 /* Y contrast */
180#define OV7610_REG_BRT 0x06 /* Y brightness */
181 /* 08-0b reserved */
182#define OV7610_REG_BLUE_BIAS 0x0C /* blue channel bias (5:0) */
183#define OV7610_REG_RED_BIAS 0x0D /* read channel bias (5:0) */
184#define OV7610_REG_GAMMA_COEFF 0x0E /* gamma settings */
185#define OV7610_REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */
186#define OV7610_REG_EXP 0x10 /* manual exposure setting */
187#define OV7610_REG_CLOCK 0x11 /* polarity/clock prescaler */
188#define OV7610_REG_COM_A 0x12 /* misc common regs */
189#define OV7610_REG_COM_B 0x13 /* misc common regs */
190#define OV7610_REG_COM_C 0x14 /* misc common regs */
191#define OV7610_REG_COM_D 0x15 /* misc common regs */
192#define OV7610_REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */
193#define OV7610_REG_HWIN_START 0x17 /* horizontal window start */
194#define OV7610_REG_HWIN_END 0x18 /* horizontal window end */
195#define OV7610_REG_VWIN_START 0x19 /* vertical window start */
196#define OV7610_REG_VWIN_END 0x1A /* vertical window end */
197#define OV7610_REG_PIXEL_SHIFT 0x1B /* pixel shift */
198#define OV7610_REG_ID_HIGH 0x1C /* manufacturer ID MSB */
199#define OV7610_REG_ID_LOW 0x1D /* manufacturer ID LSB */
200 /* 0e-0f reserved */
201#define OV7610_REG_COM_E 0x20 /* misc common regs */
202#define OV7610_REG_YOFFSET 0x21 /* Y channel offset */
203#define OV7610_REG_UOFFSET 0x22 /* U channel offset */
204 /* 23 reserved */
205#define OV7610_REG_ECW 0x24 /* Exposure white level for AEC */
206#define OV7610_REG_ECB 0x25 /* Exposure black level for AEC */
207#define OV7610_REG_COM_F 0x26 /* misc settings */
208#define OV7610_REG_COM_G 0x27 /* misc settings */
209#define OV7610_REG_COM_H 0x28 /* misc settings */
210#define OV7610_REG_COM_I 0x29 /* misc settings */
211#define OV7610_REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */
212#define OV7610_REG_FRAMERATE_L 0x2B /* frame rate LSB */
213#define OV7610_REG_ALC 0x2C /* Auto Level Control settings */
214#define OV7610_REG_COM_J 0x2D /* misc settings */
215#define OV7610_REG_VOFFSET 0x2E /* V channel offset adjustment */
216#define OV7610_REG_ARRAY_BIAS 0x2F /* Array bias -- don't change */
217 /* 30-32 reserved */
218#define OV7610_REG_YGAMMA 0x33 /* misc gamma settings (7:6) */
219#define OV7610_REG_BIAS_ADJUST 0x34 /* misc bias settings */
220#define OV7610_REG_COM_L 0x35 /* misc settings */
221 /* 36-37 reserved */
222#define OV7610_REG_COM_K 0x38 /* misc registers */
223
224/* --------------------------------- */
225/* I2C ADDRESSES */
226/* --------------------------------- */
227
228#define OV7xx0_SID 0x42
229#define OV6xx0_SID 0xC0
230#define OV8xx0_SID 0xA0
231#define KS0127_SID 0xD8
232#define SAA7111A_SID 0x48
233
234/* --------------------------------- */
235/* MISCELLANEOUS DEFINES */
236/* --------------------------------- */
237
238#define I2C_CLOCK_PRESCALER 0x03
239
240#define FRAMES_PER_DESC 10 /* FIXME - What should this be? */
241#define MAX_FRAME_SIZE_PER_DESC 993 /* For statically allocated stuff */
242#define PIXELS_PER_SEG 256 /* Pixels per segment */
243
244#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
245
246#define OV511_NUMFRAMES 2
247#if OV511_NUMFRAMES > VIDEO_MAX_FRAME
248 #error "OV511_NUMFRAMES is too high"
249#endif
250
251#define OV511_NUMSBUF 2
252
253/* Control transfers use up to 4 bytes */
254#define OV511_CBUF_SIZE 4
255
256/* Size of usb_make_path() buffer */
257#define OV511_USB_PATH_LEN 64
258
259/* Bridge types */
260enum {
261 BRG_UNKNOWN,
262 BRG_OV511,
263 BRG_OV511PLUS,
264 BRG_OV518,
265 BRG_OV518PLUS,
266};
267
268/* Bridge classes */
269enum {
270 BCL_UNKNOWN,
271 BCL_OV511,
272 BCL_OV518,
273};
274
275/* Sensor types */
276enum {
277 SEN_UNKNOWN,
278 SEN_OV76BE,
279 SEN_OV7610,
280 SEN_OV7620,
281 SEN_OV7620AE,
282 SEN_OV6620,
283 SEN_OV6630,
284 SEN_OV6630AE,
285 SEN_OV6630AF,
286 SEN_OV8600,
287 SEN_KS0127,
288 SEN_KS0127B,
289 SEN_SAA7111A,
290};
291
292enum {
293 STATE_SCANNING, /* Scanning for start */
294 STATE_HEADER, /* Parsing header */
295 STATE_LINES, /* Parsing lines */
296};
297
298/* Buffer states */
299enum {
300 BUF_NOT_ALLOCATED,
301 BUF_ALLOCATED,
302};
303
304/* --------- Definition of ioctl interface --------- */
305
306#define OV511_INTERFACE_VER 101
307
308/* LED options */
309enum {
310 LED_OFF,
311 LED_ON,
312 LED_AUTO,
313};
314
315/* Raw frame formats */
316enum {
317 RAWFMT_INVALID,
318 RAWFMT_YUV400,
319 RAWFMT_YUV420,
320 RAWFMT_YUV422,
321 RAWFMT_GBR422,
322};
323
324struct ov511_i2c_struct {
325 unsigned char slave; /* Write slave ID (read ID - 1) */
326 unsigned char reg; /* Index of register */
327 unsigned char value; /* User sets this w/ write, driver does w/ read */
328 unsigned char mask; /* Bits to be changed. Not used with read ops */
329};
330
331/* ioctls */
332#define OV511IOC_WI2C _IOW('v', BASE_VIDIOCPRIVATE + 5, \
333 struct ov511_i2c_struct)
334#define OV511IOC_RI2C _IOWR('v', BASE_VIDIOCPRIVATE + 6, \
335 struct ov511_i2c_struct)
336/* ------------- End IOCTL interface -------------- */
337
338struct usb_ov511; /* Forward declaration */
339
340struct ov511_sbuf {
341 struct usb_ov511 *ov;
342 unsigned char *data;
343 struct urb *urb;
344 spinlock_t lock;
345 int n;
346};
347
348enum {
349 FRAME_UNUSED, /* Unused (no MCAPTURE) */
350 FRAME_READY, /* Ready to start grabbing */
351 FRAME_GRABBING, /* In the process of being grabbed into */
352 FRAME_DONE, /* Finished grabbing, but not been synced yet */
353 FRAME_ERROR, /* Something bad happened while processing */
354};
355
356struct ov511_regvals {
357 enum {
358 OV511_DONE_BUS,
359 OV511_REG_BUS,
360 OV511_I2C_BUS,
361 } bus;
362 unsigned char reg;
363 unsigned char val;
364};
365
366struct ov511_frame {
367 int framenum; /* Index of this frame */
368 unsigned char *data; /* Frame buffer */
369 unsigned char *tempdata; /* Temp buffer for multi-stage conversions */
370 unsigned char *rawdata; /* Raw camera data buffer */
371 unsigned char *compbuf; /* Temp buffer for decompressor */
372
373 int depth; /* Bytes per pixel */
374 int width; /* Width application is expecting */
375 int height; /* Height application is expecting */
376
377 int rawwidth; /* Actual width of frame sent from camera */
378 int rawheight; /* Actual height of frame sent from camera */
379
380 int sub_flag; /* Sub-capture mode for this frame? */
381 unsigned int format; /* Format for this frame */
382 int compressed; /* Is frame compressed? */
383
384 volatile int grabstate; /* State of grabbing */
385 int scanstate; /* State of scanning */
386
387 int bytes_recvd; /* Number of image bytes received from camera */
388
389 long bytes_read; /* Amount that has been read() */
390
391 wait_queue_head_t wq; /* Processes waiting */
392
393 int snapshot; /* True if frame was a snapshot */
394};
395
396#define DECOMP_INTERFACE_VER 4
397
398/* Compression module operations */
399struct ov51x_decomp_ops {
400 int (*decomp_400)(unsigned char *, unsigned char *, unsigned char *,
401 int, int, int);
402 int (*decomp_420)(unsigned char *, unsigned char *, unsigned char *,
403 int, int, int);
404 int (*decomp_422)(unsigned char *, unsigned char *, unsigned char *,
405 int, int, int);
406 struct module *owner;
407};
408
409struct usb_ov511 {
410 struct video_device *vdev;
411 struct usb_device *dev;
412
413 int customid;
414 char *desc;
415 unsigned char iface;
416 char usb_path[OV511_USB_PATH_LEN];
417
418 /* Determined by sensor type */
419 int maxwidth;
420 int maxheight;
421 int minwidth;
422 int minheight;
423
424 int brightness;
425 int colour;
426 int contrast;
427 int hue;
428 int whiteness;
429 int exposure;
430 int auto_brt; /* Auto brightness enabled flag */
431 int auto_gain; /* Auto gain control enabled flag */
432 int auto_exp; /* Auto exposure enabled flag */
433 int backlight; /* Backlight exposure algorithm flag */
434 int mirror; /* Image is reversed horizontally */
435
436 int led_policy; /* LED: off|on|auto; OV511+ only */
437
438 struct semaphore lock; /* Serializes user-accessible operations */
439 int user; /* user count for exclusive use */
440
441 int streaming; /* Are we streaming Isochronous? */
442 int grabbing; /* Are we grabbing? */
443
444 int compress; /* Should the next frame be compressed? */
445 int compress_inited; /* Are compression params uploaded? */
446
447 int lightfreq; /* Power (lighting) frequency */
448 int bandfilt; /* Banding filter enabled flag */
449
450 unsigned char *fbuf; /* Videodev buffer area */
451 unsigned char *tempfbuf; /* Temporary (intermediate) buffer area */
452 unsigned char *rawfbuf; /* Raw camera data buffer area */
453
454 int sub_flag; /* Pix Array subcapture on flag */
455 int subx; /* Pix Array subcapture x offset */
456 int suby; /* Pix Array subcapture y offset */
457 int subw; /* Pix Array subcapture width */
458 int subh; /* Pix Array subcapture height */
459
460 int curframe; /* Current receiving sbuf */
461 struct ov511_frame frame[OV511_NUMFRAMES];
462
463 struct ov511_sbuf sbuf[OV511_NUMSBUF];
464
465 wait_queue_head_t wq; /* Processes waiting */
466
467 int snap_enabled; /* Snapshot mode enabled */
468
469 int bridge; /* Type of bridge (BRG_*) */
470 int bclass; /* Class of bridge (BCL_*) */
471 int sensor; /* Type of image sensor chip (SEN_*) */
472
473 int packet_size; /* Frame size per isoc desc */
474 int packet_numbering; /* Is ISO frame numbering enabled? */
475
476 struct semaphore param_lock; /* params lock for this camera */
477
478 /* Framebuffer/sbuf management */
479 int buf_state;
480 struct semaphore buf_lock;
481
482 struct ov51x_decomp_ops *decomp_ops;
483
484 /* Stop streaming while changing picture settings */
485 int stop_during_set;
486
487 int stopped; /* Streaming is temporarily paused */
488
489 /* Video decoder stuff */
490 int input; /* Composite, S-VIDEO, etc... */
491 int num_inputs; /* Number of inputs */
492 int norm; /* NTSC / PAL / SECAM */
493 int has_decoder; /* Device has a video decoder */
494 int pal; /* Device is designed for PAL resolution */
495
496 /* I2C interface */
497 struct semaphore i2c_lock; /* Protect I2C controller regs */
498 unsigned char primary_i2c_slave; /* I2C write id of sensor */
499
500 /* Control transaction stuff */
501 unsigned char *cbuf; /* Buffer for payload */
502 struct semaphore cbuf_lock;
503};
504
505/* Used to represent a list of values and their respective symbolic names */
506struct symbolic_list {
507 int num;
508 char *name;
509};
510
511#define NOT_DEFINED_STR "Unknown"
512
513/* Returns the name of the matching element in the symbolic_list array. The
514 * end of the list must be marked with an element that has a NULL name.
515 */
516static inline char *
517symbolic(struct symbolic_list list[], int num)
518{
519 int i;
520
521 for (i = 0; list[i].name != NULL; i++)
522 if (list[i].num == num)
523 return (list[i].name);
524
525 return (NOT_DEFINED_STR);
526}
527
528/* Compression stuff */
529
530#define OV511_QUANTABLESIZE 64
531#define OV518_QUANTABLESIZE 32
532
533#define OV511_YQUANTABLE { \
534 0, 1, 1, 2, 2, 3, 3, 4, \
535 1, 1, 1, 2, 2, 3, 4, 4, \
536 1, 1, 2, 2, 3, 4, 4, 4, \
537 2, 2, 2, 3, 4, 4, 4, 4, \
538 2, 2, 3, 4, 4, 5, 5, 5, \
539 3, 3, 4, 4, 5, 5, 5, 5, \
540 3, 4, 4, 4, 5, 5, 5, 5, \
541 4, 4, 4, 4, 5, 5, 5, 5 \
542}
543
544#define OV511_UVQUANTABLE { \
545 0, 2, 2, 3, 4, 4, 4, 4, \
546 2, 2, 2, 4, 4, 4, 4, 4, \
547 2, 2, 3, 4, 4, 4, 4, 4, \
548 3, 4, 4, 4, 4, 4, 4, 4, \
549 4, 4, 4, 4, 4, 4, 4, 4, \
550 4, 4, 4, 4, 4, 4, 4, 4, \
551 4, 4, 4, 4, 4, 4, 4, 4, \
552 4, 4, 4, 4, 4, 4, 4, 4 \
553}
554
555#define OV518_YQUANTABLE { \
556 5, 4, 5, 6, 6, 7, 7, 7, \
557 5, 5, 5, 5, 6, 7, 7, 7, \
558 6, 6, 6, 6, 7, 7, 7, 8, \
559 7, 7, 6, 7, 7, 7, 8, 8 \
560}
561
562#define OV518_UVQUANTABLE { \
563 6, 6, 6, 7, 7, 7, 7, 7, \
564 6, 6, 6, 7, 7, 7, 7, 7, \
565 6, 6, 6, 7, 7, 7, 7, 8, \
566 7, 7, 7, 7, 7, 7, 8, 8 \
567}
568
569#endif
diff --git a/drivers/usb/media/pwc/ChangeLog b/drivers/usb/media/pwc/ChangeLog
new file mode 100644
index 000000000000..b2eb71a9afb5
--- /dev/null
+++ b/drivers/usb/media/pwc/ChangeLog
@@ -0,0 +1,143 @@
19.0.2
2
3* Adding #ifdef to compile PWC before and after 2.6.5
4
59.0.1
6
79.0
8
9
108.12
11
12* Implement motorized pan/tilt feature for Logitech QuickCam Orbit/Spere.
13
148.11.1
15
16* Fix for PCVC720/40, would not be able to set videomode
17* Fix for Samsung MPC models, appearantly they are based on a newer chipset
18
198.11
20
21* 20 dev_hints (per request)
22* Hot unplugging should be better, no more dangling pointers or memory leaks
23* Added reserved Logitech webcam IDs
24* Device now remembers size & fps between close()/open()
25* Removed palette stuff altogether
26
278.10.1
28
29* Added IDs for PCVC720K/40 and Creative Labs Webcam Pro
30
318.10
32
33* Fixed ID for QuickCam Notebook pro
34* Added GREALSIZE ioctl() call
35* Fixed bug in case PWCX was not loaded and invalid size was set
36
378.9
38
39* Merging with kernel 2.5.49
40* Adding IDs for QuickCam Zoom & QuickCam Notebook
41
428.8
43
44* Fixing 'leds' parameter
45* Adding IDs for Logitech QuickCam Pro 4000
46* Making URB init/cleanup a little nicer
47
488.7
49
50* Incorporating changes in ioctl() parameter passing
51* Also changes to URB mechanism
52
538.6
54
55* Added ID's for Visionite VCS UM100 and UC300
56* Removed YUV420-interlaced palette altogether (was confusing)
57* Removed MIRROR stuff as it didn't work anyway
58* Fixed a problem with the 'leds' parameter (wouldn't blink)
59* Added ioctl()s for advanced features: 'extended' whitebalance ioctl()s,
60 CONTOUR, BACKLIGHT, FLICKER, DYNNOISE.
61* VIDIOCGCAP.name now contains real camera model name instead of
62 'Philips xxx webcam'
63* Added PROBE ioctl (see previous point & API doc)
64
658.5
66
67* Adding IDs for Creative Labs Webcam 5
68* Adding IDs for SOTEC CMS-001 webcam
69* Solving possible hang in VIDIOCSYNC when unplugging the cam
70* Forgot to return structure in VIDIOCPWCGAWB, oops
71* Time interval for the LEDs are now in milliseconds
72
738.4
74
75* Fixing power_save option for Vesta range
76* Handling new error codes in ISOC callback
77* Adding dev_hint module parameter, to specify /dev/videoX device nodes
78
798.3
80
81* Adding Samsung C10 and C30 cameras
82* Removing palette module parameter
83* Fixed typo in ID of QuickCam 3000 Pro
84* Adding LED settings (blinking while in use) for ToUCam cameras.
85* Turns LED off when camera is not in use.
86
878.2
88
89* Making module more silent when trace = 0
90* Adding QuickCam 3000 Pro IDs
91* Chrominance control for the Vesta cameras
92* Hopefully fixed problems on machines with BIGMEM and > 1GB of RAM
93* Included Oliver Neukem's lock_kernel() patch
94* Allocates less memory for image buffers
95* Adds ioctl()s for the whitebalancing
96
978.1
98
99* Adding support for 750
100* Adding V4L GAUDIO/SAUDIO/UNIT ioctl() calls
101
1028.0
103* 'damage control' after inclusion in 2.4.5.
104* Changed wait-queue mechanism in read/mmap/poll according to the book.
105* Included YUV420P palette.
106* Changed interface to decompressor module.
107* Cleaned up pwc structure a bit.
108
1097.0
110
111* Fixed bug in vcvt_420i_yuyv; extra variables on stack were misaligned.
112* There is now a clear error message when an image size is selected that
113 is only supported using the decompressor, and the decompressor isn't
114 loaded.
115* When the decompressor wasn't loaded, selecting large image size
116 would create skewed or double images.
117
1186.3
119
120* Introduced spinlocks for the buffer pointer manipulation; a number of
121 reports seem to suggest the down()/up() semaphores were the cause of
122 lockups, since they are not suitable for interrupt/user locking.
123* Separated decompressor and core code into 2 modules.
124
1256.2
126
127* Non-integral image sizes are now padded with gray or black.
128* Added SHUTTERSPEED ioctl().
129* Fixed buglet in VIDIOCPWCSAGC; the function would always return an error,
130 even though the call succeeded.
131* Added hotplug support for 2.4.*.
132* Memory: the 645/646 uses less memory now.
133
1346.1
135
136* VIDIOCSPICT returns -EINVAL with invalid palettes.
137* Added saturation control.
138* Split decompressors from rest.
139* Fixed bug that would reset the framerate to the default framerate if
140 the rate field was set to 0 (which is not what I intended, nl. do not
141 change the framerate!).
142* VIDIOCPWCSCQUAL (setting compression quality) now takes effect immediately.
143* Workaround for a bug in the 730 sensor.
diff --git a/drivers/usb/media/pwc/Makefile b/drivers/usb/media/pwc/Makefile
new file mode 100644
index 000000000000..e0b41ed4407f
--- /dev/null
+++ b/drivers/usb/media/pwc/Makefile
@@ -0,0 +1,20 @@
1ifneq ($(KERNELRELEASE),)
2
3pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-dec1.o pwc-dec23.o pwc-kiara.o pwc-timon.o
4
5obj-$(CONFIG_USB_PWC) += pwc.o
6
7else
8
9KDIR := /lib/modules/$(shell uname -r)/build
10PWD := $(shell pwd)
11
12default:
13 $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
14
15endif
16
17clean:
18 rm -f *.[oas] .*.flags *.ko .*.cmd .*.d .*.tmp *.mod.c
19 rm -rf .tmp_versions
20
diff --git a/drivers/usb/media/pwc/philips.txt b/drivers/usb/media/pwc/philips.txt
new file mode 100644
index 000000000000..04a640d723ed
--- /dev/null
+++ b/drivers/usb/media/pwc/philips.txt
@@ -0,0 +1,236 @@
1This file contains some additional information for the Philips and OEM webcams.
2E-mail: webcam@smcc.demon.nl Last updated: 2004-01-19
3Site: http://www.smcc.demon.nl/webcam/
4
5As of this moment, the following cameras are supported:
6 * Philips PCA645
7 * Philips PCA646
8 * Philips PCVC675
9 * Philips PCVC680
10 * Philips PCVC690
11 * Philips PCVC720/40
12 * Philips PCVC730
13 * Philips PCVC740
14 * Philips PCVC750
15 * Askey VC010
16 * Creative Labs Webcam 5
17 * Creative Labs Webcam Pro Ex
18 * Logitech QuickCam 3000 Pro
19 * Logitech QuickCam 4000 Pro
20 * Logitech QuickCam Notebook Pro
21 * Logitech QuickCam Zoom
22 * Logitech QuickCam Orbit
23 * Logitech QuickCam Sphere
24 * Samsung MPC-C10
25 * Samsung MPC-C30
26 * Sotec Afina Eye
27 * AME CU-001
28 * Visionite VCS-UM100
29 * Visionite VCS-UC300
30
31The main webpage for the Philips driver is at the address above. It contains
32a lot of extra information, a FAQ, and the binary plugin 'PWCX'. This plugin
33contains decompression routines that allow you to use higher image sizes and
34framerates; in addition the webcam uses less bandwidth on the USB bus (handy
35if you want to run more than 1 camera simultaneously). These routines fall
36under a NDA, and may therefor not be distributed as source; however, its use
37is completely optional.
38
39You can build this code either into your kernel, or as a module. I recommend
40the latter, since it makes troubleshooting a lot easier. The built-in
41microphone is supported through the USB Audio class.
42
43When you load the module you can set some default settings for the
44camera; some programs depend on a particular image-size or -format and
45don't know how to set it properly in the driver. The options are:
46
47size
48 Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or
49 'vga', for an image size of resp. 128x96, 160x120, 176x144,
50 320x240, 352x288 and 640x480 (of course, only for those cameras that
51 support these resolutions).
52
53fps
54 Specifies the desired framerate. Is an integer in the range of 4-30.
55
56fbufs
57 This paramter specifies the number of internal buffers to use for storing
58 frames from the cam. This will help if the process that reads images from
59 the cam is a bit slow or momentarely busy. However, on slow machines it
60 only introduces lag, so choose carefully. The default is 3, which is
61 reasonable. You can set it between 2 and 5.
62
63mbufs
64 This is an integer between 1 and 10. It will tell the module the number of
65 buffers to reserve for mmap(), VIDIOCCGMBUF, VIDIOCMCAPTURE and friends.
66 The default is 2, which is adequate for most applications (double
67 buffering).
68
69 Should you experience a lot of 'Dumping frame...' messages during
70 grabbing with a tool that uses mmap(), you might want to increase if.
71 However, it doesn't really buffer images, it just gives you a bit more
72 slack when your program is behind. But you need a multi-threaded or
73 forked program to really take advantage of these buffers.
74
75 The absolute maximum is 10, but don't set it too high! Every buffer takes
76 up 460 KB of RAM, so unless you have a lot of memory setting this to
77 something more than 4 is an absolute waste. This memory is only
78 allocated during open(), so nothing is wasted when the camera is not in
79 use.
80
81power_save
82 When power_save is enabled (set to 1), the module will try to shut down
83 the cam on close() and re-activate on open(). This will save power and
84 turn off the LED. Not all cameras support this though (the 645 and 646
85 don't have power saving at all), and some models don't work either (they
86 will shut down, but never wake up). Consider this experimental. By
87 default this option is disabled.
88
89compression (only useful with the plugin)
90 With this option you can control the compression factor that the camera
91 uses to squeeze the image through the USB bus. You can set the
92 parameter between 0 and 3:
93 0 = prefer uncompressed images; if the requested mode is not available
94 in an uncompressed format, the driver will silently switch to low
95 compression.
96 1 = low compression.
97 2 = medium compression.
98 3 = high compression.
99
100 High compression takes less bandwidth of course, but it could also
101 introduce some unwanted artefacts. The default is 2, medium compression.
102 See the FAQ on the website for an overview of which modes require
103 compression.
104
105 The compression parameter does not apply to the 645 and 646 cameras
106 and OEM models derived from those (only a few). Most cams honour this
107 parameter.
108
109leds
110 This settings takes 2 integers, that define the on/off time for the LED
111 (in milliseconds). One of the interesting things that you can do with
112 this is let the LED blink while the camera is in use. This:
113
114 leds=500,500
115
116 will blink the LED once every second. But with:
117
118 leds=0,0
119
120 the LED never goes on, making it suitable for silent surveillance.
121
122 By default the camera's LED is on solid while in use, and turned off
123 when the camera is not used anymore.
124
125 This parameter works only with the ToUCam range of cameras (720, 730, 740,
126 750) and OEMs. For other cameras this command is silently ignored, and
127 the LED cannot be controlled.
128
129 Finally: this parameters does not take effect UNTIL the first time you
130 open the camera device. Until then, the LED remains on.
131
132dev_hint
133 A long standing problem with USB devices is their dynamic nature: you
134 never know what device a camera gets assigned; it depends on module load
135 order, the hub configuration, the order in which devices are plugged in,
136 and the phase of the moon (i.e. it can be random). With this option you
137 can give the driver a hint as to what video device node (/dev/videoX) it
138 should use with a specific camera. This is also handy if you have two
139 cameras of the same model.
140
141 A camera is specified by its type (the number from the camera model,
142 like PCA645, PCVC750VC, etc) and optionally the serial number (visible
143 in /proc/bus/usb/devices). A hint consists of a string with the following
144 format:
145
146 [type[.serialnumber]:]node
147
148 The square brackets mean that both the type and the serialnumber are
149 optional, but a serialnumber cannot be specified without a type (which
150 would be rather pointless). The serialnumber is separated from the type
151 by a '.'; the node number by a ':'.
152
153 This somewhat cryptic syntax is best explained by a few examples:
154
155 dev_hint=3,5 The first detected cam gets assigned
156 /dev/video3, the second /dev/video5. Any
157 other cameras will get the first free
158 available slot (see below).
159
160 dev_hint=645:1,680:2 The PCA645 camera will get /dev/video1,
161 and a PCVC680 /dev/video2.
162
163 dev_hint=645.0123:3,645.4567:0 The PCA645 camera with serialnumber
164 0123 goes to /dev/video3, the same
165 camera model with the 4567 serial
166 gets /dev/video0.
167
168 dev_hint=750:1,4,5,6 The PCVC750 camera will get /dev/video1, the
169 next 3 Philips cams will use /dev/video4
170 through /dev/video6.
171
172 Some points worth knowing:
173 - Serialnumbers are case sensitive and must be written full, including
174 leading zeroes (it's treated as a string).
175 - If a device node is already occupied, registration will fail and
176 the webcam is not available.
177 - You can have up to 64 video devices; be sure to make enough device
178 nodes in /dev if you want to spread the numbers (this does not apply
179 to devfs). After /dev/video9 comes /dev/video10 (not /dev/videoA).
180 - If a camera does not match any dev_hint, it will simply get assigned
181 the first available device node, just as it used to be.
182
183trace
184 In order to better detect problems, it is now possible to turn on a
185 'trace' of some of the calls the module makes; it logs all items in your
186 kernel log at debug level.
187
188 The trace variable is a bitmask; each bit represents a certain feature.
189 If you want to trace something, look up the bit value(s) in the table
190 below, add the values together and supply that to the trace variable.
191
192 Value Value Description Default
193 (dec) (hex)
194 1 0x1 Module initialization; this will log messages On
195 while loading and unloading the module
196
197 2 0x2 probe() and disconnect() traces On
198
199 4 0x4 Trace open() and close() calls Off
200
201 8 0x8 read(), mmap() and associated ioctl() calls Off
202
203 16 0x10 Memory allocation of buffers, etc. Off
204
205 32 0x20 Showing underflow, overflow and Dumping frame On
206 messages
207
208 64 0x40 Show viewport and image sizes Off
209
210 128 0x80 PWCX debugging Off
211
212 For example, to trace the open() & read() fuctions, sum 8 + 4 = 12,
213 so you would supply trace=12 during insmod or modprobe. If
214 you want to turn the initialization and probing tracing off, set trace=0.
215 The default value for trace is 35 (0x23).
216
217
218
219Example:
220
221 # modprobe pwc size=cif fps=15 power_save=1
222
223The fbufs, mbufs and trace parameters are global and apply to all connected
224cameras. Each camera has its own set of buffers.
225
226size and fps only specify defaults when you open() the device; this is to
227accommodate some tools that don't set the size. You can change these
228settings after open() with the Video4Linux ioctl() calls. The default of
229defaults is QCIF size at 10 fps.
230
231The compression parameter is semiglobal; it sets the initial compression
232preference for all camera's, but this parameter can be set per camera with
233the VIDIOCPWCSCQUAL ioctl() call.
234
235All parameters are optional.
236
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c
new file mode 100644
index 000000000000..26aa914bc541
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-ctrl.c
@@ -0,0 +1,1630 @@
1/* Driver for Philips webcam
2 Functions that send various control messages to the webcam, including
3 video modes.
4 (C) 1999-2003 Nemosoft Unv.
5 (C) 2004 Luc Saillard (luc@saillard.org)
6
7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
8 driver and thus may have bugs that are not present in the original version.
9 Please send bug reports and support requests to <luc@saillard.org>.
10
11 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
12 driver and thus may have bugs that are not present in the original version.
13 Please send bug reports and support requests to <luc@saillard.org>.
14 The decompression routines have been implemented by reverse-engineering the
15 Nemosoft binary pwcx module. Caveat emptor.
16
17 This program is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 2 of the License, or
20 (at your option) any later version.
21
22 This program is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
26
27 You should have received a copy of the GNU General Public License
28 along with this program; if not, write to the Free Software
29 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30*/
31
32/*
33 Changes
34 2001/08/03 Alvarado Added methods for changing white balance and
35 red/green gains
36 */
37
38/* Control functions for the cam; brightness, contrast, video mode, etc. */
39
40#ifdef __KERNEL__
41#include <asm/uaccess.h>
42#endif
43#include <asm/errno.h>
44#include <linux/version.h>
45
46#include "pwc.h"
47#include "pwc-ioctl.h"
48#include "pwc-uncompress.h"
49#include "pwc-kiara.h"
50#include "pwc-timon.h"
51#include "pwc-dec1.h"
52#include "pwc-dec23.h"
53
54/* Request types: video */
55#define SET_LUM_CTL 0x01
56#define GET_LUM_CTL 0x02
57#define SET_CHROM_CTL 0x03
58#define GET_CHROM_CTL 0x04
59#define SET_STATUS_CTL 0x05
60#define GET_STATUS_CTL 0x06
61#define SET_EP_STREAM_CTL 0x07
62#define GET_EP_STREAM_CTL 0x08
63#define SET_MPT_CTL 0x0D
64#define GET_MPT_CTL 0x0E
65
66/* Selectors for the Luminance controls [GS]ET_LUM_CTL */
67#define AGC_MODE_FORMATTER 0x2000
68#define PRESET_AGC_FORMATTER 0x2100
69#define SHUTTER_MODE_FORMATTER 0x2200
70#define PRESET_SHUTTER_FORMATTER 0x2300
71#define PRESET_CONTOUR_FORMATTER 0x2400
72#define AUTO_CONTOUR_FORMATTER 0x2500
73#define BACK_LIGHT_COMPENSATION_FORMATTER 0x2600
74#define CONTRAST_FORMATTER 0x2700
75#define DYNAMIC_NOISE_CONTROL_FORMATTER 0x2800
76#define FLICKERLESS_MODE_FORMATTER 0x2900
77#define AE_CONTROL_SPEED 0x2A00
78#define BRIGHTNESS_FORMATTER 0x2B00
79#define GAMMA_FORMATTER 0x2C00
80
81/* Selectors for the Chrominance controls [GS]ET_CHROM_CTL */
82#define WB_MODE_FORMATTER 0x1000
83#define AWB_CONTROL_SPEED_FORMATTER 0x1100
84#define AWB_CONTROL_DELAY_FORMATTER 0x1200
85#define PRESET_MANUAL_RED_GAIN_FORMATTER 0x1300
86#define PRESET_MANUAL_BLUE_GAIN_FORMATTER 0x1400
87#define COLOUR_MODE_FORMATTER 0x1500
88#define SATURATION_MODE_FORMATTER1 0x1600
89#define SATURATION_MODE_FORMATTER2 0x1700
90
91/* Selectors for the Status controls [GS]ET_STATUS_CTL */
92#define SAVE_USER_DEFAULTS_FORMATTER 0x0200
93#define RESTORE_USER_DEFAULTS_FORMATTER 0x0300
94#define RESTORE_FACTORY_DEFAULTS_FORMATTER 0x0400
95#define READ_AGC_FORMATTER 0x0500
96#define READ_SHUTTER_FORMATTER 0x0600
97#define READ_RED_GAIN_FORMATTER 0x0700
98#define READ_BLUE_GAIN_FORMATTER 0x0800
99#define SENSOR_TYPE_FORMATTER1 0x0C00
100#define READ_RAW_Y_MEAN_FORMATTER 0x3100
101#define SET_POWER_SAVE_MODE_FORMATTER 0x3200
102#define MIRROR_IMAGE_FORMATTER 0x3300
103#define LED_FORMATTER 0x3400
104#define SENSOR_TYPE_FORMATTER2 0x3700
105
106/* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */
107#define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100
108
109/* Formatters for the motorized pan & tilt [GS]ET_MPT_CTL */
110#define PT_RELATIVE_CONTROL_FORMATTER 0x01
111#define PT_RESET_CONTROL_FORMATTER 0x02
112#define PT_STATUS_FORMATTER 0x03
113
114static char *size2name[PSZ_MAX] =
115{
116 "subQCIF",
117 "QSIF",
118 "QCIF",
119 "SIF",
120 "CIF",
121 "VGA",
122};
123
124/********/
125
126/* Entries for the Nala (645/646) camera; the Nala doesn't have compression
127 preferences, so you either get compressed or non-compressed streams.
128
129 An alternate value of 0 means this mode is not available at all.
130 */
131
132struct Nala_table_entry {
133 char alternate; /* USB alternate setting */
134 int compressed; /* Compressed yes/no */
135
136 unsigned char mode[3]; /* precomputed mode table */
137};
138
139static struct Nala_table_entry Nala_table[PSZ_MAX][8] =
140{
141#include "pwc-nala.h"
142};
143
144
145/****************************************************************************/
146
147
148#define SendControlMsg(request, value, buflen) \
149 usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), \
150 request, \
151 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
152 value, \
153 pdev->vcinterface, \
154 &buf, buflen, 500)
155
156#define RecvControlMsg(request, value, buflen) \
157 usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), \
158 request, \
159 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
160 value, \
161 pdev->vcinterface, \
162 &buf, buflen, 500)
163
164
165#if PWC_DEBUG
166void pwc_hexdump(void *p, int len)
167{
168 int i;
169 unsigned char *s;
170 char buf[100], *d;
171
172 s = (unsigned char *)p;
173 d = buf;
174 *d = '\0';
175 Debug("Doing hexdump @ %p, %d bytes.\n", p, len);
176 for (i = 0; i < len; i++) {
177 d += sprintf(d, "%02X ", *s++);
178 if ((i & 0xF) == 0xF) {
179 Debug("%s\n", buf);
180 d = buf;
181 *d = '\0';
182 }
183 }
184 if ((i & 0xF) != 0)
185 Debug("%s\n", buf);
186}
187#endif
188
189static inline int send_video_command(struct usb_device *udev, int index, void *buf, int buflen)
190{
191 return usb_control_msg(udev,
192 usb_sndctrlpipe(udev, 0),
193 SET_EP_STREAM_CTL,
194 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
195 VIDEO_OUTPUT_CONTROL_FORMATTER,
196 index,
197 buf, buflen, 1000);
198}
199
200
201
202static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
203{
204 unsigned char buf[3];
205 int ret, fps;
206 struct Nala_table_entry *pEntry;
207 int frames2frames[31] =
208 { /* closest match of framerate */
209 0, 0, 0, 0, 4, /* 0-4 */
210 5, 5, 7, 7, 10, /* 5-9 */
211 10, 10, 12, 12, 15, /* 10-14 */
212 15, 15, 15, 20, 20, /* 15-19 */
213 20, 20, 20, 24, 24, /* 20-24 */
214 24, 24, 24, 24, 24, /* 25-29 */
215 24 /* 30 */
216 };
217 int frames2table[31] =
218 { 0, 0, 0, 0, 0, /* 0-4 */
219 1, 1, 1, 2, 2, /* 5-9 */
220 3, 3, 4, 4, 4, /* 10-14 */
221 5, 5, 5, 5, 5, /* 15-19 */
222 6, 6, 6, 6, 7, /* 20-24 */
223 7, 7, 7, 7, 7, /* 25-29 */
224 7 /* 30 */
225 };
226
227 if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25)
228 return -EINVAL;
229 frames = frames2frames[frames];
230 fps = frames2table[frames];
231 pEntry = &Nala_table[size][fps];
232 if (pEntry->alternate == 0)
233 return -EINVAL;
234
235 if (pEntry->compressed)
236 return -ENOENT; /* Not supported. */
237
238 memcpy(buf, pEntry->mode, 3);
239 ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
240 if (ret < 0) {
241 Debug("Failed to send video command... %d\n", ret);
242 return ret;
243 }
244 if (pEntry->compressed && pdev->vpalette != VIDEO_PALETTE_RAW)
245 {
246 switch(pdev->type) {
247 case 645:
248 case 646:
249 pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data);
250 break;
251
252 case 675:
253 case 680:
254 case 690:
255 case 720:
256 case 730:
257 case 740:
258 case 750:
259 pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data);
260 break;
261 }
262 }
263
264 pdev->cmd_len = 3;
265 memcpy(pdev->cmd_buf, buf, 3);
266
267 /* Set various parameters */
268 pdev->vframes = frames;
269 pdev->vsize = size;
270 pdev->valternate = pEntry->alternate;
271 pdev->image = pwc_image_sizes[size];
272 pdev->frame_size = (pdev->image.x * pdev->image.y * 3) / 2;
273 if (pEntry->compressed) {
274 if (pdev->release < 5) { /* 4 fold compression */
275 pdev->vbandlength = 528;
276 pdev->frame_size /= 4;
277 }
278 else {
279 pdev->vbandlength = 704;
280 pdev->frame_size /= 3;
281 }
282 }
283 else
284 pdev->vbandlength = 0;
285 return 0;
286}
287
288
289static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
290{
291 unsigned char buf[13];
292 const struct Timon_table_entry *pChoose;
293 int ret, fps;
294
295 if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3)
296 return -EINVAL;
297 if (size == PSZ_VGA && frames > 15)
298 return -EINVAL;
299 fps = (frames / 5) - 1;
300
301 /* Find a supported framerate with progressively higher compression ratios
302 if the preferred ratio is not available.
303 */
304 pChoose = NULL;
305 while (compression <= 3) {
306 pChoose = &Timon_table[size][fps][compression];
307 if (pChoose->alternate != 0)
308 break;
309 compression++;
310 }
311 if (pChoose == NULL || pChoose->alternate == 0)
312 return -ENOENT; /* Not supported. */
313
314 memcpy(buf, pChoose->mode, 13);
315 if (snapshot)
316 buf[0] |= 0x80;
317 ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 13);
318 if (ret < 0)
319 return ret;
320
321 if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
322 pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data);
323
324 pdev->cmd_len = 13;
325 memcpy(pdev->cmd_buf, buf, 13);
326
327 /* Set various parameters */
328 pdev->vframes = frames;
329 pdev->vsize = size;
330 pdev->vsnapshot = snapshot;
331 pdev->valternate = pChoose->alternate;
332 pdev->image = pwc_image_sizes[size];
333 pdev->vbandlength = pChoose->bandlength;
334 if (pChoose->bandlength > 0)
335 pdev->frame_size = (pChoose->bandlength * pdev->image.y) / 4;
336 else
337 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
338 return 0;
339}
340
341
342static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
343{
344 const struct Kiara_table_entry *pChoose = NULL;
345 int fps, ret;
346 unsigned char buf[12];
347 struct Kiara_table_entry RawEntry = {6, 773, 1272, {0xAD, 0xF4, 0x10, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}};
348
349 if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3)
350 return -EINVAL;
351 if (size == PSZ_VGA && frames > 15)
352 return -EINVAL;
353 fps = (frames / 5) - 1;
354
355 /* special case: VGA @ 5 fps and snapshot is raw bayer mode */
356 if (size == PSZ_VGA && frames == 5 && snapshot)
357 {
358 /* Only available in case the raw palette is selected or
359 we have the decompressor available. This mode is
360 only available in compressed form
361 */
362 if (pdev->vpalette == VIDEO_PALETTE_RAW)
363 {
364 Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette);
365 pChoose = &RawEntry;
366 }
367 else
368 {
369 Info("VGA/5 BAYER mode _must_ have a decompressor available, or use RAW palette.\n");
370 }
371 }
372 else
373 {
374 /* Find a supported framerate with progressively higher compression ratios
375 if the preferred ratio is not available.
376 Skip this step when using RAW modes.
377 */
378 while (compression <= 3) {
379 pChoose = &Kiara_table[size][fps][compression];
380 if (pChoose->alternate != 0)
381 break;
382 compression++;
383 }
384 }
385 if (pChoose == NULL || pChoose->alternate == 0)
386 return -ENOENT; /* Not supported. */
387
388 Debug("Using alternate setting %d.\n", pChoose->alternate);
389
390 /* usb_control_msg won't take staticly allocated arrays as argument?? */
391 memcpy(buf, pChoose->mode, 12);
392 if (snapshot)
393 buf[0] |= 0x80;
394
395 /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
396 ret = send_video_command(pdev->udev, 4 /* pdev->vendpoint */, buf, 12);
397 if (ret < 0)
398 return ret;
399
400 if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
401 pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data);
402
403 pdev->cmd_len = 12;
404 memcpy(pdev->cmd_buf, buf, 12);
405 /* All set and go */
406 pdev->vframes = frames;
407 pdev->vsize = size;
408 pdev->vsnapshot = snapshot;
409 pdev->valternate = pChoose->alternate;
410 pdev->image = pwc_image_sizes[size];
411 pdev->vbandlength = pChoose->bandlength;
412 if (pdev->vbandlength > 0)
413 pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4;
414 else
415 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
416 return 0;
417}
418
419
420
421/**
422 @pdev: device structure
423 @width: viewport width
424 @height: viewport height
425 @frame: framerate, in fps
426 @compression: preferred compression ratio
427 @snapshot: snapshot mode or streaming
428 */
429int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot)
430{
431 int ret, size;
432
433 Trace(TRACE_FLOW, "set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette);
434 size = pwc_decode_size(pdev, width, height);
435 if (size < 0) {
436 Debug("Could not find suitable size.\n");
437 return -ERANGE;
438 }
439 Debug("decode_size = %d.\n", size);
440
441 ret = -EINVAL;
442 switch(pdev->type) {
443 case 645:
444 case 646:
445 ret = set_video_mode_Nala(pdev, size, frames);
446 break;
447
448 case 675:
449 case 680:
450 case 690:
451 ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
452 break;
453
454 case 720:
455 case 730:
456 case 740:
457 case 750:
458 ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot);
459 break;
460 }
461 if (ret < 0) {
462 if (ret == -ENOENT)
463 Info("Video mode %s@%d fps is only supported with the decompressor module (pwcx).\n", size2name[size], frames);
464 else {
465 Err("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
466 }
467 return ret;
468 }
469 pdev->view.x = width;
470 pdev->view.y = height;
471 pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
472 pwc_set_image_buffer_size(pdev);
473 Trace(TRACE_SIZE, "Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y);
474 return 0;
475}
476
477
478void pwc_set_image_buffer_size(struct pwc_device *pdev)
479{
480 int i, factor = 0, filler = 0;
481
482 /* for PALETTE_YUV420P */
483 switch(pdev->vpalette)
484 {
485 case VIDEO_PALETTE_YUV420P:
486 factor = 6;
487 filler = 128;
488 break;
489 case VIDEO_PALETTE_RAW:
490 factor = 6; /* can be uncompressed YUV420P */
491 filler = 0;
492 break;
493 }
494
495 /* Set sizes in bytes */
496 pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
497 pdev->view.size = pdev->view.x * pdev->view.y * factor / 4;
498
499 /* Align offset, or you'll get some very weird results in
500 YUV420 mode... x must be multiple of 4 (to get the Y's in
501 place), and y even (or you'll mixup U & V). This is less of a
502 problem for YUV420P.
503 */
504 pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
505 pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
506
507 /* Fill buffers with gray or black */
508 for (i = 0; i < MAX_IMAGES; i++) {
509 if (pdev->image_ptr[i] != NULL)
510 memset(pdev->image_ptr[i], filler, pdev->view.size);
511 }
512}
513
514
515
516/* BRIGHTNESS */
517
518int pwc_get_brightness(struct pwc_device *pdev)
519{
520 char buf;
521 int ret;
522
523 ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
524 if (ret < 0)
525 return ret;
526 return buf << 9;
527}
528
529int pwc_set_brightness(struct pwc_device *pdev, int value)
530{
531 char buf;
532
533 if (value < 0)
534 value = 0;
535 if (value > 0xffff)
536 value = 0xffff;
537 buf = (value >> 9) & 0x7f;
538 return SendControlMsg(SET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
539}
540
541/* CONTRAST */
542
543int pwc_get_contrast(struct pwc_device *pdev)
544{
545 char buf;
546 int ret;
547
548 ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1);
549 if (ret < 0)
550 return ret;
551 return buf << 10;
552}
553
554int pwc_set_contrast(struct pwc_device *pdev, int value)
555{
556 char buf;
557
558 if (value < 0)
559 value = 0;
560 if (value > 0xffff)
561 value = 0xffff;
562 buf = (value >> 10) & 0x3f;
563 return SendControlMsg(SET_LUM_CTL, CONTRAST_FORMATTER, 1);
564}
565
566/* GAMMA */
567
568int pwc_get_gamma(struct pwc_device *pdev)
569{
570 char buf;
571 int ret;
572
573 ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1);
574 if (ret < 0)
575 return ret;
576 return buf << 11;
577}
578
579int pwc_set_gamma(struct pwc_device *pdev, int value)
580{
581 char buf;
582
583 if (value < 0)
584 value = 0;
585 if (value > 0xffff)
586 value = 0xffff;
587 buf = (value >> 11) & 0x1f;
588 return SendControlMsg(SET_LUM_CTL, GAMMA_FORMATTER, 1);
589}
590
591
592/* SATURATION */
593
594int pwc_get_saturation(struct pwc_device *pdev)
595{
596 char buf;
597 int ret;
598
599 if (pdev->type < 675)
600 return -1;
601 ret = RecvControlMsg(GET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1);
602 if (ret < 0)
603 return ret;
604 return 32768 + buf * 327;
605}
606
607int pwc_set_saturation(struct pwc_device *pdev, int value)
608{
609 char buf;
610
611 if (pdev->type < 675)
612 return -EINVAL;
613 if (value < 0)
614 value = 0;
615 if (value > 0xffff)
616 value = 0xffff;
617 /* saturation ranges from -100 to +100 */
618 buf = (value - 32768) / 327;
619 return SendControlMsg(SET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1);
620}
621
622/* AGC */
623
624static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
625{
626 char buf;
627 int ret;
628
629 if (mode)
630 buf = 0x0; /* auto */
631 else
632 buf = 0xff; /* fixed */
633
634 ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1);
635
636 if (!mode && ret >= 0) {
637 if (value < 0)
638 value = 0;
639 if (value > 0xffff)
640 value = 0xffff;
641 buf = (value >> 10) & 0x3F;
642 ret = SendControlMsg(SET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
643 }
644 if (ret < 0)
645 return ret;
646 return 0;
647}
648
649static inline int pwc_get_agc(struct pwc_device *pdev, int *value)
650{
651 unsigned char buf;
652 int ret;
653
654 ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1);
655 if (ret < 0)
656 return ret;
657
658 if (buf != 0) { /* fixed */
659 ret = RecvControlMsg(GET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
660 if (ret < 0)
661 return ret;
662 if (buf > 0x3F)
663 buf = 0x3F;
664 *value = (buf << 10);
665 }
666 else { /* auto */
667 ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1);
668 if (ret < 0)
669 return ret;
670 /* Gah... this value ranges from 0x00 ... 0x9F */
671 if (buf > 0x9F)
672 buf = 0x9F;
673 *value = -(48 + buf * 409);
674 }
675
676 return 0;
677}
678
679static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value)
680{
681 char buf[2];
682 int speed, ret;
683
684
685 if (mode)
686 buf[0] = 0x0; /* auto */
687 else
688 buf[0] = 0xff; /* fixed */
689
690 ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1);
691
692 if (!mode && ret >= 0) {
693 if (value < 0)
694 value = 0;
695 if (value > 0xffff)
696 value = 0xffff;
697 switch(pdev->type) {
698 case 675:
699 case 680:
700 case 690:
701 /* speed ranges from 0x0 to 0x290 (656) */
702 speed = (value / 100);
703 buf[1] = speed >> 8;
704 buf[0] = speed & 0xff;
705 break;
706 case 720:
707 case 730:
708 case 740:
709 case 750:
710 /* speed seems to range from 0x0 to 0xff */
711 buf[1] = 0;
712 buf[0] = value >> 8;
713 break;
714 }
715
716 ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2);
717 }
718 return ret;
719}
720
721
722/* POWER */
723
724int pwc_camera_power(struct pwc_device *pdev, int power)
725{
726 char buf;
727
728 if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6))
729 return 0; /* Not supported by Nala or Timon < release 6 */
730
731 if (power)
732 buf = 0x00; /* active */
733 else
734 buf = 0xFF; /* power save */
735 return SendControlMsg(SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, 1);
736}
737
738
739
740/* private calls */
741
742static inline int pwc_restore_user(struct pwc_device *pdev)
743{
744 char buf; /* dummy */
745 return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0);
746}
747
748static inline int pwc_save_user(struct pwc_device *pdev)
749{
750 char buf; /* dummy */
751 return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0);
752}
753
754static inline int pwc_restore_factory(struct pwc_device *pdev)
755{
756 char buf; /* dummy */
757 return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0);
758}
759
760 /* ************************************************* */
761 /* Patch by Alvarado: (not in the original version */
762
763 /*
764 * the camera recognizes modes from 0 to 4:
765 *
766 * 00: indoor (incandescant lighting)
767 * 01: outdoor (sunlight)
768 * 02: fluorescent lighting
769 * 03: manual
770 * 04: auto
771 */
772static inline int pwc_set_awb(struct pwc_device *pdev, int mode)
773{
774 char buf;
775 int ret;
776
777 if (mode < 0)
778 mode = 0;
779
780 if (mode > 4)
781 mode = 4;
782
783 buf = mode & 0x07; /* just the lowest three bits */
784
785 ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1);
786
787 if (ret < 0)
788 return ret;
789 return 0;
790}
791
792static inline int pwc_get_awb(struct pwc_device *pdev)
793{
794 unsigned char buf;
795 int ret;
796
797 ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1);
798
799 if (ret < 0)
800 return ret;
801 return buf;
802}
803
804static inline int pwc_set_red_gain(struct pwc_device *pdev, int value)
805{
806 unsigned char buf;
807
808 if (value < 0)
809 value = 0;
810 if (value > 0xffff)
811 value = 0xffff;
812 /* only the msb is considered */
813 buf = value >> 8;
814 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
815}
816
817static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value)
818{
819 unsigned char buf;
820 int ret;
821
822 ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
823 if (ret < 0)
824 return ret;
825 *value = buf << 8;
826 return 0;
827}
828
829
830static inline int pwc_set_blue_gain(struct pwc_device *pdev, int value)
831{
832 unsigned char buf;
833
834 if (value < 0)
835 value = 0;
836 if (value > 0xffff)
837 value = 0xffff;
838 /* only the msb is considered */
839 buf = value >> 8;
840 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
841}
842
843static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
844{
845 unsigned char buf;
846 int ret;
847
848 ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
849 if (ret < 0)
850 return ret;
851 *value = buf << 8;
852 return 0;
853}
854
855
856/* The following two functions are different, since they only read the
857 internal red/blue gains, which may be different from the manual
858 gains set or read above.
859 */
860static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value)
861{
862 unsigned char buf;
863 int ret;
864
865 ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1);
866 if (ret < 0)
867 return ret;
868 *value = buf << 8;
869 return 0;
870}
871
872static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
873{
874 unsigned char buf;
875 int ret;
876
877 ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1);
878 if (ret < 0)
879 return ret;
880 *value = buf << 8;
881 return 0;
882}
883
884
885static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
886{
887 unsigned char buf;
888
889 /* useful range is 0x01..0x20 */
890 buf = speed / 0x7f0;
891 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
892}
893
894static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
895{
896 unsigned char buf;
897 int ret;
898
899 ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
900 if (ret < 0)
901 return ret;
902 *value = buf * 0x7f0;
903 return 0;
904}
905
906
907static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
908{
909 unsigned char buf;
910
911 /* useful range is 0x01..0x3F */
912 buf = (delay >> 10);
913 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
914}
915
916static inline int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
917{
918 unsigned char buf;
919 int ret;
920
921 ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
922 if (ret < 0)
923 return ret;
924 *value = buf << 10;
925 return 0;
926}
927
928
929int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
930{
931 unsigned char buf[2];
932
933 if (pdev->type < 730)
934 return 0;
935 on_value /= 100;
936 off_value /= 100;
937 if (on_value < 0)
938 on_value = 0;
939 if (on_value > 0xff)
940 on_value = 0xff;
941 if (off_value < 0)
942 off_value = 0;
943 if (off_value > 0xff)
944 off_value = 0xff;
945
946 buf[0] = on_value;
947 buf[1] = off_value;
948
949 return SendControlMsg(SET_STATUS_CTL, LED_FORMATTER, 2);
950}
951
952int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
953{
954 unsigned char buf[2];
955 int ret;
956
957 if (pdev->type < 730) {
958 *on_value = -1;
959 *off_value = -1;
960 return 0;
961 }
962
963 ret = RecvControlMsg(GET_STATUS_CTL, LED_FORMATTER, 2);
964 if (ret < 0)
965 return ret;
966 *on_value = buf[0] * 100;
967 *off_value = buf[1] * 100;
968 return 0;
969}
970
971static inline int pwc_set_contour(struct pwc_device *pdev, int contour)
972{
973 unsigned char buf;
974 int ret;
975
976 if (contour < 0)
977 buf = 0xff; /* auto contour on */
978 else
979 buf = 0x0; /* auto contour off */
980 ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
981 if (ret < 0)
982 return ret;
983
984 if (contour < 0)
985 return 0;
986 if (contour > 0xffff)
987 contour = 0xffff;
988
989 buf = (contour >> 10); /* contour preset is [0..3f] */
990 ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
991 if (ret < 0)
992 return ret;
993 return 0;
994}
995
996static inline int pwc_get_contour(struct pwc_device *pdev, int *contour)
997{
998 unsigned char buf;
999 int ret;
1000
1001 ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
1002 if (ret < 0)
1003 return ret;
1004
1005 if (buf == 0) {
1006 /* auto mode off, query current preset value */
1007 ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
1008 if (ret < 0)
1009 return ret;
1010 *contour = buf << 10;
1011 }
1012 else
1013 *contour = -1;
1014 return 0;
1015}
1016
1017
1018static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight)
1019{
1020 unsigned char buf;
1021
1022 if (backlight)
1023 buf = 0xff;
1024 else
1025 buf = 0x0;
1026 return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
1027}
1028
1029static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
1030{
1031 int ret;
1032 unsigned char buf;
1033
1034 ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
1035 if (ret < 0)
1036 return ret;
1037 *backlight = buf;
1038 return 0;
1039}
1040
1041
1042static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker)
1043{
1044 unsigned char buf;
1045
1046 if (flicker)
1047 buf = 0xff;
1048 else
1049 buf = 0x0;
1050 return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
1051}
1052
1053static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
1054{
1055 int ret;
1056 unsigned char buf;
1057
1058 ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
1059 if (ret < 0)
1060 return ret;
1061 *flicker = buf;
1062 return 0;
1063}
1064
1065
1066static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
1067{
1068 unsigned char buf;
1069
1070 if (noise < 0)
1071 noise = 0;
1072 if (noise > 3)
1073 noise = 3;
1074 buf = noise;
1075 return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
1076}
1077
1078static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
1079{
1080 int ret;
1081 unsigned char buf;
1082
1083 ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
1084 if (ret < 0)
1085 return ret;
1086 *noise = buf;
1087 return 0;
1088}
1089
1090static int pwc_mpt_reset(struct pwc_device *pdev, int flags)
1091{
1092 unsigned char buf;
1093
1094 buf = flags & 0x03; // only lower two bits are currently used
1095 return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1);
1096}
1097
1098static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
1099{
1100 unsigned char buf[4];
1101
1102 /* set new relative angle; angles are expressed in degrees * 100,
1103 but cam as .5 degree resolution, hence devide by 200. Also
1104 the angle must be multiplied by 64 before it's send to
1105 the cam (??)
1106 */
1107 pan = 64 * pan / 100;
1108 tilt = -64 * tilt / 100; /* positive tilt is down, which is not what the user would expect */
1109 buf[0] = pan & 0xFF;
1110 buf[1] = (pan >> 8) & 0xFF;
1111 buf[2] = tilt & 0xFF;
1112 buf[3] = (tilt >> 8) & 0xFF;
1113 return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4);
1114}
1115
1116static inline int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status)
1117{
1118 int ret;
1119 unsigned char buf[5];
1120
1121 ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5);
1122 if (ret < 0)
1123 return ret;
1124 status->status = buf[0] & 0x7; // 3 bits are used for reporting
1125 status->time_pan = (buf[1] << 8) + buf[2];
1126 status->time_tilt = (buf[3] << 8) + buf[4];
1127 return 0;
1128}
1129
1130
1131int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
1132{
1133 unsigned char buf;
1134 int ret = -1, request;
1135
1136 if (pdev->type < 675)
1137 request = SENSOR_TYPE_FORMATTER1;
1138 else if (pdev->type < 730)
1139 return -1; /* The Vesta series doesn't have this call */
1140 else
1141 request = SENSOR_TYPE_FORMATTER2;
1142
1143 ret = RecvControlMsg(GET_STATUS_CTL, request, 1);
1144 if (ret < 0)
1145 return ret;
1146 if (pdev->type < 675)
1147 *sensor = buf | 0x100;
1148 else
1149 *sensor = buf;
1150 return 0;
1151}
1152
1153
1154 /* End of Add-Ons */
1155 /* ************************************************* */
1156
1157/* Linux 2.5.something and 2.6 pass direct pointers to arguments of
1158 ioctl() calls. With 2.4, you have to do tedious copy_from_user()
1159 and copy_to_user() calls. With these macros we circumvent this,
1160 and let me maintain only one source file. The functionality is
1161 exactly the same otherwise.
1162 */
1163
1164#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
1165
1166/* define local variable for arg */
1167#define ARG_DEF(ARG_type, ARG_name)\
1168 ARG_type *ARG_name = arg;
1169/* copy arg to local variable */
1170#define ARG_IN(ARG_name) /* nothing */
1171/* argument itself (referenced) */
1172#define ARGR(ARG_name) (*ARG_name)
1173/* argument address */
1174#define ARGA(ARG_name) ARG_name
1175/* copy local variable to arg */
1176#define ARG_OUT(ARG_name) /* nothing */
1177
1178#else
1179
1180#define ARG_DEF(ARG_type, ARG_name)\
1181 ARG_type ARG_name;
1182#define ARG_IN(ARG_name)\
1183 if (copy_from_user(&ARG_name, arg, sizeof(ARG_name))) {\
1184 ret = -EFAULT;\
1185 break;\
1186 }
1187#define ARGR(ARG_name) ARG_name
1188#define ARGA(ARG_name) &ARG_name
1189#define ARG_OUT(ARG_name)\
1190 if (copy_to_user(arg, &ARG_name, sizeof(ARG_name))) {\
1191 ret = -EFAULT;\
1192 break;\
1193 }
1194
1195#endif
1196
1197int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1198{
1199 int ret = 0;
1200
1201 switch(cmd) {
1202 case VIDIOCPWCRUSER:
1203 {
1204 if (pwc_restore_user(pdev))
1205 ret = -EINVAL;
1206 break;
1207 }
1208
1209 case VIDIOCPWCSUSER:
1210 {
1211 if (pwc_save_user(pdev))
1212 ret = -EINVAL;
1213 break;
1214 }
1215
1216 case VIDIOCPWCFACTORY:
1217 {
1218 if (pwc_restore_factory(pdev))
1219 ret = -EINVAL;
1220 break;
1221 }
1222
1223 case VIDIOCPWCSCQUAL:
1224 {
1225 ARG_DEF(int, qual)
1226
1227 ARG_IN(qual)
1228 if (ARGR(qual) < 0 || ARGR(qual) > 3)
1229 ret = -EINVAL;
1230 else
1231 ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
1232 if (ret >= 0)
1233 pdev->vcompression = ARGR(qual);
1234 break;
1235 }
1236
1237 case VIDIOCPWCGCQUAL:
1238 {
1239 ARG_DEF(int, qual)
1240
1241 ARGR(qual) = pdev->vcompression;
1242 ARG_OUT(qual)
1243 break;
1244 }
1245
1246 case VIDIOCPWCPROBE:
1247 {
1248 ARG_DEF(struct pwc_probe, probe)
1249
1250 strcpy(ARGR(probe).name, pdev->vdev->name);
1251 ARGR(probe).type = pdev->type;
1252 ARG_OUT(probe)
1253 break;
1254 }
1255
1256 case VIDIOCPWCGSERIAL:
1257 {
1258 ARG_DEF(struct pwc_serial, serial)
1259
1260 strcpy(ARGR(serial).serial, pdev->serial);
1261 ARG_OUT(serial)
1262 break;
1263 }
1264
1265 case VIDIOCPWCSAGC:
1266 {
1267 ARG_DEF(int, agc)
1268
1269 ARG_IN(agc)
1270 if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc)))
1271 ret = -EINVAL;
1272 break;
1273 }
1274
1275 case VIDIOCPWCGAGC:
1276 {
1277 ARG_DEF(int, agc)
1278
1279 if (pwc_get_agc(pdev, ARGA(agc)))
1280 ret = -EINVAL;
1281 ARG_OUT(agc)
1282 break;
1283 }
1284
1285 case VIDIOCPWCSSHUTTER:
1286 {
1287 ARG_DEF(int, shutter_speed)
1288
1289 ARG_IN(shutter_speed)
1290 ret = pwc_set_shutter_speed(pdev, ARGR(shutter_speed) < 0 ? 1 : 0, ARGR(shutter_speed));
1291 break;
1292 }
1293
1294 case VIDIOCPWCSAWB:
1295 {
1296 ARG_DEF(struct pwc_whitebalance, wb)
1297
1298 ARG_IN(wb)
1299 ret = pwc_set_awb(pdev, ARGR(wb).mode);
1300 if (ret >= 0 && ARGR(wb).mode == PWC_WB_MANUAL) {
1301 pwc_set_red_gain(pdev, ARGR(wb).manual_red);
1302 pwc_set_blue_gain(pdev, ARGR(wb).manual_blue);
1303 }
1304 break;
1305 }
1306
1307 case VIDIOCPWCGAWB:
1308 {
1309 ARG_DEF(struct pwc_whitebalance, wb)
1310
1311 memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance));
1312 ARGR(wb).mode = pwc_get_awb(pdev);
1313 if (ARGR(wb).mode < 0)
1314 ret = -EINVAL;
1315 else {
1316 if (ARGR(wb).mode == PWC_WB_MANUAL) {
1317 ret = pwc_get_red_gain(pdev, &ARGR(wb).manual_red);
1318 if (ret < 0)
1319 break;
1320 ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue);
1321 if (ret < 0)
1322 break;
1323 }
1324 if (ARGR(wb).mode == PWC_WB_AUTO) {
1325 ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red);
1326 if (ret < 0)
1327 break;
1328 ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue);
1329 if (ret < 0)
1330 break;
1331 }
1332 }
1333 ARG_OUT(wb)
1334 break;
1335 }
1336
1337 case VIDIOCPWCSAWBSPEED:
1338 {
1339 ARG_DEF(struct pwc_wb_speed, wbs)
1340
1341 if (ARGR(wbs).control_speed > 0) {
1342 ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed);
1343 }
1344 if (ARGR(wbs).control_delay > 0) {
1345 ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay);
1346 }
1347 break;
1348 }
1349
1350 case VIDIOCPWCGAWBSPEED:
1351 {
1352 ARG_DEF(struct pwc_wb_speed, wbs)
1353
1354 ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed);
1355 if (ret < 0)
1356 break;
1357 ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay);
1358 if (ret < 0)
1359 break;
1360 ARG_OUT(wbs)
1361 break;
1362 }
1363
1364 case VIDIOCPWCSLED:
1365 {
1366 ARG_DEF(struct pwc_leds, leds)
1367
1368 ARG_IN(leds)
1369 ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off);
1370 break;
1371 }
1372
1373
1374 case VIDIOCPWCGLED:
1375 {
1376 ARG_DEF(struct pwc_leds, leds)
1377
1378 ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off);
1379 ARG_OUT(leds)
1380 break;
1381 }
1382
1383 case VIDIOCPWCSCONTOUR:
1384 {
1385 ARG_DEF(int, contour)
1386
1387 ARG_IN(contour)
1388 ret = pwc_set_contour(pdev, ARGR(contour));
1389 break;
1390 }
1391
1392 case VIDIOCPWCGCONTOUR:
1393 {
1394 ARG_DEF(int, contour)
1395
1396 ret = pwc_get_contour(pdev, ARGA(contour));
1397 ARG_OUT(contour)
1398 break;
1399 }
1400
1401 case VIDIOCPWCSBACKLIGHT:
1402 {
1403 ARG_DEF(int, backlight)
1404
1405 ARG_IN(backlight)
1406 ret = pwc_set_backlight(pdev, ARGR(backlight));
1407 break;
1408 }
1409
1410 case VIDIOCPWCGBACKLIGHT:
1411 {
1412 ARG_DEF(int, backlight)
1413
1414 ret = pwc_get_backlight(pdev, ARGA(backlight));
1415 ARG_OUT(backlight)
1416 break;
1417 }
1418
1419 case VIDIOCPWCSFLICKER:
1420 {
1421 ARG_DEF(int, flicker)
1422
1423 ARG_IN(flicker)
1424 ret = pwc_set_flicker(pdev, ARGR(flicker));
1425 break;
1426 }
1427
1428 case VIDIOCPWCGFLICKER:
1429 {
1430 ARG_DEF(int, flicker)
1431
1432 ret = pwc_get_flicker(pdev, ARGA(flicker));
1433 ARG_OUT(flicker)
1434 break;
1435 }
1436
1437 case VIDIOCPWCSDYNNOISE:
1438 {
1439 ARG_DEF(int, dynnoise)
1440
1441 ARG_IN(dynnoise)
1442 ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise));
1443 break;
1444 }
1445
1446 case VIDIOCPWCGDYNNOISE:
1447 {
1448 ARG_DEF(int, dynnoise)
1449
1450 ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise));
1451 ARG_OUT(dynnoise);
1452 break;
1453 }
1454
1455 case VIDIOCPWCGREALSIZE:
1456 {
1457 ARG_DEF(struct pwc_imagesize, size)
1458
1459 ARGR(size).width = pdev->image.x;
1460 ARGR(size).height = pdev->image.y;
1461 ARG_OUT(size)
1462 break;
1463 }
1464
1465 case VIDIOCPWCMPTRESET:
1466 {
1467 if (pdev->features & FEATURE_MOTOR_PANTILT)
1468 {
1469 ARG_DEF(int, flags)
1470
1471 ARG_IN(flags)
1472 ret = pwc_mpt_reset(pdev, ARGR(flags));
1473 if (ret >= 0)
1474 {
1475 pdev->pan_angle = 0;
1476 pdev->tilt_angle = 0;
1477 }
1478 }
1479 else
1480 {
1481 ret = -ENXIO;
1482 }
1483 break;
1484 }
1485
1486 case VIDIOCPWCMPTGRANGE:
1487 {
1488 if (pdev->features & FEATURE_MOTOR_PANTILT)
1489 {
1490 ARG_DEF(struct pwc_mpt_range, range)
1491
1492 ARGR(range) = pdev->angle_range;
1493 ARG_OUT(range)
1494 }
1495 else
1496 {
1497 ret = -ENXIO;
1498 }
1499 break;
1500 }
1501
1502 case VIDIOCPWCMPTSANGLE:
1503 {
1504 int new_pan, new_tilt;
1505
1506 if (pdev->features & FEATURE_MOTOR_PANTILT)
1507 {
1508 ARG_DEF(struct pwc_mpt_angles, angles)
1509
1510 ARG_IN(angles)
1511 /* The camera can only set relative angles, so
1512 do some calculations when getting an absolute angle .
1513 */
1514 if (ARGR(angles).absolute)
1515 {
1516 new_pan = ARGR(angles).pan;
1517 new_tilt = ARGR(angles).tilt;
1518 }
1519 else
1520 {
1521 new_pan = pdev->pan_angle + ARGR(angles).pan;
1522 new_tilt = pdev->tilt_angle + ARGR(angles).tilt;
1523 }
1524 /* check absolute ranges */
1525 if (new_pan < pdev->angle_range.pan_min ||
1526 new_pan > pdev->angle_range.pan_max ||
1527 new_tilt < pdev->angle_range.tilt_min ||
1528 new_tilt > pdev->angle_range.tilt_max)
1529 {
1530 ret = -ERANGE;
1531 }
1532 else
1533 {
1534 /* go to relative range, check again */
1535 new_pan -= pdev->pan_angle;
1536 new_tilt -= pdev->tilt_angle;
1537 /* angles are specified in degrees * 100, thus the limit = 36000 */
1538 if (new_pan < -36000 || new_pan > 36000 || new_tilt < -36000 || new_tilt > 36000)
1539 ret = -ERANGE;
1540 }
1541 if (ret == 0) /* no errors so far */
1542 {
1543 ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt);
1544 if (ret >= 0)
1545 {
1546 pdev->pan_angle += new_pan;
1547 pdev->tilt_angle += new_tilt;
1548 }
1549 if (ret == -EPIPE) /* stall -> out of range */
1550 ret = -ERANGE;
1551 }
1552 }
1553 else
1554 {
1555 ret = -ENXIO;
1556 }
1557 break;
1558 }
1559
1560 case VIDIOCPWCMPTGANGLE:
1561 {
1562
1563 if (pdev->features & FEATURE_MOTOR_PANTILT)
1564 {
1565 ARG_DEF(struct pwc_mpt_angles, angles)
1566
1567 ARGR(angles).absolute = 1;
1568 ARGR(angles).pan = pdev->pan_angle;
1569 ARGR(angles).tilt = pdev->tilt_angle;
1570 ARG_OUT(angles)
1571 }
1572 else
1573 {
1574 ret = -ENXIO;
1575 }
1576 break;
1577 }
1578
1579 case VIDIOCPWCMPTSTATUS:
1580 {
1581 if (pdev->features & FEATURE_MOTOR_PANTILT)
1582 {
1583 ARG_DEF(struct pwc_mpt_status, status)
1584
1585 ret = pwc_mpt_get_status(pdev, ARGA(status));
1586 ARG_OUT(status)
1587 }
1588 else
1589 {
1590 ret = -ENXIO;
1591 }
1592 break;
1593 }
1594
1595 case VIDIOCPWCGVIDCMD:
1596 {
1597 ARG_DEF(struct pwc_video_command, cmd);
1598
1599 ARGR(cmd).type = pdev->type;
1600 ARGR(cmd).release = pdev->release;
1601 ARGR(cmd).command_len = pdev->cmd_len;
1602 memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len);
1603 ARGR(cmd).bandlength = pdev->vbandlength;
1604 ARGR(cmd).frame_size = pdev->frame_size;
1605 ARG_OUT(cmd)
1606 break;
1607 }
1608 /*
1609 case VIDIOCPWCGVIDTABLE:
1610 {
1611 ARG_DEF(struct pwc_table_init_buffer, table);
1612 ARGR(table).len = pdev->cmd_len;
1613 memcpy(&ARGR(table).buffer, pdev->decompress_data, pdev->decompressor->table_size);
1614 ARG_OUT(table)
1615 break;
1616 }
1617 */
1618
1619 default:
1620 ret = -ENOIOCTLCMD;
1621 break;
1622 }
1623
1624 if (ret > 0)
1625 return 0;
1626 return ret;
1627}
1628
1629
1630
diff --git a/drivers/usb/media/pwc/pwc-dec1.c b/drivers/usb/media/pwc/pwc-dec1.c
new file mode 100644
index 000000000000..57d03d9178f6
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-dec1.c
@@ -0,0 +1,42 @@
1/* Linux driver for Philips webcam
2 Decompression for chipset version 1
3 (C) 2004 Luc Saillard (luc@saillard.org)
4
5 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
6 driver and thus may have bugs that are not present in the original version.
7 Please send bug reports and support requests to <luc@saillard.org>.
8 The decompression routines have been implemented by reverse-engineering the
9 Nemosoft binary pwcx module. Caveat emptor.
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 as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24*/
25
26
27
28#include "pwc-dec1.h"
29
30
31void pwc_dec1_init(int type, int release, void *buffer, void *table)
32{
33
34}
35
36void pwc_dec1_exit(void)
37{
38
39
40
41}
42
diff --git a/drivers/usb/media/pwc/pwc-dec1.h b/drivers/usb/media/pwc/pwc-dec1.h
new file mode 100644
index 000000000000..a7ffd9c45a2c
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-dec1.h
@@ -0,0 +1,36 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
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
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
26
27#ifndef PWC_DEC1_H
28#define PWC_DEC1_H
29
30void pwc_dec1_init(int type, int release, void *buffer, void *private_data);
31void pwc_dec1_exit(void);
32
33#endif
34
35
36
diff --git a/drivers/usb/media/pwc/pwc-dec23.c b/drivers/usb/media/pwc/pwc-dec23.c
new file mode 100644
index 000000000000..98fa3f7a9eff
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-dec23.c
@@ -0,0 +1,623 @@
1/* Linux driver for Philips webcam
2 Decompression for chipset version 2 et 3
3 (C) 2004 Luc Saillard (luc@saillard.org)
4
5 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
6 driver and thus may have bugs that are not present in the original version.
7 Please send bug reports and support requests to <luc@saillard.org>.
8 The decompression routines have been implemented by reverse-engineering the
9 Nemosoft binary pwcx module. Caveat emptor.
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 as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24*/
25
26#include "pwc-timon.h"
27#include "pwc-kiara.h"
28#include "pwc-dec23.h"
29#include "pwc-ioctl.h"
30
31#include <linux/string.h>
32
33/****
34 *
35 *
36 *
37 */
38
39
40static void fill_table_a000(unsigned int *p)
41{
42 static unsigned int initial_values[12] = {
43 0xFFAD9B00, 0xFFDDEE00, 0x00221200, 0x00526500,
44 0xFFC21E00, 0x003DE200, 0xFF924B80, 0xFFD2A300,
45 0x002D5D00, 0x006DB480, 0xFFED3E00, 0x0012C200
46 };
47 static unsigned int values_derivated[12] = {
48 0x0000A4CA, 0x00004424, 0xFFFFBBDC, 0xFFFF5B36,
49 0x00007BC4, 0xFFFF843C, 0x0000DB69, 0x00005ABA,
50 0xFFFFA546, 0xFFFF2497, 0x00002584, 0xFFFFDA7C
51 };
52 unsigned int temp_values[12];
53 int i,j;
54
55 memcpy(temp_values,initial_values,sizeof(initial_values));
56 for (i=0;i<256;i++)
57 {
58 for (j=0;j<12;j++)
59 {
60 *p++ = temp_values[j];
61 temp_values[j] += values_derivated[j];
62 }
63 }
64}
65
66static void fill_table_d000(unsigned char *p)
67{
68 int bit,byte;
69
70 for (bit=0; bit<8; bit++)
71 {
72 unsigned char bitpower = 1<<bit;
73 unsigned char mask = bitpower-1;
74 for (byte=0; byte<256; byte++)
75 {
76 if (byte & bitpower)
77 *p++ = -(byte & mask);
78 else
79 *p++ = (byte & mask);
80 }
81 }
82}
83
84/*
85 *
86 * Kiara: 0 <= ver <= 7
87 * Timon: 0 <= ver <= 15
88 *
89 */
90static void fill_table_color(unsigned int version, const unsigned int *romtable,
91 unsigned char *p0004,
92 unsigned char *p8004)
93{
94 const unsigned int *table;
95 unsigned char *p0, *p8;
96 int i,j,k;
97 int dl,bit,pw;
98
99 romtable += version*256;
100
101 for (i=0; i<2; i++)
102 {
103 table = romtable + i*128;
104
105 for (dl=0; dl<16; dl++)
106 {
107 p0 = p0004 + (i<<14) + (dl<<10);
108 p8 = p8004 + (i<<12) + (dl<<8);
109
110 for (j=0; j<8; j++ , table++, p0+=128)
111 {
112 for (k=0; k<16; k++)
113 {
114 if (k==0)
115 bit=1;
116 else if (k>=1 && k<3)
117 bit=(table[0]>>15)&7;
118 else if (k>=3 && k<6)
119 bit=(table[0]>>12)&7;
120 else if (k>=6 && k<10)
121 bit=(table[0]>>9)&7;
122 else if (k>=10 && k<13)
123 bit=(table[0]>>6)&7;
124 else if (k>=13 && k<15)
125 bit=(table[0]>>3)&7;
126 else
127 bit=(table[0])&7;
128 if (k == 0)
129 *(unsigned char *)p8++ = 8;
130 else
131 *(unsigned char *)p8++ = j - bit;
132 *(unsigned char *)p8++ = bit;
133
134 pw = 1<<bit;
135 p0[k+0x00] = (1*pw) + 0x80;
136 p0[k+0x10] = (2*pw) + 0x80;
137 p0[k+0x20] = (3*pw) + 0x80;
138 p0[k+0x30] = (4*pw) + 0x80;
139 p0[k+0x40] = (-pw) + 0x80;
140 p0[k+0x50] = (2*-pw) + 0x80;
141 p0[k+0x60] = (3*-pw) + 0x80;
142 p0[k+0x70] = (4*-pw) + 0x80;
143 } /* end of for (k=0; k<16; k++, p8++) */
144 } /* end of for (j=0; j<8; j++ , table++) */
145 } /* end of for (dl=0; dl<16; dl++) */
146 } /* end of for (i=0; i<2; i++) */
147}
148
149/*
150 * precision = (pdev->xx + pdev->yy)
151 *
152 */
153static void fill_table_dc00_d800(unsigned int precision, unsigned int *pdc00, unsigned int *pd800)
154{
155 int i;
156 unsigned int offset1, offset2;
157
158 for(i=0,offset1=0x4000, offset2=0; i<256 ; i++,offset1+=0x7BC4, offset2+=0x7BC4)
159 {
160 unsigned int msb = offset1 >> 15;
161
162 if ( msb > 255)
163 {
164 if (msb)
165 msb=0;
166 else
167 msb=255;
168 }
169
170 *pdc00++ = msb << precision;
171 *pd800++ = offset2;
172 }
173
174}
175
176/*
177 * struct {
178 * unsigned char op; // operation to execute
179 * unsigned char bits; // bits use to perform operation
180 * unsigned char offset1; // offset to add to access in the table_0004 % 16
181 * unsigned char offset2; // offset to add to access in the table_0004
182 * }
183 *
184 */
185static unsigned int table_ops[] = {
1860x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x01,0x30,
1870x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x20, 0x01,0x00,0x00,0x00,
1880x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x00,
1890x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x00, 0x01,0x00,0x00,0x00,
1900x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x02,0x10,
1910x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x60, 0x01,0x00,0x00,0x00,
1920x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x40,
1930x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x40, 0x01,0x00,0x00,0x00,
1940x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x01,0x70,
1950x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x20, 0x01,0x00,0x00,0x00,
1960x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x00,
1970x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x00, 0x01,0x00,0x00,0x00,
1980x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x02,0x50,
1990x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x60, 0x01,0x00,0x00,0x00,
2000x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x40,
2010x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x40, 0x01,0x00,0x00,0x00
202};
203
204/*
205 * TODO: multiply by 4 all values
206 *
207 */
208static unsigned int MulIdx[256] = {
209 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
210 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
211 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
212 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,
213 6, 7, 8, 9, 7,10,11, 8, 8,11,10, 7, 9, 8, 7, 6,
214 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,
215 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,
216 0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,
217 0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,
218 1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,
219 7,10,11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8,11,10, 7,
220 4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,
221 7, 9, 6, 8,10, 8, 7,11,11, 7, 8,10, 8, 6, 9, 7,
222 1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,
223 1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,
22410, 8, 7,11, 8, 6, 9, 7, 7, 9, 6, 8,11, 7, 8,10
225};
226
227
228
229void pwc_dec23_init(int type, int release, unsigned char *mode, void *data)
230{
231 int flags;
232 struct pwc_dec23_private *pdev = data;
233 release = release;
234
235 switch (type)
236 {
237 case 720:
238 case 730:
239 case 740:
240 case 750:
241 flags = mode[2]&0x18; /* our: flags = 8, mode[2]==e8 */
242 if (flags==8)
243 pdev->zz = 7;
244 else if (flags==0x10)
245 pdev->zz = 8;
246 else
247 pdev->zz = 6;
248 flags = mode[2]>>5; /* our: 7 */
249
250 fill_table_color(flags, (unsigned int *)KiaraRomTable, pdev->table_0004, pdev->table_8004);
251 break;
252
253
254 case 675:
255 case 680:
256 case 690:
257 flags = mode[2]&6;
258 if (flags==2)
259 pdev->zz = 7;
260 else if (flags==4)
261 pdev->zz = 8;
262 else
263 pdev->zz = 6;
264 flags = mode[2]>>3;
265
266 fill_table_color(flags, (unsigned int *)TimonRomTable, pdev->table_0004, pdev->table_8004);
267 break;
268
269 default:
270 /* Not supported */
271 return;
272 }
273
274 /* * * * ** */
275 pdev->xx = 8 - pdev->zz;
276 pdev->yy = 15 - pdev->xx;
277 pdev->zzmask = 0xFF>>pdev->xx;
278 //pdev->zzmask = (1U<<pdev->zz)-1;
279
280
281 fill_table_dc00_d800(pdev->xx + pdev->yy, pdev->table_dc00, pdev->table_d800);
282 fill_table_a000(pdev->table_a004);
283 fill_table_d000(pdev->table_d004);
284}
285
286
287/*
288 * To manage the stream, we keep in a 32 bits variables,
289 * the next bits in the stream. fill_reservoir() add to
290 * the reservoir at least wanted nbits.
291 *
292 *
293 */
294#define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
295 while (nbits_in_reservoir<nbits_wanted) \
296 { \
297 reservoir |= (*(stream)++) << nbits_in_reservoir; \
298 nbits_in_reservoir+=8; \
299 } \
300} while(0);
301
302#define get_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \
303 fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted); \
304 result = (reservoir) & ((1U<<nbits_wanted)-1); \
305 reservoir >>= nbits_wanted; \
306 nbits_in_reservoir -= nbits_wanted; \
307} while(0);
308
309
310
311static void DecompressBand23(const struct pwc_dec23_private *pdev,
312 const unsigned char *rawyuv,
313 unsigned char *planar_y,
314 unsigned char *planar_u,
315 unsigned char *planar_v,
316 unsigned int image_x, /* aka number of pixels wanted ??? */
317 unsigned int pixels_per_line, /* aka number of pixels per line */
318 int flags)
319{
320
321
322 unsigned int reservoir, nbits_in_reservoir;
323 int first_4_bits;
324 unsigned int bytes_per_channel;
325 int line_size; /* size of the line (4Y+U+V) */
326 int passes;
327 const unsigned char *ptable0004, *ptable8004;
328
329 int even_line;
330 unsigned int temp_colors[16];
331 int nblocks;
332
333 const unsigned char *stream;
334 unsigned char *dest_y, *dest_u=NULL, *dest_v=NULL;
335 unsigned int offset_to_plane_u, offset_to_plane_v;
336
337 int i;
338
339
340 reservoir = 0;
341 nbits_in_reservoir = 0;
342 stream = rawyuv+1; /* The first byte of the stream is skipped */
343 even_line = 1;
344
345 get_nbits(reservoir,nbits_in_reservoir,stream,4,first_4_bits);
346
347 line_size = pixels_per_line*3;
348
349 for (passes=0;passes<2;passes++)
350 {
351 if (passes==0)
352 {
353 bytes_per_channel = pixels_per_line;
354 dest_y = planar_y;
355 nblocks = image_x/4;
356 }
357 else
358 {
359 /* Format planar: All Y, then all U, then all V */
360 bytes_per_channel = pixels_per_line/2;
361 dest_u = planar_u;
362 dest_v = planar_v;
363 dest_y = dest_u;
364 nblocks = image_x/8;
365 }
366
367 offset_to_plane_u = bytes_per_channel*2;
368 offset_to_plane_v = bytes_per_channel*3;
369 /*
370 printf("bytes_per_channel = %d\n",bytes_per_channel);
371 printf("offset_to_plane_u = %d\n",offset_to_plane_u);
372 printf("offset_to_plane_v = %d\n",offset_to_plane_v);
373 */
374
375 while (nblocks-->0)
376 {
377 unsigned int gray_index;
378
379 fill_nbits(reservoir,nbits_in_reservoir,stream,16);
380 gray_index = reservoir & pdev->zzmask;
381 reservoir >>= pdev->zz;
382 nbits_in_reservoir -= pdev->zz;
383
384 fill_nbits(reservoir,nbits_in_reservoir,stream,2);
385
386 if ( (reservoir & 3) == 0)
387 {
388 reservoir>>=2;
389 nbits_in_reservoir-=2;
390 for (i=0;i<16;i++)
391 temp_colors[i] = pdev->table_dc00[gray_index];
392
393 }
394 else
395 {
396 unsigned int channel_v, offset1;
397
398 /* swap bit 0 and 2 of offset_OR */
399 channel_v = ((reservoir & 1) << 2) | (reservoir & 2) | ((reservoir & 4)>>2);
400 reservoir>>=3;
401 nbits_in_reservoir-=3;
402
403 for (i=0;i<16;i++)
404 temp_colors[i] = pdev->table_d800[gray_index];
405
406 ptable0004 = pdev->table_0004 + (passes*16384) + (first_4_bits*1024) + (channel_v*128);
407 ptable8004 = pdev->table_8004 + (passes*4096) + (first_4_bits*256) + (channel_v*32);
408
409 offset1 = 0;
410 while(1)
411 {
412 unsigned int index_in_table_ops, op, rows=0;
413 fill_nbits(reservoir,nbits_in_reservoir,stream,16);
414
415 /* mode is 0,1 or 2 */
416 index_in_table_ops = (reservoir&0x3F);
417 op = table_ops[ index_in_table_ops*4 ];
418 if (op == 2)
419 {
420 reservoir >>= 2;
421 nbits_in_reservoir -= 2;
422 break; /* exit the while(1) */
423 }
424 if (op == 0)
425 {
426 unsigned int shift;
427
428 offset1 = (offset1 + table_ops[index_in_table_ops*4+2]) & 0x0F;
429 shift = table_ops[ index_in_table_ops*4+1 ];
430 reservoir >>= shift;
431 nbits_in_reservoir -= shift;
432 rows = ptable0004[ offset1 + table_ops[index_in_table_ops*4+3] ];
433 }
434 if (op == 1)
435 {
436 /* 10bits [ xxxx xxxx yyyy 000 ]
437 * yyy => offset in the table8004
438 * xxx => offset in the tabled004
439 */
440 unsigned int mask, shift;
441 unsigned int col1, row1, total_bits;
442
443 offset1 = (offset1 + ((reservoir>>3)&0x0F)+1) & 0x0F;
444
445 col1 = (reservoir>>7) & 0xFF;
446 row1 = ptable8004 [ offset1*2 ];
447
448 /* Bit mask table */
449 mask = pdev->table_d004[ (row1<<8) + col1 ];
450 shift = ptable8004 [ offset1*2 + 1];
451 rows = ((mask << shift) + 0x80) & 0xFF;
452
453 total_bits = row1 + 8;
454 reservoir >>= total_bits;
455 nbits_in_reservoir -= total_bits;
456 }
457 {
458 const unsigned int *table_a004 = pdev->table_a004 + rows*12;
459 unsigned int *poffset = MulIdx + offset1*16; /* 64/4 (int) */
460 for (i=0;i<16;i++)
461 {
462 temp_colors[i] += table_a004[ *poffset ];
463 poffset++;
464 }
465 }
466 }
467 }
468#define USE_SIGNED_INT_FOR_COLOR
469#ifdef USE_SIGNED_INT_FOR_COLOR
470# define CLAMP(x) ((x)>255?255:((x)<0?0:x))
471#else
472# define CLAMP(x) ((x)>255?255:x)
473#endif
474
475 if (passes == 0)
476 {
477#ifdef USE_SIGNED_INT_FOR_COLOR
478 const int *c = temp_colors;
479#else
480 const unsigned int *c = temp_colors;
481#endif
482 unsigned char *d;
483
484 d = dest_y;
485 for (i=0;i<4;i++,c++)
486 *d++ = CLAMP((*c) >> pdev->yy);
487
488 d = dest_y + bytes_per_channel;
489 for (i=0;i<4;i++,c++)
490 *d++ = CLAMP((*c) >> pdev->yy);
491
492 d = dest_y + offset_to_plane_u;
493 for (i=0;i<4;i++,c++)
494 *d++ = CLAMP((*c) >> pdev->yy);
495
496 d = dest_y + offset_to_plane_v;
497 for (i=0;i<4;i++,c++)
498 *d++ = CLAMP((*c) >> pdev->yy);
499
500 dest_y += 4;
501 }
502 else if (passes == 1)
503 {
504#ifdef USE_SIGNED_INT_FOR_COLOR
505 int *c1 = temp_colors;
506 int *c2 = temp_colors+4;
507#else
508 unsigned int *c1 = temp_colors;
509 unsigned int *c2 = temp_colors+4;
510#endif
511 unsigned char *d;
512
513 d = dest_y;
514 for (i=0;i<4;i++,c1++,c2++)
515 {
516 *d++ = CLAMP((*c1) >> pdev->yy);
517 *d++ = CLAMP((*c2) >> pdev->yy);
518 }
519 c1 = temp_colors+12;
520 //c2 = temp_colors+8;
521 d = dest_y + bytes_per_channel;
522 for (i=0;i<4;i++,c1++,c2++)
523 {
524 *d++ = CLAMP((*c1) >> pdev->yy);
525 *d++ = CLAMP((*c2) >> pdev->yy);
526 }
527
528 if (even_line) /* Each line, swap u/v */
529 {
530 even_line=0;
531 dest_y = dest_v;
532 dest_u += 8;
533 }
534 else
535 {
536 even_line=1;
537 dest_y = dest_u;
538 dest_v += 8;
539 }
540 }
541
542 } /* end of while (nblocks-->0) */
543
544 } /* end of for (passes=0;passes<2;passes++) */
545
546}
547
548
549/**
550 *
551 * image: size of the image wanted
552 * view : size of the image returned by the camera
553 * offset: (x,y) to displayer image in the view
554 *
555 * src: raw data
556 * dst: image output
557 * flags: PWCX_FLAG_PLANAR
558 * pdev: private buffer
559 * bandlength:
560 *
561 */
562void pwc_dec23_decompress(const struct pwc_coord *image,
563 const struct pwc_coord *view,
564 const struct pwc_coord *offset,
565 const void *src,
566 void *dst,
567 int flags,
568 const void *data,
569 int bandlength)
570{
571 const struct pwc_dec23_private *pdev = data;
572 unsigned char *pout, *pout_planar_y=NULL, *pout_planar_u=NULL, *pout_planar_v=NULL;
573 int i,n,stride,pixel_size;
574
575
576 if (flags & PWCX_FLAG_BAYER)
577 {
578 pout = dst + (view->x * offset->y) + offset->x;
579 pixel_size = view->x * 4;
580 }
581 else
582 {
583 n = view->x * view->y;
584
585 /* offset in Y plane */
586 stride = view->x * offset->y;
587 pout_planar_y = dst + stride + offset->x;
588
589 /* offsets in U/V planes */
590 stride = (view->x * offset->y)/4 + offset->x/2;
591 pout_planar_u = dst + n + + stride;
592 pout_planar_v = dst + n + n/4 + stride;
593
594 pixel_size = view->x * 4;
595 }
596
597
598 for (i=0;i<image->y;i+=4)
599 {
600 if (flags & PWCX_FLAG_BAYER)
601 {
602 //TODO:
603 //DecompressBandBayer(pdev,src,pout,image.x,view->x,flags);
604 src += bandlength;
605 pout += pixel_size;
606 }
607 else
608 {
609 DecompressBand23(pdev,src,pout_planar_y,pout_planar_u,pout_planar_v,image->x,view->x,flags);
610 src += bandlength;
611 pout_planar_y += pixel_size;
612 pout_planar_u += view->x;
613 pout_planar_v += view->x;
614 }
615 }
616}
617
618void pwc_dec23_exit(void)
619{
620 /* Do nothing */
621
622}
623
diff --git a/drivers/usb/media/pwc/pwc-dec23.h b/drivers/usb/media/pwc/pwc-dec23.h
new file mode 100644
index 000000000000..5b2aacdefa6c
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-dec23.h
@@ -0,0 +1,58 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
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
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25#ifndef PWC_DEC23_H
26#define PWC_DEC23_H
27
28struct pwc_dec23_private
29{
30 unsigned char xx,yy,zz,zzmask;
31
32 unsigned char table_0004[2*0x4000];
33 unsigned char table_8004[2*0x1000];
34 unsigned int table_a004[256*12];
35
36 unsigned char table_d004[8*256];
37 unsigned int table_d800[256];
38 unsigned int table_dc00[256];
39};
40
41
42void pwc_dec23_init(int type, int release, unsigned char *buffer, void *private_data);
43void pwc_dec23_exit(void);
44void pwc_dec23_decompress(const struct pwc_coord *image,
45 const struct pwc_coord *view,
46 const struct pwc_coord *offset,
47 const void *src,
48 void *dst,
49 int flags,
50 const void *data,
51 int bandlength);
52
53
54
55#endif
56
57
58
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
new file mode 100644
index 000000000000..100a5a4f03a3
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -0,0 +1,2212 @@
1/* Linux driver for Philips webcam
2 USB and Video4Linux interface part.
3 (C) 1999-2004 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org)
5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version.
8 Please send bug reports and support requests to <luc@saillard.org>.
9 The decompression routines have been implemented by reverse-engineering the
10 Nemosoft binary pwcx module. Caveat emptor.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
26*/
27
28/*
29 This code forms the interface between the USB layers and the Philips
30 specific stuff. Some adanved stuff of the driver falls under an
31 NDA, signed between me and Philips B.V., Eindhoven, the Netherlands, and
32 is thus not distributed in source form. The binary pwcx.o module
33 contains the code that falls under the NDA.
34
35 In case you're wondering: 'pwc' stands for "Philips WebCam", but
36 I really didn't want to type 'philips_web_cam' every time (I'm lazy as
37 any Linux kernel hacker, but I don't like uncomprehensible abbreviations
38 without explanation).
39
40 Oh yes, convention: to disctinguish between all the various pointers to
41 device-structures, I use these names for the pointer variables:
42 udev: struct usb_device *
43 vdev: struct video_device *
44 pdev: struct pwc_devive *
45*/
46
47/* Contributors:
48 - Alvarado: adding whitebalance code
49 - Alistar Moire: QuickCam 3000 Pro device/product ID
50 - Tony Hoyle: Creative Labs Webcam 5 device/product ID
51 - Mark Burazin: solving hang in VIDIOCSYNC when camera gets unplugged
52 - Jk Fang: Sotec Afina Eye ID
53 - Xavier Roche: QuickCam Pro 4000 ID
54 - Jens Knudsen: QuickCam Zoom ID
55 - J. Debert: QuickCam for Notebooks ID
56*/
57
58#include <linux/errno.h>
59#include <linux/init.h>
60#include <linux/mm.h>
61#include <linux/module.h>
62#include <linux/poll.h>
63#include <linux/slab.h>
64#include <linux/vmalloc.h>
65#include <asm/io.h>
66
67#include "pwc.h"
68#include "pwc-ioctl.h"
69#include "pwc-kiara.h"
70#include "pwc-timon.h"
71#include "pwc-dec23.h"
72#include "pwc-dec1.h"
73#include "pwc-uncompress.h"
74
75/* Function prototypes and driver templates */
76
77/* hotplug device table support */
78static struct usb_device_id pwc_device_table [] = {
79 { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */
80 { USB_DEVICE(0x0471, 0x0303) },
81 { USB_DEVICE(0x0471, 0x0304) },
82 { USB_DEVICE(0x0471, 0x0307) },
83 { USB_DEVICE(0x0471, 0x0308) },
84 { USB_DEVICE(0x0471, 0x030C) },
85 { USB_DEVICE(0x0471, 0x0310) },
86 { USB_DEVICE(0x0471, 0x0311) },
87 { USB_DEVICE(0x0471, 0x0312) },
88 { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
89 { USB_DEVICE(0x069A, 0x0001) }, /* Askey */
90 { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
91 { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
92 { USB_DEVICE(0x046D, 0x08B2) }, /* Logitech QuickCam Pro 4000 */
93 { USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */
94 { USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */
95 { USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */
96 { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */
97 { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */
98 { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */
99 { USB_DEVICE(0x055D, 0x9000) }, /* Samsung */
100 { USB_DEVICE(0x055D, 0x9001) },
101 { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */
102 { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */
103 { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */
104 { USB_DEVICE(0x06BE, 0x8116) }, /* new Afina Eye */
105 { USB_DEVICE(0x0d81, 0x1910) }, /* Visionite */
106 { USB_DEVICE(0x0d81, 0x1900) },
107 { }
108};
109MODULE_DEVICE_TABLE(usb, pwc_device_table);
110
111static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id);
112static void usb_pwc_disconnect(struct usb_interface *intf);
113
114static struct usb_driver pwc_driver = {
115 .owner = THIS_MODULE,
116 .name = "Philips webcam", /* name */
117 .id_table = pwc_device_table,
118 .probe = usb_pwc_probe, /* probe() */
119 .disconnect = usb_pwc_disconnect, /* disconnect() */
120};
121
122#define MAX_DEV_HINTS 20
123#define MAX_ISOC_ERRORS 20
124
125static int default_size = PSZ_QCIF;
126static int default_fps = 10;
127static int default_fbufs = 3; /* Default number of frame buffers */
128static int default_mbufs = 2; /* Default number of mmap() buffers */
129 int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX;
130static int power_save = 0;
131static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */
132 int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */
133static struct {
134 int type;
135 char serial_number[30];
136 int device_node;
137 struct pwc_device *pdev;
138} device_hint[MAX_DEV_HINTS];
139
140/***/
141
142static int pwc_video_open(struct inode *inode, struct file *file);
143static int pwc_video_close(struct inode *inode, struct file *file);
144static ssize_t pwc_video_read(struct file *file, char __user * buf,
145 size_t count, loff_t *ppos);
146static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
147static int pwc_video_ioctl(struct inode *inode, struct file *file,
148 unsigned int ioctlnr, unsigned long arg);
149static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
150
151static struct file_operations pwc_fops = {
152 .owner = THIS_MODULE,
153 .open = pwc_video_open,
154 .release = pwc_video_close,
155 .read = pwc_video_read,
156 .poll = pwc_video_poll,
157 .mmap = pwc_video_mmap,
158 .ioctl = pwc_video_ioctl,
159 .llseek = no_llseek,
160};
161static struct video_device pwc_template = {
162 .owner = THIS_MODULE,
163 .name = "Philips Webcam", /* Filled in later */
164 .type = VID_TYPE_CAPTURE,
165 .hardware = VID_HARDWARE_PWC,
166 .release = video_device_release,
167 .fops = &pwc_fops,
168 .minor = -1,
169};
170
171/***************************************************************************/
172
173/* Okay, this is some magic that I worked out and the reasoning behind it...
174
175 The biggest problem with any USB device is of course: "what to do
176 when the user unplugs the device while it is in use by an application?"
177 We have several options:
178 1) Curse them with the 7 plagues when they do (requires divine intervention)
179 2) Tell them not to (won't work: they'll do it anyway)
180 3) Oops the kernel (this will have a negative effect on a user's uptime)
181 4) Do something sensible.
182
183 Of course, we go for option 4.
184
185 It happens that this device will be linked to two times, once from
186 usb_device and once from the video_device in their respective 'private'
187 pointers. This is done when the device is probed() and all initialization
188 succeeded. The pwc_device struct links back to both structures.
189
190 When a device is unplugged while in use it will be removed from the
191 list of known USB devices; I also de-register it as a V4L device, but
192 unfortunately I can't free the memory since the struct is still in use
193 by the file descriptor. This free-ing is then deferend until the first
194 opportunity. Crude, but it works.
195
196 A small 'advantage' is that if a user unplugs the cam and plugs it back
197 in, it should get assigned the same video device minor, but unfortunately
198 it's non-trivial to re-link the cam back to the video device... (that
199 would surely be magic! :))
200*/
201
202/***************************************************************************/
203/* Private functions */
204
205/* Here we want the physical address of the memory.
206 * This is used when initializing the contents of the area.
207 */
208static inline unsigned long kvirt_to_pa(unsigned long adr)
209{
210 unsigned long kva, ret;
211
212 kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
213 kva |= adr & (PAGE_SIZE-1); /* restore the offset */
214 ret = __pa(kva);
215 return ret;
216}
217
218static void * rvmalloc(unsigned long size)
219{
220 void * mem;
221 unsigned long adr;
222
223 size=PAGE_ALIGN(size);
224 mem=vmalloc_32(size);
225 if (mem)
226 {
227 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
228 adr=(unsigned long) mem;
229 while (size > 0)
230 {
231 SetPageReserved(vmalloc_to_page((void *)adr));
232 adr+=PAGE_SIZE;
233 size-=PAGE_SIZE;
234 }
235 }
236 return mem;
237}
238
239static void rvfree(void * mem, unsigned long size)
240{
241 unsigned long adr;
242
243 if (mem)
244 {
245 adr=(unsigned long) mem;
246 while ((long) size > 0)
247 {
248 ClearPageReserved(vmalloc_to_page((void *)adr));
249 adr+=PAGE_SIZE;
250 size-=PAGE_SIZE;
251 }
252 vfree(mem);
253 }
254}
255
256
257
258
259static int pwc_allocate_buffers(struct pwc_device *pdev)
260{
261 int i;
262 void *kbuf;
263
264 Trace(TRACE_MEMORY, ">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev);
265
266 if (pdev == NULL)
267 return -ENXIO;
268
269#ifdef PWC_MAGIC
270 if (pdev->magic != PWC_MAGIC) {
271 Err("allocate_buffers(): magic failed.\n");
272 return -ENXIO;
273 }
274#endif
275 /* Allocate Isochronuous pipe buffers */
276 for (i = 0; i < MAX_ISO_BUFS; i++) {
277 if (pdev->sbuf[i].data == NULL) {
278 kbuf = kmalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
279 if (kbuf == NULL) {
280 Err("Failed to allocate iso buffer %d.\n", i);
281 return -ENOMEM;
282 }
283 Trace(TRACE_MEMORY, "Allocated iso buffer at %p.\n", kbuf);
284 pdev->sbuf[i].data = kbuf;
285 memset(kbuf, 0, ISO_BUFFER_SIZE);
286 }
287 }
288
289 /* Allocate frame buffer structure */
290 if (pdev->fbuf == NULL) {
291 kbuf = kmalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL);
292 if (kbuf == NULL) {
293 Err("Failed to allocate frame buffer structure.\n");
294 return -ENOMEM;
295 }
296 Trace(TRACE_MEMORY, "Allocated frame buffer structure at %p.\n", kbuf);
297 pdev->fbuf = kbuf;
298 memset(kbuf, 0, default_fbufs * sizeof(struct pwc_frame_buf));
299 }
300 /* create frame buffers, and make circular ring */
301 for (i = 0; i < default_fbufs; i++) {
302 if (pdev->fbuf[i].data == NULL) {
303 kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
304 if (kbuf == NULL) {
305 Err("Failed to allocate frame buffer %d.\n", i);
306 return -ENOMEM;
307 }
308 Trace(TRACE_MEMORY, "Allocated frame buffer %d at %p.\n", i, kbuf);
309 pdev->fbuf[i].data = kbuf;
310 memset(kbuf, 128, PWC_FRAME_SIZE);
311 }
312 }
313
314 /* Allocate decompressor table space */
315 kbuf = NULL;
316 switch (pdev->type)
317 {
318 case 675:
319 case 680:
320 case 690:
321 case 720:
322 case 730:
323 case 740:
324 case 750:
325 Trace(TRACE_MEMORY,"private_data(%Zd)\n",sizeof(struct pwc_dec23_private));
326 kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); /* Timon & Kiara */
327 break;
328 case 645:
329 case 646:
330 /* TODO & FIXME */
331 kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
332 break;
333 }
334 if (kbuf == NULL) {
335 Err("Failed to allocate decompress table.\n");
336 return -ENOMEM;
337 }
338 pdev->decompress_data = kbuf;
339
340 /* Allocate image buffer; double buffer for mmap() */
341 kbuf = rvmalloc(default_mbufs * pdev->len_per_image);
342 if (kbuf == NULL) {
343 Err("Failed to allocate image buffer(s). needed (%d)\n",default_mbufs * pdev->len_per_image);
344 return -ENOMEM;
345 }
346 Trace(TRACE_MEMORY, "Allocated image buffer at %p.\n", kbuf);
347 pdev->image_data = kbuf;
348 for (i = 0; i < default_mbufs; i++)
349 pdev->image_ptr[i] = kbuf + i * pdev->len_per_image;
350 for (; i < MAX_IMAGES; i++)
351 pdev->image_ptr[i] = NULL;
352
353 kbuf = NULL;
354
355 Trace(TRACE_MEMORY, "<< pwc_allocate_buffers()\n");
356 return 0;
357}
358
359static void pwc_free_buffers(struct pwc_device *pdev)
360{
361 int i;
362
363 Trace(TRACE_MEMORY, "Entering free_buffers(%p).\n", pdev);
364
365 if (pdev == NULL)
366 return;
367#ifdef PWC_MAGIC
368 if (pdev->magic != PWC_MAGIC) {
369 Err("free_buffers(): magic failed.\n");
370 return;
371 }
372#endif
373
374 /* Release Iso-pipe buffers */
375 for (i = 0; i < MAX_ISO_BUFS; i++)
376 if (pdev->sbuf[i].data != NULL) {
377 Trace(TRACE_MEMORY, "Freeing ISO buffer at %p.\n", pdev->sbuf[i].data);
378 kfree(pdev->sbuf[i].data);
379 pdev->sbuf[i].data = NULL;
380 }
381
382 /* The same for frame buffers */
383 if (pdev->fbuf != NULL) {
384 for (i = 0; i < default_fbufs; i++) {
385 if (pdev->fbuf[i].data != NULL) {
386 Trace(TRACE_MEMORY, "Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data);
387 vfree(pdev->fbuf[i].data);
388 pdev->fbuf[i].data = NULL;
389 }
390 }
391 kfree(pdev->fbuf);
392 pdev->fbuf = NULL;
393 }
394
395 /* Intermediate decompression buffer & tables */
396 if (pdev->decompress_data != NULL) {
397 Trace(TRACE_MEMORY, "Freeing decompression buffer at %p.\n", pdev->decompress_data);
398 kfree(pdev->decompress_data);
399 pdev->decompress_data = NULL;
400 }
401 pdev->decompressor = NULL;
402
403 /* Release image buffers */
404 if (pdev->image_data != NULL) {
405 Trace(TRACE_MEMORY, "Freeing image buffer at %p.\n", pdev->image_data);
406 rvfree(pdev->image_data, default_mbufs * pdev->len_per_image);
407 }
408 pdev->image_data = NULL;
409
410 Trace(TRACE_MEMORY, "Leaving free_buffers().\n");
411}
412
413/* The frame & image buffer mess.
414
415 Yes, this is a mess. Well, it used to be simple, but alas... In this
416 module, 3 buffers schemes are used to get the data from the USB bus to
417 the user program. The first scheme involves the ISO buffers (called thus
418 since they transport ISO data from the USB controller), and not really
419 interesting. Suffices to say the data from this buffer is quickly
420 gathered in an interrupt handler (pwc_isoc_handler) and placed into the
421 frame buffer.
422
423 The frame buffer is the second scheme, and is the central element here.
424 It collects the data from a single frame from the camera (hence, the
425 name). Frames are delimited by the USB camera with a short USB packet,
426 so that's easy to detect. The frame buffers form a list that is filled
427 by the camera+USB controller and drained by the user process through
428 either read() or mmap().
429
430 The image buffer is the third scheme, in which frames are decompressed
431 and converted into planar format. For mmap() there is more than
432 one image buffer available.
433
434 The frame buffers provide the image buffering. In case the user process
435 is a bit slow, this introduces lag and some undesired side-effects.
436 The problem arises when the frame buffer is full. I used to drop the last
437 frame, which makes the data in the queue stale very quickly. But dropping
438 the frame at the head of the queue proved to be a litte bit more difficult.
439 I tried a circular linked scheme, but this introduced more problems than
440 it solved.
441
442 Because filling and draining are completely asynchronous processes, this
443 requires some fiddling with pointers and mutexes.
444
445 Eventually, I came up with a system with 2 lists: an 'empty' frame list
446 and a 'full' frame list:
447 * Initially, all frame buffers but one are on the 'empty' list; the one
448 remaining buffer is our initial fill frame.
449 * If a frame is needed for filling, we try to take it from the 'empty'
450 list, unless that list is empty, in which case we take the buffer at
451 the head of the 'full' list.
452 * When our fill buffer has been filled, it is appended to the 'full'
453 list.
454 * If a frame is needed by read() or mmap(), it is taken from the head of
455 the 'full' list, handled, and then appended to the 'empty' list. If no
456 buffer is present on the 'full' list, we wait.
457 The advantage is that the buffer that is currently being decompressed/
458 converted, is on neither list, and thus not in our way (any other scheme
459 I tried had the problem of old data lingering in the queue).
460
461 Whatever strategy you choose, it always remains a tradeoff: with more
462 frame buffers the chances of a missed frame are reduced. On the other
463 hand, on slower machines it introduces lag because the queue will
464 always be full.
465 */
466
467/**
468 \brief Find next frame buffer to fill. Take from empty or full list, whichever comes first.
469 */
470static inline int pwc_next_fill_frame(struct pwc_device *pdev)
471{
472 int ret;
473 unsigned long flags;
474
475 ret = 0;
476 spin_lock_irqsave(&pdev->ptrlock, flags);
477 if (pdev->fill_frame != NULL) {
478 /* append to 'full' list */
479 if (pdev->full_frames == NULL) {
480 pdev->full_frames = pdev->fill_frame;
481 pdev->full_frames_tail = pdev->full_frames;
482 }
483 else {
484 pdev->full_frames_tail->next = pdev->fill_frame;
485 pdev->full_frames_tail = pdev->fill_frame;
486 }
487 }
488 if (pdev->empty_frames != NULL) {
489 /* We have empty frames available. That's easy */
490 pdev->fill_frame = pdev->empty_frames;
491 pdev->empty_frames = pdev->empty_frames->next;
492 }
493 else {
494 /* Hmm. Take it from the full list */
495#if PWC_DEBUG
496 /* sanity check */
497 if (pdev->full_frames == NULL) {
498 Err("Neither empty or full frames available!\n");
499 spin_unlock_irqrestore(&pdev->ptrlock, flags);
500 return -EINVAL;
501 }
502#endif
503 pdev->fill_frame = pdev->full_frames;
504 pdev->full_frames = pdev->full_frames->next;
505 ret = 1;
506 }
507 pdev->fill_frame->next = NULL;
508#if PWC_DEBUG
509 Trace(TRACE_SEQUENCE, "Assigning sequence number %d.\n", pdev->sequence);
510 pdev->fill_frame->sequence = pdev->sequence++;
511#endif
512 spin_unlock_irqrestore(&pdev->ptrlock, flags);
513 return ret;
514}
515
516
517/**
518 \brief Reset all buffers, pointers and lists, except for the image_used[] buffer.
519
520 If the image_used[] buffer is cleared too, mmap()/VIDIOCSYNC will run into trouble.
521 */
522static void pwc_reset_buffers(struct pwc_device *pdev)
523{
524 int i;
525 unsigned long flags;
526
527 spin_lock_irqsave(&pdev->ptrlock, flags);
528 pdev->full_frames = NULL;
529 pdev->full_frames_tail = NULL;
530 for (i = 0; i < default_fbufs; i++) {
531 pdev->fbuf[i].filled = 0;
532 if (i > 0)
533 pdev->fbuf[i].next = &pdev->fbuf[i - 1];
534 else
535 pdev->fbuf->next = NULL;
536 }
537 pdev->empty_frames = &pdev->fbuf[default_fbufs - 1];
538 pdev->empty_frames_tail = pdev->fbuf;
539 pdev->read_frame = NULL;
540 pdev->fill_frame = pdev->empty_frames;
541 pdev->empty_frames = pdev->empty_frames->next;
542
543 pdev->image_read_pos = 0;
544 pdev->fill_image = 0;
545 spin_unlock_irqrestore(&pdev->ptrlock, flags);
546}
547
548
549/**
550 \brief Do all the handling for getting one frame: get pointer, decompress, advance pointers.
551 */
552static int pwc_handle_frame(struct pwc_device *pdev)
553{
554 int ret = 0;
555 unsigned long flags;
556
557 spin_lock_irqsave(&pdev->ptrlock, flags);
558 /* First grab our read_frame; this is removed from all lists, so
559 we can release the lock after this without problems */
560 if (pdev->read_frame != NULL) {
561 /* This can't theoretically happen */
562 Err("Huh? Read frame still in use?\n");
563 }
564 else {
565 if (pdev->full_frames == NULL) {
566 Err("Woops. No frames ready.\n");
567 }
568 else {
569 pdev->read_frame = pdev->full_frames;
570 pdev->full_frames = pdev->full_frames->next;
571 pdev->read_frame->next = NULL;
572 }
573
574 if (pdev->read_frame != NULL) {
575#if PWC_DEBUG
576 Trace(TRACE_SEQUENCE, "Decompressing frame %d\n", pdev->read_frame->sequence);
577#endif
578 /* Decompression is a lenghty process, so it's outside of the lock.
579 This gives the isoc_handler the opportunity to fill more frames
580 in the mean time.
581 */
582 spin_unlock_irqrestore(&pdev->ptrlock, flags);
583 ret = pwc_decompress(pdev);
584 spin_lock_irqsave(&pdev->ptrlock, flags);
585
586 /* We're done with read_buffer, tack it to the end of the empty buffer list */
587 if (pdev->empty_frames == NULL) {
588 pdev->empty_frames = pdev->read_frame;
589 pdev->empty_frames_tail = pdev->empty_frames;
590 }
591 else {
592 pdev->empty_frames_tail->next = pdev->read_frame;
593 pdev->empty_frames_tail = pdev->read_frame;
594 }
595 pdev->read_frame = NULL;
596 }
597 }
598 spin_unlock_irqrestore(&pdev->ptrlock, flags);
599 return ret;
600}
601
602/**
603 \brief Advance pointers of image buffer (after each user request)
604*/
605static inline void pwc_next_image(struct pwc_device *pdev)
606{
607 pdev->image_used[pdev->fill_image] = 0;
608 pdev->fill_image = (pdev->fill_image + 1) % default_mbufs;
609}
610
611
612/* This gets called for the Isochronous pipe (video). This is done in
613 * interrupt time, so it has to be fast, not crash, and not stall. Neat.
614 */
615static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
616{
617 struct pwc_device *pdev;
618 int i, fst, flen;
619 int awake;
620 struct pwc_frame_buf *fbuf;
621 unsigned char *fillptr = NULL, *iso_buf = NULL;
622
623 awake = 0;
624 pdev = (struct pwc_device *)urb->context;
625 if (pdev == NULL) {
626 Err("isoc_handler() called with NULL device?!\n");
627 return;
628 }
629#ifdef PWC_MAGIC
630 if (pdev->magic != PWC_MAGIC) {
631 Err("isoc_handler() called with bad magic!\n");
632 return;
633 }
634#endif
635 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
636 Trace(TRACE_OPEN, "pwc_isoc_handler(): URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a");
637 return;
638 }
639 if (urb->status != -EINPROGRESS && urb->status != 0) {
640 const char *errmsg;
641
642 errmsg = "Unknown";
643 switch(urb->status) {
644 case -ENOSR: errmsg = "Buffer error (overrun)"; break;
645 case -EPIPE: errmsg = "Stalled (device not responding)"; break;
646 case -EOVERFLOW: errmsg = "Babble (bad cable?)"; break;
647 case -EPROTO: errmsg = "Bit-stuff error (bad cable?)"; break;
648 case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break;
649 case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break;
650 }
651 Trace(TRACE_FLOW, "pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg);
652 /* Give up after a number of contiguous errors on the USB bus.
653 Appearantly something is wrong so we simulate an unplug event.
654 */
655 if (++pdev->visoc_errors > MAX_ISOC_ERRORS)
656 {
657 Info("Too many ISOC errors, bailing out.\n");
658 pdev->error_status = EIO;
659 awake = 1;
660 wake_up_interruptible(&pdev->frameq);
661 }
662 goto handler_end; // ugly, but practical
663 }
664
665 fbuf = pdev->fill_frame;
666 if (fbuf == NULL) {
667 Err("pwc_isoc_handler without valid fill frame.\n");
668 awake = 1;
669 goto handler_end;
670 }
671 else {
672 fillptr = fbuf->data + fbuf->filled;
673 }
674
675 /* Reset ISOC error counter. We did get here, after all. */
676 pdev->visoc_errors = 0;
677
678 /* vsync: 0 = don't copy data
679 1 = sync-hunt
680 2 = synched
681 */
682 /* Compact data */
683 for (i = 0; i < urb->number_of_packets; i++) {
684 fst = urb->iso_frame_desc[i].status;
685 flen = urb->iso_frame_desc[i].actual_length;
686 iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
687 if (fst == 0) {
688 if (flen > 0) { /* if valid data... */
689 if (pdev->vsync > 0) { /* ...and we are not sync-hunting... */
690 pdev->vsync = 2;
691
692 /* ...copy data to frame buffer, if possible */
693 if (flen + fbuf->filled > pdev->frame_total_size) {
694 Trace(TRACE_FLOW, "Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size);
695 pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */
696 pdev->vframes_error++;
697 }
698 else {
699 memmove(fillptr, iso_buf, flen);
700 fillptr += flen;
701 }
702 }
703 fbuf->filled += flen;
704 } /* ..flen > 0 */
705
706 if (flen < pdev->vlast_packet_size) {
707 /* Shorter packet... We probably have the end of an image-frame;
708 wake up read() process and let select()/poll() do something.
709 Decompression is done in user time over there.
710 */
711 if (pdev->vsync == 2) {
712 /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus
713 frames on the USB wire after an exposure change. This conditition is
714 however detected in the cam and a bit is set in the header.
715 */
716 if (pdev->type == 730) {
717 unsigned char *ptr = (unsigned char *)fbuf->data;
718
719 if (ptr[1] == 1 && ptr[0] & 0x10) {
720#if PWC_DEBUG
721 Debug("Hyundai CMOS sensor bug. Dropping frame %d.\n", fbuf->sequence);
722#endif
723 pdev->drop_frames += 2;
724 pdev->vframes_error++;
725 }
726 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
727 if (ptr[0] & 0x01)
728 Info("Snapshot button pressed.\n");
729 else
730 Info("Snapshot button released.\n");
731 }
732 if ((ptr[0] ^ pdev->vmirror) & 0x02) {
733 if (ptr[0] & 0x02)
734 Info("Image is mirrored.\n");
735 else
736 Info("Image is normal.\n");
737 }
738 pdev->vmirror = ptr[0] & 0x03;
739 /* Sometimes the trailer of the 730 is still sent as a 4 byte packet
740 after a short frame; this condition is filtered out specifically. A 4 byte
741 frame doesn't make sense anyway.
742 So we get either this sequence:
743 drop_bit set -> 4 byte frame -> short frame -> good frame
744 Or this one:
745 drop_bit set -> short frame -> good frame
746 So we drop either 3 or 2 frames in all!
747 */
748 if (fbuf->filled == 4)
749 pdev->drop_frames++;
750 }
751
752 /* In case we were instructed to drop the frame, do so silently.
753 The buffer pointers are not updated either (but the counters are reset below).
754 */
755 if (pdev->drop_frames > 0)
756 pdev->drop_frames--;
757 else {
758 /* Check for underflow first */
759 if (fbuf->filled < pdev->frame_total_size) {
760 Trace(TRACE_FLOW, "Frame buffer underflow (%d bytes); discarded.\n", fbuf->filled);
761 pdev->vframes_error++;
762 }
763 else {
764 /* Send only once per EOF */
765 awake = 1; /* delay wake_ups */
766
767 /* Find our next frame to fill. This will always succeed, since we
768 * nick a frame from either empty or full list, but if we had to
769 * take it from the full list, it means a frame got dropped.
770 */
771 if (pwc_next_fill_frame(pdev)) {
772 pdev->vframes_dumped++;
773 if ((pdev->vframe_count > FRAME_LOWMARK) && (pwc_trace & TRACE_FLOW)) {
774 if (pdev->vframes_dumped < 20)
775 Trace(TRACE_FLOW, "Dumping frame %d.\n", pdev->vframe_count);
776 if (pdev->vframes_dumped == 20)
777 Trace(TRACE_FLOW, "Dumping frame %d (last message).\n", pdev->vframe_count);
778 }
779 }
780 fbuf = pdev->fill_frame;
781 }
782 } /* !drop_frames */
783 pdev->vframe_count++;
784 }
785 fbuf->filled = 0;
786 fillptr = fbuf->data;
787 pdev->vsync = 1;
788 } /* .. flen < last_packet_size */
789 pdev->vlast_packet_size = flen;
790 } /* ..status == 0 */
791#if PWC_DEBUG
792 /* This is normally not interesting to the user, unless you are really debugging something */
793 else {
794 static int iso_error = 0;
795 iso_error++;
796 if (iso_error < 20)
797 Trace(TRACE_FLOW, "Iso frame %d of USB has error %d\n", i, fst);
798 }
799#endif
800 }
801
802handler_end:
803 if (awake)
804 wake_up_interruptible(&pdev->frameq);
805
806 urb->dev = pdev->udev;
807 i = usb_submit_urb(urb, GFP_ATOMIC);
808 if (i != 0)
809 Err("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i);
810}
811
812
813static int pwc_isoc_init(struct pwc_device *pdev)
814{
815 struct usb_device *udev;
816 struct urb *urb;
817 int i, j, ret;
818
819 struct usb_interface *intf;
820 struct usb_host_interface *idesc = NULL;
821
822 if (pdev == NULL)
823 return -EFAULT;
824 if (pdev->iso_init)
825 return 0;
826 pdev->vsync = 0;
827 udev = pdev->udev;
828
829 /* Get the current alternate interface, adjust packet size */
830 if (!udev->actconfig)
831 return -EFAULT;
832#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5)
833 idesc = &udev->actconfig->interface[0]->altsetting[pdev->valternate];
834#else
835 intf = usb_ifnum_to_if(udev, 0);
836 if (intf)
837 idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
838#endif
839
840 if (!idesc)
841 return -EFAULT;
842
843 /* Search video endpoint */
844 pdev->vmax_packet_size = -1;
845 for (i = 0; i < idesc->desc.bNumEndpoints; i++)
846 if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) {
847 pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize);
848 break;
849 }
850
851 if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
852 Err("Failed to find packet size for video endpoint in current alternate setting.\n");
853 return -ENFILE; /* Odd error, that should be noticable */
854 }
855
856 /* Set alternate interface */
857 ret = 0;
858 Trace(TRACE_OPEN, "Setting alternate interface %d\n", pdev->valternate);
859 ret = usb_set_interface(pdev->udev, 0, pdev->valternate);
860 if (ret < 0)
861 return ret;
862
863 for (i = 0; i < MAX_ISO_BUFS; i++) {
864 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
865 if (urb == NULL) {
866 Err("Failed to allocate urb %d\n", i);
867 ret = -ENOMEM;
868 break;
869 }
870 pdev->sbuf[i].urb = urb;
871 Trace(TRACE_MEMORY, "Allocated URB at 0x%p\n", urb);
872 }
873 if (ret) {
874 /* De-allocate in reverse order */
875 while (i >= 0) {
876 if (pdev->sbuf[i].urb != NULL)
877 usb_free_urb(pdev->sbuf[i].urb);
878 pdev->sbuf[i].urb = NULL;
879 i--;
880 }
881 return ret;
882 }
883
884 /* init URB structure */
885 for (i = 0; i < MAX_ISO_BUFS; i++) {
886 urb = pdev->sbuf[i].urb;
887
888 urb->interval = 1; // devik
889 urb->dev = udev;
890 urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint);
891 urb->transfer_flags = URB_ISO_ASAP;
892 urb->transfer_buffer = pdev->sbuf[i].data;
893 urb->transfer_buffer_length = ISO_BUFFER_SIZE;
894 urb->complete = pwc_isoc_handler;
895 urb->context = pdev;
896 urb->start_frame = 0;
897 urb->number_of_packets = ISO_FRAMES_PER_DESC;
898 for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
899 urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE;
900 urb->iso_frame_desc[j].length = pdev->vmax_packet_size;
901 }
902 }
903
904 /* link */
905 for (i = 0; i < MAX_ISO_BUFS; i++) {
906 ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL);
907 if (ret)
908 Err("isoc_init() submit_urb %d failed with error %d\n", i, ret);
909 else
910 Trace(TRACE_MEMORY, "URB 0x%p submitted.\n", pdev->sbuf[i].urb);
911 }
912
913 /* All is done... */
914 pdev->iso_init = 1;
915 Trace(TRACE_OPEN, "<< pwc_isoc_init()\n");
916 return 0;
917}
918
919static void pwc_isoc_cleanup(struct pwc_device *pdev)
920{
921 int i;
922
923 Trace(TRACE_OPEN, ">> pwc_isoc_cleanup()\n");
924 if (pdev == NULL)
925 return;
926
927 /* Unlinking ISOC buffers one by one */
928 for (i = 0; i < MAX_ISO_BUFS; i++) {
929 struct urb *urb;
930
931 urb = pdev->sbuf[i].urb;
932 if (urb != 0) {
933 if (pdev->iso_init) {
934 Trace(TRACE_MEMORY, "Unlinking URB %p\n", urb);
935 usb_kill_urb(urb);
936 }
937 Trace(TRACE_MEMORY, "Freeing URB\n");
938 usb_free_urb(urb);
939 pdev->sbuf[i].urb = NULL;
940 }
941 }
942
943 /* Stop camera, but only if we are sure the camera is still there (unplug
944 is signalled by EPIPE)
945 */
946 if (pdev->error_status && pdev->error_status != EPIPE) {
947 Trace(TRACE_OPEN, "Setting alternate interface 0.\n");
948 usb_set_interface(pdev->udev, 0, 0);
949 }
950
951 pdev->iso_init = 0;
952 Trace(TRACE_OPEN, "<< pwc_isoc_cleanup()\n");
953}
954
955int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot)
956{
957 int ret, start;
958
959 /* Stop isoc stuff */
960 pwc_isoc_cleanup(pdev);
961 /* Reset parameters */
962 pwc_reset_buffers(pdev);
963 /* Try to set video mode... */
964 start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot);
965 if (ret) {
966 Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n");
967 /* That failed... restore old mode (we know that worked) */
968 start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
969 if (start) {
970 Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n");
971 }
972 }
973 if (start == 0)
974 {
975 if (pwc_isoc_init(pdev) < 0)
976 {
977 Info("Failed to restart ISOC transfers in pwc_try_video_mode.\n");
978 ret = -EAGAIN; /* let's try again, who knows if it works a second time */
979 }
980 }
981 pdev->drop_frames++; /* try to avoid garbage during switch */
982 return ret; /* Return original error code */
983}
984
985
986/***************************************************************************/
987/* Video4Linux functions */
988
989static int pwc_video_open(struct inode *inode, struct file *file)
990{
991 int i;
992 struct video_device *vdev = video_devdata(file);
993 struct pwc_device *pdev;
994
995 Trace(TRACE_OPEN, ">> video_open called(vdev = 0x%p).\n", vdev);
996
997 pdev = (struct pwc_device *)vdev->priv;
998 if (pdev == NULL)
999 BUG();
1000 if (pdev->vopen)
1001 return -EBUSY;
1002
1003 down(&pdev->modlock);
1004 if (!pdev->usb_init) {
1005 Trace(TRACE_OPEN, "Doing first time initialization.\n");
1006 pdev->usb_init = 1;
1007
1008 if (pwc_trace & TRACE_OPEN)
1009 {
1010 /* Query sensor type */
1011 const char *sensor_type = NULL;
1012 int ret;
1013
1014 ret = pwc_get_cmos_sensor(pdev, &i);
1015 if (ret >= 0)
1016 {
1017 switch(i) {
1018 case 0x00: sensor_type = "Hyundai CMOS sensor"; break;
1019 case 0x20: sensor_type = "Sony CCD sensor + TDA8787"; break;
1020 case 0x2E: sensor_type = "Sony CCD sensor + Exas 98L59"; break;
1021 case 0x2F: sensor_type = "Sony CCD sensor + ADI 9804"; break;
1022 case 0x30: sensor_type = "Sharp CCD sensor + TDA8787"; break;
1023 case 0x3E: sensor_type = "Sharp CCD sensor + Exas 98L59"; break;
1024 case 0x3F: sensor_type = "Sharp CCD sensor + ADI 9804"; break;
1025 case 0x40: sensor_type = "UPA 1021 sensor"; break;
1026 case 0x100: sensor_type = "VGA sensor"; break;
1027 case 0x101: sensor_type = "PAL MR sensor"; break;
1028 default: sensor_type = "unknown type of sensor"; break;
1029 }
1030 }
1031 if (sensor_type != NULL)
1032 Info("This %s camera is equipped with a %s (%d).\n", pdev->vdev->name, sensor_type, i);
1033 }
1034 }
1035
1036 /* Turn on camera */
1037 if (power_save) {
1038 i = pwc_camera_power(pdev, 1);
1039 if (i < 0)
1040 Info("Failed to restore power to the camera! (%d)\n", i);
1041 }
1042 /* Set LED on/off time */
1043 if (pwc_set_leds(pdev, led_on, led_off) < 0)
1044 Info("Failed to set LED on/off time.\n");
1045
1046 pwc_construct(pdev); /* set min/max sizes correct */
1047
1048 /* So far, so good. Allocate memory. */
1049 i = pwc_allocate_buffers(pdev);
1050 if (i < 0) {
1051 Trace(TRACE_OPEN, "Failed to allocate buffer memory.\n");
1052 up(&pdev->modlock);
1053 return i;
1054 }
1055
1056 /* Reset buffers & parameters */
1057 pwc_reset_buffers(pdev);
1058 for (i = 0; i < default_mbufs; i++)
1059 pdev->image_used[i] = 0;
1060 pdev->vframe_count = 0;
1061 pdev->vframes_dumped = 0;
1062 pdev->vframes_error = 0;
1063 pdev->visoc_errors = 0;
1064 pdev->error_status = 0;
1065#if PWC_DEBUG
1066 pdev->sequence = 0;
1067#endif
1068 pwc_construct(pdev); /* set min/max sizes correct */
1069
1070 /* Set some defaults */
1071 pdev->vsnapshot = 0;
1072
1073 /* Start iso pipe for video; first try the last used video size
1074 (or the default one); if that fails try QCIF/10 or QSIF/10;
1075 it that fails too, give up.
1076 */
1077 i = pwc_set_video_mode(pdev, pwc_image_sizes[pdev->vsize].x, pwc_image_sizes[pdev->vsize].y, pdev->vframes, pdev->vcompression, 0);
1078 if (i) {
1079 Trace(TRACE_OPEN, "First attempt at set_video_mode failed.\n");
1080 if (pdev->type == 730 || pdev->type == 740 || pdev->type == 750)
1081 i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QSIF].x, pwc_image_sizes[PSZ_QSIF].y, 10, pdev->vcompression, 0);
1082 else
1083 i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QCIF].x, pwc_image_sizes[PSZ_QCIF].y, 10, pdev->vcompression, 0);
1084 }
1085 if (i) {
1086 Trace(TRACE_OPEN, "Second attempt at set_video_mode failed.\n");
1087 up(&pdev->modlock);
1088 return i;
1089 }
1090
1091 i = pwc_isoc_init(pdev);
1092 if (i) {
1093 Trace(TRACE_OPEN, "Failed to init ISOC stuff = %d.\n", i);
1094 up(&pdev->modlock);
1095 return i;
1096 }
1097
1098 pdev->vopen++;
1099 file->private_data = vdev;
1100 up(&pdev->modlock);
1101 Trace(TRACE_OPEN, "<< video_open() returns 0.\n");
1102 return 0;
1103}
1104
1105/* Note that all cleanup is done in the reverse order as in _open */
1106static int pwc_video_close(struct inode *inode, struct file *file)
1107{
1108 struct video_device *vdev = file->private_data;
1109 struct pwc_device *pdev;
1110 int i;
1111
1112 Trace(TRACE_OPEN, ">> video_close called(vdev = 0x%p).\n", vdev);
1113
1114 pdev = (struct pwc_device *)vdev->priv;
1115 if (pdev->vopen == 0)
1116 Info("video_close() called on closed device?\n");
1117
1118 /* Dump statistics, but only if a reasonable amount of frames were
1119 processed (to prevent endless log-entries in case of snap-shot
1120 programs)
1121 */
1122 if (pdev->vframe_count > 20)
1123 Info("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error);
1124
1125 switch (pdev->type)
1126 {
1127 case 675:
1128 case 680:
1129 case 690:
1130 case 720:
1131 case 730:
1132 case 740:
1133 case 750:
1134 pwc_dec23_exit(); /* Timon & Kiara */
1135 break;
1136 case 645:
1137 case 646:
1138 pwc_dec1_exit();
1139 break;
1140 }
1141
1142 pwc_isoc_cleanup(pdev);
1143 pwc_free_buffers(pdev);
1144
1145 /* Turn off LEDS and power down camera, but only when not unplugged */
1146 if (pdev->error_status != EPIPE) {
1147 /* Turn LEDs off */
1148 if (pwc_set_leds(pdev, 0, 0) < 0)
1149 Info("Failed to set LED on/off time.\n");
1150 if (power_save) {
1151 i = pwc_camera_power(pdev, 0);
1152 if (i < 0)
1153 Err("Failed to power down camera (%d)\n", i);
1154 }
1155 }
1156 pdev->vopen = 0;
1157 Trace(TRACE_OPEN, "<< video_close()\n");
1158 return 0;
1159}
1160
1161/*
1162 * FIXME: what about two parallel reads ????
1163 * ANSWER: Not supported. You can't open the device more than once,
1164 despite what the V4L1 interface says. First, I don't see
1165 the need, second there's no mechanism of alerting the
1166 2nd/3rd/... process of events like changing image size.
1167 And I don't see the point of blocking that for the
1168 2nd/3rd/... process.
1169 In multi-threaded environments reading parallel from any
1170 device is tricky anyhow.
1171 */
1172
1173static ssize_t pwc_video_read(struct file *file, char __user * buf,
1174 size_t count, loff_t *ppos)
1175{
1176 struct video_device *vdev = file->private_data;
1177 struct pwc_device *pdev;
1178 int noblock = file->f_flags & O_NONBLOCK;
1179 DECLARE_WAITQUEUE(wait, current);
1180 int bytes_to_read;
1181
1182 Trace(TRACE_READ, "video_read(0x%p, %p, %Zd) called.\n", vdev, buf, count);
1183 if (vdev == NULL)
1184 return -EFAULT;
1185 pdev = vdev->priv;
1186 if (pdev == NULL)
1187 return -EFAULT;
1188 if (pdev->error_status)
1189 return -pdev->error_status; /* Something happened, report what. */
1190
1191 /* In case we're doing partial reads, we don't have to wait for a frame */
1192 if (pdev->image_read_pos == 0) {
1193 /* Do wait queueing according to the (doc)book */
1194 add_wait_queue(&pdev->frameq, &wait);
1195 while (pdev->full_frames == NULL) {
1196 /* Check for unplugged/etc. here */
1197 if (pdev->error_status) {
1198 remove_wait_queue(&pdev->frameq, &wait);
1199 set_current_state(TASK_RUNNING);
1200 return -pdev->error_status ;
1201 }
1202 if (noblock) {
1203 remove_wait_queue(&pdev->frameq, &wait);
1204 set_current_state(TASK_RUNNING);
1205 return -EWOULDBLOCK;
1206 }
1207 if (signal_pending(current)) {
1208 remove_wait_queue(&pdev->frameq, &wait);
1209 set_current_state(TASK_RUNNING);
1210 return -ERESTARTSYS;
1211 }
1212 schedule();
1213 set_current_state(TASK_INTERRUPTIBLE);
1214 }
1215 remove_wait_queue(&pdev->frameq, &wait);
1216 set_current_state(TASK_RUNNING);
1217
1218 /* Decompress and release frame */
1219 if (pwc_handle_frame(pdev))
1220 return -EFAULT;
1221 }
1222
1223 Trace(TRACE_READ, "Copying data to user space.\n");
1224 if (pdev->vpalette == VIDEO_PALETTE_RAW)
1225 bytes_to_read = pdev->frame_size;
1226 else
1227 bytes_to_read = pdev->view.size;
1228
1229 /* copy bytes to user space; we allow for partial reads */
1230 if (count + pdev->image_read_pos > bytes_to_read)
1231 count = bytes_to_read - pdev->image_read_pos;
1232 if (copy_to_user(buf, pdev->image_ptr[pdev->fill_image] + pdev->image_read_pos, count))
1233 return -EFAULT;
1234 pdev->image_read_pos += count;
1235 if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */
1236 pdev->image_read_pos = 0;
1237 pwc_next_image(pdev);
1238 }
1239 return count;
1240}
1241
1242static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1243{
1244 struct video_device *vdev = file->private_data;
1245 struct pwc_device *pdev;
1246
1247 if (vdev == NULL)
1248 return -EFAULT;
1249 pdev = vdev->priv;
1250 if (pdev == NULL)
1251 return -EFAULT;
1252
1253 poll_wait(file, &pdev->frameq, wait);
1254 if (pdev->error_status)
1255 return POLLERR;
1256 if (pdev->full_frames != NULL) /* we have frames waiting */
1257 return (POLLIN | POLLRDNORM);
1258
1259 return 0;
1260}
1261
1262static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
1263 unsigned int cmd, void *arg)
1264{
1265 struct video_device *vdev = file->private_data;
1266 struct pwc_device *pdev;
1267 DECLARE_WAITQUEUE(wait, current);
1268
1269 if (vdev == NULL)
1270 return -EFAULT;
1271 pdev = vdev->priv;
1272 if (pdev == NULL)
1273 return -EFAULT;
1274
1275 switch (cmd) {
1276 /* Query cabapilities */
1277 case VIDIOCGCAP:
1278 {
1279 struct video_capability *caps = arg;
1280
1281 strcpy(caps->name, vdev->name);
1282 caps->type = VID_TYPE_CAPTURE;
1283 caps->channels = 1;
1284 caps->audios = 1;
1285 caps->minwidth = pdev->view_min.x;
1286 caps->minheight = pdev->view_min.y;
1287 caps->maxwidth = pdev->view_max.x;
1288 caps->maxheight = pdev->view_max.y;
1289 break;
1290 }
1291
1292 /* Channel functions (simulate 1 channel) */
1293 case VIDIOCGCHAN:
1294 {
1295 struct video_channel *v = arg;
1296
1297 if (v->channel != 0)
1298 return -EINVAL;
1299 v->flags = 0;
1300 v->tuners = 0;
1301 v->type = VIDEO_TYPE_CAMERA;
1302 strcpy(v->name, "Webcam");
1303 return 0;
1304 }
1305
1306 case VIDIOCSCHAN:
1307 {
1308 /* The spec says the argument is an integer, but
1309 the bttv driver uses a video_channel arg, which
1310 makes sense becasue it also has the norm flag.
1311 */
1312 struct video_channel *v = arg;
1313 if (v->channel != 0)
1314 return -EINVAL;
1315 return 0;
1316 }
1317
1318
1319 /* Picture functions; contrast etc. */
1320 case VIDIOCGPICT:
1321 {
1322 struct video_picture *p = arg;
1323 int val;
1324
1325 val = pwc_get_brightness(pdev);
1326 if (val >= 0)
1327 p->brightness = val;
1328 else
1329 p->brightness = 0xffff;
1330 val = pwc_get_contrast(pdev);
1331 if (val >= 0)
1332 p->contrast = val;
1333 else
1334 p->contrast = 0xffff;
1335 /* Gamma, Whiteness, what's the difference? :) */
1336 val = pwc_get_gamma(pdev);
1337 if (val >= 0)
1338 p->whiteness = val;
1339 else
1340 p->whiteness = 0xffff;
1341 val = pwc_get_saturation(pdev);
1342 if (val >= 0)
1343 p->colour = val;
1344 else
1345 p->colour = 0xffff;
1346 p->depth = 24;
1347 p->palette = pdev->vpalette;
1348 p->hue = 0xFFFF; /* N/A */
1349 break;
1350 }
1351
1352 case VIDIOCSPICT:
1353 {
1354 struct video_picture *p = arg;
1355 /*
1356 * FIXME: Suppose we are mid read
1357 ANSWER: No problem: the firmware of the camera
1358 can handle brightness/contrast/etc
1359 changes at _any_ time, and the palette
1360 is used exactly once in the uncompress
1361 routine.
1362 */
1363 pwc_set_brightness(pdev, p->brightness);
1364 pwc_set_contrast(pdev, p->contrast);
1365 pwc_set_gamma(pdev, p->whiteness);
1366 pwc_set_saturation(pdev, p->colour);
1367 if (p->palette && p->palette != pdev->vpalette) {
1368 switch (p->palette) {
1369 case VIDEO_PALETTE_YUV420P:
1370 case VIDEO_PALETTE_RAW:
1371 pdev->vpalette = p->palette;
1372 return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
1373 break;
1374 default:
1375 return -EINVAL;
1376 break;
1377 }
1378 }
1379 break;
1380 }
1381
1382 /* Window/size parameters */
1383 case VIDIOCGWIN:
1384 {
1385 struct video_window *vw = arg;
1386
1387 vw->x = 0;
1388 vw->y = 0;
1389 vw->width = pdev->view.x;
1390 vw->height = pdev->view.y;
1391 vw->chromakey = 0;
1392 vw->flags = (pdev->vframes << PWC_FPS_SHIFT) |
1393 (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0);
1394 break;
1395 }
1396
1397 case VIDIOCSWIN:
1398 {
1399 struct video_window *vw = arg;
1400 int fps, snapshot, ret;
1401
1402 fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
1403 snapshot = vw->flags & PWC_FPS_SNAPSHOT;
1404 if (fps == 0)
1405 fps = pdev->vframes;
1406 if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot)
1407 return 0;
1408 ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot);
1409 if (ret)
1410 return ret;
1411 break;
1412 }
1413
1414 /* We don't have overlay support (yet) */
1415 case VIDIOCGFBUF:
1416 {
1417 struct video_buffer *vb = arg;
1418
1419 memset(vb,0,sizeof(*vb));
1420 break;
1421 }
1422
1423 /* mmap() functions */
1424 case VIDIOCGMBUF:
1425 {
1426 /* Tell the user program how much memory is needed for a mmap() */
1427 struct video_mbuf *vm = arg;
1428 int i;
1429
1430 memset(vm, 0, sizeof(*vm));
1431 vm->size = default_mbufs * pdev->len_per_image;
1432 vm->frames = default_mbufs; /* double buffering should be enough for most applications */
1433 for (i = 0; i < default_mbufs; i++)
1434 vm->offsets[i] = i * pdev->len_per_image;
1435 break;
1436 }
1437
1438 case VIDIOCMCAPTURE:
1439 {
1440 /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */
1441 struct video_mmap *vm = arg;
1442
1443 Trace(TRACE_READ, "VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format);
1444 if (vm->frame < 0 || vm->frame >= default_mbufs)
1445 return -EINVAL;
1446
1447 /* xawtv is nasty. It probes the available palettes
1448 by setting a very small image size and trying
1449 various palettes... The driver doesn't support
1450 such small images, so I'm working around it.
1451 */
1452 if (vm->format)
1453 {
1454 switch (vm->format)
1455 {
1456 case VIDEO_PALETTE_YUV420P:
1457 case VIDEO_PALETTE_RAW:
1458 break;
1459 default:
1460 return -EINVAL;
1461 break;
1462 }
1463 }
1464
1465 if ((vm->width != pdev->view.x || vm->height != pdev->view.y) &&
1466 (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) {
1467 int ret;
1468
1469 Trace(TRACE_OPEN, "VIDIOCMCAPTURE: changing size to please xawtv :-(.\n");
1470 ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
1471 if (ret)
1472 return ret;
1473 } /* ... size mismatch */
1474
1475 /* FIXME: should we lock here? */
1476 if (pdev->image_used[vm->frame])
1477 return -EBUSY; /* buffer wasn't available. Bummer */
1478 pdev->image_used[vm->frame] = 1;
1479
1480 /* Okay, we're done here. In the SYNC call we wait until a
1481 frame comes available, then expand image into the given
1482 buffer.
1483 In contrast to the CPiA cam the Philips cams deliver a
1484 constant stream, almost like a grabber card. Also,
1485 we have separate buffers for the rawdata and the image,
1486 meaning we can nearly always expand into the requested buffer.
1487 */
1488 Trace(TRACE_READ, "VIDIOCMCAPTURE done.\n");
1489 break;
1490 }
1491
1492 case VIDIOCSYNC:
1493 {
1494 /* The doc says: "Whenever a buffer is used it should
1495 call VIDIOCSYNC to free this frame up and continue."
1496
1497 The only odd thing about this whole procedure is
1498 that MCAPTURE flags the buffer as "in use", and
1499 SYNC immediately unmarks it, while it isn't
1500 after SYNC that you know that the buffer actually
1501 got filled! So you better not start a CAPTURE in
1502 the same frame immediately (use double buffering).
1503 This is not a problem for this cam, since it has
1504 extra intermediate buffers, but a hardware
1505 grabber card will then overwrite the buffer
1506 you're working on.
1507 */
1508 int *mbuf = arg;
1509 int ret;
1510
1511 Trace(TRACE_READ, "VIDIOCSYNC called (%d).\n", *mbuf);
1512
1513 /* bounds check */
1514 if (*mbuf < 0 || *mbuf >= default_mbufs)
1515 return -EINVAL;
1516 /* check if this buffer was requested anyway */
1517 if (pdev->image_used[*mbuf] == 0)
1518 return -EINVAL;
1519
1520 /* Add ourselves to the frame wait-queue.
1521
1522 FIXME: needs auditing for safety.
1523 QUESTION: In what respect? I think that using the
1524 frameq is safe now.
1525 */
1526 add_wait_queue(&pdev->frameq, &wait);
1527 while (pdev->full_frames == NULL) {
1528 if (pdev->error_status) {
1529 remove_wait_queue(&pdev->frameq, &wait);
1530 set_current_state(TASK_RUNNING);
1531 return -pdev->error_status;
1532 }
1533
1534 if (signal_pending(current)) {
1535 remove_wait_queue(&pdev->frameq, &wait);
1536 set_current_state(TASK_RUNNING);
1537 return -ERESTARTSYS;
1538 }
1539 schedule();
1540 set_current_state(TASK_INTERRUPTIBLE);
1541 }
1542 remove_wait_queue(&pdev->frameq, &wait);
1543 set_current_state(TASK_RUNNING);
1544
1545 /* The frame is ready. Expand in the image buffer
1546 requested by the user. I don't care if you
1547 mmap() 5 buffers and request data in this order:
1548 buffer 4 2 3 0 1 2 3 0 4 3 1 . . .
1549 Grabber hardware may not be so forgiving.
1550 */
1551 Trace(TRACE_READ, "VIDIOCSYNC: frame ready.\n");
1552 pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */
1553 /* Decompress, etc */
1554 ret = pwc_handle_frame(pdev);
1555 pdev->image_used[*mbuf] = 0;
1556 if (ret)
1557 return -EFAULT;
1558 break;
1559 }
1560
1561 case VIDIOCGAUDIO:
1562 {
1563 struct video_audio *v = arg;
1564
1565 strcpy(v->name, "Microphone");
1566 v->audio = -1; /* unknown audio minor */
1567 v->flags = 0;
1568 v->mode = VIDEO_SOUND_MONO;
1569 v->volume = 0;
1570 v->bass = 0;
1571 v->treble = 0;
1572 v->balance = 0x8000;
1573 v->step = 1;
1574 break;
1575 }
1576
1577 case VIDIOCSAUDIO:
1578 {
1579 /* Dummy: nothing can be set */
1580 break;
1581 }
1582
1583 case VIDIOCGUNIT:
1584 {
1585 struct video_unit *vu = arg;
1586
1587 vu->video = pdev->vdev->minor & 0x3F;
1588 vu->audio = -1; /* not known yet */
1589 vu->vbi = -1;
1590 vu->radio = -1;
1591 vu->teletext = -1;
1592 break;
1593 }
1594 default:
1595 return pwc_ioctl(pdev, cmd, arg);
1596 } /* ..switch */
1597 return 0;
1598}
1599
1600static int pwc_video_ioctl(struct inode *inode, struct file *file,
1601 unsigned int cmd, unsigned long arg)
1602{
1603 return video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl);
1604}
1605
1606
1607static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
1608{
1609 struct video_device *vdev = file->private_data;
1610 struct pwc_device *pdev;
1611 unsigned long start = vma->vm_start;
1612 unsigned long size = vma->vm_end-vma->vm_start;
1613 unsigned long page, pos;
1614
1615 Trace(TRACE_MEMORY, "mmap(0x%p, 0x%lx, %lu) called.\n", vdev, start, size);
1616 pdev = vdev->priv;
1617
1618 vma->vm_flags |= VM_IO;
1619
1620 pos = (unsigned long)pdev->image_data;
1621 while (size > 0) {
1622 page = vmalloc_to_pfn((void *)pos);
1623 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
1624 return -EAGAIN;
1625
1626 start += PAGE_SIZE;
1627 pos += PAGE_SIZE;
1628 if (size > PAGE_SIZE)
1629 size -= PAGE_SIZE;
1630 else
1631 size = 0;
1632 }
1633
1634 return 0;
1635}
1636
1637/***************************************************************************/
1638/* USB functions */
1639
1640/* This function gets called when a new device is plugged in or the usb core
1641 * is loaded.
1642 */
1643
1644static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id)
1645{
1646 struct usb_device *udev = interface_to_usbdev(intf);
1647 struct pwc_device *pdev = NULL;
1648 int vendor_id, product_id, type_id;
1649 int i, hint;
1650 int features = 0;
1651 int video_nr = -1; /* default: use next available device */
1652 char serial_number[30], *name;
1653
1654 /* Check if we can handle this device */
1655 Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n",
1656 le16_to_cpu(udev->descriptor.idVendor),
1657 le16_to_cpu(udev->descriptor.idProduct),
1658 intf->altsetting->desc.bInterfaceNumber);
1659
1660 /* the interfaces are probed one by one. We are only interested in the
1661 video interface (0) now.
1662 Interface 1 is the Audio Control, and interface 2 Audio itself.
1663 */
1664 if (intf->altsetting->desc.bInterfaceNumber > 0)
1665 return -ENODEV;
1666
1667 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
1668 product_id = le16_to_cpu(udev->descriptor.idProduct);
1669
1670 if (vendor_id == 0x0471) {
1671 switch (product_id) {
1672 case 0x0302:
1673 Info("Philips PCA645VC USB webcam detected.\n");
1674 name = "Philips 645 webcam";
1675 type_id = 645;
1676 break;
1677 case 0x0303:
1678 Info("Philips PCA646VC USB webcam detected.\n");
1679 name = "Philips 646 webcam";
1680 type_id = 646;
1681 break;
1682 case 0x0304:
1683 Info("Askey VC010 type 2 USB webcam detected.\n");
1684 name = "Askey VC010 webcam";
1685 type_id = 646;
1686 break;
1687 case 0x0307:
1688 Info("Philips PCVC675K (Vesta) USB webcam detected.\n");
1689 name = "Philips 675 webcam";
1690 type_id = 675;
1691 break;
1692 case 0x0308:
1693 Info("Philips PCVC680K (Vesta Pro) USB webcam detected.\n");
1694 name = "Philips 680 webcam";
1695 type_id = 680;
1696 break;
1697 case 0x030C:
1698 Info("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n");
1699 name = "Philips 690 webcam";
1700 type_id = 690;
1701 break;
1702 case 0x0310:
1703 Info("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n");
1704 name = "Philips 730 webcam";
1705 type_id = 730;
1706 break;
1707 case 0x0311:
1708 Info("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n");
1709 name = "Philips 740 webcam";
1710 type_id = 740;
1711 break;
1712 case 0x0312:
1713 Info("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n");
1714 name = "Philips 750 webcam";
1715 type_id = 750;
1716 break;
1717 case 0x0313:
1718 Info("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n");
1719 name = "Philips 720K/40 webcam";
1720 type_id = 720;
1721 break;
1722 default:
1723 return -ENODEV;
1724 break;
1725 }
1726 }
1727 else if (vendor_id == 0x069A) {
1728 switch(product_id) {
1729 case 0x0001:
1730 Info("Askey VC010 type 1 USB webcam detected.\n");
1731 name = "Askey VC010 webcam";
1732 type_id = 645;
1733 break;
1734 default:
1735 return -ENODEV;
1736 break;
1737 }
1738 }
1739 else if (vendor_id == 0x046d) {
1740 switch(product_id) {
1741 case 0x08b0:
1742 Info("Logitech QuickCam Pro 3000 USB webcam detected.\n");
1743 name = "Logitech QuickCam Pro 3000";
1744 type_id = 740; /* CCD sensor */
1745 break;
1746 case 0x08b1:
1747 Info("Logitech QuickCam Notebook Pro USB webcam detected.\n");
1748 name = "Logitech QuickCam Notebook Pro";
1749 type_id = 740; /* CCD sensor */
1750 break;
1751 case 0x08b2:
1752 Info("Logitech QuickCam 4000 Pro USB webcam detected.\n");
1753 name = "Logitech QuickCam Pro 4000";
1754 type_id = 740; /* CCD sensor */
1755 break;
1756 case 0x08b3:
1757 Info("Logitech QuickCam Zoom USB webcam detected.\n");
1758 name = "Logitech QuickCam Zoom";
1759 type_id = 740; /* CCD sensor */
1760 break;
1761 case 0x08B4:
1762 Info("Logitech QuickCam Zoom (new model) USB webcam detected.\n");
1763 name = "Logitech QuickCam Zoom";
1764 type_id = 740; /* CCD sensor */
1765 break;
1766 case 0x08b5:
1767 Info("Logitech QuickCam Orbit/Sphere USB webcam detected.\n");
1768 name = "Logitech QuickCam Orbit";
1769 type_id = 740; /* CCD sensor */
1770 features |= FEATURE_MOTOR_PANTILT;
1771 break;
1772 case 0x08b6:
1773 case 0x08b7:
1774 case 0x08b8:
1775 Info("Logitech QuickCam detected (reserved ID).\n");
1776 name = "Logitech QuickCam (res.)";
1777 type_id = 730; /* Assuming CMOS */
1778 break;
1779 default:
1780 return -ENODEV;
1781 break;
1782 }
1783 }
1784 else if (vendor_id == 0x055d) {
1785 /* I don't know the difference between the C10 and the C30;
1786 I suppose the difference is the sensor, but both cameras
1787 work equally well with a type_id of 675
1788 */
1789 switch(product_id) {
1790 case 0x9000:
1791 Info("Samsung MPC-C10 USB webcam detected.\n");
1792 name = "Samsung MPC-C10";
1793 type_id = 675;
1794 break;
1795 case 0x9001:
1796 Info("Samsung MPC-C30 USB webcam detected.\n");
1797 name = "Samsung MPC-C30";
1798 type_id = 675;
1799 break;
1800 default:
1801 return -ENODEV;
1802 break;
1803 }
1804 }
1805 else if (vendor_id == 0x041e) {
1806 switch(product_id) {
1807 case 0x400c:
1808 Info("Creative Labs Webcam 5 detected.\n");
1809 name = "Creative Labs Webcam 5";
1810 type_id = 730;
1811 break;
1812 case 0x4011:
1813 Info("Creative Labs Webcam Pro Ex detected.\n");
1814 name = "Creative Labs Webcam Pro Ex";
1815 type_id = 740;
1816 break;
1817 default:
1818 return -ENODEV;
1819 break;
1820 }
1821 }
1822 else if (vendor_id == 0x04cc) {
1823 switch(product_id) {
1824 case 0x8116:
1825 Info("Sotec Afina Eye USB webcam detected.\n");
1826 name = "Sotec Afina Eye";
1827 type_id = 730;
1828 break;
1829 default:
1830 return -ENODEV;
1831 break;
1832 }
1833 }
1834 else if (vendor_id == 0x06be) {
1835 switch(product_id) {
1836 case 0x8116:
1837 /* This is essentially the same cam as the Sotec Afina Eye */
1838 Info("AME Co. Afina Eye USB webcam detected.\n");
1839 name = "AME Co. Afina Eye";
1840 type_id = 750;
1841 break;
1842 default:
1843 return -ENODEV;
1844 break;
1845 }
1846
1847 }
1848 else if (vendor_id == 0x0d81) {
1849 switch(product_id) {
1850 case 0x1900:
1851 Info("Visionite VCS-UC300 USB webcam detected.\n");
1852 name = "Visionite VCS-UC300";
1853 type_id = 740; /* CCD sensor */
1854 break;
1855 case 0x1910:
1856 Info("Visionite VCS-UM100 USB webcam detected.\n");
1857 name = "Visionite VCS-UM100";
1858 type_id = 730; /* CMOS sensor */
1859 break;
1860 default:
1861 return -ENODEV;
1862 break;
1863 }
1864 }
1865 else
1866 return -ENODEV; /* Not any of the know types; but the list keeps growing. */
1867
1868 memset(serial_number, 0, 30);
1869 usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
1870 Trace(TRACE_PROBE, "Device serial number is %s\n", serial_number);
1871
1872 if (udev->descriptor.bNumConfigurations > 1)
1873 Info("Warning: more than 1 configuration available.\n");
1874
1875 /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */
1876 pdev = kmalloc(sizeof(struct pwc_device), GFP_KERNEL);
1877 if (pdev == NULL) {
1878 Err("Oops, could not allocate memory for pwc_device.\n");
1879 return -ENOMEM;
1880 }
1881 memset(pdev, 0, sizeof(struct pwc_device));
1882 pdev->type = type_id;
1883 pdev->vsize = default_size;
1884 pdev->vframes = default_fps;
1885 strcpy(pdev->serial, serial_number);
1886 pdev->features = features;
1887 if (vendor_id == 0x046D && product_id == 0x08B5)
1888 {
1889 /* Logitech QuickCam Orbit
1890 The ranges have been determined experimentally; they may differ from cam to cam.
1891 Also, the exact ranges left-right and up-down are different for my cam
1892 */
1893 pdev->angle_range.pan_min = -7000;
1894 pdev->angle_range.pan_max = 7000;
1895 pdev->angle_range.tilt_min = -3000;
1896 pdev->angle_range.tilt_max = 2500;
1897 }
1898
1899 init_MUTEX(&pdev->modlock);
1900 spin_lock_init(&pdev->ptrlock);
1901
1902 pdev->udev = udev;
1903 init_waitqueue_head(&pdev->frameq);
1904 pdev->vcompression = pwc_preferred_compression;
1905
1906 /* Allocate video_device structure */
1907 pdev->vdev = video_device_alloc();
1908 if (pdev->vdev == 0)
1909 {
1910 Err("Err, cannot allocate video_device struture. Failing probe.");
1911 kfree(pdev);
1912 return -ENOMEM;
1913 }
1914 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
1915 strcpy(pdev->vdev->name, name);
1916 pdev->vdev->owner = THIS_MODULE;
1917 video_set_drvdata(pdev->vdev, pdev);
1918
1919 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
1920 Trace(TRACE_PROBE, "Release: %04x\n", pdev->release);
1921
1922 /* Now search device_hint[] table for a match, so we can hint a node number. */
1923 for (hint = 0; hint < MAX_DEV_HINTS; hint++) {
1924 if (((device_hint[hint].type == -1) || (device_hint[hint].type == pdev->type)) &&
1925 (device_hint[hint].pdev == NULL)) {
1926 /* so far, so good... try serial number */
1927 if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) {
1928 /* match! */
1929 video_nr = device_hint[hint].device_node;
1930 Trace(TRACE_PROBE, "Found hint, will try to register as /dev/video%d\n", video_nr);
1931 break;
1932 }
1933 }
1934 }
1935
1936 pdev->vdev->release = video_device_release;
1937 i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr);
1938 if (i < 0) {
1939 Err("Failed to register as video device (%d).\n", i);
1940 video_device_release(pdev->vdev); /* Drip... drip... drip... */
1941 kfree(pdev); /* Oops, no memory leaks please */
1942 return -EIO;
1943 }
1944 else {
1945 Info("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F);
1946 }
1947
1948 /* occupy slot */
1949 if (hint < MAX_DEV_HINTS)
1950 device_hint[hint].pdev = pdev;
1951
1952 Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev);
1953 usb_set_intfdata (intf, pdev);
1954 return 0;
1955}
1956
1957/* The user janked out the cable... */
1958static void usb_pwc_disconnect(struct usb_interface *intf)
1959{
1960 struct pwc_device *pdev;
1961 int hint;
1962
1963 lock_kernel();
1964 pdev = usb_get_intfdata (intf);
1965 usb_set_intfdata (intf, NULL);
1966 if (pdev == NULL) {
1967 Err("pwc_disconnect() Called without private pointer.\n");
1968 goto disconnect_out;
1969 }
1970 if (pdev->udev == NULL) {
1971 Err("pwc_disconnect() already called for %p\n", pdev);
1972 goto disconnect_out;
1973 }
1974 if (pdev->udev != interface_to_usbdev(intf)) {
1975 Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n");
1976 goto disconnect_out;
1977 }
1978#ifdef PWC_MAGIC
1979 if (pdev->magic != PWC_MAGIC) {
1980 Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n");
1981 goto disconnect_out;
1982 }
1983#endif
1984
1985 /* We got unplugged; this is signalled by an EPIPE error code */
1986 if (pdev->vopen) {
1987 Info("Disconnected while webcam is in use!\n");
1988 pdev->error_status = EPIPE;
1989 }
1990
1991 /* Alert waiting processes */
1992 wake_up_interruptible(&pdev->frameq);
1993 /* Wait until device is closed */
1994 while (pdev->vopen)
1995 schedule();
1996 /* Device is now closed, so we can safely unregister it */
1997 Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n");
1998 video_unregister_device(pdev->vdev);
1999
2000 /* Free memory (don't set pdev to 0 just yet) */
2001 kfree(pdev);
2002
2003disconnect_out:
2004 /* search device_hint[] table if we occupy a slot, by any chance */
2005 for (hint = 0; hint < MAX_DEV_HINTS; hint++)
2006 if (device_hint[hint].pdev == pdev)
2007 device_hint[hint].pdev = NULL;
2008
2009 unlock_kernel();
2010}
2011
2012
2013/* *grunt* We have to do atoi ourselves :-( */
2014static int pwc_atoi(const char *s)
2015{
2016 int k = 0;
2017
2018 k = 0;
2019 while (*s != '\0' && *s >= '0' && *s <= '9') {
2020 k = 10 * k + (*s - '0');
2021 s++;
2022 }
2023 return k;
2024}
2025
2026
2027/*
2028 * Initialization code & module stuff
2029 */
2030
2031static char size[10];
2032static int fps = 0;
2033static int fbufs = 0;
2034static int mbufs = 0;
2035static int trace = -1;
2036static int compression = -1;
2037static int leds[2] = { -1, -1 };
2038static char *dev_hint[MAX_DEV_HINTS] = { };
2039
2040module_param_string(size, size, sizeof(size), 0);
2041MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga");
2042module_param(fps, int, 0000);
2043MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
2044module_param(fbufs, int, 0000);
2045MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve");
2046module_param(mbufs, int, 0000);
2047MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers");
2048module_param(trace, int, 0000);
2049MODULE_PARM_DESC(trace, "For debugging purposes");
2050module_param(power_save, bool, 0000);
2051MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off");
2052module_param(compression, int, 0000);
2053MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
2054module_param_array(leds, int, NULL, 0000);
2055MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
2056module_param_array(dev_hint, charp, NULL, 0000);
2057MODULE_PARM_DESC(dev_hint, "Device node hints");
2058
2059MODULE_DESCRIPTION("Philips & OEM USB webcam driver");
2060MODULE_AUTHOR("Luc Saillard <luc@saillard.org>");
2061MODULE_LICENSE("GPL");
2062
2063static int __init usb_pwc_init(void)
2064{
2065 int i, sz;
2066 char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" };
2067
2068 Info("Philips webcam module version " PWC_VERSION " loaded.\n");
2069 Info("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n");
2070 Info("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n");
2071 Info("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n");
2072
2073 if (fps) {
2074 if (fps < 4 || fps > 30) {
2075 Err("Framerate out of bounds (4-30).\n");
2076 return -EINVAL;
2077 }
2078 default_fps = fps;
2079 Info("Default framerate set to %d.\n", default_fps);
2080 }
2081
2082 if (size[0]) {
2083 /* string; try matching with array */
2084 for (sz = 0; sz < PSZ_MAX; sz++) {
2085 if (!strcmp(sizenames[sz], size)) { /* Found! */
2086 default_size = sz;
2087 break;
2088 }
2089 }
2090 if (sz == PSZ_MAX) {
2091 Err("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n");
2092 return -EINVAL;
2093 }
2094 Info("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y);
2095 }
2096 if (mbufs) {
2097 if (mbufs < 1 || mbufs > MAX_IMAGES) {
2098 Err("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES);
2099 return -EINVAL;
2100 }
2101 default_mbufs = mbufs;
2102 Info("Number of image buffers set to %d.\n", default_mbufs);
2103 }
2104 if (fbufs) {
2105 if (fbufs < 2 || fbufs > MAX_FRAMES) {
2106 Err("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES);
2107 return -EINVAL;
2108 }
2109 default_fbufs = fbufs;
2110 Info("Number of frame buffers set to %d.\n", default_fbufs);
2111 }
2112 if (trace >= 0) {
2113 Info("Trace options: 0x%04x\n", trace);
2114 pwc_trace = trace;
2115 }
2116 if (compression >= 0) {
2117 if (compression > 3) {
2118 Err("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n");
2119 return -EINVAL;
2120 }
2121 pwc_preferred_compression = compression;
2122 Info("Preferred compression set to %d.\n", pwc_preferred_compression);
2123 }
2124 if (power_save)
2125 Info("Enabling power save on open/close.\n");
2126 if (leds[0] >= 0)
2127 led_on = leds[0];
2128 if (leds[1] >= 0)
2129 led_off = leds[1];
2130
2131 /* Big device node whoopla. Basicly, it allows you to assign a
2132 device node (/dev/videoX) to a camera, based on its type
2133 & serial number. The format is [type[.serialnumber]:]node.
2134
2135 Any camera that isn't matched by these rules gets the next
2136 available free device node.
2137 */
2138 for (i = 0; i < MAX_DEV_HINTS; i++) {
2139 char *s, *colon, *dot;
2140
2141 /* This loop also initializes the array */
2142 device_hint[i].pdev = NULL;
2143 s = dev_hint[i];
2144 if (s != NULL && *s != '\0') {
2145 device_hint[i].type = -1; /* wildcard */
2146 strcpy(device_hint[i].serial_number, "*");
2147
2148 /* parse string: chop at ':' & '/' */
2149 colon = dot = s;
2150 while (*colon != '\0' && *colon != ':')
2151 colon++;
2152 while (*dot != '\0' && *dot != '.')
2153 dot++;
2154 /* Few sanity checks */
2155 if (*dot != '\0' && dot > colon) {
2156 Err("Malformed camera hint: the colon must be after the dot.\n");
2157 return -EINVAL;
2158 }
2159
2160 if (*colon == '\0') {
2161 /* No colon */
2162 if (*dot != '\0') {
2163 Err("Malformed camera hint: no colon + device node given.\n");
2164 return -EINVAL;
2165 }
2166 else {
2167 /* No type or serial number specified, just a number. */
2168 device_hint[i].device_node = pwc_atoi(s);
2169 }
2170 }
2171 else {
2172 /* There's a colon, so we have at least a type and a device node */
2173 device_hint[i].type = pwc_atoi(s);
2174 device_hint[i].device_node = pwc_atoi(colon + 1);
2175 if (*dot != '\0') {
2176 /* There's a serial number as well */
2177 int k;
2178
2179 dot++;
2180 k = 0;
2181 while (*dot != ':' && k < 29) {
2182 device_hint[i].serial_number[k++] = *dot;
2183 dot++;
2184 }
2185 device_hint[i].serial_number[k] = '\0';
2186 }
2187 }
2188#if PWC_DEBUG
2189 Debug("device_hint[%d]:\n", i);
2190 Debug(" type : %d\n", device_hint[i].type);
2191 Debug(" serial# : %s\n", device_hint[i].serial_number);
2192 Debug(" node : %d\n", device_hint[i].device_node);
2193#endif
2194 }
2195 else
2196 device_hint[i].type = 0; /* not filled */
2197 } /* ..for MAX_DEV_HINTS */
2198
2199 Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver);
2200 return usb_register(&pwc_driver);
2201}
2202
2203static void __exit usb_pwc_exit(void)
2204{
2205 Trace(TRACE_MODULE, "Deregistering driver.\n");
2206 usb_deregister(&pwc_driver);
2207 Info("Philips webcam module removed.\n");
2208}
2209
2210module_init(usb_pwc_init);
2211module_exit(usb_pwc_exit);
2212
diff --git a/drivers/usb/media/pwc/pwc-ioctl.h b/drivers/usb/media/pwc/pwc-ioctl.h
new file mode 100644
index 000000000000..65805eaa9a1c
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-ioctl.h
@@ -0,0 +1,292 @@
1#ifndef PWC_IOCTL_H
2#define PWC_IOCTL_H
3
4/* (C) 2001-2004 Nemosoft Unv.
5 (C) 2004 Luc Saillard (luc@saillard.org)
6
7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
8 driver and thus may have bugs that are not present in the original version.
9 Please send bug reports and support requests to <luc@saillard.org>.
10 The decompression routines have been implemented by reverse-engineering the
11 Nemosoft binary pwcx module. Caveat emptor.
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26*/
27
28/* This is pwc-ioctl.h belonging to PWC 8.12.1
29 It contains structures and defines to communicate from user space
30 directly to the driver.
31 */
32
33/*
34 Changes
35 2001/08/03 Alvarado Added ioctl constants to access methods for
36 changing white balance and red/blue gains
37 2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE
38 2003/12/13 Nemosft Unv. Some modifications to make interfacing to
39 PWCX easier
40 */
41
42/* These are private ioctl() commands, specific for the Philips webcams.
43 They contain functions not found in other webcams, and settings not
44 specified in the Video4Linux API.
45
46 The #define names are built up like follows:
47 VIDIOC VIDeo IOCtl prefix
48 PWC Philps WebCam
49 G optional: Get
50 S optional: Set
51 ... the function
52 */
53
54
55 /* Enumeration of image sizes */
56#define PSZ_SQCIF 0x00
57#define PSZ_QSIF 0x01
58#define PSZ_QCIF 0x02
59#define PSZ_SIF 0x03
60#define PSZ_CIF 0x04
61#define PSZ_VGA 0x05
62#define PSZ_MAX 6
63
64
65/* The frame rate is encoded in the video_window.flags parameter using
66 the upper 16 bits, since some flags are defined nowadays. The following
67 defines provide a mask and shift to filter out this value.
68
69 In 'Snapshot' mode the camera freezes its automatic exposure and colour
70 balance controls.
71 */
72#define PWC_FPS_SHIFT 16
73#define PWC_FPS_MASK 0x00FF0000
74#define PWC_FPS_FRMASK 0x003F0000
75#define PWC_FPS_SNAPSHOT 0x00400000
76
77
78/* structure for transfering x & y coordinates */
79struct pwc_coord
80{
81 int x, y; /* guess what */
82 int size; /* size, or offset */
83};
84
85
86/* Used with VIDIOCPWCPROBE */
87struct pwc_probe
88{
89 char name[32];
90 int type;
91};
92
93struct pwc_serial
94{
95 char serial[30]; /* String with serial number. Contains terminating 0 */
96};
97
98/* pwc_whitebalance.mode values */
99#define PWC_WB_INDOOR 0
100#define PWC_WB_OUTDOOR 1
101#define PWC_WB_FL 2
102#define PWC_WB_MANUAL 3
103#define PWC_WB_AUTO 4
104
105/* Used with VIDIOCPWC[SG]AWB (Auto White Balance).
106 Set mode to one of the PWC_WB_* values above.
107 *red and *blue are the respective gains of these colour components inside
108 the camera; range 0..65535
109 When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read;
110 otherwise undefined.
111 'read_red' and 'read_blue' are read-only.
112*/
113struct pwc_whitebalance
114{
115 int mode;
116 int manual_red, manual_blue; /* R/W */
117 int read_red, read_blue; /* R/O */
118};
119
120/*
121 'control_speed' and 'control_delay' are used in automatic whitebalance mode,
122 and tell the camera how fast it should react to changes in lighting, and
123 with how much delay. Valid values are 0..65535.
124*/
125struct pwc_wb_speed
126{
127 int control_speed;
128 int control_delay;
129
130};
131
132/* Used with VIDIOCPWC[SG]LED */
133struct pwc_leds
134{
135 int led_on; /* Led on-time; range = 0..25000 */
136 int led_off; /* Led off-time; range = 0..25000 */
137};
138
139/* Image size (used with GREALSIZE) */
140struct pwc_imagesize
141{
142 int width;
143 int height;
144};
145
146/* Defines and structures for Motorized Pan & Tilt */
147#define PWC_MPT_PAN 0x01
148#define PWC_MPT_TILT 0x02
149#define PWC_MPT_TIMEOUT 0x04 /* for status */
150
151/* Set angles; when absolute != 0, the angle is absolute and the
152 driver calculates the relative offset for you. This can only
153 be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns
154 absolute angles.
155 */
156struct pwc_mpt_angles
157{
158 int absolute; /* write-only */
159 int pan; /* degrees * 100 */
160 int tilt; /* degress * 100 */
161};
162
163/* Range of angles of the camera, both horizontally and vertically.
164 */
165struct pwc_mpt_range
166{
167 int pan_min, pan_max; /* degrees * 100 */
168 int tilt_min, tilt_max;
169};
170
171struct pwc_mpt_status
172{
173 int status;
174 int time_pan;
175 int time_tilt;
176};
177
178
179/* This is used for out-of-kernel decompression. With it, you can get
180 all the necessary information to initialize and use the decompressor
181 routines in standalone applications.
182 */
183struct pwc_video_command
184{
185 int type; /* camera type (645, 675, 730, etc.) */
186 int release; /* release number */
187
188 int size; /* one of PSZ_* */
189 int alternate;
190 int command_len; /* length of USB video command */
191 unsigned char command_buf[13]; /* Actual USB video command */
192 int bandlength; /* >0 = compressed */
193 int frame_size; /* Size of one (un)compressed frame */
194};
195
196/* Flags for PWCX subroutines. Not all modules honour all flags. */
197#define PWCX_FLAG_PLANAR 0x0001
198#define PWCX_FLAG_BAYER 0x0008
199
200
201/* IOCTL definitions */
202
203 /* Restore user settings */
204#define VIDIOCPWCRUSER _IO('v', 192)
205 /* Save user settings */
206#define VIDIOCPWCSUSER _IO('v', 193)
207 /* Restore factory settings */
208#define VIDIOCPWCFACTORY _IO('v', 194)
209
210 /* You can manipulate the compression factor. A compression preference of 0
211 means use uncompressed modes when available; 1 is low compression, 2 is
212 medium and 3 is high compression preferred. Of course, the higher the
213 compression, the lower the bandwidth used but more chance of artefacts
214 in the image. The driver automatically chooses a higher compression when
215 the preferred mode is not available.
216 */
217 /* Set preferred compression quality (0 = uncompressed, 3 = highest compression) */
218#define VIDIOCPWCSCQUAL _IOW('v', 195, int)
219 /* Get preferred compression quality */
220#define VIDIOCPWCGCQUAL _IOR('v', 195, int)
221
222
223/* Retrieve serial number of camera */
224#define VIDIOCPWCGSERIAL _IOR('v', 198, struct pwc_serial)
225
226 /* This is a probe function; since so many devices are supported, it
227 becomes difficult to include all the names in programs that want to
228 check for the enhanced Philips stuff. So in stead, try this PROBE;
229 it returns a structure with the original name, and the corresponding
230 Philips type.
231 To use, fill the structure with zeroes, call PROBE and if that succeeds,
232 compare the name with that returned from VIDIOCGCAP; they should be the
233 same. If so, you can be assured it is a Philips (OEM) cam and the type
234 is valid.
235 */
236#define VIDIOCPWCPROBE _IOR('v', 199, struct pwc_probe)
237
238 /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */
239#define VIDIOCPWCSAGC _IOW('v', 200, int)
240 /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */
241#define VIDIOCPWCGAGC _IOR('v', 200, int)
242 /* Set shutter speed; int < 0 = auto; >= 0 = fixed, range 0..65535 */
243#define VIDIOCPWCSSHUTTER _IOW('v', 201, int)
244
245 /* Color compensation (Auto White Balance) */
246#define VIDIOCPWCSAWB _IOW('v', 202, struct pwc_whitebalance)
247#define VIDIOCPWCGAWB _IOR('v', 202, struct pwc_whitebalance)
248
249 /* Auto WB speed */
250#define VIDIOCPWCSAWBSPEED _IOW('v', 203, struct pwc_wb_speed)
251#define VIDIOCPWCGAWBSPEED _IOR('v', 203, struct pwc_wb_speed)
252
253 /* LEDs on/off/blink; int range 0..65535 */
254#define VIDIOCPWCSLED _IOW('v', 205, struct pwc_leds)
255#define VIDIOCPWCGLED _IOR('v', 205, struct pwc_leds)
256
257 /* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */
258#define VIDIOCPWCSCONTOUR _IOW('v', 206, int)
259#define VIDIOCPWCGCONTOUR _IOR('v', 206, int)
260
261 /* Backlight compensation; 0 = off, otherwise on */
262#define VIDIOCPWCSBACKLIGHT _IOW('v', 207, int)
263#define VIDIOCPWCGBACKLIGHT _IOR('v', 207, int)
264
265 /* Flickerless mode; = 0 off, otherwise on */
266#define VIDIOCPWCSFLICKER _IOW('v', 208, int)
267#define VIDIOCPWCGFLICKER _IOR('v', 208, int)
268
269 /* Dynamic noise reduction; 0 off, 3 = high noise reduction */
270#define VIDIOCPWCSDYNNOISE _IOW('v', 209, int)
271#define VIDIOCPWCGDYNNOISE _IOR('v', 209, int)
272
273 /* Real image size as used by the camera; tells you whether or not there's a gray border around the image */
274#define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize)
275
276 /* Motorized pan & tilt functions */
277#define VIDIOCPWCMPTRESET _IOW('v', 211, int)
278#define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range)
279#define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles)
280#define VIDIOCPWCMPTGANGLE _IOR('v', 212, struct pwc_mpt_angles)
281#define VIDIOCPWCMPTSTATUS _IOR('v', 213, struct pwc_mpt_status)
282
283 /* Get the USB set-video command; needed for initializing libpwcx */
284#define VIDIOCPWCGVIDCMD _IOR('v', 215, struct pwc_video_command)
285struct pwc_table_init_buffer {
286 int len;
287 char *buffer;
288
289};
290#define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer)
291
292#endif
diff --git a/drivers/usb/media/pwc/pwc-kiara.c b/drivers/usb/media/pwc/pwc-kiara.c
new file mode 100644
index 000000000000..5485800efd83
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-kiara.c
@@ -0,0 +1,891 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
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
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
26/* This tables contains entries for the 730/740/750 (Kiara) camera, with
27 4 different qualities (no compression, low, medium, high).
28 It lists the bandwidth requirements for said mode by its alternate interface
29 number. An alternate of 0 means that the mode is unavailable.
30
31 There are 6 * 4 * 4 entries:
32 6 different resolutions subqcif, qsif, qcif, sif, cif, vga
33 6 framerates: 5, 10, 15, 20, 25, 30
34 4 compression modi: none, low, medium, high
35
36 When an uncompressed mode is not available, the next available compressed mode
37 will be chosen (unless the decompressor is absent). Sometimes there are only
38 1 or 2 compressed modes available; in that case entries are duplicated.
39*/
40
41
42#include "pwc-kiara.h"
43#include "pwc-uncompress.h"
44
45const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
46{
47 /* SQCIF */
48 {
49 /* 5 fps */
50 {
51 {0, },
52 {0, },
53 {0, },
54 {0, },
55 },
56 /* 10 fps */
57 {
58 {0, },
59 {0, },
60 {0, },
61 {0, },
62 },
63 /* 15 fps */
64 {
65 {0, },
66 {0, },
67 {0, },
68 {0, },
69 },
70 /* 20 fps */
71 {
72 {0, },
73 {0, },
74 {0, },
75 {0, },
76 },
77 /* 25 fps */
78 {
79 {0, },
80 {0, },
81 {0, },
82 {0, },
83 },
84 /* 30 fps */
85 {
86 {0, },
87 {0, },
88 {0, },
89 {0, },
90 },
91 },
92 /* QSIF */
93 {
94 /* 5 fps */
95 {
96 {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
97 {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
98 {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
99 {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
100 },
101 /* 10 fps */
102 {
103 {2, 291, 0, {0x1C, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0x01, 0x80}},
104 {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
105 {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
106 {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
107 },
108 /* 15 fps */
109 {
110 {3, 437, 0, {0x1B, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x01, 0x80}},
111 {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
112 {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
113 {1, 192, 420, {0x13, 0xF4, 0x30, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
114 },
115 /* 20 fps */
116 {
117 {4, 589, 0, {0x1A, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4D, 0x02, 0x80}},
118 {3, 448, 730, {0x12, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xC0, 0x01, 0x80}},
119 {2, 292, 476, {0x12, 0xF4, 0x30, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0x01, 0x80}},
120 {1, 192, 312, {0x12, 0xF4, 0x50, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
121 },
122 /* 25 fps */
123 {
124 {5, 703, 0, {0x19, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x02, 0x80}},
125 {3, 447, 610, {0x11, 0xF4, 0x30, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x28, 0xBF, 0x01, 0x80}},
126 {2, 292, 398, {0x11, 0xF4, 0x50, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x28, 0x24, 0x01, 0x80}},
127 {1, 193, 262, {0x11, 0xF4, 0x50, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x28, 0xC1, 0x00, 0x80}},
128 },
129 /* 30 fps */
130 {
131 {8, 874, 0, {0x18, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x6A, 0x03, 0x80}},
132 {5, 704, 730, {0x10, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x28, 0xC0, 0x02, 0x80}},
133 {3, 448, 492, {0x10, 0xF4, 0x30, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x28, 0xC0, 0x01, 0x80}},
134 {2, 292, 320, {0x10, 0xF4, 0x50, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x28, 0x24, 0x01, 0x80}},
135 },
136 },
137 /* QCIF */
138 {
139 /* 5 fps */
140 {
141 {0, },
142 {0, },
143 {0, },
144 {0, },
145 },
146 /* 10 fps */
147 {
148 {0, },
149 {0, },
150 {0, },
151 {0, },
152 },
153 /* 15 fps */
154 {
155 {0, },
156 {0, },
157 {0, },
158 {0, },
159 },
160 /* 20 fps */
161 {
162 {0, },
163 {0, },
164 {0, },
165 {0, },
166 },
167 /* 25 fps */
168 {
169 {0, },
170 {0, },
171 {0, },
172 {0, },
173 },
174 /* 30 fps */
175 {
176 {0, },
177 {0, },
178 {0, },
179 {0, },
180 },
181 },
182 /* SIF */
183 {
184 /* 5 fps */
185 {
186 {4, 582, 0, {0x0D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x02, 0x80}},
187 {3, 387, 1276, {0x05, 0xF4, 0x30, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x01, 0x80}},
188 {2, 291, 960, {0x05, 0xF4, 0x30, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0x01, 0x80}},
189 {1, 191, 630, {0x05, 0xF4, 0x50, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x18, 0xBF, 0x00, 0x80}},
190 },
191 /* 10 fps */
192 {
193 {0, },
194 {6, 775, 1278, {0x04, 0xF4, 0x30, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x03, 0x80}},
195 {3, 447, 736, {0x04, 0xF4, 0x30, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x28, 0xBF, 0x01, 0x80}},
196 {2, 292, 480, {0x04, 0xF4, 0x70, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x28, 0x24, 0x01, 0x80}},
197 },
198 /* 15 fps */
199 {
200 {0, },
201 {9, 955, 1050, {0x03, 0xF4, 0x30, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x03, 0x80}},
202 {4, 592, 650, {0x03, 0xF4, 0x30, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x50, 0x02, 0x80}},
203 {3, 448, 492, {0x03, 0xF4, 0x50, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x38, 0xC0, 0x01, 0x80}},
204 },
205 /* 20 fps */
206 {
207 {0, },
208 {9, 958, 782, {0x02, 0xF4, 0x30, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x03, 0x80}},
209 {5, 703, 574, {0x02, 0xF4, 0x50, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x02, 0x80}},
210 {3, 446, 364, {0x02, 0xF4, 0x90, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x38, 0xBE, 0x01, 0x80}},
211 },
212 /* 25 fps */
213 {
214 {0, },
215 {9, 958, 654, {0x01, 0xF4, 0x30, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x03, 0x80}},
216 {6, 776, 530, {0x01, 0xF4, 0x50, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x03, 0x80}},
217 {4, 592, 404, {0x01, 0xF4, 0x70, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x48, 0x50, 0x02, 0x80}},
218 },
219 /* 30 fps */
220 {
221 {0, },
222 {9, 957, 526, {0x00, 0xF4, 0x50, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x03, 0x80}},
223 {6, 775, 426, {0x00, 0xF4, 0x70, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x03, 0x80}},
224 {4, 590, 324, {0x00, 0x7A, 0x88, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x50, 0x4E, 0x02, 0x80}},
225 },
226 },
227 /* CIF */
228 {
229 /* 5 fps */
230 {
231 {0, },
232 {0, },
233 {0, },
234 {0, },
235 },
236 /* 10 fps */
237 {
238 {0, },
239 {0, },
240 {0, },
241 {0, },
242 },
243 /* 15 fps */
244 {
245 {0, },
246 {0, },
247 {0, },
248 {0, },
249 },
250 /* 20 fps */
251 {
252 {0, },
253 {0, },
254 {0, },
255 {0, },
256 },
257 /* 25 fps */
258 {
259 {0, },
260 {0, },
261 {0, },
262 {0, },
263 },
264 /* 30 fps */
265 {
266 {0, },
267 {0, },
268 {0, },
269 {0, },
270 },
271 },
272 /* VGA */
273 {
274 /* 5 fps */
275 {
276 {0, },
277 {6, 773, 1272, {0x25, 0xF4, 0x30, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}},
278 {4, 592, 976, {0x25, 0xF4, 0x50, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x02, 0x80}},
279 {3, 448, 738, {0x25, 0xF4, 0x90, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x01, 0x80}},
280 },
281 /* 10 fps */
282 {
283 {0, },
284 {9, 956, 788, {0x24, 0xF4, 0x70, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x03, 0x80}},
285 {6, 776, 640, {0x24, 0xF4, 0xB0, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x03, 0x80}},
286 {4, 592, 488, {0x24, 0x7A, 0xE8, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x02, 0x80}},
287 },
288 /* 15 fps */
289 {
290 {0, },
291 {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
292 {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
293 {8, 895, 492, {0x23, 0x7A, 0xE8, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x03, 0x80}},
294 },
295 /* 20 fps */
296 {
297 {0, },
298 {0, },
299 {0, },
300 {0, },
301 },
302 /* 25 fps */
303 {
304 {0, },
305 {0, },
306 {0, },
307 {0, },
308 },
309 /* 30 fps */
310 {
311 {0, },
312 {0, },
313 {0, },
314 {0, },
315 },
316 },
317};
318
319
320/*
321 * Rom table for kiara chips
322 *
323 * 32 roms tables (one for each resolution ?)
324 * 2 tables per roms (one for each passes) (Y, and U&V)
325 * 128 bytes per passes
326 */
327
328const unsigned int KiaraRomTable [8][2][16][8] =
329{
330 { /* version 0 */
331 { /* version 0, passes 0 */
332 {0x00000000,0x00000000,0x00000000,0x00000000,
333 0x00000000,0x00000000,0x00000001,0x00000001},
334 {0x00000000,0x00000000,0x00000009,0x00000009,
335 0x00000009,0x00000009,0x00000009,0x00000009},
336 {0x00000000,0x00000000,0x00000009,0x00000049,
337 0x00000049,0x00000049,0x00000049,0x00000049},
338 {0x00000000,0x00000000,0x00000049,0x00000049,
339 0x00000049,0x00000249,0x0000024a,0x00000049},
340 {0x00000000,0x00000000,0x00000049,0x00000049,
341 0x00000249,0x00000249,0x0000024a,0x0000024a},
342 {0x00000000,0x00000000,0x00000049,0x00000249,
343 0x00000249,0x0000124a,0x0000024a,0x0000024a},
344 {0x00000000,0x00000000,0x00000049,0x00000249,
345 0x0000124a,0x00009252,0x00001252,0x00001252},
346 {0x00000000,0x00000000,0x00000249,0x00000249,
347 0x00009252,0x00009292,0x00009292,0x00009292},
348 {0x00000000,0x00000000,0x00000249,0x00001249,
349 0x00009292,0x00009292,0x00009493,0x000124db},
350 {0x00000000,0x00000000,0x00000249,0x0000924a,
351 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
352 {0x00000000,0x00000000,0x00001249,0x00009252,
353 0x0000a493,0x000124db,0x000124db,0x000126dc},
354 {0x00000000,0x00000000,0x00001249,0x00009493,
355 0x000124db,0x000126dc,0x000136e4,0x000126dc},
356 {0x00000000,0x00000000,0x00009292,0x0000a49b,
357 0x000124db,0x000136e4,0x000136e4,0x000136e4},
358 {0x00000000,0x00000000,0x00009292,0x0000a49b,
359 0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
360 {0x00000000,0x00000000,0x00009492,0x000124db,
361 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
362 {0x00000000,0x00000000,0x00000000,0x00000000,
363 0x00000000,0x00000000,0x00000000,0x00000000}
364 },
365 { /* version 0, passes 1 */
366 {0x00000000,0x00000000,0x00000000,0x00000000,
367 0x00000000,0x00000000,0x00000000,0x00000000},
368 {0x00000000,0x00000000,0x00000000,0x00000000,
369 0x00000000,0x00000000,0x00000000,0x00000000},
370 {0x00000000,0x00000000,0x00000001,0x00000009,
371 0x00000009,0x00000009,0x00000009,0x00000001},
372 {0x00000000,0x00000000,0x00000009,0x00000009,
373 0x00000049,0x00000049,0x00000049,0x00000049},
374 {0x00000000,0x00000000,0x00000049,0x00000049,
375 0x00000049,0x00000049,0x0000024a,0x0000024a},
376 {0x00000000,0x00000000,0x00000049,0x00000049,
377 0x00000249,0x00000249,0x0000024a,0x0000024a},
378 {0x00000000,0x00000000,0x00000049,0x00000249,
379 0x00000249,0x00000249,0x0000024a,0x00001252},
380 {0x00000000,0x00000000,0x00000049,0x00001249,
381 0x0000124a,0x0000124a,0x00001252,0x00009292},
382 {0x00000000,0x00000000,0x00000249,0x00001249,
383 0x00009252,0x00009252,0x00009292,0x00009493},
384 {0x00000000,0x00000000,0x00000249,0x0000924a,
385 0x00009292,0x00009292,0x00009292,0x00009493},
386 {0x00000000,0x00000000,0x00000249,0x00009292,
387 0x00009492,0x00009493,0x0000a49b,0x00009493},
388 {0x00000000,0x00000000,0x00001249,0x00009292,
389 0x0000a493,0x000124db,0x000126dc,0x000126dc},
390 {0x00000000,0x00000000,0x0000924a,0x00009493,
391 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
392 {0x00000000,0x00000000,0x00009252,0x00009493,
393 0x000126dc,0x000126dc,0x000136e4,0x000136e4},
394 {0x00000000,0x00000000,0x00009292,0x0000a49b,
395 0x000136e4,0x000136e4,0x0001b725,0x0001b724},
396 {0x00000000,0x00000000,0x00000000,0x00000000,
397 0x00000000,0x00000000,0x00000000,0x00000000}
398 }
399 },
400 { /* version 1 */
401 { /* version 1, passes 0 */
402 {0x00000000,0x00000000,0x00000000,0x00000000,
403 0x00000000,0x00000000,0x00000000,0x00000001},
404 {0x00000000,0x00000000,0x00000009,0x00000009,
405 0x00000009,0x00000009,0x00000009,0x00000009},
406 {0x00000000,0x00000000,0x00000049,0x00000049,
407 0x00000049,0x00000049,0x00000049,0x00000049},
408 {0x00000000,0x00000000,0x00000049,0x00000049,
409 0x00000049,0x00000249,0x0000024a,0x0000024a},
410 {0x00000000,0x00000000,0x00000049,0x00000249,
411 0x00000249,0x00000249,0x0000024a,0x00001252},
412 {0x00000000,0x00000000,0x00000249,0x00000249,
413 0x00000249,0x0000124a,0x00001252,0x00001252},
414 {0x00000000,0x00000000,0x00000249,0x00000249,
415 0x0000124a,0x0000124a,0x00009292,0x00009292},
416 {0x00000000,0x00000000,0x00000249,0x00001249,
417 0x0000124a,0x00009252,0x00009292,0x00009292},
418 {0x00000000,0x00000000,0x00000249,0x00001249,
419 0x00009252,0x00009292,0x00009292,0x00009292},
420 {0x00000000,0x00000000,0x00000249,0x00001249,
421 0x00009252,0x00009292,0x00009493,0x00009493},
422 {0x00000000,0x00000000,0x00000249,0x0000924a,
423 0x00009252,0x00009493,0x00009493,0x00009493},
424 {0x00000000,0x00000000,0x00000249,0x0000924a,
425 0x00009292,0x00009493,0x00009493,0x00009493},
426 {0x00000000,0x00000000,0x00000249,0x00009252,
427 0x00009492,0x00009493,0x0000a49b,0x0000a49b},
428 {0x00000000,0x00000000,0x00001249,0x00009292,
429 0x00009492,0x000124db,0x000124db,0x000124db},
430 {0x00000000,0x00000000,0x0000924a,0x00009493,
431 0x0000a493,0x000126dc,0x000126dc,0x000126dc},
432 {0x00000000,0x00000000,0x00000000,0x00000000,
433 0x00000000,0x00000000,0x00000000,0x00000000}
434 },
435 { /* version 1, passes 1 */
436 {0x00000000,0x00000000,0x00000000,0x00000000,
437 0x00000000,0x00000000,0x00000000,0x00000000},
438 {0x00000000,0x00000000,0x00000049,0x00000009,
439 0x00000049,0x00000009,0x00000001,0x00000000},
440 {0x00000000,0x00000000,0x00000049,0x00000049,
441 0x00000049,0x00000049,0x00000049,0x00000000},
442 {0x00000000,0x00000000,0x00000249,0x00000049,
443 0x00000249,0x00000049,0x0000024a,0x00000001},
444 {0x00000000,0x00000000,0x00000249,0x00000249,
445 0x00000249,0x00000249,0x0000024a,0x00000001},
446 {0x00000000,0x00000000,0x00000249,0x00000249,
447 0x00000249,0x00000249,0x0000024a,0x00000001},
448 {0x00000000,0x00000000,0x00000249,0x00000249,
449 0x00000249,0x00000249,0x0000024a,0x00000009},
450 {0x00000000,0x00000000,0x00000249,0x00000249,
451 0x0000124a,0x0000124a,0x0000024a,0x00000009},
452 {0x00000000,0x00000000,0x00000249,0x00000249,
453 0x0000124a,0x0000124a,0x0000024a,0x00000009},
454 {0x00000000,0x00000000,0x00001249,0x00001249,
455 0x0000124a,0x00009252,0x00001252,0x00000049},
456 {0x00000000,0x00000000,0x00001249,0x00001249,
457 0x0000124a,0x00009292,0x00001252,0x00000049},
458 {0x00000000,0x00000000,0x00001249,0x00001249,
459 0x0000124a,0x00009292,0x00001252,0x00000049},
460 {0x00000000,0x00000000,0x00001249,0x00001249,
461 0x00009252,0x00009292,0x00001252,0x0000024a},
462 {0x00000000,0x00000000,0x00001249,0x00001249,
463 0x00009292,0x00009292,0x00001252,0x0000024a},
464 {0x00000000,0x00000000,0x0000924a,0x0000924a,
465 0x00009492,0x00009493,0x00009292,0x00001252},
466 {0x00000000,0x00000000,0x00000000,0x00000000,
467 0x00000000,0x00000000,0x00000000,0x00000000}
468 }
469 },
470 { /* version 2 */
471 { /* version 2, passes 0 */
472 {0x00000000,0x00000000,0x00000049,0x00000049,
473 0x00000049,0x00000049,0x0000024a,0x0000024a},
474 {0x00000000,0x00000000,0x00000249,0x00000249,
475 0x00000249,0x0000124a,0x00001252,0x00009292},
476 {0x00000000,0x00000000,0x00000249,0x00000249,
477 0x0000124a,0x00009252,0x00009292,0x00009292},
478 {0x00000000,0x00000000,0x00000249,0x00001249,
479 0x0000124a,0x00009292,0x00009493,0x00009493},
480 {0x00000000,0x00000000,0x00000249,0x00001249,
481 0x00009252,0x00009493,0x00009493,0x0000a49b},
482 {0x00000000,0x00000000,0x00000249,0x0000924a,
483 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
484 {0x00000000,0x00000000,0x00001249,0x0000924a,
485 0x00009292,0x00009493,0x0000a49b,0x000124db},
486 {0x00000000,0x00000000,0x00001249,0x00009252,
487 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
488 {0x00000000,0x00000000,0x00001249,0x00009292,
489 0x00009492,0x000124db,0x000124db,0x000126dc},
490 {0x00000000,0x00000000,0x00001249,0x00009292,
491 0x0000a493,0x000124db,0x000126dc,0x000126dc},
492 {0x00000000,0x00000000,0x00001249,0x00009493,
493 0x0000a493,0x000124db,0x000126dc,0x000136e4},
494 {0x00000000,0x00000000,0x00001249,0x00009493,
495 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
496 {0x00000000,0x00000000,0x0000924a,0x00009493,
497 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
498 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
499 0x000124db,0x000136e4,0x000136e4,0x0001b724},
500 {0x00000000,0x00000000,0x00009252,0x000124db,
501 0x000126dc,0x0001b724,0x0001b725,0x0001b925},
502 {0x00000000,0x00000000,0x00000000,0x00000000,
503 0x00000000,0x00000000,0x00000000,0x00000000}
504 },
505 { /* version 2, passes 1 */
506 {0x00000000,0x00000000,0x00000049,0x00000049,
507 0x00000049,0x00000049,0x00000049,0x00000049},
508 {0x00000000,0x00000000,0x00000249,0x00000249,
509 0x00000249,0x00000249,0x0000024a,0x00000049},
510 {0x00000000,0x00000000,0x00001249,0x00000249,
511 0x0000124a,0x0000124a,0x00001252,0x00000049},
512 {0x00000000,0x00000000,0x00001249,0x00001249,
513 0x0000124a,0x0000124a,0x00009292,0x0000024a},
514 {0x00000000,0x00000000,0x00001249,0x00001249,
515 0x00009252,0x00009292,0x00009292,0x0000024a},
516 {0x00000000,0x00000000,0x00001249,0x00001249,
517 0x00009252,0x00009292,0x0000a49b,0x0000024a},
518 {0x00000000,0x00000000,0x00001249,0x00001249,
519 0x00009292,0x00009493,0x0000a49b,0x00001252},
520 {0x00000000,0x00000000,0x00001249,0x00001249,
521 0x00009292,0x00009493,0x0000a49b,0x00001252},
522 {0x00000000,0x00000000,0x00001249,0x0000924a,
523 0x00009492,0x0000a49b,0x0000a49b,0x00001252},
524 {0x00000000,0x00000000,0x00001249,0x00009252,
525 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
526 {0x00000000,0x00000000,0x00001249,0x00009292,
527 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
528 {0x00000000,0x00000000,0x00001249,0x00009493,
529 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
530 {0x00000000,0x00000000,0x00001249,0x00009493,
531 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
532 {0x00000000,0x00000000,0x0000924a,0x00009493,
533 0x0000a493,0x000124db,0x0000a49b,0x00009493},
534 {0x00000000,0x00000000,0x00009252,0x0000a49b,
535 0x0001249b,0x000126dc,0x000124db,0x0000a49b},
536 {0x00000000,0x00000000,0x00000000,0x00000000,
537 0x00000000,0x00000000,0x00000000,0x00000000}
538 }
539 },
540 { /* version 3 */
541 { /* version 3, passes 0 */
542 {0x00000000,0x00000000,0x00000249,0x00000249,
543 0x0000124a,0x0000124a,0x00009292,0x00009292},
544 {0x00000000,0x00000000,0x00001249,0x00001249,
545 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
546 {0x00000000,0x00000000,0x00001249,0x0000924a,
547 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
548 {0x00000000,0x00000000,0x00001249,0x00009292,
549 0x00009492,0x000124db,0x000126dc,0x000126dc},
550 {0x00000000,0x00000000,0x00001249,0x00009493,
551 0x0000a493,0x000124db,0x000126dc,0x000126dc},
552 {0x00000000,0x00000000,0x00001249,0x00009493,
553 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
554 {0x00000000,0x00000000,0x00001249,0x00009493,
555 0x0000a493,0x000126dc,0x000136e4,0x0001b724},
556 {0x00000000,0x00000000,0x00001249,0x00009493,
557 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
558 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
559 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
560 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
561 0x0001249b,0x000136e4,0x0001b725,0x0001b724},
562 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
563 0x000124db,0x000136e4,0x0001b725,0x0001b925},
564 {0x00000000,0x00000000,0x00009292,0x0000a49b,
565 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
566 {0x00000000,0x00000000,0x00009292,0x0000a49b,
567 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
568 {0x00000000,0x00000000,0x00009492,0x000124db,
569 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
570 {0x00000000,0x00000000,0x0000a492,0x000126db,
571 0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
572 {0x00000000,0x00000000,0x00000000,0x00000000,
573 0x00000000,0x00000000,0x00000000,0x00000000}
574 },
575 { /* version 3, passes 1 */
576 {0x00000000,0x00000000,0x00001249,0x00000249,
577 0x0000124a,0x0000124a,0x00001252,0x00001252},
578 {0x00000000,0x00000000,0x00001249,0x00001249,
579 0x00009252,0x00009292,0x00009292,0x00001252},
580 {0x00000000,0x00000000,0x00001249,0x0000924a,
581 0x00009492,0x00009493,0x0000a49b,0x00001252},
582 {0x00000000,0x00000000,0x00001249,0x00009252,
583 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
584 {0x00000000,0x00000000,0x00001249,0x00009292,
585 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
586 {0x00000000,0x00000000,0x00001249,0x00009493,
587 0x0000a493,0x0000a49b,0x000126dc,0x00009292},
588 {0x00000000,0x00000000,0x0000924a,0x00009493,
589 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
590 {0x00000000,0x00000000,0x0000924a,0x00009493,
591 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
592 {0x00000000,0x00000000,0x0000924a,0x00009493,
593 0x0000a493,0x000124db,0x000126dc,0x00009493},
594 {0x00000000,0x00000000,0x0000924a,0x00009493,
595 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
596 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
597 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
598 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
599 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
600 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
601 0x000124db,0x000136e4,0x000126dc,0x000124db},
602 {0x00000000,0x00000000,0x00009492,0x0000a49b,
603 0x000136e4,0x000136e4,0x000126dc,0x000124db},
604 {0x00000000,0x00000000,0x0000a492,0x000124db,
605 0x0001b724,0x0001b724,0x000136e4,0x000126dc},
606 {0x00000000,0x00000000,0x00000000,0x00000000,
607 0x00000000,0x00000000,0x00000000,0x00000000}
608 }
609 },
610 { /* version 4 */
611 { /* version 4, passes 0 */
612 {0x00000000,0x00000000,0x00000049,0x00000049,
613 0x00000049,0x00000049,0x00000049,0x00000049},
614 {0x00000000,0x00000000,0x00000249,0x00000049,
615 0x00000249,0x00000249,0x0000024a,0x00000049},
616 {0x00000000,0x00000000,0x00000249,0x00000249,
617 0x0000124a,0x00009252,0x00001252,0x0000024a},
618 {0x00000000,0x00000000,0x00001249,0x00001249,
619 0x00009252,0x00009292,0x00009493,0x00001252},
620 {0x00000000,0x00000000,0x00001249,0x0000924a,
621 0x00009292,0x00009493,0x00009493,0x00001252},
622 {0x00000000,0x00000000,0x00001249,0x00009292,
623 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
624 {0x00000000,0x00000000,0x00001249,0x00009493,
625 0x0000a493,0x000124db,0x000124db,0x00009493},
626 {0x00000000,0x00000000,0x0000924a,0x00009493,
627 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
628 {0x00000000,0x00000000,0x0000924a,0x00009493,
629 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
630 {0x00000000,0x00000000,0x0000924a,0x00009493,
631 0x0001249b,0x000126dc,0x000126dc,0x000124db},
632 {0x00000000,0x00000000,0x00009252,0x00009493,
633 0x000124db,0x000136e4,0x000136e4,0x000126dc},
634 {0x00000000,0x00000000,0x00009252,0x0000a49b,
635 0x000124db,0x000136e4,0x000136e4,0x000126dc},
636 {0x00000000,0x00000000,0x00009292,0x0000a49b,
637 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
638 {0x00000000,0x00000000,0x00009492,0x0000a49b,
639 0x000126dc,0x0001b724,0x0001b725,0x0001b724},
640 {0x00000000,0x00000000,0x0000a492,0x000124db,
641 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
642 {0x00000000,0x00000000,0x00000000,0x00000000,
643 0x00000000,0x00000000,0x00000000,0x00000000}
644 },
645 { /* version 4, passes 1 */
646 {0x00000000,0x00000000,0x00000249,0x00000049,
647 0x00000009,0x00000009,0x00000009,0x00000009},
648 {0x00000000,0x00000000,0x00000249,0x00000249,
649 0x00000049,0x00000049,0x00000009,0x00000009},
650 {0x00000000,0x00000000,0x00001249,0x00001249,
651 0x0000124a,0x00000249,0x00000049,0x00000049},
652 {0x00000000,0x00000000,0x00001249,0x00001249,
653 0x0000124a,0x0000124a,0x00000049,0x00000049},
654 {0x00000000,0x00000000,0x00001249,0x00001249,
655 0x00009252,0x0000124a,0x0000024a,0x0000024a},
656 {0x00000000,0x00000000,0x00001249,0x0000924a,
657 0x00009252,0x0000124a,0x0000024a,0x0000024a},
658 {0x00000000,0x00000000,0x00001249,0x00009292,
659 0x00009492,0x00009252,0x00001252,0x00001252},
660 {0x00000000,0x00000000,0x00001249,0x00009493,
661 0x0000a493,0x00009292,0x00009292,0x00001252},
662 {0x00000000,0x00000000,0x0000924a,0x00009493,
663 0x0000a493,0x00009292,0x00009292,0x00009292},
664 {0x00000000,0x00000000,0x0000924a,0x00009493,
665 0x0000a493,0x00009493,0x00009493,0x00009292},
666 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
667 0x0000a493,0x0000a49b,0x00009493,0x00009493},
668 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
669 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
670 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
671 0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
672 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
673 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
674 {0x00000000,0x00000000,0x00009252,0x000124db,
675 0x0001b724,0x000136e4,0x000126dc,0x000124db},
676 {0x00000000,0x00000000,0x00000000,0x00000000,
677 0x00000000,0x00000000,0x00000000,0x00000000}
678 }
679 },
680 { /* version 5 */
681 { /* version 5, passes 0 */
682 {0x00000000,0x00000000,0x00000249,0x00000249,
683 0x00000249,0x00000249,0x00001252,0x00001252},
684 {0x00000000,0x00000000,0x00001249,0x00001249,
685 0x00009252,0x00009292,0x00009292,0x00001252},
686 {0x00000000,0x00000000,0x00001249,0x0000924a,
687 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
688 {0x00000000,0x00000000,0x00001249,0x00009493,
689 0x0000a493,0x0000a49b,0x000124db,0x00009493},
690 {0x00000000,0x00000000,0x00001249,0x00009493,
691 0x0000a493,0x000124db,0x000126dc,0x00009493},
692 {0x00000000,0x00000000,0x0000924a,0x00009493,
693 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
694 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
695 0x0001249b,0x000126dc,0x000136e4,0x000124db},
696 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
697 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
698 {0x00000000,0x00000000,0x00009292,0x0000a49b,
699 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
700 {0x00000000,0x00000000,0x00009292,0x0000a49b,
701 0x000126dc,0x0001b724,0x0001b725,0x000136e4},
702 {0x00000000,0x00000000,0x00009292,0x0000a49b,
703 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
704 {0x00000000,0x00000000,0x00009492,0x0000a49b,
705 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
706 {0x00000000,0x00000000,0x00009492,0x000124db,
707 0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
708 {0x00000000,0x00000000,0x00009492,0x000124db,
709 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
710 {0x00000000,0x00000000,0x0000a492,0x000126db,
711 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
712 {0x00000000,0x00000000,0x00000000,0x00000000,
713 0x00000000,0x00000000,0x00000000,0x00000000}
714 },
715 { /* version 5, passes 1 */
716 {0x00000000,0x00000000,0x00001249,0x00000249,
717 0x00000249,0x00000249,0x0000024a,0x0000024a},
718 {0x00000000,0x00000000,0x00001249,0x00001249,
719 0x0000124a,0x0000124a,0x0000024a,0x0000024a},
720 {0x00000000,0x00000000,0x00001249,0x0000924a,
721 0x00009252,0x00009252,0x0000024a,0x0000024a},
722 {0x00000000,0x00000000,0x00001249,0x00009292,
723 0x00009492,0x0000a49b,0x00001252,0x00001252},
724 {0x00000000,0x00000000,0x0000924a,0x00009493,
725 0x0000a493,0x0000a49b,0x00001252,0x00001252},
726 {0x00000000,0x00000000,0x0000924a,0x00009493,
727 0x0000a493,0x0000a49b,0x00009292,0x00001252},
728 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
729 0x0000a493,0x0000a49b,0x00009292,0x00009292},
730 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
731 0x0000a493,0x0000a49b,0x00009493,0x00009292},
732 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
733 0x0001249b,0x000124db,0x00009493,0x00009292},
734 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
735 0x0001249b,0x000124db,0x00009493,0x00009493},
736 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
737 0x000124db,0x000124db,0x0000a49b,0x00009493},
738 {0x00000000,0x00000000,0x0000924a,0x000124db,
739 0x000126dc,0x000126dc,0x0000a49b,0x00009493},
740 {0x00000000,0x00000000,0x0000924a,0x000124db,
741 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
742 {0x00000000,0x00000000,0x00009292,0x000124db,
743 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
744 {0x00000000,0x00000000,0x00009492,0x000126db,
745 0x0001b724,0x000136e4,0x000126dc,0x000124db},
746 {0x00000000,0x00000000,0x00000000,0x00000000,
747 0x00000000,0x00000000,0x00000000,0x00000000}
748 }
749 },
750 { /* version 6 */
751 { /* version 6, passes 0 */
752 {0x00000000,0x00000000,0x00001249,0x00001249,
753 0x00009252,0x00009292,0x00009493,0x00009493},
754 {0x00000000,0x00000000,0x00001249,0x00009292,
755 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
756 {0x00000000,0x00000000,0x00001249,0x00009493,
757 0x0000a493,0x000124db,0x000124db,0x0000a49b},
758 {0x00000000,0x00000000,0x0000924a,0x00009493,
759 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
760 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
761 0x0001249b,0x000126dc,0x000136e4,0x000124db},
762 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
763 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
764 {0x00000000,0x00000000,0x00009292,0x0000a49b,
765 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
766 {0x00000000,0x00000000,0x00009292,0x0000a49b,
767 0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
768 {0x00000000,0x00000000,0x00009492,0x0000a49b,
769 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
770 {0x00000000,0x00000000,0x00009492,0x000124db,
771 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
772 {0x00000000,0x00000000,0x00009492,0x000124db,
773 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
774 {0x00000000,0x00000000,0x00009492,0x000124db,
775 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
776 {0x00000000,0x00000000,0x0000a492,0x000124db,
777 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
778 {0x00000000,0x00000000,0x0000a492,0x000124db,
779 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
780 {0x00000000,0x00000000,0x00012492,0x000126db,
781 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
782 {0x00000000,0x00000000,0x00000000,0x00000000,
783 0x00000000,0x00000000,0x00000000,0x00000000}
784 },
785 { /* version 6, passes 1 */
786 {0x00000000,0x00000000,0x00001249,0x00001249,
787 0x0000124a,0x0000124a,0x00001252,0x00001252},
788 {0x00000000,0x00000000,0x00001249,0x00009292,
789 0x00009492,0x00009252,0x00001252,0x00001252},
790 {0x00000000,0x00000000,0x0000924a,0x00009493,
791 0x0000a493,0x00009292,0x00001252,0x00001252},
792 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
793 0x0000a493,0x0000a49b,0x00009292,0x00009292},
794 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
795 0x0000a493,0x0000a49b,0x00009292,0x00009292},
796 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
797 0x0001249b,0x0000a49b,0x00009493,0x00009292},
798 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
799 0x000124db,0x000124db,0x00009493,0x00009493},
800 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
801 0x000124db,0x000124db,0x0000a49b,0x00009493},
802 {0x00000000,0x00000000,0x0000924a,0x000124db,
803 0x000126dc,0x000124db,0x0000a49b,0x00009493},
804 {0x00000000,0x00000000,0x0000924a,0x000124db,
805 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
806 {0x00000000,0x00000000,0x0000924a,0x000124db,
807 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
808 {0x00000000,0x00000000,0x00009492,0x000126db,
809 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
810 {0x00000000,0x00000000,0x00009492,0x000126db,
811 0x0001b724,0x000136e4,0x000126dc,0x000124db},
812 {0x00000000,0x00000000,0x00009492,0x000126db,
813 0x0001b724,0x000136e4,0x000126dc,0x000124db},
814 {0x00000000,0x00000000,0x0000a492,0x000136db,
815 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
816 {0x00000000,0x00000000,0x00000000,0x00000000,
817 0x00000000,0x00000000,0x00000000,0x00000000}
818 }
819 },
820 { /* version 7 */
821 { /* version 7, passes 0 */
822 {0x00000000,0x00000000,0x00001249,0x00001249,
823 0x00009252,0x00009292,0x00009493,0x00009493},
824 {0x00000000,0x00000000,0x00001249,0x00009493,
825 0x0000a493,0x000124db,0x000126dc,0x00009493},
826 {0x00000000,0x00000000,0x00001249,0x0000a49b,
827 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
828 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
829 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
830 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
831 0x000126dc,0x000136e4,0x0001b725,0x000124db},
832 {0x00000000,0x00000000,0x00009292,0x0000a49b,
833 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
834 {0x00000000,0x00000000,0x00009292,0x000124db,
835 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
836 {0x00000000,0x00000000,0x00009492,0x000124db,
837 0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
838 {0x00000000,0x00000000,0x00009492,0x000124db,
839 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
840 {0x00000000,0x00000000,0x0000a492,0x000124db,
841 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
842 {0x00000000,0x00000000,0x0000a492,0x000124db,
843 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
844 {0x00000000,0x00000000,0x0000a492,0x000126db,
845 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
846 {0x00000000,0x00000000,0x0000a492,0x000126db,
847 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
848 {0x00000000,0x00000000,0x0000a492,0x000126db,
849 0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
850 {0x00000000,0x00000000,0x00012492,0x000136db,
851 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
852 {0x00000000,0x00000000,0x00000000,0x00000000,
853 0x00000000,0x00000000,0x00000000,0x00000000}
854 },
855 { /* version 7, passes 1 */
856 {0x00000000,0x00000000,0x00001249,0x00001249,
857 0x0000124a,0x0000124a,0x00001252,0x00001252},
858 {0x00000000,0x00000000,0x0000924a,0x00009493,
859 0x00009492,0x00009292,0x00001252,0x00001252},
860 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
861 0x0000a493,0x0000a49b,0x00001252,0x00001252},
862 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
863 0x0000a493,0x0000a49b,0x00009292,0x00009292},
864 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
865 0x0000a493,0x0000a49b,0x00009292,0x00009292},
866 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
867 0x000126dc,0x0000a49b,0x00009493,0x00009292},
868 {0x00000000,0x00000000,0x0000924a,0x000124db,
869 0x000126dc,0x000124db,0x00009493,0x00009493},
870 {0x00000000,0x00000000,0x0000924a,0x000124db,
871 0x000136e4,0x000124db,0x0000a49b,0x00009493},
872 {0x00000000,0x00000000,0x0000924a,0x000136db,
873 0x0001b724,0x000124db,0x0000a49b,0x00009493},
874 {0x00000000,0x00000000,0x0000924a,0x000136db,
875 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
876 {0x00000000,0x00000000,0x00009292,0x000136db,
877 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
878 {0x00000000,0x00000000,0x00009492,0x000136db,
879 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
880 {0x00000000,0x00000000,0x0000a492,0x000136db,
881 0x0001b724,0x000136e4,0x000126dc,0x000124db},
882 {0x00000000,0x00000000,0x0000a492,0x000136db,
883 0x0001b724,0x000136e4,0x000126dc,0x000124db},
884 {0x00000000,0x00000000,0x00012492,0x0001b6db,
885 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
886 {0x00000000,0x00000000,0x00000000,0x00000000,
887 0x00000000,0x00000000,0x00000000,0x00000000}
888 }
889 }
890};
891
diff --git a/drivers/usb/media/pwc/pwc-kiara.h b/drivers/usb/media/pwc/pwc-kiara.h
new file mode 100644
index 000000000000..12929abbb1f0
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-kiara.h
@@ -0,0 +1,45 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
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
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25/* Entries for the Kiara (730/740/750) camera */
26
27#ifndef PWC_KIARA_H
28#define PWC_KIARA_H
29
30#include "pwc-ioctl.h"
31
32struct Kiara_table_entry
33{
34 char alternate; /* USB alternate interface */
35 unsigned short packetsize; /* Normal packet size */
36 unsigned short bandlength; /* Bandlength when decompressing */
37 unsigned char mode[12]; /* precomputed mode settings for cam */
38};
39
40const extern struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4];
41const extern unsigned int KiaraRomTable[8][2][16][8];
42
43#endif
44
45
diff --git a/drivers/usb/media/pwc/pwc-misc.c b/drivers/usb/media/pwc/pwc-misc.c
new file mode 100644
index 000000000000..b7a4bd3524c7
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-misc.c
@@ -0,0 +1,140 @@
1/* Linux driver for Philips webcam
2 Various miscellaneous functions and tables.
3 (C) 1999-2003 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org)
5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version.
8 Please send bug reports and support requests to <luc@saillard.org>.
9 The decompression routines have been implemented by reverse-engineering the
10 Nemosoft binary pwcx module. Caveat emptor.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25*/
26
27#include <linux/slab.h>
28
29#include "pwc.h"
30
31struct pwc_coord pwc_image_sizes[PSZ_MAX] =
32{
33 { 128, 96, 0 },
34 { 160, 120, 0 },
35 { 176, 144, 0 },
36 { 320, 240, 0 },
37 { 352, 288, 0 },
38 { 640, 480, 0 },
39};
40
41/* x,y -> PSZ_ */
42int pwc_decode_size(struct pwc_device *pdev, int width, int height)
43{
44 int i, find;
45
46 /* Make sure we don't go beyond our max size.
47 NB: we have different limits for RAW and normal modes. In case
48 you don't have the decompressor loaded or use RAW mode,
49 the maximum viewable size is smaller.
50 */
51 if (pdev->vpalette == VIDEO_PALETTE_RAW)
52 {
53 if (width > pdev->abs_max.x || height > pdev->abs_max.y)
54 {
55 Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n");
56 return -1;
57 }
58 }
59 else
60 {
61 if (width > pdev->view_max.x || height > pdev->view_max.y)
62 {
63 Debug("VIDEO_PALETTE_ not RAW: going beyond view_max.\n");
64 return -1;
65 }
66 }
67
68 /* Find the largest size supported by the camera that fits into the
69 requested size.
70 */
71 find = -1;
72 for (i = 0; i < PSZ_MAX; i++) {
73 if (pdev->image_mask & (1 << i)) {
74 if (pwc_image_sizes[i].x <= width && pwc_image_sizes[i].y <= height)
75 find = i;
76 }
77 }
78 return find;
79}
80
81/* initialize variables depending on type and decompressor*/
82void pwc_construct(struct pwc_device *pdev)
83{
84 switch(pdev->type) {
85 case 645:
86 case 646:
87 pdev->view_min.x = 128;
88 pdev->view_min.y = 96;
89 pdev->view_max.x = 352;
90 pdev->view_max.y = 288;
91 pdev->abs_max.x = 352;
92 pdev->abs_max.y = 288;
93 pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
94 pdev->vcinterface = 2;
95 pdev->vendpoint = 4;
96 pdev->frame_header_size = 0;
97 pdev->frame_trailer_size = 0;
98 break;
99 case 675:
100 case 680:
101 case 690:
102 pdev->view_min.x = 128;
103 pdev->view_min.y = 96;
104 /* Anthill bug #38: PWC always reports max size, even without PWCX */
105 pdev->view_max.x = 640;
106 pdev->view_max.y = 480;
107 pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
108 pdev->abs_max.x = 640;
109 pdev->abs_max.y = 480;
110 pdev->vcinterface = 3;
111 pdev->vendpoint = 4;
112 pdev->frame_header_size = 0;
113 pdev->frame_trailer_size = 0;
114 break;
115 case 720:
116 case 730:
117 case 740:
118 case 750:
119 pdev->view_min.x = 160;
120 pdev->view_min.y = 120;
121 pdev->view_max.x = 640;
122 pdev->view_max.y = 480;
123 pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
124 pdev->abs_max.x = 640;
125 pdev->abs_max.y = 480;
126 pdev->vcinterface = 3;
127 pdev->vendpoint = 5;
128 pdev->frame_header_size = TOUCAM_HEADER_SIZE;
129 pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;
130 break;
131 }
132 Debug("type = %d\n",pdev->type);
133 pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */
134 pdev->view_min.size = pdev->view_min.x * pdev->view_min.y;
135 pdev->view_max.size = pdev->view_max.x * pdev->view_max.y;
136 /* length of image, in YUV format; always allocate enough memory. */
137 pdev->len_per_image = (pdev->abs_max.x * pdev->abs_max.y * 3) / 2;
138}
139
140
diff --git a/drivers/usb/media/pwc/pwc-nala.h b/drivers/usb/media/pwc/pwc-nala.h
new file mode 100644
index 000000000000..e6c5cb69d03b
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-nala.h
@@ -0,0 +1,66 @@
1 /* SQCIF */
2 {
3 {0, 0, {0x04, 0x01, 0x03}},
4 {8, 0, {0x05, 0x01, 0x03}},
5 {7, 0, {0x08, 0x01, 0x03}},
6 {7, 0, {0x0A, 0x01, 0x03}},
7 {6, 0, {0x0C, 0x01, 0x03}},
8 {5, 0, {0x0F, 0x01, 0x03}},
9 {4, 0, {0x14, 0x01, 0x03}},
10 {3, 0, {0x18, 0x01, 0x03}},
11 },
12 /* QSIF */
13 {
14 {0},
15 {0},
16 {0},
17 {0},
18 {0},
19 {0},
20 {0},
21 {0},
22 },
23 /* QCIF */
24 {
25 {0, 0, {0x04, 0x01, 0x02}},
26 {8, 0, {0x05, 0x01, 0x02}},
27 {7, 0, {0x08, 0x01, 0x02}},
28 {6, 0, {0x0A, 0x01, 0x02}},
29 {5, 0, {0x0C, 0x01, 0x02}},
30 {4, 0, {0x0F, 0x01, 0x02}},
31 {1, 0, {0x14, 0x01, 0x02}},
32 {1, 0, {0x18, 0x01, 0x02}},
33 },
34 /* SIF */
35 {
36 {0},
37 {0},
38 {0},
39 {0},
40 {0},
41 {0},
42 {0},
43 {0},
44 },
45 /* CIF */
46 {
47 {4, 0, {0x04, 0x01, 0x01}},
48 {7, 1, {0x05, 0x03, 0x01}},
49 {6, 1, {0x08, 0x03, 0x01}},
50 {4, 1, {0x0A, 0x03, 0x01}},
51 {3, 1, {0x0C, 0x03, 0x01}},
52 {2, 1, {0x0F, 0x03, 0x01}},
53 {0},
54 {0},
55 },
56 /* VGA */
57 {
58 {0},
59 {0},
60 {0},
61 {0},
62 {0},
63 {0},
64 {0},
65 {0},
66 },
diff --git a/drivers/usb/media/pwc/pwc-timon.c b/drivers/usb/media/pwc/pwc-timon.c
new file mode 100644
index 000000000000..f950a4e5ed96
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-timon.c
@@ -0,0 +1,1446 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
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
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
26/* This tables contains entries for the 675/680/690 (Timon) camera, with
27 4 different qualities (no compression, low, medium, high).
28 It lists the bandwidth requirements for said mode by its alternate interface
29 number. An alternate of 0 means that the mode is unavailable.
30
31 There are 6 * 4 * 4 entries:
32 6 different resolutions subqcif, qsif, qcif, sif, cif, vga
33 6 framerates: 5, 10, 15, 20, 25, 30
34 4 compression modi: none, low, medium, high
35
36 When an uncompressed mode is not available, the next available compressed mode
37 will be chosen (unless the decompressor is absent). Sometimes there are only
38 1 or 2 compressed modes available; in that case entries are duplicated.
39*/
40
41#include "pwc-timon.h"
42
43const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] =
44{
45 /* SQCIF */
46 {
47 /* 5 fps */
48 {
49 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
50 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
51 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
52 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
53 },
54 /* 10 fps */
55 {
56 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
57 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
58 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
59 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
60 },
61 /* 15 fps */
62 {
63 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
64 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
65 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
66 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
67 },
68 /* 20 fps */
69 {
70 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
71 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
72 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
73 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
74 },
75 /* 25 fps */
76 {
77 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
78 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
79 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
80 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
81 },
82 /* 30 fps */
83 {
84 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
85 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
86 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
87 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
88 },
89 },
90 /* QSIF */
91 {
92 /* 5 fps */
93 {
94 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
95 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
96 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
97 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
98 },
99 /* 10 fps */
100 {
101 {2, 291, 0, {0x2C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0xA1, 0xC0, 0x02}},
102 {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
103 {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
104 {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
105 },
106 /* 15 fps */
107 {
108 {3, 437, 0, {0x2B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x6D, 0xC0, 0x02}},
109 {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
110 {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
111 {1, 191, 420, {0x2B, 0xF4, 0x0D, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
112 },
113 /* 20 fps */
114 {
115 {4, 588, 0, {0x2A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4C, 0x52, 0xC0, 0x02}},
116 {3, 447, 730, {0x2A, 0xF4, 0x05, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
117 {2, 292, 476, {0x2A, 0xF4, 0x0D, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
118 {1, 192, 312, {0x2A, 0xF4, 0x1D, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
119 },
120 /* 25 fps */
121 {
122 {5, 703, 0, {0x29, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x42, 0xC0, 0x02}},
123 {3, 447, 610, {0x29, 0xF4, 0x05, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
124 {2, 292, 398, {0x29, 0xF4, 0x0D, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
125 {1, 192, 262, {0x29, 0xF4, 0x25, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
126 },
127 /* 30 fps */
128 {
129 {8, 873, 0, {0x28, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x69, 0x37, 0xC0, 0x02}},
130 {5, 704, 774, {0x28, 0xF4, 0x05, 0x18, 0x21, 0x17, 0x59, 0x0F, 0x18, 0xC0, 0x42, 0xC0, 0x02}},
131 {3, 448, 492, {0x28, 0xF4, 0x05, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x18, 0xC0, 0x69, 0xC0, 0x02}},
132 {2, 291, 320, {0x28, 0xF4, 0x1D, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
133 },
134 },
135 /* QCIF */
136 {
137 /* 5 fps */
138 {
139 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
140 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
141 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
142 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
143 },
144 /* 10 fps */
145 {
146 {3, 385, 0, {0x0C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x81, 0x79, 0xC0, 0x02}},
147 {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
148 {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
149 {1, 194, 532, {0x0C, 0xF4, 0x05, 0x10, 0x9A, 0x0F, 0xBE, 0x1B, 0x08, 0xC2, 0xF0, 0xC0, 0x02}},
150 },
151 /* 15 fps */
152 {
153 {4, 577, 0, {0x0B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x41, 0x52, 0xC0, 0x02}},
154 {3, 447, 818, {0x0B, 0xF4, 0x05, 0x19, 0x89, 0x18, 0xAD, 0x0F, 0x10, 0xBF, 0x69, 0xC0, 0x02}},
155 {2, 292, 534, {0x0B, 0xF4, 0x05, 0x10, 0xA3, 0x0F, 0xC7, 0x19, 0x10, 0x24, 0xA1, 0xC0, 0x02}},
156 {1, 195, 356, {0x0B, 0xF4, 0x15, 0x0B, 0x11, 0x0A, 0x35, 0x1E, 0x10, 0xC3, 0xF0, 0xC0, 0x02}},
157 },
158 /* 20 fps */
159 {
160 {6, 776, 0, {0x0A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x08, 0x3F, 0xC0, 0x02}},
161 {4, 591, 804, {0x0A, 0xF4, 0x05, 0x19, 0x1E, 0x18, 0x42, 0x0F, 0x18, 0x4F, 0x4E, 0xC0, 0x02}},
162 {3, 447, 608, {0x0A, 0xF4, 0x05, 0x12, 0xFD, 0x12, 0x21, 0x15, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
163 {2, 291, 396, {0x0A, 0xF4, 0x15, 0x0C, 0x5E, 0x0B, 0x82, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
164 },
165 /* 25 fps */
166 {
167 {9, 928, 0, {0x09, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA0, 0x33, 0xC0, 0x02}},
168 {5, 703, 800, {0x09, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x10, 0x18, 0xBF, 0x42, 0xC0, 0x02}},
169 {3, 447, 508, {0x09, 0xF4, 0x0D, 0x0F, 0xD2, 0x0E, 0xF6, 0x1B, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
170 {2, 292, 332, {0x09, 0xF4, 0x1D, 0x0A, 0x5A, 0x09, 0x7E, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
171 },
172 /* 30 fps */
173 {
174 {0, },
175 {9, 956, 876, {0x08, 0xF4, 0x05, 0x1B, 0x58, 0x1A, 0x7C, 0x0E, 0x20, 0xBC, 0x33, 0x10, 0x02}},
176 {4, 592, 542, {0x08, 0xF4, 0x05, 0x10, 0xE4, 0x10, 0x08, 0x17, 0x20, 0x50, 0x4E, 0x10, 0x02}},
177 {2, 291, 266, {0x08, 0xF4, 0x25, 0x08, 0x48, 0x07, 0x6C, 0x1E, 0x20, 0x23, 0xA1, 0x10, 0x02}},
178 },
179 },
180 /* SIF */
181 {
182 /* 5 fps */
183 {
184 {4, 582, 0, {0x35, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x52, 0x60, 0x02}},
185 {3, 387, 1276, {0x35, 0xF4, 0x05, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x79, 0x60, 0x02}},
186 {2, 291, 960, {0x35, 0xF4, 0x0D, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0xA1, 0x60, 0x02}},
187 {1, 191, 630, {0x35, 0xF4, 0x1D, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x08, 0xBF, 0xF4, 0x60, 0x02}},
188 },
189 /* 10 fps */
190 {
191 {0, },
192 {6, 775, 1278, {0x34, 0xF4, 0x05, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x3F, 0x10, 0x02}},
193 {3, 447, 736, {0x34, 0xF4, 0x15, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x18, 0xBF, 0x69, 0x10, 0x02}},
194 {2, 291, 480, {0x34, 0xF4, 0x2D, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x18, 0x23, 0xA1, 0x10, 0x02}},
195 },
196 /* 15 fps */
197 {
198 {0, },
199 {9, 955, 1050, {0x33, 0xF4, 0x05, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x33, 0x10, 0x02}},
200 {4, 591, 650, {0x33, 0xF4, 0x15, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x4F, 0x4E, 0x10, 0x02}},
201 {3, 448, 492, {0x33, 0xF4, 0x25, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x28, 0xC0, 0x69, 0x10, 0x02}},
202 },
203 /* 20 fps */
204 {
205 {0, },
206 {9, 958, 782, {0x32, 0xF4, 0x0D, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x33, 0xD0, 0x02}},
207 {5, 703, 574, {0x32, 0xF4, 0x1D, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x42, 0xD0, 0x02}},
208 {3, 446, 364, {0x32, 0xF4, 0x3D, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x30, 0xBE, 0x69, 0xD0, 0x02}},
209 },
210 /* 25 fps */
211 {
212 {0, },
213 {9, 958, 654, {0x31, 0xF4, 0x15, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x33, 0x90, 0x02}},
214 {6, 776, 530, {0x31, 0xF4, 0x25, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x3F, 0x90, 0x02}},
215 {4, 592, 404, {0x31, 0xF4, 0x35, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x38, 0x50, 0x4E, 0x90, 0x02}},
216 },
217 /* 30 fps */
218 {
219 {0, },
220 {9, 957, 526, {0x30, 0xF4, 0x25, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x33, 0x60, 0x02}},
221 {6, 775, 426, {0x30, 0xF4, 0x35, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x3F, 0x60, 0x02}},
222 {4, 590, 324, {0x30, 0x7A, 0x4B, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x40, 0x4E, 0x52, 0x60, 0x02}},
223 },
224 },
225 /* CIF */
226 {
227 /* 5 fps */
228 {
229 {6, 771, 0, {0x15, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x3F, 0x80, 0x02}},
230 {4, 465, 1278, {0x15, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x03, 0x18, 0xD1, 0x65, 0x80, 0x02}},
231 {2, 291, 800, {0x15, 0xF4, 0x15, 0x18, 0xF4, 0x17, 0x3C, 0x05, 0x18, 0x23, 0xA1, 0x80, 0x02}},
232 {1, 193, 528, {0x15, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x18, 0xC1, 0xF4, 0x80, 0x02}},
233 },
234 /* 10 fps */
235 {
236 {0, },
237 {9, 932, 1278, {0x14, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x04, 0x30, 0xA4, 0x33, 0x10, 0x02}},
238 {4, 591, 812, {0x14, 0xF4, 0x15, 0x19, 0x56, 0x17, 0x9E, 0x06, 0x28, 0x4F, 0x4E, 0x10, 0x02}},
239 {2, 291, 400, {0x14, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x28, 0x23, 0xA1, 0x10, 0x02}},
240 },
241 /* 15 fps */
242 {
243 {0, },
244 {9, 956, 876, {0x13, 0xF4, 0x0D, 0x1B, 0x58, 0x19, 0xA0, 0x05, 0x38, 0xBC, 0x33, 0x60, 0x02}},
245 {5, 703, 644, {0x13, 0xF4, 0x1D, 0x14, 0x1C, 0x12, 0x64, 0x08, 0x38, 0xBF, 0x42, 0x60, 0x02}},
246 {3, 448, 410, {0x13, 0xF4, 0x3D, 0x0C, 0xC4, 0x0B, 0x0C, 0x0E, 0x38, 0xC0, 0x69, 0x60, 0x02}},
247 },
248 /* 20 fps */
249 {
250 {0, },
251 {9, 956, 650, {0x12, 0xF4, 0x1D, 0x14, 0x4A, 0x12, 0x92, 0x09, 0x48, 0xBC, 0x33, 0x10, 0x03}},
252 {6, 776, 528, {0x12, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x40, 0x08, 0x3F, 0x10, 0x03}},
253 {4, 591, 402, {0x12, 0xF4, 0x3D, 0x0C, 0x8F, 0x0A, 0xD7, 0x0E, 0x40, 0x4F, 0x4E, 0x10, 0x03}},
254 },
255 /* 25 fps */
256 {
257 {0, },
258 {9, 956, 544, {0x11, 0xF4, 0x25, 0x10, 0xF4, 0x0F, 0x3C, 0x0A, 0x48, 0xBC, 0x33, 0xC0, 0x02}},
259 {7, 840, 478, {0x11, 0xF4, 0x2D, 0x0E, 0xEB, 0x0D, 0x33, 0x0B, 0x48, 0x48, 0x3B, 0xC0, 0x02}},
260 {5, 703, 400, {0x11, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x48, 0xBF, 0x42, 0xC0, 0x02}},
261 },
262 /* 30 fps */
263 {
264 {0, },
265 {9, 956, 438, {0x10, 0xF4, 0x35, 0x0D, 0xAC, 0x0B, 0xF4, 0x0D, 0x50, 0xBC, 0x33, 0x10, 0x02}},
266 {7, 838, 384, {0x10, 0xF4, 0x45, 0x0B, 0xFD, 0x0A, 0x45, 0x0F, 0x50, 0x46, 0x3B, 0x10, 0x02}},
267 {6, 773, 354, {0x10, 0x7A, 0x4B, 0x0B, 0x0C, 0x09, 0x80, 0x10, 0x50, 0x05, 0x3F, 0x10, 0x02}},
268 },
269 },
270 /* VGA */
271 {
272 /* 5 fps */
273 {
274 {0, },
275 {6, 773, 1272, {0x1D, 0xF4, 0x15, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x3F, 0x10, 0x02}},
276 {4, 592, 976, {0x1D, 0xF4, 0x25, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x4E, 0x10, 0x02}},
277 {3, 448, 738, {0x1D, 0xF4, 0x3D, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x69, 0x10, 0x02}},
278 },
279 /* 10 fps */
280 {
281 {0, },
282 {9, 956, 788, {0x1C, 0xF4, 0x35, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x33, 0x10, 0x02}},
283 {6, 776, 640, {0x1C, 0x7A, 0x53, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x3F, 0x10, 0x02}},
284 {4, 592, 488, {0x1C, 0x7A, 0x6B, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x4E, 0x10, 0x02}},
285 },
286 /* 15 fps */
287 {
288 {0, },
289 {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
290 {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
291 {8, 895, 492, {0x1B, 0x7A, 0x6B, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x37, 0x80, 0x02}},
292 },
293 /* 20 fps */
294 {
295 {0, },
296 {0, },
297 {0, },
298 {0, },
299 },
300 /* 25 fps */
301 {
302 {0, },
303 {0, },
304 {0, },
305 {0, },
306 },
307 /* 30 fps */
308 {
309 {0, },
310 {0, },
311 {0, },
312 {0, },
313 },
314 },
315};
316
317/*
318 * 16 versions:
319 * 2 tables (one for Y, and one for U&V)
320 * 16 levels of details per tables
321 * 8 blocs
322 */
323
324const unsigned int TimonRomTable [16][2][16][8] =
325{
326 { /* version 0 */
327 { /* version 0, passes 0 */
328 {0x00000000,0x00000000,0x00000000,0x00000000,
329 0x00000000,0x00000000,0x00000000,0x00000001},
330 {0x00000000,0x00000000,0x00000001,0x00000001,
331 0x00000001,0x00000001,0x00000001,0x00000001},
332 {0x00000000,0x00000000,0x00000001,0x00000001,
333 0x00000001,0x00000009,0x00000009,0x00000009},
334 {0x00000000,0x00000000,0x00000009,0x00000001,
335 0x00000009,0x00000009,0x00000009,0x00000009},
336 {0x00000000,0x00000000,0x00000009,0x00000009,
337 0x00000009,0x00000009,0x00000049,0x00000009},
338 {0x00000000,0x00000000,0x00000009,0x00000009,
339 0x00000009,0x00000049,0x00000049,0x00000049},
340 {0x00000000,0x00000000,0x00000009,0x00000009,
341 0x00000049,0x00000049,0x00000049,0x00000049},
342 {0x00000000,0x00000000,0x00000009,0x00000049,
343 0x00000049,0x00000049,0x00000049,0x00000049},
344 {0x00000000,0x00000000,0x00000049,0x00000049,
345 0x00000049,0x00000049,0x0000024a,0x0000024a},
346 {0x00000000,0x00000000,0x00000049,0x00000049,
347 0x00000049,0x00000249,0x0000024a,0x0000024a},
348 {0x00000000,0x00000000,0x00000049,0x00000049,
349 0x00000249,0x00000249,0x0000024a,0x0000024a},
350 {0x00000000,0x00000000,0x00000049,0x00000049,
351 0x00000249,0x00000249,0x00001252,0x0000024a},
352 {0x00000000,0x00000000,0x00000049,0x00000049,
353 0x00000249,0x0000124a,0x00001252,0x0000024a},
354 {0x00000000,0x00000000,0x00000049,0x00000249,
355 0x00000249,0x0000124a,0x00001252,0x0000024a},
356 {0x00000000,0x00000000,0x00000249,0x00001249,
357 0x0000124a,0x00009252,0x00009292,0x00001252},
358 {0x00000000,0x00000000,0x00000000,0x00000000,
359 0x00000000,0x00000000,0x00000000,0x00000000}
360 },
361 { /* version 0, passes 1 */
362 {0x00000000,0x00000000,0x00000000,0x00000000,
363 0x00000000,0x00000000,0x00000000,0x00000000},
364 {0x00000000,0x00000000,0x00000001,0x00000001,
365 0x00000001,0x00000001,0x00000000,0x00000000},
366 {0x00000000,0x00000000,0x00000009,0x00000001,
367 0x00000001,0x00000009,0x00000000,0x00000000},
368 {0x00000000,0x00000000,0x00000009,0x00000009,
369 0x00000009,0x00000009,0x00000000,0x00000000},
370 {0x00000000,0x00000000,0x00000009,0x00000009,
371 0x00000009,0x00000009,0x00000001,0x00000000},
372 {0x00000000,0x00000000,0x00000049,0x00000009,
373 0x00000009,0x00000049,0x00000001,0x00000001},
374 {0x00000000,0x00000000,0x00000049,0x00000009,
375 0x00000009,0x00000049,0x00000001,0x00000001},
376 {0x00000000,0x00000000,0x00000049,0x00000049,
377 0x00000049,0x00000049,0x00000009,0x00000001},
378 {0x00000000,0x00000000,0x00000049,0x00000049,
379 0x00000049,0x00000049,0x00000009,0x00000001},
380 {0x00000000,0x00000000,0x00000049,0x00000049,
381 0x00000049,0x00000049,0x00000009,0x00000001},
382 {0x00000000,0x00000000,0x00000049,0x00000049,
383 0x00000049,0x00000049,0x00000009,0x00000009},
384 {0x00000000,0x00000000,0x00000049,0x00000049,
385 0x00000049,0x00000249,0x00000049,0x00000009},
386 {0x00000000,0x00000000,0x00000049,0x00000049,
387 0x00000049,0x00000249,0x00000049,0x00000009},
388 {0x00000000,0x00000000,0x00000249,0x00000049,
389 0x00000249,0x00000249,0x00000049,0x00000009},
390 {0x00000000,0x00000000,0x00001249,0x00000249,
391 0x0000124a,0x0000124a,0x0000024a,0x00000049},
392 {0x00000000,0x00000000,0x00000000,0x00000000,
393 0x00000000,0x00000000,0x00000000,0x00000000}
394 }
395 },
396 { /* version 1 */
397 { /* version 1, passes 0 */
398 {0x00000000,0x00000000,0x00000000,0x00000000,
399 0x00000000,0x00000000,0x00000000,0x00000001},
400 {0x00000000,0x00000000,0x00000001,0x00000001,
401 0x00000001,0x00000009,0x00000009,0x00000009},
402 {0x00000000,0x00000000,0x00000009,0x00000009,
403 0x00000009,0x00000009,0x00000009,0x00000009},
404 {0x00000000,0x00000000,0x00000009,0x00000009,
405 0x00000009,0x00000049,0x00000049,0x00000049},
406 {0x00000000,0x00000000,0x00000009,0x00000049,
407 0x00000049,0x00000049,0x00000049,0x00000049},
408 {0x00000000,0x00000000,0x00000049,0x00000049,
409 0x00000049,0x00000249,0x0000024a,0x0000024a},
410 {0x00000000,0x00000000,0x00000049,0x00000049,
411 0x00000249,0x00000249,0x0000024a,0x0000024a},
412 {0x00000000,0x00000000,0x00000049,0x00000249,
413 0x00000249,0x00000249,0x0000024a,0x00001252},
414 {0x00000000,0x00000000,0x00000049,0x00000249,
415 0x00000249,0x0000124a,0x00001252,0x00001252},
416 {0x00000000,0x00000000,0x00000049,0x00000249,
417 0x0000124a,0x0000124a,0x00001252,0x00001252},
418 {0x00000000,0x00000000,0x00000249,0x00000249,
419 0x0000124a,0x0000124a,0x00009292,0x00009292},
420 {0x00000000,0x00000000,0x00000249,0x00001249,
421 0x0000124a,0x00009252,0x00009292,0x00009292},
422 {0x00000000,0x00000000,0x00000249,0x00001249,
423 0x00009252,0x00009252,0x00009292,0x00009292},
424 {0x00000000,0x00000000,0x00000249,0x0000924a,
425 0x00009292,0x00009493,0x00009493,0x00009493},
426 {0x00000000,0x00000000,0x00001249,0x00009252,
427 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
428 {0x00000000,0x00000000,0x00000000,0x00000000,
429 0x00000000,0x00000000,0x00000000,0x00000000}
430 },
431 { /* version 1, passes 1 */
432 {0x00000000,0x00000000,0x00000000,0x00000000,
433 0x00000000,0x00000000,0x00000000,0x00000000},
434 {0x00000000,0x00000000,0x00000009,0x00000009,
435 0x00000009,0x00000001,0x00000001,0x00000000},
436 {0x00000000,0x00000000,0x00000009,0x00000009,
437 0x00000009,0x00000009,0x00000001,0x00000000},
438 {0x00000000,0x00000000,0x00000049,0x00000049,
439 0x00000049,0x00000009,0x00000001,0x00000000},
440 {0x00000000,0x00000000,0x00000049,0x00000049,
441 0x00000049,0x00000049,0x00000001,0x00000001},
442 {0x00000000,0x00000000,0x00000049,0x00000049,
443 0x00000049,0x00000049,0x00000009,0x00000001},
444 {0x00000000,0x00000000,0x00000249,0x00000049,
445 0x00000049,0x00000249,0x00000009,0x00000001},
446 {0x00000000,0x00000000,0x00000249,0x00000049,
447 0x00000249,0x00000249,0x00000009,0x00000009},
448 {0x00000000,0x00000000,0x00000249,0x00000249,
449 0x00000249,0x00000249,0x00000049,0x00000009},
450 {0x00000000,0x00000000,0x00000249,0x00000249,
451 0x00000249,0x0000124a,0x00000049,0x00000009},
452 {0x00000000,0x00000000,0x00000249,0x00000249,
453 0x00000249,0x0000124a,0x00000049,0x00000009},
454 {0x00000000,0x00000000,0x00000249,0x00000249,
455 0x00000249,0x0000124a,0x0000024a,0x00000049},
456 {0x00000000,0x00000000,0x00000249,0x00000249,
457 0x0000124a,0x0000124a,0x0000024a,0x00000049},
458 {0x00000000,0x00000000,0x00000249,0x00000249,
459 0x0000124a,0x0000124a,0x0000024a,0x00000049},
460 {0x00000000,0x00000000,0x00001249,0x00001249,
461 0x00009252,0x00009252,0x00001252,0x0000024a},
462 {0x00000000,0x00000000,0x00000000,0x00000000,
463 0x00000000,0x00000000,0x00000000,0x00000000}
464 }
465 },
466 { /* version 2 */
467 { /* version 2, passes 0 */
468 {0x00000000,0x00000000,0x00000000,0x00000000,
469 0x00000000,0x00000000,0x00000000,0x00000001},
470 {0x00000000,0x00000000,0x00000009,0x00000009,
471 0x00000009,0x00000009,0x00000009,0x00000009},
472 {0x00000000,0x00000000,0x00000049,0x00000049,
473 0x00000049,0x00000049,0x00000049,0x00000049},
474 {0x00000000,0x00000000,0x00000049,0x00000049,
475 0x00000049,0x00000249,0x0000024a,0x0000024a},
476 {0x00000000,0x00000000,0x00000049,0x00000249,
477 0x00000249,0x00000249,0x0000024a,0x00001252},
478 {0x00000000,0x00000000,0x00000249,0x00000249,
479 0x00000249,0x0000124a,0x00001252,0x00001252},
480 {0x00000000,0x00000000,0x00000249,0x00000249,
481 0x0000124a,0x0000124a,0x00009292,0x00009292},
482 {0x00000000,0x00000000,0x00000249,0x00001249,
483 0x0000124a,0x00009252,0x00009292,0x00009292},
484 {0x00000000,0x00000000,0x00000249,0x00001249,
485 0x00009252,0x00009292,0x00009292,0x00009292},
486 {0x00000000,0x00000000,0x00000249,0x00001249,
487 0x00009252,0x00009292,0x00009493,0x00009493},
488 {0x00000000,0x00000000,0x00000249,0x0000924a,
489 0x00009252,0x00009493,0x00009493,0x00009493},
490 {0x00000000,0x00000000,0x00000249,0x0000924a,
491 0x00009292,0x00009493,0x00009493,0x00009493},
492 {0x00000000,0x00000000,0x00000249,0x00009252,
493 0x00009492,0x00009493,0x0000a49b,0x0000a49b},
494 {0x00000000,0x00000000,0x00001249,0x00009292,
495 0x00009492,0x000124db,0x000124db,0x000124db},
496 {0x00000000,0x00000000,0x0000924a,0x00009493,
497 0x0000a493,0x000126dc,0x000126dc,0x000126dc},
498 {0x00000000,0x00000000,0x00000000,0x00000000,
499 0x00000000,0x00000000,0x00000000,0x00000000}
500 },
501 { /* version 2, passes 1 */
502 {0x00000000,0x00000000,0x00000000,0x00000000,
503 0x00000000,0x00000000,0x00000000,0x00000000},
504 {0x00000000,0x00000000,0x00000049,0x00000009,
505 0x00000049,0x00000009,0x00000001,0x00000000},
506 {0x00000000,0x00000000,0x00000049,0x00000049,
507 0x00000049,0x00000049,0x00000049,0x00000000},
508 {0x00000000,0x00000000,0x00000249,0x00000049,
509 0x00000249,0x00000049,0x0000024a,0x00000001},
510 {0x00000000,0x00000000,0x00000249,0x00000249,
511 0x00000249,0x00000249,0x0000024a,0x00000001},
512 {0x00000000,0x00000000,0x00000249,0x00000249,
513 0x00000249,0x00000249,0x0000024a,0x00000001},
514 {0x00000000,0x00000000,0x00000249,0x00000249,
515 0x00000249,0x00000249,0x0000024a,0x00000009},
516 {0x00000000,0x00000000,0x00000249,0x00000249,
517 0x0000124a,0x0000124a,0x0000024a,0x00000009},
518 {0x00000000,0x00000000,0x00000249,0x00000249,
519 0x0000124a,0x0000124a,0x0000024a,0x00000009},
520 {0x00000000,0x00000000,0x00001249,0x00001249,
521 0x0000124a,0x00009252,0x00001252,0x00000049},
522 {0x00000000,0x00000000,0x00001249,0x00001249,
523 0x0000124a,0x00009292,0x00001252,0x00000049},
524 {0x00000000,0x00000000,0x00001249,0x00001249,
525 0x0000124a,0x00009292,0x00001252,0x00000049},
526 {0x00000000,0x00000000,0x00001249,0x00001249,
527 0x00009252,0x00009292,0x00001252,0x0000024a},
528 {0x00000000,0x00000000,0x00001249,0x00001249,
529 0x00009292,0x00009292,0x00001252,0x0000024a},
530 {0x00000000,0x00000000,0x0000924a,0x0000924a,
531 0x00009492,0x00009493,0x00009292,0x00001252},
532 {0x00000000,0x00000000,0x00000000,0x00000000,
533 0x00000000,0x00000000,0x00000000,0x00000000}
534 }
535 },
536 { /* version 3 */
537 { /* version 3, passes 0 */
538 {0x00000000,0x00000000,0x00000000,0x00000000,
539 0x00000000,0x00000000,0x00000000,0x00000001},
540 {0x00000000,0x00000000,0x00000049,0x00000049,
541 0x00000049,0x00000049,0x00000049,0x00000049},
542 {0x00000000,0x00000000,0x00000049,0x00000249,
543 0x00000249,0x00000249,0x00001252,0x0000024a},
544 {0x00000000,0x00000000,0x00000249,0x00000249,
545 0x00000249,0x0000124a,0x00001252,0x00001252},
546 {0x00000000,0x00000000,0x00000249,0x00000249,
547 0x0000124a,0x00009252,0x00009292,0x00009292},
548 {0x00000000,0x00000000,0x00000249,0x00001249,
549 0x0000124a,0x00009292,0x00009292,0x00009493},
550 {0x00000000,0x00000000,0x00000249,0x00001249,
551 0x00009252,0x00009292,0x00009493,0x00009493},
552 {0x00000000,0x00000000,0x00000249,0x00001249,
553 0x00009292,0x00009493,0x00009493,0x00009493},
554 {0x00000000,0x00000000,0x00000249,0x00009252,
555 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
556 {0x00000000,0x00000000,0x00001249,0x00009252,
557 0x00009292,0x0000a49b,0x0000a49b,0x0000a49b},
558 {0x00000000,0x00000000,0x00001249,0x00009252,
559 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
560 {0x00000000,0x00000000,0x00001249,0x00009292,
561 0x00009492,0x0000a49b,0x000124db,0x000124db},
562 {0x00000000,0x00000000,0x00001249,0x00009292,
563 0x0000a493,0x0000a49b,0x000124db,0x000124db},
564 {0x00000000,0x00000000,0x00001249,0x00009493,
565 0x0001249b,0x000126dc,0x000136e4,0x000126dc},
566 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
567 0x000124db,0x000136e4,0x0001b725,0x000136e4},
568 {0x00000000,0x00000000,0x00000000,0x00000000,
569 0x00000000,0x00000000,0x00000000,0x00000000}
570 },
571 { /* version 3, passes 1 */
572 {0x00000000,0x00000000,0x00000000,0x00000000,
573 0x00000000,0x00000000,0x00000000,0x00000000},
574 {0x00000000,0x00000000,0x00000049,0x00000049,
575 0x00000049,0x00000049,0x00000001,0x00000000},
576 {0x00000000,0x00000000,0x00000249,0x00000249,
577 0x00000249,0x00000249,0x00000049,0x00000001},
578 {0x00000000,0x00000000,0x00000249,0x00000249,
579 0x00000249,0x0000124a,0x00001252,0x00000001},
580 {0x00000000,0x00000000,0x00000249,0x00000249,
581 0x0000124a,0x0000124a,0x00001252,0x00000009},
582 {0x00000000,0x00000000,0x00000249,0x00001249,
583 0x0000124a,0x00009252,0x00009292,0x00000009},
584 {0x00000000,0x00000000,0x00001249,0x00001249,
585 0x0000124a,0x00009252,0x00009292,0x00000049},
586 {0x00000000,0x00000000,0x00001249,0x00001249,
587 0x00009252,0x00009252,0x00009292,0x00000049},
588 {0x00000000,0x00000000,0x00001249,0x00001249,
589 0x00009252,0x00009493,0x00009292,0x0000024a},
590 {0x00000000,0x00000000,0x00001249,0x00001249,
591 0x00009252,0x00009493,0x00009292,0x0000024a},
592 {0x00000000,0x00000000,0x00001249,0x00001249,
593 0x00009252,0x00009493,0x00009493,0x00001252},
594 {0x00000000,0x00000000,0x00001249,0x0000924a,
595 0x00009292,0x00009493,0x00009493,0x00001252},
596 {0x00000000,0x00000000,0x00001249,0x0000924a,
597 0x00009492,0x00009493,0x00009493,0x00009292},
598 {0x00000000,0x00000000,0x00001249,0x00009252,
599 0x00009492,0x0000a49b,0x00009493,0x00009292},
600 {0x00000000,0x00000000,0x0000924a,0x00009292,
601 0x0000a493,0x000124db,0x0000a49b,0x00009493},
602 {0x00000000,0x00000000,0x00000000,0x00000000,
603 0x00000000,0x00000000,0x00000000,0x00000000}
604 }
605 },
606 { /* version 4 */
607 { /* version 4, passes 0 */
608 {0x00000000,0x00000000,0x00000049,0x00000049,
609 0x00000049,0x00000049,0x0000024a,0x0000024a},
610 {0x00000000,0x00000000,0x00000249,0x00000249,
611 0x00000249,0x0000124a,0x00001252,0x00009292},
612 {0x00000000,0x00000000,0x00000249,0x00000249,
613 0x0000124a,0x00009252,0x00009292,0x00009292},
614 {0x00000000,0x00000000,0x00000249,0x00001249,
615 0x0000124a,0x00009292,0x00009493,0x00009493},
616 {0x00000000,0x00000000,0x00000249,0x00001249,
617 0x00009252,0x00009493,0x00009493,0x0000a49b},
618 {0x00000000,0x00000000,0x00000249,0x0000924a,
619 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
620 {0x00000000,0x00000000,0x00001249,0x0000924a,
621 0x00009292,0x00009493,0x0000a49b,0x000124db},
622 {0x00000000,0x00000000,0x00001249,0x00009252,
623 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
624 {0x00000000,0x00000000,0x00001249,0x00009292,
625 0x00009492,0x000124db,0x000124db,0x000126dc},
626 {0x00000000,0x00000000,0x00001249,0x00009292,
627 0x0000a493,0x000124db,0x000126dc,0x000126dc},
628 {0x00000000,0x00000000,0x00001249,0x00009493,
629 0x0000a493,0x000124db,0x000126dc,0x000136e4},
630 {0x00000000,0x00000000,0x00001249,0x00009493,
631 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
632 {0x00000000,0x00000000,0x0000924a,0x00009493,
633 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
634 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
635 0x000124db,0x000136e4,0x000136e4,0x0001b724},
636 {0x00000000,0x00000000,0x00009252,0x000124db,
637 0x000126dc,0x0001b724,0x0001b725,0x0001b925},
638 {0x00000000,0x00000000,0x00000000,0x00000000,
639 0x00000000,0x00000000,0x00000000,0x00000000}
640 },
641 { /* version 4, passes 1 */
642 {0x00000000,0x00000000,0x00000049,0x00000049,
643 0x00000049,0x00000049,0x00000049,0x00000049},
644 {0x00000000,0x00000000,0x00000249,0x00000249,
645 0x00000249,0x00000249,0x0000024a,0x00000049},
646 {0x00000000,0x00000000,0x00001249,0x00000249,
647 0x0000124a,0x0000124a,0x00001252,0x00000049},
648 {0x00000000,0x00000000,0x00001249,0x00001249,
649 0x0000124a,0x0000124a,0x00009292,0x0000024a},
650 {0x00000000,0x00000000,0x00001249,0x00001249,
651 0x00009252,0x00009292,0x00009292,0x0000024a},
652 {0x00000000,0x00000000,0x00001249,0x00001249,
653 0x00009252,0x00009292,0x0000a49b,0x0000024a},
654 {0x00000000,0x00000000,0x00001249,0x00001249,
655 0x00009292,0x00009493,0x0000a49b,0x00001252},
656 {0x00000000,0x00000000,0x00001249,0x00001249,
657 0x00009292,0x00009493,0x0000a49b,0x00001252},
658 {0x00000000,0x00000000,0x00001249,0x0000924a,
659 0x00009492,0x0000a49b,0x0000a49b,0x00001252},
660 {0x00000000,0x00000000,0x00001249,0x00009252,
661 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
662 {0x00000000,0x00000000,0x00001249,0x00009292,
663 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
664 {0x00000000,0x00000000,0x00001249,0x00009493,
665 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
666 {0x00000000,0x00000000,0x00001249,0x00009493,
667 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
668 {0x00000000,0x00000000,0x0000924a,0x00009493,
669 0x0000a493,0x000124db,0x0000a49b,0x00009493},
670 {0x00000000,0x00000000,0x00009252,0x0000a49b,
671 0x0001249b,0x000126dc,0x000124db,0x0000a49b},
672 {0x00000000,0x00000000,0x00000000,0x00000000,
673 0x00000000,0x00000000,0x00000000,0x00000000}
674 }
675 },
676 { /* version 5 */
677 { /* version 5, passes 0 */
678 {0x00000000,0x00000000,0x00000249,0x00000249,
679 0x00000249,0x0000124a,0x00001252,0x00009292},
680 {0x00000000,0x00000000,0x00000249,0x00001249,
681 0x0000124a,0x00009292,0x00009292,0x00009493},
682 {0x00000000,0x00000000,0x00000249,0x0000924a,
683 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
684 {0x00000000,0x00000000,0x00001249,0x0000924a,
685 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
686 {0x00000000,0x00000000,0x00001249,0x0000924a,
687 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
688 {0x00000000,0x00000000,0x00001249,0x00009292,
689 0x00009492,0x0000a49b,0x000124db,0x000124db},
690 {0x00000000,0x00000000,0x00001249,0x00009292,
691 0x0000a493,0x000124db,0x000124db,0x000126dc},
692 {0x00000000,0x00000000,0x00001249,0x00009493,
693 0x0000a493,0x000124db,0x000126dc,0x000126dc},
694 {0x00000000,0x00000000,0x00001249,0x00009493,
695 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
696 {0x00000000,0x00000000,0x00001249,0x00009493,
697 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
698 {0x00000000,0x00000000,0x00001249,0x00009493,
699 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
700 {0x00000000,0x00000000,0x0000924a,0x00009493,
701 0x0001249b,0x000126dc,0x0001b725,0x0001b724},
702 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
703 0x000124db,0x000126dc,0x0001b725,0x0001b724},
704 {0x00000000,0x00000000,0x00009292,0x0000a49b,
705 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
706 {0x00000000,0x00000000,0x00009492,0x000124db,
707 0x000136e4,0x0001b724,0x0001c96e,0x0001c92d},
708 {0x00000000,0x00000000,0x00000000,0x00000000,
709 0x00000000,0x00000000,0x00000000,0x00000000}
710 },
711 { /* version 5, passes 1 */
712 {0x00000000,0x00000000,0x00000249,0x00000249,
713 0x0000124a,0x00000249,0x0000024a,0x0000024a},
714 {0x00000000,0x00000000,0x00001249,0x00001249,
715 0x0000124a,0x0000124a,0x00001252,0x0000024a},
716 {0x00000000,0x00000000,0x00001249,0x00001249,
717 0x00009292,0x00009493,0x00009493,0x0000024a},
718 {0x00000000,0x00000000,0x00001249,0x00001249,
719 0x00009292,0x00009493,0x00009493,0x00001252},
720 {0x00000000,0x00000000,0x00001249,0x00001249,
721 0x00009292,0x00009493,0x0000a49b,0x00001252},
722 {0x00000000,0x00000000,0x00001249,0x0000924a,
723 0x00009492,0x00009493,0x000124db,0x00001252},
724 {0x00000000,0x00000000,0x00001249,0x00009292,
725 0x00009492,0x00009493,0x000124db,0x00009292},
726 {0x00000000,0x00000000,0x00001249,0x00009292,
727 0x00009492,0x0000a49b,0x000124db,0x00009292},
728 {0x00000000,0x00000000,0x00001249,0x00009493,
729 0x0000a493,0x0000a49b,0x000124db,0x00009292},
730 {0x00000000,0x00000000,0x00001249,0x00009493,
731 0x0000a493,0x000124db,0x000124db,0x00009493},
732 {0x00000000,0x00000000,0x0000924a,0x00009493,
733 0x0000a493,0x000124db,0x000124db,0x00009493},
734 {0x00000000,0x00000000,0x0000924a,0x00009493,
735 0x0000a493,0x000124db,0x000124db,0x00009493},
736 {0x00000000,0x00000000,0x0000924a,0x00009493,
737 0x0000a493,0x000124db,0x000124db,0x0000a49b},
738 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
739 0x000124db,0x000126dc,0x000124db,0x0000a49b},
740 {0x00000000,0x00000000,0x00009252,0x000124db,
741 0x000126dc,0x000136e4,0x000126dc,0x000124db},
742 {0x00000000,0x00000000,0x00000000,0x00000000,
743 0x00000000,0x00000000,0x00000000,0x00000000}
744 }
745 },
746 { /* version 6 */
747 { /* version 6, passes 0 */
748 {0x00000000,0x00000000,0x00000249,0x00000249,
749 0x0000124a,0x0000124a,0x00009292,0x00009292},
750 {0x00000000,0x00000000,0x00001249,0x00001249,
751 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
752 {0x00000000,0x00000000,0x00001249,0x0000924a,
753 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
754 {0x00000000,0x00000000,0x00001249,0x00009292,
755 0x00009492,0x000124db,0x000126dc,0x000126dc},
756 {0x00000000,0x00000000,0x00001249,0x00009493,
757 0x0000a493,0x000124db,0x000126dc,0x000126dc},
758 {0x00000000,0x00000000,0x00001249,0x00009493,
759 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
760 {0x00000000,0x00000000,0x00001249,0x00009493,
761 0x0000a493,0x000126dc,0x000136e4,0x0001b724},
762 {0x00000000,0x00000000,0x00001249,0x00009493,
763 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
764 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
765 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
766 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
767 0x0001249b,0x000136e4,0x0001b725,0x0001b724},
768 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
769 0x000124db,0x000136e4,0x0001b725,0x0001b925},
770 {0x00000000,0x00000000,0x00009292,0x0000a49b,
771 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
772 {0x00000000,0x00000000,0x00009292,0x0000a49b,
773 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
774 {0x00000000,0x00000000,0x00009492,0x000124db,
775 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
776 {0x00000000,0x00000000,0x0000a492,0x000126db,
777 0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
778 {0x00000000,0x00000000,0x00000000,0x00000000,
779 0x00000000,0x00000000,0x00000000,0x00000000}
780 },
781 { /* version 6, passes 1 */
782 {0x00000000,0x00000000,0x00001249,0x00000249,
783 0x0000124a,0x0000124a,0x00001252,0x00001252},
784 {0x00000000,0x00000000,0x00001249,0x00001249,
785 0x00009252,0x00009292,0x00009292,0x00001252},
786 {0x00000000,0x00000000,0x00001249,0x0000924a,
787 0x00009492,0x00009493,0x0000a49b,0x00001252},
788 {0x00000000,0x00000000,0x00001249,0x00009252,
789 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
790 {0x00000000,0x00000000,0x00001249,0x00009292,
791 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
792 {0x00000000,0x00000000,0x00001249,0x00009493,
793 0x0000a493,0x0000a49b,0x000126dc,0x00009292},
794 {0x00000000,0x00000000,0x0000924a,0x00009493,
795 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
796 {0x00000000,0x00000000,0x0000924a,0x00009493,
797 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
798 {0x00000000,0x00000000,0x0000924a,0x00009493,
799 0x0000a493,0x000124db,0x000126dc,0x00009493},
800 {0x00000000,0x00000000,0x0000924a,0x00009493,
801 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
802 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
803 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
804 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
805 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
806 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
807 0x000124db,0x000136e4,0x000126dc,0x000124db},
808 {0x00000000,0x00000000,0x00009492,0x0000a49b,
809 0x000136e4,0x000136e4,0x000126dc,0x000124db},
810 {0x00000000,0x00000000,0x0000a492,0x000124db,
811 0x0001b724,0x0001b724,0x000136e4,0x000126dc},
812 {0x00000000,0x00000000,0x00000000,0x00000000,
813 0x00000000,0x00000000,0x00000000,0x00000000}
814 }
815 },
816 { /* version 7 */
817 { /* version 7, passes 0 */
818 {0x00000000,0x00000000,0x00001249,0x00001249,
819 0x00009292,0x00009493,0x0000a49b,0x000124db},
820 {0x00000000,0x00000000,0x00001249,0x00009292,
821 0x0000a493,0x0000a49b,0x000124db,0x000126dc},
822 {0x00000000,0x00000000,0x00001249,0x00009493,
823 0x0000a493,0x000124db,0x000126dc,0x000136e4},
824 {0x00000000,0x00000000,0x00001249,0x00009493,
825 0x0000a493,0x000124db,0x000136e4,0x000136e4},
826 {0x00000000,0x00000000,0x00001249,0x00009493,
827 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
828 {0x00000000,0x00000000,0x00001249,0x0000a49b,
829 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
830 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
831 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
832 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
833 0x000124db,0x000136e4,0x0001b725,0x0001b724},
834 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
835 0x000126dc,0x000136e4,0x0001b725,0x0001b925},
836 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
837 0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
838 {0x00000000,0x00000000,0x00009292,0x0000a49b,
839 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
840 {0x00000000,0x00000000,0x00009292,0x000124db,
841 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
842 {0x00000000,0x00000000,0x00009492,0x000124db,
843 0x000136e4,0x0001b724,0x0001c96e,0x0002496e},
844 {0x00000000,0x00000000,0x00009492,0x000126db,
845 0x000136e4,0x0001b925,0x0001c96e,0x0002496e},
846 {0x00000000,0x00000000,0x0000a492,0x000136db,
847 0x0001b724,0x0002496d,0x00025bb6,0x00025bbf},
848 {0x00000000,0x00000000,0x00000000,0x00000000,
849 0x00000000,0x00000000,0x00000000,0x00000000}
850 },
851 { /* version 7, passes 1 */
852 {0x00000000,0x00000000,0x00001249,0x00001249,
853 0x00009252,0x00009292,0x00009292,0x00009292},
854 {0x00000000,0x00000000,0x00001249,0x0000924a,
855 0x00009492,0x00009493,0x00009493,0x00009292},
856 {0x00000000,0x00000000,0x00001249,0x00009493,
857 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
858 {0x00000000,0x00000000,0x0000924a,0x00009493,
859 0x0000a493,0x0000a49b,0x000124db,0x00009493},
860 {0x00000000,0x00000000,0x0000924a,0x00009493,
861 0x0000a493,0x000124db,0x000124db,0x00009493},
862 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
863 0x0000a493,0x000124db,0x000136e4,0x00009493},
864 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
865 0x0000a493,0x000124db,0x000136e4,0x0000a49b},
866 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
867 0x0001249b,0x000124db,0x000136e4,0x0000a49b},
868 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
869 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
870 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
871 0x0001249b,0x000126dc,0x000136e4,0x000124db},
872 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
873 0x000126dc,0x000136e4,0x000136e4,0x000124db},
874 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
875 0x000126dc,0x000136e4,0x000136e4,0x000124db},
876 {0x00000000,0x00000000,0x0000924a,0x000124db,
877 0x000136e4,0x000136e4,0x000136e4,0x000126dc},
878 {0x00000000,0x00000000,0x0000a492,0x000124db,
879 0x000136e4,0x0001b724,0x000136e4,0x000126dc},
880 {0x00000000,0x00000000,0x00012492,0x000126db,
881 0x0001b724,0x0001b925,0x0001b725,0x000136e4},
882 {0x00000000,0x00000000,0x00000000,0x00000000,
883 0x00000000,0x00000000,0x00000000,0x00000000}
884 }
885 },
886 { /* version 8 */
887 { /* version 8, passes 0 */
888 {0x00000000,0x00000000,0x00001249,0x00001249,
889 0x00009292,0x00009493,0x0000a49b,0x000124db},
890 {0x00000000,0x00000000,0x00001249,0x00009292,
891 0x0000a493,0x000124db,0x000126dc,0x000126dc},
892 {0x00000000,0x00000000,0x00001249,0x00009493,
893 0x0000a493,0x000124db,0x000126dc,0x000136e4},
894 {0x00000000,0x00000000,0x00001249,0x0000a49b,
895 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
896 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
897 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
898 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
899 0x000124db,0x000136e4,0x0001b725,0x0001b724},
900 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
901 0x000126dc,0x000136e4,0x0001b725,0x0001b925},
902 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
903 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
904 {0x00000000,0x00000000,0x00009252,0x000124db,
905 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
906 {0x00000000,0x00000000,0x00009292,0x000124db,
907 0x000126dc,0x0001b925,0x0001c96e,0x0001c92d},
908 {0x00000000,0x00000000,0x00009492,0x000124db,
909 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
910 {0x00000000,0x00000000,0x00009492,0x000124db,
911 0x000136e4,0x0001b925,0x00024b76,0x00024b77},
912 {0x00000000,0x00000000,0x00009492,0x000126db,
913 0x000136e4,0x0001b925,0x00024b76,0x00025bbf},
914 {0x00000000,0x00000000,0x0000a492,0x000126db,
915 0x000136e4,0x0001c92d,0x00024b76,0x00025bbf},
916 {0x00000000,0x00000000,0x00012492,0x000136db,
917 0x0001b724,0x00024b6d,0x0002ddb6,0x0002efff},
918 {0x00000000,0x00000000,0x00000000,0x00000000,
919 0x00000000,0x00000000,0x00000000,0x00000000}
920 },
921 { /* version 8, passes 1 */
922 {0x00000000,0x00000000,0x00001249,0x00001249,
923 0x00009252,0x00009493,0x00009493,0x00009493},
924 {0x00000000,0x00000000,0x00001249,0x00009292,
925 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
926 {0x00000000,0x00000000,0x0000924a,0x00009493,
927 0x0000a493,0x0000a49b,0x000124db,0x00009493},
928 {0x00000000,0x00000000,0x0000924a,0x00009493,
929 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
930 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
931 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
932 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
933 0x0000a493,0x000124db,0x000136e4,0x000124db},
934 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
935 0x0001249b,0x000126dc,0x000136e4,0x000124db},
936 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
937 0x000126dc,0x000126dc,0x000136e4,0x000126dc},
938 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
939 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
940 {0x00000000,0x00000000,0x0000924a,0x000124db,
941 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
942 {0x00000000,0x00000000,0x0000924a,0x000124db,
943 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
944 {0x00000000,0x00000000,0x00009292,0x000124db,
945 0x000136e4,0x0001b724,0x0001b725,0x000136e4},
946 {0x00000000,0x00000000,0x00009492,0x000126db,
947 0x000136e4,0x0001b925,0x0001b725,0x0001b724},
948 {0x00000000,0x00000000,0x00009492,0x000126db,
949 0x000136e4,0x0001b925,0x0001b725,0x0001b724},
950 {0x00000000,0x00000000,0x0000a492,0x000136db,
951 0x0001b724,0x0002496d,0x0001b92d,0x0001b925},
952 {0x00000000,0x00000000,0x00000000,0x00000000,
953 0x00000000,0x00000000,0x00000000,0x00000000}
954 }
955 },
956 { /* version 9 */
957 { /* version 9, passes 0 */
958 {0x00000000,0x00000000,0x00000049,0x00000049,
959 0x00000049,0x00000049,0x00000049,0x00000049},
960 {0x00000000,0x00000000,0x00000249,0x00000049,
961 0x00000249,0x00000249,0x0000024a,0x00000049},
962 {0x00000000,0x00000000,0x00000249,0x00000249,
963 0x0000124a,0x00009252,0x00001252,0x0000024a},
964 {0x00000000,0x00000000,0x00001249,0x00001249,
965 0x00009252,0x00009292,0x00009493,0x00001252},
966 {0x00000000,0x00000000,0x00001249,0x0000924a,
967 0x00009292,0x00009493,0x00009493,0x00001252},
968 {0x00000000,0x00000000,0x00001249,0x00009292,
969 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
970 {0x00000000,0x00000000,0x00001249,0x00009493,
971 0x0000a493,0x000124db,0x000124db,0x00009493},
972 {0x00000000,0x00000000,0x0000924a,0x00009493,
973 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
974 {0x00000000,0x00000000,0x0000924a,0x00009493,
975 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
976 {0x00000000,0x00000000,0x0000924a,0x00009493,
977 0x0001249b,0x000126dc,0x000126dc,0x000124db},
978 {0x00000000,0x00000000,0x00009252,0x00009493,
979 0x000124db,0x000136e4,0x000136e4,0x000126dc},
980 {0x00000000,0x00000000,0x00009252,0x0000a49b,
981 0x000124db,0x000136e4,0x000136e4,0x000126dc},
982 {0x00000000,0x00000000,0x00009292,0x0000a49b,
983 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
984 {0x00000000,0x00000000,0x00009492,0x0000a49b,
985 0x000126dc,0x0001b724,0x0001b725,0x0001b724},
986 {0x00000000,0x00000000,0x0000a492,0x000124db,
987 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
988 {0x00000000,0x00000000,0x00000000,0x00000000,
989 0x00000000,0x00000000,0x00000000,0x00000000}
990 },
991 { /* version 9, passes 1 */
992 {0x00000000,0x00000000,0x00000249,0x00000049,
993 0x00000009,0x00000009,0x00000009,0x00000009},
994 {0x00000000,0x00000000,0x00000249,0x00000249,
995 0x00000049,0x00000049,0x00000009,0x00000009},
996 {0x00000000,0x00000000,0x00001249,0x00001249,
997 0x0000124a,0x00000249,0x00000049,0x00000049},
998 {0x00000000,0x00000000,0x00001249,0x00001249,
999 0x0000124a,0x0000124a,0x00000049,0x00000049},
1000 {0x00000000,0x00000000,0x00001249,0x00001249,
1001 0x00009252,0x0000124a,0x0000024a,0x0000024a},
1002 {0x00000000,0x00000000,0x00001249,0x0000924a,
1003 0x00009252,0x0000124a,0x0000024a,0x0000024a},
1004 {0x00000000,0x00000000,0x00001249,0x00009292,
1005 0x00009492,0x00009252,0x00001252,0x00001252},
1006 {0x00000000,0x00000000,0x00001249,0x00009493,
1007 0x0000a493,0x00009292,0x00009292,0x00001252},
1008 {0x00000000,0x00000000,0x0000924a,0x00009493,
1009 0x0000a493,0x00009292,0x00009292,0x00009292},
1010 {0x00000000,0x00000000,0x0000924a,0x00009493,
1011 0x0000a493,0x00009493,0x00009493,0x00009292},
1012 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1013 0x0000a493,0x0000a49b,0x00009493,0x00009493},
1014 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1015 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
1016 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1017 0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
1018 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1019 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1020 {0x00000000,0x00000000,0x00009252,0x000124db,
1021 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1022 {0x00000000,0x00000000,0x00000000,0x00000000,
1023 0x00000000,0x00000000,0x00000000,0x00000000}
1024 }
1025 },
1026 { /* version 10 */
1027 { /* version 10, passes 0 */
1028 {0x00000000,0x00000000,0x00000249,0x00000249,
1029 0x00000249,0x00000249,0x0000024a,0x0000024a},
1030 {0x00000000,0x00000000,0x00000249,0x00001249,
1031 0x00009252,0x00009292,0x00009292,0x0000024a},
1032 {0x00000000,0x00000000,0x00001249,0x00001249,
1033 0x00009252,0x00009292,0x00009292,0x00001252},
1034 {0x00000000,0x00000000,0x00001249,0x0000924a,
1035 0x00009492,0x00009493,0x0000a49b,0x00009292},
1036 {0x00000000,0x00000000,0x00001249,0x00009292,
1037 0x00009492,0x000124db,0x000124db,0x00009292},
1038 {0x00000000,0x00000000,0x00001249,0x00009493,
1039 0x0000a493,0x000124db,0x000124db,0x00009493},
1040 {0x00000000,0x00000000,0x00001249,0x00009493,
1041 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
1042 {0x00000000,0x00000000,0x0000924a,0x00009493,
1043 0x0000a493,0x000124db,0x000126dc,0x000124db},
1044 {0x00000000,0x00000000,0x0000924a,0x00009493,
1045 0x0001249b,0x000126dc,0x000126dc,0x000124db},
1046 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1047 0x000124db,0x000126dc,0x000136e4,0x000126dc},
1048 {0x00000000,0x00000000,0x00009252,0x0000a49b,
1049 0x000124db,0x000136e4,0x000136e4,0x000136e4},
1050 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1051 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
1052 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1053 0x000126dc,0x0001b724,0x0001b92d,0x0001b724},
1054 {0x00000000,0x00000000,0x00009492,0x000124db,
1055 0x000126dc,0x0001b925,0x0001b92d,0x0001b925},
1056 {0x00000000,0x00000000,0x0000a492,0x000126db,
1057 0x000136e4,0x0002496d,0x0001c96e,0x0001c92d},
1058 {0x00000000,0x00000000,0x00000000,0x00000000,
1059 0x00000000,0x00000000,0x00000000,0x00000000}
1060 },
1061 { /* version 10, passes 1 */
1062 {0x00000000,0x00000000,0x00000249,0x00000249,
1063 0x00000049,0x00000049,0x00000049,0x00000049},
1064 {0x00000000,0x00000000,0x00001249,0x00001249,
1065 0x0000124a,0x00000249,0x00000049,0x00000049},
1066 {0x00000000,0x00000000,0x00001249,0x00001249,
1067 0x0000124a,0x00009252,0x0000024a,0x00000049},
1068 {0x00000000,0x00000000,0x00001249,0x00001249,
1069 0x00009252,0x00009493,0x0000024a,0x0000024a},
1070 {0x00000000,0x00000000,0x00001249,0x00009252,
1071 0x00009492,0x00009493,0x00001252,0x0000024a},
1072 {0x00000000,0x00000000,0x00001249,0x00009292,
1073 0x00009492,0x00009493,0x00001252,0x00001252},
1074 {0x00000000,0x00000000,0x0000924a,0x00009493,
1075 0x00009492,0x00009493,0x00009292,0x00001252},
1076 {0x00000000,0x00000000,0x0000924a,0x00009493,
1077 0x0000a493,0x00009493,0x00009292,0x00009292},
1078 {0x00000000,0x00000000,0x0000924a,0x00009493,
1079 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1080 {0x00000000,0x00000000,0x0000924a,0x00009493,
1081 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1082 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1083 0x0000a493,0x000124db,0x0000a49b,0x00009493},
1084 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1085 0x0000a493,0x000124db,0x0000a49b,0x00009493},
1086 {0x00000000,0x00000000,0x0000924a,0x000124db,
1087 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1088 {0x00000000,0x00000000,0x0000924a,0x000124db,
1089 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1090 {0x00000000,0x00000000,0x00009252,0x000126db,
1091 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1092 {0x00000000,0x00000000,0x00000000,0x00000000,
1093 0x00000000,0x00000000,0x00000000,0x00000000}
1094 }
1095 },
1096 { /* version 11 */
1097 { /* version 11, passes 0 */
1098 {0x00000000,0x00000000,0x00000249,0x00000249,
1099 0x00000249,0x00000249,0x00001252,0x00001252},
1100 {0x00000000,0x00000000,0x00001249,0x00001249,
1101 0x00009252,0x00009292,0x00009292,0x00001252},
1102 {0x00000000,0x00000000,0x00001249,0x0000924a,
1103 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
1104 {0x00000000,0x00000000,0x00001249,0x00009493,
1105 0x0000a493,0x0000a49b,0x000124db,0x00009493},
1106 {0x00000000,0x00000000,0x00001249,0x00009493,
1107 0x0000a493,0x000124db,0x000126dc,0x00009493},
1108 {0x00000000,0x00000000,0x0000924a,0x00009493,
1109 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
1110 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1111 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1112 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1113 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1114 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1115 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1116 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1117 0x000126dc,0x0001b724,0x0001b725,0x000136e4},
1118 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1119 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1120 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1121 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1122 {0x00000000,0x00000000,0x00009492,0x000124db,
1123 0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
1124 {0x00000000,0x00000000,0x00009492,0x000124db,
1125 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
1126 {0x00000000,0x00000000,0x0000a492,0x000126db,
1127 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
1128 {0x00000000,0x00000000,0x00000000,0x00000000,
1129 0x00000000,0x00000000,0x00000000,0x00000000}
1130 },
1131 { /* version 11, passes 1 */
1132 {0x00000000,0x00000000,0x00001249,0x00000249,
1133 0x00000249,0x00000249,0x0000024a,0x0000024a},
1134 {0x00000000,0x00000000,0x00001249,0x00001249,
1135 0x0000124a,0x0000124a,0x0000024a,0x0000024a},
1136 {0x00000000,0x00000000,0x00001249,0x0000924a,
1137 0x00009252,0x00009252,0x0000024a,0x0000024a},
1138 {0x00000000,0x00000000,0x00001249,0x00009292,
1139 0x00009492,0x0000a49b,0x00001252,0x00001252},
1140 {0x00000000,0x00000000,0x0000924a,0x00009493,
1141 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1142 {0x00000000,0x00000000,0x0000924a,0x00009493,
1143 0x0000a493,0x0000a49b,0x00009292,0x00001252},
1144 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1145 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1146 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1147 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1148 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1149 0x0001249b,0x000124db,0x00009493,0x00009292},
1150 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1151 0x0001249b,0x000124db,0x00009493,0x00009493},
1152 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1153 0x000124db,0x000124db,0x0000a49b,0x00009493},
1154 {0x00000000,0x00000000,0x0000924a,0x000124db,
1155 0x000126dc,0x000126dc,0x0000a49b,0x00009493},
1156 {0x00000000,0x00000000,0x0000924a,0x000124db,
1157 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1158 {0x00000000,0x00000000,0x00009292,0x000124db,
1159 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1160 {0x00000000,0x00000000,0x00009492,0x000126db,
1161 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1162 {0x00000000,0x00000000,0x00000000,0x00000000,
1163 0x00000000,0x00000000,0x00000000,0x00000000}
1164 }
1165 },
1166 { /* version 12 */
1167 { /* version 12, passes 0 */
1168 {0x00000000,0x00000000,0x00001249,0x00001249,
1169 0x00009252,0x00009292,0x00009493,0x00009493},
1170 {0x00000000,0x00000000,0x00001249,0x00009292,
1171 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
1172 {0x00000000,0x00000000,0x00001249,0x00009493,
1173 0x0000a493,0x000124db,0x000124db,0x0000a49b},
1174 {0x00000000,0x00000000,0x0000924a,0x00009493,
1175 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
1176 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1177 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1178 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1179 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1180 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1181 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
1182 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1183 0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
1184 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1185 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1186 {0x00000000,0x00000000,0x00009492,0x000124db,
1187 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1188 {0x00000000,0x00000000,0x00009492,0x000124db,
1189 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
1190 {0x00000000,0x00000000,0x00009492,0x000124db,
1191 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
1192 {0x00000000,0x00000000,0x0000a492,0x000124db,
1193 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
1194 {0x00000000,0x00000000,0x0000a492,0x000124db,
1195 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
1196 {0x00000000,0x00000000,0x00012492,0x000126db,
1197 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
1198 {0x00000000,0x00000000,0x00000000,0x00000000,
1199 0x00000000,0x00000000,0x00000000,0x00000000}
1200 },
1201 { /* version 12, passes 1 */
1202 {0x00000000,0x00000000,0x00001249,0x00001249,
1203 0x0000124a,0x0000124a,0x00001252,0x00001252},
1204 {0x00000000,0x00000000,0x00001249,0x00009292,
1205 0x00009492,0x00009252,0x00001252,0x00001252},
1206 {0x00000000,0x00000000,0x0000924a,0x00009493,
1207 0x0000a493,0x00009292,0x00001252,0x00001252},
1208 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1209 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1210 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1211 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1212 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1213 0x0001249b,0x0000a49b,0x00009493,0x00009292},
1214 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1215 0x000124db,0x000124db,0x00009493,0x00009493},
1216 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1217 0x000124db,0x000124db,0x0000a49b,0x00009493},
1218 {0x00000000,0x00000000,0x0000924a,0x000124db,
1219 0x000126dc,0x000124db,0x0000a49b,0x00009493},
1220 {0x00000000,0x00000000,0x0000924a,0x000124db,
1221 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
1222 {0x00000000,0x00000000,0x0000924a,0x000124db,
1223 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1224 {0x00000000,0x00000000,0x00009492,0x000126db,
1225 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1226 {0x00000000,0x00000000,0x00009492,0x000126db,
1227 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1228 {0x00000000,0x00000000,0x00009492,0x000126db,
1229 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1230 {0x00000000,0x00000000,0x0000a492,0x000136db,
1231 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1232 {0x00000000,0x00000000,0x00000000,0x00000000,
1233 0x00000000,0x00000000,0x00000000,0x00000000}
1234 }
1235 },
1236 { /* version 13 */
1237 { /* version 13, passes 0 */
1238 {0x00000000,0x00000000,0x00001249,0x00001249,
1239 0x00009252,0x00009292,0x00009493,0x00009493},
1240 {0x00000000,0x00000000,0x00001249,0x00009493,
1241 0x0000a493,0x000124db,0x000126dc,0x00009493},
1242 {0x00000000,0x00000000,0x00001249,0x0000a49b,
1243 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
1244 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1245 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
1246 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1247 0x000126dc,0x000136e4,0x0001b725,0x000124db},
1248 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1249 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
1250 {0x00000000,0x00000000,0x00009292,0x000124db,
1251 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
1252 {0x00000000,0x00000000,0x00009492,0x000124db,
1253 0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
1254 {0x00000000,0x00000000,0x00009492,0x000124db,
1255 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
1256 {0x00000000,0x00000000,0x0000a492,0x000124db,
1257 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
1258 {0x00000000,0x00000000,0x0000a492,0x000124db,
1259 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
1260 {0x00000000,0x00000000,0x0000a492,0x000126db,
1261 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1262 {0x00000000,0x00000000,0x0000a492,0x000126db,
1263 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1264 {0x00000000,0x00000000,0x0000a492,0x000126db,
1265 0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
1266 {0x00000000,0x00000000,0x00012492,0x000136db,
1267 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
1268 {0x00000000,0x00000000,0x00000000,0x00000000,
1269 0x00000000,0x00000000,0x00000000,0x00000000}
1270 },
1271 { /* version 13, passes 1 */
1272 {0x00000000,0x00000000,0x00001249,0x00001249,
1273 0x0000124a,0x0000124a,0x00001252,0x00001252},
1274 {0x00000000,0x00000000,0x0000924a,0x00009493,
1275 0x00009492,0x00009292,0x00001252,0x00001252},
1276 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1277 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1278 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1279 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1280 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1281 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1282 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1283 0x000126dc,0x0000a49b,0x00009493,0x00009292},
1284 {0x00000000,0x00000000,0x0000924a,0x000124db,
1285 0x000126dc,0x000124db,0x00009493,0x00009493},
1286 {0x00000000,0x00000000,0x0000924a,0x000124db,
1287 0x000136e4,0x000124db,0x0000a49b,0x00009493},
1288 {0x00000000,0x00000000,0x0000924a,0x000136db,
1289 0x0001b724,0x000124db,0x0000a49b,0x00009493},
1290 {0x00000000,0x00000000,0x0000924a,0x000136db,
1291 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
1292 {0x00000000,0x00000000,0x00009292,0x000136db,
1293 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
1294 {0x00000000,0x00000000,0x00009492,0x000136db,
1295 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
1296 {0x00000000,0x00000000,0x0000a492,0x000136db,
1297 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1298 {0x00000000,0x00000000,0x0000a492,0x000136db,
1299 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1300 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1301 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1302 {0x00000000,0x00000000,0x00000000,0x00000000,
1303 0x00000000,0x00000000,0x00000000,0x00000000}
1304 }
1305 },
1306 { /* version 14 */
1307 { /* version 14, passes 0 */
1308 {0x00000000,0x00000000,0x00001249,0x0000924a,
1309 0x00009292,0x00009493,0x00009493,0x00009493},
1310 {0x00000000,0x00000000,0x00001249,0x0000a49b,
1311 0x0000a493,0x000124db,0x000126dc,0x00009493},
1312 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1313 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
1314 {0x00000000,0x00000000,0x0000924a,0x000124db,
1315 0x000126dc,0x000136e4,0x0001b725,0x000124db},
1316 {0x00000000,0x00000000,0x00009292,0x000124db,
1317 0x000126dc,0x0001b724,0x0001b92d,0x000126dc},
1318 {0x00000000,0x00000000,0x00009492,0x000124db,
1319 0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
1320 {0x00000000,0x00000000,0x00009492,0x000124db,
1321 0x000136e4,0x0001c92d,0x0001c96e,0x000136e4},
1322 {0x00000000,0x00000000,0x00009492,0x000124db,
1323 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1324 {0x00000000,0x00000000,0x0000a492,0x000124db,
1325 0x0001b724,0x0001c92d,0x00024b76,0x0001b925},
1326 {0x00000000,0x00000000,0x0000a492,0x000126db,
1327 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1328 {0x00000000,0x00000000,0x0000a492,0x000126db,
1329 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1330 {0x00000000,0x00000000,0x0000a492,0x000136db,
1331 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
1332 {0x00000000,0x00000000,0x0000a492,0x000136db,
1333 0x0001b924,0x0002496d,0x00024b76,0x00024b77},
1334 {0x00000000,0x00000000,0x0000a492,0x000136db,
1335 0x0001b924,0x00024b6d,0x0002ddb6,0x00025bbf},
1336 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1337 0x00024924,0x0002db6d,0x00036db6,0x0002efff},
1338 {0x00000000,0x00000000,0x00000000,0x00000000,
1339 0x00000000,0x00000000,0x00000000,0x00000000}
1340 },
1341 { /* version 14, passes 1 */
1342 {0x00000000,0x00000000,0x00001249,0x00001249,
1343 0x0000124a,0x0000124a,0x00001252,0x00001252},
1344 {0x00000000,0x00000000,0x0000924a,0x00009493,
1345 0x0000a493,0x00009292,0x00001252,0x00001252},
1346 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1347 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1348 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1349 0x0001249b,0x000136e4,0x00009292,0x00009292},
1350 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1351 0x0001249b,0x000136e4,0x00009292,0x00009292},
1352 {0x00000000,0x00000000,0x0000924a,0x000124db,
1353 0x000136e4,0x000136e4,0x00009493,0x00009292},
1354 {0x00000000,0x00000000,0x00009492,0x000136db,
1355 0x0001b724,0x000136e4,0x00009493,0x00009493},
1356 {0x00000000,0x00000000,0x00009492,0x000136db,
1357 0x0001b724,0x000136e4,0x0000a49b,0x00009493},
1358 {0x00000000,0x00000000,0x00009492,0x000136db,
1359 0x0001b724,0x000136e4,0x0000a49b,0x00009493},
1360 {0x00000000,0x00000000,0x00009492,0x000136db,
1361 0x0001b724,0x000136e4,0x0000a49b,0x0000a49b},
1362 {0x00000000,0x00000000,0x0000a492,0x000136db,
1363 0x0001b724,0x000136e4,0x000124db,0x0000a49b},
1364 {0x00000000,0x00000000,0x0000a492,0x000136db,
1365 0x0001b724,0x000136e4,0x000124db,0x0000a49b},
1366 {0x00000000,0x00000000,0x0000a492,0x000136db,
1367 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1368 {0x00000000,0x00000000,0x0000a492,0x000136db,
1369 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1370 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1371 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1372 {0x00000000,0x00000000,0x00000000,0x00000000,
1373 0x00000000,0x00000000,0x00000000,0x00000000}
1374 }
1375 },
1376 { /* version 15 */
1377 { /* version 15, passes 0 */
1378 {0x00000000,0x00000000,0x00001249,0x00009493,
1379 0x0000a493,0x0000a49b,0x000124db,0x000124db},
1380 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1381 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1382 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1383 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
1384 {0x00000000,0x00000000,0x0000924a,0x000124db,
1385 0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
1386 {0x00000000,0x00000000,0x00009492,0x000124db,
1387 0x000136e4,0x0001b925,0x0001c96e,0x000136e4},
1388 {0x00000000,0x00000000,0x00009492,0x000124db,
1389 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1390 {0x00000000,0x00000000,0x0000a492,0x000124db,
1391 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1392 {0x00000000,0x00000000,0x0000a492,0x000126db,
1393 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
1394 {0x00000000,0x00000000,0x0000a492,0x000126db,
1395 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1396 {0x00000000,0x00000000,0x0000a492,0x000136db,
1397 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1398 {0x00000000,0x00000000,0x0000a492,0x000136db,
1399 0x0001b924,0x0002496d,0x00024b76,0x0002496e},
1400 {0x00000000,0x00000000,0x0000a492,0x000136db,
1401 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
1402 {0x00000000,0x00000000,0x0000a492,0x000136db,
1403 0x0001c924,0x00024b6d,0x00025bb6,0x00024b77},
1404 {0x00000000,0x00000000,0x00012492,0x000136db,
1405 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
1406 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1407 0x00024924,0x0002db6d,0x00036db6,0x0002efff},
1408 {0x00000000,0x00000000,0x00000000,0x00000000,
1409 0x00000000,0x00000000,0x00000000,0x00000000}
1410 },
1411 { /* version 15, passes 1 */
1412 {0x00000000,0x00000000,0x0000924a,0x0000924a,
1413 0x00009292,0x00009292,0x00009292,0x00009292},
1414 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1415 0x0000a493,0x000124db,0x00009292,0x00009292},
1416 {0x00000000,0x00000000,0x0000924a,0x000124db,
1417 0x000124db,0x0001b724,0x00009493,0x00009493},
1418 {0x00000000,0x00000000,0x0000924a,0x000124db,
1419 0x000126dc,0x0001b724,0x00009493,0x00009493},
1420 {0x00000000,0x00000000,0x0000924a,0x000124db,
1421 0x000136e4,0x0001b724,0x0000a49b,0x0000a49b},
1422 {0x00000000,0x00000000,0x00009292,0x000136db,
1423 0x0001b724,0x0001b724,0x0000a49b,0x0000a49b},
1424 {0x00000000,0x00000000,0x00009492,0x000136db,
1425 0x0001c924,0x0001b724,0x000124db,0x000124db},
1426 {0x00000000,0x00000000,0x00009492,0x000136db,
1427 0x0001c924,0x0001b724,0x000124db,0x000124db},
1428 {0x00000000,0x00000000,0x0000a492,0x000136db,
1429 0x0001c924,0x0001b724,0x000126dc,0x000126dc},
1430 {0x00000000,0x00000000,0x0000a492,0x000136db,
1431 0x0001c924,0x0001b925,0x000126dc,0x000126dc},
1432 {0x00000000,0x00000000,0x0000a492,0x000136db,
1433 0x0001c924,0x0001b925,0x000136e4,0x000136e4},
1434 {0x00000000,0x00000000,0x0000a492,0x000136db,
1435 0x0001c924,0x0001b925,0x000136e4,0x000136e4},
1436 {0x00000000,0x00000000,0x0000a492,0x000136db,
1437 0x0001c924,0x0001b925,0x0001b725,0x0001b724},
1438 {0x00000000,0x00000000,0x00012492,0x000136db,
1439 0x0001c924,0x0001b925,0x0001b725,0x0001b724},
1440 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1441 0x00024924,0x0002496d,0x0001b92d,0x0001b925},
1442 {0x00000000,0x00000000,0x00000000,0x00000000,
1443 0x00000000,0x00000000,0x00000000,0x00000000}
1444 }
1445 }
1446};
diff --git a/drivers/usb/media/pwc/pwc-timon.h b/drivers/usb/media/pwc/pwc-timon.h
new file mode 100644
index 000000000000..a86b3782a081
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-timon.h
@@ -0,0 +1,61 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
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
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
26
27/* This tables contains entries for the 675/680/690 (Timon) camera, with
28 4 different qualities (no compression, low, medium, high).
29 It lists the bandwidth requirements for said mode by its alternate interface
30 number. An alternate of 0 means that the mode is unavailable.
31
32 There are 6 * 4 * 4 entries:
33 6 different resolutions subqcif, qsif, qcif, sif, cif, vga
34 6 framerates: 5, 10, 15, 20, 25, 30
35 4 compression modi: none, low, medium, high
36
37 When an uncompressed mode is not available, the next available compressed mode
38 will be chosen (unless the decompressor is absent). Sometimes there are only
39 1 or 2 compressed modes available; in that case entries are duplicated.
40*/
41
42#ifndef PWC_TIMON_H
43#define PWC_TIMON_H
44
45#include "pwc-ioctl.h"
46
47struct Timon_table_entry
48{
49 char alternate; /* USB alternate interface */
50 unsigned short packetsize; /* Normal packet size */
51 unsigned short bandlength; /* Bandlength when decompressing */
52 unsigned char mode[13]; /* precomputed mode settings for cam */
53};
54
55const extern struct Timon_table_entry Timon_table[PSZ_MAX][6][4];
56const extern unsigned int TimonRomTable [16][2][16][8];
57
58
59#endif
60
61
diff --git a/drivers/usb/media/pwc/pwc-uncompress.c b/drivers/usb/media/pwc/pwc-uncompress.c
new file mode 100644
index 000000000000..c062e43b3ac5
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-uncompress.c
@@ -0,0 +1,147 @@
1/* Linux driver for Philips webcam
2 Decompression frontend.
3 (C) 1999-2003 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org)
5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version.
8 Please send bug reports and support requests to <luc@saillard.org>.
9 The decompression routines have been implemented by reverse-engineering the
10 Nemosoft binary pwcx module. Caveat emptor.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25*/
26
27#include <asm/current.h>
28#include <asm/types.h>
29
30#include "pwc.h"
31#include "pwc-uncompress.h"
32#include "pwc-dec1.h"
33#include "pwc-dec23.h"
34
35int pwc_decompress(struct pwc_device *pdev)
36{
37 struct pwc_frame_buf *fbuf;
38 int n, line, col, stride;
39 void *yuv, *image;
40 u16 *src;
41 u16 *dsty, *dstu, *dstv;
42
43 if (pdev == NULL)
44 return -EFAULT;
45#if defined(__KERNEL__) && defined(PWC_MAGIC)
46 if (pdev->magic != PWC_MAGIC) {
47 Err("pwc_decompress(): magic failed.\n");
48 return -EFAULT;
49 }
50#endif
51
52 fbuf = pdev->read_frame;
53 if (fbuf == NULL)
54 return -EFAULT;
55 image = pdev->image_ptr[pdev->fill_image];
56 if (!image)
57 return -EFAULT;
58
59 yuv = fbuf->data + pdev->frame_header_size; /* Skip header */
60
61 /* Raw format; that's easy... */
62 if (pdev->vpalette == VIDEO_PALETTE_RAW)
63 {
64 memcpy(image, yuv, pdev->frame_size);
65 return 0;
66 }
67
68 if (pdev->vbandlength == 0) {
69 /* Uncompressed mode. We copy the data into the output buffer,
70 using the viewport size (which may be larger than the image
71 size). Unfortunately we have to do a bit of byte stuffing
72 to get the desired output format/size.
73 */
74 /*
75 * We do some byte shuffling here to go from the
76 * native format to YUV420P.
77 */
78 src = (u16 *)yuv;
79 n = pdev->view.x * pdev->view.y;
80
81 /* offset in Y plane */
82 stride = pdev->view.x * pdev->offset.y + pdev->offset.x;
83 dsty = (u16 *)(image + stride);
84
85 /* offsets in U/V planes */
86 stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2;
87 dstu = (u16 *)(image + n + stride);
88 dstv = (u16 *)(image + n + n / 4 + stride);
89
90 /* increment after each line */
91 stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */
92
93 for (line = 0; line < pdev->image.y; line++) {
94 for (col = 0; col < pdev->image.x; col += 4) {
95 *dsty++ = *src++;
96 *dsty++ = *src++;
97 if (line & 1)
98 *dstv++ = *src++;
99 else
100 *dstu++ = *src++;
101 }
102 dsty += stride;
103 if (line & 1)
104 dstv += (stride >> 1);
105 else
106 dstu += (stride >> 1);
107 }
108 }
109 else {
110 /* Compressed; the decompressor routines will write the data
111 in planar format immediately.
112 */
113 int flags;
114
115 flags = PWCX_FLAG_PLANAR;
116 if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot)
117 {
118 printk(KERN_ERR "pwc: Mode Bayer is not supported for now\n");
119 flags |= PWCX_FLAG_BAYER;
120 return -ENXIO; /* No such device or address: missing decompressor */
121 }
122
123 switch (pdev->type)
124 {
125 case 675:
126 case 680:
127 case 690:
128 case 720:
129 case 730:
130 case 740:
131 case 750:
132 pwc_dec23_decompress(&pdev->image, &pdev->view, &pdev->offset,
133 yuv, image,
134 flags,
135 pdev->decompress_data, pdev->vbandlength);
136 break;
137 case 645:
138 case 646:
139 /* TODO & FIXME */
140 return -ENXIO; /* No such device or address: missing decompressor */
141 break;
142 }
143 }
144 return 0;
145}
146
147
diff --git a/drivers/usb/media/pwc/pwc-uncompress.h b/drivers/usb/media/pwc/pwc-uncompress.h
new file mode 100644
index 000000000000..d3b9250e4ed3
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-uncompress.h
@@ -0,0 +1,41 @@
1/* (C) 1999-2003 Nemosoft Unv.
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
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
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25/* This file is the bridge between the kernel module and the plugin; it
26 describes the structures and datatypes used in both modules. Any
27 significant change should be reflected by increasing the
28 pwc_decompressor_version major number.
29 */
30#ifndef PWC_UNCOMPRESS_H
31#define PWC_UNCOMPRESS_H
32
33#include <linux/config.h>
34
35#include "pwc-ioctl.h"
36
37/* from pwc-dec.h */
38#define PWCX_FLAG_PLANAR 0x0001
39/* */
40
41#endif
diff --git a/drivers/usb/media/pwc/pwc.h b/drivers/usb/media/pwc/pwc.h
new file mode 100644
index 000000000000..53b516d29cf5
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc.h
@@ -0,0 +1,278 @@
1/* (C) 1999-2003 Nemosoft Unv.
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
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
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25#ifndef PWC_H
26#define PWC_H
27
28#include <linux/version.h>
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/usb.h>
33#include <linux/spinlock.h>
34#include <linux/videodev.h>
35#include <linux/wait.h>
36#include <linux/smp_lock.h>
37#include <asm/semaphore.h>
38#include <asm/errno.h>
39
40#include "pwc-uncompress.h"
41#include "pwc-ioctl.h"
42
43/* Defines and structures for the Philips webcam */
44/* Used for checking memory corruption/pointer validation */
45#define PWC_MAGIC 0x89DC10ABUL
46#undef PWC_MAGIC
47
48/* Turn some debugging options on/off */
49#define PWC_DEBUG 0
50
51/* Trace certain actions in the driver */
52#define TRACE_MODULE 0x0001
53#define TRACE_PROBE 0x0002
54#define TRACE_OPEN 0x0004
55#define TRACE_READ 0x0008
56#define TRACE_MEMORY 0x0010
57#define TRACE_FLOW 0x0020
58#define TRACE_SIZE 0x0040
59#define TRACE_PWCX 0x0080
60#define TRACE_SEQUENCE 0x1000
61
62#define Trace(R, A...) if (pwc_trace & R) printk(KERN_DEBUG PWC_NAME " " A)
63#define Debug(A...) printk(KERN_DEBUG PWC_NAME " " A)
64#define Info(A...) printk(KERN_INFO PWC_NAME " " A)
65#define Err(A...) printk(KERN_ERR PWC_NAME " " A)
66
67
68/* Defines for ToUCam cameras */
69#define TOUCAM_HEADER_SIZE 8
70#define TOUCAM_TRAILER_SIZE 4
71
72#define FEATURE_MOTOR_PANTILT 0x0001
73
74/* Version block */
75#define PWC_MAJOR 9
76#define PWC_MINOR 0
77#define PWC_VERSION "9.0.2-unofficial"
78#define PWC_NAME "pwc"
79
80/* Turn certain features on/off */
81#define PWC_INT_PIPE 0
82
83/* Ignore errors in the first N frames, to allow for startup delays */
84#define FRAME_LOWMARK 5
85
86/* Size and number of buffers for the ISO pipe. */
87#define MAX_ISO_BUFS 2
88#define ISO_FRAMES_PER_DESC 10
89#define ISO_MAX_FRAME_SIZE 960
90#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
91
92/* Frame buffers: contains compressed or uncompressed video data. */
93#define MAX_FRAMES 5
94/* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */
95#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
96
97/* Absolute maximum number of buffers available for mmap() */
98#define MAX_IMAGES 10
99
100/* The following structures were based on cpia.h. Why reinvent the wheel? :-) */
101struct pwc_iso_buf
102{
103 void *data;
104 int length;
105 int read;
106 struct urb *urb;
107};
108
109/* intermediate buffers with raw data from the USB cam */
110struct pwc_frame_buf
111{
112 void *data;
113 volatile int filled; /* number of bytes filled */
114 struct pwc_frame_buf *next; /* list */
115#if PWC_DEBUG
116 int sequence; /* Sequence number */
117#endif
118};
119
120struct pwc_device
121{
122 struct video_device *vdev;
123#ifdef PWC_MAGIC
124 int magic;
125#endif
126 /* Pointer to our usb_device */
127 struct usb_device *udev;
128
129 int type; /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */
130 int release; /* release number */
131 int features; /* feature bits */
132 char serial[30]; /* serial number (string) */
133 int error_status; /* set when something goes wrong with the cam (unplugged, USB errors) */
134 int usb_init; /* set when the cam has been initialized over USB */
135
136 /*** Video data ***/
137 int vopen; /* flag */
138 int vendpoint; /* video isoc endpoint */
139 int vcinterface; /* video control interface */
140 int valternate; /* alternate interface needed */
141 int vframes, vsize; /* frames-per-second & size (see PSZ_*) */
142 int vpalette; /* palette: 420P, RAW or RGBBAYER */
143 int vframe_count; /* received frames */
144 int vframes_dumped; /* counter for dumped frames */
145 int vframes_error; /* frames received in error */
146 int vmax_packet_size; /* USB maxpacket size */
147 int vlast_packet_size; /* for frame synchronisation */
148 int visoc_errors; /* number of contiguous ISOC errors */
149 int vcompression; /* desired compression factor */
150 int vbandlength; /* compressed band length; 0 is uncompressed */
151 char vsnapshot; /* snapshot mode */
152 char vsync; /* used by isoc handler */
153 char vmirror; /* for ToUCaM series */
154
155 int cmd_len;
156 unsigned char cmd_buf[13];
157
158 /* The image acquisition requires 3 to 4 steps:
159 1. data is gathered in short packets from the USB controller
160 2. data is synchronized and packed into a frame buffer
161 3a. in case data is compressed, decompress it directly into image buffer
162 3b. in case data is uncompressed, copy into image buffer with viewport
163 4. data is transferred to the user process
164
165 Note that MAX_ISO_BUFS != MAX_FRAMES != MAX_IMAGES....
166 We have in effect a back-to-back-double-buffer system.
167 */
168 /* 1: isoc */
169 struct pwc_iso_buf sbuf[MAX_ISO_BUFS];
170 char iso_init;
171
172 /* 2: frame */
173 struct pwc_frame_buf *fbuf; /* all frames */
174 struct pwc_frame_buf *empty_frames, *empty_frames_tail; /* all empty frames */
175 struct pwc_frame_buf *full_frames, *full_frames_tail; /* all filled frames */
176 struct pwc_frame_buf *fill_frame; /* frame currently being filled */
177 struct pwc_frame_buf *read_frame; /* frame currently read by user process */
178 int frame_header_size, frame_trailer_size;
179 int frame_size;
180 int frame_total_size; /* including header & trailer */
181 int drop_frames;
182#if PWC_DEBUG
183 int sequence; /* Debugging aid */
184#endif
185
186 /* 3: decompression */
187 struct pwc_decompressor *decompressor; /* function block with decompression routines */
188 void *decompress_data; /* private data for decompression engine */
189
190 /* 4: image */
191 /* We have an 'image' and a 'view', where 'image' is the fixed-size image
192 as delivered by the camera, and 'view' is the size requested by the
193 program. The camera image is centered in this viewport, laced with
194 a gray or black border. view_min <= image <= view <= view_max;
195 */
196 int image_mask; /* bitmask of supported sizes */
197 struct pwc_coord view_min, view_max; /* minimum and maximum viewable sizes */
198 struct pwc_coord abs_max; /* maximum supported size with compression */
199 struct pwc_coord image, view; /* image and viewport size */
200 struct pwc_coord offset; /* offset within the viewport */
201
202 void *image_data; /* total buffer, which is subdivided into ... */
203 void *image_ptr[MAX_IMAGES]; /* ...several images... */
204 int fill_image; /* ...which are rotated. */
205 int len_per_image; /* length per image */
206 int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */
207 int image_used[MAX_IMAGES]; /* For MCAPTURE and SYNC */
208
209 struct semaphore modlock; /* to prevent races in video_open(), etc */
210 spinlock_t ptrlock; /* for manipulating the buffer pointers */
211
212 /*** motorized pan/tilt feature */
213 struct pwc_mpt_range angle_range;
214 int pan_angle; /* in degrees * 100 */
215 int tilt_angle; /* absolute angle; 0,0 is home position */
216
217 /*** Misc. data ***/
218 wait_queue_head_t frameq; /* When waiting for a frame to finish... */
219#if PWC_INT_PIPE
220 void *usb_int_handler; /* for the interrupt endpoint */
221#endif
222};
223
224
225#ifdef __cplusplus
226extern "C" {
227#endif
228
229/* Global variables */
230extern int pwc_trace;
231extern int pwc_preferred_compression;
232
233/** functions in pwc-if.c */
234int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot);
235
236/** Functions in pwc-misc.c */
237/* sizes in pixels */
238extern struct pwc_coord pwc_image_sizes[PSZ_MAX];
239
240int pwc_decode_size(struct pwc_device *pdev, int width, int height);
241void pwc_construct(struct pwc_device *pdev);
242
243/** Functions in pwc-ctrl.c */
244/* Request a certain video mode. Returns < 0 if not possible */
245extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot);
246/* Calculate the number of bytes per image (not frame) */
247extern void pwc_set_image_buffer_size(struct pwc_device *pdev);
248
249/* Various controls; should be obvious. Value 0..65535, or < 0 on error */
250extern int pwc_get_brightness(struct pwc_device *pdev);
251extern int pwc_set_brightness(struct pwc_device *pdev, int value);
252extern int pwc_get_contrast(struct pwc_device *pdev);
253extern int pwc_set_contrast(struct pwc_device *pdev, int value);
254extern int pwc_get_gamma(struct pwc_device *pdev);
255extern int pwc_set_gamma(struct pwc_device *pdev, int value);
256extern int pwc_get_saturation(struct pwc_device *pdev);
257extern int pwc_set_saturation(struct pwc_device *pdev, int value);
258extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
259extern int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value);
260extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);
261
262/* Power down or up the camera; not supported by all models */
263extern int pwc_camera_power(struct pwc_device *pdev, int power);
264
265/* Private ioctl()s; see pwc-ioctl.h */
266extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg);
267
268
269/** pwc-uncompress.c */
270/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */
271extern int pwc_decompress(struct pwc_device *pdev);
272
273#ifdef __cplusplus
274}
275#endif
276
277
278#endif
diff --git a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c
new file mode 100644
index 000000000000..685bdae5cb62
--- /dev/null
+++ b/drivers/usb/media/se401.c
@@ -0,0 +1,1436 @@
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
28static const char version[] = "0.24";
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/vmalloc.h>
34#include <linux/slab.h>
35#include <linux/pagemap.h>
36#include <linux/usb.h>
37#include "se401.h"
38
39static int flickerless=0;
40static int video_nr = -1;
41
42static struct usb_device_id device_table [] = {
43 { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
44 { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
45 { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
46 { USB_DEVICE(0x047d, 0x5002) },/* Kensington 6701(5/7) */
47 { USB_DEVICE(0x047d, 0x5003) },/* Kensington 67016 */
48 { }
49};
50
51MODULE_DEVICE_TABLE(usb, device_table);
52
53MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
54MODULE_DESCRIPTION("SE401 USB Camera Driver");
55MODULE_LICENSE("GPL");
56module_param(flickerless, int, 0);
57MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)");
58module_param(video_nr, int, 0);
59
60static struct usb_driver se401_driver;
61
62
63/**********************************************************************
64 *
65 * Memory management
66 *
67 **********************************************************************/
68static 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
89static 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
113static 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
129static 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
149static 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
177static int se401_send_pict(struct usb_se401 *se401)
178{
179 se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);/* integration time low */
180 se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);/* integration time mid */
181 se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);/* integration time mid */
182 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);/* reset level value */
183 se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);/* red color gain */
184 se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);/* green color gain */
185 se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);/* blue color gain */
186
187 return 0;
188}
189
190static void se401_set_exposure(struct usb_se401 *se401, int brightness)
191{
192 int integration=brightness<<5;
193
194 if (flickerless==50) {
195 integration=integration-integration%106667;
196 }
197 if (flickerless==60) {
198 integration=integration-integration%88889;
199 }
200 se401->brightness=integration>>5;
201 se401->expose_h=(integration>>16)&0xff;
202 se401->expose_m=(integration>>8)&0xff;
203 se401->expose_l=integration&0xff;
204}
205
206static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
207{
208 p->brightness=se401->brightness;
209 if (se401->enhance) {
210 p->whiteness=32768;
211 } else {
212 p->whiteness=0;
213 }
214 p->colour=65535;
215 p->contrast=65535;
216 p->hue=se401->rgain<<10;
217 p->palette=se401->palette;
218 p->depth=3; /* rgb24 */
219 return 0;
220}
221
222
223static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
224{
225 if (p->palette != VIDEO_PALETTE_RGB24)
226 return 1;
227 se401->palette=p->palette;
228 if (p->hue!=se401->hue) {
229 se401->rgain= p->hue>>10;
230 se401->bgain= 0x40-(p->hue>>10);
231 se401->hue=p->hue;
232 }
233 if (p->brightness!=se401->brightness) {
234 se401_set_exposure(se401, p->brightness);
235 }
236 if (p->whiteness>=32768) {
237 se401->enhance=1;
238 } else {
239 se401->enhance=0;
240 }
241 se401_send_pict(se401);
242 se401_send_pict(se401);
243 return 0;
244}
245
246/*
247 Hyundai have some really nice docs about this and other sensor related
248 stuff on their homepage: www.hei.co.kr
249*/
250static void se401_auto_resetlevel(struct usb_se401 *se401)
251{
252 unsigned int ahrc, alrc;
253 int oldreset=se401->resetlevel;
254
255 /* For some reason this normally read-only register doesn't get reset
256 to zero after reading them just once...
257 */
258 se401_get_feature(se401, HV7131_REG_HIREFNOH);
259 se401_get_feature(se401, HV7131_REG_HIREFNOL);
260 se401_get_feature(se401, HV7131_REG_LOREFNOH);
261 se401_get_feature(se401, HV7131_REG_LOREFNOL);
262 ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) +
263 se401_get_feature(se401, HV7131_REG_HIREFNOL);
264 alrc=256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
265 se401_get_feature(se401, HV7131_REG_LOREFNOL);
266
267 /* Not an exact science, but it seems to work pretty well... */
268 if (alrc > 10) {
269 while (alrc>=10 && se401->resetlevel < 63) {
270 se401->resetlevel++;
271 alrc /=2;
272 }
273 } else if (ahrc > 20) {
274 while (ahrc>=20 && se401->resetlevel > 0) {
275 se401->resetlevel--;
276 ahrc /=2;
277 }
278 }
279 if (se401->resetlevel!=oldreset)
280 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
281
282 return;
283}
284
285/* irq handler for snapshot button */
286static void se401_button_irq(struct urb *urb, struct pt_regs *regs)
287{
288 struct usb_se401 *se401 = urb->context;
289 int status;
290
291 if (!se401->dev) {
292 info("ohoh: device vapourished");
293 return;
294 }
295
296 switch (urb->status) {
297 case 0:
298 /* success */
299 break;
300 case -ECONNRESET:
301 case -ENOENT:
302 case -ESHUTDOWN:
303 /* this urb is terminated, clean up */
304 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
305 return;
306 default:
307 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
308 goto exit;
309 }
310
311 if (urb->actual_length >=2) {
312 if (se401->button)
313 se401->buttonpressed=1;
314 }
315exit:
316 status = usb_submit_urb (urb, GFP_ATOMIC);
317 if (status)
318 err ("%s - usb_submit_urb failed with result %d",
319 __FUNCTION__, status);
320}
321
322static void se401_video_irq(struct urb *urb, struct pt_regs *regs)
323{
324 struct usb_se401 *se401 = urb->context;
325 int length = urb->actual_length;
326
327 /* ohoh... */
328 if (!se401->streaming)
329 return;
330
331 if (!se401->dev) {
332 info ("ohoh: device vapourished");
333 return;
334 }
335
336 /* 0 sized packets happen if we are to fast, but sometimes the camera
337 keeps sending them forever...
338 */
339 if (length && !urb->status) {
340 se401->nullpackets=0;
341 switch(se401->scratch[se401->scratch_next].state) {
342 case BUFFER_READY:
343 case BUFFER_BUSY: {
344 se401->dropped++;
345 break;
346 }
347 case BUFFER_UNUSED: {
348 memcpy(se401->scratch[se401->scratch_next].data, (unsigned char *)urb->transfer_buffer, length);
349 se401->scratch[se401->scratch_next].state=BUFFER_READY;
350 se401->scratch[se401->scratch_next].offset=se401->bayeroffset;
351 se401->scratch[se401->scratch_next].length=length;
352 if (waitqueue_active(&se401->wq)) {
353 wake_up_interruptible(&se401->wq);
354 }
355 se401->scratch_overflow=0;
356 se401->scratch_next++;
357 if (se401->scratch_next>=SE401_NUMSCRATCH)
358 se401->scratch_next=0;
359 break;
360 }
361 }
362 se401->bayeroffset+=length;
363 if (se401->bayeroffset>=se401->cheight*se401->cwidth) {
364 se401->bayeroffset=0;
365 }
366 } else {
367 se401->nullpackets++;
368 if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
369 if (waitqueue_active(&se401->wq)) {
370 wake_up_interruptible(&se401->wq);
371 }
372 }
373 }
374
375 /* Resubmit urb for new data */
376 urb->status=0;
377 urb->dev=se401->dev;
378 if(usb_submit_urb(urb, GFP_KERNEL))
379 info("urb burned down");
380 return;
381}
382
383static void se401_send_size(struct usb_se401 *se401, int width, int height)
384{
385 int i=0;
386 int mode=0x03; /* No compression */
387 int sendheight=height;
388 int sendwidth=width;
389
390 /* JangGu compression can only be used with the camera supported sizes,
391 but bayer seems to work with any size that fits on the sensor.
392 We check if we can use compression with the current size with either
393 4 or 16 times subcapturing, if not we use uncompressed bayer data
394 but this will result in cutouts of the maximum size....
395 */
396 while (i<se401->sizes && !(se401->width[i]==width && se401->height[i]==height))
397 i++;
398 while (i<se401->sizes) {
399 if (se401->width[i]==width*2 && se401->height[i]==height*2) {
400 sendheight=se401->height[i];
401 sendwidth=se401->width[i];
402 mode=0x40;
403 }
404 if (se401->width[i]==width*4 && se401->height[i]==height*4) {
405 sendheight=se401->height[i];
406 sendwidth=se401->width[i];
407 mode=0x42;
408 }
409 i++;
410 }
411
412 se401_sndctrl(1, se401, SE401_REQ_SET_WIDTH, sendwidth, NULL, 0);
413 se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0);
414 se401_set_feature(se401, SE401_OPERATINGMODE, mode);
415
416 if (mode==0x03) {
417 se401->format=FMT_BAYER;
418 } else {
419 se401->format=FMT_JANGGU;
420 }
421
422 return;
423}
424
425/*
426 In this function se401_send_pict is called several times,
427 for some reason (depending on the state of the sensor and the phase of
428 the moon :) doing this only in either place doesn't always work...
429*/
430static int se401_start_stream(struct usb_se401 *se401)
431{
432 struct urb *urb;
433 int err=0, i;
434 se401->streaming=1;
435
436 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
437 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
438
439 /* Set picture settings */
440 se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */
441 se401_send_pict(se401);
442
443 se401_send_size(se401, se401->cwidth, se401->cheight);
444
445 se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, NULL, 0);
446
447 /* Do some memory allocation */
448 for (i=0; i<SE401_NUMFRAMES; i++) {
449 se401->frame[i].data=se401->fbuf + i * se401->maxframesize;
450 se401->frame[i].curpix=0;
451 }
452 for (i=0; i<SE401_NUMSBUF; i++) {
453 se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
454 }
455
456 se401->bayeroffset=0;
457 se401->scratch_next=0;
458 se401->scratch_use=0;
459 se401->scratch_overflow=0;
460 for (i=0; i<SE401_NUMSCRATCH; i++) {
461 se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
462 se401->scratch[i].state=BUFFER_UNUSED;
463 }
464
465 for (i=0; i<SE401_NUMSBUF; i++) {
466 urb=usb_alloc_urb(0, GFP_KERNEL);
467 if(!urb)
468 return -ENOMEM;
469
470 usb_fill_bulk_urb(urb, se401->dev,
471 usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
472 se401->sbuf[i].data, SE401_PACKETSIZE,
473 se401_video_irq,
474 se401);
475
476 se401->urb[i]=urb;
477
478 err=usb_submit_urb(se401->urb[i], GFP_KERNEL);
479 if(err)
480 err("urb burned down");
481 }
482
483 se401->framecount=0;
484
485 return 0;
486}
487
488static int se401_stop_stream(struct usb_se401 *se401)
489{
490 int i;
491
492 if (!se401->streaming || !se401->dev)
493 return 1;
494
495 se401->streaming=0;
496
497 se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);
498
499 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
500 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
501
502 for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
503 usb_kill_urb(se401->urb[i]);
504 usb_free_urb(se401->urb[i]);
505 se401->urb[i]=NULL;
506 kfree(se401->sbuf[i].data);
507 }
508 for (i=0; i<SE401_NUMSCRATCH; i++) {
509 kfree(se401->scratch[i].data);
510 se401->scratch[i].data=NULL;
511 }
512
513 return 0;
514}
515
516static int se401_set_size(struct usb_se401 *se401, int width, int height)
517{
518 int wasstreaming=se401->streaming;
519 /* Check to see if we need to change */
520 if (se401->cwidth==width && se401->cheight==height)
521 return 0;
522
523 /* Check for a valid mode */
524 if (!width || !height)
525 return 1;
526 if ((width & 1) || (height & 1))
527 return 1;
528 if (width>se401->width[se401->sizes-1])
529 return 1;
530 if (height>se401->height[se401->sizes-1])
531 return 1;
532
533 /* Stop a current stream and start it again at the new size */
534 if (wasstreaming)
535 se401_stop_stream(se401);
536 se401->cwidth=width;
537 se401->cheight=height;
538 if (wasstreaming)
539 se401_start_stream(se401);
540 return 0;
541}
542
543
544/****************************************************************************
545 *
546 * Video Decoding
547 *
548 ***************************************************************************/
549
550/*
551 This shouldn't really be done in a v4l driver....
552 But it does make the image look a lot more usable.
553 Basically it lifts the dark pixels more than the light pixels.
554*/
555static inline void enhance_picture(unsigned char *frame, int len)
556{
557 while (len--) {
558 *frame=(((*frame^255)*(*frame^255))/255)^255;
559 frame++;
560 }
561}
562
563static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
564{
565 struct se401_frame *frame=&se401->frame[se401->curframe];
566 int linelength=se401->cwidth*3;
567
568 if (frame->curlinepix >= linelength) {
569 frame->curlinepix=0;
570 frame->curline+=linelength;
571 }
572
573 /* First three are absolute, all others relative.
574 * Format is rgb from right to left (mirrorred image),
575 * we flip it to get bgr from left to right. */
576 if (frame->curlinepix < 3) {
577 *(frame->curline-frame->curlinepix)=1+data*4;
578 } else {
579 *(frame->curline-frame->curlinepix)=
580 *(frame->curline-frame->curlinepix+3)+data*4;
581 }
582 frame->curlinepix++;
583}
584
585static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *data, int bit_exp, int packetlength)
586{
587 int pos=0;
588 int vlc_cod=0;
589 int vlc_size=0;
590 int vlc_data=0;
591 int bit_cur;
592 int bit;
593 data+=4;
594 while (pos < packetlength) {
595 bit_cur=8;
596 while (bit_cur && bit_exp) {
597 bit=((*data)>>(bit_cur-1))&1;
598 if (!vlc_cod) {
599 if (bit) {
600 vlc_size++;
601 } else {
602 if (!vlc_size) {
603 decode_JangGu_integrate(se401, 0);
604 } else {
605 vlc_cod=2;
606 vlc_data=0;
607 }
608 }
609 } else {
610 if (vlc_cod==2) {
611 if (!bit)
612 vlc_data = -(1<<vlc_size) + 1;
613 vlc_cod--;
614 }
615 vlc_size--;
616 vlc_data+=bit<<vlc_size;
617 if (!vlc_size) {
618 decode_JangGu_integrate(se401, vlc_data);
619 vlc_cod=0;
620 }
621 }
622 bit_cur--;
623 bit_exp--;
624 }
625 pos++;
626 data++;
627 }
628}
629
630static inline void decode_JangGu (struct usb_se401 *se401, struct se401_scratch *buffer)
631{
632 unsigned char *data=buffer->data;
633 int len=buffer->length;
634 int bit_exp=0, pix_exp=0, frameinfo=0, packetlength=0, size;
635 int datapos=0;
636
637 /* New image? */
638 if (!se401->frame[se401->curframe].curpix) {
639 se401->frame[se401->curframe].curlinepix=0;
640 se401->frame[se401->curframe].curline=
641 se401->frame[se401->curframe].data+
642 se401->cwidth*3-1;
643 if (se401->frame[se401->curframe].grabstate==FRAME_READY)
644 se401->frame[se401->curframe].grabstate=FRAME_GRABBING;
645 se401->vlcdatapos=0;
646 }
647 while (datapos < len) {
648 size=1024-se401->vlcdatapos;
649 if (size+datapos > len)
650 size=len-datapos;
651 memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
652 se401->vlcdatapos+=size;
653 packetlength=0;
654 if (se401->vlcdatapos >= 4) {
655 bit_exp=se401->vlcdata[3]+(se401->vlcdata[2]<<8);
656 pix_exp=se401->vlcdata[1]+((se401->vlcdata[0]&0x3f)<<8);
657 frameinfo=se401->vlcdata[0]&0xc0;
658 packetlength=((bit_exp+47)>>4)<<1;
659 if (packetlength > 1024) {
660 se401->vlcdatapos=0;
661 datapos=len;
662 packetlength=0;
663 se401->error++;
664 se401->frame[se401->curframe].curpix=0;
665 }
666 }
667 if (packetlength && se401->vlcdatapos >= packetlength) {
668 decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, packetlength);
669 se401->frame[se401->curframe].curpix+=pix_exp*3;
670 datapos+=size-(se401->vlcdatapos-packetlength);
671 se401->vlcdatapos=0;
672 if (se401->frame[se401->curframe].curpix>=se401->cwidth*se401->cheight*3) {
673 if (se401->frame[se401->curframe].curpix==se401->cwidth*se401->cheight*3) {
674 if (se401->frame[se401->curframe].grabstate==FRAME_GRABBING) {
675 se401->frame[se401->curframe].grabstate=FRAME_DONE;
676 se401->framecount++;
677 se401->readcount++;
678 }
679 if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
680 se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
681 }
682 } else {
683 se401->error++;
684 }
685 se401->frame[se401->curframe].curpix=0;
686 datapos=len;
687 }
688 } else {
689 datapos+=size;
690 }
691 }
692}
693
694static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *buffer)
695{
696 unsigned char *data=buffer->data;
697 int len=buffer->length;
698 int offset=buffer->offset;
699 int datasize=se401->cwidth*se401->cheight;
700 struct se401_frame *frame=&se401->frame[se401->curframe];
701
702 unsigned char *framedata=frame->data, *curline, *nextline;
703 int width=se401->cwidth;
704 int blineoffset=0, bline;
705 int linelength=width*3, i;
706
707
708 if (frame->curpix==0) {
709 if (frame->grabstate==FRAME_READY) {
710 frame->grabstate=FRAME_GRABBING;
711 }
712 frame->curline=framedata+linelength;
713 frame->curlinepix=0;
714 }
715
716 if (offset!=frame->curpix) {
717 /* Regard frame as lost :( */
718 frame->curpix=0;
719 se401->error++;
720 return;
721 }
722
723 /* Check if we have to much data */
724 if (frame->curpix+len > datasize) {
725 len=datasize-frame->curpix;
726 }
727 if (se401->cheight%4)
728 blineoffset=1;
729 bline=frame->curpix/se401->cwidth+blineoffset;
730
731 curline=frame->curline;
732 nextline=curline+linelength;
733 if (nextline >= framedata+datasize*3)
734 nextline=curline;
735 while (len) {
736 if (frame->curlinepix>=width) {
737 frame->curlinepix-=width;
738 bline=frame->curpix/width+blineoffset;
739 curline+=linelength*2;
740 nextline+=linelength*2;
741 if (curline >= framedata+datasize*3) {
742 frame->curlinepix++;
743 curline-=3;
744 nextline-=3;
745 len--;
746 data++;
747 frame->curpix++;
748 }
749 if (nextline >= framedata+datasize*3)
750 nextline=curline;
751 }
752 if ((bline&1)) {
753 if ((frame->curlinepix&1)) {
754 *(curline+2)=*data;
755 *(curline-1)=*data;
756 *(nextline+2)=*data;
757 *(nextline-1)=*data;
758 } else {
759 *(curline+1)=
760 (*(curline+1)+*data)/2;
761 *(curline-2)=
762 (*(curline-2)+*data)/2;
763 *(nextline+1)=*data;
764 *(nextline-2)=*data;
765 }
766 } else {
767 if ((frame->curlinepix&1)) {
768 *(curline+1)=
769 (*(curline+1)+*data)/2;
770 *(curline-2)=
771 (*(curline-2)+*data)/2;
772 *(nextline+1)=*data;
773 *(nextline-2)=*data;
774 } else {
775 *curline=*data;
776 *(curline-3)=*data;
777 *nextline=*data;
778 *(nextline-3)=*data;
779 }
780 }
781 frame->curlinepix++;
782 curline-=3;
783 nextline-=3;
784 len--;
785 data++;
786 frame->curpix++;
787 }
788 frame->curline=curline;
789
790 if (frame->curpix>=datasize) {
791 /* Fix the top line */
792 framedata+=linelength;
793 for (i=0; i<linelength; i++) {
794 framedata--;
795 *framedata=*(framedata+linelength);
796 }
797 /* Fix the left side (green is already present) */
798 for (i=0; i<se401->cheight; i++) {
799 *framedata=*(framedata+3);
800 *(framedata+1)=*(framedata+4);
801 *(framedata+2)=*(framedata+5);
802 framedata+=linelength;
803 }
804 frame->curpix=0;
805 frame->grabstate=FRAME_DONE;
806 se401->framecount++;
807 se401->readcount++;
808 if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
809 se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
810 }
811 }
812}
813
814static int se401_newframe(struct usb_se401 *se401, int framenr)
815{
816 DECLARE_WAITQUEUE(wait, current);
817 int errors=0;
818
819 while (se401->streaming &&
820 (se401->frame[framenr].grabstate==FRAME_READY ||
821 se401->frame[framenr].grabstate==FRAME_GRABBING) ) {
822 if(!se401->frame[framenr].curpix) {
823 errors++;
824 }
825 wait_interruptible(
826 se401->scratch[se401->scratch_use].state!=BUFFER_READY,
827 &se401->wq,
828 &wait
829 );
830 if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
831 se401->nullpackets=0;
832 info("to many null length packets, restarting capture");
833 se401_stop_stream(se401);
834 se401_start_stream(se401);
835 } else {
836 if (se401->scratch[se401->scratch_use].state!=BUFFER_READY) {
837 se401->frame[framenr].grabstate=FRAME_ERROR;
838 return -EIO;
839 }
840 se401->scratch[se401->scratch_use].state=BUFFER_BUSY;
841 if (se401->format==FMT_JANGGU) {
842 decode_JangGu(se401, &se401->scratch[se401->scratch_use]);
843 } else {
844 decode_bayer(se401, &se401->scratch[se401->scratch_use]);
845 }
846 se401->scratch[se401->scratch_use].state=BUFFER_UNUSED;
847 se401->scratch_use++;
848 if (se401->scratch_use>=SE401_NUMSCRATCH)
849 se401->scratch_use=0;
850 if (errors > SE401_MAX_ERRORS) {
851 errors=0;
852 info("to much errors, restarting capture");
853 se401_stop_stream(se401);
854 se401_start_stream(se401);
855 }
856 }
857 }
858
859 if (se401->frame[framenr].grabstate==FRAME_DONE)
860 if (se401->enhance)
861 enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3);
862 return 0;
863}
864
865static void usb_se401_remove_disconnected (struct usb_se401 *se401)
866{
867 int i;
868
869 se401->dev = NULL;
870
871 for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
872 usb_kill_urb(se401->urb[i]);
873 usb_free_urb(se401->urb[i]);
874 se401->urb[i] = NULL;
875 kfree(se401->sbuf[i].data);
876 }
877 for (i=0; i<SE401_NUMSCRATCH; i++) if (se401->scratch[i].data) {
878 kfree(se401->scratch[i].data);
879 }
880 if (se401->inturb) {
881 usb_kill_urb(se401->inturb);
882 usb_free_urb(se401->inturb);
883 }
884 info("%s disconnected", se401->camera_name);
885
886 /* Free the memory */
887 kfree(se401->width);
888 kfree(se401->height);
889 kfree(se401);
890}
891
892
893
894/****************************************************************************
895 *
896 * Video4Linux
897 *
898 ***************************************************************************/
899
900
901static int se401_open(struct inode *inode, struct file *file)
902{
903 struct video_device *dev = video_devdata(file);
904 struct usb_se401 *se401 = (struct usb_se401 *)dev;
905 int err = 0;
906
907 if (se401->user)
908 return -EBUSY;
909 se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
910 if (se401->fbuf)
911 file->private_data = dev;
912 else
913 err = -ENOMEM;
914 se401->user = !err;
915
916 return err;
917}
918
919static int se401_close(struct inode *inode, struct file *file)
920{
921 struct video_device *dev = file->private_data;
922 struct usb_se401 *se401 = (struct usb_se401 *)dev;
923 int i;
924
925 rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
926 if (se401->removed) {
927 usb_se401_remove_disconnected(se401);
928 info("device unregistered");
929 } else {
930 for (i=0; i<SE401_NUMFRAMES; i++)
931 se401->frame[i].grabstate=FRAME_UNUSED;
932 if (se401->streaming)
933 se401_stop_stream(se401);
934 se401->user=0;
935 }
936 file->private_data = NULL;
937 return 0;
938}
939
940static int se401_do_ioctl(struct inode *inode, struct file *file,
941 unsigned int cmd, void *arg)
942{
943 struct video_device *vdev = file->private_data;
944 struct usb_se401 *se401 = (struct usb_se401 *)vdev;
945
946 if (!se401->dev)
947 return -EIO;
948
949 switch (cmd) {
950 case VIDIOCGCAP:
951 {
952 struct video_capability *b = arg;
953 strcpy(b->name, se401->camera_name);
954 b->type = VID_TYPE_CAPTURE;
955 b->channels = 1;
956 b->audios = 0;
957 b->maxwidth = se401->width[se401->sizes-1];
958 b->maxheight = se401->height[se401->sizes-1];
959 b->minwidth = se401->width[0];
960 b->minheight = se401->height[0];
961 return 0;
962 }
963 case VIDIOCGCHAN:
964 {
965 struct video_channel *v = arg;
966
967 if (v->channel != 0)
968 return -EINVAL;
969 v->flags = 0;
970 v->tuners = 0;
971 v->type = VIDEO_TYPE_CAMERA;
972 strcpy(v->name, "Camera");
973 return 0;
974 }
975 case VIDIOCSCHAN:
976 {
977 struct video_channel *v = arg;
978
979 if (v->channel != 0)
980 return -EINVAL;
981 return 0;
982 }
983 case VIDIOCGPICT:
984 {
985 struct video_picture *p = arg;
986
987 se401_get_pict(se401, p);
988 return 0;
989 }
990 case VIDIOCSPICT:
991 {
992 struct video_picture *p = arg;
993
994 if (se401_set_pict(se401, p))
995 return -EINVAL;
996 return 0;
997 }
998 case VIDIOCSWIN:
999 {
1000 struct video_window *vw = arg;
1001
1002 if (vw->flags)
1003 return -EINVAL;
1004 if (vw->clipcount)
1005 return -EINVAL;
1006 if (se401_set_size(se401, vw->width, vw->height))
1007 return -EINVAL;
1008 return 0;
1009 }
1010 case VIDIOCGWIN:
1011 {
1012 struct video_window *vw = arg;
1013
1014 vw->x = 0; /* FIXME */
1015 vw->y = 0;
1016 vw->chromakey = 0;
1017 vw->flags = 0;
1018 vw->clipcount = 0;
1019 vw->width = se401->cwidth;
1020 vw->height = se401->cheight;
1021 return 0;
1022 }
1023 case VIDIOCGMBUF:
1024 {
1025 struct video_mbuf *vm = arg;
1026 int i;
1027
1028 memset(vm, 0, sizeof(*vm));
1029 vm->size = SE401_NUMFRAMES * se401->maxframesize;
1030 vm->frames = SE401_NUMFRAMES;
1031 for (i=0; i<SE401_NUMFRAMES; i++)
1032 vm->offsets[i] = se401->maxframesize * i;
1033 return 0;
1034 }
1035 case VIDIOCMCAPTURE:
1036 {
1037 struct video_mmap *vm = arg;
1038
1039 if (vm->format != VIDEO_PALETTE_RGB24)
1040 return -EINVAL;
1041 if (vm->frame >= SE401_NUMFRAMES)
1042 return -EINVAL;
1043 if (se401->frame[vm->frame].grabstate != FRAME_UNUSED)
1044 return -EBUSY;
1045
1046 /* Is this according to the v4l spec??? */
1047 if (se401_set_size(se401, vm->width, vm->height))
1048 return -EINVAL;
1049 se401->frame[vm->frame].grabstate=FRAME_READY;
1050
1051 if (!se401->streaming)
1052 se401_start_stream(se401);
1053
1054 /* Set the picture properties */
1055 if (se401->framecount==0)
1056 se401_send_pict(se401);
1057 /* Calibrate the reset level after a few frames. */
1058 if (se401->framecount%20==1)
1059 se401_auto_resetlevel(se401);
1060
1061 return 0;
1062 }
1063 case VIDIOCSYNC:
1064 {
1065 int *frame = arg;
1066 int ret=0;
1067
1068 if(*frame <0 || *frame >= SE401_NUMFRAMES)
1069 return -EINVAL;
1070
1071 ret=se401_newframe(se401, *frame);
1072 se401->frame[*frame].grabstate=FRAME_UNUSED;
1073 return ret;
1074 }
1075 case VIDIOCGFBUF:
1076 {
1077 struct video_buffer *vb = arg;
1078
1079 memset(vb, 0, sizeof(*vb));
1080 return 0;
1081 }
1082 case VIDIOCKEY:
1083 return 0;
1084 case VIDIOCCAPTURE:
1085 return -EINVAL;
1086 case VIDIOCSFBUF:
1087 return -EINVAL;
1088 case VIDIOCGTUNER:
1089 case VIDIOCSTUNER:
1090 return -EINVAL;
1091 case VIDIOCGFREQ:
1092 case VIDIOCSFREQ:
1093 return -EINVAL;
1094 case VIDIOCGAUDIO:
1095 case VIDIOCSAUDIO:
1096 return -EINVAL;
1097 default:
1098 return -ENOIOCTLCMD;
1099 } /* end switch */
1100
1101 return 0;
1102}
1103
1104static int se401_ioctl(struct inode *inode, struct file *file,
1105 unsigned int cmd, unsigned long arg)
1106{
1107 return video_usercopy(inode, file, cmd, arg, se401_do_ioctl);
1108}
1109
1110static ssize_t se401_read(struct file *file, char __user *buf,
1111 size_t count, loff_t *ppos)
1112{
1113 int realcount=count, ret=0;
1114 struct video_device *dev = file->private_data;
1115 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1116
1117
1118 if (se401->dev == NULL)
1119 return -EIO;
1120 if (realcount > se401->cwidth*se401->cheight*3)
1121 realcount=se401->cwidth*se401->cheight*3;
1122
1123 /* Shouldn't happen: */
1124 if (se401->frame[0].grabstate==FRAME_GRABBING)
1125 return -EBUSY;
1126 se401->frame[0].grabstate=FRAME_READY;
1127 se401->frame[1].grabstate=FRAME_UNUSED;
1128 se401->curframe=0;
1129
1130 if (!se401->streaming)
1131 se401_start_stream(se401);
1132
1133 /* Set the picture properties */
1134 if (se401->framecount==0)
1135 se401_send_pict(se401);
1136 /* Calibrate the reset level after a few frames. */
1137 if (se401->framecount%20==1)
1138 se401_auto_resetlevel(se401);
1139
1140 ret=se401_newframe(se401, 0);
1141
1142 se401->frame[0].grabstate=FRAME_UNUSED;
1143 if (ret)
1144 return ret;
1145 if (copy_to_user(buf, se401->frame[0].data, realcount))
1146 return -EFAULT;
1147
1148 return realcount;
1149}
1150
1151static int se401_mmap(struct file *file, struct vm_area_struct *vma)
1152{
1153 struct video_device *dev = file->private_data;
1154 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1155 unsigned long start = vma->vm_start;
1156 unsigned long size = vma->vm_end-vma->vm_start;
1157 unsigned long page, pos;
1158
1159 down(&se401->lock);
1160
1161 if (se401->dev == NULL) {
1162 up(&se401->lock);
1163 return -EIO;
1164 }
1165 if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
1166 up(&se401->lock);
1167 return -EINVAL;
1168 }
1169 pos = (unsigned long)se401->fbuf;
1170 while (size > 0) {
1171 page = vmalloc_to_pfn((void *)pos);
1172 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
1173 up(&se401->lock);
1174 return -EAGAIN;
1175 }
1176 start += PAGE_SIZE;
1177 pos += PAGE_SIZE;
1178 if (size > PAGE_SIZE)
1179 size -= PAGE_SIZE;
1180 else
1181 size = 0;
1182 }
1183 up(&se401->lock);
1184
1185 return 0;
1186}
1187
1188static struct file_operations se401_fops = {
1189 .owner = THIS_MODULE,
1190 .open = se401_open,
1191 .release = se401_close,
1192 .read = se401_read,
1193 .mmap = se401_mmap,
1194 .ioctl = se401_ioctl,
1195 .llseek = no_llseek,
1196};
1197static struct video_device se401_template = {
1198 .owner = THIS_MODULE,
1199 .name = "se401 USB camera",
1200 .type = VID_TYPE_CAPTURE,
1201 .hardware = VID_HARDWARE_SE401,
1202 .fops = &se401_fops,
1203};
1204
1205
1206
1207/***************************/
1208static int se401_init(struct usb_se401 *se401, int button)
1209{
1210 int i=0, rc;
1211 unsigned char cp[0x40];
1212 char temp[200];
1213
1214 /* led on */
1215 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1216
1217 /* get camera descriptor */
1218 rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp));
1219 if (cp[1]!=0x41) {
1220 err("Wrong descriptor type");
1221 return 1;
1222 }
1223 sprintf (temp, "ExtraFeatures: %d", cp[3]);
1224
1225 se401->sizes=cp[4]+cp[5]*256;
1226 se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1227 if (!se401->width)
1228 return 1;
1229 se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1230 if (!se401->height) {
1231 kfree(se401->width);
1232 return 1;
1233 }
1234 for (i=0; i<se401->sizes; i++) {
1235 se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256;
1236 se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256;
1237 }
1238 sprintf (temp, "%s Sizes:", temp);
1239 for (i=0; i<se401->sizes; i++) {
1240 sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]);
1241 }
1242 info("%s", temp);
1243 se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3;
1244
1245 rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
1246 se401->cwidth=cp[0]+cp[1]*256;
1247 rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
1248 se401->cheight=cp[0]+cp[1]*256;
1249
1250 if (!cp[2] && SE401_FORMAT_BAYER) {
1251 err("Bayer format not supported!");
1252 return 1;
1253 }
1254 /* set output mode (BAYER) */
1255 se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0);
1256
1257 rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
1258 se401->brightness=cp[0]+cp[1]*256;
1259 /* some default values */
1260 se401->resetlevel=0x2d;
1261 se401->rgain=0x20;
1262 se401->ggain=0x20;
1263 se401->bgain=0x20;
1264 se401_set_exposure(se401, 20000);
1265 se401->palette=VIDEO_PALETTE_RGB24;
1266 se401->enhance=1;
1267 se401->dropped=0;
1268 se401->error=0;
1269 se401->framecount=0;
1270 se401->readcount=0;
1271
1272 /* Start interrupt transfers for snapshot button */
1273 if (button) {
1274 se401->inturb=usb_alloc_urb(0, GFP_KERNEL);
1275 if (!se401->inturb) {
1276 info("Allocation of inturb failed");
1277 return 1;
1278 }
1279 usb_fill_int_urb(se401->inturb, se401->dev,
1280 usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
1281 &se401->button, sizeof(se401->button),
1282 se401_button_irq,
1283 se401,
1284 8
1285 );
1286 if (usb_submit_urb(se401->inturb, GFP_KERNEL)) {
1287 info("int urb burned down");
1288 return 1;
1289 }
1290 } else
1291 se401->inturb=NULL;
1292
1293 /* Flash the led */
1294 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
1295 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1296 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
1297 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
1298
1299 return 0;
1300}
1301
1302static int se401_probe(struct usb_interface *intf,
1303 const struct usb_device_id *id)
1304{
1305 struct usb_device *dev = interface_to_usbdev(intf);
1306 struct usb_interface_descriptor *interface;
1307 struct usb_se401 *se401;
1308 char *camera_name=NULL;
1309 int button=1;
1310
1311 /* We don't handle multi-config cameras */
1312 if (dev->descriptor.bNumConfigurations != 1)
1313 return -ENODEV;
1314
1315 interface = &intf->cur_altsetting->desc;
1316
1317 /* Is it an se401? */
1318 if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 &&
1319 le16_to_cpu(dev->descriptor.idProduct) == 0x0004) {
1320 camera_name="Endpoints/Aox SE401";
1321 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 &&
1322 le16_to_cpu(dev->descriptor.idProduct) == 0x030b) {
1323 camera_name="Philips PCVC665K";
1324 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1325 le16_to_cpu(dev->descriptor.idProduct) == 0x5001) {
1326 camera_name="Kensington VideoCAM 67014";
1327 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1328 le16_to_cpu(dev->descriptor.idProduct) == 0x5002) {
1329 camera_name="Kensington VideoCAM 6701(5/7)";
1330 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1331 le16_to_cpu(dev->descriptor.idProduct) == 0x5003) {
1332 camera_name="Kensington VideoCAM 67016";
1333 button=0;
1334 } else
1335 return -ENODEV;
1336
1337 /* Checking vendor/product should be enough, but what the hell */
1338 if (interface->bInterfaceClass != 0x00)
1339 return -ENODEV;
1340 if (interface->bInterfaceSubClass != 0x00)
1341 return -ENODEV;
1342
1343 /* We found one */
1344 info("SE401 camera found: %s", camera_name);
1345
1346 if ((se401 = kmalloc(sizeof(*se401), GFP_KERNEL)) == NULL) {
1347 err("couldn't kmalloc se401 struct");
1348 return -ENOMEM;
1349 }
1350
1351 memset(se401, 0, sizeof(*se401));
1352
1353 se401->dev = dev;
1354 se401->iface = interface->bInterfaceNumber;
1355 se401->camera_name = camera_name;
1356
1357 info("firmware version: %02x", le16_to_cpu(dev->descriptor.bcdDevice) & 255);
1358
1359 if (se401_init(se401, button)) {
1360 kfree(se401);
1361 return -EIO;
1362 }
1363
1364 memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
1365 memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
1366 init_waitqueue_head(&se401->wq);
1367 init_MUTEX(&se401->lock);
1368 wmb();
1369
1370 if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
1371 kfree(se401);
1372 err("video_register_device failed");
1373 return -EIO;
1374 }
1375 info("registered new video device: video%d", se401->vdev.minor);
1376
1377 usb_set_intfdata (intf, se401);
1378 return 0;
1379}
1380
1381static void se401_disconnect(struct usb_interface *intf)
1382{
1383 struct usb_se401 *se401 = usb_get_intfdata (intf);
1384
1385 usb_set_intfdata (intf, NULL);
1386 if (se401) {
1387 video_unregister_device(&se401->vdev);
1388 if (!se401->user){
1389 usb_se401_remove_disconnected(se401);
1390 } else {
1391 se401->frame[0].grabstate = FRAME_ERROR;
1392 se401->frame[0].grabstate = FRAME_ERROR;
1393
1394 se401->streaming = 0;
1395
1396 wake_up_interruptible(&se401->wq);
1397 se401->removed = 1;
1398 }
1399 }
1400}
1401
1402static struct usb_driver se401_driver = {
1403 .owner = THIS_MODULE,
1404 .name = "se401",
1405 .id_table = device_table,
1406 .probe = se401_probe,
1407 .disconnect = se401_disconnect,
1408};
1409
1410
1411
1412/****************************************************************************
1413 *
1414 * Module routines
1415 *
1416 ***************************************************************************/
1417
1418static int __init usb_se401_init(void)
1419{
1420 info("SE401 usb camera driver version %s registering", version);
1421 if (flickerless)
1422 if (flickerless!=50 && flickerless!=60) {
1423 info("Invallid flickerless value, use 0, 50 or 60.");
1424 return -1;
1425 }
1426 return usb_register(&se401_driver);
1427}
1428
1429static void __exit usb_se401_exit(void)
1430{
1431 usb_deregister(&se401_driver);
1432 info("SE401 driver deregistered");
1433}
1434
1435module_init(usb_se401_init);
1436module_exit(usb_se401_exit);
diff --git a/drivers/usb/media/se401.h b/drivers/usb/media/se401.h
new file mode 100644
index 000000000000..2e5846f1eb20
--- /dev/null
+++ b/drivers/usb/media/se401.h
@@ -0,0 +1,233 @@
1
2#ifndef __LINUX_se401_H
3#define __LINUX_se401_H
4
5#include <asm/uaccess.h>
6#include <linux/videodev.h>
7#include <linux/smp_lock.h>
8
9#define se401_DEBUG /* Turn on debug messages */
10
11#ifdef se401_DEBUG
12# define PDEBUG(level, fmt, args...) \
13if (debug >= level) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args)
14#else
15# define PDEBUG(level, fmt, args...) do {} while(0)
16#endif
17
18/* An almost drop-in replacement for sleep_on_interruptible */
19#define wait_interruptible(test, queue, wait) \
20{ \
21 add_wait_queue(queue, wait); \
22 set_current_state(TASK_INTERRUPTIBLE); \
23 if (test) \
24 schedule(); \
25 remove_wait_queue(queue, wait); \
26 set_current_state(TASK_RUNNING); \
27 if (signal_pending(current)) \
28 break; \
29}
30
31#define SE401_REQ_GET_CAMERA_DESCRIPTOR 0x06
32#define SE401_REQ_START_CONTINUOUS_CAPTURE 0x41
33#define SE401_REQ_STOP_CONTINUOUS_CAPTURE 0x42
34#define SE401_REQ_CAPTURE_FRAME 0x43
35#define SE401_REQ_GET_BRT 0x44
36#define SE401_REQ_SET_BRT 0x45
37#define SE401_REQ_GET_WIDTH 0x4c
38#define SE401_REQ_SET_WIDTH 0x4d
39#define SE401_REQ_GET_HEIGHT 0x4e
40#define SE401_REQ_SET_HEIGHT 0x4f
41#define SE401_REQ_GET_OUTPUT_MODE 0x50
42#define SE401_REQ_SET_OUTPUT_MODE 0x51
43#define SE401_REQ_GET_EXT_FEATURE 0x52
44#define SE401_REQ_SET_EXT_FEATURE 0x53
45#define SE401_REQ_CAMERA_POWER 0x56
46#define SE401_REQ_LED_CONTROL 0x57
47#define SE401_REQ_BIOS 0xff
48
49#define SE401_BIOS_READ 0x07
50
51#define SE401_FORMAT_BAYER 0x40
52
53/* Hyundai hv7131b registers
54 7121 and 7141 should be the same (haven't really checked...) */
55/* Mode registers: */
56#define HV7131_REG_MODE_A 0x00
57#define HV7131_REG_MODE_B 0x01
58#define HV7131_REG_MODE_C 0x02
59/* Frame registers: */
60#define HV7131_REG_FRSU 0x10
61#define HV7131_REG_FRSL 0x11
62#define HV7131_REG_FCSU 0x12
63#define HV7131_REG_FCSL 0x13
64#define HV7131_REG_FWHU 0x14
65#define HV7131_REG_FWHL 0x15
66#define HV7131_REG_FWWU 0x16
67#define HV7131_REG_FWWL 0x17
68/* Timing registers: */
69#define HV7131_REG_THBU 0x20
70#define HV7131_REG_THBL 0x21
71#define HV7131_REG_TVBU 0x22
72#define HV7131_REG_TVBL 0x23
73#define HV7131_REG_TITU 0x25
74#define HV7131_REG_TITM 0x26
75#define HV7131_REG_TITL 0x27
76#define HV7131_REG_TMCD 0x28
77/* Adjust Registers: */
78#define HV7131_REG_ARLV 0x30
79#define HV7131_REG_ARCG 0x31
80#define HV7131_REG_AGCG 0x32
81#define HV7131_REG_ABCG 0x33
82#define HV7131_REG_APBV 0x34
83#define HV7131_REG_ASLP 0x54
84/* Offset Registers: */
85#define HV7131_REG_OFSR 0x50
86#define HV7131_REG_OFSG 0x51
87#define HV7131_REG_OFSB 0x52
88/* REset level statistics registers: */
89#define HV7131_REG_LOREFNOH 0x57
90#define HV7131_REG_LOREFNOL 0x58
91#define HV7131_REG_HIREFNOH 0x59
92#define HV7131_REG_HIREFNOL 0x5a
93
94/* se401 registers */
95#define SE401_OPERATINGMODE 0x2000
96
97
98/* size of usb transfers */
99#define SE401_PACKETSIZE 4096
100/* number of queued bulk transfers to use, should be about 8 */
101#define SE401_NUMSBUF 1
102/* read the usb specs for this one :) */
103#define SE401_VIDEO_ENDPOINT 1
104#define SE401_BUTTON_ENDPOINT 2
105/* number of frames supported by the v4l part */
106#define SE401_NUMFRAMES 2
107/* scratch buffers for passing data to the decoders */
108#define SE401_NUMSCRATCH 32
109/* maximum amount of data in a JangGu packet */
110#define SE401_VLCDATALEN 1024
111/* number of nul sized packets to receive before kicking the camera */
112#define SE401_MAX_NULLPACKETS 4000
113/* number of decoding errors before kicking the camera */
114#define SE401_MAX_ERRORS 200
115
116struct usb_device;
117
118struct se401_sbuf {
119 unsigned char *data;
120};
121
122enum {
123 FRAME_UNUSED, /* Unused (no MCAPTURE) */
124 FRAME_READY, /* Ready to start grabbing */
125 FRAME_GRABBING, /* In the process of being grabbed into */
126 FRAME_DONE, /* Finished grabbing, but not been synced yet */
127 FRAME_ERROR, /* Something bad happened while processing */
128};
129
130enum {
131 FMT_BAYER,
132 FMT_JANGGU,
133};
134
135enum {
136 BUFFER_UNUSED,
137 BUFFER_READY,
138 BUFFER_BUSY,
139 BUFFER_DONE,
140};
141
142struct se401_scratch {
143 unsigned char *data;
144 volatile int state;
145 int offset;
146 int length;
147};
148
149struct se401_frame {
150 unsigned char *data; /* Frame buffer */
151
152 volatile int grabstate; /* State of grabbing */
153
154 unsigned char *curline;
155 int curlinepix;
156 int curpix;
157};
158
159struct usb_se401 {
160 struct video_device vdev;
161
162 /* Device structure */
163 struct usb_device *dev;
164
165 unsigned char iface;
166
167 char *camera_name;
168
169 int change;
170 int brightness;
171 int hue;
172 int rgain;
173 int ggain;
174 int bgain;
175 int expose_h;
176 int expose_m;
177 int expose_l;
178 int resetlevel;
179
180 int enhance;
181
182 int format;
183 int sizes;
184 int *width;
185 int *height;
186 int cwidth; /* current width */
187 int cheight; /* current height */
188 int palette;
189 int maxframesize;
190 int cframesize; /* current framesize */
191
192 struct semaphore lock;
193 int user; /* user count for exclusive use */
194 int removed; /* device disconnected */
195
196 int streaming; /* Are we streaming video? */
197
198 char *fbuf; /* Videodev buffer area */
199
200 struct urb *urb[SE401_NUMSBUF];
201 struct urb *inturb;
202
203 int button;
204 int buttonpressed;
205
206 int curframe; /* Current receiving frame */
207 struct se401_frame frame[SE401_NUMFRAMES];
208 int readcount;
209 int framecount;
210 int error;
211 int dropped;
212
213 int scratch_next;
214 int scratch_use;
215 int scratch_overflow;
216 struct se401_scratch scratch[SE401_NUMSCRATCH];
217
218 /* Decoder specific data: */
219 unsigned char vlcdata[SE401_VLCDATALEN];
220 int vlcdatapos;
221 int bayeroffset;
222
223 struct se401_sbuf sbuf[SE401_NUMSBUF];
224
225 wait_queue_head_t wq; /* Processes waiting */
226
227 int nullpackets;
228};
229
230
231
232#endif
233
diff --git a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h
new file mode 100644
index 000000000000..8b8a4c8743f8
--- /dev/null
+++ b/drivers/usb/media/sn9c102.h
@@ -0,0 +1,206 @@
1/***************************************************************************
2 * V4L2 driver for SN9C10x PC Camera Controllers *
3 * *
4 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#ifndef _SN9C102_H_
22#define _SN9C102_H_
23
24#include <linux/version.h>
25#include <linux/usb.h>
26#include <linux/videodev.h>
27#include <linux/device.h>
28#include <linux/list.h>
29#include <linux/spinlock.h>
30#include <linux/time.h>
31#include <linux/wait.h>
32#include <linux/types.h>
33#include <linux/param.h>
34#include <linux/rwsem.h>
35#include <asm/semaphore.h>
36
37#include "sn9c102_sensor.h"
38
39/*****************************************************************************/
40
41#define SN9C102_DEBUG
42#define SN9C102_DEBUG_LEVEL 2
43#define SN9C102_MAX_DEVICES 64
44#define SN9C102_PRESERVE_IMGSCALE 0
45#define SN9C102_FORCE_MUNMAP 0
46#define SN9C102_MAX_FRAMES 32
47#define SN9C102_URBS 2
48#define SN9C102_ISO_PACKETS 7
49#define SN9C102_ALTERNATE_SETTING 8
50#define SN9C102_URB_TIMEOUT msecs_to_jiffies(2 * SN9C102_ISO_PACKETS)
51#define SN9C102_CTRL_TIMEOUT 300
52
53/*****************************************************************************/
54
55#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers"
56#define SN9C102_MODULE_AUTHOR "(C) 2004-2005 Luca Risolia"
57#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
58#define SN9C102_MODULE_LICENSE "GPL"
59#define SN9C102_MODULE_VERSION "1:1.24"
60#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 24)
61
62enum sn9c102_bridge {
63 BRIDGE_SN9C101 = 0x01,
64 BRIDGE_SN9C102 = 0x02,
65 BRIDGE_SN9C103 = 0x04,
66};
67
68SN9C102_ID_TABLE
69SN9C102_SENSOR_TABLE
70
71enum sn9c102_frame_state {
72 F_UNUSED,
73 F_QUEUED,
74 F_GRABBING,
75 F_DONE,
76 F_ERROR,
77};
78
79struct sn9c102_frame_t {
80 void* bufmem;
81 struct v4l2_buffer buf;
82 enum sn9c102_frame_state state;
83 struct list_head frame;
84 unsigned long vma_use_count;
85};
86
87enum sn9c102_dev_state {
88 DEV_INITIALIZED = 0x01,
89 DEV_DISCONNECTED = 0x02,
90 DEV_MISCONFIGURED = 0x04,
91};
92
93enum sn9c102_io_method {
94 IO_NONE,
95 IO_READ,
96 IO_MMAP,
97};
98
99enum sn9c102_stream_state {
100 STREAM_OFF,
101 STREAM_INTERRUPT,
102 STREAM_ON,
103};
104
105typedef char sn9c102_sof_header_t[12];
106typedef char sn9c102_eof_header_t[4];
107
108struct sn9c102_sysfs_attr {
109 u8 reg, i2c_reg;
110 sn9c102_sof_header_t frame_header;
111};
112
113struct sn9c102_module_param {
114 u8 force_munmap;
115};
116
117static DECLARE_MUTEX(sn9c102_sysfs_lock);
118static DECLARE_RWSEM(sn9c102_disconnect);
119
120struct sn9c102_device {
121 struct device dev;
122
123 struct video_device* v4ldev;
124
125 enum sn9c102_bridge bridge;
126 struct sn9c102_sensor* sensor;
127
128 struct usb_device* usbdev;
129 struct urb* urb[SN9C102_URBS];
130 void* transfer_buffer[SN9C102_URBS];
131 u8* control_buffer;
132
133 struct sn9c102_frame_t *frame_current, frame[SN9C102_MAX_FRAMES];
134 struct list_head inqueue, outqueue;
135 u32 frame_count, nbuffers, nreadbuffers;
136
137 enum sn9c102_io_method io;
138 enum sn9c102_stream_state stream;
139
140 struct v4l2_jpegcompression compression;
141
142 struct sn9c102_sysfs_attr sysfs;
143 sn9c102_sof_header_t sof_header;
144 u16 reg[32];
145
146 struct sn9c102_module_param module_param;
147
148 enum sn9c102_dev_state state;
149 u8 users;
150
151 struct semaphore dev_sem, fileop_sem;
152 spinlock_t queue_lock;
153 wait_queue_head_t open, wait_frame, wait_stream;
154};
155
156/*****************************************************************************/
157
158void
159sn9c102_attach_sensor(struct sn9c102_device* cam,
160 struct sn9c102_sensor* sensor)
161{
162 cam->sensor = sensor;
163 cam->sensor->dev = &cam->dev;
164 cam->sensor->usbdev = cam->usbdev;
165}
166
167/*****************************************************************************/
168
169#undef DBG
170#undef KDBG
171#ifdef SN9C102_DEBUG
172# define DBG(level, fmt, args...) \
173{ \
174 if (debug >= (level)) { \
175 if ((level) == 1) \
176 dev_err(&cam->dev, fmt "\n", ## args); \
177 else if ((level) == 2) \
178 dev_info(&cam->dev, fmt "\n", ## args); \
179 else if ((level) >= 3) \
180 dev_info(&cam->dev, "[%s:%d] " fmt "\n", \
181 __FUNCTION__, __LINE__ , ## args); \
182 } \
183}
184# define KDBG(level, fmt, args...) \
185{ \
186 if (debug >= (level)) { \
187 if ((level) == 1 || (level) == 2) \
188 pr_info("sn9c102: " fmt "\n", ## args); \
189 else if ((level) == 3) \
190 pr_debug("sn9c102: [%s:%d] " fmt "\n", __FUNCTION__, \
191 __LINE__ , ## args); \
192 } \
193}
194#else
195# define KDBG(level, fmt, args...) do {;} while(0);
196# define DBG(level, fmt, args...) do {;} while(0);
197#endif
198
199#undef PDBG
200#define PDBG(fmt, args...) \
201dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args);
202
203#undef PDBGG
204#define PDBGG(fmt, args...) do {;} while(0); /* placeholder */
205
206#endif /* _SN9C102_H_ */
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c
new file mode 100644
index 000000000000..898401cf7dcc
--- /dev/null
+++ b/drivers/usb/media/sn9c102_core.c
@@ -0,0 +1,2744 @@
1/***************************************************************************
2 * V4L2 driver for SN9C10x PC Camera Controllers *
3 * *
4 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/param.h>
25#include <linux/moduleparam.h>
26#include <linux/errno.h>
27#include <linux/slab.h>
28#include <linux/string.h>
29#include <linux/device.h>
30#include <linux/fs.h>
31#include <linux/delay.h>
32#include <linux/stddef.h>
33#include <linux/compiler.h>
34#include <linux/ioctl.h>
35#include <linux/poll.h>
36#include <linux/stat.h>
37#include <linux/mm.h>
38#include <linux/vmalloc.h>
39#include <linux/page-flags.h>
40#include <linux/byteorder/generic.h>
41#include <asm/page.h>
42#include <asm/uaccess.h>
43
44#include "sn9c102.h"
45
46/*****************************************************************************/
47
48MODULE_DEVICE_TABLE(usb, sn9c102_id_table);
49
50MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL);
51MODULE_DESCRIPTION(SN9C102_MODULE_NAME);
52MODULE_VERSION(SN9C102_MODULE_VERSION);
53MODULE_LICENSE(SN9C102_MODULE_LICENSE);
54
55static short video_nr[] = {[0 ... SN9C102_MAX_DEVICES-1] = -1};
56module_param_array(video_nr, short, NULL, 0444);
57MODULE_PARM_DESC(video_nr,
58 "\n<-1|n[,...]> Specify V4L2 minor mode number."
59 "\n -1 = use next available (default)"
60 "\n n = use minor number n (integer >= 0)"
61 "\nYou can specify up to "__MODULE_STRING(SN9C102_MAX_DEVICES)
62 " cameras this way."
63 "\nFor example:"
64 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
65 "\nthe second camera and use auto for the first"
66 "\none and for every other camera."
67 "\n");
68
69static short force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] =
70 SN9C102_FORCE_MUNMAP};
71module_param_array(force_munmap, bool, NULL, 0444);
72MODULE_PARM_DESC(force_munmap,
73 "\n<0|1[,...]> Force the application to unmap previously "
74 "\nmapped buffer memory before calling any VIDIOC_S_CROP or "
75 "\nVIDIOC_S_FMT ioctl's. Not all the applications support "
76 "\nthis feature. This parameter is specific for each "
77 "\ndetected camera."
78 "\n 0 = do not force memory unmapping"
79 "\n 1 = force memory unmapping (save memory)"
80 "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
81 "\n");
82
83#ifdef SN9C102_DEBUG
84static unsigned short debug = SN9C102_DEBUG_LEVEL;
85module_param(debug, ushort, 0644);
86MODULE_PARM_DESC(debug,
87 "\n<n> Debugging information level, from 0 to 3:"
88 "\n0 = none (use carefully)"
89 "\n1 = critical errors"
90 "\n2 = significant informations"
91 "\n3 = more verbose messages"
92 "\nLevel 3 is useful for testing only, when only "
93 "one device is used."
94 "\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"."
95 "\n");
96#endif
97
98/*****************************************************************************/
99
100static sn9c102_sof_header_t sn9c102_sof_header[] = {
101 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x00},
102 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x01},
103};
104
105
106static sn9c102_eof_header_t sn9c102_eof_header[] = {
107 {0x00, 0x00, 0x00, 0x00},
108 {0x40, 0x00, 0x00, 0x00},
109 {0x80, 0x00, 0x00, 0x00},
110 {0xc0, 0x00, 0x00, 0x00},
111};
112
113/*****************************************************************************/
114
115static void* rvmalloc(size_t size)
116{
117 void* mem;
118 unsigned long adr;
119
120 size = PAGE_ALIGN(size);
121
122 mem = vmalloc_32((unsigned long)size);
123 if (!mem)
124 return NULL;
125
126 memset(mem, 0, size);
127
128 adr = (unsigned long)mem;
129 while (size > 0) {
130 SetPageReserved(vmalloc_to_page((void *)adr));
131 adr += PAGE_SIZE;
132 size -= PAGE_SIZE;
133 }
134
135 return mem;
136}
137
138
139static void rvfree(void* mem, size_t size)
140{
141 unsigned long adr;
142
143 if (!mem)
144 return;
145
146 size = PAGE_ALIGN(size);
147
148 adr = (unsigned long)mem;
149 while (size > 0) {
150 ClearPageReserved(vmalloc_to_page((void *)adr));
151 adr += PAGE_SIZE;
152 size -= PAGE_SIZE;
153 }
154
155 vfree(mem);
156}
157
158
159static u32
160sn9c102_request_buffers(struct sn9c102_device* cam, u32 count,
161 enum sn9c102_io_method io)
162{
163 struct v4l2_pix_format* p = &(cam->sensor->pix_format);
164 struct v4l2_rect* r = &(cam->sensor->cropcap.bounds);
165 const size_t imagesize = cam->module_param.force_munmap ||
166 io == IO_READ ?
167 (p->width * p->height * p->priv) / 8 :
168 (r->width * r->height * p->priv) / 8;
169 void* buff = NULL;
170 u32 i;
171
172 if (count > SN9C102_MAX_FRAMES)
173 count = SN9C102_MAX_FRAMES;
174
175 cam->nbuffers = count;
176 while (cam->nbuffers > 0) {
177 if ((buff = rvmalloc(cam->nbuffers * PAGE_ALIGN(imagesize))))
178 break;
179 cam->nbuffers--;
180 }
181
182 for (i = 0; i < cam->nbuffers; i++) {
183 cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
184 cam->frame[i].buf.index = i;
185 cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
186 cam->frame[i].buf.length = imagesize;
187 cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
188 cam->frame[i].buf.sequence = 0;
189 cam->frame[i].buf.field = V4L2_FIELD_NONE;
190 cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
191 cam->frame[i].buf.flags = 0;
192 }
193
194 return cam->nbuffers;
195}
196
197
198static void sn9c102_release_buffers(struct sn9c102_device* cam)
199{
200 if (cam->nbuffers) {
201 rvfree(cam->frame[0].bufmem,
202 cam->nbuffers * cam->frame[0].buf.length);
203 cam->nbuffers = 0;
204 }
205}
206
207
208static void sn9c102_empty_framequeues(struct sn9c102_device* cam)
209{
210 u32 i;
211
212 INIT_LIST_HEAD(&cam->inqueue);
213 INIT_LIST_HEAD(&cam->outqueue);
214
215 for (i = 0; i < SN9C102_MAX_FRAMES; i++) {
216 cam->frame[i].state = F_UNUSED;
217 cam->frame[i].buf.bytesused = 0;
218 }
219}
220
221
222static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
223{
224 unsigned long lock_flags;
225 u32 i;
226
227 for (i = 0; i < cam->nbuffers; i++)
228 if (cam->frame[i].state == F_UNUSED) {
229 cam->frame[i].state = F_QUEUED;
230 spin_lock_irqsave(&cam->queue_lock, lock_flags);
231 list_add_tail(&cam->frame[i].frame, &cam->inqueue);
232 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
233 }
234}
235
236/*****************************************************************************/
237
238int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index)
239{
240 struct usb_device* udev = cam->usbdev;
241 u8* buff = cam->control_buffer;
242 int res;
243
244 *buff = value;
245
246 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
247 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
248 if (res < 0) {
249 DBG(3, "Failed to write a register (value 0x%02X, index "
250 "0x%02X, error %d)", value, index, res)
251 return -1;
252 }
253
254 cam->reg[index] = value;
255
256 return 0;
257}
258
259
260/* NOTE: reading some registers always returns 0 */
261static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
262{
263 struct usb_device* udev = cam->usbdev;
264 u8* buff = cam->control_buffer;
265 int res;
266
267 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
268 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
269 if (res < 0)
270 DBG(3, "Failed to read a register (index 0x%02X, error %d)",
271 index, res)
272
273 return (res >= 0) ? (int)(*buff) : -1;
274}
275
276
277int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index)
278{
279 if (index > 0x1f)
280 return -EINVAL;
281
282 return cam->reg[index];
283}
284
285
286static int
287sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
288{
289 int i, r;
290
291 for (i = 1; i <= 5; i++) {
292 r = sn9c102_read_reg(cam, 0x08);
293 if (r < 0)
294 return -EIO;
295 if (r & 0x04)
296 return 0;
297 if (sensor->frequency & SN9C102_I2C_400KHZ)
298 udelay(5*16);
299 else
300 udelay(16*16);
301 }
302 return -EBUSY;
303}
304
305
306static int
307sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
308 struct sn9c102_sensor* sensor)
309{
310 int r;
311 r = sn9c102_read_reg(cam, 0x08);
312 return (r < 0 || (r >= 0 && !(r & 0x08))) ? -EIO : 0;
313}
314
315
316static int
317sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
318 struct sn9c102_sensor* sensor)
319{
320 int r;
321 r = sn9c102_read_reg(cam, 0x08);
322 return (r < 0 || (r >= 0 && (r & 0x08))) ? -EIO : 0;
323}
324
325
326int
327sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
328 struct sn9c102_sensor* sensor, u8 data0, u8 data1,
329 u8 n, u8 buffer[])
330{
331 struct usb_device* udev = cam->usbdev;
332 u8* data = cam->control_buffer;
333 int err = 0, res;
334
335 /* Write cycle */
336 data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
337 ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) | 0x10;
338 data[1] = data0; /* I2C slave id */
339 data[2] = data1; /* address */
340 data[7] = 0x10;
341 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
342 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
343 if (res < 0)
344 err += res;
345
346 err += sn9c102_i2c_wait(cam, sensor);
347
348 /* Read cycle - n bytes */
349 data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
350 ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) |
351 (n << 4) | 0x02;
352 data[1] = data0;
353 data[7] = 0x10;
354 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
355 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
356 if (res < 0)
357 err += res;
358
359 err += sn9c102_i2c_wait(cam, sensor);
360
361 /* The first read byte will be placed in data[4] */
362 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
363 0x0a, 0, data, 5, SN9C102_CTRL_TIMEOUT);
364 if (res < 0)
365 err += res;
366
367 err += sn9c102_i2c_detect_read_error(cam, sensor);
368
369 PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1,
370 data[4])
371
372 if (err) {
373 DBG(3, "I2C read failed for %s image sensor", sensor->name)
374 return -1;
375 }
376
377 if (buffer)
378 memcpy(buffer, data, sizeof(buffer));
379
380 return (int)data[4];
381}
382
383
384int
385sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
386 struct sn9c102_sensor* sensor, u8 n, u8 data0,
387 u8 data1, u8 data2, u8 data3, u8 data4, u8 data5)
388{
389 struct usb_device* udev = cam->usbdev;
390 u8* data = cam->control_buffer;
391 int err = 0, res;
392
393 /* Write cycle. It usually is address + value */
394 data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
395 ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0)
396 | ((n - 1) << 4);
397 data[1] = data0;
398 data[2] = data1;
399 data[3] = data2;
400 data[4] = data3;
401 data[5] = data4;
402 data[6] = data5;
403 data[7] = 0x14;
404 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
405 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
406 if (res < 0)
407 err += res;
408
409 err += sn9c102_i2c_wait(cam, sensor);
410 err += sn9c102_i2c_detect_write_error(cam, sensor);
411
412 if (err)
413 DBG(3, "I2C write failed for %s image sensor", sensor->name)
414
415 PDBGG("I2C raw write: %u bytes, data0 = 0x%02X, data1 = 0x%02X, "
416 "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X",
417 n, data0, data1, data2, data3, data4, data5)
418
419 return err ? -1 : 0;
420}
421
422
423int
424sn9c102_i2c_try_read(struct sn9c102_device* cam,
425 struct sn9c102_sensor* sensor, u8 address)
426{
427 return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
428 address, 1, NULL);
429}
430
431
432int
433sn9c102_i2c_try_write(struct sn9c102_device* cam,
434 struct sn9c102_sensor* sensor, u8 address, u8 value)
435{
436 return sn9c102_i2c_try_raw_write(cam, sensor, 3,
437 sensor->i2c_slave_id, address,
438 value, 0, 0, 0);
439}
440
441
442int sn9c102_i2c_read(struct sn9c102_device* cam, u8 address)
443{
444 if (!cam->sensor)
445 return -1;
446
447 return sn9c102_i2c_try_read(cam, cam->sensor, address);
448}
449
450
451int sn9c102_i2c_write(struct sn9c102_device* cam, u8 address, u8 value)
452{
453 if (!cam->sensor)
454 return -1;
455
456 return sn9c102_i2c_try_write(cam, cam->sensor, address, value);
457}
458
459/*****************************************************************************/
460
461static void*
462sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len)
463{
464 size_t soflen = sizeof(sn9c102_sof_header_t), i;
465 u8 j, n = sizeof(sn9c102_sof_header) / soflen;
466
467 for (i = 0; (len >= soflen) && (i <= len - soflen); i++)
468 for (j = 0; j < n; j++)
469 /* It's enough to compare 7 bytes */
470 if (!memcmp(mem + i, sn9c102_sof_header[j], 7)) {
471 memcpy(cam->sof_header, mem + i, soflen);
472 /* Skip the header */
473 return mem + i + soflen;
474 }
475
476 return NULL;
477}
478
479
480static void*
481sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
482{
483 size_t eoflen = sizeof(sn9c102_eof_header_t), i;
484 unsigned j, n = sizeof(sn9c102_eof_header) / eoflen;
485
486 if (cam->sensor->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
487 return NULL; /* EOF header does not exist in compressed data */
488
489 for (i = 0; (len >= eoflen) && (i <= len - eoflen); i++)
490 for (j = 0; j < n; j++)
491 if (!memcmp(mem + i, sn9c102_eof_header[j], eoflen))
492 return mem + i;
493
494 return NULL;
495}
496
497
498static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
499{
500 struct sn9c102_device* cam = urb->context;
501 struct sn9c102_frame_t** f;
502 size_t imagesize;
503 unsigned long lock_flags;
504 u8 i;
505 int err = 0;
506
507 if (urb->status == -ENOENT)
508 return;
509
510 f = &cam->frame_current;
511
512 if (cam->stream == STREAM_INTERRUPT) {
513 cam->stream = STREAM_OFF;
514 if ((*f))
515 (*f)->state = F_QUEUED;
516 DBG(3, "Stream interrupted")
517 wake_up_interruptible(&cam->wait_stream);
518 }
519
520 if (cam->state & DEV_DISCONNECTED)
521 return;
522
523 if (cam->state & DEV_MISCONFIGURED) {
524 wake_up_interruptible(&cam->wait_frame);
525 return;
526 }
527
528 if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
529 goto resubmit_urb;
530
531 if (!(*f))
532 (*f) = list_entry(cam->inqueue.next, struct sn9c102_frame_t,
533 frame);
534
535 imagesize = (cam->sensor->pix_format.width *
536 cam->sensor->pix_format.height *
537 cam->sensor->pix_format.priv) / 8;
538
539 for (i = 0; i < urb->number_of_packets; i++) {
540 unsigned int img, len, status;
541 void *pos, *sof, *eof;
542
543 len = urb->iso_frame_desc[i].actual_length;
544 status = urb->iso_frame_desc[i].status;
545 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
546
547 if (status) {
548 DBG(3, "Error in isochronous frame")
549 (*f)->state = F_ERROR;
550 continue;
551 }
552
553 PDBGG("Isochrnous frame: length %u, #%u i", len, i)
554
555 /*
556 NOTE: It is probably correct to assume that SOF and EOF
557 headers do not occur between two consecutive packets,
558 but who knows..Whatever is the truth, this assumption
559 doesn't introduce bugs.
560 */
561
562redo:
563 sof = sn9c102_find_sof_header(cam, pos, len);
564 if (!sof) {
565 eof = sn9c102_find_eof_header(cam, pos, len);
566 if ((*f)->state == F_GRABBING) {
567end_of_frame:
568 img = len;
569
570 if (eof)
571 img = (eof > pos) ? eof - pos - 1 : 0;
572
573 if ((*f)->buf.bytesused+img > imagesize) {
574 u32 b = (*f)->buf.bytesused + img -
575 imagesize;
576 img = imagesize - (*f)->buf.bytesused;
577 DBG(3, "Expected EOF not found: "
578 "video frame cut")
579 if (eof)
580 DBG(3, "Exceeded limit: +%u "
581 "bytes", (unsigned)(b))
582 }
583
584 memcpy((*f)->bufmem + (*f)->buf.bytesused, pos,
585 img);
586
587 if ((*f)->buf.bytesused == 0)
588 do_gettimeofday(&(*f)->buf.timestamp);
589
590 (*f)->buf.bytesused += img;
591
592 if ((*f)->buf.bytesused == imagesize ||
593 (cam->sensor->pix_format.pixelformat ==
594 V4L2_PIX_FMT_SN9C10X && eof)) {
595 u32 b = (*f)->buf.bytesused;
596 (*f)->state = F_DONE;
597 (*f)->buf.sequence= ++cam->frame_count;
598 spin_lock_irqsave(&cam->queue_lock,
599 lock_flags);
600 list_move_tail(&(*f)->frame,
601 &cam->outqueue);
602 if (!list_empty(&cam->inqueue))
603 (*f) = list_entry(
604 cam->inqueue.next,
605 struct sn9c102_frame_t,
606 frame );
607 else
608 (*f) = NULL;
609 spin_unlock_irqrestore(&cam->queue_lock
610 , lock_flags);
611 memcpy(cam->sysfs.frame_header,
612 cam->sof_header,
613 sizeof(sn9c102_sof_header_t));
614 DBG(3, "Video frame captured: "
615 "%lu bytes", (unsigned long)(b))
616
617 if (!(*f))
618 goto resubmit_urb;
619
620 } else if (eof) {
621 (*f)->state = F_ERROR;
622 DBG(3, "Not expected EOF after %lu "
623 "bytes of image data",
624 (unsigned long)((*f)->buf.bytesused))
625 }
626
627 if (sof) /* (1) */
628 goto start_of_frame;
629
630 } else if (eof) {
631 DBG(3, "EOF without SOF")
632 continue;
633
634 } else {
635 PDBGG("Ignoring pointless isochronous frame")
636 continue;
637 }
638
639 } else if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR) {
640start_of_frame:
641 (*f)->state = F_GRABBING;
642 (*f)->buf.bytesused = 0;
643 len -= (sof - pos);
644 pos = sof;
645 DBG(3, "SOF detected: new video frame")
646 if (len)
647 goto redo;
648
649 } else if ((*f)->state == F_GRABBING) {
650 eof = sn9c102_find_eof_header(cam, pos, len);
651 if (eof && eof < sof)
652 goto end_of_frame; /* (1) */
653 else {
654 if (cam->sensor->pix_format.pixelformat ==
655 V4L2_PIX_FMT_SN9C10X) {
656 eof = sof-sizeof(sn9c102_sof_header_t);
657 goto end_of_frame;
658 } else {
659 DBG(3, "SOF before expected EOF after "
660 "%lu bytes of image data",
661 (unsigned long)((*f)->buf.bytesused))
662 goto start_of_frame;
663 }
664 }
665 }
666 }
667
668resubmit_urb:
669 urb->dev = cam->usbdev;
670 err = usb_submit_urb(urb, GFP_ATOMIC);
671 if (err < 0 && err != -EPERM) {
672 cam->state |= DEV_MISCONFIGURED;
673 DBG(1, "usb_submit_urb() failed")
674 }
675
676 wake_up_interruptible(&cam->wait_frame);
677}
678
679
680static int sn9c102_start_transfer(struct sn9c102_device* cam)
681{
682 struct usb_device *udev = cam->usbdev;
683 struct urb* urb;
684 const unsigned int wMaxPacketSize[] = {0, 128, 256, 384, 512,
685 680, 800, 900, 1023};
686 const unsigned int psz = wMaxPacketSize[SN9C102_ALTERNATE_SETTING];
687 s8 i, j;
688 int err = 0;
689
690 for (i = 0; i < SN9C102_URBS; i++) {
691 cam->transfer_buffer[i] = kmalloc(SN9C102_ISO_PACKETS * psz,
692 GFP_KERNEL);
693 if (!cam->transfer_buffer[i]) {
694 err = -ENOMEM;
695 DBG(1, "Not enough memory")
696 goto free_buffers;
697 }
698 }
699
700 for (i = 0; i < SN9C102_URBS; i++) {
701 urb = usb_alloc_urb(SN9C102_ISO_PACKETS, GFP_KERNEL);
702 cam->urb[i] = urb;
703 if (!urb) {
704 err = -ENOMEM;
705 DBG(1, "usb_alloc_urb() failed")
706 goto free_urbs;
707 }
708 urb->dev = udev;
709 urb->context = cam;
710 urb->pipe = usb_rcvisocpipe(udev, 1);
711 urb->transfer_flags = URB_ISO_ASAP;
712 urb->number_of_packets = SN9C102_ISO_PACKETS;
713 urb->complete = sn9c102_urb_complete;
714 urb->transfer_buffer = cam->transfer_buffer[i];
715 urb->transfer_buffer_length = psz * SN9C102_ISO_PACKETS;
716 urb->interval = 1;
717 for (j = 0; j < SN9C102_ISO_PACKETS; j++) {
718 urb->iso_frame_desc[j].offset = psz * j;
719 urb->iso_frame_desc[j].length = psz;
720 }
721 }
722
723 /* Enable video */
724 if (!(cam->reg[0x01] & 0x04)) {
725 err = sn9c102_write_reg(cam, cam->reg[0x01] | 0x04, 0x01);
726 if (err) {
727 err = -EIO;
728 DBG(1, "I/O hardware error")
729 goto free_urbs;
730 }
731 }
732
733 err = usb_set_interface(udev, 0, SN9C102_ALTERNATE_SETTING);
734 if (err) {
735 DBG(1, "usb_set_interface() failed")
736 goto free_urbs;
737 }
738
739 cam->frame_current = NULL;
740
741 for (i = 0; i < SN9C102_URBS; i++) {
742 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
743 if (err) {
744 for (j = i-1; j >= 0; j--)
745 usb_kill_urb(cam->urb[j]);
746 DBG(1, "usb_submit_urb() failed, error %d", err)
747 goto free_urbs;
748 }
749 }
750
751 return 0;
752
753free_urbs:
754 for (i = 0; (i < SN9C102_URBS) && cam->urb[i]; i++)
755 usb_free_urb(cam->urb[i]);
756
757free_buffers:
758 for (i = 0; (i < SN9C102_URBS) && cam->transfer_buffer[i]; i++)
759 kfree(cam->transfer_buffer[i]);
760
761 return err;
762}
763
764
765static int sn9c102_stop_transfer(struct sn9c102_device* cam)
766{
767 struct usb_device *udev = cam->usbdev;
768 s8 i;
769 int err = 0;
770
771 if (cam->state & DEV_DISCONNECTED)
772 return 0;
773
774 for (i = SN9C102_URBS-1; i >= 0; i--) {
775 usb_kill_urb(cam->urb[i]);
776 usb_free_urb(cam->urb[i]);
777 kfree(cam->transfer_buffer[i]);
778 }
779
780 err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
781 if (err)
782 DBG(3, "usb_set_interface() failed")
783
784 return err;
785}
786
787
788int sn9c102_stream_interrupt(struct sn9c102_device* cam)
789{
790 int err = 0;
791
792 cam->stream = STREAM_INTERRUPT;
793 err = wait_event_timeout(cam->wait_stream,
794 (cam->stream == STREAM_OFF) ||
795 (cam->state & DEV_DISCONNECTED),
796 SN9C102_URB_TIMEOUT);
797 if (cam->state & DEV_DISCONNECTED)
798 return -ENODEV;
799 else if (err) {
800 cam->state |= DEV_MISCONFIGURED;
801 DBG(1, "The camera is misconfigured. To use it, close and "
802 "open /dev/video%d again.", cam->v4ldev->minor)
803 return err;
804 }
805
806 return 0;
807}
808
809/*****************************************************************************/
810
811static u8 sn9c102_strtou8(const char* buff, size_t len, ssize_t* count)
812{
813 char str[5];
814 char* endp;
815 unsigned long val;
816
817 if (len < 4) {
818 strncpy(str, buff, len);
819 str[len+1] = '\0';
820 } else {
821 strncpy(str, buff, 4);
822 str[4] = '\0';
823 }
824
825 val = simple_strtoul(str, &endp, 0);
826
827 *count = 0;
828 if (val <= 0xff)
829 *count = (ssize_t)(endp - str);
830 if ((*count) && (len == *count+1) && (buff[*count] == '\n'))
831 *count += 1;
832
833 return (u8)val;
834}
835
836/*
837 NOTE 1: being inside one of the following methods implies that the v4l
838 device exists for sure (see kobjects and reference counters)
839 NOTE 2: buffers are PAGE_SIZE long
840*/
841
842static ssize_t sn9c102_show_reg(struct class_device* cd, char* buf)
843{
844 struct sn9c102_device* cam;
845 ssize_t count;
846
847 if (down_interruptible(&sn9c102_sysfs_lock))
848 return -ERESTARTSYS;
849
850 cam = video_get_drvdata(to_video_device(cd));
851 if (!cam) {
852 up(&sn9c102_sysfs_lock);
853 return -ENODEV;
854 }
855
856 count = sprintf(buf, "%u\n", cam->sysfs.reg);
857
858 up(&sn9c102_sysfs_lock);
859
860 return count;
861}
862
863
864static ssize_t
865sn9c102_store_reg(struct class_device* cd, const char* buf, size_t len)
866{
867 struct sn9c102_device* cam;
868 u8 index;
869 ssize_t count;
870
871 if (down_interruptible(&sn9c102_sysfs_lock))
872 return -ERESTARTSYS;
873
874 cam = video_get_drvdata(to_video_device(cd));
875 if (!cam) {
876 up(&sn9c102_sysfs_lock);
877 return -ENODEV;
878 }
879
880 index = sn9c102_strtou8(buf, len, &count);
881 if (index > 0x1f || !count) {
882 up(&sn9c102_sysfs_lock);
883 return -EINVAL;
884 }
885
886 cam->sysfs.reg = index;
887
888 DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg)
889 DBG(3, "Written bytes: %zd", count)
890
891 up(&sn9c102_sysfs_lock);
892
893 return count;
894}
895
896
897static ssize_t sn9c102_show_val(struct class_device* cd, char* buf)
898{
899 struct sn9c102_device* cam;
900 ssize_t count;
901 int val;
902
903 if (down_interruptible(&sn9c102_sysfs_lock))
904 return -ERESTARTSYS;
905
906 cam = video_get_drvdata(to_video_device(cd));
907 if (!cam) {
908 up(&sn9c102_sysfs_lock);
909 return -ENODEV;
910 }
911
912 if ((val = sn9c102_read_reg(cam, cam->sysfs.reg)) < 0) {
913 up(&sn9c102_sysfs_lock);
914 return -EIO;
915 }
916
917 count = sprintf(buf, "%d\n", val);
918
919 DBG(3, "Read bytes: %zd", count)
920
921 up(&sn9c102_sysfs_lock);
922
923 return count;
924}
925
926
927static ssize_t
928sn9c102_store_val(struct class_device* cd, const char* buf, size_t len)
929{
930 struct sn9c102_device* cam;
931 u8 value;
932 ssize_t count;
933 int err;
934
935 if (down_interruptible(&sn9c102_sysfs_lock))
936 return -ERESTARTSYS;
937
938 cam = video_get_drvdata(to_video_device(cd));
939 if (!cam) {
940 up(&sn9c102_sysfs_lock);
941 return -ENODEV;
942 }
943
944 value = sn9c102_strtou8(buf, len, &count);
945 if (!count) {
946 up(&sn9c102_sysfs_lock);
947 return -EINVAL;
948 }
949
950 err = sn9c102_write_reg(cam, value, cam->sysfs.reg);
951 if (err) {
952 up(&sn9c102_sysfs_lock);
953 return -EIO;
954 }
955
956 DBG(2, "Written SN9C10X reg. 0x%02X, val. 0x%02X",
957 cam->sysfs.reg, value)
958 DBG(3, "Written bytes: %zd", count)
959
960 up(&sn9c102_sysfs_lock);
961
962 return count;
963}
964
965
966static ssize_t sn9c102_show_i2c_reg(struct class_device* cd, char* buf)
967{
968 struct sn9c102_device* cam;
969 ssize_t count;
970
971 if (down_interruptible(&sn9c102_sysfs_lock))
972 return -ERESTARTSYS;
973
974 cam = video_get_drvdata(to_video_device(cd));
975 if (!cam) {
976 up(&sn9c102_sysfs_lock);
977 return -ENODEV;
978 }
979
980 count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
981
982 DBG(3, "Read bytes: %zd", count)
983
984 up(&sn9c102_sysfs_lock);
985
986 return count;
987}
988
989
990static ssize_t
991sn9c102_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
992{
993 struct sn9c102_device* cam;
994 u8 index;
995 ssize_t count;
996
997 if (down_interruptible(&sn9c102_sysfs_lock))
998 return -ERESTARTSYS;
999
1000 cam = video_get_drvdata(to_video_device(cd));
1001 if (!cam) {
1002 up(&sn9c102_sysfs_lock);
1003 return -ENODEV;
1004 }
1005
1006 index = sn9c102_strtou8(buf, len, &count);
1007 if (!count) {
1008 up(&sn9c102_sysfs_lock);
1009 return -EINVAL;
1010 }
1011
1012 cam->sysfs.i2c_reg = index;
1013
1014 DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg)
1015 DBG(3, "Written bytes: %zd", count)
1016
1017 up(&sn9c102_sysfs_lock);
1018
1019 return count;
1020}
1021
1022
1023static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf)
1024{
1025 struct sn9c102_device* cam;
1026 ssize_t count;
1027 int val;
1028
1029 if (down_interruptible(&sn9c102_sysfs_lock))
1030 return -ERESTARTSYS;
1031
1032 cam = video_get_drvdata(to_video_device(cd));
1033 if (!cam) {
1034 up(&sn9c102_sysfs_lock);
1035 return -ENODEV;
1036 }
1037
1038 if (!(cam->sensor->sysfs_ops & SN9C102_I2C_READ)) {
1039 up(&sn9c102_sysfs_lock);
1040 return -ENOSYS;
1041 }
1042
1043 if ((val = sn9c102_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) {
1044 up(&sn9c102_sysfs_lock);
1045 return -EIO;
1046 }
1047
1048 count = sprintf(buf, "%d\n", val);
1049
1050 DBG(3, "Read bytes: %zd", count)
1051
1052 up(&sn9c102_sysfs_lock);
1053
1054 return count;
1055}
1056
1057
1058static ssize_t
1059sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
1060{
1061 struct sn9c102_device* cam;
1062 u8 value;
1063 ssize_t count;
1064 int err;
1065
1066 if (down_interruptible(&sn9c102_sysfs_lock))
1067 return -ERESTARTSYS;
1068
1069 cam = video_get_drvdata(to_video_device(cd));
1070 if (!cam) {
1071 up(&sn9c102_sysfs_lock);
1072 return -ENODEV;
1073 }
1074
1075 if (!(cam->sensor->sysfs_ops & SN9C102_I2C_WRITE)) {
1076 up(&sn9c102_sysfs_lock);
1077 return -ENOSYS;
1078 }
1079
1080 value = sn9c102_strtou8(buf, len, &count);
1081 if (!count) {
1082 up(&sn9c102_sysfs_lock);
1083 return -EINVAL;
1084 }
1085
1086 err = sn9c102_i2c_write(cam, cam->sysfs.i2c_reg, value);
1087 if (err) {
1088 up(&sn9c102_sysfs_lock);
1089 return -EIO;
1090 }
1091
1092 DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
1093 cam->sysfs.i2c_reg, value)
1094 DBG(3, "Written bytes: %zd", count)
1095
1096 up(&sn9c102_sysfs_lock);
1097
1098 return count;
1099}
1100
1101
1102static ssize_t
1103sn9c102_store_green(struct class_device* cd, const char* buf, size_t len)
1104{
1105 struct sn9c102_device* cam;
1106 enum sn9c102_bridge bridge;
1107 ssize_t res = 0;
1108 u8 value;
1109 ssize_t count;
1110
1111 if (down_interruptible(&sn9c102_sysfs_lock))
1112 return -ERESTARTSYS;
1113
1114 cam = video_get_drvdata(to_video_device(cd));
1115 if (!cam) {
1116 up(&sn9c102_sysfs_lock);
1117 return -ENODEV;
1118 }
1119
1120 bridge = cam->bridge;
1121
1122 up(&sn9c102_sysfs_lock);
1123
1124 value = sn9c102_strtou8(buf, len, &count);
1125 if (!count)
1126 return -EINVAL;
1127
1128 switch (bridge) {
1129 case BRIDGE_SN9C101:
1130 case BRIDGE_SN9C102:
1131 if (value > 0x0f)
1132 return -EINVAL;
1133 if ((res = sn9c102_store_reg(cd, "0x11", 4)) >= 0)
1134 res = sn9c102_store_val(cd, buf, len);
1135 break;
1136 case BRIDGE_SN9C103:
1137 if (value > 0x7f)
1138 return -EINVAL;
1139 if ((res = sn9c102_store_reg(cd, "0x04", 4)) >= 0)
1140 res = sn9c102_store_val(cd, buf, len);
1141 break;
1142 }
1143
1144 return res;
1145}
1146
1147
1148static ssize_t
1149sn9c102_store_blue(struct class_device* cd, const char* buf, size_t len)
1150{
1151 ssize_t res = 0;
1152 u8 value;
1153 ssize_t count;
1154
1155 value = sn9c102_strtou8(buf, len, &count);
1156 if (!count || value > 0x7f)
1157 return -EINVAL;
1158
1159 if ((res = sn9c102_store_reg(cd, "0x06", 4)) >= 0)
1160 res = sn9c102_store_val(cd, buf, len);
1161
1162 return res;
1163}
1164
1165
1166static ssize_t
1167sn9c102_store_red(struct class_device* cd, const char* buf, size_t len)
1168{
1169 ssize_t res = 0;
1170 u8 value;
1171 ssize_t count;
1172
1173 value = sn9c102_strtou8(buf, len, &count);
1174 if (!count || value > 0x7f)
1175 return -EINVAL;
1176
1177 if ((res = sn9c102_store_reg(cd, "0x05", 4)) >= 0)
1178 res = sn9c102_store_val(cd, buf, len);
1179
1180 return res;
1181}
1182
1183
1184static ssize_t sn9c102_show_frame_header(struct class_device* cd, char* buf)
1185{
1186 struct sn9c102_device* cam;
1187 ssize_t count;
1188
1189 cam = video_get_drvdata(to_video_device(cd));
1190 if (!cam)
1191 return -ENODEV;
1192
1193 count = sizeof(cam->sysfs.frame_header);
1194 memcpy(buf, cam->sysfs.frame_header, count);
1195
1196 DBG(3, "Frame header, read bytes: %zd", count)
1197
1198 return count;
1199}
1200
1201
1202static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
1203 sn9c102_show_reg, sn9c102_store_reg);
1204static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
1205 sn9c102_show_val, sn9c102_store_val);
1206static CLASS_DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
1207 sn9c102_show_i2c_reg, sn9c102_store_i2c_reg);
1208static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
1209 sn9c102_show_i2c_val, sn9c102_store_i2c_val);
1210static CLASS_DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green);
1211static CLASS_DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue);
1212static CLASS_DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red);
1213static CLASS_DEVICE_ATTR(frame_header, S_IRUGO,
1214 sn9c102_show_frame_header, NULL);
1215
1216
1217static void sn9c102_create_sysfs(struct sn9c102_device* cam)
1218{
1219 struct video_device *v4ldev = cam->v4ldev;
1220
1221 video_device_create_file(v4ldev, &class_device_attr_reg);
1222 video_device_create_file(v4ldev, &class_device_attr_val);
1223 video_device_create_file(v4ldev, &class_device_attr_frame_header);
1224 if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
1225 video_device_create_file(v4ldev, &class_device_attr_green);
1226 else if (cam->bridge == BRIDGE_SN9C103) {
1227 video_device_create_file(v4ldev, &class_device_attr_blue);
1228 video_device_create_file(v4ldev, &class_device_attr_red);
1229 }
1230 if (cam->sensor->sysfs_ops) {
1231 video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
1232 video_device_create_file(v4ldev, &class_device_attr_i2c_val);
1233 }
1234}
1235
1236/*****************************************************************************/
1237
1238static int
1239sn9c102_set_pix_format(struct sn9c102_device* cam, struct v4l2_pix_format* pix)
1240{
1241 int err = 0;
1242
1243 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
1244 err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80, 0x18);
1245 else
1246 err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f, 0x18);
1247
1248 return err ? -EIO : 0;
1249}
1250
1251
1252static int
1253sn9c102_set_compression(struct sn9c102_device* cam,
1254 struct v4l2_jpegcompression* compression)
1255{
1256 int err = 0;
1257
1258 if (compression->quality == 0)
1259 err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01, 0x17);
1260 else if (compression->quality == 1)
1261 err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe, 0x17);
1262
1263 return err ? -EIO : 0;
1264}
1265
1266
1267static int sn9c102_set_scale(struct sn9c102_device* cam, u8 scale)
1268{
1269 u8 r = 0;
1270 int err = 0;
1271
1272 if (scale == 1)
1273 r = cam->reg[0x18] & 0xcf;
1274 else if (scale == 2) {
1275 r = cam->reg[0x18] & 0xcf;
1276 r |= 0x10;
1277 } else if (scale == 4)
1278 r = cam->reg[0x18] | 0x20;
1279
1280 err += sn9c102_write_reg(cam, r, 0x18);
1281 if (err)
1282 return -EIO;
1283
1284 PDBGG("Scaling factor: %u", scale)
1285
1286 return 0;
1287}
1288
1289
1290static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect)
1291{
1292 struct sn9c102_sensor* s = cam->sensor;
1293 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left),
1294 v_start = (u8)(rect->top - s->cropcap.bounds.top),
1295 h_size = (u8)(rect->width / 16),
1296 v_size = (u8)(rect->height / 16);
1297 int err = 0;
1298
1299 err += sn9c102_write_reg(cam, h_start, 0x12);
1300 err += sn9c102_write_reg(cam, v_start, 0x13);
1301 err += sn9c102_write_reg(cam, h_size, 0x15);
1302 err += sn9c102_write_reg(cam, v_size, 0x16);
1303 if (err)
1304 return -EIO;
1305
1306 PDBGG("h_start, v_start, h_size, v_size, ho_size, vo_size "
1307 "%u %u %u %u", h_start, v_start, h_size, v_size)
1308
1309 return 0;
1310}
1311
1312
1313static int sn9c102_init(struct sn9c102_device* cam)
1314{
1315 struct sn9c102_sensor* s = cam->sensor;
1316 struct v4l2_control ctrl;
1317 struct v4l2_queryctrl *qctrl;
1318 struct v4l2_rect* rect;
1319 u8 i = 0, n = 0;
1320 int err = 0;
1321
1322 if (!(cam->state & DEV_INITIALIZED)) {
1323 init_waitqueue_head(&cam->open);
1324 qctrl = s->qctrl;
1325 rect = &(s->cropcap.defrect);
1326 } else { /* use current values */
1327 qctrl = s->_qctrl;
1328 rect = &(s->_rect);
1329 }
1330
1331 err += sn9c102_set_scale(cam, rect->width / s->pix_format.width);
1332 err += sn9c102_set_crop(cam, rect);
1333 if (err)
1334 return err;
1335
1336 if (s->init) {
1337 err = s->init(cam);
1338 if (err) {
1339 DBG(3, "Sensor initialization failed")
1340 return err;
1341 }
1342 }
1343
1344 if (!(cam->state & DEV_INITIALIZED))
1345 cam->compression.quality = cam->reg[0x17] & 0x01 ? 0 : 1;
1346 else
1347 err += sn9c102_set_compression(cam, &cam->compression);
1348 err += sn9c102_set_pix_format(cam, &s->pix_format);
1349 if (s->set_pix_format)
1350 err += s->set_pix_format(cam, &s->pix_format);
1351 if (err)
1352 return err;
1353
1354 if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
1355 DBG(3, "Compressed video format is active, quality %d",
1356 cam->compression.quality)
1357 else
1358 DBG(3, "Uncompressed video format is active")
1359
1360 if (s->set_crop)
1361 if ((err = s->set_crop(cam, rect))) {
1362 DBG(3, "set_crop() failed")
1363 return err;
1364 }
1365
1366 if (s->set_ctrl) {
1367 n = sizeof(s->qctrl) / sizeof(s->qctrl[0]);
1368 for (i = 0; i < n; i++)
1369 if (s->qctrl[i].id != 0 &&
1370 !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
1371 ctrl.id = s->qctrl[i].id;
1372 ctrl.value = qctrl[i].default_value;
1373 err = s->set_ctrl(cam, &ctrl);
1374 if (err) {
1375 DBG(3, "Set %s control failed",
1376 s->qctrl[i].name)
1377 return err;
1378 }
1379 DBG(3, "Image sensor supports '%s' control",
1380 s->qctrl[i].name)
1381 }
1382 }
1383
1384 if (!(cam->state & DEV_INITIALIZED)) {
1385 init_MUTEX(&cam->fileop_sem);
1386 spin_lock_init(&cam->queue_lock);
1387 init_waitqueue_head(&cam->wait_frame);
1388 init_waitqueue_head(&cam->wait_stream);
1389 cam->nreadbuffers = 2;
1390 memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
1391 memcpy(&(s->_rect), &(s->cropcap.defrect),
1392 sizeof(struct v4l2_rect));
1393 cam->state |= DEV_INITIALIZED;
1394 }
1395
1396 DBG(2, "Initialization succeeded")
1397 return 0;
1398}
1399
1400
1401static void sn9c102_release_resources(struct sn9c102_device* cam)
1402{
1403 down(&sn9c102_sysfs_lock);
1404
1405 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor)
1406 video_set_drvdata(cam->v4ldev, NULL);
1407 video_unregister_device(cam->v4ldev);
1408
1409 up(&sn9c102_sysfs_lock);
1410
1411 kfree(cam->control_buffer);
1412}
1413
1414/*****************************************************************************/
1415
1416static int sn9c102_open(struct inode* inode, struct file* filp)
1417{
1418 struct sn9c102_device* cam;
1419 int err = 0;
1420
1421 /*
1422 This is the only safe way to prevent race conditions with
1423 disconnect
1424 */
1425 if (!down_read_trylock(&sn9c102_disconnect))
1426 return -ERESTARTSYS;
1427
1428 cam = video_get_drvdata(video_devdata(filp));
1429
1430 if (down_interruptible(&cam->dev_sem)) {
1431 up_read(&sn9c102_disconnect);
1432 return -ERESTARTSYS;
1433 }
1434
1435 if (cam->users) {
1436 DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor)
1437 if ((filp->f_flags & O_NONBLOCK) ||
1438 (filp->f_flags & O_NDELAY)) {
1439 err = -EWOULDBLOCK;
1440 goto out;
1441 }
1442 up(&cam->dev_sem);
1443 err = wait_event_interruptible_exclusive(cam->open,
1444 cam->state & DEV_DISCONNECTED
1445 || !cam->users);
1446 if (err) {
1447 up_read(&sn9c102_disconnect);
1448 return err;
1449 }
1450 if (cam->state & DEV_DISCONNECTED) {
1451 up_read(&sn9c102_disconnect);
1452 return -ENODEV;
1453 }
1454 down(&cam->dev_sem);
1455 }
1456
1457
1458 if (cam->state & DEV_MISCONFIGURED) {
1459 err = sn9c102_init(cam);
1460 if (err) {
1461 DBG(1, "Initialization failed again. "
1462 "I will retry on next open().")
1463 goto out;
1464 }
1465 cam->state &= ~DEV_MISCONFIGURED;
1466 }
1467
1468 if ((err = sn9c102_start_transfer(cam)))
1469 goto out;
1470
1471 filp->private_data = cam;
1472 cam->users++;
1473 cam->io = IO_NONE;
1474 cam->stream = STREAM_OFF;
1475 cam->nbuffers = 0;
1476 cam->frame_count = 0;
1477 sn9c102_empty_framequeues(cam);
1478
1479 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor)
1480
1481out:
1482 up(&cam->dev_sem);
1483 up_read(&sn9c102_disconnect);
1484 return err;
1485}
1486
1487
1488static int sn9c102_release(struct inode* inode, struct file* filp)
1489{
1490 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1491
1492 down(&cam->dev_sem); /* prevent disconnect() to be called */
1493
1494 sn9c102_stop_transfer(cam);
1495
1496 sn9c102_release_buffers(cam);
1497
1498 if (cam->state & DEV_DISCONNECTED) {
1499 sn9c102_release_resources(cam);
1500 up(&cam->dev_sem);
1501 kfree(cam);
1502 return 0;
1503 }
1504
1505 cam->users--;
1506 wake_up_interruptible_nr(&cam->open, 1);
1507
1508 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor)
1509
1510 up(&cam->dev_sem);
1511
1512 return 0;
1513}
1514
1515
1516static ssize_t
1517sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1518{
1519 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1520 struct sn9c102_frame_t* f, * i;
1521 unsigned long lock_flags;
1522 int err = 0;
1523
1524 if (down_interruptible(&cam->fileop_sem))
1525 return -ERESTARTSYS;
1526
1527 if (cam->state & DEV_DISCONNECTED) {
1528 DBG(1, "Device not present")
1529 up(&cam->fileop_sem);
1530 return -ENODEV;
1531 }
1532
1533 if (cam->state & DEV_MISCONFIGURED) {
1534 DBG(1, "The camera is misconfigured. Close and open it again.")
1535 up(&cam->fileop_sem);
1536 return -EIO;
1537 }
1538
1539 if (cam->io == IO_MMAP) {
1540 DBG(3, "Close and open the device again to choose "
1541 "the read method")
1542 up(&cam->fileop_sem);
1543 return -EINVAL;
1544 }
1545
1546 if (cam->io == IO_NONE) {
1547 if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) {
1548 DBG(1, "read() failed, not enough memory")
1549 up(&cam->fileop_sem);
1550 return -ENOMEM;
1551 }
1552 cam->io = IO_READ;
1553 cam->stream = STREAM_ON;
1554 sn9c102_queue_unusedframes(cam);
1555 }
1556
1557 if (!count) {
1558 up(&cam->fileop_sem);
1559 return 0;
1560 }
1561
1562 if (list_empty(&cam->outqueue)) {
1563 if (filp->f_flags & O_NONBLOCK) {
1564 up(&cam->fileop_sem);
1565 return -EAGAIN;
1566 }
1567 err = wait_event_interruptible
1568 ( cam->wait_frame,
1569 (!list_empty(&cam->outqueue)) ||
1570 (cam->state & DEV_DISCONNECTED) ||
1571 (cam->state & DEV_MISCONFIGURED) );
1572 if (err) {
1573 up(&cam->fileop_sem);
1574 return err;
1575 }
1576 if (cam->state & DEV_DISCONNECTED) {
1577 up(&cam->fileop_sem);
1578 return -ENODEV;
1579 }
1580 if (cam->state & DEV_MISCONFIGURED) {
1581 up(&cam->fileop_sem);
1582 return -EIO;
1583 }
1584 }
1585
1586 f = list_entry(cam->outqueue.prev, struct sn9c102_frame_t, frame);
1587
1588 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1589 list_for_each_entry(i, &cam->outqueue, frame)
1590 i->state = F_UNUSED;
1591 INIT_LIST_HEAD(&cam->outqueue);
1592 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1593
1594 sn9c102_queue_unusedframes(cam);
1595
1596 if (count > f->buf.bytesused)
1597 count = f->buf.bytesused;
1598
1599 if (copy_to_user(buf, f->bufmem, count)) {
1600 up(&cam->fileop_sem);
1601 return -EFAULT;
1602 }
1603 *f_pos += count;
1604
1605 PDBGG("Frame #%lu, bytes read: %zu", (unsigned long)f->buf.index,count)
1606
1607 up(&cam->fileop_sem);
1608
1609 return count;
1610}
1611
1612
1613static unsigned int sn9c102_poll(struct file *filp, poll_table *wait)
1614{
1615 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1616 unsigned int mask = 0;
1617
1618 if (down_interruptible(&cam->fileop_sem))
1619 return POLLERR;
1620
1621 if (cam->state & DEV_DISCONNECTED) {
1622 DBG(1, "Device not present")
1623 goto error;
1624 }
1625
1626 if (cam->state & DEV_MISCONFIGURED) {
1627 DBG(1, "The camera is misconfigured. Close and open it again.")
1628 goto error;
1629 }
1630
1631 if (cam->io == IO_NONE) {
1632 if (!sn9c102_request_buffers(cam, cam->nreadbuffers,
1633 IO_READ)) {
1634 DBG(1, "poll() failed, not enough memory")
1635 goto error;
1636 }
1637 cam->io = IO_READ;
1638 cam->stream = STREAM_ON;
1639 }
1640
1641 if (cam->io == IO_READ)
1642 sn9c102_queue_unusedframes(cam);
1643
1644 poll_wait(filp, &cam->wait_frame, wait);
1645
1646 if (!list_empty(&cam->outqueue))
1647 mask |= POLLIN | POLLRDNORM;
1648
1649 up(&cam->fileop_sem);
1650
1651 return mask;
1652
1653error:
1654 up(&cam->fileop_sem);
1655 return POLLERR;
1656}
1657
1658
1659static void sn9c102_vm_open(struct vm_area_struct* vma)
1660{
1661 struct sn9c102_frame_t* f = vma->vm_private_data;
1662 f->vma_use_count++;
1663}
1664
1665
1666static void sn9c102_vm_close(struct vm_area_struct* vma)
1667{
1668 /* NOTE: buffers are not freed here */
1669 struct sn9c102_frame_t* f = vma->vm_private_data;
1670 f->vma_use_count--;
1671}
1672
1673
1674static struct vm_operations_struct sn9c102_vm_ops = {
1675 .open = sn9c102_vm_open,
1676 .close = sn9c102_vm_close,
1677};
1678
1679
1680static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
1681{
1682 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1683 unsigned long size = vma->vm_end - vma->vm_start,
1684 start = vma->vm_start,
1685 pos,
1686 page;
1687 u32 i;
1688
1689 if (down_interruptible(&cam->fileop_sem))
1690 return -ERESTARTSYS;
1691
1692 if (cam->state & DEV_DISCONNECTED) {
1693 DBG(1, "Device not present")
1694 up(&cam->fileop_sem);
1695 return -ENODEV;
1696 }
1697
1698 if (cam->state & DEV_MISCONFIGURED) {
1699 DBG(1, "The camera is misconfigured. Close and open it again.")
1700 up(&cam->fileop_sem);
1701 return -EIO;
1702 }
1703
1704 if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
1705 size != PAGE_ALIGN(cam->frame[0].buf.length)) {
1706 up(&cam->fileop_sem);
1707 return -EINVAL;
1708 }
1709
1710 for (i = 0; i < cam->nbuffers; i++) {
1711 if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
1712 break;
1713 }
1714 if (i == cam->nbuffers) {
1715 up(&cam->fileop_sem);
1716 return -EINVAL;
1717 }
1718
1719 /* VM_IO is eventually going to replace PageReserved altogether */
1720 vma->vm_flags |= VM_IO;
1721 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
1722
1723 pos = (unsigned long)cam->frame[i].bufmem;
1724 while (size > 0) { /* size is page-aligned */
1725 page = vmalloc_to_pfn((void *)pos);
1726 if (remap_pfn_range(vma, start, page, PAGE_SIZE,
1727 vma->vm_page_prot)) {
1728 up(&cam->fileop_sem);
1729 return -EAGAIN;
1730 }
1731 start += PAGE_SIZE;
1732 pos += PAGE_SIZE;
1733 size -= PAGE_SIZE;
1734 }
1735
1736 vma->vm_ops = &sn9c102_vm_ops;
1737 vma->vm_private_data = &cam->frame[i];
1738
1739 sn9c102_vm_open(vma);
1740
1741 up(&cam->fileop_sem);
1742
1743 return 0;
1744}
1745
1746
1747static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
1748 unsigned int cmd, void __user * arg)
1749{
1750 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1751
1752 switch (cmd) {
1753
1754 case VIDIOC_QUERYCAP:
1755 {
1756 struct v4l2_capability cap = {
1757 .driver = "sn9c102",
1758 .version = SN9C102_MODULE_VERSION_CODE,
1759 .capabilities = V4L2_CAP_VIDEO_CAPTURE |
1760 V4L2_CAP_READWRITE |
1761 V4L2_CAP_STREAMING,
1762 };
1763
1764 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
1765 if (usb_make_path(cam->usbdev, cap.bus_info,
1766 sizeof(cap.bus_info)) < 0)
1767 strlcpy(cap.bus_info, cam->dev.bus_id,
1768 sizeof(cap.bus_info));
1769
1770 if (copy_to_user(arg, &cap, sizeof(cap)))
1771 return -EFAULT;
1772
1773 return 0;
1774 }
1775
1776 case VIDIOC_ENUMINPUT:
1777 {
1778 struct v4l2_input i;
1779
1780 if (copy_from_user(&i, arg, sizeof(i)))
1781 return -EFAULT;
1782
1783 if (i.index)
1784 return -EINVAL;
1785
1786 memset(&i, 0, sizeof(i));
1787 strcpy(i.name, "USB");
1788
1789 if (copy_to_user(arg, &i, sizeof(i)))
1790 return -EFAULT;
1791
1792 return 0;
1793 }
1794
1795 case VIDIOC_G_INPUT:
1796 case VIDIOC_S_INPUT:
1797 {
1798 int index;
1799
1800 if (copy_from_user(&index, arg, sizeof(index)))
1801 return -EFAULT;
1802
1803 if (index != 0)
1804 return -EINVAL;
1805
1806 return 0;
1807 }
1808
1809 case VIDIOC_QUERYCTRL:
1810 {
1811 struct sn9c102_sensor* s = cam->sensor;
1812 struct v4l2_queryctrl qc;
1813 u8 i, n;
1814
1815 if (copy_from_user(&qc, arg, sizeof(qc)))
1816 return -EFAULT;
1817
1818 n = sizeof(s->qctrl) / sizeof(s->qctrl[0]);
1819 for (i = 0; i < n; i++)
1820 if (qc.id && qc.id == s->qctrl[i].id) {
1821 memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
1822 if (copy_to_user(arg, &qc, sizeof(qc)))
1823 return -EFAULT;
1824 return 0;
1825 }
1826
1827 return -EINVAL;
1828 }
1829
1830 case VIDIOC_G_CTRL:
1831 {
1832 struct sn9c102_sensor* s = cam->sensor;
1833 struct v4l2_control ctrl;
1834 int err = 0;
1835
1836 if (!s->get_ctrl)
1837 return -EINVAL;
1838
1839 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1840 return -EFAULT;
1841
1842 err = s->get_ctrl(cam, &ctrl);
1843
1844 if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
1845 return -EFAULT;
1846
1847 return err;
1848 }
1849
1850 case VIDIOC_S_CTRL_OLD:
1851 case VIDIOC_S_CTRL:
1852 {
1853 struct sn9c102_sensor* s = cam->sensor;
1854 struct v4l2_control ctrl;
1855 u8 i, n;
1856 int err = 0;
1857
1858 if (!s->set_ctrl)
1859 return -EINVAL;
1860
1861 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1862 return -EFAULT;
1863
1864 n = sizeof(s->qctrl) / sizeof(s->qctrl[0]);
1865 for (i = 0; i < n; i++)
1866 if (ctrl.id == s->qctrl[i].id) {
1867 if (ctrl.value < s->qctrl[i].minimum ||
1868 ctrl.value > s->qctrl[i].maximum)
1869 return -ERANGE;
1870 ctrl.value -= ctrl.value % s->qctrl[i].step;
1871 break;
1872 }
1873
1874 if ((err = s->set_ctrl(cam, &ctrl)))
1875 return err;
1876
1877 s->_qctrl[i].default_value = ctrl.value;
1878
1879 PDBGG("VIDIOC_S_CTRL: id %lu, value %lu",
1880 (unsigned long)ctrl.id, (unsigned long)ctrl.value)
1881
1882 return 0;
1883 }
1884
1885 case VIDIOC_CROPCAP:
1886 {
1887 struct v4l2_cropcap* cc = &(cam->sensor->cropcap);
1888
1889 cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1890 cc->pixelaspect.numerator = 1;
1891 cc->pixelaspect.denominator = 1;
1892
1893 if (copy_to_user(arg, cc, sizeof(*cc)))
1894 return -EFAULT;
1895
1896 return 0;
1897 }
1898
1899 case VIDIOC_G_CROP:
1900 {
1901 struct sn9c102_sensor* s = cam->sensor;
1902 struct v4l2_crop crop = {
1903 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1904 };
1905
1906 memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
1907
1908 if (copy_to_user(arg, &crop, sizeof(crop)))
1909 return -EFAULT;
1910
1911 return 0;
1912 }
1913
1914 case VIDIOC_S_CROP:
1915 {
1916 struct sn9c102_sensor* s = cam->sensor;
1917 struct v4l2_crop crop;
1918 struct v4l2_rect* rect;
1919 struct v4l2_rect* bounds = &(s->cropcap.bounds);
1920 struct v4l2_pix_format* pix_format = &(s->pix_format);
1921 u8 scale;
1922 const enum sn9c102_stream_state stream = cam->stream;
1923 const u32 nbuffers = cam->nbuffers;
1924 u32 i;
1925 int err = 0;
1926
1927 if (copy_from_user(&crop, arg, sizeof(crop)))
1928 return -EFAULT;
1929
1930 rect = &(crop.c);
1931
1932 if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1933 return -EINVAL;
1934
1935 if (cam->module_param.force_munmap)
1936 for (i = 0; i < cam->nbuffers; i++)
1937 if (cam->frame[i].vma_use_count) {
1938 DBG(3, "VIDIOC_S_CROP failed. "
1939 "Unmap the buffers first.")
1940 return -EINVAL;
1941 }
1942
1943 /* Preserve R,G or B origin */
1944 rect->left = (s->_rect.left & 1L) ?
1945 rect->left | 1L : rect->left & ~1L;
1946 rect->top = (s->_rect.top & 1L) ?
1947 rect->top | 1L : rect->top & ~1L;
1948
1949 if (rect->width < 16)
1950 rect->width = 16;
1951 if (rect->height < 16)
1952 rect->height = 16;
1953 if (rect->width > bounds->width)
1954 rect->width = bounds->width;
1955 if (rect->height > bounds->height)
1956 rect->height = bounds->height;
1957 if (rect->left < bounds->left)
1958 rect->left = bounds->left;
1959 if (rect->top < bounds->top)
1960 rect->top = bounds->top;
1961 if (rect->left + rect->width > bounds->left + bounds->width)
1962 rect->left = bounds->left+bounds->width - rect->width;
1963 if (rect->top + rect->height > bounds->top + bounds->height)
1964 rect->top = bounds->top+bounds->height - rect->height;
1965
1966 rect->width &= ~15L;
1967 rect->height &= ~15L;
1968
1969 if (SN9C102_PRESERVE_IMGSCALE) {
1970 /* Calculate the actual scaling factor */
1971 u32 a, b;
1972 a = rect->width * rect->height;
1973 b = pix_format->width * pix_format->height;
1974 scale = b ? (u8)((a / b) < 4 ? 1 :
1975 ((a / b) < 16 ? 2 : 4)) : 1;
1976 } else
1977 scale = 1;
1978
1979 if (cam->stream == STREAM_ON)
1980 if ((err = sn9c102_stream_interrupt(cam)))
1981 return err;
1982
1983 if (copy_to_user(arg, &crop, sizeof(crop))) {
1984 cam->stream = stream;
1985 return -EFAULT;
1986 }
1987
1988 if (cam->module_param.force_munmap || cam->io == IO_READ)
1989 sn9c102_release_buffers(cam);
1990
1991 err = sn9c102_set_crop(cam, rect);
1992 if (s->set_crop)
1993 err += s->set_crop(cam, rect);
1994 err += sn9c102_set_scale(cam, scale);
1995
1996 if (err) { /* atomic, no rollback in ioctl() */
1997 cam->state |= DEV_MISCONFIGURED;
1998 DBG(1, "VIDIOC_S_CROP failed because of hardware "
1999 "problems. To use the camera, close and open "
2000 "/dev/video%d again.", cam->v4ldev->minor)
2001 return -EIO;
2002 }
2003
2004 s->pix_format.width = rect->width/scale;
2005 s->pix_format.height = rect->height/scale;
2006 memcpy(&(s->_rect), rect, sizeof(*rect));
2007
2008 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
2009 nbuffers != sn9c102_request_buffers(cam, nbuffers,
2010 cam->io)) {
2011 cam->state |= DEV_MISCONFIGURED;
2012 DBG(1, "VIDIOC_S_CROP failed because of not enough "
2013 "memory. To use the camera, close and open "
2014 "/dev/video%d again.", cam->v4ldev->minor)
2015 return -ENOMEM;
2016 }
2017
2018 cam->stream = stream;
2019
2020 return 0;
2021 }
2022
2023 case VIDIOC_ENUM_FMT:
2024 {
2025 struct v4l2_fmtdesc fmtd;
2026
2027 if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
2028 return -EFAULT;
2029
2030 if (fmtd.index == 0) {
2031 strcpy(fmtd.description, "bayer rgb");
2032 fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
2033 } else if (fmtd.index == 1) {
2034 strcpy(fmtd.description, "compressed");
2035 fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
2036 fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
2037 } else
2038 return -EINVAL;
2039
2040 fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2041 memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
2042
2043 if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
2044 return -EFAULT;
2045
2046 return 0;
2047 }
2048
2049 case VIDIOC_G_FMT:
2050 {
2051 struct v4l2_format format;
2052 struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format);
2053
2054 if (copy_from_user(&format, arg, sizeof(format)))
2055 return -EFAULT;
2056
2057 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2058 return -EINVAL;
2059
2060 pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X)
2061 ? 0 : (pfmt->width * pfmt->priv) / 8;
2062 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
2063 pfmt->field = V4L2_FIELD_NONE;
2064 memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
2065
2066 if (copy_to_user(arg, &format, sizeof(format)))
2067 return -EFAULT;
2068
2069 return 0;
2070 }
2071
2072 case VIDIOC_TRY_FMT:
2073 case VIDIOC_S_FMT:
2074 {
2075 struct sn9c102_sensor* s = cam->sensor;
2076 struct v4l2_format format;
2077 struct v4l2_pix_format* pix;
2078 struct v4l2_pix_format* pfmt = &(s->pix_format);
2079 struct v4l2_rect* bounds = &(s->cropcap.bounds);
2080 struct v4l2_rect rect;
2081 u8 scale;
2082 const enum sn9c102_stream_state stream = cam->stream;
2083 const u32 nbuffers = cam->nbuffers;
2084 u32 i;
2085 int err = 0;
2086
2087 if (copy_from_user(&format, arg, sizeof(format)))
2088 return -EFAULT;
2089
2090 pix = &(format.fmt.pix);
2091
2092 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2093 return -EINVAL;
2094
2095 memcpy(&rect, &(s->_rect), sizeof(rect));
2096
2097 { /* calculate the actual scaling factor */
2098 u32 a, b;
2099 a = rect.width * rect.height;
2100 b = pix->width * pix->height;
2101 scale = b ? (u8)((a / b) < 4 ? 1 :
2102 ((a / b) < 16 ? 2 : 4)) : 1;
2103 }
2104
2105 rect.width = scale * pix->width;
2106 rect.height = scale * pix->height;
2107
2108 if (rect.width < 16)
2109 rect.width = 16;
2110 if (rect.height < 16)
2111 rect.height = 16;
2112 if (rect.width > bounds->left + bounds->width - rect.left)
2113 rect.width = bounds->left + bounds->width - rect.left;
2114 if (rect.height > bounds->top + bounds->height - rect.top)
2115 rect.height = bounds->top + bounds->height - rect.top;
2116
2117 rect.width &= ~15L;
2118 rect.height &= ~15L;
2119
2120 { /* adjust the scaling factor */
2121 u32 a, b;
2122 a = rect.width * rect.height;
2123 b = pix->width * pix->height;
2124 scale = b ? (u8)((a / b) < 4 ? 1 :
2125 ((a / b) < 16 ? 2 : 4)) : 1;
2126 }
2127
2128 pix->width = rect.width / scale;
2129 pix->height = rect.height / scale;
2130
2131 if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
2132 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
2133 pix->pixelformat = pfmt->pixelformat;
2134 pix->priv = pfmt->priv; /* bpp */
2135 pix->colorspace = pfmt->colorspace;
2136 pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
2137 ? 0 : (pix->width * pix->priv) / 8;
2138 pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
2139 pix->field = V4L2_FIELD_NONE;
2140
2141 if (cmd == VIDIOC_TRY_FMT) {
2142 if (copy_to_user(arg, &format, sizeof(format)))
2143 return -EFAULT;
2144 return 0;
2145 }
2146
2147 if (cam->module_param.force_munmap)
2148 for (i = 0; i < cam->nbuffers; i++)
2149 if (cam->frame[i].vma_use_count) {
2150 DBG(3, "VIDIOC_S_FMT failed. "
2151 "Unmap the buffers first.")
2152 return -EINVAL;
2153 }
2154
2155 if (cam->stream == STREAM_ON)
2156 if ((err = sn9c102_stream_interrupt(cam)))
2157 return err;
2158
2159 if (copy_to_user(arg, &format, sizeof(format))) {
2160 cam->stream = stream;
2161 return -EFAULT;
2162 }
2163
2164 if (cam->module_param.force_munmap || cam->io == IO_READ)
2165 sn9c102_release_buffers(cam);
2166
2167 err += sn9c102_set_pix_format(cam, pix);
2168 err += sn9c102_set_crop(cam, &rect);
2169 if (s->set_pix_format)
2170 err += s->set_pix_format(cam, pix);
2171 if (s->set_crop)
2172 err += s->set_crop(cam, &rect);
2173 err += sn9c102_set_scale(cam, scale);
2174
2175 if (err) { /* atomic, no rollback in ioctl() */
2176 cam->state |= DEV_MISCONFIGURED;
2177 DBG(1, "VIDIOC_S_FMT failed because of hardware "
2178 "problems. To use the camera, close and open "
2179 "/dev/video%d again.", cam->v4ldev->minor)
2180 return -EIO;
2181 }
2182
2183 memcpy(pfmt, pix, sizeof(*pix));
2184 memcpy(&(s->_rect), &rect, sizeof(rect));
2185
2186 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
2187 nbuffers != sn9c102_request_buffers(cam, nbuffers,
2188 cam->io)) {
2189 cam->state |= DEV_MISCONFIGURED;
2190 DBG(1, "VIDIOC_S_FMT failed because of not enough "
2191 "memory. To use the camera, close and open "
2192 "/dev/video%d again.", cam->v4ldev->minor)
2193 return -ENOMEM;
2194 }
2195
2196 cam->stream = stream;
2197
2198 return 0;
2199 }
2200
2201 case VIDIOC_G_JPEGCOMP:
2202 {
2203 if (copy_to_user(arg, &cam->compression,
2204 sizeof(cam->compression)))
2205 return -EFAULT;
2206
2207 return 0;
2208 }
2209
2210 case VIDIOC_S_JPEGCOMP:
2211 {
2212 struct v4l2_jpegcompression jc;
2213 const enum sn9c102_stream_state stream = cam->stream;
2214 int err = 0;
2215
2216 if (copy_from_user(&jc, arg, sizeof(jc)))
2217 return -EFAULT;
2218
2219 if (jc.quality != 0 && jc.quality != 1)
2220 return -EINVAL;
2221
2222 if (cam->stream == STREAM_ON)
2223 if ((err = sn9c102_stream_interrupt(cam)))
2224 return err;
2225
2226 err += sn9c102_set_compression(cam, &jc);
2227 if (err) { /* atomic, no rollback in ioctl() */
2228 cam->state |= DEV_MISCONFIGURED;
2229 DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
2230 "problems. To use the camera, close and open "
2231 "/dev/video%d again.", cam->v4ldev->minor)
2232 return -EIO;
2233 }
2234
2235 cam->compression.quality = jc.quality;
2236
2237 cam->stream = stream;
2238
2239 return 0;
2240 }
2241
2242 case VIDIOC_REQBUFS:
2243 {
2244 struct v4l2_requestbuffers rb;
2245 u32 i;
2246 int err;
2247
2248 if (copy_from_user(&rb, arg, sizeof(rb)))
2249 return -EFAULT;
2250
2251 if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2252 rb.memory != V4L2_MEMORY_MMAP)
2253 return -EINVAL;
2254
2255 if (cam->io == IO_READ) {
2256 DBG(3, "Close and open the device again to choose "
2257 "the mmap I/O method")
2258 return -EINVAL;
2259 }
2260
2261 for (i = 0; i < cam->nbuffers; i++)
2262 if (cam->frame[i].vma_use_count) {
2263 DBG(3, "VIDIOC_REQBUFS failed. "
2264 "Previous buffers are still mapped.")
2265 return -EINVAL;
2266 }
2267
2268 if (cam->stream == STREAM_ON)
2269 if ((err = sn9c102_stream_interrupt(cam)))
2270 return err;
2271
2272 sn9c102_empty_framequeues(cam);
2273
2274 sn9c102_release_buffers(cam);
2275 if (rb.count)
2276 rb.count = sn9c102_request_buffers(cam, rb.count,
2277 IO_MMAP);
2278
2279 if (copy_to_user(arg, &rb, sizeof(rb))) {
2280 sn9c102_release_buffers(cam);
2281 cam->io = IO_NONE;
2282 return -EFAULT;
2283 }
2284
2285 cam->io = rb.count ? IO_MMAP : IO_NONE;
2286
2287 return 0;
2288 }
2289
2290 case VIDIOC_QUERYBUF:
2291 {
2292 struct v4l2_buffer b;
2293
2294 if (copy_from_user(&b, arg, sizeof(b)))
2295 return -EFAULT;
2296
2297 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2298 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2299 return -EINVAL;
2300
2301 memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
2302
2303 if (cam->frame[b.index].vma_use_count)
2304 b.flags |= V4L2_BUF_FLAG_MAPPED;
2305
2306 if (cam->frame[b.index].state == F_DONE)
2307 b.flags |= V4L2_BUF_FLAG_DONE;
2308 else if (cam->frame[b.index].state != F_UNUSED)
2309 b.flags |= V4L2_BUF_FLAG_QUEUED;
2310
2311 if (copy_to_user(arg, &b, sizeof(b)))
2312 return -EFAULT;
2313
2314 return 0;
2315 }
2316
2317 case VIDIOC_QBUF:
2318 {
2319 struct v4l2_buffer b;
2320 unsigned long lock_flags;
2321
2322 if (copy_from_user(&b, arg, sizeof(b)))
2323 return -EFAULT;
2324
2325 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2326 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2327 return -EINVAL;
2328
2329 if (cam->frame[b.index].state != F_UNUSED)
2330 return -EINVAL;
2331
2332 cam->frame[b.index].state = F_QUEUED;
2333
2334 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2335 list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
2336 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2337
2338 PDBGG("Frame #%lu queued", (unsigned long)b.index)
2339
2340 return 0;
2341 }
2342
2343 case VIDIOC_DQBUF:
2344 {
2345 struct v4l2_buffer b;
2346 struct sn9c102_frame_t *f;
2347 unsigned long lock_flags;
2348 int err = 0;
2349
2350 if (copy_from_user(&b, arg, sizeof(b)))
2351 return -EFAULT;
2352
2353 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP)
2354 return -EINVAL;
2355
2356 if (list_empty(&cam->outqueue)) {
2357 if (cam->stream == STREAM_OFF)
2358 return -EINVAL;
2359 if (filp->f_flags & O_NONBLOCK)
2360 return -EAGAIN;
2361 err = wait_event_interruptible
2362 ( cam->wait_frame,
2363 (!list_empty(&cam->outqueue)) ||
2364 (cam->state & DEV_DISCONNECTED) ||
2365 (cam->state & DEV_MISCONFIGURED) );
2366 if (err)
2367 return err;
2368 if (cam->state & DEV_DISCONNECTED)
2369 return -ENODEV;
2370 if (cam->state & DEV_MISCONFIGURED)
2371 return -EIO;
2372 }
2373
2374 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2375 f = list_entry(cam->outqueue.next, struct sn9c102_frame_t,
2376 frame);
2377 list_del(cam->outqueue.next);
2378 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2379
2380 f->state = F_UNUSED;
2381
2382 memcpy(&b, &f->buf, sizeof(b));
2383 if (f->vma_use_count)
2384 b.flags |= V4L2_BUF_FLAG_MAPPED;
2385
2386 if (copy_to_user(arg, &b, sizeof(b)))
2387 return -EFAULT;
2388
2389 PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index)
2390
2391 return 0;
2392 }
2393
2394 case VIDIOC_STREAMON:
2395 {
2396 int type;
2397
2398 if (copy_from_user(&type, arg, sizeof(type)))
2399 return -EFAULT;
2400
2401 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2402 return -EINVAL;
2403
2404 if (list_empty(&cam->inqueue))
2405 return -EINVAL;
2406
2407 cam->stream = STREAM_ON;
2408
2409 DBG(3, "Stream on")
2410
2411 return 0;
2412 }
2413
2414 case VIDIOC_STREAMOFF:
2415 {
2416 int type, err;
2417
2418 if (copy_from_user(&type, arg, sizeof(type)))
2419 return -EFAULT;
2420
2421 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2422 return -EINVAL;
2423
2424 if (cam->stream == STREAM_ON)
2425 if ((err = sn9c102_stream_interrupt(cam)))
2426 return err;
2427
2428 sn9c102_empty_framequeues(cam);
2429
2430 DBG(3, "Stream off")
2431
2432 return 0;
2433 }
2434
2435 case VIDIOC_G_PARM:
2436 {
2437 struct v4l2_streamparm sp;
2438
2439 if (copy_from_user(&sp, arg, sizeof(sp)))
2440 return -EFAULT;
2441
2442 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2443 return -EINVAL;
2444
2445 sp.parm.capture.extendedmode = 0;
2446 sp.parm.capture.readbuffers = cam->nreadbuffers;
2447
2448 if (copy_to_user(arg, &sp, sizeof(sp)))
2449 return -EFAULT;
2450
2451 return 0;
2452 }
2453
2454 case VIDIOC_S_PARM_OLD:
2455 case VIDIOC_S_PARM:
2456 {
2457 struct v4l2_streamparm sp;
2458
2459 if (copy_from_user(&sp, arg, sizeof(sp)))
2460 return -EFAULT;
2461
2462 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2463 return -EINVAL;
2464
2465 sp.parm.capture.extendedmode = 0;
2466
2467 if (sp.parm.capture.readbuffers == 0)
2468 sp.parm.capture.readbuffers = cam->nreadbuffers;
2469
2470 if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES)
2471 sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES;
2472
2473 if (copy_to_user(arg, &sp, sizeof(sp)))
2474 return -EFAULT;
2475
2476 cam->nreadbuffers = sp.parm.capture.readbuffers;
2477
2478 return 0;
2479 }
2480
2481 case VIDIOC_G_STD:
2482 case VIDIOC_S_STD:
2483 case VIDIOC_QUERYSTD:
2484 case VIDIOC_ENUMSTD:
2485 case VIDIOC_QUERYMENU:
2486 return -EINVAL;
2487
2488 default:
2489 return -EINVAL;
2490
2491 }
2492}
2493
2494
2495static int sn9c102_ioctl(struct inode* inode, struct file* filp,
2496 unsigned int cmd, unsigned long arg)
2497{
2498 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
2499 int err = 0;
2500
2501 if (down_interruptible(&cam->fileop_sem))
2502 return -ERESTARTSYS;
2503
2504 if (cam->state & DEV_DISCONNECTED) {
2505 DBG(1, "Device not present")
2506 up(&cam->fileop_sem);
2507 return -ENODEV;
2508 }
2509
2510 if (cam->state & DEV_MISCONFIGURED) {
2511 DBG(1, "The camera is misconfigured. Close and open it again.")
2512 up(&cam->fileop_sem);
2513 return -EIO;
2514 }
2515
2516 err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
2517
2518 up(&cam->fileop_sem);
2519
2520 return err;
2521}
2522
2523
2524static struct file_operations sn9c102_fops = {
2525 .owner = THIS_MODULE,
2526 .open = sn9c102_open,
2527 .release = sn9c102_release,
2528 .ioctl = sn9c102_ioctl,
2529 .read = sn9c102_read,
2530 .poll = sn9c102_poll,
2531 .mmap = sn9c102_mmap,
2532 .llseek = no_llseek,
2533};
2534
2535/*****************************************************************************/
2536
2537/* It exists a single interface only. We do not need to validate anything. */
2538static int
2539sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2540{
2541 struct usb_device *udev = interface_to_usbdev(intf);
2542 struct sn9c102_device* cam;
2543 static unsigned int dev_nr = 0;
2544 unsigned int i, n;
2545 int err = 0, r;
2546
2547 n = sizeof(sn9c102_id_table)/sizeof(sn9c102_id_table[0]);
2548 for (i = 0; i < n-1; i++)
2549 if (le16_to_cpu(udev->descriptor.idVendor) ==
2550 sn9c102_id_table[i].idVendor &&
2551 le16_to_cpu(udev->descriptor.idProduct) ==
2552 sn9c102_id_table[i].idProduct)
2553 break;
2554 if (i == n-1)
2555 return -ENODEV;
2556
2557 if (!(cam = kmalloc(sizeof(struct sn9c102_device), GFP_KERNEL)))
2558 return -ENOMEM;
2559 memset(cam, 0, sizeof(*cam));
2560
2561 cam->usbdev = udev;
2562
2563 memcpy(&cam->dev, &udev->dev, sizeof(struct device));
2564
2565 if (!(cam->control_buffer = kmalloc(8, GFP_KERNEL))) {
2566 DBG(1, "kmalloc() failed")
2567 err = -ENOMEM;
2568 goto fail;
2569 }
2570 memset(cam->control_buffer, 0, 8);
2571
2572 if (!(cam->v4ldev = video_device_alloc())) {
2573 DBG(1, "video_device_alloc() failed")
2574 err = -ENOMEM;
2575 goto fail;
2576 }
2577
2578 init_MUTEX(&cam->dev_sem);
2579
2580 r = sn9c102_read_reg(cam, 0x00);
2581 if (r < 0 || r != 0x10) {
2582 DBG(1, "Sorry, this is not a SN9C10x based camera "
2583 "(vid/pid 0x%04X/0x%04X)",
2584 sn9c102_id_table[i].idVendor,sn9c102_id_table[i].idProduct)
2585 err = -ENODEV;
2586 goto fail;
2587 }
2588
2589 cam->bridge = (sn9c102_id_table[i].idProduct & 0xffc0) == 0x6080 ?
2590 BRIDGE_SN9C103 : BRIDGE_SN9C102;
2591 switch (cam->bridge) {
2592 case BRIDGE_SN9C101:
2593 case BRIDGE_SN9C102:
2594 DBG(2, "SN9C10[12] PC Camera Controller detected "
2595 "(vid/pid 0x%04X/0x%04X)", sn9c102_id_table[i].idVendor,
2596 sn9c102_id_table[i].idProduct)
2597 break;
2598 case BRIDGE_SN9C103:
2599 DBG(2, "SN9C103 PC Camera Controller detected "
2600 "(vid/pid 0x%04X/0x%04X)", sn9c102_id_table[i].idVendor,
2601 sn9c102_id_table[i].idProduct)
2602 break;
2603 }
2604
2605 for (i = 0; sn9c102_sensor_table[i]; i++) {
2606 err = sn9c102_sensor_table[i](cam);
2607 if (!err)
2608 break;
2609 }
2610
2611 if (!err && cam->sensor) {
2612 DBG(2, "%s image sensor detected", cam->sensor->name)
2613 DBG(3, "Support for %s maintained by %s",
2614 cam->sensor->name, cam->sensor->maintainer)
2615 } else {
2616 DBG(1, "No supported image sensor detected")
2617 err = -ENODEV;
2618 goto fail;
2619 }
2620
2621 if (sn9c102_init(cam)) {
2622 DBG(1, "Initialization failed. I will retry on open().")
2623 cam->state |= DEV_MISCONFIGURED;
2624 }
2625
2626 strcpy(cam->v4ldev->name, "SN9C10x PC Camera");
2627 cam->v4ldev->owner = THIS_MODULE;
2628 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
2629 cam->v4ldev->hardware = VID_HARDWARE_SN9C102;
2630 cam->v4ldev->fops = &sn9c102_fops;
2631 cam->v4ldev->minor = video_nr[dev_nr];
2632 cam->v4ldev->release = video_device_release;
2633 video_set_drvdata(cam->v4ldev, cam);
2634
2635 down(&cam->dev_sem);
2636
2637 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
2638 video_nr[dev_nr]);
2639 if (err) {
2640 DBG(1, "V4L2 device registration failed")
2641 if (err == -ENFILE && video_nr[dev_nr] == -1)
2642 DBG(1, "Free /dev/videoX node not found")
2643 video_nr[dev_nr] = -1;
2644 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
2645 up(&cam->dev_sem);
2646 goto fail;
2647 }
2648
2649 DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor)
2650
2651 cam->module_param.force_munmap = force_munmap[dev_nr];
2652
2653 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
2654
2655 sn9c102_create_sysfs(cam);
2656 DBG(2, "Optional device control through 'sysfs' interface ready")
2657
2658 usb_set_intfdata(intf, cam);
2659
2660 up(&cam->dev_sem);
2661
2662 return 0;
2663
2664fail:
2665 if (cam) {
2666 kfree(cam->control_buffer);
2667 if (cam->v4ldev)
2668 video_device_release(cam->v4ldev);
2669 kfree(cam);
2670 }
2671 return err;
2672}
2673
2674
2675static void sn9c102_usb_disconnect(struct usb_interface* intf)
2676{
2677 struct sn9c102_device* cam = usb_get_intfdata(intf);
2678
2679 if (!cam)
2680 return;
2681
2682 down_write(&sn9c102_disconnect);
2683
2684 down(&cam->dev_sem);
2685
2686 DBG(2, "Disconnecting %s...", cam->v4ldev->name)
2687
2688 wake_up_interruptible_all(&cam->open);
2689
2690 if (cam->users) {
2691 DBG(2, "Device /dev/video%d is open! Deregistration and "
2692 "memory deallocation are deferred on close.",
2693 cam->v4ldev->minor)
2694 cam->state |= DEV_MISCONFIGURED;
2695 sn9c102_stop_transfer(cam);
2696 cam->state |= DEV_DISCONNECTED;
2697 wake_up_interruptible(&cam->wait_frame);
2698 wake_up_interruptible(&cam->wait_stream);
2699 } else {
2700 cam->state |= DEV_DISCONNECTED;
2701 sn9c102_release_resources(cam);
2702 }
2703
2704 up(&cam->dev_sem);
2705
2706 if (!cam->users)
2707 kfree(cam);
2708
2709 up_write(&sn9c102_disconnect);
2710}
2711
2712
2713static struct usb_driver sn9c102_usb_driver = {
2714 .owner = THIS_MODULE,
2715 .name = "sn9c102",
2716 .id_table = sn9c102_id_table,
2717 .probe = sn9c102_usb_probe,
2718 .disconnect = sn9c102_usb_disconnect,
2719};
2720
2721/*****************************************************************************/
2722
2723static int __init sn9c102_module_init(void)
2724{
2725 int err = 0;
2726
2727 KDBG(2, SN9C102_MODULE_NAME " v" SN9C102_MODULE_VERSION)
2728 KDBG(3, SN9C102_MODULE_AUTHOR)
2729
2730 if ((err = usb_register(&sn9c102_usb_driver)))
2731 KDBG(1, "usb_register() failed")
2732
2733 return err;
2734}
2735
2736
2737static void __exit sn9c102_module_exit(void)
2738{
2739 usb_deregister(&sn9c102_usb_driver);
2740}
2741
2742
2743module_init(sn9c102_module_init);
2744module_exit(sn9c102_module_exit);
diff --git a/drivers/usb/media/sn9c102_hv7131d.c b/drivers/usb/media/sn9c102_hv7131d.c
new file mode 100644
index 000000000000..18070d5333cf
--- /dev/null
+++ b/drivers/usb/media/sn9c102_hv7131d.c
@@ -0,0 +1,271 @@
1/***************************************************************************
2 * Plug-in for HV7131D image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "sn9c102_sensor.h"
23
24
25static struct sn9c102_sensor hv7131d;
26
27
28static int hv7131d_init(struct sn9c102_device* cam)
29{
30 int err = 0;
31
32 err += sn9c102_write_reg(cam, 0x00, 0x10);
33 err += sn9c102_write_reg(cam, 0x00, 0x11);
34 err += sn9c102_write_reg(cam, 0x00, 0x14);
35 err += sn9c102_write_reg(cam, 0x60, 0x17);
36 err += sn9c102_write_reg(cam, 0x0e, 0x18);
37 err += sn9c102_write_reg(cam, 0xf2, 0x19);
38
39 err += sn9c102_i2c_write(cam, 0x01, 0x04);
40 err += sn9c102_i2c_write(cam, 0x02, 0x00);
41 err += sn9c102_i2c_write(cam, 0x28, 0x00);
42
43 return err;
44}
45
46
47static int hv7131d_get_ctrl(struct sn9c102_device* cam,
48 struct v4l2_control* ctrl)
49{
50 switch (ctrl->id) {
51 case V4L2_CID_EXPOSURE:
52 {
53 int r1 = sn9c102_i2c_read(cam, 0x26),
54 r2 = sn9c102_i2c_read(cam, 0x27);
55 if (r1 < 0 || r2 < 0)
56 return -EIO;
57 ctrl->value = (r1 << 8) | (r2 & 0xff);
58 }
59 return 0;
60 case V4L2_CID_RED_BALANCE:
61 if ((ctrl->value = sn9c102_i2c_read(cam, 0x31)) < 0)
62 return -EIO;
63 ctrl->value = 0x3f - (ctrl->value & 0x3f);
64 return 0;
65 case V4L2_CID_BLUE_BALANCE:
66 if ((ctrl->value = sn9c102_i2c_read(cam, 0x33)) < 0)
67 return -EIO;
68 ctrl->value = 0x3f - (ctrl->value & 0x3f);
69 return 0;
70 case SN9C102_V4L2_CID_GREEN_BALANCE:
71 if ((ctrl->value = sn9c102_i2c_read(cam, 0x32)) < 0)
72 return -EIO;
73 ctrl->value = 0x3f - (ctrl->value & 0x3f);
74 return 0;
75 case SN9C102_V4L2_CID_RESET_LEVEL:
76 if ((ctrl->value = sn9c102_i2c_read(cam, 0x30)) < 0)
77 return -EIO;
78 ctrl->value &= 0x3f;
79 return 0;
80 case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
81 if ((ctrl->value = sn9c102_i2c_read(cam, 0x34)) < 0)
82 return -EIO;
83 ctrl->value &= 0x07;
84 return 0;
85 default:
86 return -EINVAL;
87 }
88}
89
90
91static int hv7131d_set_ctrl(struct sn9c102_device* cam,
92 const struct v4l2_control* ctrl)
93{
94 int err = 0;
95
96 switch (ctrl->id) {
97 case V4L2_CID_EXPOSURE:
98 err += sn9c102_i2c_write(cam, 0x26, ctrl->value >> 8);
99 err += sn9c102_i2c_write(cam, 0x27, ctrl->value & 0xff);
100 break;
101 case V4L2_CID_RED_BALANCE:
102 err += sn9c102_i2c_write(cam, 0x31, 0x3f - ctrl->value);
103 break;
104 case V4L2_CID_BLUE_BALANCE:
105 err += sn9c102_i2c_write(cam, 0x33, 0x3f - ctrl->value);
106 break;
107 case SN9C102_V4L2_CID_GREEN_BALANCE:
108 err += sn9c102_i2c_write(cam, 0x32, 0x3f - ctrl->value);
109 break;
110 case SN9C102_V4L2_CID_RESET_LEVEL:
111 err += sn9c102_i2c_write(cam, 0x30, ctrl->value);
112 break;
113 case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
114 err += sn9c102_i2c_write(cam, 0x34, ctrl->value);
115 break;
116 default:
117 return -EINVAL;
118 }
119
120 return err ? -EIO : 0;
121}
122
123
124static int hv7131d_set_crop(struct sn9c102_device* cam,
125 const struct v4l2_rect* rect)
126{
127 struct sn9c102_sensor* s = &hv7131d;
128 int err = 0;
129 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 2,
130 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
131
132 err += sn9c102_write_reg(cam, h_start, 0x12);
133 err += sn9c102_write_reg(cam, v_start, 0x13);
134
135 return err;
136}
137
138
139static int hv7131d_set_pix_format(struct sn9c102_device* cam,
140 const struct v4l2_pix_format* pix)
141{
142 int err = 0;
143
144 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
145 err += sn9c102_write_reg(cam, 0x42, 0x19);
146 else
147 err += sn9c102_write_reg(cam, 0xf2, 0x19);
148
149 return err;
150}
151
152
153static struct sn9c102_sensor hv7131d = {
154 .name = "HV7131D",
155 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
156 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
157 .frequency = SN9C102_I2C_100KHZ,
158 .interface = SN9C102_I2C_2WIRES,
159 .i2c_slave_id = 0x11,
160 .init = &hv7131d_init,
161 .qctrl = {
162 {
163 .id = V4L2_CID_EXPOSURE,
164 .type = V4L2_CTRL_TYPE_INTEGER,
165 .name = "exposure",
166 .minimum = 0x0250,
167 .maximum = 0xffff,
168 .step = 0x0001,
169 .default_value = 0x0250,
170 .flags = 0,
171 },
172 {
173 .id = V4L2_CID_RED_BALANCE,
174 .type = V4L2_CTRL_TYPE_INTEGER,
175 .name = "red balance",
176 .minimum = 0x00,
177 .maximum = 0x3f,
178 .step = 0x01,
179 .default_value = 0x00,
180 .flags = 0,
181 },
182 {
183 .id = V4L2_CID_BLUE_BALANCE,
184 .type = V4L2_CTRL_TYPE_INTEGER,
185 .name = "blue balance",
186 .minimum = 0x00,
187 .maximum = 0x3f,
188 .step = 0x01,
189 .default_value = 0x20,
190 .flags = 0,
191 },
192 {
193 .id = SN9C102_V4L2_CID_GREEN_BALANCE,
194 .type = V4L2_CTRL_TYPE_INTEGER,
195 .name = "green balance",
196 .minimum = 0x00,
197 .maximum = 0x3f,
198 .step = 0x01,
199 .default_value = 0x1e,
200 .flags = 0,
201 },
202 {
203 .id = SN9C102_V4L2_CID_RESET_LEVEL,
204 .type = V4L2_CTRL_TYPE_INTEGER,
205 .name = "reset level",
206 .minimum = 0x19,
207 .maximum = 0x3f,
208 .step = 0x01,
209 .default_value = 0x30,
210 .flags = 0,
211 },
212 {
213 .id = SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE,
214 .type = V4L2_CTRL_TYPE_INTEGER,
215 .name = "pixel bias voltage",
216 .minimum = 0x00,
217 .maximum = 0x07,
218 .step = 0x01,
219 .default_value = 0x02,
220 .flags = 0,
221 },
222 },
223 .get_ctrl = &hv7131d_get_ctrl,
224 .set_ctrl = &hv7131d_set_ctrl,
225 .cropcap = {
226 .bounds = {
227 .left = 0,
228 .top = 0,
229 .width = 640,
230 .height = 480,
231 },
232 .defrect = {
233 .left = 0,
234 .top = 0,
235 .width = 640,
236 .height = 480,
237 },
238 },
239 .set_crop = &hv7131d_set_crop,
240 .pix_format = {
241 .width = 640,
242 .height = 480,
243 .pixelformat = V4L2_PIX_FMT_SBGGR8,
244 .priv = 8,
245 },
246 .set_pix_format = &hv7131d_set_pix_format
247};
248
249
250int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
251{
252 int r0 = 0, r1 = 0, err = 0;
253
254 err += sn9c102_write_reg(cam, 0x01, 0x01);
255 err += sn9c102_write_reg(cam, 0x00, 0x01);
256 err += sn9c102_write_reg(cam, 0x28, 0x17);
257 if (err)
258 return -EIO;
259
260 r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
261 r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
262 if (r0 < 0 || r1 < 0)
263 return -EIO;
264
265 if (r0 != 0x00 && r1 != 0x04)
266 return -ENODEV;
267
268 sn9c102_attach_sensor(cam, &hv7131d);
269
270 return 0;
271}
diff --git a/drivers/usb/media/sn9c102_mi0343.c b/drivers/usb/media/sn9c102_mi0343.c
new file mode 100644
index 000000000000..86676abf3547
--- /dev/null
+++ b/drivers/usb/media/sn9c102_mi0343.c
@@ -0,0 +1,363 @@
1/***************************************************************************
2 * Plug-in for MI-0343 image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "sn9c102_sensor.h"
23
24
25static struct sn9c102_sensor mi0343;
26static u8 mi0343_i2c_data[5+1];
27
28
29static int mi0343_init(struct sn9c102_device* cam)
30{
31 int err = 0;
32
33 err += sn9c102_write_reg(cam, 0x00, 0x10);
34 err += sn9c102_write_reg(cam, 0x00, 0x11);
35 err += sn9c102_write_reg(cam, 0x0a, 0x14);
36 err += sn9c102_write_reg(cam, 0x40, 0x01);
37 err += sn9c102_write_reg(cam, 0x20, 0x17);
38 err += sn9c102_write_reg(cam, 0x07, 0x18);
39 err += sn9c102_write_reg(cam, 0xa0, 0x19);
40
41 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
42 0x0d, 0x00, 0x01, 0, 0);
43 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
44 0x0d, 0x00, 0x00, 0, 0);
45 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
46 0x03, 0x01, 0xe1, 0, 0);
47 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
48 0x04, 0x02, 0x81, 0, 0);
49 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
50 0x05, 0x00, 0x17, 0, 0);
51 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
52 0x06, 0x00, 0x11, 0, 0);
53 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
54 0x62, 0x04, 0x9a, 0, 0);
55
56 return err;
57}
58
59
60static int mi0343_get_ctrl(struct sn9c102_device* cam,
61 struct v4l2_control* ctrl)
62{
63 switch (ctrl->id) {
64 case V4L2_CID_EXPOSURE:
65 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
66 0x09, 2+1, mi0343_i2c_data) < 0)
67 return -EIO;
68 ctrl->value = mi0343_i2c_data[2];
69 return 0;
70 case V4L2_CID_GAIN:
71 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
72 0x35, 2+1, mi0343_i2c_data) < 0)
73 return -EIO;
74 break;
75 case V4L2_CID_HFLIP:
76 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
77 0x20, 2+1, mi0343_i2c_data) < 0)
78 return -EIO;
79 ctrl->value = mi0343_i2c_data[3] & 0x20 ? 1 : 0;
80 return 0;
81 case V4L2_CID_VFLIP:
82 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
83 0x20, 2+1, mi0343_i2c_data) < 0)
84 return -EIO;
85 ctrl->value = mi0343_i2c_data[3] & 0x80 ? 1 : 0;
86 return 0;
87 case V4L2_CID_RED_BALANCE:
88 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
89 0x2d, 2+1, mi0343_i2c_data) < 0)
90 return -EIO;
91 break;
92 case V4L2_CID_BLUE_BALANCE:
93 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
94 0x2c, 2+1, mi0343_i2c_data) < 0)
95 return -EIO;
96 break;
97 case SN9C102_V4L2_CID_GREEN_BALANCE:
98 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
99 0x2e, 2+1, mi0343_i2c_data) < 0)
100 return -EIO;
101 break;
102 default:
103 return -EINVAL;
104 }
105
106 switch (ctrl->id) {
107 case V4L2_CID_GAIN:
108 case V4L2_CID_RED_BALANCE:
109 case V4L2_CID_BLUE_BALANCE:
110 case SN9C102_V4L2_CID_GREEN_BALANCE:
111 ctrl->value = mi0343_i2c_data[3] | (mi0343_i2c_data[2] << 8);
112 if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
113 ctrl->value -= 0x10;
114 else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
115 ctrl->value -= 0x60;
116 else if (ctrl->value >= 0xe0 && ctrl->value <= 0xff)
117 ctrl->value -= 0xe0;
118 }
119
120 return 0;
121}
122
123
124static int mi0343_set_ctrl(struct sn9c102_device* cam,
125 const struct v4l2_control* ctrl)
126{
127 u16 reg = 0;
128 int err = 0;
129
130 switch (ctrl->id) {
131 case V4L2_CID_GAIN:
132 case V4L2_CID_RED_BALANCE:
133 case V4L2_CID_BLUE_BALANCE:
134 case SN9C102_V4L2_CID_GREEN_BALANCE:
135 if (ctrl->value <= (0x3f-0x10))
136 reg = 0x10 + ctrl->value;
137 else if (ctrl->value <= ((0x3f-0x10) + (0x7f-0x60)))
138 reg = 0x60 + (ctrl->value - (0x3f-0x10));
139 else
140 reg = 0xe0 + (ctrl->value - (0x3f-0x10) - (0x7f-0x60));
141 break;
142 }
143
144 switch (ctrl->id) {
145 case V4L2_CID_EXPOSURE:
146 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
147 mi0343.i2c_slave_id,
148 0x09, ctrl->value, 0x00,
149 0, 0);
150 break;
151 case V4L2_CID_GAIN:
152 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
153 mi0343.i2c_slave_id,
154 0x35, reg >> 8, reg & 0xff,
155 0, 0);
156 break;
157 case V4L2_CID_HFLIP:
158 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
159 mi0343.i2c_slave_id,
160 0x20, ctrl->value ? 0x40:0x00,
161 ctrl->value ? 0x20:0x00,
162 0, 0);
163 break;
164 case V4L2_CID_VFLIP:
165 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
166 mi0343.i2c_slave_id,
167 0x20, ctrl->value ? 0x80:0x00,
168 ctrl->value ? 0x80:0x00,
169 0, 0);
170 break;
171 case V4L2_CID_RED_BALANCE:
172 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
173 mi0343.i2c_slave_id,
174 0x2d, reg >> 8, reg & 0xff,
175 0, 0);
176 break;
177 case V4L2_CID_BLUE_BALANCE:
178 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
179 mi0343.i2c_slave_id,
180 0x2c, reg >> 8, reg & 0xff,
181 0, 0);
182 break;
183 case SN9C102_V4L2_CID_GREEN_BALANCE:
184 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
185 mi0343.i2c_slave_id,
186 0x2b, reg >> 8, reg & 0xff,
187 0, 0);
188 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
189 mi0343.i2c_slave_id,
190 0x2e, reg >> 8, reg & 0xff,
191 0, 0);
192 break;
193 default:
194 return -EINVAL;
195 }
196
197 return err ? -EIO : 0;
198}
199
200
201static int mi0343_set_crop(struct sn9c102_device* cam,
202 const struct v4l2_rect* rect)
203{
204 struct sn9c102_sensor* s = &mi0343;
205 int err = 0;
206 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0,
207 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
208
209 err += sn9c102_write_reg(cam, h_start, 0x12);
210 err += sn9c102_write_reg(cam, v_start, 0x13);
211
212 return err;
213}
214
215
216static int mi0343_set_pix_format(struct sn9c102_device* cam,
217 const struct v4l2_pix_format* pix)
218{
219 int err = 0;
220
221 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
222 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
223 mi0343.i2c_slave_id,
224 0x0a, 0x00, 0x03, 0, 0);
225 err += sn9c102_write_reg(cam, 0x20, 0x19);
226 } else {
227 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
228 mi0343.i2c_slave_id,
229 0x0a, 0x00, 0x05, 0, 0);
230 err += sn9c102_write_reg(cam, 0xa0, 0x19);
231 }
232
233 return err;
234}
235
236
237static struct sn9c102_sensor mi0343 = {
238 .name = "MI-0343",
239 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
240 .frequency = SN9C102_I2C_100KHZ,
241 .interface = SN9C102_I2C_2WIRES,
242 .i2c_slave_id = 0x5d,
243 .init = &mi0343_init,
244 .qctrl = {
245 {
246 .id = V4L2_CID_EXPOSURE,
247 .type = V4L2_CTRL_TYPE_INTEGER,
248 .name = "exposure",
249 .minimum = 0x00,
250 .maximum = 0x0f,
251 .step = 0x01,
252 .default_value = 0x06,
253 .flags = 0,
254 },
255 {
256 .id = V4L2_CID_GAIN,
257 .type = V4L2_CTRL_TYPE_INTEGER,
258 .name = "global gain",
259 .minimum = 0x00,
260 .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),/*0x6d*/
261 .step = 0x01,
262 .default_value = 0x00,
263 .flags = 0,
264 },
265 {
266 .id = V4L2_CID_HFLIP,
267 .type = V4L2_CTRL_TYPE_BOOLEAN,
268 .name = "horizontal mirror",
269 .minimum = 0,
270 .maximum = 1,
271 .step = 1,
272 .default_value = 0,
273 .flags = 0,
274 },
275 {
276 .id = V4L2_CID_VFLIP,
277 .type = V4L2_CTRL_TYPE_BOOLEAN,
278 .name = "vertical mirror",
279 .minimum = 0,
280 .maximum = 1,
281 .step = 1,
282 .default_value = 0,
283 .flags = 0,
284 },
285 {
286 .id = V4L2_CID_RED_BALANCE,
287 .type = V4L2_CTRL_TYPE_INTEGER,
288 .name = "red balance",
289 .minimum = 0x00,
290 .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
291 .step = 0x01,
292 .default_value = 0x00,
293 .flags = 0,
294 },
295 {
296 .id = V4L2_CID_BLUE_BALANCE,
297 .type = V4L2_CTRL_TYPE_INTEGER,
298 .name = "blue balance",
299 .minimum = 0x00,
300 .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
301 .step = 0x01,
302 .default_value = 0x00,
303 .flags = 0,
304 },
305 {
306 .id = SN9C102_V4L2_CID_GREEN_BALANCE,
307 .type = V4L2_CTRL_TYPE_INTEGER,
308 .name = "green balance",
309 .minimum = 0x00,
310 .maximum = ((0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0)),
311 .step = 0x01,
312 .default_value = 0x00,
313 .flags = 0,
314 },
315 },
316 .get_ctrl = &mi0343_get_ctrl,
317 .set_ctrl = &mi0343_set_ctrl,
318 .cropcap = {
319 .bounds = {
320 .left = 0,
321 .top = 0,
322 .width = 640,
323 .height = 480,
324 },
325 .defrect = {
326 .left = 0,
327 .top = 0,
328 .width = 640,
329 .height = 480,
330 },
331 },
332 .set_crop = &mi0343_set_crop,
333 .pix_format = {
334 .width = 640,
335 .height = 480,
336 .pixelformat = V4L2_PIX_FMT_SBGGR8,
337 .priv = 8,
338 },
339 .set_pix_format = &mi0343_set_pix_format
340};
341
342
343int sn9c102_probe_mi0343(struct sn9c102_device* cam)
344{
345 int err = 0;
346
347 err += sn9c102_write_reg(cam, 0x01, 0x01);
348 err += sn9c102_write_reg(cam, 0x00, 0x01);
349 err += sn9c102_write_reg(cam, 0x28, 0x17);
350 if (err)
351 return -EIO;
352
353 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
354 2, mi0343_i2c_data) < 0)
355 return -EIO;
356
357 if (mi0343_i2c_data[4] != 0x32 && mi0343_i2c_data[3] != 0xe3)
358 return -ENODEV;
359
360 sn9c102_attach_sensor(cam, &mi0343);
361
362 return 0;
363}
diff --git a/drivers/usb/media/sn9c102_pas106b.c b/drivers/usb/media/sn9c102_pas106b.c
new file mode 100644
index 000000000000..48e3ec39d4e2
--- /dev/null
+++ b/drivers/usb/media/sn9c102_pas106b.c
@@ -0,0 +1,307 @@
1/***************************************************************************
2 * Plug-in for PAS106B image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include <linux/delay.h>
23#include "sn9c102_sensor.h"
24
25
26static struct sn9c102_sensor pas106b;
27
28
29static int pas106b_init(struct sn9c102_device* cam)
30{
31 int err = 0;
32
33 err += sn9c102_write_reg(cam, 0x00, 0x10);
34 err += sn9c102_write_reg(cam, 0x00, 0x11);
35 err += sn9c102_write_reg(cam, 0x00, 0x14);
36 err += sn9c102_write_reg(cam, 0x20, 0x17);
37 err += sn9c102_write_reg(cam, 0x20, 0x19);
38 err += sn9c102_write_reg(cam, 0x09, 0x18);
39
40 err += sn9c102_i2c_write(cam, 0x02, 0x0c);
41 err += sn9c102_i2c_write(cam, 0x05, 0x5a);
42 err += sn9c102_i2c_write(cam, 0x06, 0x88);
43 err += sn9c102_i2c_write(cam, 0x07, 0x80);
44 err += sn9c102_i2c_write(cam, 0x10, 0x06);
45 err += sn9c102_i2c_write(cam, 0x11, 0x06);
46 err += sn9c102_i2c_write(cam, 0x12, 0x00);
47 err += sn9c102_i2c_write(cam, 0x14, 0x02);
48 err += sn9c102_i2c_write(cam, 0x13, 0x01);
49
50 msleep(400);
51
52 return err;
53}
54
55
56static int pas106b_get_ctrl(struct sn9c102_device* cam,
57 struct v4l2_control* ctrl)
58{
59 switch (ctrl->id) {
60 case V4L2_CID_EXPOSURE:
61 {
62 int r1 = sn9c102_i2c_read(cam, 0x03),
63 r2 = sn9c102_i2c_read(cam, 0x04);
64 if (r1 < 0 || r2 < 0)
65 return -EIO;
66 ctrl->value = (r1 << 4) | (r2 & 0x0f);
67 }
68 return 0;
69 case V4L2_CID_RED_BALANCE:
70 if ((ctrl->value = sn9c102_i2c_read(cam, 0x0c)) < 0)
71 return -EIO;
72 ctrl->value &= 0x1f;
73 return 0;
74 case V4L2_CID_BLUE_BALANCE:
75 if ((ctrl->value = sn9c102_i2c_read(cam, 0x09)) < 0)
76 return -EIO;
77 ctrl->value &= 0x1f;
78 return 0;
79 case V4L2_CID_GAIN:
80 if ((ctrl->value = sn9c102_i2c_read(cam, 0x0e)) < 0)
81 return -EIO;
82 ctrl->value &= 0x1f;
83 return 0;
84 case V4L2_CID_CONTRAST:
85 if ((ctrl->value = sn9c102_i2c_read(cam, 0x0f)) < 0)
86 return -EIO;
87 ctrl->value &= 0x07;
88 return 0;
89 case SN9C102_V4L2_CID_GREEN_BALANCE:
90 if ((ctrl->value = sn9c102_i2c_read(cam, 0x0a)) < 0)
91 return -EIO;
92 ctrl->value = (ctrl->value & 0x1f) << 1;
93 return 0;
94 case SN9C102_V4L2_CID_DAC_MAGNITUDE:
95 if ((ctrl->value = sn9c102_i2c_read(cam, 0x08)) < 0)
96 return -EIO;
97 ctrl->value &= 0xf8;
98 return 0;
99 default:
100 return -EINVAL;
101 }
102}
103
104
105static int pas106b_set_ctrl(struct sn9c102_device* cam,
106 const struct v4l2_control* ctrl)
107{
108 int err = 0;
109
110 switch (ctrl->id) {
111 case V4L2_CID_EXPOSURE:
112 err += sn9c102_i2c_write(cam, 0x03, ctrl->value >> 4);
113 err += sn9c102_i2c_write(cam, 0x04, ctrl->value & 0x0f);
114 break;
115 case V4L2_CID_RED_BALANCE:
116 err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
117 break;
118 case V4L2_CID_BLUE_BALANCE:
119 err += sn9c102_i2c_write(cam, 0x09, ctrl->value);
120 break;
121 case V4L2_CID_GAIN:
122 err += sn9c102_i2c_write(cam, 0x0e, ctrl->value);
123 break;
124 case V4L2_CID_CONTRAST:
125 err += sn9c102_i2c_write(cam, 0x0f, ctrl->value);
126 break;
127 case SN9C102_V4L2_CID_GREEN_BALANCE:
128 err += sn9c102_i2c_write(cam, 0x0a, ctrl->value >> 1);
129 err += sn9c102_i2c_write(cam, 0x0b, ctrl->value >> 1);
130 break;
131 case SN9C102_V4L2_CID_DAC_MAGNITUDE:
132 err += sn9c102_i2c_write(cam, 0x08, ctrl->value << 3);
133 break;
134 default:
135 return -EINVAL;
136 }
137 err += sn9c102_i2c_write(cam, 0x13, 0x01);
138
139 return err ? -EIO : 0;
140}
141
142
143static int pas106b_set_crop(struct sn9c102_device* cam,
144 const struct v4l2_rect* rect)
145{
146 struct sn9c102_sensor* s = &pas106b;
147 int err = 0;
148 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4,
149 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3;
150
151 err += sn9c102_write_reg(cam, h_start, 0x12);
152 err += sn9c102_write_reg(cam, v_start, 0x13);
153
154 return err;
155}
156
157
158static int pas106b_set_pix_format(struct sn9c102_device* cam,
159 const struct v4l2_pix_format* pix)
160{
161 int err = 0;
162
163 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
164 err += sn9c102_write_reg(cam, 0x2c, 0x17);
165 else
166 err += sn9c102_write_reg(cam, 0x20, 0x17);
167
168 return err;
169}
170
171
172static struct sn9c102_sensor pas106b = {
173 .name = "PAS106B",
174 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
175 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
176 .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
177 .interface = SN9C102_I2C_2WIRES,
178 .i2c_slave_id = 0x40,
179 .init = &pas106b_init,
180 .qctrl = {
181 {
182 .id = V4L2_CID_EXPOSURE,
183 .type = V4L2_CTRL_TYPE_INTEGER,
184 .name = "exposure",
185 .minimum = 0x125,
186 .maximum = 0xfff,
187 .step = 0x001,
188 .default_value = 0x140,
189 .flags = 0,
190 },
191 {
192 .id = V4L2_CID_GAIN,
193 .type = V4L2_CTRL_TYPE_INTEGER,
194 .name = "global gain",
195 .minimum = 0x00,
196 .maximum = 0x1f,
197 .step = 0x01,
198 .default_value = 0x0d,
199 .flags = 0,
200 },
201 {
202 .id = V4L2_CID_CONTRAST,
203 .type = V4L2_CTRL_TYPE_INTEGER,
204 .name = "contrast",
205 .minimum = 0x00,
206 .maximum = 0x07,
207 .step = 0x01,
208 .default_value = 0x00, /* 0x00~0x03 have same effect */
209 .flags = 0,
210 },
211 {
212 .id = V4L2_CID_RED_BALANCE,
213 .type = V4L2_CTRL_TYPE_INTEGER,
214 .name = "red balance",
215 .minimum = 0x00,
216 .maximum = 0x1f,
217 .step = 0x01,
218 .default_value = 0x04,
219 .flags = 0,
220 },
221 {
222 .id = V4L2_CID_BLUE_BALANCE,
223 .type = V4L2_CTRL_TYPE_INTEGER,
224 .name = "blue balance",
225 .minimum = 0x00,
226 .maximum = 0x1f,
227 .step = 0x01,
228 .default_value = 0x06,
229 .flags = 0,
230 },
231 {
232 .id = SN9C102_V4L2_CID_GREEN_BALANCE,
233 .type = V4L2_CTRL_TYPE_INTEGER,
234 .name = "green balance",
235 .minimum = 0x00,
236 .maximum = 0x3e,
237 .step = 0x02,
238 .default_value = 0x02,
239 .flags = 0,
240 },
241 {
242 .id = SN9C102_V4L2_CID_DAC_MAGNITUDE,
243 .type = V4L2_CTRL_TYPE_INTEGER,
244 .name = "DAC magnitude",
245 .minimum = 0x00,
246 .maximum = 0x1f,
247 .step = 0x01,
248 .default_value = 0x01,
249 .flags = 0,
250 },
251 },
252 .get_ctrl = &pas106b_get_ctrl,
253 .set_ctrl = &pas106b_set_ctrl,
254 .cropcap = {
255 .bounds = {
256 .left = 0,
257 .top = 0,
258 .width = 352,
259 .height = 288,
260 },
261 .defrect = {
262 .left = 0,
263 .top = 0,
264 .width = 352,
265 .height = 288,
266 },
267 },
268 .set_crop = &pas106b_set_crop,
269 .pix_format = {
270 .width = 352,
271 .height = 288,
272 .pixelformat = V4L2_PIX_FMT_SBGGR8,
273 .priv = 8, /* we use this field as 'bits per pixel' */
274 },
275 .set_pix_format = &pas106b_set_pix_format
276};
277
278
279int sn9c102_probe_pas106b(struct sn9c102_device* cam)
280{
281 int r0 = 0, r1 = 0, err = 0;
282 unsigned int pid = 0;
283
284 /*
285 Minimal initialization to enable the I2C communication
286 NOTE: do NOT change the values!
287 */
288 err += sn9c102_write_reg(cam, 0x01, 0x01); /* sensor power down */
289 err += sn9c102_write_reg(cam, 0x00, 0x01); /* sensor power on */
290 err += sn9c102_write_reg(cam, 0x28, 0x17); /* sensor clock at 24 MHz */
291 if (err)
292 return -EIO;
293
294 r0 = sn9c102_i2c_try_read(cam, &pas106b, 0x00);
295 r1 = sn9c102_i2c_try_read(cam, &pas106b, 0x01);
296
297 if (r0 < 0 || r1 < 0)
298 return -EIO;
299
300 pid = (r0 << 11) | ((r1 & 0xf0) >> 4);
301 if (pid != 0x007)
302 return -ENODEV;
303
304 sn9c102_attach_sensor(cam, &pas106b);
305
306 return 0;
307}
diff --git a/drivers/usb/media/sn9c102_pas202bcb.c b/drivers/usb/media/sn9c102_pas202bcb.c
new file mode 100644
index 000000000000..5ca54c7daaf2
--- /dev/null
+++ b/drivers/usb/media/sn9c102_pas202bcb.c
@@ -0,0 +1,293 @@
1/***************************************************************************
2 * Plug-in for PAS202BCB image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2004 by Carlos Eduardo Medaglia Dyonisio *
6 * <medaglia@undl.org.br> *
7 * http://cadu.homelinux.com:8080/ *
8 * *
9 * DAC Magnitude, exposure and green gain controls added by *
10 * Luca Risolia <luca.risolia@studio.unibo.it> *
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
27#include <linux/delay.h>
28#include "sn9c102_sensor.h"
29
30
31static struct sn9c102_sensor pas202bcb;
32
33
34static int pas202bcb_init(struct sn9c102_device* cam)
35{
36 int err = 0;
37
38 err += sn9c102_write_reg(cam, 0x00, 0x10);
39 err += sn9c102_write_reg(cam, 0x00, 0x11);
40 err += sn9c102_write_reg(cam, 0x00, 0x14);
41 err += sn9c102_write_reg(cam, 0x20, 0x17);
42 err += sn9c102_write_reg(cam, 0x30, 0x19);
43 err += sn9c102_write_reg(cam, 0x09, 0x18);
44
45 err += sn9c102_i2c_write(cam, 0x02, 0x14);
46 err += sn9c102_i2c_write(cam, 0x03, 0x40);
47 err += sn9c102_i2c_write(cam, 0x0d, 0x2c);
48 err += sn9c102_i2c_write(cam, 0x0e, 0x01);
49 err += sn9c102_i2c_write(cam, 0x0f, 0xa9);
50 err += sn9c102_i2c_write(cam, 0x10, 0x08);
51 err += sn9c102_i2c_write(cam, 0x13, 0x63);
52 err += sn9c102_i2c_write(cam, 0x15, 0x70);
53 err += sn9c102_i2c_write(cam, 0x11, 0x01);
54
55 msleep(400);
56
57 return err;
58}
59
60
61static int pas202bcb_get_ctrl(struct sn9c102_device* cam,
62 struct v4l2_control* ctrl)
63{
64 switch (ctrl->id) {
65 case V4L2_CID_EXPOSURE:
66 {
67 int r1 = sn9c102_i2c_read(cam, 0x04),
68 r2 = sn9c102_i2c_read(cam, 0x05);
69 if (r1 < 0 || r2 < 0)
70 return -EIO;
71 ctrl->value = (r1 << 6) | (r2 & 0x3f);
72 }
73 return 0;
74 case V4L2_CID_RED_BALANCE:
75 if ((ctrl->value = sn9c102_i2c_read(cam, 0x09)) < 0)
76 return -EIO;
77 ctrl->value &= 0x0f;
78 return 0;
79 case V4L2_CID_BLUE_BALANCE:
80 if ((ctrl->value = sn9c102_i2c_read(cam, 0x07)) < 0)
81 return -EIO;
82 ctrl->value &= 0x0f;
83 return 0;
84 case V4L2_CID_GAIN:
85 if ((ctrl->value = sn9c102_i2c_read(cam, 0x10)) < 0)
86 return -EIO;
87 ctrl->value &= 0x1f;
88 return 0;
89 case SN9C102_V4L2_CID_GREEN_BALANCE:
90 if ((ctrl->value = sn9c102_i2c_read(cam, 0x08)) < 0)
91 return -EIO;
92 ctrl->value &= 0x0f;
93 return 0;
94 case SN9C102_V4L2_CID_DAC_MAGNITUDE:
95 if ((ctrl->value = sn9c102_i2c_read(cam, 0x0c)) < 0)
96 return -EIO;
97 return 0;
98 default:
99 return -EINVAL;
100 }
101}
102
103
104static int pas202bcb_set_pix_format(struct sn9c102_device* cam,
105 const struct v4l2_pix_format* pix)
106{
107 int err = 0;
108
109 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
110 err += sn9c102_write_reg(cam, 0x24, 0x17);
111 else
112 err += sn9c102_write_reg(cam, 0x20, 0x17);
113
114 return err;
115}
116
117
118static int pas202bcb_set_ctrl(struct sn9c102_device* cam,
119 const struct v4l2_control* ctrl)
120{
121 int err = 0;
122
123 switch (ctrl->id) {
124 case V4L2_CID_EXPOSURE:
125 err += sn9c102_i2c_write(cam, 0x04, ctrl->value >> 6);
126 err += sn9c102_i2c_write(cam, 0x05, ctrl->value & 0x3f);
127 break;
128 case V4L2_CID_RED_BALANCE:
129 err += sn9c102_i2c_write(cam, 0x09, ctrl->value);
130 break;
131 case V4L2_CID_BLUE_BALANCE:
132 err += sn9c102_i2c_write(cam, 0x07, ctrl->value);
133 break;
134 case V4L2_CID_GAIN:
135 err += sn9c102_i2c_write(cam, 0x10, ctrl->value);
136 break;
137 case SN9C102_V4L2_CID_GREEN_BALANCE:
138 err += sn9c102_i2c_write(cam, 0x08, ctrl->value);
139 break;
140 case SN9C102_V4L2_CID_DAC_MAGNITUDE:
141 err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
142 break;
143 default:
144 return -EINVAL;
145 }
146 err += sn9c102_i2c_write(cam, 0x11, 0x01);
147
148 return err ? -EIO : 0;
149}
150
151
152static int pas202bcb_set_crop(struct sn9c102_device* cam,
153 const struct v4l2_rect* rect)
154{
155 struct sn9c102_sensor* s = &pas202bcb;
156 int err = 0;
157 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4,
158 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3;
159
160 err += sn9c102_write_reg(cam, h_start, 0x12);
161 err += sn9c102_write_reg(cam, v_start, 0x13);
162
163 return err;
164}
165
166
167static struct sn9c102_sensor pas202bcb = {
168 .name = "PAS202BCB",
169 .maintainer = "Carlos Eduardo Medaglia Dyonisio "
170 "<medaglia@undl.org.br>",
171 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
172 .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
173 .interface = SN9C102_I2C_2WIRES,
174 .i2c_slave_id = 0x40,
175 .init = &pas202bcb_init,
176 .qctrl = {
177 {
178 .id = V4L2_CID_EXPOSURE,
179 .type = V4L2_CTRL_TYPE_INTEGER,
180 .name = "exposure",
181 .minimum = 0x01e5,
182 .maximum = 0x3fff,
183 .step = 0x0001,
184 .default_value = 0x01e5,
185 .flags = 0,
186 },
187 {
188 .id = V4L2_CID_GAIN,
189 .type = V4L2_CTRL_TYPE_INTEGER,
190 .name = "global gain",
191 .minimum = 0x00,
192 .maximum = 0x1f,
193 .step = 0x01,
194 .default_value = 0x0c,
195 .flags = 0,
196 },
197 {
198 .id = V4L2_CID_RED_BALANCE,
199 .type = V4L2_CTRL_TYPE_INTEGER,
200 .name = "red balance",
201 .minimum = 0x00,
202 .maximum = 0x0f,
203 .step = 0x01,
204 .default_value = 0x01,
205 .flags = 0,
206 },
207 {
208 .id = V4L2_CID_BLUE_BALANCE,
209 .type = V4L2_CTRL_TYPE_INTEGER,
210 .name = "blue balance",
211 .minimum = 0x00,
212 .maximum = 0x0f,
213 .step = 0x01,
214 .default_value = 0x05,
215 .flags = 0,
216 },
217 {
218 .id = SN9C102_V4L2_CID_GREEN_BALANCE,
219 .type = V4L2_CTRL_TYPE_INTEGER,
220 .name = "green balance",
221 .minimum = 0x00,
222 .maximum = 0x0f,
223 .step = 0x01,
224 .default_value = 0x00,
225 .flags = 0,
226 },
227 {
228 .id = SN9C102_V4L2_CID_DAC_MAGNITUDE,
229 .type = V4L2_CTRL_TYPE_INTEGER,
230 .name = "DAC magnitude",
231 .minimum = 0x00,
232 .maximum = 0xff,
233 .step = 0x01,
234 .default_value = 0x04,
235 .flags = 0,
236 },
237 },
238 .get_ctrl = &pas202bcb_get_ctrl,
239 .set_ctrl = &pas202bcb_set_ctrl,
240 .cropcap = {
241 .bounds = {
242 .left = 0,
243 .top = 0,
244 .width = 640,
245 .height = 480,
246 },
247 .defrect = {
248 .left = 0,
249 .top = 0,
250 .width = 640,
251 .height = 480,
252 },
253 },
254 .set_crop = &pas202bcb_set_crop,
255 .pix_format = {
256 .width = 640,
257 .height = 480,
258 .pixelformat = V4L2_PIX_FMT_SBGGR8,
259 .priv = 8,
260 },
261 .set_pix_format = &pas202bcb_set_pix_format
262};
263
264
265int sn9c102_probe_pas202bcb(struct sn9c102_device* cam)
266{
267 int r0 = 0, r1 = 0, err = 0;
268 unsigned int pid = 0;
269
270 /*
271 * Minimal initialization to enable the I2C communication
272 * NOTE: do NOT change the values!
273 */
274 err += sn9c102_write_reg(cam, 0x01, 0x01); /* sensor power down */
275 err += sn9c102_write_reg(cam, 0x40, 0x01); /* sensor power on */
276 err += sn9c102_write_reg(cam, 0x28, 0x17); /* sensor clock at 24 MHz */
277 if (err)
278 return -EIO;
279
280 r0 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x00);
281 r1 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x01);
282
283 if (r0 < 0 || r1 < 0)
284 return -EIO;
285
286 pid = (r0 << 4) | ((r1 & 0xf0) >> 4);
287 if (pid != 0x017)
288 return -ENODEV;
289
290 sn9c102_attach_sensor(cam, &pas202bcb);
291
292 return 0;
293}
diff --git a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h
new file mode 100644
index 000000000000..16f7483559f0
--- /dev/null
+++ b/drivers/usb/media/sn9c102_sensor.h
@@ -0,0 +1,373 @@
1/***************************************************************************
2 * API for image sensors connected to the SN9C10x PC Camera Controllers *
3 * *
4 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#ifndef _SN9C102_SENSOR_H_
22#define _SN9C102_SENSOR_H_
23
24#include <linux/usb.h>
25#include <linux/videodev.h>
26#include <linux/device.h>
27#include <linux/stddef.h>
28#include <linux/errno.h>
29#include <asm/types.h>
30
31struct sn9c102_device;
32struct sn9c102_sensor;
33
34/*****************************************************************************/
35
36/*
37 OVERVIEW.
38 This is a small interface that allows you to add support for any CCD/CMOS
39 image sensors connected to the SN9C10X bridges. The entire API is documented
40 below. In the most general case, to support a sensor there are three steps
41 you have to follow:
42 1) define the main "sn9c102_sensor" structure by setting the basic fields;
43 2) write a probing function to be called by the core module when the USB
44 camera is recognized, then add both the USB ids and the name of that
45 function to the two corresponding tables SENSOR_TABLE and ID_TABLE (see
46 below);
47 3) implement the methods that you want/need (and fill the rest of the main
48 structure accordingly).
49 "sn9c102_pas106b.c" is an example of all this stuff. Remember that you do
50 NOT need to touch the source code of the core module for the things to work
51 properly, unless you find bugs or flaws in it. Finally, do not forget to
52 read the V4L2 API for completeness.
53*/
54
55/*****************************************************************************/
56
57/*
58 Probing functions: on success, you must attach the sensor to the camera
59 by calling sn9c102_attach_sensor() provided below.
60 To enable the I2C communication, you might need to perform a really basic
61 initialization of the SN9C10X chip by using the write function declared
62 ahead.
63 Functions must return 0 on success, the appropriate error otherwise.
64*/
65extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam);
66extern int sn9c102_probe_mi0343(struct sn9c102_device* cam);
67extern int sn9c102_probe_pas106b(struct sn9c102_device* cam);
68extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam);
69extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam);
70extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam);
71
72/*
73 Add the above entries to this table. Be sure to add the entry in the right
74 place, since, on failure, the next probing routine is called according to
75 the order of the list below, from top to bottom.
76*/
77#define SN9C102_SENSOR_TABLE \
78static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = { \
79 &sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */ \
80 &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ \
81 &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ \
82 &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ \
83 &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ \
84 &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ \
85 NULL, \
86};
87
88/* Attach a probed sensor to the camera. */
89extern void
90sn9c102_attach_sensor(struct sn9c102_device* cam,
91 struct sn9c102_sensor* sensor);
92
93/* Each SN9C10X camera has proper PID/VID identifiers. Add them here in case.*/
94#define SN9C102_ID_TABLE \
95static const struct usb_device_id sn9c102_id_table[] = { \
96 { USB_DEVICE(0x0c45, 0x6001), }, /* TAS5110C1B */ \
97 { USB_DEVICE(0x0c45, 0x6005), }, /* TAS5110C1B */ \
98 { USB_DEVICE(0x0c45, 0x6009), }, /* PAS106B */ \
99 { USB_DEVICE(0x0c45, 0x600d), }, /* PAS106B */ \
100 { USB_DEVICE(0x0c45, 0x6024), }, \
101 { USB_DEVICE(0x0c45, 0x6025), }, /* TAS5130D1B and TAS5110C1B */ \
102 { USB_DEVICE(0x0c45, 0x6028), }, /* PAS202BCB */ \
103 { USB_DEVICE(0x0c45, 0x6029), }, /* PAS106B */ \
104 { USB_DEVICE(0x0c45, 0x602a), }, /* HV7131D */ \
105 { USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */ \
106 { USB_DEVICE(0x0c45, 0x602c), }, /* OV7620 */ \
107 { USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \
108 { USB_DEVICE(0x0c45, 0x6080), }, \
109 { USB_DEVICE(0x0c45, 0x6082), }, /* MI0343 and MI0360 */ \
110 { USB_DEVICE(0x0c45, 0x6083), }, /* HV7131[D|E1] */ \
111 { USB_DEVICE(0x0c45, 0x6088), }, \
112 { USB_DEVICE(0x0c45, 0x608a), }, \
113 { USB_DEVICE(0x0c45, 0x608b), }, \
114 { USB_DEVICE(0x0c45, 0x608c), }, /* HV7131x */ \
115 { USB_DEVICE(0x0c45, 0x608e), }, /* CIS-VF10 */ \
116 { USB_DEVICE(0x0c45, 0x608f), }, /* OV7630 */ \
117 { USB_DEVICE(0x0c45, 0x60a0), }, \
118 { USB_DEVICE(0x0c45, 0x60a2), }, \
119 { USB_DEVICE(0x0c45, 0x60a3), }, \
120 { USB_DEVICE(0x0c45, 0x60a8), }, /* PAS106B */ \
121 { USB_DEVICE(0x0c45, 0x60aa), }, /* TAS5130D1B */ \
122 { USB_DEVICE(0x0c45, 0x60ab), }, /* TAS5110C1B */ \
123 { USB_DEVICE(0x0c45, 0x60ac), }, \
124 { USB_DEVICE(0x0c45, 0x60ae), }, \
125 { USB_DEVICE(0x0c45, 0x60af), }, /* PAS202BCB */ \
126 { USB_DEVICE(0x0c45, 0x60b0), }, \
127 { USB_DEVICE(0x0c45, 0x60b2), }, \
128 { USB_DEVICE(0x0c45, 0x60b3), }, \
129 { USB_DEVICE(0x0c45, 0x60b8), }, \
130 { USB_DEVICE(0x0c45, 0x60ba), }, \
131 { USB_DEVICE(0x0c45, 0x60bb), }, \
132 { USB_DEVICE(0x0c45, 0x60bc), }, \
133 { USB_DEVICE(0x0c45, 0x60be), }, \
134 { } \
135};
136
137/*****************************************************************************/
138
139/*
140 Read/write routines: they always return -1 on error, 0 or the read value
141 otherwise. NOTE that a real read operation is not supported by the SN9C10X
142 chip for some of its registers. To work around this problem, a pseudo-read
143 call is provided instead: it returns the last successfully written value
144 on the register (0 if it has never been written), the usual -1 on error.
145*/
146
147/* The "try" I2C I/O versions are used when probing the sensor */
148extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*,
149 u8 address, u8 value);
150extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
151 u8 address);
152
153/*
154 These must be used if and only if the sensor doesn't implement the standard
155 I2C protocol. There are a number of good reasons why you must use the
156 single-byte versions of these functions: do not abuse. The first function
157 writes n bytes, from data0 to datan, to registers 0x09 - 0x09+n of SN9C10X
158 chip. The second one programs the registers 0x09 and 0x10 with data0 and
159 data1, and places the n bytes read from the sensor register table in the
160 buffer pointed by 'buffer'. Both the functions return -1 on error; the write
161 version returns 0 on success, while the read version returns the first read
162 byte.
163*/
164extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
165 struct sn9c102_sensor* sensor, u8 n,
166 u8 data0, u8 data1, u8 data2, u8 data3,
167 u8 data4, u8 data5);
168extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
169 struct sn9c102_sensor* sensor, u8 data0,
170 u8 data1, u8 n, u8 buffer[]);
171
172/* To be used after the sensor struct has been attached to the camera struct */
173extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
174extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
175
176/* I/O on registers in the bridge. Could be used by the sensor methods too */
177extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
178extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
179
180/*
181 NOTE: there are no exported debugging functions. To uniform the output you
182 must use the dev_info()/dev_warn()/dev_err() macros defined in device.h,
183 already included here, the argument being the struct device 'dev' of the
184 sensor structure. Do NOT use these macros before the sensor is attached or
185 the kernel will crash! However, you should not need to notify the user about
186 common errors or other messages, since this is done by the master module.
187*/
188
189/*****************************************************************************/
190
191enum sn9c102_i2c_sysfs_ops {
192 SN9C102_I2C_READ = 0x01,
193 SN9C102_I2C_WRITE = 0x02,
194};
195
196enum sn9c102_i2c_frequency { /* sensors may support both the frequencies */
197 SN9C102_I2C_100KHZ = 0x01,
198 SN9C102_I2C_400KHZ = 0x02,
199};
200
201enum sn9c102_i2c_interface {
202 SN9C102_I2C_2WIRES,
203 SN9C102_I2C_3WIRES,
204};
205
206struct sn9c102_sensor {
207 char name[32], /* sensor name */
208 maintainer[64]; /* name of the mantainer <email> */
209
210 /* Supported operations through the 'sysfs' interface */
211 enum sn9c102_i2c_sysfs_ops sysfs_ops;
212
213 /*
214 These sensor capabilities must be provided if the SN9C10X controller
215 needs to communicate through the sensor serial interface by using
216 at least one of the i2c functions available.
217 */
218 enum sn9c102_i2c_frequency frequency;
219 enum sn9c102_i2c_interface interface;
220
221 /*
222 This identifier must be provided if the image sensor implements
223 the standard I2C protocol.
224 */
225 u8 i2c_slave_id; /* reg. 0x09 */
226
227 /*
228 NOTE: Where not noted,most of the functions below are not mandatory.
229 Set to null if you do not implement them. If implemented,
230 they must return 0 on success, the proper error otherwise.
231 */
232
233 int (*init)(struct sn9c102_device* cam);
234 /*
235 This function will be called after the sensor has been attached.
236 It should be used to initialize the sensor only, but may also
237 configure part of the SN9C10X chip if necessary. You don't need to
238 setup picture settings like brightness, contrast, etc.. here, if
239 the corrisponding controls are implemented (see below), since
240 they are adjusted in the core driver by calling the set_ctrl()
241 method after init(), where the arguments are the default values
242 specified in the v4l2_queryctrl list of supported controls;
243 Same suggestions apply for other settings, _if_ the corresponding
244 methods are present; if not, the initialization must configure the
245 sensor according to the default configuration structures below.
246 */
247
248 struct v4l2_queryctrl qctrl[V4L2_CID_LASTP1-V4L2_CID_BASE];
249 /*
250 Optional list of default controls, defined as indicated in the
251 V4L2 API. Menu type controls are not handled by this interface.
252 */
253
254 int (*get_ctrl)(struct sn9c102_device* cam, struct v4l2_control* ctrl);
255 int (*set_ctrl)(struct sn9c102_device* cam,
256 const struct v4l2_control* ctrl);
257 /*
258 You must implement at least the set_ctrl method if you have defined
259 the list above. The returned value must follow the V4L2
260 specifications for the VIDIOC_G|C_CTRL ioctls. V4L2_CID_H|VCENTER
261 are not supported by this driver, so do not implement them. Also,
262 you don't have to check whether the passed values are out of bounds,
263 given that this is done by the core module.
264 */
265
266 struct v4l2_cropcap cropcap;
267 /*
268 Think the image sensor as a grid of R,G,B monochromatic pixels
269 disposed according to a particular Bayer pattern, which describes
270 the complete array of pixels, from (0,0) to (xmax, ymax). We will
271 use this coordinate system from now on. It is assumed the sensor
272 chip can be programmed to capture/transmit a subsection of that
273 array of pixels: we will call this subsection "active window".
274 It is not always true that the largest achievable active window can
275 cover the whole array of pixels. The V4L2 API defines another
276 area called "source rectangle", which, in turn, is a subrectangle of
277 the active window. The SN9C10X chip is always programmed to read the
278 source rectangle.
279 The bounds of both the active window and the source rectangle are
280 specified in the cropcap substructures 'bounds' and 'defrect'.
281 By default, the source rectangle should cover the largest possible
282 area. Again, it is not always true that the largest source rectangle
283 can cover the entire active window, although it is a rare case for
284 the hardware we have. The bounds of the source rectangle _must_ be
285 multiple of 16 and must use the same coordinate system as indicated
286 before; their centers shall align initially.
287 If necessary, the sensor chip must be initialized during init() to
288 set the bounds of the active sensor window; however, by default, it
289 usually covers the largest achievable area (maxwidth x maxheight)
290 of pixels, so no particular initialization is needed, if you have
291 defined the correct default bounds in the structures.
292 See the V4L2 API for further details.
293 NOTE: once you have defined the bounds of the active window
294 (struct cropcap.bounds) you must not change them.anymore.
295 Only 'bounds' and 'defrect' fields are mandatory, other fields
296 will be ignored.
297 */
298
299 int (*set_crop)(struct sn9c102_device* cam,
300 const struct v4l2_rect* rect);
301 /*
302 To be called on VIDIOC_C_SETCROP. The core module always calls a
303 default routine which configures the appropriate SN9C10X regs (also
304 scaling), but you may need to override/adjust specific stuff.
305 'rect' contains width and height values that are multiple of 16: in
306 case you override the default function, you always have to program
307 the chip to match those values; on error return the corresponding
308 error code without rolling back.
309 NOTE: in case, you must program the SN9C10X chip to get rid of
310 blank pixels or blank lines at the _start_ of each line or
311 frame after each HSYNC or VSYNC, so that the image starts with
312 real RGB data (see regs 0x12, 0x13) (having set H_SIZE and,
313 V_SIZE you don't have to care about blank pixels or blank
314 lines at the end of each line or frame).
315 */
316
317 struct v4l2_pix_format pix_format;
318 /*
319 What you have to define here are: 1) initial 'width' and 'height' of
320 the target rectangle 2) the initial 'pixelformat', which can be
321 either V4L2_PIX_FMT_SN9C10X (for compressed video) or
322 V4L2_PIX_FMT_SBGGR8 3) 'priv', which we'll be used to indicate the
323 number of bits per pixel for uncompressed video, 8 or 9 (despite the
324 current value of 'pixelformat').
325 NOTE 1: both 'width' and 'height' _must_ be either 1/1 or 1/2 or 1/4
326 of cropcap.defrect.width and cropcap.defrect.height. I
327 suggest 1/1.
328 NOTE 2: The initial compression quality is defined by the first bit
329 of reg 0x17 during the initialization of the image sensor.
330 NOTE 3: as said above, you have to program the SN9C10X chip to get
331 rid of any blank pixels, so that the output of the sensor
332 matches the RGB bayer sequence (i.e. BGBGBG...GRGRGR).
333 */
334
335 int (*set_pix_format)(struct sn9c102_device* cam,
336 const struct v4l2_pix_format* pix);
337 /*
338 To be called on VIDIOC_S_FMT, when switching from the SBGGR8 to
339 SN9C10X pixel format or viceversa. On error return the corresponding
340 error code without rolling back.
341 */
342
343 const struct device* dev;
344 /*
345 This is the argument for dev_err(), dev_info() and dev_warn(). It
346 is used for debugging purposes. You must not access the struct
347 before the sensor is attached.
348 */
349
350 const struct usb_device* usbdev;
351 /*
352 Points to the usb_device struct after the sensor is attached.
353 Do not touch unless you know what you are doing.
354 */
355
356 /*
357 Do NOT write to the data below, it's READ ONLY. It is used by the
358 core module to store successfully updated values of the above
359 settings, for rollbacks..etc..in case of errors during atomic I/O
360 */
361 struct v4l2_queryctrl _qctrl[V4L2_CID_LASTP1-V4L2_CID_BASE];
362 struct v4l2_rect _rect;
363};
364
365/*****************************************************************************/
366
367/* Private ioctl's for control settings supported by some image sensors */
368#define SN9C102_V4L2_CID_DAC_MAGNITUDE V4L2_CID_PRIVATE_BASE
369#define SN9C102_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 1
370#define SN9C102_V4L2_CID_RESET_LEVEL V4L2_CID_PRIVATE_BASE + 2
371#define SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE V4L2_CID_PRIVATE_BASE + 3
372
373#endif /* _SN9C102_SENSOR_H_ */
diff --git a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c
new file mode 100644
index 000000000000..690d62192273
--- /dev/null
+++ b/drivers/usb/media/sn9c102_tas5110c1b.c
@@ -0,0 +1,174 @@
1/***************************************************************************
2 * Plug-in for TAS5110C1B image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "sn9c102_sensor.h"
23
24
25static struct sn9c102_sensor tas5110c1b;
26
27static struct v4l2_control tas5110c1b_gain;
28
29
30static int tas5110c1b_init(struct sn9c102_device* cam)
31{
32 int err = 0;
33
34 err += sn9c102_write_reg(cam, 0x01, 0x01);
35 err += sn9c102_write_reg(cam, 0x44, 0x01);
36 err += sn9c102_write_reg(cam, 0x00, 0x10);
37 err += sn9c102_write_reg(cam, 0x00, 0x11);
38 err += sn9c102_write_reg(cam, 0x0a, 0x14);
39 err += sn9c102_write_reg(cam, 0x60, 0x17);
40 err += sn9c102_write_reg(cam, 0x06, 0x18);
41 err += sn9c102_write_reg(cam, 0xfb, 0x19);
42
43 err += sn9c102_i2c_write(cam, 0xc0, 0x80);
44
45 return err;
46}
47
48
49static int tas5110c1b_get_ctrl(struct sn9c102_device* cam,
50 struct v4l2_control* ctrl)
51{
52 switch (ctrl->id) {
53 case V4L2_CID_GAIN:
54 ctrl->value = tas5110c1b_gain.value;
55 break;
56 default:
57 return -EINVAL;
58 }
59
60 return 0;
61}
62
63
64static int tas5110c1b_set_ctrl(struct sn9c102_device* cam,
65 const struct v4l2_control* ctrl)
66{
67 int err = 0;
68
69 switch (ctrl->id) {
70 case V4L2_CID_GAIN:
71 if (!(err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value)))
72 tas5110c1b_gain.value = ctrl->value;
73 break;
74 default:
75 return -EINVAL;
76 }
77
78 return err ? -EIO : 0;
79}
80
81
82static int tas5110c1b_set_crop(struct sn9c102_device* cam,
83 const struct v4l2_rect* rect)
84{
85 struct sn9c102_sensor* s = &tas5110c1b;
86 int err = 0;
87 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69,
88 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9;
89
90 err += sn9c102_write_reg(cam, h_start, 0x12);
91 err += sn9c102_write_reg(cam, v_start, 0x13);
92
93 /* Don't change ! */
94 err += sn9c102_write_reg(cam, 0x14, 0x1a);
95 err += sn9c102_write_reg(cam, 0x0a, 0x1b);
96 err += sn9c102_write_reg(cam, sn9c102_pread_reg(cam, 0x19), 0x19);
97
98 return err;
99}
100
101
102static int tas5110c1b_set_pix_format(struct sn9c102_device* cam,
103 const struct v4l2_pix_format* pix)
104{
105 int err = 0;
106
107 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
108 err += sn9c102_write_reg(cam, 0x2b, 0x19);
109 else
110 err += sn9c102_write_reg(cam, 0xfb, 0x19);
111
112 return err;
113}
114
115
116static struct sn9c102_sensor tas5110c1b = {
117 .name = "TAS5110C1B",
118 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
119 .sysfs_ops = SN9C102_I2C_WRITE,
120 .frequency = SN9C102_I2C_100KHZ,
121 .interface = SN9C102_I2C_3WIRES,
122 .init = &tas5110c1b_init,
123 .qctrl = {
124 {
125 .id = V4L2_CID_GAIN,
126 .type = V4L2_CTRL_TYPE_INTEGER,
127 .name = "global gain",
128 .minimum = 0x00,
129 .maximum = 0xf6,
130 .step = 0x01,
131 .default_value = 0x40,
132 .flags = 0,
133 },
134 },
135 .set_ctrl = &tas5110c1b_set_ctrl,
136 .cropcap = {
137 .bounds = {
138 .left = 0,
139 .top = 0,
140 .width = 352,
141 .height = 288,
142 },
143 .defrect = {
144 .left = 0,
145 .top = 0,
146 .width = 352,
147 .height = 288,
148 },
149 },
150 .get_ctrl = &tas5110c1b_get_ctrl,
151 .set_crop = &tas5110c1b_set_crop,
152 .pix_format = {
153 .width = 352,
154 .height = 288,
155 .pixelformat = V4L2_PIX_FMT_SBGGR8,
156 .priv = 8,
157 },
158 .set_pix_format = &tas5110c1b_set_pix_format
159};
160
161
162int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam)
163{
164 /* This sensor has no identifiers, so let's attach it anyway */
165 sn9c102_attach_sensor(cam, &tas5110c1b);
166
167 /* Sensor detection is based on USB pid/vid */
168 if (le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x6001 &&
169 le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x6005 &&
170 le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x60ab)
171 return -ENODEV;
172
173 return 0;
174}
diff --git a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c
new file mode 100644
index 000000000000..b378e941bbe8
--- /dev/null
+++ b/drivers/usb/media/sn9c102_tas5130d1b.c
@@ -0,0 +1,188 @@
1/***************************************************************************
2 * Plug-in for TAS5130D1B image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "sn9c102_sensor.h"
23
24
25static struct sn9c102_sensor tas5130d1b;
26
27static struct v4l2_control tas5130d1b_gain, tas5130d1b_exposure;
28
29
30static int tas5130d1b_init(struct sn9c102_device* cam)
31{
32 int err = 0;
33
34 err += sn9c102_write_reg(cam, 0x01, 0x01);
35 err += sn9c102_write_reg(cam, 0x20, 0x17);
36 err += sn9c102_write_reg(cam, 0x04, 0x01);
37 err += sn9c102_write_reg(cam, 0x01, 0x10);
38 err += sn9c102_write_reg(cam, 0x00, 0x11);
39 err += sn9c102_write_reg(cam, 0x00, 0x14);
40 err += sn9c102_write_reg(cam, 0x60, 0x17);
41 err += sn9c102_write_reg(cam, 0x07, 0x18);
42
43 return err;
44}
45
46
47static int tas5130d1b_get_ctrl(struct sn9c102_device* cam,
48 struct v4l2_control* ctrl)
49{
50 switch (ctrl->id) {
51 case V4L2_CID_GAIN:
52 ctrl->value = tas5130d1b_gain.value;
53 break;
54 case V4L2_CID_EXPOSURE:
55 ctrl->value = tas5130d1b_exposure.value;
56 break;
57 default:
58 return -EINVAL;
59 }
60
61 return 0;
62}
63
64
65static int tas5130d1b_set_ctrl(struct sn9c102_device* cam,
66 const struct v4l2_control* ctrl)
67{
68 int err = 0;
69
70 switch (ctrl->id) {
71 case V4L2_CID_GAIN:
72 if (!(err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value)))
73 tas5130d1b_gain.value = ctrl->value;
74 break;
75 case V4L2_CID_EXPOSURE:
76 if (!(err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value)))
77 tas5130d1b_exposure.value = ctrl->value;
78 break;
79 default:
80 return -EINVAL;
81 }
82
83 return err ? -EIO : 0;
84}
85
86
87static int tas5130d1b_set_crop(struct sn9c102_device* cam,
88 const struct v4l2_rect* rect)
89{
90 struct sn9c102_sensor* s = &tas5130d1b;
91 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 104,
92 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 12;
93 int err = 0;
94
95 err += sn9c102_write_reg(cam, h_start, 0x12);
96 err += sn9c102_write_reg(cam, v_start, 0x13);
97
98 /* Do NOT change! */
99 err += sn9c102_write_reg(cam, 0x1f, 0x1a);
100 err += sn9c102_write_reg(cam, 0x1a, 0x1b);
101 err += sn9c102_write_reg(cam, sn9c102_pread_reg(cam, 0x19), 0x19);
102
103 return err;
104}
105
106
107static int tas5130d1b_set_pix_format(struct sn9c102_device* cam,
108 const struct v4l2_pix_format* pix)
109{
110 int err = 0;
111
112 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
113 err += sn9c102_write_reg(cam, 0x63, 0x19);
114 else
115 err += sn9c102_write_reg(cam, 0xf3, 0x19);
116
117 return err;
118}
119
120
121static struct sn9c102_sensor tas5130d1b = {
122 .name = "TAS5130D1B",
123 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
124 .sysfs_ops = SN9C102_I2C_WRITE,
125 .frequency = SN9C102_I2C_100KHZ,
126 .interface = SN9C102_I2C_3WIRES,
127 .init = &tas5130d1b_init,
128 .qctrl = {
129 {
130 .id = V4L2_CID_GAIN,
131 .type = V4L2_CTRL_TYPE_INTEGER,
132 .name = "global gain",
133 .minimum = 0x00,
134 .maximum = 0xf6,
135 .step = 0x02,
136 .default_value = 0x00,
137 .flags = 0,
138 },
139 {
140 .id = V4L2_CID_EXPOSURE,
141 .type = V4L2_CTRL_TYPE_INTEGER,
142 .name = "exposure",
143 .minimum = 0x00,
144 .maximum = 0x47,
145 .step = 0x01,
146 .default_value = 0x00,
147 .flags = 0,
148 },
149 },
150 .get_ctrl = &tas5130d1b_get_ctrl,
151 .set_ctrl = &tas5130d1b_set_ctrl,
152 .cropcap = {
153 .bounds = {
154 .left = 0,
155 .top = 0,
156 .width = 640,
157 .height = 480,
158 },
159 .defrect = {
160 .left = 0,
161 .top = 0,
162 .width = 640,
163 .height = 480,
164 },
165 },
166 .set_crop = &tas5130d1b_set_crop,
167 .pix_format = {
168 .width = 640,
169 .height = 480,
170 .pixelformat = V4L2_PIX_FMT_SBGGR8,
171 .priv = 8,
172 },
173 .set_pix_format = &tas5130d1b_set_pix_format
174};
175
176
177int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam)
178{
179 /* This sensor has no identifiers, so let's attach it anyway */
180 sn9c102_attach_sensor(cam, &tas5130d1b);
181
182 /* Sensor detection is based on USB pid/vid */
183 if (le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x6025 &&
184 le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x60aa)
185 return -ENODEV;
186
187 return 0;
188}
diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c
new file mode 100644
index 000000000000..ae455c8e3702
--- /dev/null
+++ b/drivers/usb/media/stv680.c
@@ -0,0 +1,1506 @@
1/*
2 * STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net)
3 *
4 * Thanks to STMicroelectronics for information on the usb commands, and
5 * to Steve Miller at STM for his help and encouragement while I was
6 * writing this driver.
7 *
8 * This driver is based heavily on the
9 * Endpoints (formerly known as AOX) se401 USB Camera Driver
10 * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
11 *
12 * Still somewhat based on the Linux ov511 driver.
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software Foundation,
26 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * History:
29 * ver 0.1 October, 2001. Initial attempt.
30 *
31 * ver 0.2 November, 2001. Fixed asbility to resize, added brightness
32 * function, made more stable (?)
33 *
34 * ver 0.21 Nov, 2001. Added gamma correction and white balance,
35 * due to Alexander Schwartz. Still trying to
36 * improve stablility. Moved stuff into stv680.h
37 *
38 * ver 0.22 Nov, 2001. Added sharpen function (by Michael Sweet,
39 * mike@easysw.com) from GIMP, also used in pencam.
40 * Simple, fast, good integer math routine.
41 *
42 * ver 0.23 Dec, 2001 (gkh)
43 * Took out sharpen function, ran code through
44 * Lindent, and did other minor tweaks to get
45 * things to work properly with 2.5.1
46 *
47 * ver 0.24 Jan, 2002 (kjs)
48 * Fixed the problem with webcam crashing after
49 * two pictures. Changed the way pic is halved to
50 * improve quality. Got rid of green line around
51 * frame. Fix brightness reset when changing size
52 * bug. Adjusted gamma filters slightly.
53 *
54 * ver 0.25 Jan, 2002 (kjs)
55 * Fixed a bug in which the driver sometimes attempted
56 * to set to a non-supported size. This allowed
57 * gnomemeeting to work.
58 * Fixed proc entry removal bug.
59 */
60
61#include <linux/config.h>
62#include <linux/module.h>
63#include <linux/init.h>
64#include <linux/vmalloc.h>
65#include <linux/slab.h>
66#include <linux/pagemap.h>
67#include <linux/errno.h>
68#include <linux/videodev.h>
69#include <linux/usb.h>
70
71#include "stv680.h"
72
73static int video_nr = -1;
74static int swapRGB = 0; /* default for auto sleect */
75static int swapRGB_on = 0; /* default to allow auto select; -1=swap never, +1= swap always */
76
77static unsigned int debug = 0;
78
79#define PDEBUG(level, fmt, args...) \
80 do { \
81 if (debug >= level) \
82 info("[%s:%d] " fmt, __FUNCTION__, __LINE__ , ## args); \
83 } while (0)
84
85
86/*
87 * Version Information
88 */
89#define DRIVER_VERSION "v0.25"
90#define DRIVER_AUTHOR "Kevin Sisson <kjsisson@bellsouth.net>"
91#define DRIVER_DESC "STV0680 USB Camera Driver"
92
93MODULE_AUTHOR (DRIVER_AUTHOR);
94MODULE_DESCRIPTION (DRIVER_DESC);
95MODULE_LICENSE ("GPL");
96module_param(debug, int, S_IRUGO | S_IWUSR);
97MODULE_PARM_DESC (debug, "Debug enabled or not");
98module_param(swapRGB_on, int, 0);
99MODULE_PARM_DESC (swapRGB_on, "Red/blue swap: 1=always, 0=auto, -1=never");
100module_param(video_nr, int, 0);
101
102/********************************************************************
103 *
104 * Memory management
105 *
106 * This is a shameless copy from the USB-cpia driver (linux kernel
107 * version 2.3.29 or so, I have no idea what this code actually does ;).
108 * Actually it seems to be a copy of a shameless copy of the bttv-driver.
109 * Or that is a copy of a shameless copy of ... (To the powers: is there
110 * no generic kernel-function to do this sort of stuff?)
111 *
112 * Yes, it was a shameless copy from the bttv-driver. IIRC, Alan says
113 * there will be one, but apparentely not yet -jerdfelt
114 *
115 * So I copied it again for the ov511 driver -claudio
116 *
117 * Same for the se401 driver -Jeroen
118 *
119 * And the STV0680 driver - Kevin
120 ********************************************************************/
121static void *rvmalloc (unsigned long size)
122{
123 void *mem;
124 unsigned long adr;
125
126 size = PAGE_ALIGN(size);
127 mem = vmalloc_32 (size);
128 if (!mem)
129 return NULL;
130
131 memset (mem, 0, size); /* Clear the ram out, no junk to the user */
132 adr = (unsigned long) mem;
133 while (size > 0) {
134 SetPageReserved(vmalloc_to_page((void *)adr));
135 adr += PAGE_SIZE;
136 size -= PAGE_SIZE;
137 }
138 return mem;
139}
140
141static void rvfree (void *mem, unsigned long size)
142{
143 unsigned long adr;
144
145 if (!mem)
146 return;
147
148 adr = (unsigned long) mem;
149 while ((long) size > 0) {
150 ClearPageReserved(vmalloc_to_page((void *)adr));
151 adr += PAGE_SIZE;
152 size -= PAGE_SIZE;
153 }
154 vfree (mem);
155}
156
157
158/*********************************************************************
159 * pencam read/write functions
160 ********************************************************************/
161
162static int stv_sndctrl (int set, struct usb_stv *stv680, unsigned short req, unsigned short value, unsigned char *buffer, int size)
163{
164 int ret = -1;
165
166 switch (set) {
167 case 0: /* 0xc1 */
168 ret = usb_control_msg (stv680->udev,
169 usb_rcvctrlpipe (stv680->udev, 0),
170 req,
171 (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT),
172 value, 0, buffer, size, PENCAM_TIMEOUT);
173 break;
174
175 case 1: /* 0x41 */
176 ret = usb_control_msg (stv680->udev,
177 usb_sndctrlpipe (stv680->udev, 0),
178 req,
179 (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT),
180 value, 0, buffer, size, PENCAM_TIMEOUT);
181 break;
182
183 case 2: /* 0x80 */
184 ret = usb_control_msg (stv680->udev,
185 usb_rcvctrlpipe (stv680->udev, 0),
186 req,
187 (USB_DIR_IN | USB_RECIP_DEVICE),
188 value, 0, buffer, size, PENCAM_TIMEOUT);
189 break;
190
191 case 3: /* 0x40 */
192 ret = usb_control_msg (stv680->udev,
193 usb_sndctrlpipe (stv680->udev, 0),
194 req,
195 (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
196 value, 0, buffer, size, PENCAM_TIMEOUT);
197 break;
198
199 }
200 if ((ret < 0) && (req != 0x0a)) {
201 PDEBUG (1, "STV(e): usb_control_msg error %i, request = 0x%x, error = %i", set, req, ret);
202 }
203 return ret;
204}
205
206static int stv_set_config (struct usb_stv *dev, int configuration, int interface, int alternate)
207{
208
209 if (configuration != dev->udev->actconfig->desc.bConfigurationValue
210 || usb_reset_configuration (dev->udev) < 0) {
211 PDEBUG (1, "STV(e): FAILED to reset configuration %i", configuration);
212 return -1;
213 }
214 if (usb_set_interface (dev->udev, interface, alternate) < 0) {
215 PDEBUG (1, "STV(e): FAILED to set alternate interface %i", alternate);
216 return -1;
217 }
218 return 0;
219}
220
221static int stv_stop_video (struct usb_stv *dev)
222{
223 int i;
224 unsigned char *buf;
225
226 buf = kmalloc (40, GFP_KERNEL);
227 if (buf == NULL) {
228 PDEBUG (0, "STV(e): Out of (small buf) memory");
229 return -1;
230 }
231
232 /* this is a high priority command; it stops all lower order commands */
233 if ((i = stv_sndctrl (1, dev, 0x04, 0x0000, buf, 0x0)) < 0) {
234 i = stv_sndctrl (0, dev, 0x80, 0, buf, 0x02); /* Get Last Error; 2 = busy */
235 PDEBUG (1, "STV(i): last error: %i, command = 0x%x", buf[0], buf[1]);
236 } else {
237 PDEBUG (1, "STV(i): Camera reset to idle mode.");
238 }
239
240 if ((i = stv_set_config (dev, 1, 0, 0)) < 0)
241 PDEBUG (1, "STV(e): Reset config during exit failed");
242
243 /* get current mode */
244 buf[0] = 0xf0;
245 if ((i = stv_sndctrl (0, dev, 0x87, 0, buf, 0x08)) != 0x08) /* get mode */
246 PDEBUG (0, "STV(e): Stop_video: problem setting original mode");
247 if (dev->origMode != buf[0]) {
248 memset (buf, 0, 8);
249 buf[0] = (unsigned char) dev->origMode;
250 if ((i = stv_sndctrl (3, dev, 0x07, 0x0100, buf, 0x08)) != 0x08) {
251 PDEBUG (0, "STV(e): Stop_video: Set_Camera_Mode failed");
252 i = -1;
253 }
254 buf[0] = 0xf0;
255 i = stv_sndctrl (0, dev, 0x87, 0, buf, 0x08);
256 if ((i != 0x08) || (buf[0] != dev->origMode)) {
257 PDEBUG (0, "STV(e): camera NOT set to original resolution.");
258 i = -1;
259 } else
260 PDEBUG (0, "STV(i): Camera set to original resolution");
261 }
262 /* origMode */
263 kfree (buf);
264 return i;
265}
266
267static int stv_set_video_mode (struct usb_stv *dev)
268{
269 int i, stop_video = 1;
270 unsigned char *buf;
271
272 buf = kmalloc (40, GFP_KERNEL);
273 if (buf == NULL) {
274 PDEBUG (0, "STV(e): Out of (small buf) memory");
275 return -1;
276 }
277
278 if ((i = stv_set_config (dev, 1, 0, 0)) < 0) {
279 kfree (buf);
280 return i;
281 }
282
283 i = stv_sndctrl (2, dev, 0x06, 0x0100, buf, 0x12);
284 if (!(i > 0) && (buf[8] == 0x53) && (buf[9] == 0x05)) {
285 PDEBUG (1, "STV(e): Could not get descriptor 0100.");
286 goto error;
287 }
288
289 /* set alternate interface 1 */
290 if ((i = stv_set_config (dev, 1, 0, 1)) < 0)
291 goto error;
292
293 if ((i = stv_sndctrl (0, dev, 0x85, 0, buf, 0x10)) != 0x10)
294 goto error;
295 PDEBUG (1, "STV(i): Setting video mode.");
296 /* Switch to Video mode: 0x0100 = VGA (640x480), 0x0000 = CIF (352x288) 0x0300 = QVGA (320x240) */
297 if ((i = stv_sndctrl (1, dev, 0x09, dev->VideoMode, buf, 0x0)) < 0) {
298 stop_video = 0;
299 goto error;
300 }
301 goto exit;
302
303error:
304 kfree (buf);
305 if (stop_video == 1)
306 stv_stop_video (dev);
307 return -1;
308
309exit:
310 kfree (buf);
311 return 0;
312}
313
314static int stv_init (struct usb_stv *stv680)
315{
316 int i = 0;
317 unsigned char *buffer;
318 unsigned long int bufsize;
319
320 buffer = kmalloc (40, GFP_KERNEL);
321 if (buffer == NULL) {
322 PDEBUG (0, "STV(e): Out of (small buf) memory");
323 return -1;
324 }
325 memset (buffer, 0, 40);
326 udelay (100);
327
328 /* set config 1, interface 0, alternate 0 */
329 if ((i = stv_set_config (stv680, 1, 0, 0)) < 0) {
330 kfree (buffer);
331 PDEBUG (0, "STV(e): set config 1,0,0 failed");
332 return -1;
333 }
334 /* ping camera to be sure STV0680 is present */
335 if ((i = stv_sndctrl (0, stv680, 0x88, 0x5678, buffer, 0x02)) != 0x02)
336 goto error;
337 if ((buffer[0] != 0x56) || (buffer[1] != 0x78)) {
338 PDEBUG (1, "STV(e): camera ping failed!!");
339 goto error;
340 }
341
342 /* get camera descriptor */
343 if ((i = stv_sndctrl (2, stv680, 0x06, 0x0200, buffer, 0x09)) != 0x09)
344 goto error;
345 i = stv_sndctrl (2, stv680, 0x06, 0x0200, buffer, 0x22);
346 if (!(i >= 0) && (buffer[7] == 0xa0) && (buffer[8] == 0x23)) {
347 PDEBUG (1, "STV(e): Could not get descriptor 0200.");
348 goto error;
349 }
350 if ((i = stv_sndctrl (0, stv680, 0x8a, 0, buffer, 0x02)) != 0x02)
351 goto error;
352 if ((i = stv_sndctrl (0, stv680, 0x8b, 0, buffer, 0x24)) != 0x24)
353 goto error;
354 if ((i = stv_sndctrl (0, stv680, 0x85, 0, buffer, 0x10)) != 0x10)
355 goto error;
356
357 stv680->SupportedModes = buffer[7];
358 i = stv680->SupportedModes;
359 stv680->CIF = 0;
360 stv680->VGA = 0;
361 stv680->QVGA = 0;
362 if (i & 1)
363 stv680->CIF = 1;
364 if (i & 2)
365 stv680->VGA = 1;
366 if (i & 8)
367 stv680->QVGA = 1;
368 if (stv680->SupportedModes == 0) {
369 PDEBUG (0, "STV(e): There are NO supported STV680 modes!!");
370 i = -1;
371 goto error;
372 } else {
373 if (stv680->CIF)
374 PDEBUG (0, "STV(i): CIF is supported");
375 if (stv680->QVGA)
376 PDEBUG (0, "STV(i): QVGA is supported");
377 }
378 /* FW rev, ASIC rev, sensor ID */
379 PDEBUG (1, "STV(i): Firmware rev is %i.%i", buffer[0], buffer[1]);
380 PDEBUG (1, "STV(i): ASIC rev is %i.%i", buffer[2], buffer[3]);
381 PDEBUG (1, "STV(i): Sensor ID is %i", (buffer[4]*16) + (buffer[5]>>4));
382
383 /* set alternate interface 1 */
384 if ((i = stv_set_config (stv680, 1, 0, 1)) < 0)
385 goto error;
386
387 if ((i = stv_sndctrl (0, stv680, 0x85, 0, buffer, 0x10)) != 0x10)
388 goto error;
389 if ((i = stv_sndctrl (0, stv680, 0x8d, 0, buffer, 0x08)) != 0x08)
390 goto error;
391 i = buffer[3];
392 PDEBUG (0, "STV(i): Camera has %i pictures.", i);
393
394 /* get current mode */
395 if ((i = stv_sndctrl (0, stv680, 0x87, 0, buffer, 0x08)) != 0x08)
396 goto error;
397 stv680->origMode = buffer[0]; /* 01 = VGA, 03 = QVGA, 00 = CIF */
398
399 /* This will attemp CIF mode, if supported. If not, set to QVGA */
400 memset (buffer, 0, 8);
401 if (stv680->CIF)
402 buffer[0] = 0x00;
403 else if (stv680->QVGA)
404 buffer[0] = 0x03;
405 if ((i = stv_sndctrl (3, stv680, 0x07, 0x0100, buffer, 0x08)) != 0x08) {
406 PDEBUG (0, "STV(i): Set_Camera_Mode failed");
407 i = -1;
408 goto error;
409 }
410 buffer[0] = 0xf0;
411 stv_sndctrl (0, stv680, 0x87, 0, buffer, 0x08);
412 if (((stv680->CIF == 1) && (buffer[0] != 0x00)) || ((stv680->QVGA == 1) && (buffer[0] != 0x03))) {
413 PDEBUG (0, "STV(e): Error setting camera video mode!");
414 i = -1;
415 goto error;
416 } else {
417 if (buffer[0] == 0) {
418 stv680->VideoMode = 0x0000;
419 PDEBUG (0, "STV(i): Video Mode set to CIF");
420 }
421 if (buffer[0] == 0x03) {
422 stv680->VideoMode = 0x0300;
423 PDEBUG (0, "STV(i): Video Mode set to QVGA");
424 }
425 }
426 if ((i = stv_sndctrl (0, stv680, 0x8f, 0, buffer, 0x10)) != 0x10)
427 goto error;
428 bufsize = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | (buffer[3]);
429 stv680->cwidth = (buffer[4] << 8) | (buffer[5]); /* ->camera = 322, 356, 644 */
430 stv680->cheight = (buffer[6] << 8) | (buffer[7]); /* ->camera = 242, 292, 484 */
431 stv680->origGain = buffer[12];
432
433 goto exit;
434
435error:
436 i = stv_sndctrl (0, stv680, 0x80, 0, buffer, 0x02); /* Get Last Error */
437 PDEBUG (1, "STV(i): last error: %i, command = 0x%x", buffer[0], buffer[1]);
438 kfree (buffer);
439 return -1;
440
441exit:
442 kfree (buffer);
443
444 /* video = 320x240, 352x288 */
445 if (stv680->CIF == 1) {
446 stv680->maxwidth = 352;
447 stv680->maxheight = 288;
448 stv680->vwidth = 352;
449 stv680->vheight = 288;
450 }
451 if (stv680->QVGA == 1) {
452 stv680->maxwidth = 320;
453 stv680->maxheight = 240;
454 stv680->vwidth = 320;
455 stv680->vheight = 240;
456 }
457
458 stv680->rawbufsize = bufsize; /* must be ./. by 8 */
459 stv680->maxframesize = bufsize * 3; /* RGB size */
460 PDEBUG (2, "STV(i): cwidth = %i, cheight = %i", stv680->cwidth, stv680->cheight);
461 PDEBUG (1, "STV(i): width = %i, height = %i, rawbufsize = %li", stv680->vwidth, stv680->vheight, stv680->rawbufsize);
462
463 /* some default values */
464 stv680->bulk_in_endpointAddr = 0x82;
465 stv680->dropped = 0;
466 stv680->error = 0;
467 stv680->framecount = 0;
468 stv680->readcount = 0;
469 stv680->streaming = 0;
470 /* bright, white, colour, hue, contrast are set by software, not in stv0680 */
471 stv680->brightness = 32767;
472 stv680->chgbright = 0;
473 stv680->whiteness = 0; /* only for greyscale */
474 stv680->colour = 32767;
475 stv680->contrast = 32767;
476 stv680->hue = 32767;
477 stv680->palette = STV_VIDEO_PALETTE;
478 stv680->depth = 24; /* rgb24 bits */
479 if ((swapRGB_on == 0) && (swapRGB == 0))
480 PDEBUG (1, "STV(i): swapRGB is (auto) OFF");
481 else if ((swapRGB_on == 0) && (swapRGB == 1))
482 PDEBUG (1, "STV(i): swapRGB is (auto) ON");
483 else if (swapRGB_on == 1)
484 PDEBUG (1, "STV(i): swapRGB is (forced) ON");
485 else if (swapRGB_on == -1)
486 PDEBUG (1, "STV(i): swapRGB is (forced) OFF");
487
488 if (stv_set_video_mode (stv680) < 0) {
489 PDEBUG (0, "STV(e): Could not set video mode in stv_init");
490 return -1;
491 }
492
493 return 0;
494}
495
496/***************** last of pencam routines *******************/
497
498/****************************************************************************
499 * sysfs
500 ***************************************************************************/
501#define stv680_file(name, variable, field) \
502static ssize_t show_##name(struct class_device *class_dev, char *buf) \
503{ \
504 struct video_device *vdev = to_video_device(class_dev); \
505 struct usb_stv *stv = video_get_drvdata(vdev); \
506 return sprintf(buf, field, stv->variable); \
507} \
508static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
509
510stv680_file(model, camera_name, "%s\n");
511stv680_file(in_use, user, "%d\n");
512stv680_file(streaming, streaming, "%d\n");
513stv680_file(palette, palette, "%i\n");
514stv680_file(frames_total, readcount, "%d\n");
515stv680_file(frames_read, framecount, "%d\n");
516stv680_file(packets_dropped, dropped, "%d\n");
517stv680_file(decoding_errors, error, "%d\n");
518
519static void stv680_create_sysfs_files(struct video_device *vdev)
520{
521 video_device_create_file(vdev, &class_device_attr_model);
522 video_device_create_file(vdev, &class_device_attr_in_use);
523 video_device_create_file(vdev, &class_device_attr_streaming);
524 video_device_create_file(vdev, &class_device_attr_palette);
525 video_device_create_file(vdev, &class_device_attr_frames_total);
526 video_device_create_file(vdev, &class_device_attr_frames_read);
527 video_device_create_file(vdev, &class_device_attr_packets_dropped);
528 video_device_create_file(vdev, &class_device_attr_decoding_errors);
529}
530
531static void stv680_remove_sysfs_files(struct video_device *vdev)
532{
533 video_device_remove_file(vdev, &class_device_attr_model);
534 video_device_remove_file(vdev, &class_device_attr_in_use);
535 video_device_remove_file(vdev, &class_device_attr_streaming);
536 video_device_remove_file(vdev, &class_device_attr_palette);
537 video_device_remove_file(vdev, &class_device_attr_frames_total);
538 video_device_remove_file(vdev, &class_device_attr_frames_read);
539 video_device_remove_file(vdev, &class_device_attr_packets_dropped);
540 video_device_remove_file(vdev, &class_device_attr_decoding_errors);
541}
542
543/********************************************************************
544 * Camera control
545 *******************************************************************/
546
547static int stv680_get_pict (struct usb_stv *stv680, struct video_picture *p)
548{
549 /* This sets values for v4l interface. max/min = 65535/0 */
550
551 p->brightness = stv680->brightness;
552 p->whiteness = stv680->whiteness; /* greyscale */
553 p->colour = stv680->colour;
554 p->contrast = stv680->contrast;
555 p->hue = stv680->hue;
556 p->palette = stv680->palette;
557 p->depth = stv680->depth;
558 return 0;
559}
560
561static int stv680_set_pict (struct usb_stv *stv680, struct video_picture *p)
562{
563 /* See above stv680_get_pict */
564
565 if (p->palette != STV_VIDEO_PALETTE) {
566 PDEBUG (2, "STV(e): Palette set error in _set_pic");
567 return 1;
568 }
569
570 if (stv680->brightness != p->brightness) {
571 stv680->chgbright = 1;
572 stv680->brightness = p->brightness;
573 }
574
575 stv680->whiteness = p->whiteness; /* greyscale */
576 stv680->colour = p->colour;
577 stv680->contrast = p->contrast;
578 stv680->hue = p->hue;
579 stv680->palette = p->palette;
580 stv680->depth = p->depth;
581
582 return 0;
583}
584
585static void stv680_video_irq (struct urb *urb, struct pt_regs *regs)
586{
587 struct usb_stv *stv680 = urb->context;
588 int length = urb->actual_length;
589
590 if (length < stv680->rawbufsize)
591 PDEBUG (2, "STV(i): Lost data in transfer: exp %li, got %i", stv680->rawbufsize, length);
592
593 /* ohoh... */
594 if (!stv680->streaming)
595 return;
596
597 if (!stv680->udev) {
598 PDEBUG (0, "STV(e): device vapourished in video_irq");
599 return;
600 }
601
602 /* 0 sized packets happen if we are to fast, but sometimes the camera
603 keeps sending them forever...
604 */
605 if (length && !urb->status) {
606 stv680->nullpackets = 0;
607 switch (stv680->scratch[stv680->scratch_next].state) {
608 case BUFFER_READY:
609 case BUFFER_BUSY:
610 stv680->dropped++;
611 break;
612
613 case BUFFER_UNUSED:
614 memcpy (stv680->scratch[stv680->scratch_next].data,
615 (unsigned char *) urb->transfer_buffer, length);
616 stv680->scratch[stv680->scratch_next].state = BUFFER_READY;
617 stv680->scratch[stv680->scratch_next].length = length;
618 if (waitqueue_active (&stv680->wq)) {
619 wake_up_interruptible (&stv680->wq);
620 }
621 stv680->scratch_overflow = 0;
622 stv680->scratch_next++;
623 if (stv680->scratch_next >= STV680_NUMSCRATCH)
624 stv680->scratch_next = 0;
625 break;
626 } /* switch */
627 } else {
628 stv680->nullpackets++;
629 if (stv680->nullpackets > STV680_MAX_NULLPACKETS) {
630 if (waitqueue_active (&stv680->wq)) {
631 wake_up_interruptible (&stv680->wq);
632 }
633 }
634 } /* if - else */
635
636 /* Resubmit urb for new data */
637 urb->status = 0;
638 urb->dev = stv680->udev;
639 if (usb_submit_urb (urb, GFP_ATOMIC))
640 PDEBUG (0, "STV(e): urb burned down in video irq");
641 return;
642} /* _video_irq */
643
644static int stv680_start_stream (struct usb_stv *stv680)
645{
646 struct urb *urb;
647 int err = 0, i;
648
649 stv680->streaming = 1;
650
651 /* Do some memory allocation */
652 for (i = 0; i < STV680_NUMFRAMES; i++) {
653 stv680->frame[i].data = stv680->fbuf + i * stv680->maxframesize;
654 stv680->frame[i].curpix = 0;
655 }
656 /* packet size = 4096 */
657 for (i = 0; i < STV680_NUMSBUF; i++) {
658 stv680->sbuf[i].data = kmalloc (stv680->rawbufsize, GFP_KERNEL);
659 if (stv680->sbuf[i].data == NULL) {
660 PDEBUG (0, "STV(e): Could not kmalloc raw data buffer %i", i);
661 return -1;
662 }
663 }
664
665 stv680->scratch_next = 0;
666 stv680->scratch_use = 0;
667 stv680->scratch_overflow = 0;
668 for (i = 0; i < STV680_NUMSCRATCH; i++) {
669 stv680->scratch[i].data = kmalloc (stv680->rawbufsize, GFP_KERNEL);
670 if (stv680->scratch[i].data == NULL) {
671 PDEBUG (0, "STV(e): Could not kmalloc raw scratch buffer %i", i);
672 return -1;
673 }
674 stv680->scratch[i].state = BUFFER_UNUSED;
675 }
676
677 for (i = 0; i < STV680_NUMSBUF; i++) {
678 urb = usb_alloc_urb (0, GFP_KERNEL);
679 if (!urb)
680 return -ENOMEM;
681
682 /* sbuf is urb->transfer_buffer, later gets memcpyed to scratch */
683 usb_fill_bulk_urb (urb, stv680->udev,
684 usb_rcvbulkpipe (stv680->udev, stv680->bulk_in_endpointAddr),
685 stv680->sbuf[i].data, stv680->rawbufsize,
686 stv680_video_irq, stv680);
687 stv680->urb[i] = urb;
688 err = usb_submit_urb (stv680->urb[i], GFP_KERNEL);
689 if (err)
690 PDEBUG (0, "STV(e): urb burned down in start stream");
691 } /* i STV680_NUMSBUF */
692
693 stv680->framecount = 0;
694 return 0;
695}
696
697static int stv680_stop_stream (struct usb_stv *stv680)
698{
699 int i;
700
701 if (!stv680->streaming || !stv680->udev)
702 return 1;
703
704 stv680->streaming = 0;
705
706 for (i = 0; i < STV680_NUMSBUF; i++)
707 if (stv680->urb[i]) {
708 usb_kill_urb (stv680->urb[i]);
709 usb_free_urb (stv680->urb[i]);
710 stv680->urb[i] = NULL;
711 kfree (stv680->sbuf[i].data);
712 }
713 for (i = 0; i < STV680_NUMSCRATCH; i++) {
714 kfree (stv680->scratch[i].data);
715 stv680->scratch[i].data = NULL;
716 }
717
718 return 0;
719}
720
721static int stv680_set_size (struct usb_stv *stv680, int width, int height)
722{
723 int wasstreaming = stv680->streaming;
724
725 /* Check to see if we need to change */
726 if ((stv680->vwidth == width) && (stv680->vheight == height))
727 return 0;
728
729 PDEBUG (1, "STV(i): size request for %i x %i", width, height);
730 /* Check for a valid mode */
731 if ((!width || !height) || ((width & 1) || (height & 1))) {
732 PDEBUG (1, "STV(e): set_size error: request: v.width = %i, v.height = %i actual: stv.width = %i, stv.height = %i", width, height, stv680->vwidth, stv680->vheight);
733 return 1;
734 }
735
736 if ((width < (stv680->maxwidth / 2)) || (height < (stv680->maxheight / 2))) {
737 width = stv680->maxwidth / 2;
738 height = stv680->maxheight / 2;
739 } else if ((width >= 158) && (width <= 166) && (stv680->QVGA == 1)) {
740 width = 160;
741 height = 120;
742 } else if ((width >= 172) && (width <= 180) && (stv680->CIF == 1)) {
743 width = 176;
744 height = 144;
745 } else if ((width >= 318) && (width <= 350) && (stv680->QVGA == 1)) {
746 width = 320;
747 height = 240;
748 } else if ((width >= 350) && (width <= 358) && (stv680->CIF == 1)) {
749 width = 352;
750 height = 288;
751 } else {
752 PDEBUG (1, "STV(e): request for non-supported size: request: v.width = %i, v.height = %i actual: stv.width = %i, stv.height = %i", width, height, stv680->vwidth, stv680->vheight);
753 return 1;
754 }
755
756 /* Stop a current stream and start it again at the new size */
757 if (wasstreaming)
758 stv680_stop_stream (stv680);
759 stv680->vwidth = width;
760 stv680->vheight = height;
761 PDEBUG (1, "STV(i): size set to %i x %i", stv680->vwidth, stv680->vheight);
762 if (wasstreaming)
763 stv680_start_stream (stv680);
764
765 return 0;
766}
767
768/**********************************************************************
769 * Video Decoding
770 **********************************************************************/
771
772/******* routines from the pencam program; hey, they work! ********/
773
774/*
775 * STV0680 Vision Camera Chipset Driver
776 * Copyright (C) 2000 Adam Harrison <adam@antispin.org>
777*/
778
779#define RED 0
780#define GREEN 1
781#define BLUE 2
782#define AD(x, y, w) (((y)*(w)+(x))*3)
783
784static void bayer_unshuffle (struct usb_stv *stv680, struct stv680_scratch *buffer)
785{
786 int x, y, i;
787 int w = stv680->cwidth;
788 int vw = stv680->cwidth, vh = stv680->cheight;
789 unsigned int p = 0;
790 int colour = 0, bayer = 0;
791 unsigned char *raw = buffer->data;
792 struct stv680_frame *frame = &stv680->frame[stv680->curframe];
793 unsigned char *output = frame->data;
794 unsigned char *temp = frame->data;
795 int offset = buffer->offset;
796
797 if (frame->curpix == 0) {
798 if (frame->grabstate == FRAME_READY) {
799 frame->grabstate = FRAME_GRABBING;
800 }
801 }
802 if (offset != frame->curpix) { /* Regard frame as lost :( */
803 frame->curpix = 0;
804 stv680->error++;
805 return;
806 }
807
808 if ((stv680->vwidth == 320) || (stv680->vwidth == 160)) {
809 vw = 320;
810 vh = 240;
811 }
812 if ((stv680->vwidth == 352) || (stv680->vwidth == 176)) {
813 vw = 352;
814 vh = 288;
815 }
816
817 memset (output, 0, 3 * vw * vh); /* clear output matrix. */
818
819 for (y = 0; y < vh; y++) {
820 for (x = 0; x < vw; x++) {
821 if (x & 1)
822 p = *(raw + y * w + (x >> 1));
823 else
824 p = *(raw + y * w + (x >> 1) + (w >> 1));
825
826 if (y & 1)
827 bayer = 2;
828 else
829 bayer = 0;
830 if (x & 1)
831 bayer++;
832
833 switch (bayer) {
834 case 0:
835 case 3:
836 colour = 1;
837 break;
838 case 1:
839 colour = 0;
840 break;
841 case 2:
842 colour = 2;
843 break;
844 }
845 i = (y * vw + x) * 3;
846 *(output + i + colour) = (unsigned char) p;
847 } /* for x */
848
849 } /* for y */
850
851 /****** gamma correction plus hardcoded white balance */
852 /* Thanks to Alexander Schwartx <alexander.schwartx@gmx.net> for this code.
853 Correction values red[], green[], blue[], are generated by
854 (pow(i/256.0, GAMMA)*255.0)*white balanceRGB where GAMMA=0.55, 1<i<255.
855 White balance (RGB)= 1.0, 1.17, 1.48. Values are calculated as double float and
856 converted to unsigned char. Values are in stv680.h */
857
858 for (y = 0; y < vh; y++) {
859 for (x = 0; x < vw; x++) {
860 i = (y * vw + x) * 3;
861 *(output + i) = red[*(output + i)];
862 *(output + i + 1) = green[*(output + i + 1)];
863 *(output + i + 2) = blue[*(output + i + 2)];
864 }
865 }
866
867 /****** bayer demosaic ******/
868 for (y = 1; y < (vh - 1); y++) {
869 for (x = 1; x < (vw - 1); x++) { /* work out pixel type */
870 if (y & 1)
871 bayer = 0;
872 else
873 bayer = 2;
874 if (!(x & 1))
875 bayer++;
876
877 switch (bayer) {
878 case 0: /* green. blue lr, red tb */
879 *(output + AD (x, y, vw) + BLUE) = ((int) *(output + AD (x - 1, y, vw) + BLUE) + (int) *(output + AD (x + 1, y, vw) + BLUE)) >> 1;
880 *(output + AD (x, y, vw) + RED) = ((int) *(output + AD (x, y - 1, vw) + RED) + (int) *(output + AD (x, y + 1, vw) + RED)) >> 1;
881 break;
882
883 case 1: /* blue. green lrtb, red diagonals */
884 *(output + AD (x, y, vw) + GREEN) = ((int) *(output + AD (x - 1, y, vw) + GREEN) + (int) *(output + AD (x + 1, y, vw) + GREEN) + (int) *(output + AD (x, y - 1, vw) + GREEN) + (int) *(output + AD (x, y + 1, vw) + GREEN)) >> 2;
885 *(output + AD (x, y, vw) + RED) = ((int) *(output + AD (x - 1, y - 1, vw) + RED) + (int) *(output + AD (x - 1, y + 1, vw) + RED) + (int) *(output + AD (x + 1, y - 1, vw) + RED) + (int) *(output + AD (x + 1, y + 1, vw) + RED)) >> 2;
886 break;
887
888 case 2: /* red. green lrtb, blue diagonals */
889 *(output + AD (x, y, vw) + GREEN) = ((int) *(output + AD (x - 1, y, vw) + GREEN) + (int) *(output + AD (x + 1, y, vw) + GREEN) + (int) *(output + AD (x, y - 1, vw) + GREEN) + (int) *(output + AD (x, y + 1, vw) + GREEN)) >> 2;
890 *(output + AD (x, y, vw) + BLUE) = ((int) *(output + AD (x - 1, y - 1, vw) + BLUE) + (int) *(output + AD (x + 1, y - 1, vw) + BLUE) + (int) *(output + AD (x - 1, y + 1, vw) + BLUE) + (int) *(output + AD (x + 1, y + 1, vw) + BLUE)) >> 2;
891 break;
892
893 case 3: /* green. red lr, blue tb */
894 *(output + AD (x, y, vw) + RED) = ((int) *(output + AD (x - 1, y, vw) + RED) + (int) *(output + AD (x + 1, y, vw) + RED)) >> 1;
895 *(output + AD (x, y, vw) + BLUE) = ((int) *(output + AD (x, y - 1, vw) + BLUE) + (int) *(output + AD (x, y + 1, vw) + BLUE)) >> 1;
896 break;
897 } /* switch */
898 } /* for x */
899 } /* for y - end demosaic */
900
901 /* fix top and bottom row, left and right side */
902 i = vw * 3;
903 memcpy (output, (output + i), i);
904 memcpy ((output + (vh * i)), (output + ((vh - 1) * i)), i);
905 for (y = 0; y < vh; y++) {
906 i = y * vw * 3;
907 memcpy ((output + i), (output + i + 3), 3);
908 memcpy ((output + i + (vw * 3)), (output + i + (vw - 1) * 3), 3);
909 }
910
911 /* process all raw data, then trim to size if necessary */
912 if ((stv680->vwidth == 160) || (stv680->vwidth == 176)) {
913 i = 0;
914 for (y = 0; y < vh; y++) {
915 if (!(y & 1)) {
916 for (x = 0; x < vw; x++) {
917 p = (y * vw + x) * 3;
918 if (!(x & 1)) {
919 *(output + i) = *(output + p);
920 *(output + i + 1) = *(output + p + 1);
921 *(output + i + 2) = *(output + p + 2);
922 i += 3;
923 }
924 } /* for x */
925 }
926 } /* for y */
927 }
928 /* reset to proper width */
929 if ((stv680->vwidth == 160)) {
930 vw = 160;
931 vh = 120;
932 }
933 if ((stv680->vwidth == 176)) {
934 vw = 176;
935 vh = 144;
936 }
937
938 /* output is RGB; some programs want BGR */
939 /* swapRGB_on=0 -> program decides; swapRGB_on=1, always swap */
940 /* swapRGB_on=-1, never swap */
941 if (((swapRGB == 1) && (swapRGB_on != -1)) || (swapRGB_on == 1)) {
942 for (y = 0; y < vh; y++) {
943 for (x = 0; x < vw; x++) {
944 i = (y * vw + x) * 3;
945 *(temp) = *(output + i);
946 *(output + i) = *(output + i + 2);
947 *(output + i + 2) = *(temp);
948 }
949 }
950 }
951 /* brightness */
952 if (stv680->chgbright == 1) {
953 if (stv680->brightness >= 32767) {
954 p = (stv680->brightness - 32767) / 256;
955 for (x = 0; x < (vw * vh * 3); x++) {
956 if ((*(output + x) + (unsigned char) p) > 255)
957 *(output + x) = 255;
958 else
959 *(output + x) += (unsigned char) p;
960 } /* for */
961 } else {
962 p = (32767 - stv680->brightness) / 256;
963 for (x = 0; x < (vw * vh * 3); x++) {
964 if ((unsigned char) p > *(output + x))
965 *(output + x) = 0;
966 else
967 *(output + x) -= (unsigned char) p;
968 } /* for */
969 } /* else */
970 }
971 /* if */
972 frame->curpix = 0;
973 frame->curlinepix = 0;
974 frame->grabstate = FRAME_DONE;
975 stv680->framecount++;
976 stv680->readcount++;
977 if (stv680->frame[(stv680->curframe + 1) & (STV680_NUMFRAMES - 1)].grabstate == FRAME_READY) {
978 stv680->curframe = (stv680->curframe + 1) & (STV680_NUMFRAMES - 1);
979 }
980
981} /* bayer_unshuffle */
982
983/******* end routines from the pencam program *********/
984
985static int stv680_newframe (struct usb_stv *stv680, int framenr)
986{
987 int errors = 0;
988
989 while (stv680->streaming && (stv680->frame[framenr].grabstate == FRAME_READY || stv680->frame[framenr].grabstate == FRAME_GRABBING)) {
990 if (!stv680->frame[framenr].curpix) {
991 errors++;
992 }
993 wait_event_interruptible (stv680->wq, (stv680->scratch[stv680->scratch_use].state == BUFFER_READY));
994
995 if (stv680->nullpackets > STV680_MAX_NULLPACKETS) {
996 stv680->nullpackets = 0;
997 PDEBUG (2, "STV(i): too many null length packets, restarting capture");
998 stv680_stop_stream (stv680);
999 stv680_start_stream (stv680);
1000 } else {
1001 if (stv680->scratch[stv680->scratch_use].state != BUFFER_READY) {
1002 stv680->frame[framenr].grabstate = FRAME_ERROR;
1003 PDEBUG (2, "STV(e): FRAME_ERROR in _newframe");
1004 return -EIO;
1005 }
1006 stv680->scratch[stv680->scratch_use].state = BUFFER_BUSY;
1007
1008 bayer_unshuffle (stv680, &stv680->scratch[stv680->scratch_use]);
1009
1010 stv680->scratch[stv680->scratch_use].state = BUFFER_UNUSED;
1011 stv680->scratch_use++;
1012 if (stv680->scratch_use >= STV680_NUMSCRATCH)
1013 stv680->scratch_use = 0;
1014 if (errors > STV680_MAX_ERRORS) {
1015 errors = 0;
1016 PDEBUG (2, "STV(i): too many errors, restarting capture");
1017 stv680_stop_stream (stv680);
1018 stv680_start_stream (stv680);
1019 }
1020 } /* else */
1021 } /* while */
1022 return 0;
1023}
1024
1025/*********************************************************************
1026 * Video4Linux
1027 *********************************************************************/
1028
1029static int stv_open (struct inode *inode, struct file *file)
1030{
1031 struct video_device *dev = video_devdata(file);
1032 struct usb_stv *stv680 = video_get_drvdata(dev);
1033 int err = 0;
1034
1035 /* we are called with the BKL held */
1036 stv680->user = 1;
1037 err = stv_init (stv680); /* main initialization routine for camera */
1038
1039 if (err >= 0) {
1040 stv680->fbuf = rvmalloc (stv680->maxframesize * STV680_NUMFRAMES);
1041 if (!stv680->fbuf) {
1042 PDEBUG (0, "STV(e): Could not rvmalloc frame bufer");
1043 err = -ENOMEM;
1044 }
1045 file->private_data = dev;
1046 }
1047 if (err)
1048 stv680->user = 0;
1049
1050 return err;
1051}
1052
1053static int stv_close (struct inode *inode, struct file *file)
1054{
1055 struct video_device *dev = file->private_data;
1056 struct usb_stv *stv680 = video_get_drvdata(dev);
1057 int i;
1058
1059 for (i = 0; i < STV680_NUMFRAMES; i++)
1060 stv680->frame[i].grabstate = FRAME_UNUSED;
1061 if (stv680->streaming)
1062 stv680_stop_stream (stv680);
1063
1064 if ((i = stv_stop_video (stv680)) < 0)
1065 PDEBUG (1, "STV(e): stop_video failed in stv_close");
1066
1067 rvfree (stv680->fbuf, stv680->maxframesize * STV680_NUMFRAMES);
1068 stv680->user = 0;
1069
1070 if (stv680->removed) {
1071 kfree (stv680);
1072 stv680 = NULL;
1073 PDEBUG (0, "STV(i): device unregistered");
1074 }
1075 file->private_data = NULL;
1076 return 0;
1077}
1078
1079static int stv680_do_ioctl (struct inode *inode, struct file *file,
1080 unsigned int cmd, void *arg)
1081{
1082 struct video_device *vdev = file->private_data;
1083 struct usb_stv *stv680 = video_get_drvdata(vdev);
1084
1085 if (!stv680->udev)
1086 return -EIO;
1087
1088 switch (cmd) {
1089 case VIDIOCGCAP:{
1090 struct video_capability *b = arg;
1091
1092 strcpy (b->name, stv680->camera_name);
1093 b->type = VID_TYPE_CAPTURE;
1094 b->channels = 1;
1095 b->audios = 0;
1096 b->maxwidth = stv680->maxwidth;
1097 b->maxheight = stv680->maxheight;
1098 b->minwidth = stv680->maxwidth / 2;
1099 b->minheight = stv680->maxheight / 2;
1100 return 0;
1101 }
1102 case VIDIOCGCHAN:{
1103 struct video_channel *v = arg;
1104
1105 if (v->channel != 0)
1106 return -EINVAL;
1107 v->flags = 0;
1108 v->tuners = 0;
1109 v->type = VIDEO_TYPE_CAMERA;
1110 strcpy (v->name, "STV Camera");
1111 return 0;
1112 }
1113 case VIDIOCSCHAN:{
1114 struct video_channel *v = arg;
1115 if (v->channel != 0)
1116 return -EINVAL;
1117 return 0;
1118 }
1119 case VIDIOCGPICT:{
1120 struct video_picture *p = arg;
1121
1122 stv680_get_pict (stv680, p);
1123 return 0;
1124 }
1125 case VIDIOCSPICT:{
1126 struct video_picture *p = arg;
1127
1128 if (stv680_set_pict (stv680, p))
1129 return -EINVAL;
1130 return 0;
1131 }
1132 case VIDIOCSWIN:{
1133 struct video_window *vw = arg;
1134
1135 if (vw->flags)
1136 return -EINVAL;
1137 if (vw->clipcount)
1138 return -EINVAL;
1139 if (vw->width != stv680->vwidth) {
1140 if (stv680_set_size (stv680, vw->width, vw->height)) {
1141 PDEBUG (2, "STV(e): failed (from user) set size in VIDIOCSWIN");
1142 return -EINVAL;
1143 }
1144 }
1145 return 0;
1146 }
1147 case VIDIOCGWIN:{
1148 struct video_window *vw = arg;
1149
1150 vw->x = 0; /* FIXME */
1151 vw->y = 0;
1152 vw->chromakey = 0;
1153 vw->flags = 0;
1154 vw->clipcount = 0;
1155 vw->width = stv680->vwidth;
1156 vw->height = stv680->vheight;
1157 return 0;
1158 }
1159 case VIDIOCGMBUF:{
1160 struct video_mbuf *vm = arg;
1161 int i;
1162
1163 memset (vm, 0, sizeof (*vm));
1164 vm->size = STV680_NUMFRAMES * stv680->maxframesize;
1165 vm->frames = STV680_NUMFRAMES;
1166 for (i = 0; i < STV680_NUMFRAMES; i++)
1167 vm->offsets[i] = stv680->maxframesize * i;
1168 return 0;
1169 }
1170 case VIDIOCMCAPTURE:{
1171 struct video_mmap *vm = arg;
1172
1173 if (vm->format != STV_VIDEO_PALETTE) {
1174 PDEBUG (2, "STV(i): VIDIOCMCAPTURE vm.format (%i) != VIDEO_PALETTE (%i)",
1175 vm->format, STV_VIDEO_PALETTE);
1176 if ((vm->format == 3) && (swapRGB_on == 0)) {
1177 PDEBUG (2, "STV(i): VIDIOCMCAPTURE swapRGB is (auto) ON");
1178 /* this may fix those apps (e.g., xawtv) that want BGR */
1179 swapRGB = 1;
1180 }
1181 return -EINVAL;
1182 }
1183 if (vm->frame >= STV680_NUMFRAMES) {
1184 PDEBUG (2, "STV(e): VIDIOCMCAPTURE vm.frame > NUMFRAMES");
1185 return -EINVAL;
1186 }
1187 if ((stv680->frame[vm->frame].grabstate == FRAME_ERROR)
1188 || (stv680->frame[vm->frame].grabstate == FRAME_GRABBING)) {
1189 PDEBUG (2, "STV(e): VIDIOCMCAPTURE grabstate (%i) error",
1190 stv680->frame[vm->frame].grabstate);
1191 return -EBUSY;
1192 }
1193 /* Is this according to the v4l spec??? */
1194 if (stv680->vwidth != vm->width) {
1195 if (stv680_set_size (stv680, vm->width, vm->height)) {
1196 PDEBUG (2, "STV(e): VIDIOCMCAPTURE set_size failed");
1197 return -EINVAL;
1198 }
1199 }
1200 stv680->frame[vm->frame].grabstate = FRAME_READY;
1201
1202 if (!stv680->streaming)
1203 stv680_start_stream (stv680);
1204
1205 return 0;
1206 }
1207 case VIDIOCSYNC:{
1208 int *frame = arg;
1209 int ret = 0;
1210
1211 if (*frame < 0 || *frame >= STV680_NUMFRAMES) {
1212 PDEBUG (2, "STV(e): Bad frame # in VIDIOCSYNC");
1213 return -EINVAL;
1214 }
1215 ret = stv680_newframe (stv680, *frame);
1216 stv680->frame[*frame].grabstate = FRAME_UNUSED;
1217 return ret;
1218 }
1219 case VIDIOCGFBUF:{
1220 struct video_buffer *vb = arg;
1221
1222 memset (vb, 0, sizeof (*vb));
1223 return 0;
1224 }
1225 case VIDIOCKEY:
1226 return 0;
1227 case VIDIOCCAPTURE:
1228 {
1229 PDEBUG (2, "STV(e): VIDIOCCAPTURE failed");
1230 return -EINVAL;
1231 }
1232 case VIDIOCSFBUF:
1233 case VIDIOCGTUNER:
1234 case VIDIOCSTUNER:
1235 case VIDIOCGFREQ:
1236 case VIDIOCSFREQ:
1237 case VIDIOCGAUDIO:
1238 case VIDIOCSAUDIO:
1239 return -EINVAL;
1240 default:
1241 return -ENOIOCTLCMD;
1242 } /* end switch */
1243
1244 return 0;
1245}
1246
1247static int stv680_ioctl(struct inode *inode, struct file *file,
1248 unsigned int cmd, unsigned long arg)
1249{
1250 return video_usercopy(inode, file, cmd, arg, stv680_do_ioctl);
1251}
1252
1253static int stv680_mmap (struct file *file, struct vm_area_struct *vma)
1254{
1255 struct video_device *dev = file->private_data;
1256 struct usb_stv *stv680 = video_get_drvdata(dev);
1257 unsigned long start = vma->vm_start;
1258 unsigned long size = vma->vm_end-vma->vm_start;
1259 unsigned long page, pos;
1260
1261 down (&stv680->lock);
1262
1263 if (stv680->udev == NULL) {
1264 up (&stv680->lock);
1265 return -EIO;
1266 }
1267 if (size > (((STV680_NUMFRAMES * stv680->maxframesize) + PAGE_SIZE - 1)
1268 & ~(PAGE_SIZE - 1))) {
1269 up (&stv680->lock);
1270 return -EINVAL;
1271 }
1272 pos = (unsigned long) stv680->fbuf;
1273 while (size > 0) {
1274 page = vmalloc_to_pfn((void *)pos);
1275 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
1276 up (&stv680->lock);
1277 return -EAGAIN;
1278 }
1279 start += PAGE_SIZE;
1280 pos += PAGE_SIZE;
1281 if (size > PAGE_SIZE)
1282 size -= PAGE_SIZE;
1283 else
1284 size = 0;
1285 }
1286 up (&stv680->lock);
1287
1288 return 0;
1289}
1290
1291static ssize_t stv680_read (struct file *file, char __user *buf,
1292 size_t count, loff_t *ppos)
1293{
1294 struct video_device *dev = file->private_data;
1295 unsigned long int realcount = count;
1296 int ret = 0;
1297 struct usb_stv *stv680 = video_get_drvdata(dev);
1298 unsigned long int i;
1299
1300 if (STV680_NUMFRAMES != 2) {
1301 PDEBUG (0, "STV(e): STV680_NUMFRAMES needs to be 2!");
1302 return -1;
1303 }
1304 if (stv680->udev == NULL)
1305 return -EIO;
1306 if (realcount > (stv680->vwidth * stv680->vheight * 3))
1307 realcount = stv680->vwidth * stv680->vheight * 3;
1308
1309 /* Shouldn't happen: */
1310 if (stv680->frame[0].grabstate == FRAME_GRABBING) {
1311 PDEBUG (2, "STV(e): FRAME_GRABBING in stv680_read");
1312 return -EBUSY;
1313 }
1314 stv680->frame[0].grabstate = FRAME_READY;
1315 stv680->frame[1].grabstate = FRAME_UNUSED;
1316 stv680->curframe = 0;
1317
1318 if (!stv680->streaming)
1319 stv680_start_stream (stv680);
1320
1321 if (!stv680->streaming) {
1322 ret = stv680_newframe (stv680, 0); /* ret should = 0 */
1323 }
1324
1325 ret = stv680_newframe (stv680, 0);
1326
1327 if (!ret) {
1328 if ((i = copy_to_user (buf, stv680->frame[0].data, realcount)) != 0) {
1329 PDEBUG (2, "STV(e): copy_to_user frame 0 failed, ret count = %li", i);
1330 return -EFAULT;
1331 }
1332 } else {
1333 realcount = ret;
1334 }
1335 stv680->frame[0].grabstate = FRAME_UNUSED;
1336 return realcount;
1337} /* stv680_read */
1338
1339static struct file_operations stv680_fops = {
1340 .owner = THIS_MODULE,
1341 .open = stv_open,
1342 .release = stv_close,
1343 .read = stv680_read,
1344 .mmap = stv680_mmap,
1345 .ioctl = stv680_ioctl,
1346 .llseek = no_llseek,
1347};
1348static struct video_device stv680_template = {
1349 .owner = THIS_MODULE,
1350 .name = "STV0680 USB camera",
1351 .type = VID_TYPE_CAPTURE,
1352 .hardware = VID_HARDWARE_SE401,
1353 .fops = &stv680_fops,
1354 .release = video_device_release,
1355 .minor = -1,
1356};
1357
1358static int stv680_probe (struct usb_interface *intf, const struct usb_device_id *id)
1359{
1360 struct usb_device *dev = interface_to_usbdev(intf);
1361 struct usb_host_interface *interface;
1362 struct usb_stv *stv680 = NULL;
1363 char *camera_name = NULL;
1364 int retval = 0;
1365
1366 /* We don't handle multi-config cameras */
1367 if (dev->descriptor.bNumConfigurations != 1) {
1368 PDEBUG (0, "STV(e): Number of Configurations != 1");
1369 return -ENODEV;
1370 }
1371
1372 interface = &intf->altsetting[0];
1373 /* Is it a STV680? */
1374 if ((le16_to_cpu(dev->descriptor.idVendor) == USB_PENCAM_VENDOR_ID) &&
1375 (le16_to_cpu(dev->descriptor.idProduct) == USB_PENCAM_PRODUCT_ID)) {
1376 camera_name = "STV0680";
1377 PDEBUG (0, "STV(i): STV0680 camera found.");
1378 } else {
1379 PDEBUG (0, "STV(e): Vendor/Product ID do not match STV0680 values.");
1380 PDEBUG (0, "STV(e): Check that the STV0680 camera is connected to the computer.");
1381 retval = -ENODEV;
1382 goto error;
1383 }
1384 /* We found one */
1385 if ((stv680 = kmalloc (sizeof (*stv680), GFP_KERNEL)) == NULL) {
1386 PDEBUG (0, "STV(e): couldn't kmalloc stv680 struct.");
1387 retval = -ENOMEM;
1388 goto error;
1389 }
1390
1391 memset (stv680, 0, sizeof (*stv680));
1392
1393 stv680->udev = dev;
1394 stv680->camera_name = camera_name;
1395
1396 stv680->vdev = video_device_alloc();
1397 if (!stv680->vdev) {
1398 retval = -ENOMEM;
1399 goto error;
1400 }
1401 memcpy(stv680->vdev, &stv680_template, sizeof(stv680_template));
1402 stv680->vdev->dev = &intf->dev;
1403 video_set_drvdata(stv680->vdev, stv680);
1404
1405 memcpy (stv680->vdev->name, stv680->camera_name, strlen (stv680->camera_name));
1406 init_waitqueue_head (&stv680->wq);
1407 init_MUTEX (&stv680->lock);
1408 wmb ();
1409
1410 if (video_register_device (stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
1411 PDEBUG (0, "STV(e): video_register_device failed");
1412 retval = -EIO;
1413 goto error_vdev;
1414 }
1415 PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev->minor);
1416
1417 usb_set_intfdata (intf, stv680);
1418 stv680_create_sysfs_files(stv680->vdev);
1419 return 0;
1420
1421error_vdev:
1422 video_device_release(stv680->vdev);
1423error:
1424 kfree(stv680);
1425 return retval;
1426}
1427
1428static inline void usb_stv680_remove_disconnected (struct usb_stv *stv680)
1429{
1430 int i;
1431
1432 stv680->udev = NULL;
1433 stv680->frame[0].grabstate = FRAME_ERROR;
1434 stv680->frame[1].grabstate = FRAME_ERROR;
1435 stv680->streaming = 0;
1436
1437 wake_up_interruptible (&stv680->wq);
1438
1439 for (i = 0; i < STV680_NUMSBUF; i++)
1440 if (stv680->urb[i]) {
1441 usb_kill_urb (stv680->urb[i]);
1442 usb_free_urb (stv680->urb[i]);
1443 stv680->urb[i] = NULL;
1444 kfree (stv680->sbuf[i].data);
1445 }
1446 for (i = 0; i < STV680_NUMSCRATCH; i++)
1447 kfree (stv680->scratch[i].data);
1448 PDEBUG (0, "STV(i): %s disconnected", stv680->camera_name);
1449
1450 /* Free the memory */
1451 kfree (stv680);
1452}
1453
1454static void stv680_disconnect (struct usb_interface *intf)
1455{
1456 struct usb_stv *stv680 = usb_get_intfdata (intf);
1457
1458 usb_set_intfdata (intf, NULL);
1459
1460 if (stv680) {
1461 /* We don't want people trying to open up the device */
1462 if (stv680->vdev) {
1463 stv680_remove_sysfs_files(stv680->vdev);
1464 video_unregister_device(stv680->vdev);
1465 stv680->vdev = NULL;
1466 }
1467 if (!stv680->user) {
1468 usb_stv680_remove_disconnected (stv680);
1469 } else {
1470 stv680->removed = 1;
1471 }
1472 }
1473}
1474
1475static struct usb_driver stv680_driver = {
1476 .owner = THIS_MODULE,
1477 .name = "stv680",
1478 .probe = stv680_probe,
1479 .disconnect = stv680_disconnect,
1480 .id_table = device_table
1481};
1482
1483/********************************************************************
1484 * Module routines
1485 ********************************************************************/
1486
1487static int __init usb_stv680_init (void)
1488{
1489 if (usb_register (&stv680_driver) < 0) {
1490 PDEBUG (0, "STV(e): Could not setup STV0680 driver");
1491 return -1;
1492 }
1493 PDEBUG (0, "STV(i): usb camera driver version %s registering", DRIVER_VERSION);
1494
1495 info(DRIVER_DESC " " DRIVER_VERSION);
1496 return 0;
1497}
1498
1499static void __exit usb_stv680_exit (void)
1500{
1501 usb_deregister (&stv680_driver);
1502 PDEBUG (0, "STV(i): driver deregistered");
1503}
1504
1505module_init (usb_stv680_init);
1506module_exit (usb_stv680_exit);
diff --git a/drivers/usb/media/stv680.h b/drivers/usb/media/stv680.h
new file mode 100644
index 000000000000..7e0e314dcf12
--- /dev/null
+++ b/drivers/usb/media/stv680.h
@@ -0,0 +1,222 @@
1/****************************************************************************
2 *
3 * Filename: stv680.h
4 *
5 * Description:
6 * This is a USB driver for STV0680 based usb video cameras.
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/* size of usb transfers */
25#define STV680_PACKETSIZE 4096
26
27/* number of queued bulk transfers to use, may have problems if > 1 */
28#define STV680_NUMSBUF 1
29
30/* number of frames supported by the v4l part */
31#define STV680_NUMFRAMES 2
32
33/* scratch buffers for passing data to the decoders: 2 or 4 are good */
34#define STV680_NUMSCRATCH 2
35
36/* number of nul sized packets to receive before kicking the camera */
37#define STV680_MAX_NULLPACKETS 200
38
39/* number of decoding errors before kicking the camera */
40#define STV680_MAX_ERRORS 100
41
42#define USB_PENCAM_VENDOR_ID 0x0553
43#define USB_PENCAM_PRODUCT_ID 0x0202
44#define PENCAM_TIMEOUT 1000
45/* fmt 4 */
46#define STV_VIDEO_PALETTE VIDEO_PALETTE_RGB24
47
48static struct usb_device_id device_table[] = {
49 {USB_DEVICE (USB_PENCAM_VENDOR_ID, USB_PENCAM_PRODUCT_ID)},
50 {}
51};
52MODULE_DEVICE_TABLE (usb, device_table);
53
54struct stv680_sbuf {
55 unsigned char *data;
56};
57
58enum {
59 FRAME_UNUSED, /* Unused (no MCAPTURE) */
60 FRAME_READY, /* Ready to start grabbing */
61 FRAME_GRABBING, /* In the process of being grabbed into */
62 FRAME_DONE, /* Finished grabbing, but not been synced yet */
63 FRAME_ERROR, /* Something bad happened while processing */
64};
65
66enum {
67 BUFFER_UNUSED,
68 BUFFER_READY,
69 BUFFER_BUSY,
70 BUFFER_DONE,
71};
72
73/* raw camera data <- sbuf (urb transfer buf) */
74struct stv680_scratch {
75 unsigned char *data;
76 volatile int state;
77 int offset;
78 int length;
79};
80
81/* processed data for display ends up here, after bayer */
82struct stv680_frame {
83 unsigned char *data; /* Frame buffer */
84 volatile int grabstate; /* State of grabbing */
85 unsigned char *curline;
86 int curlinepix;
87 int curpix;
88};
89
90/* this is almost the video structure uvd_t, with extra parameters for stv */
91struct usb_stv {
92 struct video_device *vdev;
93
94 struct usb_device *udev;
95
96 unsigned char bulk_in_endpointAddr; /* __u8 the address of the bulk in endpoint */
97 char *camera_name;
98
99 unsigned int VideoMode; /* 0x0100 = VGA, 0x0000 = CIF, 0x0300 = QVGA */
100 int SupportedModes;
101 int CIF;
102 int VGA;
103 int QVGA;
104 int cwidth; /* camera width */
105 int cheight; /* camera height */
106 int maxwidth; /* max video width */
107 int maxheight; /* max video height */
108 int vwidth; /* current width for video window */
109 int vheight; /* current height for video window */
110 unsigned long int rawbufsize;
111 unsigned long int maxframesize; /* rawbufsize * 3 for RGB */
112
113 int origGain;
114 int origMode; /* original camera mode */
115
116 struct semaphore lock; /* to lock the structure */
117 int user; /* user count for exclusive use */
118 int removed; /* device disconnected */
119 int streaming; /* Are we streaming video? */
120 char *fbuf; /* Videodev buffer area */
121 struct urb *urb[STV680_NUMSBUF]; /* # of queued bulk transfers */
122 int curframe; /* Current receiving frame */
123 struct stv680_frame frame[STV680_NUMFRAMES]; /* # frames supported by v4l part */
124 int readcount;
125 int framecount;
126 int error;
127 int dropped;
128 int scratch_next;
129 int scratch_use;
130 int scratch_overflow;
131 struct stv680_scratch scratch[STV680_NUMSCRATCH]; /* for decoders */
132 struct stv680_sbuf sbuf[STV680_NUMSBUF];
133
134 unsigned int brightness;
135 unsigned int chgbright;
136 unsigned int whiteness;
137 unsigned int colour;
138 unsigned int contrast;
139 unsigned int hue;
140 unsigned int palette;
141 unsigned int depth; /* rgb24 in bits */
142
143 wait_queue_head_t wq; /* Processes waiting */
144
145 int nullpackets;
146};
147
148
149static unsigned char red[256] = {
150 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
151 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42,
152 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69,
153 71, 71, 73, 75, 77, 78, 80, 81, 82, 84, 85, 87,
154 88, 89, 90, 91, 93, 94, 95, 97, 98, 98, 99, 101,
155 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
156 114, 115, 116, 116, 117, 118, 119, 120, 121, 122, 123, 124,
157 125, 125, 126, 127, 128, 129, 129, 130, 131, 132, 133, 134,
158 134, 135, 135, 136, 137, 138, 139, 140, 140, 141, 142, 143,
159 143, 143, 144, 145, 146, 147, 147, 148, 149, 150, 150, 151,
160 152, 152, 152, 153, 154, 154, 155, 156, 157, 157, 158, 159,
161 159, 160, 161, 161, 161, 162, 163, 163, 164, 165, 165, 166,
162 167, 167, 168, 168, 169, 170, 170, 170, 171, 171, 172, 173,
163 173, 174, 174, 175, 176, 176, 177, 178, 178, 179, 179, 179,
164 180, 180, 181, 181, 182, 183, 183, 184, 184, 185, 185, 186,
165 187, 187, 188, 188, 188, 188, 189, 190, 190, 191, 191, 192,
166 192, 193, 193, 194, 195, 195, 196, 196, 197, 197, 197, 197,
167 198, 198, 199, 199, 200, 201, 201, 202, 202, 203, 203, 204,
168 204, 205, 205, 206, 206, 206, 206, 207, 207, 208, 208, 209,
169 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215,
170 215, 215, 215, 216, 216, 217, 217, 218, 218, 218, 219, 219,
171 220, 220, 221, 221
172};
173
174static unsigned char green[256] = {
175 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
176 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47,
177 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77,
178 79, 80, 82, 84, 86, 87, 89, 91, 92, 94, 95, 97,
179 98, 100, 101, 102, 104, 105, 106, 108, 109, 110, 111, 113,
180 114, 115, 116, 117, 118, 120, 121, 122, 123, 124, 125, 126,
181 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
182 139, 140, 141, 142, 143, 144, 144, 145, 146, 147, 148, 149,
183 150, 151, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159,
184 160, 160, 161, 162, 163, 164, 164, 165, 166, 167, 167, 168,
185 169, 170, 170, 171, 172, 172, 173, 174, 175, 175, 176, 177,
186 177, 178, 179, 179, 180, 181, 182, 182, 183, 184, 184, 185,
187 186, 186, 187, 187, 188, 189, 189, 190, 191, 191, 192, 193,
188 193, 194, 194, 195, 196, 196, 197, 198, 198, 199, 199, 200,
189 201, 201, 202, 202, 203, 204, 204, 205, 205, 206, 206, 207,
190 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214,
191 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 220,
192 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227,
193 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
194 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239,
195 239, 240, 240, 241, 241, 242, 242, 243, 243, 243, 244, 244,
196 245, 245, 246, 246
197};
198
199static unsigned char blue[256] = {
200 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
201 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51,
202 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84,
203 86, 88, 90, 92, 94, 95, 97, 100, 101, 103, 104, 106,
204 107, 110, 111, 112, 114, 115, 116, 118, 119, 121, 122, 124,
205 125, 126, 127, 128, 129, 132, 133, 134, 135, 136, 137, 138,
206 139, 140, 141, 143, 144, 145, 146, 147, 148, 149, 150, 151,
207 152, 154, 155, 156, 157, 158, 158, 159, 160, 161, 162, 163,
208 165, 166, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174,
209 176, 176, 177, 178, 179, 180, 180, 181, 182, 183, 183, 184,
210 185, 187, 187, 188, 189, 189, 190, 191, 192, 192, 193, 194,
211 194, 195, 196, 196, 198, 199, 200, 200, 201, 202, 202, 203,
212 204, 204, 205, 205, 206, 207, 207, 209, 210, 210, 211, 212,
213 212, 213, 213, 214, 215, 215, 216, 217, 217, 218, 218, 220,
214 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227,
215 228, 228, 229, 229, 231, 231, 232, 233, 233, 234, 234, 235,
216 235, 236, 236, 237, 238, 238, 239, 239, 240, 240, 242, 242,
217 243, 243, 244, 244, 245, 246, 246, 247, 247, 248, 248, 249,
218 249, 250, 250, 251, 251, 253, 253, 254, 254, 255, 255, 255,
219 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
220 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
221 255, 255, 255, 255
222};
diff --git a/drivers/usb/media/ultracam.c b/drivers/usb/media/ultracam.c
new file mode 100644
index 000000000000..75ff755224df
--- /dev/null
+++ b/drivers/usb/media/ultracam.c
@@ -0,0 +1,679 @@
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/sched.h>
10#include <linux/module.h>
11#include <linux/init.h>
12
13#include "usbvideo.h"
14
15#define ULTRACAM_VENDOR_ID 0x0461
16#define ULTRACAM_PRODUCT_ID 0x0813
17
18#define MAX_CAMERAS 4 /* How many devices we allow to connect */
19
20/*
21 * This structure lives in uvd_t->user field.
22 */
23typedef struct {
24 int initialized; /* Had we already sent init sequence? */
25 int camera_model; /* What type of IBM camera we got? */
26 int has_hdr;
27} ultracam_t;
28#define ULTRACAM_T(uvd) ((ultracam_t *)((uvd)->user_data))
29
30static struct usbvideo *cams = NULL;
31
32static int debug = 0;
33
34static int flags = 0; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */
35
36static const int min_canvasWidth = 8;
37static const int min_canvasHeight = 4;
38
39#define FRAMERATE_MIN 0
40#define FRAMERATE_MAX 6
41static int framerate = -1;
42
43/*
44 * Here we define several initialization variables. They may
45 * be used to automatically set color, hue, brightness and
46 * contrast to desired values. This is particularly useful in
47 * case of webcams (which have no controls and no on-screen
48 * output) and also when a client V4L software is used that
49 * does not have some of those controls. In any case it's
50 * good to have startup values as options.
51 *
52 * These values are all in [0..255] range. This simplifies
53 * operation. Note that actual values of V4L variables may
54 * be scaled up (as much as << 8). User can see that only
55 * on overlay output, however, or through a V4L client.
56 */
57static int init_brightness = 128;
58static int init_contrast = 192;
59static int init_color = 128;
60static int init_hue = 128;
61static int hue_correction = 128;
62
63module_param(debug, int, S_IRUGO | S_IWUSR);
64MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
65module_param(flags, int, 0);
66MODULE_PARM_DESC(flags,
67 "Bitfield: 0=VIDIOCSYNC, "
68 "1=B/W, "
69 "2=show hints, "
70 "3=show stats, "
71 "4=test pattern, "
72 "5=separate frames, "
73 "6=clean frames");
74module_param(framerate, int, 0);
75MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)");
76
77module_param(init_brightness, int, 0);
78MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)");
79module_param(init_contrast, int, 0);
80MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)");
81module_param(init_color, int, 0);
82MODULE_PARM_DESC(init_color, "Color preconfiguration: 0-255 (default=128)");
83module_param(init_hue, int, 0);
84MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)");
85module_param(hue_correction, int, 0);
86MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)");
87
88/*
89 * ultracam_ProcessIsocData()
90 *
91 * Generic routine to parse the ring queue data. It employs either
92 * ultracam_find_header() or ultracam_parse_lines() to do most
93 * of work.
94 *
95 * 02-Nov-2000 First (mostly dummy) version.
96 * 06-Nov-2000 Rewrote to dump all data into frame.
97 */
98static void ultracam_ProcessIsocData(struct uvd *uvd, struct usbvideo_frame *frame)
99{
100 int n;
101
102 assert(uvd != NULL);
103 assert(frame != NULL);
104
105 /* Try to move data from queue into frame buffer */
106 n = RingQueue_GetLength(&uvd->dp);
107 if (n > 0) {
108 int m;
109 /* See how much spare we have left */
110 m = uvd->max_frame_size - frame->seqRead_Length;
111 if (n > m)
112 n = m;
113 /* Now move that much data into frame buffer */
114 RingQueue_Dequeue(
115 &uvd->dp,
116 frame->data + frame->seqRead_Length,
117 m);
118 frame->seqRead_Length += m;
119 }
120 /* See if we filled the frame */
121 if (frame->seqRead_Length >= uvd->max_frame_size) {
122 frame->frameState = FrameState_Done;
123 uvd->curframe = -1;
124 uvd->stats.frame_num++;
125 }
126}
127
128/*
129 * ultracam_veio()
130 *
131 * History:
132 * 1/27/00 Added check for dev == NULL; this happens if camera is unplugged.
133 */
134static int ultracam_veio(
135 struct uvd *uvd,
136 unsigned char req,
137 unsigned short value,
138 unsigned short index,
139 int is_out)
140{
141 static const char proc[] = "ultracam_veio";
142 unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */;
143 int i;
144
145 if (!CAMERA_IS_OPERATIONAL(uvd))
146 return 0;
147
148 if (!is_out) {
149 i = usb_control_msg(
150 uvd->dev,
151 usb_rcvctrlpipe(uvd->dev, 0),
152 req,
153 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
154 value,
155 index,
156 cp,
157 sizeof(cp),
158 1000);
159#if 1
160 info("USB => %02x%02x%02x%02x%02x%02x%02x%02x "
161 "(req=$%02x val=$%04x ind=$%04x)",
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 */
188static int ultracam_calculate_fps(struct uvd *uvd)
189{
190 return 3 + framerate*4 + framerate/2;
191}
192
193/*
194 * ultracam_adjust_contrast()
195 */
196static 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 */
205static void ultracam_set_brightness(struct uvd *uvd)
206{
207}
208
209static 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 */
219static 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 */
232static 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 */
243static void ultracam_reinit_iso(struct uvd *uvd, int do_stop)
244{
245}
246
247static void ultracam_video_start(struct uvd *uvd)
248{
249 ultracam_reinit_iso(uvd, 0);
250}
251
252static int ultracam_resetPipe(struct uvd *uvd)
253{
254 usb_clear_halt(uvd->dev, uvd->video_endp);
255 return 0;
256}
257
258static 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 */
274static 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
462static 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 */
512static 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 info("ultracam_probe(%p)", intf);
522
523 /* We don't handle multi-config cameras */
524 if (dev->descriptor.bNumConfigurations != 1)
525 return -ENODEV;
526
527 info("IBM Ultra camera found (rev. 0x%04x)",
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 info("Number of alternate settings=%d.", nas);
534 if (nas < 8) {
535 err("Too few alternate settings for this camera!");
536 return -ENODEV;
537 }
538 /* Validate all alternate settings */
539 for (ix=0; ix < nas; ix++) {
540 const struct usb_host_interface *interface;
541 const struct usb_endpoint_descriptor *endpoint;
542
543 interface = &intf->altsetting[ix];
544 i = interface->desc.bAlternateSetting;
545 if (interface->desc.bNumEndpoints != 1) {
546 err("Interface %d. has %u. endpoints!",
547 interface->desc.bInterfaceNumber,
548 (unsigned)(interface->desc.bNumEndpoints));
549 return -ENODEV;
550 }
551 endpoint = &interface->endpoint[0].desc;
552 if (video_ep == 0)
553 video_ep = endpoint->bEndpointAddress;
554 else if (video_ep != endpoint->bEndpointAddress) {
555 err("Alternate settings have different endpoint addresses!");
556 return -ENODEV;
557 }
558 if ((endpoint->bmAttributes & 0x03) != 0x01) {
559 err("Interface %d. has non-ISO endpoint!",
560 interface->desc.bInterfaceNumber);
561 return -ENODEV;
562 }
563 if ((endpoint->bEndpointAddress & 0x80) == 0) {
564 err("Interface %d. has ISO OUT endpoint!",
565 interface->desc.bInterfaceNumber);
566 return -ENODEV;
567 }
568 if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
569 if (inactInterface < 0)
570 inactInterface = i;
571 else {
572 err("More than one inactive alt. setting!");
573 return -ENODEV;
574 }
575 } else {
576 if (actInterface < 0) {
577 actInterface = i;
578 maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
579 if (debug > 0)
580 info("Active setting=%d. maxPS=%d.", i, maxPS);
581 } else {
582 /* Got another active alt. setting */
583 if (maxPS < le16_to_cpu(endpoint->wMaxPacketSize)) {
584 /* This one is better! */
585 actInterface = i;
586 maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
587 if (debug > 0) {
588 info("Even better ctive setting=%d. maxPS=%d.",
589 i, maxPS);
590 }
591 }
592 }
593 }
594 }
595 if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) {
596 err("Failed to recognize the camera!");
597 return -ENODEV;
598 }
599
600 uvd = usbvideo_AllocateDevice(cams);
601 if (uvd != NULL) {
602 /* Here uvd is a fully allocated uvd object */
603 uvd->flags = flags;
604 uvd->debug = debug;
605 uvd->dev = dev;
606 uvd->iface = intf->altsetting->desc.bInterfaceNumber;
607 uvd->ifaceAltInactive = inactInterface;
608 uvd->ifaceAltActive = actInterface;
609 uvd->video_endp = video_ep;
610 uvd->iso_packet_len = maxPS;
611 uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
612 uvd->defaultPalette = VIDEO_PALETTE_RGB24;
613 uvd->canvas = VIDEOSIZE(640, 480); /* FIXME */
614 uvd->videosize = uvd->canvas; /* ultracam_size_to_videosize(size);*/
615
616 /* Initialize ibmcam-specific data */
617 assert(ULTRACAM_T(uvd) != NULL);
618 ULTRACAM_T(uvd)->camera_model = 0; /* Not used yet */
619 ULTRACAM_T(uvd)->initialized = 0;
620
621 ultracam_configure_video(uvd);
622
623 i = usbvideo_RegisterVideoDevice(uvd);
624 if (i != 0) {
625 err("usbvideo_RegisterVideoDevice() failed.");
626 uvd = NULL;
627 }
628 }
629
630 if (uvd) {
631 usb_set_intfdata (intf, uvd);
632 return 0;
633 }
634 return -EIO;
635}
636
637
638static struct usb_device_id id_table[] = {
639 { USB_DEVICE(ULTRACAM_VENDOR_ID, ULTRACAM_PRODUCT_ID) },
640 { } /* Terminating entry */
641};
642
643/*
644 * ultracam_init()
645 *
646 * This code is run to initialize the driver.
647 */
648static int __init ultracam_init(void)
649{
650 struct usbvideo_cb cbTbl;
651 memset(&cbTbl, 0, sizeof(cbTbl));
652 cbTbl.probe = ultracam_probe;
653 cbTbl.setupOnOpen = ultracam_setup_on_open;
654 cbTbl.videoStart = ultracam_video_start;
655 cbTbl.videoStop = ultracam_video_stop;
656 cbTbl.processData = ultracam_ProcessIsocData;
657 cbTbl.postProcess = usbvideo_DeinterlaceFrame;
658 cbTbl.adjustPicture = ultracam_adjust_picture;
659 cbTbl.getFPS = ultracam_calculate_fps;
660 return usbvideo_register(
661 &cams,
662 MAX_CAMERAS,
663 sizeof(ultracam_t),
664 "ultracam",
665 &cbTbl,
666 THIS_MODULE,
667 id_table);
668}
669
670static void __exit ultracam_cleanup(void)
671{
672 usbvideo_Deregister(&cams);
673}
674
675MODULE_DEVICE_TABLE(usb, id_table);
676MODULE_LICENSE("GPL");
677
678module_init(ultracam_init);
679module_exit(ultracam_cleanup);
diff --git a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c
new file mode 100644
index 000000000000..298484aa27d2
--- /dev/null
+++ b/drivers/usb/media/usbvideo.c
@@ -0,0 +1,2192 @@
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/smp_lock.h>
24#include <linux/vmalloc.h>
25#include <linux/init.h>
26#include <linux/spinlock.h>
27
28#include <asm/io.h>
29
30#include "usbvideo.h"
31
32#if defined(MAP_NR)
33#define virt_to_page(v) MAP_NR(v) /* Kernels 2.2.x */
34#endif
35
36static int video_nr = -1;
37module_param(video_nr, int, 0);
38
39/*
40 * Local prototypes.
41 */
42static void usbvideo_Disconnect(struct usb_interface *intf);
43static void usbvideo_CameraRelease(struct uvd *uvd);
44
45static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file,
46 unsigned int cmd, unsigned long arg);
47static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma);
48static int usbvideo_v4l_open(struct inode *inode, struct file *file);
49static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
50 size_t count, loff_t *ppos);
51static int usbvideo_v4l_close(struct inode *inode, struct file *file);
52
53static int usbvideo_StartDataPump(struct uvd *uvd);
54static void usbvideo_StopDataPump(struct uvd *uvd);
55static int usbvideo_GetFrame(struct uvd *uvd, int frameNum);
56static int usbvideo_NewFrame(struct uvd *uvd, int framenum);
57static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd,
58 struct usbvideo_frame *frame);
59
60/*******************************/
61/* Memory management functions */
62/*******************************/
63static void *usbvideo_rvmalloc(unsigned long size)
64{
65 void *mem;
66 unsigned long adr;
67
68 size = PAGE_ALIGN(size);
69 mem = vmalloc_32(size);
70 if (!mem)
71 return NULL;
72
73 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
74 adr = (unsigned long) mem;
75 while (size > 0) {
76 SetPageReserved(vmalloc_to_page((void *)adr));
77 adr += PAGE_SIZE;
78 size -= PAGE_SIZE;
79 }
80
81 return mem;
82}
83
84static void usbvideo_rvfree(void *mem, unsigned long size)
85{
86 unsigned long adr;
87
88 if (!mem)
89 return;
90
91 adr = (unsigned long) mem;
92 while ((long) size > 0) {
93 ClearPageReserved(vmalloc_to_page((void *)adr));
94 adr += PAGE_SIZE;
95 size -= PAGE_SIZE;
96 }
97 vfree(mem);
98}
99
100static void RingQueue_Initialize(struct RingQueue *rq)
101{
102 assert(rq != NULL);
103 init_waitqueue_head(&rq->wqh);
104}
105
106static void RingQueue_Allocate(struct RingQueue *rq, int rqLen)
107{
108 /* Make sure the requested size is a power of 2 and
109 round up if necessary. This allows index wrapping
110 using masks rather than modulo */
111
112 int i = 1;
113 assert(rq != NULL);
114 assert(rqLen > 0);
115
116 while(rqLen >> i)
117 i++;
118 if(rqLen != 1 << (i-1))
119 rqLen = 1 << i;
120
121 rq->length = rqLen;
122 rq->ri = rq->wi = 0;
123 rq->queue = usbvideo_rvmalloc(rq->length);
124 assert(rq->queue != NULL);
125}
126
127static int RingQueue_IsAllocated(const struct RingQueue *rq)
128{
129 if (rq == NULL)
130 return 0;
131 return (rq->queue != NULL) && (rq->length > 0);
132}
133
134static void RingQueue_Free(struct RingQueue *rq)
135{
136 assert(rq != NULL);
137 if (RingQueue_IsAllocated(rq)) {
138 usbvideo_rvfree(rq->queue, rq->length);
139 rq->queue = NULL;
140 rq->length = 0;
141 }
142}
143
144int RingQueue_Dequeue(struct RingQueue *rq, unsigned char *dst, int len)
145{
146 int rql, toread;
147
148 assert(rq != NULL);
149 assert(dst != NULL);
150
151 rql = RingQueue_GetLength(rq);
152 if(!rql)
153 return 0;
154
155 /* Clip requested length to available data */
156 if(len > rql)
157 len = rql;
158
159 toread = len;
160 if(rq->ri > rq->wi) {
161 /* Read data from tail */
162 int read = (toread < (rq->length - rq->ri)) ? toread : rq->length - rq->ri;
163 memcpy(dst, rq->queue + rq->ri, read);
164 toread -= read;
165 dst += read;
166 rq->ri = (rq->ri + read) & (rq->length-1);
167 }
168 if(toread) {
169 /* Read data from head */
170 memcpy(dst, rq->queue + rq->ri, toread);
171 rq->ri = (rq->ri + toread) & (rq->length-1);
172 }
173 return len;
174}
175
176EXPORT_SYMBOL(RingQueue_Dequeue);
177
178int RingQueue_Enqueue(struct RingQueue *rq, const unsigned char *cdata, int n)
179{
180 int enqueued = 0;
181
182 assert(rq != NULL);
183 assert(cdata != NULL);
184 assert(rq->length > 0);
185 while (n > 0) {
186 int m, q_avail;
187
188 /* Calculate the largest chunk that fits the tail of the ring */
189 q_avail = rq->length - rq->wi;
190 if (q_avail <= 0) {
191 rq->wi = 0;
192 q_avail = rq->length;
193 }
194 m = n;
195 assert(q_avail > 0);
196 if (m > q_avail)
197 m = q_avail;
198
199 memcpy(rq->queue + rq->wi, cdata, m);
200 RING_QUEUE_ADVANCE_INDEX(rq, wi, m);
201 cdata += m;
202 enqueued += m;
203 n -= m;
204 }
205 return enqueued;
206}
207
208EXPORT_SYMBOL(RingQueue_Enqueue);
209
210static void RingQueue_InterruptibleSleepOn(struct RingQueue *rq)
211{
212 assert(rq != NULL);
213 interruptible_sleep_on(&rq->wqh);
214}
215
216void RingQueue_WakeUpInterruptible(struct RingQueue *rq)
217{
218 assert(rq != NULL);
219 if (waitqueue_active(&rq->wqh))
220 wake_up_interruptible(&rq->wqh);
221}
222
223EXPORT_SYMBOL(RingQueue_WakeUpInterruptible);
224
225void RingQueue_Flush(struct RingQueue *rq)
226{
227 assert(rq != NULL);
228 rq->ri = 0;
229 rq->wi = 0;
230}
231
232EXPORT_SYMBOL(RingQueue_Flush);
233
234
235/*
236 * usbvideo_VideosizeToString()
237 *
238 * This procedure converts given videosize value to readable string.
239 *
240 * History:
241 * 07-Aug-2000 Created.
242 * 19-Oct-2000 Reworked for usbvideo module.
243 */
244static void usbvideo_VideosizeToString(char *buf, int bufLen, videosize_t vs)
245{
246 char tmp[40];
247 int n;
248
249 n = 1 + sprintf(tmp, "%ldx%ld", VIDEOSIZE_X(vs), VIDEOSIZE_Y(vs));
250 assert(n < sizeof(tmp));
251 if ((buf == NULL) || (bufLen < n))
252 err("usbvideo_VideosizeToString: buffer is too small.");
253 else
254 memmove(buf, tmp, n);
255}
256
257/*
258 * usbvideo_OverlayChar()
259 *
260 * History:
261 * 01-Feb-2000 Created.
262 */
263static void usbvideo_OverlayChar(struct uvd *uvd, struct usbvideo_frame *frame,
264 int x, int y, int ch)
265{
266 static const unsigned short digits[16] = {
267 0xF6DE, /* 0 */
268 0x2492, /* 1 */
269 0xE7CE, /* 2 */
270 0xE79E, /* 3 */
271 0xB792, /* 4 */
272 0xF39E, /* 5 */
273 0xF3DE, /* 6 */
274 0xF492, /* 7 */
275 0xF7DE, /* 8 */
276 0xF79E, /* 9 */
277 0x77DA, /* a */
278 0xD75C, /* b */
279 0xF24E, /* c */
280 0xD6DC, /* d */
281 0xF34E, /* e */
282 0xF348 /* f */
283 };
284 unsigned short digit;
285 int ix, iy;
286
287 if ((uvd == NULL) || (frame == NULL))
288 return;
289
290 if (ch >= '0' && ch <= '9')
291 ch -= '0';
292 else if (ch >= 'A' && ch <= 'F')
293 ch = 10 + (ch - 'A');
294 else if (ch >= 'a' && ch <= 'f')
295 ch = 10 + (ch - 'a');
296 else
297 return;
298 digit = digits[ch];
299
300 for (iy=0; iy < 5; iy++) {
301 for (ix=0; ix < 3; ix++) {
302 if (digit & 0x8000) {
303 if (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24)) {
304/* TODO */ RGB24_PUTPIXEL(frame, x+ix, y+iy, 0xFF, 0xFF, 0xFF);
305 }
306 }
307 digit = digit << 1;
308 }
309 }
310}
311
312/*
313 * usbvideo_OverlayString()
314 *
315 * History:
316 * 01-Feb-2000 Created.
317 */
318static void usbvideo_OverlayString(struct uvd *uvd, struct usbvideo_frame *frame,
319 int x, int y, const char *str)
320{
321 while (*str) {
322 usbvideo_OverlayChar(uvd, frame, x, y, *str);
323 str++;
324 x += 4; /* 3 pixels character + 1 space */
325 }
326}
327
328/*
329 * usbvideo_OverlayStats()
330 *
331 * Overlays important debugging information.
332 *
333 * History:
334 * 01-Feb-2000 Created.
335 */
336static void usbvideo_OverlayStats(struct uvd *uvd, struct usbvideo_frame *frame)
337{
338 const int y_diff = 8;
339 char tmp[16];
340 int x = 10, y=10;
341 long i, j, barLength;
342 const int qi_x1 = 60, qi_y1 = 10;
343 const int qi_x2 = VIDEOSIZE_X(frame->request) - 10, qi_h = 10;
344
345 /* Call the user callback, see if we may proceed after that */
346 if (VALID_CALLBACK(uvd, overlayHook)) {
347 if (GET_CALLBACK(uvd, overlayHook)(uvd, frame) < 0)
348 return;
349 }
350
351 /*
352 * We draw a (mostly) hollow rectangle with qi_xxx coordinates.
353 * Left edge symbolizes the queue index 0; right edge symbolizes
354 * the full capacity of the queue.
355 */
356 barLength = qi_x2 - qi_x1 - 2;
357 if ((barLength > 10) && (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24))) {
358/* TODO */ long u_lo, u_hi, q_used;
359 long m_ri, m_wi, m_lo, m_hi;
360
361 /*
362 * Determine fill zones (used areas of the queue):
363 * 0 xxxxxxx u_lo ...... uvd->dp.ri xxxxxxxx u_hi ..... uvd->dp.length
364 *
365 * if u_lo < 0 then there is no first filler.
366 */
367
368 q_used = RingQueue_GetLength(&uvd->dp);
369 if ((uvd->dp.ri + q_used) >= uvd->dp.length) {
370 u_hi = uvd->dp.length;
371 u_lo = (q_used + uvd->dp.ri) & (uvd->dp.length-1);
372 } else {
373 u_hi = (q_used + uvd->dp.ri);
374 u_lo = -1;
375 }
376
377 /* Convert byte indices into screen units */
378 m_ri = qi_x1 + ((barLength * uvd->dp.ri) / uvd->dp.length);
379 m_wi = qi_x1 + ((barLength * uvd->dp.wi) / uvd->dp.length);
380 m_lo = (u_lo > 0) ? (qi_x1 + ((barLength * u_lo) / uvd->dp.length)) : -1;
381 m_hi = qi_x1 + ((barLength * u_hi) / uvd->dp.length);
382
383 for (j=qi_y1; j < (qi_y1 + qi_h); j++) {
384 for (i=qi_x1; i < qi_x2; i++) {
385 /* Draw border lines */
386 if ((j == qi_y1) || (j == (qi_y1 + qi_h - 1)) ||
387 (i == qi_x1) || (i == (qi_x2 - 1))) {
388 RGB24_PUTPIXEL(frame, i, j, 0xFF, 0xFF, 0xFF);
389 continue;
390 }
391 /* For all other points the Y coordinate does not matter */
392 if ((i >= m_ri) && (i <= (m_ri + 3))) {
393 RGB24_PUTPIXEL(frame, i, j, 0x00, 0xFF, 0x00);
394 } else if ((i >= m_wi) && (i <= (m_wi + 3))) {
395 RGB24_PUTPIXEL(frame, i, j, 0xFF, 0x00, 0x00);
396 } else if ((i < m_lo) || ((i > m_ri) && (i < m_hi)))
397 RGB24_PUTPIXEL(frame, i, j, 0x00, 0x00, 0xFF);
398 }
399 }
400 }
401
402 sprintf(tmp, "%8lx", uvd->stats.frame_num);
403 usbvideo_OverlayString(uvd, frame, x, y, tmp);
404 y += y_diff;
405
406 sprintf(tmp, "%8lx", uvd->stats.urb_count);
407 usbvideo_OverlayString(uvd, frame, x, y, tmp);
408 y += y_diff;
409
410 sprintf(tmp, "%8lx", uvd->stats.urb_length);
411 usbvideo_OverlayString(uvd, frame, x, y, tmp);
412 y += y_diff;
413
414 sprintf(tmp, "%8lx", uvd->stats.data_count);
415 usbvideo_OverlayString(uvd, frame, x, y, tmp);
416 y += y_diff;
417
418 sprintf(tmp, "%8lx", uvd->stats.header_count);
419 usbvideo_OverlayString(uvd, frame, x, y, tmp);
420 y += y_diff;
421
422 sprintf(tmp, "%8lx", uvd->stats.iso_skip_count);
423 usbvideo_OverlayString(uvd, frame, x, y, tmp);
424 y += y_diff;
425
426 sprintf(tmp, "%8lx", uvd->stats.iso_err_count);
427 usbvideo_OverlayString(uvd, frame, x, y, tmp);
428 y += y_diff;
429
430 sprintf(tmp, "%8x", uvd->vpic.colour);
431 usbvideo_OverlayString(uvd, frame, x, y, tmp);
432 y += y_diff;
433
434 sprintf(tmp, "%8x", uvd->vpic.hue);
435 usbvideo_OverlayString(uvd, frame, x, y, tmp);
436 y += y_diff;
437
438 sprintf(tmp, "%8x", uvd->vpic.brightness >> 8);
439 usbvideo_OverlayString(uvd, frame, x, y, tmp);
440 y += y_diff;
441
442 sprintf(tmp, "%8x", uvd->vpic.contrast >> 12);
443 usbvideo_OverlayString(uvd, frame, x, y, tmp);
444 y += y_diff;
445
446 sprintf(tmp, "%8d", uvd->vpic.whiteness >> 8);
447 usbvideo_OverlayString(uvd, frame, x, y, tmp);
448 y += y_diff;
449}
450
451/*
452 * usbvideo_ReportStatistics()
453 *
454 * This procedure prints packet and transfer statistics.
455 *
456 * History:
457 * 14-Jan-2000 Corrected default multiplier.
458 */
459static void usbvideo_ReportStatistics(const struct uvd *uvd)
460{
461 if ((uvd != NULL) && (uvd->stats.urb_count > 0)) {
462 unsigned long allPackets, badPackets, goodPackets, percent;
463 allPackets = uvd->stats.urb_count * CAMERA_URB_FRAMES;
464 badPackets = uvd->stats.iso_skip_count + uvd->stats.iso_err_count;
465 goodPackets = allPackets - badPackets;
466 /* Calculate percentage wisely, remember integer limits */
467 assert(allPackets != 0);
468 if (goodPackets < (((unsigned long)-1)/100))
469 percent = (100 * goodPackets) / allPackets;
470 else
471 percent = goodPackets / (allPackets / 100);
472 info("Packet Statistics: Total=%lu. Empty=%lu. Usage=%lu%%",
473 allPackets, badPackets, percent);
474 if (uvd->iso_packet_len > 0) {
475 unsigned long allBytes, xferBytes;
476 char multiplier = ' ';
477 allBytes = allPackets * uvd->iso_packet_len;
478 xferBytes = uvd->stats.data_count;
479 assert(allBytes != 0);
480 if (xferBytes < (((unsigned long)-1)/100))
481 percent = (100 * xferBytes) / allBytes;
482 else
483 percent = xferBytes / (allBytes / 100);
484 /* Scale xferBytes for easy reading */
485 if (xferBytes > 10*1024) {
486 xferBytes /= 1024;
487 multiplier = 'K';
488 if (xferBytes > 10*1024) {
489 xferBytes /= 1024;
490 multiplier = 'M';
491 if (xferBytes > 10*1024) {
492 xferBytes /= 1024;
493 multiplier = 'G';
494 if (xferBytes > 10*1024) {
495 xferBytes /= 1024;
496 multiplier = 'T';
497 }
498 }
499 }
500 }
501 info("Transfer Statistics: Transferred=%lu%cB Usage=%lu%%",
502 xferBytes, multiplier, percent);
503 }
504 }
505}
506
507/*
508 * usbvideo_TestPattern()
509 *
510 * Procedure forms a test pattern (yellow grid on blue background).
511 *
512 * Parameters:
513 * fullframe: if TRUE then entire frame is filled, otherwise the procedure
514 * continues from the current scanline.
515 * pmode 0: fill the frame with solid blue color (like on VCR or TV)
516 * 1: Draw a colored grid
517 *
518 * History:
519 * 01-Feb-2000 Created.
520 */
521void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode)
522{
523 struct usbvideo_frame *frame;
524 int num_cell = 0;
525 int scan_length = 0;
526 static int num_pass = 0;
527
528 if (uvd == NULL) {
529 err("%s: uvd == NULL", __FUNCTION__);
530 return;
531 }
532 if ((uvd->curframe < 0) || (uvd->curframe >= USBVIDEO_NUMFRAMES)) {
533 err("%s: uvd->curframe=%d.", __FUNCTION__, uvd->curframe);
534 return;
535 }
536
537 /* Grab the current frame */
538 frame = &uvd->frame[uvd->curframe];
539
540 /* Optionally start at the beginning */
541 if (fullframe) {
542 frame->curline = 0;
543 frame->seqRead_Length = 0;
544 }
545#if 0
546 { /* For debugging purposes only */
547 char tmp[20];
548 usbvideo_VideosizeToString(tmp, sizeof(tmp), frame->request);
549 info("testpattern: frame=%s", tmp);
550 }
551#endif
552 /* Form every scan line */
553 for (; frame->curline < VIDEOSIZE_Y(frame->request); frame->curline++) {
554 int i;
555 unsigned char *f = frame->data +
556 (VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL * frame->curline);
557 for (i=0; i < VIDEOSIZE_X(frame->request); i++) {
558 unsigned char cb=0x80;
559 unsigned char cg = 0;
560 unsigned char cr = 0;
561
562 if (pmode == 1) {
563 if (frame->curline % 32 == 0)
564 cb = 0, cg = cr = 0xFF;
565 else if (i % 32 == 0) {
566 if (frame->curline % 32 == 1)
567 num_cell++;
568 cb = 0, cg = cr = 0xFF;
569 } else {
570 cb = ((num_cell*7) + num_pass) & 0xFF;
571 cg = ((num_cell*5) + num_pass*2) & 0xFF;
572 cr = ((num_cell*3) + num_pass*3) & 0xFF;
573 }
574 } else {
575 /* Just the blue screen */
576 }
577
578 *f++ = cb;
579 *f++ = cg;
580 *f++ = cr;
581 scan_length += 3;
582 }
583 }
584
585 frame->frameState = FrameState_Done;
586 frame->seqRead_Length += scan_length;
587 ++num_pass;
588
589 /* We do this unconditionally, regardless of FLAGS_OVERLAY_STATS */
590 usbvideo_OverlayStats(uvd, frame);
591}
592
593EXPORT_SYMBOL(usbvideo_TestPattern);
594
595
596#ifdef DEBUG
597/*
598 * usbvideo_HexDump()
599 *
600 * A debugging tool. Prints hex dumps.
601 *
602 * History:
603 * 29-Jul-2000 Added printing of offsets.
604 */
605void usbvideo_HexDump(const unsigned char *data, int len)
606{
607 const int bytes_per_line = 32;
608 char tmp[128]; /* 32*3 + 5 */
609 int i, k;
610
611 for (i=k=0; len > 0; i++, len--) {
612 if (i > 0 && ((i % bytes_per_line) == 0)) {
613 printk("%s\n", tmp);
614 k=0;
615 }
616 if ((i % bytes_per_line) == 0)
617 k += sprintf(&tmp[k], "%04x: ", i);
618 k += sprintf(&tmp[k], "%02x ", data[i]);
619 }
620 if (k > 0)
621 printk("%s\n", tmp);
622}
623
624EXPORT_SYMBOL(usbvideo_HexDump);
625
626#endif
627
628/* ******************************************************************** */
629
630/* XXX: this piece of crap really wants some error handling.. */
631static void usbvideo_ClientIncModCount(struct uvd *uvd)
632{
633 if (uvd == NULL) {
634 err("%s: uvd == NULL", __FUNCTION__);
635 return;
636 }
637 if (uvd->handle == NULL) {
638 err("%s: uvd->handle == NULL", __FUNCTION__);
639 return;
640 }
641 if (uvd->handle->md_module == NULL) {
642 err("%s: uvd->handle->md_module == NULL", __FUNCTION__);
643 return;
644 }
645 if (!try_module_get(uvd->handle->md_module)) {
646 err("%s: try_module_get() == 0", __FUNCTION__);
647 return;
648 }
649}
650
651static void usbvideo_ClientDecModCount(struct uvd *uvd)
652{
653 if (uvd == NULL) {
654 err("%s: uvd == NULL", __FUNCTION__);
655 return;
656 }
657 if (uvd->handle == NULL) {
658 err("%s: uvd->handle == NULL", __FUNCTION__);
659 return;
660 }
661 if (uvd->handle->md_module == NULL) {
662 err("%s: uvd->handle->md_module == NULL", __FUNCTION__);
663 return;
664 }
665 module_put(uvd->handle->md_module);
666}
667
668int usbvideo_register(
669 struct usbvideo **pCams,
670 const int num_cams,
671 const int num_extra,
672 const char *driverName,
673 const struct usbvideo_cb *cbTbl,
674 struct module *md,
675 const struct usb_device_id *id_table)
676{
677 struct usbvideo *cams;
678 int i, base_size, result;
679
680 /* Check parameters for sanity */
681 if ((num_cams <= 0) || (pCams == NULL) || (cbTbl == NULL)) {
682 err("%s: Illegal call", __FUNCTION__);
683 return -EINVAL;
684 }
685
686 /* Check registration callback - must be set! */
687 if (cbTbl->probe == NULL) {
688 err("%s: probe() is required!", __FUNCTION__);
689 return -EINVAL;
690 }
691
692 base_size = num_cams * sizeof(struct uvd) + sizeof(struct usbvideo);
693 cams = (struct usbvideo *) kmalloc(base_size, GFP_KERNEL);
694 if (cams == NULL) {
695 err("Failed to allocate %d. bytes for usbvideo struct", base_size);
696 return -ENOMEM;
697 }
698 dbg("%s: Allocated $%p (%d. bytes) for %d. cameras",
699 __FUNCTION__, cams, base_size, num_cams);
700 memset(cams, 0, base_size);
701
702 /* Copy callbacks, apply defaults for those that are not set */
703 memmove(&cams->cb, cbTbl, sizeof(cams->cb));
704 if (cams->cb.getFrame == NULL)
705 cams->cb.getFrame = usbvideo_GetFrame;
706 if (cams->cb.disconnect == NULL)
707 cams->cb.disconnect = usbvideo_Disconnect;
708 if (cams->cb.startDataPump == NULL)
709 cams->cb.startDataPump = usbvideo_StartDataPump;
710 if (cams->cb.stopDataPump == NULL)
711 cams->cb.stopDataPump = usbvideo_StopDataPump;
712
713 cams->num_cameras = num_cams;
714 cams->cam = (struct uvd *) &cams[1];
715 cams->md_module = md;
716 if (cams->md_module == NULL)
717 warn("%s: module == NULL!", __FUNCTION__);
718 init_MUTEX(&cams->lock); /* to 1 == available */
719
720 for (i = 0; i < num_cams; i++) {
721 struct uvd *up = &cams->cam[i];
722
723 up->handle = cams;
724
725 /* Allocate user_data separately because of kmalloc's limits */
726 if (num_extra > 0) {
727 up->user_size = num_cams * num_extra;
728 up->user_data = (char *) kmalloc(up->user_size, GFP_KERNEL);
729 if (up->user_data == NULL) {
730 err("%s: Failed to allocate user_data (%d. bytes)",
731 __FUNCTION__, up->user_size);
732 while (i) {
733 up = &cams->cam[--i];
734 kfree(up->user_data);
735 }
736 kfree(cams);
737 return -ENOMEM;
738 }
739 dbg("%s: Allocated cams[%d].user_data=$%p (%d. bytes)",
740 __FUNCTION__, i, up->user_data, up->user_size);
741 }
742 }
743
744 /*
745 * Register ourselves with USB stack.
746 */
747 strcpy(cams->drvName, (driverName != NULL) ? driverName : "Unknown");
748 cams->usbdrv.name = cams->drvName;
749 cams->usbdrv.probe = cams->cb.probe;
750 cams->usbdrv.disconnect = cams->cb.disconnect;
751 cams->usbdrv.id_table = id_table;
752
753 /*
754 * Update global handle to usbvideo. This is very important
755 * because probe() can be called before usb_register() returns.
756 * If the handle is not yet updated then the probe() will fail.
757 */
758 *pCams = cams;
759 result = usb_register(&cams->usbdrv);
760 if (result) {
761 for (i = 0; i < num_cams; i++) {
762 struct uvd *up = &cams->cam[i];
763 kfree(up->user_data);
764 }
765 kfree(cams);
766 }
767
768 return result;
769}
770
771EXPORT_SYMBOL(usbvideo_register);
772
773/*
774 * usbvideo_Deregister()
775 *
776 * Procedure frees all usbvideo and user data structures. Be warned that
777 * if you had some dynamically allocated components in ->user field then
778 * you should free them before calling here.
779 */
780void usbvideo_Deregister(struct usbvideo **pCams)
781{
782 struct usbvideo *cams;
783 int i;
784
785 if (pCams == NULL) {
786 err("%s: pCams == NULL", __FUNCTION__);
787 return;
788 }
789 cams = *pCams;
790 if (cams == NULL) {
791 err("%s: cams == NULL", __FUNCTION__);
792 return;
793 }
794
795 dbg("%s: Deregistering %s driver.", __FUNCTION__, cams->drvName);
796 usb_deregister(&cams->usbdrv);
797
798 dbg("%s: Deallocating cams=$%p (%d. cameras)", __FUNCTION__, cams, cams->num_cameras);
799 for (i=0; i < cams->num_cameras; i++) {
800 struct uvd *up = &cams->cam[i];
801 int warning = 0;
802
803 if (up->user_data != NULL) {
804 if (up->user_size <= 0)
805 ++warning;
806 } else {
807 if (up->user_size > 0)
808 ++warning;
809 }
810 if (warning) {
811 err("%s: Warning: user_data=$%p user_size=%d.",
812 __FUNCTION__, up->user_data, up->user_size);
813 } else {
814 dbg("%s: Freeing %d. $%p->user_data=$%p",
815 __FUNCTION__, i, up, up->user_data);
816 kfree(up->user_data);
817 }
818 }
819 /* Whole array was allocated in one chunk */
820 dbg("%s: Freed %d uvd structures",
821 __FUNCTION__, cams->num_cameras);
822 kfree(cams);
823 *pCams = NULL;
824}
825
826EXPORT_SYMBOL(usbvideo_Deregister);
827
828/*
829 * usbvideo_Disconnect()
830 *
831 * This procedure stops all driver activity. Deallocation of
832 * the interface-private structure (pointed by 'ptr') is done now
833 * (if we don't have any open files) or later, when those files
834 * are closed. After that driver should be removable.
835 *
836 * This code handles surprise removal. The uvd->user is a counter which
837 * increments on open() and decrements on close(). If we see here that
838 * this counter is not 0 then we have a client who still has us opened.
839 * We set uvd->remove_pending flag as early as possible, and after that
840 * all access to the camera will gracefully fail. These failures should
841 * prompt client to (eventually) close the video device, and then - in
842 * usbvideo_v4l_close() - we decrement uvd->uvd_used and usage counter.
843 *
844 * History:
845 * 22-Jan-2000 Added polling of MOD_IN_USE to delay removal until all users gone.
846 * 27-Jan-2000 Reworked to allow pending disconnects; see xxx_close()
847 * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
848 * 19-Oct-2000 Moved to usbvideo module.
849 */
850static void usbvideo_Disconnect(struct usb_interface *intf)
851{
852 struct uvd *uvd = usb_get_intfdata (intf);
853 int i;
854
855 if (uvd == NULL) {
856 err("%s($%p): Illegal call.", __FUNCTION__, intf);
857 return;
858 }
859
860 usb_set_intfdata (intf, NULL);
861
862 usbvideo_ClientIncModCount(uvd);
863 if (uvd->debug > 0)
864 info("%s(%p.)", __FUNCTION__, intf);
865
866 down(&uvd->lock);
867 uvd->remove_pending = 1; /* Now all ISO data will be ignored */
868
869 /* At this time we ask to cancel outstanding URBs */
870 GET_CALLBACK(uvd, stopDataPump)(uvd);
871
872 for (i=0; i < USBVIDEO_NUMSBUF; i++)
873 usb_free_urb(uvd->sbuf[i].urb);
874
875 usb_put_dev(uvd->dev);
876 uvd->dev = NULL; /* USB device is no more */
877
878 video_unregister_device(&uvd->vdev);
879 if (uvd->debug > 0)
880 info("%s: Video unregistered.", __FUNCTION__);
881
882 if (uvd->user)
883 info("%s: In use, disconnect pending.", __FUNCTION__);
884 else
885 usbvideo_CameraRelease(uvd);
886 up(&uvd->lock);
887 info("USB camera disconnected.");
888
889 usbvideo_ClientDecModCount(uvd);
890}
891
892/*
893 * usbvideo_CameraRelease()
894 *
895 * This code does final release of uvd. This happens
896 * after the device is disconnected -and- all clients
897 * closed their files.
898 *
899 * History:
900 * 27-Jan-2000 Created.
901 */
902static void usbvideo_CameraRelease(struct uvd *uvd)
903{
904 if (uvd == NULL) {
905 err("%s: Illegal call", __FUNCTION__);
906 return;
907 }
908
909 RingQueue_Free(&uvd->dp);
910 if (VALID_CALLBACK(uvd, userFree))
911 GET_CALLBACK(uvd, userFree)(uvd);
912 uvd->uvd_used = 0; /* This is atomic, no need to take mutex */
913}
914
915/*
916 * usbvideo_find_struct()
917 *
918 * This code searches the array of preallocated (static) structures
919 * and returns index of the first one that isn't in use. Returns -1
920 * if there are no free structures.
921 *
922 * History:
923 * 27-Jan-2000 Created.
924 */
925static int usbvideo_find_struct(struct usbvideo *cams)
926{
927 int u, rv = -1;
928
929 if (cams == NULL) {
930 err("No usbvideo handle?");
931 return -1;
932 }
933 down(&cams->lock);
934 for (u = 0; u < cams->num_cameras; u++) {
935 struct uvd *uvd = &cams->cam[u];
936 if (!uvd->uvd_used) /* This one is free */
937 {
938 uvd->uvd_used = 1; /* In use now */
939 init_MUTEX(&uvd->lock); /* to 1 == available */
940 uvd->dev = NULL;
941 rv = u;
942 break;
943 }
944 }
945 up(&cams->lock);
946 return rv;
947}
948
949static struct file_operations usbvideo_fops = {
950 .owner = THIS_MODULE,
951 .open = usbvideo_v4l_open,
952 .release =usbvideo_v4l_close,
953 .read = usbvideo_v4l_read,
954 .mmap = usbvideo_v4l_mmap,
955 .ioctl = usbvideo_v4l_ioctl,
956 .llseek = no_llseek,
957};
958static struct video_device usbvideo_template = {
959 .owner = THIS_MODULE,
960 .type = VID_TYPE_CAPTURE,
961 .hardware = VID_HARDWARE_CPIA,
962 .fops = &usbvideo_fops,
963};
964
965struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams)
966{
967 int i, devnum;
968 struct uvd *uvd = NULL;
969
970 if (cams == NULL) {
971 err("No usbvideo handle?");
972 return NULL;
973 }
974
975 devnum = usbvideo_find_struct(cams);
976 if (devnum == -1) {
977 err("IBM USB camera driver: Too many devices!");
978 return NULL;
979 }
980 uvd = &cams->cam[devnum];
981 dbg("Device entry #%d. at $%p", devnum, uvd);
982
983 /* Not relying upon caller we increase module counter ourselves */
984 usbvideo_ClientIncModCount(uvd);
985
986 down(&uvd->lock);
987 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
988 uvd->sbuf[i].urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
989 if (uvd->sbuf[i].urb == NULL) {
990 err("usb_alloc_urb(%d.) failed.", FRAMES_PER_DESC);
991 uvd->uvd_used = 0;
992 uvd = NULL;
993 goto allocate_done;
994 }
995 }
996 uvd->user=0;
997 uvd->remove_pending = 0;
998 uvd->last_error = 0;
999 RingQueue_Initialize(&uvd->dp);
1000
1001 /* Initialize video device structure */
1002 uvd->vdev = usbvideo_template;
1003 sprintf(uvd->vdev.name, "%.20s USB Camera", cams->drvName);
1004 /*
1005 * The client is free to overwrite those because we
1006 * return control to the client's probe function right now.
1007 */
1008allocate_done:
1009 up (&uvd->lock);
1010 usbvideo_ClientDecModCount(uvd);
1011 return uvd;
1012}
1013
1014EXPORT_SYMBOL(usbvideo_AllocateDevice);
1015
1016int usbvideo_RegisterVideoDevice(struct uvd *uvd)
1017{
1018 char tmp1[20], tmp2[20]; /* Buffers for printing */
1019
1020 if (uvd == NULL) {
1021 err("%s: Illegal call.", __FUNCTION__);
1022 return -EINVAL;
1023 }
1024 if (uvd->video_endp == 0) {
1025 info("%s: No video endpoint specified; data pump disabled.", __FUNCTION__);
1026 }
1027 if (uvd->paletteBits == 0) {
1028 err("%s: No palettes specified!", __FUNCTION__);
1029 return -EINVAL;
1030 }
1031 if (uvd->defaultPalette == 0) {
1032 info("%s: No default palette!", __FUNCTION__);
1033 }
1034
1035 uvd->max_frame_size = VIDEOSIZE_X(uvd->canvas) *
1036 VIDEOSIZE_Y(uvd->canvas) * V4L_BYTES_PER_PIXEL;
1037 usbvideo_VideosizeToString(tmp1, sizeof(tmp1), uvd->videosize);
1038 usbvideo_VideosizeToString(tmp2, sizeof(tmp2), uvd->canvas);
1039
1040 if (uvd->debug > 0) {
1041 info("%s: iface=%d. endpoint=$%02x paletteBits=$%08lx",
1042 __FUNCTION__, uvd->iface, uvd->video_endp, uvd->paletteBits);
1043 }
1044 if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
1045 err("%s: video_register_device failed", __FUNCTION__);
1046 return -EPIPE;
1047 }
1048 if (uvd->debug > 1) {
1049 info("%s: video_register_device() successful", __FUNCTION__);
1050 }
1051 if (uvd->dev == NULL) {
1052 err("%s: uvd->dev == NULL", __FUNCTION__);
1053 return -EINVAL;
1054 }
1055
1056 info("%s on /dev/video%d: canvas=%s videosize=%s",
1057 (uvd->handle != NULL) ? uvd->handle->drvName : "???",
1058 uvd->vdev.minor, tmp2, tmp1);
1059
1060 usb_get_dev(uvd->dev);
1061 return 0;
1062}
1063
1064EXPORT_SYMBOL(usbvideo_RegisterVideoDevice);
1065
1066/* ******************************************************************** */
1067
1068static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma)
1069{
1070 struct uvd *uvd = file->private_data;
1071 unsigned long start = vma->vm_start;
1072 unsigned long size = vma->vm_end-vma->vm_start;
1073 unsigned long page, pos;
1074
1075 if (!CAMERA_IS_OPERATIONAL(uvd))
1076 return -EFAULT;
1077
1078 if (size > (((USBVIDEO_NUMFRAMES * uvd->max_frame_size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
1079 return -EINVAL;
1080
1081 pos = (unsigned long) uvd->fbuf;
1082 while (size > 0) {
1083 page = vmalloc_to_pfn((void *)pos);
1084 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
1085 return -EAGAIN;
1086
1087 start += PAGE_SIZE;
1088 pos += PAGE_SIZE;
1089 if (size > PAGE_SIZE)
1090 size -= PAGE_SIZE;
1091 else
1092 size = 0;
1093 }
1094
1095 return 0;
1096}
1097
1098/*
1099 * usbvideo_v4l_open()
1100 *
1101 * This is part of Video 4 Linux API. The driver can be opened by one
1102 * client only (checks internal counter 'uvdser'). The procedure
1103 * then allocates buffers needed for video processing.
1104 *
1105 * History:
1106 * 22-Jan-2000 Rewrote, moved scratch buffer allocation here. Now the
1107 * camera is also initialized here (once per connect), at
1108 * expense of V4L client (it waits on open() call).
1109 * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
1110 * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
1111 */
1112static int usbvideo_v4l_open(struct inode *inode, struct file *file)
1113{
1114 struct video_device *dev = video_devdata(file);
1115 struct uvd *uvd = (struct uvd *) dev;
1116 const int sb_size = FRAMES_PER_DESC * uvd->iso_packet_len;
1117 int i, errCode = 0;
1118
1119 if (uvd->debug > 1)
1120 info("%s($%p)", __FUNCTION__, dev);
1121
1122 usbvideo_ClientIncModCount(uvd);
1123 down(&uvd->lock);
1124
1125 if (uvd->user) {
1126 err("%s: Someone tried to open an already opened device!", __FUNCTION__);
1127 errCode = -EBUSY;
1128 } else {
1129 /* Clear statistics */
1130 memset(&uvd->stats, 0, sizeof(uvd->stats));
1131
1132 /* Clean pointers so we know if we allocated something */
1133 for (i=0; i < USBVIDEO_NUMSBUF; i++)
1134 uvd->sbuf[i].data = NULL;
1135
1136 /* Allocate memory for the frame buffers */
1137 uvd->fbuf_size = USBVIDEO_NUMFRAMES * uvd->max_frame_size;
1138 uvd->fbuf = usbvideo_rvmalloc(uvd->fbuf_size);
1139 RingQueue_Allocate(&uvd->dp, RING_QUEUE_SIZE);
1140 if ((uvd->fbuf == NULL) ||
1141 (!RingQueue_IsAllocated(&uvd->dp))) {
1142 err("%s: Failed to allocate fbuf or dp", __FUNCTION__);
1143 errCode = -ENOMEM;
1144 } else {
1145 /* Allocate all buffers */
1146 for (i=0; i < USBVIDEO_NUMFRAMES; i++) {
1147 uvd->frame[i].frameState = FrameState_Unused;
1148 uvd->frame[i].data = uvd->fbuf + i*(uvd->max_frame_size);
1149 /*
1150 * Set default sizes in case IOCTL (VIDIOCMCAPTURE)
1151 * is not used (using read() instead).
1152 */
1153 uvd->frame[i].canvas = uvd->canvas;
1154 uvd->frame[i].seqRead_Index = 0;
1155 }
1156 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
1157 uvd->sbuf[i].data = kmalloc(sb_size, GFP_KERNEL);
1158 if (uvd->sbuf[i].data == NULL) {
1159 errCode = -ENOMEM;
1160 break;
1161 }
1162 }
1163 }
1164 if (errCode != 0) {
1165 /* Have to free all that memory */
1166 if (uvd->fbuf != NULL) {
1167 usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
1168 uvd->fbuf = NULL;
1169 }
1170 RingQueue_Free(&uvd->dp);
1171 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
1172 if (uvd->sbuf[i].data != NULL) {
1173 kfree (uvd->sbuf[i].data);
1174 uvd->sbuf[i].data = NULL;
1175 }
1176 }
1177 }
1178 }
1179
1180 /* If so far no errors then we shall start the camera */
1181 if (errCode == 0) {
1182 /* Start data pump if we have valid endpoint */
1183 if (uvd->video_endp != 0)
1184 errCode = GET_CALLBACK(uvd, startDataPump)(uvd);
1185 if (errCode == 0) {
1186 if (VALID_CALLBACK(uvd, setupOnOpen)) {
1187 if (uvd->debug > 1)
1188 info("%s: setupOnOpen callback", __FUNCTION__);
1189 errCode = GET_CALLBACK(uvd, setupOnOpen)(uvd);
1190 if (errCode < 0) {
1191 err("%s: setupOnOpen callback failed (%d.).",
1192 __FUNCTION__, errCode);
1193 } else if (uvd->debug > 1) {
1194 info("%s: setupOnOpen callback successful", __FUNCTION__);
1195 }
1196 }
1197 if (errCode == 0) {
1198 uvd->settingsAdjusted = 0;
1199 if (uvd->debug > 1)
1200 info("%s: Open succeeded.", __FUNCTION__);
1201 uvd->user++;
1202 file->private_data = uvd;
1203 }
1204 }
1205 }
1206 up(&uvd->lock);
1207 if (errCode != 0)
1208 usbvideo_ClientDecModCount(uvd);
1209 if (uvd->debug > 0)
1210 info("%s: Returning %d.", __FUNCTION__, errCode);
1211 return errCode;
1212}
1213
1214/*
1215 * usbvideo_v4l_close()
1216 *
1217 * This is part of Video 4 Linux API. The procedure
1218 * stops streaming and deallocates all buffers that were earlier
1219 * allocated in usbvideo_v4l_open().
1220 *
1221 * History:
1222 * 22-Jan-2000 Moved scratch buffer deallocation here.
1223 * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
1224 * 24-May-2000 Moved MOD_DEC_USE_COUNT outside of code that can sleep.
1225 */
1226static int usbvideo_v4l_close(struct inode *inode, struct file *file)
1227{
1228 struct video_device *dev = file->private_data;
1229 struct uvd *uvd = (struct uvd *) dev;
1230 int i;
1231
1232 if (uvd->debug > 1)
1233 info("%s($%p)", __FUNCTION__, dev);
1234
1235 down(&uvd->lock);
1236 GET_CALLBACK(uvd, stopDataPump)(uvd);
1237 usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
1238 uvd->fbuf = NULL;
1239 RingQueue_Free(&uvd->dp);
1240
1241 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
1242 kfree(uvd->sbuf[i].data);
1243 uvd->sbuf[i].data = NULL;
1244 }
1245
1246#if USBVIDEO_REPORT_STATS
1247 usbvideo_ReportStatistics(uvd);
1248#endif
1249
1250 uvd->user--;
1251 if (uvd->remove_pending) {
1252 if (uvd->debug > 0)
1253 info("usbvideo_v4l_close: Final disconnect.");
1254 usbvideo_CameraRelease(uvd);
1255 }
1256 up(&uvd->lock);
1257 usbvideo_ClientDecModCount(uvd);
1258
1259 if (uvd->debug > 1)
1260 info("%s: Completed.", __FUNCTION__);
1261 file->private_data = NULL;
1262 return 0;
1263}
1264
1265/*
1266 * usbvideo_v4l_ioctl()
1267 *
1268 * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
1269 *
1270 * History:
1271 * 22-Jan-2000 Corrected VIDIOCSPICT to reject unsupported settings.
1272 */
1273static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file,
1274 unsigned int cmd, void *arg)
1275{
1276 struct uvd *uvd = file->private_data;
1277
1278 if (!CAMERA_IS_OPERATIONAL(uvd))
1279 return -EIO;
1280
1281 switch (cmd) {
1282 case VIDIOCGCAP:
1283 {
1284 struct video_capability *b = arg;
1285 *b = uvd->vcap;
1286 return 0;
1287 }
1288 case VIDIOCGCHAN:
1289 {
1290 struct video_channel *v = arg;
1291 *v = uvd->vchan;
1292 return 0;
1293 }
1294 case VIDIOCSCHAN:
1295 {
1296 struct video_channel *v = arg;
1297 if (v->channel != 0)
1298 return -EINVAL;
1299 return 0;
1300 }
1301 case VIDIOCGPICT:
1302 {
1303 struct video_picture *pic = arg;
1304 *pic = uvd->vpic;
1305 return 0;
1306 }
1307 case VIDIOCSPICT:
1308 {
1309 struct video_picture *pic = arg;
1310 /*
1311 * Use temporary 'video_picture' structure to preserve our
1312 * own settings (such as color depth, palette) that we
1313 * aren't allowing everyone (V4L client) to change.
1314 */
1315 uvd->vpic.brightness = pic->brightness;
1316 uvd->vpic.hue = pic->hue;
1317 uvd->vpic.colour = pic->colour;
1318 uvd->vpic.contrast = pic->contrast;
1319 uvd->settingsAdjusted = 0; /* Will force new settings */
1320 return 0;
1321 }
1322 case VIDIOCSWIN:
1323 {
1324 struct video_window *vw = arg;
1325
1326 if(VALID_CALLBACK(uvd, setVideoMode)) {
1327 return GET_CALLBACK(uvd, setVideoMode)(uvd, vw);
1328 }
1329
1330 if (vw->flags)
1331 return -EINVAL;
1332 if (vw->clipcount)
1333 return -EINVAL;
1334 if (vw->width != VIDEOSIZE_X(uvd->canvas))
1335 return -EINVAL;
1336 if (vw->height != VIDEOSIZE_Y(uvd->canvas))
1337 return -EINVAL;
1338
1339 return 0;
1340 }
1341 case VIDIOCGWIN:
1342 {
1343 struct video_window *vw = arg;
1344
1345 vw->x = 0;
1346 vw->y = 0;
1347 vw->width = VIDEOSIZE_X(uvd->videosize);
1348 vw->height = VIDEOSIZE_Y(uvd->videosize);
1349 vw->chromakey = 0;
1350 if (VALID_CALLBACK(uvd, getFPS))
1351 vw->flags = GET_CALLBACK(uvd, getFPS)(uvd);
1352 else
1353 vw->flags = 10; /* FIXME: do better! */
1354 return 0;
1355 }
1356 case VIDIOCGMBUF:
1357 {
1358 struct video_mbuf *vm = arg;
1359 int i;
1360
1361 memset(vm, 0, sizeof(*vm));
1362 vm->size = uvd->max_frame_size * USBVIDEO_NUMFRAMES;
1363 vm->frames = USBVIDEO_NUMFRAMES;
1364 for(i = 0; i < USBVIDEO_NUMFRAMES; i++)
1365 vm->offsets[i] = i * uvd->max_frame_size;
1366
1367 return 0;
1368 }
1369 case VIDIOCMCAPTURE:
1370 {
1371 struct video_mmap *vm = arg;
1372
1373 if (uvd->debug >= 1) {
1374 info("VIDIOCMCAPTURE: frame=%d. size=%dx%d, format=%d.",
1375 vm->frame, vm->width, vm->height, vm->format);
1376 }
1377 /*
1378 * Check if the requested size is supported. If the requestor
1379 * requests too big a frame then we may be tricked into accessing
1380 * outside of own preallocated frame buffer (in uvd->frame).
1381 * This will cause oops or a security hole. Theoretically, we
1382 * could only clamp the size down to acceptable bounds, but then
1383 * we'd need to figure out how to insert our smaller buffer into
1384 * larger caller's buffer... this is not an easy question. So we
1385 * here just flatly reject too large requests, assuming that the
1386 * caller will resubmit with smaller size. Callers should know
1387 * what size we support (returned by VIDIOCGCAP). However vidcat,
1388 * for one, does not care and allows to ask for any size.
1389 */
1390 if ((vm->width > VIDEOSIZE_X(uvd->canvas)) ||
1391 (vm->height > VIDEOSIZE_Y(uvd->canvas))) {
1392 if (uvd->debug > 0) {
1393 info("VIDIOCMCAPTURE: Size=%dx%d too large; "
1394 "allowed only up to %ldx%ld", vm->width, vm->height,
1395 VIDEOSIZE_X(uvd->canvas), VIDEOSIZE_Y(uvd->canvas));
1396 }
1397 return -EINVAL;
1398 }
1399 /* Check if the palette is supported */
1400 if (((1L << vm->format) & uvd->paletteBits) == 0) {
1401 if (uvd->debug > 0) {
1402 info("VIDIOCMCAPTURE: format=%d. not supported"
1403 " (paletteBits=$%08lx)",
1404 vm->format, uvd->paletteBits);
1405 }
1406 return -EINVAL;
1407 }
1408 if ((vm->frame < 0) || (vm->frame >= USBVIDEO_NUMFRAMES)) {
1409 err("VIDIOCMCAPTURE: vm.frame=%d. !E [0-%d]", vm->frame, USBVIDEO_NUMFRAMES-1);
1410 return -EINVAL;
1411 }
1412 if (uvd->frame[vm->frame].frameState == FrameState_Grabbing) {
1413 /* Not an error - can happen */
1414 }
1415 uvd->frame[vm->frame].request = VIDEOSIZE(vm->width, vm->height);
1416 uvd->frame[vm->frame].palette = vm->format;
1417
1418 /* Mark it as ready */
1419 uvd->frame[vm->frame].frameState = FrameState_Ready;
1420
1421 return usbvideo_NewFrame(uvd, vm->frame);
1422 }
1423 case VIDIOCSYNC:
1424 {
1425 int *frameNum = arg;
1426 int ret;
1427
1428 if (*frameNum < 0 || *frameNum >= USBVIDEO_NUMFRAMES)
1429 return -EINVAL;
1430
1431 if (uvd->debug >= 1)
1432 info("VIDIOCSYNC: syncing to frame %d.", *frameNum);
1433 if (uvd->flags & FLAGS_NO_DECODING)
1434 ret = usbvideo_GetFrame(uvd, *frameNum);
1435 else if (VALID_CALLBACK(uvd, getFrame)) {
1436 ret = GET_CALLBACK(uvd, getFrame)(uvd, *frameNum);
1437 if ((ret < 0) && (uvd->debug >= 1)) {
1438 err("VIDIOCSYNC: getFrame() returned %d.", ret);
1439 }
1440 } else {
1441 err("VIDIOCSYNC: getFrame is not set");
1442 ret = -EFAULT;
1443 }
1444
1445 /*
1446 * The frame is in FrameState_Done_Hold state. Release it
1447 * right now because its data is already mapped into
1448 * the user space and it's up to the application to
1449 * make use of it until it asks for another frame.
1450 */
1451 uvd->frame[*frameNum].frameState = FrameState_Unused;
1452 return ret;
1453 }
1454 case VIDIOCGFBUF:
1455 {
1456 struct video_buffer *vb = arg;
1457
1458 memset(vb, 0, sizeof(*vb));
1459 return 0;
1460 }
1461 case VIDIOCKEY:
1462 return 0;
1463
1464 case VIDIOCCAPTURE:
1465 return -EINVAL;
1466
1467 case VIDIOCSFBUF:
1468
1469 case VIDIOCGTUNER:
1470 case VIDIOCSTUNER:
1471
1472 case VIDIOCGFREQ:
1473 case VIDIOCSFREQ:
1474
1475 case VIDIOCGAUDIO:
1476 case VIDIOCSAUDIO:
1477 return -EINVAL;
1478
1479 default:
1480 return -ENOIOCTLCMD;
1481 }
1482 return 0;
1483}
1484
1485static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file,
1486 unsigned int cmd, unsigned long arg)
1487{
1488 return video_usercopy(inode, file, cmd, arg, usbvideo_v4l_do_ioctl);
1489}
1490
1491/*
1492 * usbvideo_v4l_read()
1493 *
1494 * This is mostly boring stuff. We simply ask for a frame and when it
1495 * arrives copy all the video data from it into user space. There is
1496 * no obvious need to override this method.
1497 *
1498 * History:
1499 * 20-Oct-2000 Created.
1500 * 01-Nov-2000 Added mutex (uvd->lock).
1501 */
1502static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
1503 size_t count, loff_t *ppos)
1504{
1505 struct uvd *uvd = file->private_data;
1506 int noblock = file->f_flags & O_NONBLOCK;
1507 int frmx = -1, i;
1508 struct usbvideo_frame *frame;
1509
1510 if (!CAMERA_IS_OPERATIONAL(uvd) || (buf == NULL))
1511 return -EFAULT;
1512
1513 if (uvd->debug >= 1)
1514 info("%s: %Zd. bytes, noblock=%d.", __FUNCTION__, count, noblock);
1515
1516 down(&uvd->lock);
1517
1518 /* See if a frame is completed, then use it. */
1519 for(i = 0; i < USBVIDEO_NUMFRAMES; i++) {
1520 if ((uvd->frame[i].frameState == FrameState_Done) ||
1521 (uvd->frame[i].frameState == FrameState_Done_Hold) ||
1522 (uvd->frame[i].frameState == FrameState_Error)) {
1523 frmx = i;
1524 break;
1525 }
1526 }
1527
1528 /* FIXME: If we don't start a frame here then who ever does? */
1529 if (noblock && (frmx == -1)) {
1530 count = -EAGAIN;
1531 goto read_done;
1532 }
1533
1534 /*
1535 * If no FrameState_Done, look for a FrameState_Grabbing state.
1536 * See if a frame is in process (grabbing), then use it.
1537 * We will need to wait until it becomes cooked, of course.
1538 */
1539 if (frmx == -1) {
1540 for(i = 0; i < USBVIDEO_NUMFRAMES; i++) {
1541 if (uvd->frame[i].frameState == FrameState_Grabbing) {
1542 frmx = i;
1543 break;
1544 }
1545 }
1546 }
1547
1548 /*
1549 * If no frame is active, start one. We don't care which one
1550 * it will be, so #0 is as good as any.
1551 * In read access mode we don't have convenience of VIDIOCMCAPTURE
1552 * to specify the requested palette (video format) on per-frame
1553 * basis. This means that we have to return data in -some- format
1554 * and just hope that the client knows what to do with it.
1555 * The default format is configured in uvd->defaultPalette field
1556 * as one of VIDEO_PALETTE_xxx values. We stuff it into the new
1557 * frame and initiate the frame filling process.
1558 */
1559 if (frmx == -1) {
1560 if (uvd->defaultPalette == 0) {
1561 err("%s: No default palette; don't know what to do!", __FUNCTION__);
1562 count = -EFAULT;
1563 goto read_done;
1564 }
1565 frmx = 0;
1566 /*
1567 * We have no per-frame control over video size.
1568 * Therefore we only can use whatever size was
1569 * specified as default.
1570 */
1571 uvd->frame[frmx].request = uvd->videosize;
1572 uvd->frame[frmx].palette = uvd->defaultPalette;
1573 uvd->frame[frmx].frameState = FrameState_Ready;
1574 usbvideo_NewFrame(uvd, frmx);
1575 /* Now frame 0 is supposed to start filling... */
1576 }
1577
1578 /*
1579 * Get a pointer to the active frame. It is either previously
1580 * completed frame or frame in progress but not completed yet.
1581 */
1582 frame = &uvd->frame[frmx];
1583
1584 /*
1585 * Sit back & wait until the frame gets filled and postprocessed.
1586 * If we fail to get the picture [in time] then return the error.
1587 * In this call we specify that we want the frame to be waited for,
1588 * postprocessed and switched into FrameState_Done_Hold state. This
1589 * state is used to hold the frame as "fully completed" between
1590 * subsequent partial reads of the same frame.
1591 */
1592 if (frame->frameState != FrameState_Done_Hold) {
1593 long rv = -EFAULT;
1594 if (uvd->flags & FLAGS_NO_DECODING)
1595 rv = usbvideo_GetFrame(uvd, frmx);
1596 else if (VALID_CALLBACK(uvd, getFrame))
1597 rv = GET_CALLBACK(uvd, getFrame)(uvd, frmx);
1598 else
1599 err("getFrame is not set");
1600 if ((rv != 0) || (frame->frameState != FrameState_Done_Hold)) {
1601 count = rv;
1602 goto read_done;
1603 }
1604 }
1605
1606 /*
1607 * Copy bytes to user space. We allow for partial reads, which
1608 * means that the user application can request read less than
1609 * the full frame size. It is up to the application to issue
1610 * subsequent calls until entire frame is read.
1611 *
1612 * First things first, make sure we don't copy more than we
1613 * have - even if the application wants more. That would be
1614 * a big security embarassment!
1615 */
1616 if ((count + frame->seqRead_Index) > frame->seqRead_Length)
1617 count = frame->seqRead_Length - frame->seqRead_Index;
1618
1619 /*
1620 * Copy requested amount of data to user space. We start
1621 * copying from the position where we last left it, which
1622 * will be zero for a new frame (not read before).
1623 */
1624 if (copy_to_user(buf, frame->data + frame->seqRead_Index, count)) {
1625 count = -EFAULT;
1626 goto read_done;
1627 }
1628
1629 /* Update last read position */
1630 frame->seqRead_Index += count;
1631 if (uvd->debug >= 1) {
1632 err("%s: {copy} count used=%Zd, new seqRead_Index=%ld",
1633 __FUNCTION__, count, frame->seqRead_Index);
1634 }
1635
1636 /* Finally check if the frame is done with and "release" it */
1637 if (frame->seqRead_Index >= frame->seqRead_Length) {
1638 /* All data has been read */
1639 frame->seqRead_Index = 0;
1640
1641 /* Mark it as available to be used again. */
1642 uvd->frame[frmx].frameState = FrameState_Unused;
1643 if (usbvideo_NewFrame(uvd, (frmx + 1) % USBVIDEO_NUMFRAMES)) {
1644 err("%s: usbvideo_NewFrame failed.", __FUNCTION__);
1645 }
1646 }
1647read_done:
1648 up(&uvd->lock);
1649 return count;
1650}
1651
1652/*
1653 * Make all of the blocks of data contiguous
1654 */
1655static int usbvideo_CompressIsochronous(struct uvd *uvd, struct urb *urb)
1656{
1657 char *cdata;
1658 int i, totlen = 0;
1659
1660 for (i = 0; i < urb->number_of_packets; i++) {
1661 int n = urb->iso_frame_desc[i].actual_length;
1662 int st = urb->iso_frame_desc[i].status;
1663
1664 cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
1665
1666 /* Detect and ignore errored packets */
1667 if (st < 0) {
1668 if (uvd->debug >= 1)
1669 err("Data error: packet=%d. len=%d. status=%d.", i, n, st);
1670 uvd->stats.iso_err_count++;
1671 continue;
1672 }
1673
1674 /* Detect and ignore empty packets */
1675 if (n <= 0) {
1676 uvd->stats.iso_skip_count++;
1677 continue;
1678 }
1679 totlen += n; /* Little local accounting */
1680 RingQueue_Enqueue(&uvd->dp, cdata, n);
1681 }
1682 return totlen;
1683}
1684
1685static void usbvideo_IsocIrq(struct urb *urb, struct pt_regs *regs)
1686{
1687 int i, ret, len;
1688 struct uvd *uvd = urb->context;
1689
1690 /* We don't want to do anything if we are about to be removed! */
1691 if (!CAMERA_IS_OPERATIONAL(uvd))
1692 return;
1693#if 0
1694 if (urb->actual_length > 0) {
1695 info("urb=$%p status=%d. errcount=%d. length=%d.",
1696 urb, urb->status, urb->error_count, urb->actual_length);
1697 } else {
1698 static int c = 0;
1699 if (c++ % 100 == 0)
1700 info("No Isoc data");
1701 }
1702#endif
1703
1704 if (!uvd->streaming) {
1705 if (uvd->debug >= 1)
1706 info("Not streaming, but interrupt!");
1707 return;
1708 }
1709
1710 uvd->stats.urb_count++;
1711 if (urb->actual_length <= 0)
1712 goto urb_done_with;
1713
1714 /* Copy the data received into ring queue */
1715 len = usbvideo_CompressIsochronous(uvd, urb);
1716 uvd->stats.urb_length = len;
1717 if (len <= 0)
1718 goto urb_done_with;
1719
1720 /* Here we got some data */
1721 uvd->stats.data_count += len;
1722 RingQueue_WakeUpInterruptible(&uvd->dp);
1723
1724urb_done_with:
1725 for (i = 0; i < FRAMES_PER_DESC; i++) {
1726 urb->iso_frame_desc[i].status = 0;
1727 urb->iso_frame_desc[i].actual_length = 0;
1728 }
1729 urb->status = 0;
1730 urb->dev = uvd->dev;
1731 ret = usb_submit_urb (urb, GFP_KERNEL);
1732 if(ret)
1733 err("usb_submit_urb error (%d)", ret);
1734 return;
1735}
1736
1737/*
1738 * usbvideo_StartDataPump()
1739 *
1740 * History:
1741 * 27-Jan-2000 Used ibmcam->iface, ibmcam->ifaceAltActive instead
1742 * of hardcoded values. Simplified by using for loop,
1743 * allowed any number of URBs.
1744 */
1745static int usbvideo_StartDataPump(struct uvd *uvd)
1746{
1747 struct usb_device *dev = uvd->dev;
1748 int i, errFlag;
1749
1750 if (uvd->debug > 1)
1751 info("%s($%p)", __FUNCTION__, uvd);
1752
1753 if (!CAMERA_IS_OPERATIONAL(uvd)) {
1754 err("%s: Camera is not operational", __FUNCTION__);
1755 return -EFAULT;
1756 }
1757 uvd->curframe = -1;
1758
1759 /* Alternate interface 1 is is the biggest frame size */
1760 i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive);
1761 if (i < 0) {
1762 err("%s: usb_set_interface error", __FUNCTION__);
1763 uvd->last_error = i;
1764 return -EBUSY;
1765 }
1766 if (VALID_CALLBACK(uvd, videoStart))
1767 GET_CALLBACK(uvd, videoStart)(uvd);
1768 else
1769 err("%s: videoStart not set", __FUNCTION__);
1770
1771 /* We double buffer the Iso lists */
1772 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
1773 int j, k;
1774 struct urb *urb = uvd->sbuf[i].urb;
1775 urb->dev = dev;
1776 urb->context = uvd;
1777 urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp);
1778 urb->interval = 1;
1779 urb->transfer_flags = URB_ISO_ASAP;
1780 urb->transfer_buffer = uvd->sbuf[i].data;
1781 urb->complete = usbvideo_IsocIrq;
1782 urb->number_of_packets = FRAMES_PER_DESC;
1783 urb->transfer_buffer_length = uvd->iso_packet_len * FRAMES_PER_DESC;
1784 for (j=k=0; j < FRAMES_PER_DESC; j++, k += uvd->iso_packet_len) {
1785 urb->iso_frame_desc[j].offset = k;
1786 urb->iso_frame_desc[j].length = uvd->iso_packet_len;
1787 }
1788 }
1789
1790 /* Submit all URBs */
1791 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
1792 errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
1793 if (errFlag)
1794 err("%s: usb_submit_isoc(%d) ret %d", __FUNCTION__, i, errFlag);
1795 }
1796
1797 uvd->streaming = 1;
1798 if (uvd->debug > 1)
1799 info("%s: streaming=1 video_endp=$%02x", __FUNCTION__, uvd->video_endp);
1800 return 0;
1801}
1802
1803/*
1804 * usbvideo_StopDataPump()
1805 *
1806 * This procedure stops streaming and deallocates URBs. Then it
1807 * activates zero-bandwidth alt. setting of the video interface.
1808 *
1809 * History:
1810 * 22-Jan-2000 Corrected order of actions to work after surprise removal.
1811 * 27-Jan-2000 Used uvd->iface, uvd->ifaceAltInactive instead of hardcoded values.
1812 */
1813static void usbvideo_StopDataPump(struct uvd *uvd)
1814{
1815 int i, j;
1816
1817 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
1818 return;
1819
1820 if (uvd->debug > 1)
1821 info("%s($%p)", __FUNCTION__, uvd);
1822
1823 /* Unschedule all of the iso td's */
1824 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
1825 usb_kill_urb(uvd->sbuf[i].urb);
1826 }
1827 if (uvd->debug > 1)
1828 info("%s: streaming=0", __FUNCTION__);
1829 uvd->streaming = 0;
1830
1831 if (!uvd->remove_pending) {
1832 /* Invoke minidriver's magic to stop the camera */
1833 if (VALID_CALLBACK(uvd, videoStop))
1834 GET_CALLBACK(uvd, videoStop)(uvd);
1835 else
1836 err("%s: videoStop not set", __FUNCTION__);
1837
1838 /* Set packet size to 0 */
1839 j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive);
1840 if (j < 0) {
1841 err("%s: usb_set_interface() error %d.", __FUNCTION__, j);
1842 uvd->last_error = j;
1843 }
1844 }
1845}
1846
1847/*
1848 * usbvideo_NewFrame()
1849 *
1850 * History:
1851 * 29-Mar-00 Added copying of previous frame into the current one.
1852 * 6-Aug-00 Added model 3 video sizes, removed redundant width, height.
1853 */
1854static int usbvideo_NewFrame(struct uvd *uvd, int framenum)
1855{
1856 struct usbvideo_frame *frame;
1857 int n;
1858
1859 if (uvd->debug > 1)
1860 info("usbvideo_NewFrame($%p,%d.)", uvd, framenum);
1861
1862 /* If we're not grabbing a frame right now and the other frame is */
1863 /* ready to be grabbed into, then use it instead */
1864 if (uvd->curframe != -1)
1865 return 0;
1866
1867 /* If necessary we adjust picture settings between frames */
1868 if (!uvd->settingsAdjusted) {
1869 if (VALID_CALLBACK(uvd, adjustPicture))
1870 GET_CALLBACK(uvd, adjustPicture)(uvd);
1871 uvd->settingsAdjusted = 1;
1872 }
1873
1874 n = (framenum + 1) % USBVIDEO_NUMFRAMES;
1875 if (uvd->frame[n].frameState == FrameState_Ready)
1876 framenum = n;
1877
1878 frame = &uvd->frame[framenum];
1879
1880 frame->frameState = FrameState_Grabbing;
1881 frame->scanstate = ScanState_Scanning;
1882 frame->seqRead_Length = 0; /* Accumulated in xxx_parse_data() */
1883 frame->deinterlace = Deinterlace_None;
1884 frame->flags = 0; /* No flags yet, up to minidriver (or us) to set them */
1885 uvd->curframe = framenum;
1886
1887 /*
1888 * Normally we would want to copy previous frame into the current one
1889 * before we even start filling it with data; this allows us to stop
1890 * filling at any moment; top portion of the frame will be new and
1891 * bottom portion will stay as it was in previous frame. If we don't
1892 * do that then missing chunks of video stream will result in flickering
1893 * portions of old data whatever it was before.
1894 *
1895 * If we choose not to copy previous frame (to, for example, save few
1896 * bus cycles - the frame can be pretty large!) then we have an option
1897 * to clear the frame before using. If we experience losses in this
1898 * mode then missing picture will be black (no flickering).
1899 *
1900 * Finally, if user chooses not to clean the current frame before
1901 * filling it with data then the old data will be visible if we fail
1902 * to refill entire frame with new data.
1903 */
1904 if (!(uvd->flags & FLAGS_SEPARATE_FRAMES)) {
1905 /* This copies previous frame into this one to mask losses */
1906 int prev = (framenum - 1 + USBVIDEO_NUMFRAMES) % USBVIDEO_NUMFRAMES;
1907 memmove(frame->data, uvd->frame[prev].data, uvd->max_frame_size);
1908 } else {
1909 if (uvd->flags & FLAGS_CLEAN_FRAMES) {
1910 /* This provides a "clean" frame but slows things down */
1911 memset(frame->data, 0, uvd->max_frame_size);
1912 }
1913 }
1914 return 0;
1915}
1916
1917/*
1918 * usbvideo_CollectRawData()
1919 *
1920 * This procedure can be used instead of 'processData' callback if you
1921 * only want to dump the raw data from the camera into the output
1922 * device (frame buffer). You can look at it with V4L client, but the
1923 * image will be unwatchable. The main purpose of this code and of the
1924 * mode FLAGS_NO_DECODING is debugging and capturing of datastreams from
1925 * new, unknown cameras. This procedure will be automatically invoked
1926 * instead of the specified callback handler when uvd->flags has bit
1927 * FLAGS_NO_DECODING set. Therefore, any regular build of any driver
1928 * based on usbvideo can use this feature at any time.
1929 */
1930static void usbvideo_CollectRawData(struct uvd *uvd, struct usbvideo_frame *frame)
1931{
1932 int n;
1933
1934 assert(uvd != NULL);
1935 assert(frame != NULL);
1936
1937 /* Try to move data from queue into frame buffer */
1938 n = RingQueue_GetLength(&uvd->dp);
1939 if (n > 0) {
1940 int m;
1941 /* See how much space we have left */
1942 m = uvd->max_frame_size - frame->seqRead_Length;
1943 if (n > m)
1944 n = m;
1945 /* Now move that much data into frame buffer */
1946 RingQueue_Dequeue(
1947 &uvd->dp,
1948 frame->data + frame->seqRead_Length,
1949 m);
1950 frame->seqRead_Length += m;
1951 }
1952 /* See if we filled the frame */
1953 if (frame->seqRead_Length >= uvd->max_frame_size) {
1954 frame->frameState = FrameState_Done;
1955 uvd->curframe = -1;
1956 uvd->stats.frame_num++;
1957 }
1958}
1959
1960static int usbvideo_GetFrame(struct uvd *uvd, int frameNum)
1961{
1962 struct usbvideo_frame *frame = &uvd->frame[frameNum];
1963
1964 if (uvd->debug >= 2)
1965 info("%s($%p,%d.)", __FUNCTION__, uvd, frameNum);
1966
1967 switch (frame->frameState) {
1968 case FrameState_Unused:
1969 if (uvd->debug >= 2)
1970 info("%s: FrameState_Unused", __FUNCTION__);
1971 return -EINVAL;
1972 case FrameState_Ready:
1973 case FrameState_Grabbing:
1974 case FrameState_Error:
1975 {
1976 int ntries, signalPending;
1977 redo:
1978 if (!CAMERA_IS_OPERATIONAL(uvd)) {
1979 if (uvd->debug >= 2)
1980 info("%s: Camera is not operational (1)", __FUNCTION__);
1981 return -EIO;
1982 }
1983 ntries = 0;
1984 do {
1985 RingQueue_InterruptibleSleepOn(&uvd->dp);
1986 signalPending = signal_pending(current);
1987 if (!CAMERA_IS_OPERATIONAL(uvd)) {
1988 if (uvd->debug >= 2)
1989 info("%s: Camera is not operational (2)", __FUNCTION__);
1990 return -EIO;
1991 }
1992 assert(uvd->fbuf != NULL);
1993 if (signalPending) {
1994 if (uvd->debug >= 2)
1995 info("%s: Signal=$%08x", __FUNCTION__, signalPending);
1996 if (uvd->flags & FLAGS_RETRY_VIDIOCSYNC) {
1997 usbvideo_TestPattern(uvd, 1, 0);
1998 uvd->curframe = -1;
1999 uvd->stats.frame_num++;
2000 if (uvd->debug >= 2)
2001 info("%s: Forced test pattern screen", __FUNCTION__);
2002 return 0;
2003 } else {
2004 /* Standard answer: Interrupted! */
2005 if (uvd->debug >= 2)
2006 info("%s: Interrupted!", __FUNCTION__);
2007 return -EINTR;
2008 }
2009 } else {
2010 /* No signals - we just got new data in dp queue */
2011 if (uvd->flags & FLAGS_NO_DECODING)
2012 usbvideo_CollectRawData(uvd, frame);
2013 else if (VALID_CALLBACK(uvd, processData))
2014 GET_CALLBACK(uvd, processData)(uvd, frame);
2015 else
2016 err("%s: processData not set", __FUNCTION__);
2017 }
2018 } while (frame->frameState == FrameState_Grabbing);
2019 if (uvd->debug >= 2) {
2020 info("%s: Grabbing done; state=%d. (%lu. bytes)",
2021 __FUNCTION__, frame->frameState, frame->seqRead_Length);
2022 }
2023 if (frame->frameState == FrameState_Error) {
2024 int ret = usbvideo_NewFrame(uvd, frameNum);
2025 if (ret < 0) {
2026 err("%s: usbvideo_NewFrame() failed (%d.)", __FUNCTION__, ret);
2027 return ret;
2028 }
2029 goto redo;
2030 }
2031 /* Note that we fall through to meet our destiny below */
2032 }
2033 case FrameState_Done:
2034 /*
2035 * Do all necessary postprocessing of data prepared in
2036 * "interrupt" code and the collecting code above. The
2037 * frame gets marked as FrameState_Done by queue parsing code.
2038 * This status means that we collected enough data and
2039 * most likely processed it as we went through. However
2040 * the data may need postprocessing, such as deinterlacing
2041 * or picture adjustments implemented in software (horror!)
2042 *
2043 * As soon as the frame becomes "final" it gets promoted to
2044 * FrameState_Done_Hold status where it will remain until the
2045 * caller consumed all the video data from the frame. Then
2046 * the empty shell of ex-frame is thrown out for dogs to eat.
2047 * But we, worried about pets, will recycle the frame!
2048 */
2049 uvd->stats.frame_num++;
2050 if ((uvd->flags & FLAGS_NO_DECODING) == 0) {
2051 if (VALID_CALLBACK(uvd, postProcess))
2052 GET_CALLBACK(uvd, postProcess)(uvd, frame);
2053 if (frame->flags & USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST)
2054 usbvideo_SoftwareContrastAdjustment(uvd, frame);
2055 }
2056 frame->frameState = FrameState_Done_Hold;
2057 if (uvd->debug >= 2)
2058 info("%s: Entered FrameState_Done_Hold state.", __FUNCTION__);
2059 return 0;
2060
2061 case FrameState_Done_Hold:
2062 /*
2063 * We stay in this state indefinitely until someone external,
2064 * like ioctl() or read() call finishes digesting the frame
2065 * data. Then it will mark the frame as FrameState_Unused and
2066 * it will be released back into the wild to roam freely.
2067 */
2068 if (uvd->debug >= 2)
2069 info("%s: FrameState_Done_Hold state.", __FUNCTION__);
2070 return 0;
2071 }
2072
2073 /* Catch-all for other cases. We shall not be here. */
2074 err("%s: Invalid state %d.", __FUNCTION__, frame->frameState);
2075 frame->frameState = FrameState_Unused;
2076 return 0;
2077}
2078
2079/*
2080 * usbvideo_DeinterlaceFrame()
2081 *
2082 * This procedure deinterlaces the given frame. Some cameras produce
2083 * only half of scanlines - sometimes only even lines, sometimes only
2084 * odd lines. The deinterlacing method is stored in frame->deinterlace
2085 * variable.
2086 *
2087 * Here we scan the frame vertically and replace missing scanlines with
2088 * average between surrounding ones - before and after. If we have no
2089 * line above then we just copy next line. Similarly, if we need to
2090 * create a last line then preceding line is used.
2091 */
2092void usbvideo_DeinterlaceFrame(struct uvd *uvd, struct usbvideo_frame *frame)
2093{
2094 if ((uvd == NULL) || (frame == NULL))
2095 return;
2096
2097 if ((frame->deinterlace == Deinterlace_FillEvenLines) ||
2098 (frame->deinterlace == Deinterlace_FillOddLines))
2099 {
2100 const int v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
2101 int i = (frame->deinterlace == Deinterlace_FillEvenLines) ? 0 : 1;
2102
2103 for (; i < VIDEOSIZE_Y(frame->request); i += 2) {
2104 const unsigned char *fs1, *fs2;
2105 unsigned char *fd;
2106 int ip, in, j; /* Previous and next lines */
2107
2108 /*
2109 * Need to average lines before and after 'i'.
2110 * If we go out of bounds seeking those lines then
2111 * we point back to existing line.
2112 */
2113 ip = i - 1; /* First, get rough numbers */
2114 in = i + 1;
2115
2116 /* Now validate */
2117 if (ip < 0)
2118 ip = in;
2119 if (in >= VIDEOSIZE_Y(frame->request))
2120 in = ip;
2121
2122 /* Sanity check */
2123 if ((ip < 0) || (in < 0) ||
2124 (ip >= VIDEOSIZE_Y(frame->request)) ||
2125 (in >= VIDEOSIZE_Y(frame->request)))
2126 {
2127 err("Error: ip=%d. in=%d. req.height=%ld.",
2128 ip, in, VIDEOSIZE_Y(frame->request));
2129 break;
2130 }
2131
2132 /* Now we need to average lines 'ip' and 'in' to produce line 'i' */
2133 fs1 = frame->data + (v4l_linesize * ip);
2134 fs2 = frame->data + (v4l_linesize * in);
2135 fd = frame->data + (v4l_linesize * i);
2136
2137 /* Average lines around destination */
2138 for (j=0; j < v4l_linesize; j++) {
2139 fd[j] = (unsigned char)((((unsigned) fs1[j]) +
2140 ((unsigned)fs2[j])) >> 1);
2141 }
2142 }
2143 }
2144
2145 /* Optionally display statistics on the screen */
2146 if (uvd->flags & FLAGS_OVERLAY_STATS)
2147 usbvideo_OverlayStats(uvd, frame);
2148}
2149
2150EXPORT_SYMBOL(usbvideo_DeinterlaceFrame);
2151
2152/*
2153 * usbvideo_SoftwareContrastAdjustment()
2154 *
2155 * This code adjusts the contrast of the frame, assuming RGB24 format.
2156 * As most software image processing, this job is CPU-intensive.
2157 * Get a camera that supports hardware adjustment!
2158 *
2159 * History:
2160 * 09-Feb-2001 Created.
2161 */
2162static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd,
2163 struct usbvideo_frame *frame)
2164{
2165 int i, j, v4l_linesize;
2166 signed long adj;
2167 const int ccm = 128; /* Color correction median - see below */
2168
2169 if ((uvd == NULL) || (frame == NULL)) {
2170 err("%s: Illegal call.", __FUNCTION__);
2171 return;
2172 }
2173 adj = (uvd->vpic.contrast - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
2174 RESTRICT_TO_RANGE(adj, -ccm, ccm+1);
2175 if (adj == 0) {
2176 /* In rare case of no adjustment */
2177 return;
2178 }
2179 v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
2180 for (i=0; i < VIDEOSIZE_Y(frame->request); i++) {
2181 unsigned char *fd = frame->data + (v4l_linesize * i);
2182 for (j=0; j < v4l_linesize; j++) {
2183 signed long v = (signed long) fd[j];
2184 /* Magnify up to 2 times, reduce down to zero */
2185 v = 128 + ((ccm + adj) * (v - 128)) / ccm;
2186 RESTRICT_TO_RANGE(v, 0, 0xFF); /* Must flatten tails */
2187 fd[j] = (unsigned char) v;
2188 }
2189 }
2190}
2191
2192MODULE_LICENSE("GPL");
diff --git a/drivers/usb/media/usbvideo.h b/drivers/usb/media/usbvideo.h
new file mode 100644
index 000000000000..6c390a1f981b
--- /dev/null
+++ b/drivers/usb/media/usbvideo.h
@@ -0,0 +1,393 @@
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/config.h>
20#include <linux/videodev.h>
21#include <linux/usb.h>
22
23/* Most helpful debugging aid */
24#define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__))))
25
26#define USBVIDEO_REPORT_STATS 1 /* Set to 0 to block statistics on close */
27
28/* Bit flags (options) */
29#define FLAGS_RETRY_VIDIOCSYNC (1 << 0)
30#define FLAGS_MONOCHROME (1 << 1)
31#define FLAGS_DISPLAY_HINTS (1 << 2)
32#define FLAGS_OVERLAY_STATS (1 << 3)
33#define FLAGS_FORCE_TESTPATTERN (1 << 4)
34#define FLAGS_SEPARATE_FRAMES (1 << 5)
35#define FLAGS_CLEAN_FRAMES (1 << 6)
36#define FLAGS_NO_DECODING (1 << 7)
37
38/* Bit flags for frames (apply to the frame where they are specified) */
39#define USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST (1 << 0)
40
41/* Camera capabilities (maximum) */
42#define CAMERA_URB_FRAMES 32
43#define CAMERA_MAX_ISO_PACKET 1023 /* 1022 actually sent by camera */
44#define FRAMES_PER_DESC (CAMERA_URB_FRAMES)
45#define FRAME_SIZE_PER_DESC (CAMERA_MAX_ISO_PACKET)
46
47/* This macro restricts an int variable to an inclusive range */
48#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
49
50#define V4L_BYTES_PER_PIXEL 3 /* Because we produce RGB24 */
51
52/*
53 * Use this macro to construct constants for different video sizes.
54 * We have to deal with different video sizes that have to be
55 * configured in the device or compared against when we receive
56 * a data. Normally one would define a bunch of VIDEOSIZE_x_by_y
57 * #defines and that's the end of story. However this solution
58 * does not allow to convert between real pixel sizes and the
59 * constant (integer) value that may be used to tag a frame or
60 * whatever. The set of macros below constructs videosize constants
61 * from the pixel size and allows to reconstruct the pixel size
62 * from the combined value later.
63 */
64#define VIDEOSIZE(x,y) (((x) & 0xFFFFL) | (((y) & 0xFFFFL) << 16))
65#define VIDEOSIZE_X(vs) ((vs) & 0xFFFFL)
66#define VIDEOSIZE_Y(vs) (((vs) >> 16) & 0xFFFFL)
67typedef unsigned long videosize_t;
68
69/*
70 * This macro checks if the camera is still operational. The 'uvd'
71 * pointer must be valid, uvd->dev must be valid, we are not
72 * removing the device and the device has not erred on us.
73 */
74#define CAMERA_IS_OPERATIONAL(uvd) (\
75 (uvd != NULL) && \
76 ((uvd)->dev != NULL) && \
77 ((uvd)->last_error == 0) && \
78 (!(uvd)->remove_pending))
79
80/*
81 * We use macros to do YUV -> RGB conversion because this is
82 * very important for speed and totally unimportant for size.
83 *
84 * YUV -> RGB Conversion
85 * ---------------------
86 *
87 * B = 1.164*(Y-16) + 2.018*(V-128)
88 * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128)
89 * R = 1.164*(Y-16) + 1.596*(U-128)
90 *
91 * If you fancy integer arithmetics (as you should), hear this:
92 *
93 * 65536*B = 76284*(Y-16) + 132252*(V-128)
94 * 65536*G = 76284*(Y-16) - 53281*(U-128) - 25625*(V-128)
95 * 65536*R = 76284*(Y-16) + 104595*(U-128)
96 *
97 * Make sure the output values are within [0..255] range.
98 */
99#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
100#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \
101 int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
102 mm_y = (my) - 16; \
103 mm_u = (mu) - 128; \
104 mm_v = (mv) - 128; \
105 mm_yc= mm_y * 76284; \
106 mm_b = (mm_yc + 132252*mm_v ) >> 16; \
107 mm_g = (mm_yc - 53281*mm_u - 25625*mm_v ) >> 16; \
108 mm_r = (mm_yc + 104595*mm_u ) >> 16; \
109 mb = LIMIT_RGB(mm_b); \
110 mg = LIMIT_RGB(mm_g); \
111 mr = LIMIT_RGB(mm_r); \
112}
113
114#define RING_QUEUE_SIZE (128*1024) /* Must be a power of 2 */
115#define RING_QUEUE_ADVANCE_INDEX(rq,ind,n) (rq)->ind = ((rq)->ind + (n)) & ((rq)->length-1)
116#define RING_QUEUE_DEQUEUE_BYTES(rq,n) RING_QUEUE_ADVANCE_INDEX(rq,ri,n)
117#define RING_QUEUE_PEEK(rq,ofs) ((rq)->queue[((ofs) + (rq)->ri) & ((rq)->length-1)])
118
119struct RingQueue {
120 unsigned char *queue; /* Data from the Isoc data pump */
121 int length; /* How many bytes allocated for the queue */
122 int wi; /* That's where we write */
123 int ri; /* Read from here until you hit write index */
124 wait_queue_head_t wqh; /* Processes waiting */
125};
126
127enum ScanState {
128 ScanState_Scanning, /* Scanning for header */
129 ScanState_Lines /* Parsing lines */
130};
131
132/* Completion states of the data parser */
133enum ParseState {
134 scan_Continue, /* Just parse next item */
135 scan_NextFrame, /* Frame done, send it to V4L */
136 scan_Out, /* Not enough data for frame */
137 scan_EndParse /* End parsing */
138};
139
140enum FrameState {
141 FrameState_Unused, /* Unused (no MCAPTURE) */
142 FrameState_Ready, /* Ready to start grabbing */
143 FrameState_Grabbing, /* In the process of being grabbed into */
144 FrameState_Done, /* Finished grabbing, but not been synced yet */
145 FrameState_Done_Hold, /* Are syncing or reading */
146 FrameState_Error, /* Something bad happened while processing */
147};
148
149/*
150 * Some frames may contain only even or odd lines. This type
151 * specifies what type of deinterlacing is required.
152 */
153enum Deinterlace {
154 Deinterlace_None=0,
155 Deinterlace_FillOddLines,
156 Deinterlace_FillEvenLines
157};
158
159#define USBVIDEO_NUMFRAMES 2 /* How many frames we work with */
160#define USBVIDEO_NUMSBUF 2 /* How many URBs linked in a ring */
161
162/* This structure represents one Isoc request - URB and buffer */
163struct usbvideo_sbuf {
164 char *data;
165 struct urb *urb;
166};
167
168struct usbvideo_frame {
169 char *data; /* Frame buffer */
170 unsigned long header; /* Significant bits from the header */
171
172 videosize_t canvas; /* The canvas (max. image) allocated */
173 videosize_t request; /* That's what the application asked for */
174 unsigned short palette; /* The desired format */
175
176 enum FrameState frameState;/* State of grabbing */
177 enum ScanState scanstate; /* State of scanning */
178 enum Deinterlace deinterlace;
179 int flags; /* USBVIDEO_FRAME_FLAG_xxx bit flags */
180
181 int curline; /* Line of frame we're working on */
182
183 long seqRead_Length; /* Raw data length of frame */
184 long seqRead_Index; /* Amount of data that has been already read */
185
186 void *user; /* Additional data that user may need */
187};
188
189/* Statistics that can be overlaid on screen */
190struct usbvideo_statistics {
191 unsigned long frame_num; /* Sequential number of the frame */
192 unsigned long urb_count; /* How many URBs we received so far */
193 unsigned long urb_length; /* Length of last URB */
194 unsigned long data_count; /* How many bytes we received */
195 unsigned long header_count; /* How many frame headers we found */
196 unsigned long iso_skip_count; /* How many empty ISO packets received */
197 unsigned long iso_err_count; /* How many bad ISO packets received */
198};
199
200struct usbvideo;
201
202struct uvd {
203 struct video_device vdev; /* Must be the first field! */
204 struct usb_device *dev;
205 struct usbvideo *handle; /* Points back to the struct usbvideo */
206 void *user_data; /* Camera-dependent data */
207 int user_size; /* Size of that camera-dependent data */
208 int debug; /* Debug level for usbvideo */
209 unsigned char iface; /* Video interface number */
210 unsigned char video_endp;
211 unsigned char ifaceAltActive;
212 unsigned char ifaceAltInactive; /* Alt settings */
213 unsigned long flags; /* FLAGS_USBVIDEO_xxx */
214 unsigned long paletteBits; /* Which palettes we accept? */
215 unsigned short defaultPalette; /* What palette to use for read() */
216 struct semaphore lock;
217 int user; /* user count for exclusive use */
218
219 videosize_t videosize; /* Current setting */
220 videosize_t canvas; /* This is the width,height of the V4L canvas */
221 int max_frame_size; /* Bytes in one video frame */
222
223 int uvd_used; /* Is this structure in use? */
224 int streaming; /* Are we streaming Isochronous? */
225 int grabbing; /* Are we grabbing? */
226 int settingsAdjusted; /* Have we adjusted contrast etc.? */
227 int last_error; /* What calamity struck us? */
228
229 char *fbuf; /* Videodev buffer area */
230 int fbuf_size; /* Videodev buffer size */
231
232 int curframe;
233 int iso_packet_len; /* Videomode-dependent, saves bus bandwidth */
234
235 struct RingQueue dp; /* Isoc data pump */
236 struct usbvideo_frame frame[USBVIDEO_NUMFRAMES];
237 struct usbvideo_sbuf sbuf[USBVIDEO_NUMSBUF];
238
239 volatile int remove_pending; /* If set then about to exit */
240
241 struct video_picture vpic, vpic_old; /* Picture settings */
242 struct video_capability vcap; /* Video capabilities */
243 struct video_channel vchan; /* May be used for tuner support */
244 struct usbvideo_statistics stats;
245 char videoName[32]; /* Holds name like "video7" */
246};
247
248/*
249 * usbvideo callbacks (virtual methods). They are set when usbvideo
250 * services are registered. All of these default to NULL, except those
251 * that default to usbvideo-provided methods.
252 */
253struct usbvideo_cb {
254 int (*probe)(struct usb_interface *, const struct usb_device_id *);
255 void (*userFree)(struct uvd *);
256 void (*disconnect)(struct usb_interface *);
257 int (*setupOnOpen)(struct uvd *);
258 void (*videoStart)(struct uvd *);
259 void (*videoStop)(struct uvd *);
260 void (*processData)(struct uvd *, struct usbvideo_frame *);
261 void (*postProcess)(struct uvd *, struct usbvideo_frame *);
262 void (*adjustPicture)(struct uvd *);
263 int (*getFPS)(struct uvd *);
264 int (*overlayHook)(struct uvd *, struct usbvideo_frame *);
265 int (*getFrame)(struct uvd *, int);
266 int (*startDataPump)(struct uvd *uvd);
267 void (*stopDataPump)(struct uvd *uvd);
268 int (*setVideoMode)(struct uvd *uvd, struct video_window *vw);
269};
270
271struct usbvideo {
272 int num_cameras; /* As allocated */
273 struct usb_driver usbdrv; /* Interface to the USB stack */
274 char drvName[80]; /* Driver name */
275 struct semaphore lock; /* Mutex protecting camera structures */
276 struct usbvideo_cb cb; /* Table of callbacks (virtual methods) */
277 struct video_device vdt; /* Video device template */
278 struct uvd *cam; /* Array of camera structures */
279 struct module *md_module; /* Minidriver module */
280};
281
282
283/*
284 * This macro retrieves callback address from the struct uvd object.
285 * No validity checks are done here, so be sure to check the
286 * callback beforehand with VALID_CALLBACK.
287 */
288#define GET_CALLBACK(uvd,cbName) ((uvd)->handle->cb.cbName)
289
290/*
291 * This macro returns either callback pointer or NULL. This is safe
292 * macro, meaning that most of components of data structures involved
293 * may be NULL - this only results in NULL being returned. You may
294 * wish to use this macro to make sure that the callback is callable.
295 * However keep in mind that those checks take time.
296 */
297#define VALID_CALLBACK(uvd,cbName) ((((uvd) != NULL) && \
298 ((uvd)->handle != NULL)) ? GET_CALLBACK(uvd,cbName) : NULL)
299
300int RingQueue_Dequeue(struct RingQueue *rq, unsigned char *dst, int len);
301int RingQueue_Enqueue(struct RingQueue *rq, const unsigned char *cdata, int n);
302void RingQueue_WakeUpInterruptible(struct RingQueue *rq);
303void RingQueue_Flush(struct RingQueue *rq);
304
305static inline int RingQueue_GetLength(const struct RingQueue *rq)
306{
307 return (rq->wi - rq->ri + rq->length) & (rq->length-1);
308}
309
310static inline int RingQueue_GetFreeSpace(const struct RingQueue *rq)
311{
312 return rq->length - RingQueue_GetLength(rq);
313}
314
315void usbvideo_DrawLine(
316 struct usbvideo_frame *frame,
317 int x1, int y1,
318 int x2, int y2,
319 unsigned char cr, unsigned char cg, unsigned char cb);
320void usbvideo_HexDump(const unsigned char *data, int len);
321void usbvideo_SayAndWait(const char *what);
322void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode);
323
324/* Memory allocation routines */
325unsigned long usbvideo_kvirt_to_pa(unsigned long adr);
326
327int usbvideo_register(
328 struct usbvideo **pCams,
329 const int num_cams,
330 const int num_extra,
331 const char *driverName,
332 const struct usbvideo_cb *cbTable,
333 struct module *md,
334 const struct usb_device_id *id_table);
335struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams);
336int usbvideo_RegisterVideoDevice(struct uvd *uvd);
337void usbvideo_Deregister(struct usbvideo **uvt);
338
339int usbvideo_v4l_initialize(struct video_device *dev);
340
341void usbvideo_DeinterlaceFrame(struct uvd *uvd, struct usbvideo_frame *frame);
342
343/*
344 * This code performs bounds checking - use it when working with
345 * new formats, or else you may get oopses all over the place.
346 * If pixel falls out of bounds then it gets shoved back (as close
347 * to place of offence as possible) and is painted bright red.
348 *
349 * There are two important concepts: frame width, height and
350 * V4L canvas width, height. The former is the area requested by
351 * the application -for this very frame-. The latter is the largest
352 * possible frame that we can serve (we advertise that via V4L ioctl).
353 * The frame data is expected to be formatted as lines of length
354 * VIDEOSIZE_X(fr->request), total VIDEOSIZE_Y(frame->request) lines.
355 */
356static inline void RGB24_PUTPIXEL(
357 struct usbvideo_frame *fr,
358 int ix, int iy,
359 unsigned char vr,
360 unsigned char vg,
361 unsigned char vb)
362{
363 register unsigned char *pf;
364 int limiter = 0, mx, my;
365 mx = ix;
366 my = iy;
367 if (mx < 0) {
368 mx=0;
369 limiter++;
370 } else if (mx >= VIDEOSIZE_X((fr)->request)) {
371 mx= VIDEOSIZE_X((fr)->request) - 1;
372 limiter++;
373 }
374 if (my < 0) {
375 my = 0;
376 limiter++;
377 } else if (my >= VIDEOSIZE_Y((fr)->request)) {
378 my = VIDEOSIZE_Y((fr)->request) - 1;
379 limiter++;
380 }
381 pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*VIDEOSIZE_X((fr)->request) + (ix));
382 if (limiter) {
383 *pf++ = 0;
384 *pf++ = 0;
385 *pf++ = 0xFF;
386 } else {
387 *pf++ = (vb);
388 *pf++ = (vg);
389 *pf++ = (vr);
390 }
391}
392
393#endif /* usbvideo_h */
diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
new file mode 100644
index 000000000000..4a5857c53f11
--- /dev/null
+++ b/drivers/usb/media/vicam.c
@@ -0,0 +1,1409 @@
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@suse.cz),
6 * John Tyner (jtyner@cs.ucr.edu),
7 * Monroe Williams (monroe@pobox.com)
8 *
9 * Supports 3COM HomeConnect PC Digital WebCam
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 as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * This source code is based heavily on the CPiA webcam driver which was
26 * written by Peter Pregler, Scott J. Bertin and Johannes Erdfelt
27 *
28 * Portions of this code were also copied from usbvideo.c
29 *
30 * Special thanks to the the whole team at Sourceforge for help making
31 * this driver become a reality. Notably:
32 * Andy Armstrong who reverse engineered the color encoding and
33 * Pavel Machek and Chris Cheney who worked on reverse engineering the
34 * camera controls and wrote the first generation driver.
35 */
36
37#include <linux/kernel.h>
38#include <linux/module.h>
39#include <linux/init.h>
40#include <linux/videodev.h>
41#include <linux/usb.h>
42#include <linux/vmalloc.h>
43#include <linux/slab.h>
44#include <linux/proc_fs.h>
45#include "usbvideo.h"
46
47// #define VICAM_DEBUG
48
49#ifdef VICAM_DEBUG
50#define ADBG(lineno,fmt,args...) printk(fmt, jiffies, __FUNCTION__, lineno, ##args)
51#define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt,##args)
52#else
53#define DBG(fmn,args...) do {} while(0)
54#endif
55
56#define DRIVER_AUTHOR "Joe Burks, jburks@wavicle.org"
57#define DRIVER_DESC "ViCam WebCam Driver"
58
59/* Define these values to match your device */
60#define USB_VICAM_VENDOR_ID 0x04c1
61#define USB_VICAM_PRODUCT_ID 0x009d
62
63#define VICAM_BYTES_PER_PIXEL 3
64#define VICAM_MAX_READ_SIZE (512*242+128)
65#define VICAM_MAX_FRAME_SIZE (VICAM_BYTES_PER_PIXEL*320*240)
66#define VICAM_FRAMES 2
67
68#define VICAM_HEADER_SIZE 64
69
70#define clamp( x, l, h ) max_t( __typeof__( x ), \
71 ( l ), \
72 min_t( __typeof__( x ), \
73 ( h ), \
74 ( x ) ) )
75
76/* Not sure what all the bytes in these char
77 * arrays do, but they're necessary to make
78 * the camera work.
79 */
80
81static unsigned char setup1[] = {
82 0xB6, 0xC3, 0x1F, 0x00, 0x02, 0x64, 0xE7, 0x67,
83 0xFD, 0xFF, 0x0E, 0xC0, 0xE7, 0x09, 0xDE, 0x00,
84 0x8E, 0x00, 0xC0, 0x09, 0x40, 0x03, 0xC0, 0x17,
85 0x44, 0x03, 0x4B, 0xAF, 0xC0, 0x07, 0x00, 0x00,
86 0x4B, 0xAF, 0x97, 0xCF, 0x00, 0x00
87};
88
89static unsigned char setup2[] = {
90 0xB6, 0xC3, 0x03, 0x00, 0x03, 0x64, 0x18, 0x00,
91 0x00, 0x00
92};
93
94static unsigned char setup3[] = {
95 0xB6, 0xC3, 0x01, 0x00, 0x06, 0x64, 0x00, 0x00
96};
97
98static unsigned char setup4[] = {
99 0xB6, 0xC3, 0x8F, 0x06, 0x02, 0x64, 0xE7, 0x07,
100 0x00, 0x00, 0x08, 0xC0, 0xE7, 0x07, 0x00, 0x00,
101 0x3E, 0xC0, 0xE7, 0x07, 0x54, 0x01, 0xAA, 0x00,
102 0xE7, 0x07, 0xC8, 0x05, 0xB6, 0x00, 0xE7, 0x07,
103 0x42, 0x01, 0xD2, 0x00, 0xE7, 0x07, 0x7C, 0x00,
104 0x16, 0x00, 0xE7, 0x07, 0x56, 0x00, 0x18, 0x00,
105 0xE7, 0x07, 0x06, 0x00, 0x92, 0xC0, 0xE7, 0x07,
106 0x00, 0x00, 0x1E, 0xC0, 0xE7, 0x07, 0xFF, 0xFF,
107 0x22, 0xC0, 0xE7, 0x07, 0x04, 0x00, 0x24, 0xC0,
108 0xE7, 0x07, 0xEC, 0x27, 0x28, 0xC0, 0xE7, 0x07,
109 0x16, 0x01, 0x8E, 0x00, 0xE7, 0x87, 0x01, 0x00,
110 0x0E, 0xC0, 0x97, 0xCF, 0xD7, 0x09, 0x00, 0xC0,
111 0xE7, 0x77, 0x01, 0x00, 0x92, 0xC0, 0x09, 0xC1,
112 0xE7, 0x09, 0xFE, 0x05, 0x24, 0x01, 0xE7, 0x09,
113 0x04, 0x06, 0x26, 0x01, 0xE7, 0x07, 0x07, 0x00,
114 0x92, 0xC0, 0xE7, 0x05, 0x00, 0xC0, 0xC0, 0xDF,
115 0x97, 0xCF, 0x17, 0x00, 0x57, 0x00, 0x17, 0x02,
116 0xD7, 0x09, 0x00, 0xC0, 0xE7, 0x77, 0x01, 0x00,
117 0x92, 0xC0, 0x0A, 0xC1, 0xE7, 0x57, 0xFF, 0xFF,
118 0xFA, 0x05, 0x0D, 0xC0, 0xE7, 0x57, 0x00, 0x00,
119 0xFA, 0x05, 0x0F, 0xC0, 0x9F, 0xAF, 0xC6, 0x00,
120 0xE7, 0x05, 0x00, 0xC0, 0xC8, 0x05, 0xC1, 0x05,
121 0xC0, 0x05, 0xC0, 0xDF, 0x97, 0xCF, 0x27, 0xDA,
122 0xFA, 0x05, 0xEF, 0x07, 0x01, 0x00, 0x0B, 0x06,
123 0x73, 0xCF, 0x9F, 0xAF, 0x78, 0x01, 0x9F, 0xAF,
124 0x1A, 0x03, 0x6E, 0xCF, 0xE7, 0x09, 0xFC, 0x05,
125 0x24, 0x01, 0xE7, 0x09, 0x02, 0x06, 0x26, 0x01,
126 0xE7, 0x07, 0x07, 0x00, 0x92, 0xC0, 0xE7, 0x09,
127 0xFC, 0x05, 0xFE, 0x05, 0xE7, 0x09, 0x02, 0x06,
128 0x04, 0x06, 0xE7, 0x09, 0x00, 0x06, 0xFC, 0x05,
129 0xE7, 0x09, 0xFE, 0x05, 0x00, 0x06, 0x27, 0xDA,
130 0xFA, 0x05, 0xE7, 0x57, 0x01, 0x00, 0xFA, 0x05,
131 0x02, 0xCA, 0x04, 0xC0, 0x97, 0xCF, 0x9F, 0xAF,
132 0x66, 0x05, 0x97, 0xCF, 0xE7, 0x07, 0x40, 0x00,
133 0x02, 0x06, 0xC8, 0x09, 0xFC, 0x05, 0x9F, 0xAF,
134 0xDA, 0x02, 0x97, 0xCF, 0xCF, 0x17, 0x02, 0x00,
135 0xEF, 0x57, 0x81, 0x00, 0x09, 0x06, 0x9F, 0xA0,
136 0xB6, 0x01, 0xEF, 0x57, 0x80, 0x00, 0x09, 0x06,
137 0x9F, 0xA0, 0x40, 0x02, 0xEF, 0x57, 0x01, 0x00,
138 0x0B, 0x06, 0x9F, 0xA0, 0x46, 0x03, 0xE7, 0x07,
139 0x01, 0x00, 0x0A, 0xC0, 0x46, 0xAF, 0x47, 0xAF,
140 0x9F, 0xAF, 0x40, 0x02, 0xE7, 0x07, 0x2E, 0x00,
141 0x0A, 0xC0, 0xEF, 0x87, 0x80, 0x00, 0x09, 0x06,
142 0x97, 0xCF, 0x00, 0x0E, 0x01, 0x00, 0xC0, 0x57,
143 0x51, 0x00, 0x9F, 0xC0, 0x9E, 0x02, 0xC0, 0x57,
144 0x50, 0x00, 0x20, 0xC0, 0xC0, 0x57, 0x55, 0x00,
145 0x12, 0xC0, 0xC0, 0x57, 0x56, 0x00, 0x9F, 0xC0,
146 0x72, 0x02, 0x9F, 0xCF, 0xD6, 0x02, 0xC1, 0x0B,
147 0x08, 0x06, 0x01, 0xD0, 0x6F, 0x90, 0x08, 0x06,
148 0xC0, 0x07, 0x08, 0x00, 0xC1, 0x0B, 0x08, 0x06,
149 0x9F, 0xAF, 0x28, 0x05, 0x97, 0xCF, 0x2F, 0x0E,
150 0x02, 0x00, 0x08, 0x06, 0xC0, 0x07, 0x08, 0x00,
151 0xC1, 0x0B, 0x08, 0x06, 0x9F, 0xAF, 0x28, 0x05,
152 0x9F, 0xCF, 0xD6, 0x02, 0x2F, 0x0E, 0x02, 0x00,
153 0x09, 0x06, 0xEF, 0x87, 0x80, 0x00, 0x09, 0x06,
154 0x9F, 0xCF, 0xD6, 0x02, 0xEF, 0x67, 0x7F, 0xFF,
155 0x09, 0x06, 0xE7, 0x67, 0xFF, 0xFD, 0x22, 0xC0,
156 0xE7, 0x67, 0xEF, 0xFF, 0x24, 0xC0, 0xE7, 0x87,
157 0x10, 0x00, 0x28, 0xC0, 0x9F, 0xAF, 0xB8, 0x05,
158 0xE7, 0x87, 0xE0, 0x21, 0x24, 0xC0, 0x9F, 0xAF,
159 0xA8, 0x05, 0xE7, 0x87, 0x08, 0x00, 0x24, 0xC0,
160 0xE7, 0x67, 0xDF, 0xFF, 0x24, 0xC0, 0xC8, 0x07,
161 0x0A, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xC1, 0x07,
162 0x01, 0x00, 0x9F, 0xAF, 0x28, 0x05, 0x9F, 0xAF,
163 0xB8, 0x05, 0xC0, 0x07, 0x9E, 0x00, 0x9F, 0xAF,
164 0x44, 0x05, 0xE7, 0x67, 0xFF, 0xFE, 0x24, 0xC0,
165 0xC0, 0x09, 0x20, 0xC0, 0xE7, 0x87, 0x00, 0x01,
166 0x24, 0xC0, 0xC0, 0x77, 0x00, 0x02, 0x0F, 0xC1,
167 0xE7, 0x67, 0xF7, 0xFF, 0x24, 0xC0, 0xE7, 0x67,
168 0xF7, 0xFF, 0x24, 0xC0, 0xE7, 0x87, 0x08, 0x00,
169 0x24, 0xC0, 0x08, 0xDA, 0x5E, 0xC1, 0xEF, 0x07,
170 0x80, 0x00, 0x09, 0x06, 0x97, 0xCF, 0xEF, 0x07,
171 0x01, 0x00, 0x0A, 0x06, 0x97, 0xCF, 0xEF, 0x07,
172 0x00, 0x00, 0x0B, 0x06, 0xEF, 0x07, 0x00, 0x00,
173 0x0A, 0x06, 0xEF, 0x67, 0x7F, 0xFF, 0x09, 0x06,
174 0xEF, 0x07, 0x00, 0x00, 0x0D, 0x06, 0xE7, 0x67,
175 0xEF, 0xFF, 0x28, 0xC0, 0xE7, 0x67, 0x17, 0xD8,
176 0x24, 0xC0, 0xE7, 0x07, 0x00, 0x00, 0x1E, 0xC0,
177 0xE7, 0x07, 0xFF, 0xFF, 0x22, 0xC0, 0x97, 0xCF,
178 0xC8, 0x07, 0x0E, 0x06, 0x9F, 0xAF, 0xDA, 0x02,
179 0xE7, 0x07, 0x00, 0x00, 0xF2, 0x05, 0xE7, 0x07,
180 0x10, 0x00, 0xF6, 0x05, 0xE7, 0x07, 0x0E, 0x06,
181 0xF4, 0x05, 0xE7, 0x07, 0xD6, 0x02, 0xF8, 0x05,
182 0xC8, 0x07, 0xF2, 0x05, 0xC1, 0x07, 0x00, 0x80,
183 0x50, 0xAF, 0x97, 0xCF, 0x2F, 0x0C, 0x02, 0x00,
184 0x07, 0x06, 0x2F, 0x0C, 0x04, 0x00, 0x06, 0x06,
185 0xE7, 0x07, 0x00, 0x00, 0xF2, 0x05, 0xE7, 0x07,
186 0x10, 0x00, 0xF6, 0x05, 0xE7, 0x07, 0xE2, 0x05,
187 0xF4, 0x05, 0xE7, 0x07, 0xCE, 0x02, 0xF8, 0x05,
188 0xC8, 0x07, 0xF2, 0x05, 0xC1, 0x07, 0x00, 0x80,
189 0x51, 0xAF, 0x97, 0xCF, 0x9F, 0xAF, 0x66, 0x04,
190 0x9F, 0xAF, 0x1A, 0x03, 0x59, 0xAF, 0x97, 0xCF,
191 0xC0, 0x07, 0x0E, 0x00, 0xC1, 0x0B, 0x0C, 0x06,
192 0x41, 0xD1, 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07,
193 0x3C, 0x00, 0x9F, 0xAF, 0x44, 0x05, 0x68, 0x00,
194 0xC0, 0x07, 0x3B, 0x00, 0x9F, 0xAF, 0x44, 0x05,
195 0x6F, 0x00, 0x0C, 0x06, 0x68, 0x00, 0xE0, 0x07,
196 0x04, 0x01, 0xE8, 0x0B, 0x0A, 0x06, 0xE8, 0x07,
197 0x00, 0x00, 0xE0, 0x07, 0x00, 0x02, 0xE0, 0x07,
198 0xEC, 0x01, 0xE0, 0x07, 0xFC, 0xFF, 0x97, 0xCF,
199 0xE7, 0x07, 0xFF, 0xFF, 0xFA, 0x05, 0xEF, 0x07,
200 0x00, 0x00, 0x0B, 0x06, 0xE7, 0x07, 0x0E, 0x06,
201 0x24, 0x01, 0xE7, 0x07, 0x0E, 0x06, 0xFE, 0x05,
202 0xE7, 0x07, 0x40, 0x00, 0x26, 0x01, 0xE7, 0x07,
203 0x40, 0x00, 0x04, 0x06, 0xE7, 0x07, 0x07, 0x00,
204 0x92, 0xC0, 0x97, 0xCF, 0xEF, 0x07, 0x02, 0x00,
205 0x0B, 0x06, 0x9F, 0xAF, 0x78, 0x01, 0xEF, 0x77,
206 0x80, 0x00, 0x07, 0x06, 0x9F, 0xC0, 0x14, 0x04,
207 0xEF, 0x77, 0x01, 0x00, 0x07, 0x06, 0x37, 0xC0,
208 0xEF, 0x77, 0x01, 0x00, 0x0D, 0x06, 0x0F, 0xC1,
209 0xEF, 0x07, 0x01, 0x00, 0x0D, 0x06, 0xC0, 0x07,
210 0x02, 0x00, 0xC1, 0x07, 0x30, 0x00, 0x9F, 0xAF,
211 0x28, 0x05, 0xC0, 0x07, 0x01, 0x00, 0xC1, 0x07,
212 0x02, 0x00, 0x9F, 0xAF, 0x28, 0x05, 0xC8, 0x07,
213 0xFF, 0x4F, 0x9F, 0xAF, 0xA8, 0x05, 0xC0, 0x07,
214 0x38, 0x00, 0x9F, 0xAF, 0x44, 0x05, 0xC1, 0x77,
215 0x03, 0x00, 0x02, 0xC1, 0x08, 0xDA, 0x75, 0xC1,
216 0xC1, 0x77, 0x01, 0x00, 0x0A, 0xC1, 0xC0, 0x07,
217 0x01, 0x00, 0xC1, 0x07, 0x02, 0x00, 0x9F, 0xAF,
218 0x28, 0x05, 0xEF, 0x07, 0x01, 0x00, 0x06, 0x06,
219 0x2C, 0xCF, 0xC0, 0x07, 0x01, 0x00, 0xC1, 0x07,
220 0x04, 0x00, 0x9F, 0xAF, 0x28, 0x05, 0xEF, 0x07,
221 0x00, 0x00, 0x06, 0x06, 0x22, 0xCF, 0xEF, 0x07,
222 0x00, 0x00, 0x0D, 0x06, 0xEF, 0x57, 0x01, 0x00,
223 0x06, 0x06, 0x1B, 0xC0, 0xC0, 0x07, 0x01, 0x00,
224 0xC1, 0x07, 0x01, 0x00, 0x9F, 0xAF, 0x28, 0x05,
225 0xC0, 0x07, 0x02, 0x00, 0xC1, 0x07, 0x30, 0x00,
226 0x9F, 0xAF, 0x28, 0x05, 0xC8, 0x07, 0xFF, 0x4F,
227 0x9F, 0xAF, 0xA8, 0x05, 0xC0, 0x07, 0x38, 0x00,
228 0x9F, 0xAF, 0x44, 0x05, 0xC1, 0x67, 0x03, 0x00,
229 0xC1, 0x57, 0x03, 0x00, 0x02, 0xC0, 0x08, 0xDA,
230 0x73, 0xC1, 0xC0, 0x07, 0x02, 0x00, 0xC1, 0x07,
231 0x12, 0x00, 0xEF, 0x57, 0x00, 0x00, 0x06, 0x06,
232 0x02, 0xC0, 0xC1, 0x07, 0x23, 0x00, 0x9F, 0xAF,
233 0x28, 0x05, 0xC0, 0x07, 0x14, 0x00, 0xC1, 0x0B,
234 0xEA, 0x05, 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07,
235 0x3E, 0x00, 0x9F, 0xAF, 0x0A, 0x05, 0xE7, 0x09,
236 0xE4, 0x05, 0xFA, 0x05, 0x27, 0xD8, 0xFA, 0x05,
237 0xE7, 0x07, 0x0E, 0x06, 0xFC, 0x05, 0xE7, 0x07,
238 0x4E, 0x06, 0x00, 0x06, 0xE7, 0x07, 0x40, 0x00,
239 0x02, 0x06, 0x9F, 0xAF, 0x66, 0x05, 0x9F, 0xAF,
240 0xC6, 0x00, 0x97, 0xCF, 0xC1, 0x0B, 0xE2, 0x05,
241 0x41, 0xD0, 0x01, 0xD2, 0xC1, 0x17, 0x23, 0x00,
242 0x9F, 0xAF, 0xDC, 0x04, 0xC0, 0x07, 0x04, 0x00,
243 0xC1, 0x0B, 0xE3, 0x05, 0x9F, 0xAF, 0x28, 0x05,
244 0xC0, 0x07, 0x06, 0x00, 0xC1, 0x09, 0xE6, 0x05,
245 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, 0x07, 0x00,
246 0xC1, 0x09, 0xE6, 0x05, 0xC1, 0xD1, 0x9F, 0xAF,
247 0x28, 0x05, 0xC0, 0x07, 0x0B, 0x00, 0xC1, 0x09,
248 0xE8, 0x05, 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07,
249 0x0C, 0x00, 0xC1, 0x09, 0xE8, 0x05, 0xC1, 0xD1,
250 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, 0x0D, 0x00,
251 0xC1, 0x07, 0x09, 0x00, 0x9F, 0xAF, 0x28, 0x05,
252 0xC0, 0x07, 0x03, 0x00, 0xC1, 0x07, 0x32, 0x00,
253 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, 0x0F, 0x00,
254 0xC1, 0x07, 0x00, 0x00, 0x9F, 0xAF, 0x28, 0x05,
255 0x97, 0xCF, 0xE7, 0x67, 0xFF, 0xD9, 0x24, 0xC0,
256 0xC8, 0x07, 0x0A, 0x00, 0x40, 0x00, 0xC0, 0x67,
257 0x00, 0x02, 0x27, 0x80, 0x24, 0xC0, 0xE7, 0x87,
258 0x00, 0x04, 0x24, 0xC0, 0xE7, 0x67, 0xFF, 0xF9,
259 0x24, 0xC0, 0x01, 0xD2, 0x08, 0xDA, 0x72, 0xC1,
260 0xE7, 0x87, 0x00, 0x20, 0x24, 0xC0, 0x97, 0xCF,
261 0x27, 0x00, 0x1E, 0xC0, 0xE7, 0x87, 0xFF, 0x00,
262 0x22, 0xC0, 0xE7, 0x67, 0x7F, 0xFF, 0x24, 0xC0,
263 0xE7, 0x87, 0x80, 0x00, 0x24, 0xC0, 0xE7, 0x87,
264 0x80, 0x00, 0x24, 0xC0, 0x97, 0xCF, 0x9F, 0xAF,
265 0x0A, 0x05, 0x67, 0x00, 0x1E, 0xC0, 0xE7, 0x67,
266 0xBF, 0xFF, 0x24, 0xC0, 0xE7, 0x87, 0x40, 0x00,
267 0x24, 0xC0, 0xE7, 0x87, 0x40, 0x00, 0x24, 0xC0,
268 0x97, 0xCF, 0x9F, 0xAF, 0x0A, 0x05, 0xE7, 0x67,
269 0x00, 0xFF, 0x22, 0xC0, 0xE7, 0x67, 0xFF, 0xFE,
270 0x24, 0xC0, 0xE7, 0x67, 0xFF, 0xFE, 0x24, 0xC0,
271 0xC1, 0x09, 0x20, 0xC0, 0xE7, 0x87, 0x00, 0x01,
272 0x24, 0xC0, 0x97, 0xCF, 0xC0, 0x07, 0x40, 0x00,
273 0xC8, 0x09, 0xFC, 0x05, 0xE7, 0x67, 0x00, 0xFF,
274 0x22, 0xC0, 0xE7, 0x67, 0xFF, 0xFE, 0x24, 0xC0,
275 0xE7, 0x67, 0xBF, 0xFF, 0x24, 0xC0, 0xE7, 0x67,
276 0xBF, 0xFF, 0x24, 0xC0, 0x00, 0xDA, 0xE8, 0x09,
277 0x20, 0xC0, 0xE7, 0x87, 0x40, 0x00, 0x24, 0xC0,
278 0xE7, 0x87, 0x40, 0x00, 0x24, 0xC0, 0x00, 0xDA,
279 0xE8, 0x09, 0x20, 0xC0, 0x6D, 0xC1, 0xE7, 0x87,
280 0x00, 0x01, 0x24, 0xC0, 0x97, 0xCF, 0xE7, 0x07,
281 0x32, 0x00, 0x12, 0xC0, 0xE7, 0x77, 0x00, 0x80,
282 0x12, 0xC0, 0x7C, 0xC0, 0x97, 0xCF, 0xE7, 0x07,
283 0x20, 0x4E, 0x12, 0xC0, 0xE7, 0x77, 0x00, 0x80,
284 0x12, 0xC0, 0x7C, 0xC0, 0x97, 0xCF, 0x09, 0x02,
285 0x19, 0x00, 0x01, 0x01, 0x00, 0x80, 0x96, 0x09,
286 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
287 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x00,
288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310};
311
312static unsigned char setup5[] = {
313 0xB6, 0xC3, 0x2F, 0x01, 0x03, 0x64, 0x0E, 0x00,
314 0x14, 0x00, 0x1A, 0x00, 0x20, 0x00, 0x26, 0x00,
315 0x4A, 0x00, 0x64, 0x00, 0x6A, 0x00, 0x92, 0x00,
316 0x9A, 0x00, 0xA0, 0x00, 0xB2, 0x00, 0xB8, 0x00,
317 0xBE, 0x00, 0xC2, 0x00, 0xC8, 0x00, 0xCE, 0x00,
318 0xDC, 0x00, 0xDA, 0x00, 0xE2, 0x00, 0xE0, 0x00,
319 0xE8, 0x00, 0xE6, 0x00, 0xEE, 0x00, 0xEC, 0x00,
320 0xF2, 0x00, 0xF8, 0x00, 0x02, 0x01, 0x0A, 0x01,
321 0x0E, 0x01, 0x12, 0x01, 0x1E, 0x01, 0x22, 0x01,
322 0x28, 0x01, 0x2C, 0x01, 0x32, 0x01, 0x36, 0x01,
323 0x44, 0x01, 0x50, 0x01, 0x5E, 0x01, 0x72, 0x01,
324 0x76, 0x01, 0x7A, 0x01, 0x80, 0x01, 0x88, 0x01,
325 0x8C, 0x01, 0x94, 0x01, 0x9C, 0x01, 0xA0, 0x01,
326 0xA4, 0x01, 0xAA, 0x01, 0xB0, 0x01, 0xB4, 0x01,
327 0xBA, 0x01, 0xD0, 0x01, 0xDA, 0x01, 0xF6, 0x01,
328 0xFA, 0x01, 0x02, 0x02, 0x34, 0x02, 0x3C, 0x02,
329 0x44, 0x02, 0x4A, 0x02, 0x50, 0x02, 0x56, 0x02,
330 0x74, 0x02, 0x78, 0x02, 0x7E, 0x02, 0x84, 0x02,
331 0x8A, 0x02, 0x88, 0x02, 0x90, 0x02, 0x8E, 0x02,
332 0x94, 0x02, 0xA2, 0x02, 0xA8, 0x02, 0xAE, 0x02,
333 0xB4, 0x02, 0xBA, 0x02, 0xB8, 0x02, 0xC0, 0x02,
334 0xBE, 0x02, 0xC4, 0x02, 0xD0, 0x02, 0xD4, 0x02,
335 0xE0, 0x02, 0xE6, 0x02, 0xEE, 0x02, 0xF8, 0x02,
336 0xFC, 0x02, 0x06, 0x03, 0x1E, 0x03, 0x24, 0x03,
337 0x28, 0x03, 0x30, 0x03, 0x2E, 0x03, 0x3C, 0x03,
338 0x4A, 0x03, 0x4E, 0x03, 0x54, 0x03, 0x58, 0x03,
339 0x5E, 0x03, 0x66, 0x03, 0x6E, 0x03, 0x7A, 0x03,
340 0x86, 0x03, 0x8E, 0x03, 0x96, 0x03, 0xB2, 0x03,
341 0xB8, 0x03, 0xC6, 0x03, 0xCC, 0x03, 0xD4, 0x03,
342 0xDA, 0x03, 0xE8, 0x03, 0xF4, 0x03, 0xFC, 0x03,
343 0x04, 0x04, 0x20, 0x04, 0x2A, 0x04, 0x32, 0x04,
344 0x36, 0x04, 0x3E, 0x04, 0x44, 0x04, 0x42, 0x04,
345 0x48, 0x04, 0x4E, 0x04, 0x4C, 0x04, 0x54, 0x04,
346 0x52, 0x04, 0x5A, 0x04, 0x5E, 0x04, 0x62, 0x04,
347 0x68, 0x04, 0x74, 0x04, 0x7C, 0x04, 0x80, 0x04,
348 0x88, 0x04, 0x8C, 0x04, 0x94, 0x04, 0x9A, 0x04,
349 0xA2, 0x04, 0xA6, 0x04, 0xAE, 0x04, 0xB4, 0x04,
350 0xC0, 0x04, 0xCC, 0x04, 0xD8, 0x04, 0x2A, 0x05,
351 0x46, 0x05, 0x6C, 0x05, 0x00, 0x00
352};
353
354/* rvmalloc / rvfree copied from usbvideo.c
355 *
356 * Not sure why these are not yet non-statics which I can reference through
357 * usbvideo.h the same as it is in 2.4.20. I bet this will get fixed sometime
358 * in the future.
359 *
360*/
361static void *rvmalloc(unsigned long size)
362{
363 void *mem;
364 unsigned long adr;
365
366 size = PAGE_ALIGN(size);
367 mem = vmalloc_32(size);
368 if (!mem)
369 return NULL;
370
371 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
372 adr = (unsigned long) mem;
373 while (size > 0) {
374 SetPageReserved(vmalloc_to_page((void *)adr));
375 adr += PAGE_SIZE;
376 size -= PAGE_SIZE;
377 }
378
379 return mem;
380}
381
382static void rvfree(void *mem, unsigned long size)
383{
384 unsigned long adr;
385
386 if (!mem)
387 return;
388
389 adr = (unsigned long) mem;
390 while ((long) size > 0) {
391 ClearPageReserved(vmalloc_to_page((void *)adr));
392 adr += PAGE_SIZE;
393 size -= PAGE_SIZE;
394 }
395 vfree(mem);
396}
397
398struct vicam_camera {
399 u16 shutter_speed; // capture shutter speed
400 u16 gain; // capture gain
401
402 u8 *raw_image; // raw data captured from the camera
403 u8 *framebuf; // processed data in RGB24 format
404 u8 *cntrlbuf; // area used to send control msgs
405
406 struct video_device vdev; // v4l video device
407 struct usb_device *udev; // usb device
408
409 /* guard against simultaneous accesses to the camera */
410 struct semaphore cam_lock;
411
412 int is_initialized;
413 u8 open_count;
414 u8 bulkEndpoint;
415 int needsDummyRead;
416
417#if defined(CONFIG_VIDEO_PROC_FS)
418 struct proc_dir_entry *proc_dir;
419#endif
420
421};
422
423static int vicam_probe( struct usb_interface *intf, const struct usb_device_id *id);
424static void vicam_disconnect(struct usb_interface *intf);
425static void read_frame(struct vicam_camera *cam, int framenum);
426static void vicam_decode_color(const u8 *, u8 *);
427
428static int __send_control_msg(struct vicam_camera *cam,
429 u8 request,
430 u16 value,
431 u16 index,
432 unsigned char *cp,
433 u16 size)
434{
435 int status;
436
437 /* cp must be memory that has been allocated by kmalloc */
438
439 status = usb_control_msg(cam->udev,
440 usb_sndctrlpipe(cam->udev, 0),
441 request,
442 USB_DIR_OUT | USB_TYPE_VENDOR |
443 USB_RECIP_DEVICE, value, index,
444 cp, size, 1000);
445
446 status = min(status, 0);
447
448 if (status < 0) {
449 printk(KERN_INFO "Failed sending control message, error %d.\n",
450 status);
451 }
452
453 return status;
454}
455
456static int send_control_msg(struct vicam_camera *cam,
457 u8 request,
458 u16 value,
459 u16 index,
460 unsigned char *cp,
461 u16 size)
462{
463 int status = -ENODEV;
464 down(&cam->cam_lock);
465 if (cam->udev) {
466 status = __send_control_msg(cam, request, value,
467 index, cp, size);
468 }
469 up(&cam->cam_lock);
470 return status;
471}
472static int
473initialize_camera(struct vicam_camera *cam)
474{
475 const struct {
476 u8 *data;
477 u32 size;
478 } firmware[] = {
479 { .data = setup1, .size = sizeof(setup1) },
480 { .data = setup2, .size = sizeof(setup2) },
481 { .data = setup3, .size = sizeof(setup3) },
482 { .data = setup4, .size = sizeof(setup4) },
483 { .data = setup5, .size = sizeof(setup5) },
484 { .data = setup3, .size = sizeof(setup3) },
485 { .data = NULL, .size = 0 }
486 };
487
488 int err, i;
489
490 for (i = 0, err = 0; firmware[i].data && !err; i++) {
491 memcpy(cam->cntrlbuf, firmware[i].data, firmware[i].size);
492
493 err = send_control_msg(cam, 0xff, 0, 0,
494 cam->cntrlbuf, firmware[i].size);
495 }
496
497 return err;
498}
499
500static int
501set_camera_power(struct vicam_camera *cam, int state)
502{
503 int status;
504
505 if ((status = send_control_msg(cam, 0x50, state, 0, NULL, 0)) < 0)
506 return status;
507
508 if (state) {
509 send_control_msg(cam, 0x55, 1, 0, NULL, 0);
510 }
511
512 return 0;
513}
514
515static int
516vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsigned long arg)
517{
518 void __user *user_arg = (void __user *)arg;
519 struct vicam_camera *cam = file->private_data;
520 int retval = 0;
521
522 if (!cam)
523 return -ENODEV;
524
525 switch (ioctlnr) {
526 /* query capabilities */
527 case VIDIOCGCAP:
528 {
529 struct video_capability b;
530
531 DBG("VIDIOCGCAP\n");
532 memset(&b, 0, sizeof(b));
533 strcpy(b.name, "ViCam-based Camera");
534 b.type = VID_TYPE_CAPTURE;
535 b.channels = 1;
536 b.audios = 0;
537 b.maxwidth = 320; /* VIDEOSIZE_CIF */
538 b.maxheight = 240;
539 b.minwidth = 320; /* VIDEOSIZE_48_48 */
540 b.minheight = 240;
541
542 if (copy_to_user(user_arg, &b, sizeof(b)))
543 retval = -EFAULT;
544
545 break;
546 }
547 /* get/set video source - we are a camera and nothing else */
548 case VIDIOCGCHAN:
549 {
550 struct video_channel v;
551
552 DBG("VIDIOCGCHAN\n");
553 if (copy_from_user(&v, user_arg, sizeof(v))) {
554 retval = -EFAULT;
555 break;
556 }
557 if (v.channel != 0) {
558 retval = -EINVAL;
559 break;
560 }
561
562 v.channel = 0;
563 strcpy(v.name, "Camera");
564 v.tuners = 0;
565 v.flags = 0;
566 v.type = VIDEO_TYPE_CAMERA;
567 v.norm = 0;
568
569 if (copy_to_user(user_arg, &v, sizeof(v)))
570 retval = -EFAULT;
571 break;
572 }
573
574 case VIDIOCSCHAN:
575 {
576 int v;
577
578 if (copy_from_user(&v, user_arg, sizeof(v)))
579 retval = -EFAULT;
580 DBG("VIDIOCSCHAN %d\n", v);
581
582 if (retval == 0 && v != 0)
583 retval = -EINVAL;
584
585 break;
586 }
587
588 /* image properties */
589 case VIDIOCGPICT:
590 {
591 struct video_picture vp;
592 DBG("VIDIOCGPICT\n");
593 memset(&vp, 0, sizeof (struct video_picture));
594 vp.brightness = cam->gain << 8;
595 vp.depth = 24;
596 vp.palette = VIDEO_PALETTE_RGB24;
597 if (copy_to_user(user_arg, &vp, sizeof (struct video_picture)))
598 retval = -EFAULT;
599 break;
600 }
601
602 case VIDIOCSPICT:
603 {
604 struct video_picture vp;
605
606 if (copy_from_user(&vp, user_arg, sizeof(vp))) {
607 retval = -EFAULT;
608 break;
609 }
610
611 DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp.depth,
612 vp.palette);
613
614 cam->gain = vp.brightness >> 8;
615
616 if (vp.depth != 24
617 || vp.palette != VIDEO_PALETTE_RGB24)
618 retval = -EINVAL;
619
620 break;
621 }
622
623 /* get/set capture window */
624 case VIDIOCGWIN:
625 {
626 struct video_window vw;
627 vw.x = 0;
628 vw.y = 0;
629 vw.width = 320;
630 vw.height = 240;
631 vw.chromakey = 0;
632 vw.flags = 0;
633 vw.clips = NULL;
634 vw.clipcount = 0;
635
636 DBG("VIDIOCGWIN\n");
637
638 if (copy_to_user(user_arg, (void *)&vw, sizeof(vw)))
639 retval = -EFAULT;
640
641 // I'm not sure what the deal with a capture window is, it is very poorly described
642 // in the doc. So I won't support it now.
643 break;
644 }
645
646 case VIDIOCSWIN:
647 {
648
649 struct video_window vw;
650
651 if (copy_from_user(&vw, user_arg, sizeof(vw))) {
652 retval = -EFAULT;
653 break;
654 }
655
656 DBG("VIDIOCSWIN %d x %d\n", vw.width, vw.height);
657
658 if ( vw.width != 320 || vw.height != 240 )
659 retval = -EFAULT;
660
661 break;
662 }
663
664 /* mmap interface */
665 case VIDIOCGMBUF:
666 {
667 struct video_mbuf vm;
668 int i;
669
670 DBG("VIDIOCGMBUF\n");
671 memset(&vm, 0, sizeof (vm));
672 vm.size =
673 VICAM_MAX_FRAME_SIZE * VICAM_FRAMES;
674 vm.frames = VICAM_FRAMES;
675 for (i = 0; i < VICAM_FRAMES; i++)
676 vm.offsets[i] = VICAM_MAX_FRAME_SIZE * i;
677
678 if (copy_to_user(user_arg, (void *)&vm, sizeof(vm)))
679 retval = -EFAULT;
680
681 break;
682 }
683
684 case VIDIOCMCAPTURE:
685 {
686 struct video_mmap vm;
687 // int video_size;
688
689 if (copy_from_user((void *)&vm, user_arg, sizeof(vm))) {
690 retval = -EFAULT;
691 break;
692 }
693
694 DBG("VIDIOCMCAPTURE frame=%d, height=%d, width=%d, format=%d.\n",vm.frame,vm.width,vm.height,vm.format);
695
696 if ( vm.frame >= VICAM_FRAMES || vm.format != VIDEO_PALETTE_RGB24 )
697 retval = -EINVAL;
698
699 // in theory right here we'd start the image capturing
700 // (fill in a bulk urb and submit it asynchronously)
701 //
702 // Instead we're going to do a total hack job for now and
703 // retrieve the frame in VIDIOCSYNC
704
705 break;
706 }
707
708 case VIDIOCSYNC:
709 {
710 int frame;
711
712 if (copy_from_user((void *)&frame, user_arg, sizeof(int))) {
713 retval = -EFAULT;
714 break;
715 }
716 DBG("VIDIOCSYNC: %d\n", frame);
717
718 read_frame(cam, frame);
719 vicam_decode_color(cam->raw_image,
720 cam->framebuf +
721 frame * VICAM_MAX_FRAME_SIZE );
722
723 break;
724 }
725
726 /* pointless to implement overlay with this camera */
727 case VIDIOCCAPTURE:
728 case VIDIOCGFBUF:
729 case VIDIOCSFBUF:
730 case VIDIOCKEY:
731 retval = -EINVAL;
732 break;
733
734 /* tuner interface - we have none */
735 case VIDIOCGTUNER:
736 case VIDIOCSTUNER:
737 case VIDIOCGFREQ:
738 case VIDIOCSFREQ:
739 retval = -EINVAL;
740 break;
741
742 /* audio interface - we have none */
743 case VIDIOCGAUDIO:
744 case VIDIOCSAUDIO:
745 retval = -EINVAL;
746 break;
747 default:
748 retval = -ENOIOCTLCMD;
749 break;
750 }
751
752 return retval;
753}
754
755static int
756vicam_open(struct inode *inode, struct file *file)
757{
758 struct video_device *dev = video_devdata(file);
759 struct vicam_camera *cam =
760 (struct vicam_camera *) dev->priv;
761 DBG("open\n");
762
763 if (!cam) {
764 printk(KERN_ERR
765 "vicam video_device improperly initialized");
766 }
767
768 /* the videodev_lock held above us protects us from
769 * simultaneous opens...for now. we probably shouldn't
770 * rely on this fact forever.
771 */
772
773 if (cam->open_count > 0) {
774 printk(KERN_INFO
775 "vicam_open called on already opened camera");
776 return -EBUSY;
777 }
778
779 cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL);
780 if (!cam->raw_image) {
781 return -ENOMEM;
782 }
783
784 cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
785 if (!cam->framebuf) {
786 kfree(cam->raw_image);
787 return -ENOMEM;
788 }
789
790 cam->cntrlbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
791 if (!cam->cntrlbuf) {
792 kfree(cam->raw_image);
793 rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
794 return -ENOMEM;
795 }
796
797 // First upload firmware, then turn the camera on
798
799 if (!cam->is_initialized) {
800 initialize_camera(cam);
801
802 cam->is_initialized = 1;
803 }
804
805 set_camera_power(cam, 1);
806
807 cam->needsDummyRead = 1;
808 cam->open_count++;
809
810 file->private_data = cam;
811
812 return 0;
813}
814
815static int
816vicam_close(struct inode *inode, struct file *file)
817{
818 struct vicam_camera *cam = file->private_data;
819 int open_count;
820 struct usb_device *udev;
821
822 DBG("close\n");
823
824 /* it's not the end of the world if
825 * we fail to turn the camera off.
826 */
827
828 set_camera_power(cam, 0);
829
830 kfree(cam->raw_image);
831 rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
832 kfree(cam->cntrlbuf);
833
834 down(&cam->cam_lock);
835
836 cam->open_count--;
837 open_count = cam->open_count;
838 udev = cam->udev;
839
840 up(&cam->cam_lock);
841
842 if (!open_count && !udev) {
843 kfree(cam);
844 }
845
846 return 0;
847}
848
849static void vicam_decode_color(const u8 *data, u8 *rgb)
850{
851 /* vicam_decode_color - Convert from Vicam Y-Cr-Cb to RGB
852 * Copyright (C) 2002 Monroe Williams (monroe@pobox.com)
853 */
854
855 int i, prevY, nextY;
856
857 prevY = 512;
858 nextY = 512;
859
860 data += VICAM_HEADER_SIZE;
861
862 for( i = 0; i < 240; i++, data += 512 ) {
863 const int y = ( i * 242 ) / 240;
864
865 int j, prevX, nextX;
866 int Y, Cr, Cb;
867
868 if ( y == 242 - 1 ) {
869 nextY = -512;
870 }
871
872 prevX = 1;
873 nextX = 1;
874
875 for ( j = 0; j < 320; j++, rgb += 3 ) {
876 const int x = ( j * 512 ) / 320;
877 const u8 * const src = &data[x];
878
879 if ( x == 512 - 1 ) {
880 nextX = -1;
881 }
882
883 Cr = ( src[prevX] - src[0] ) +
884 ( src[nextX] - src[0] );
885 Cr /= 2;
886
887 Cb = ( src[prevY] - src[prevX + prevY] ) +
888 ( src[prevY] - src[nextX + prevY] ) +
889 ( src[nextY] - src[prevX + nextY] ) +
890 ( src[nextY] - src[nextX + nextY] );
891 Cb /= 4;
892
893 Y = 1160 * ( src[0] + ( Cr / 2 ) - 16 );
894
895 if ( i & 1 ) {
896 int Ct = Cr;
897 Cr = Cb;
898 Cb = Ct;
899 }
900
901 if ( ( x ^ i ) & 1 ) {
902 Cr = -Cr;
903 Cb = -Cb;
904 }
905
906 rgb[0] = clamp( ( ( Y + ( 2017 * Cb ) ) +
907 500 ) / 900, 0, 255 );
908 rgb[1] = clamp( ( ( Y - ( 392 * Cb ) -
909 ( 813 * Cr ) ) +
910 500 ) / 1000, 0, 255 );
911 rgb[2] = clamp( ( ( Y + ( 1594 * Cr ) ) +
912 500 ) / 1300, 0, 255 );
913
914 prevX = -1;
915 }
916
917 prevY = -512;
918 }
919}
920
921static void
922read_frame(struct vicam_camera *cam, int framenum)
923{
924 unsigned char *request = cam->cntrlbuf;
925 int realShutter;
926 int n;
927 int actual_length;
928
929 if (cam->needsDummyRead) {
930 cam->needsDummyRead = 0;
931 read_frame(cam, framenum);
932 }
933
934 memset(request, 0, 16);
935 request[0] = cam->gain; // 0 = 0% gain, FF = 100% gain
936
937 request[1] = 0; // 512x242 capture
938
939 request[2] = 0x90; // the function of these two bytes
940 request[3] = 0x07; // is not yet understood
941
942 if (cam->shutter_speed > 60) {
943 // Short exposure
944 realShutter =
945 ((-15631900 / cam->shutter_speed) + 260533) / 1000;
946 request[4] = realShutter & 0xFF;
947 request[5] = (realShutter >> 8) & 0xFF;
948 request[6] = 0x03;
949 request[7] = 0x01;
950 } else {
951 // Long exposure
952 realShutter = 15600 / cam->shutter_speed - 1;
953 request[4] = 0;
954 request[5] = 0;
955 request[6] = realShutter & 0xFF;
956 request[7] = realShutter >> 8;
957 }
958
959 // Per John Markus Bjørndalen, byte at index 8 causes problems if it isn't 0
960 request[8] = 0;
961 // bytes 9-15 do not seem to affect exposure or image quality
962
963 down(&cam->cam_lock);
964
965 if (!cam->udev) {
966 goto done;
967 }
968
969 n = __send_control_msg(cam, 0x51, 0x80, 0, request, 16);
970
971 if (n < 0) {
972 printk(KERN_ERR
973 " Problem sending frame capture control message");
974 goto done;
975 }
976
977 n = usb_bulk_msg(cam->udev,
978 usb_rcvbulkpipe(cam->udev, cam->bulkEndpoint),
979 cam->raw_image,
980 512 * 242 + 128, &actual_length, 10000);
981
982 if (n < 0) {
983 printk(KERN_ERR "Problem during bulk read of frame data: %d\n",
984 n);
985 }
986
987 done:
988 up(&cam->cam_lock);
989}
990
991static ssize_t
992vicam_read( struct file *file, char __user *buf, size_t count, loff_t *ppos )
993{
994 struct vicam_camera *cam = file->private_data;
995
996 DBG("read %d bytes.\n", (int) count);
997
998 if (*ppos >= VICAM_MAX_FRAME_SIZE) {
999 *ppos = 0;
1000 return 0;
1001 }
1002
1003 if (*ppos == 0) {
1004 read_frame(cam, 0);
1005 vicam_decode_color(cam->raw_image,
1006 cam->framebuf +
1007 0 * VICAM_MAX_FRAME_SIZE);
1008 }
1009
1010 count = min_t(size_t, count, VICAM_MAX_FRAME_SIZE - *ppos);
1011
1012 if (copy_to_user(buf, &cam->framebuf[*ppos], count)) {
1013 count = -EFAULT;
1014 } else {
1015 *ppos += count;
1016 }
1017
1018 if (count == VICAM_MAX_FRAME_SIZE) {
1019 *ppos = 0;
1020 }
1021
1022 return count;
1023}
1024
1025
1026static int
1027vicam_mmap(struct file *file, struct vm_area_struct *vma)
1028{
1029 // TODO: allocate the raw frame buffer if necessary
1030 unsigned long page, pos;
1031 unsigned long start = vma->vm_start;
1032 unsigned long size = vma->vm_end-vma->vm_start;
1033 struct vicam_camera *cam = file->private_data;
1034
1035 if (!cam)
1036 return -ENODEV;
1037
1038 DBG("vicam_mmap: %ld\n", size);
1039
1040 /* We let mmap allocate as much as it wants because Linux was adding 2048 bytes
1041 * to the size the application requested for mmap and it was screwing apps up.
1042 if (size > VICAM_FRAMES*VICAM_MAX_FRAME_SIZE)
1043 return -EINVAL;
1044 */
1045
1046 pos = (unsigned long)cam->framebuf;
1047 while (size > 0) {
1048 page = vmalloc_to_pfn((void *)pos);
1049 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
1050 return -EAGAIN;
1051
1052 start += PAGE_SIZE;
1053 pos += PAGE_SIZE;
1054 if (size > PAGE_SIZE)
1055 size -= PAGE_SIZE;
1056 else
1057 size = 0;
1058 }
1059
1060 return 0;
1061}
1062
1063#if defined(CONFIG_VIDEO_PROC_FS)
1064
1065static struct proc_dir_entry *vicam_proc_root = NULL;
1066
1067static int vicam_read_helper(char *page, char **start, off_t off,
1068 int count, int *eof, int value)
1069{
1070 char *out = page;
1071 int len;
1072
1073 out += sprintf(out, "%d",value);
1074
1075 len = out - page;
1076 len -= off;
1077 if (len < count) {
1078 *eof = 1;
1079 if (len <= 0)
1080 return 0;
1081 } else
1082 len = count;
1083
1084 *start = page + off;
1085 return len;
1086}
1087
1088static int vicam_read_proc_shutter(char *page, char **start, off_t off,
1089 int count, int *eof, void *data)
1090{
1091 return vicam_read_helper(page,start,off,count,eof,
1092 ((struct vicam_camera *)data)->shutter_speed);
1093}
1094
1095static int vicam_read_proc_gain(char *page, char **start, off_t off,
1096 int count, int *eof, void *data)
1097{
1098 return vicam_read_helper(page,start,off,count,eof,
1099 ((struct vicam_camera *)data)->gain);
1100}
1101
1102static int
1103vicam_write_proc_shutter(struct file *file, const char *buffer,
1104 unsigned long count, void *data)
1105{
1106 u16 stmp;
1107 char kbuf[8];
1108 struct vicam_camera *cam = (struct vicam_camera *) data;
1109
1110 if (count > 6)
1111 return -EINVAL;
1112
1113 if (copy_from_user(kbuf, buffer, count))
1114 return -EFAULT;
1115
1116 stmp = (u16) simple_strtoul(kbuf, NULL, 10);
1117 if (stmp < 4 || stmp > 32000)
1118 return -EINVAL;
1119
1120 cam->shutter_speed = stmp;
1121
1122 return count;
1123}
1124
1125static int
1126vicam_write_proc_gain(struct file *file, const char *buffer,
1127 unsigned long count, void *data)
1128{
1129 u16 gtmp;
1130 char kbuf[8];
1131
1132 struct vicam_camera *cam = (struct vicam_camera *) data;
1133
1134 if (count > 4)
1135 return -EINVAL;
1136
1137 if (copy_from_user(kbuf, buffer, count))
1138 return -EFAULT;
1139
1140 gtmp = (u16) simple_strtoul(kbuf, NULL, 10);
1141 if (gtmp > 255)
1142 return -EINVAL;
1143 cam->gain = gtmp;
1144
1145 return count;
1146}
1147
1148static void
1149vicam_create_proc_root(void)
1150{
1151 vicam_proc_root = create_proc_entry("video/vicam", S_IFDIR, 0);
1152
1153 if (vicam_proc_root)
1154 vicam_proc_root->owner = THIS_MODULE;
1155 else
1156 printk(KERN_ERR
1157 "could not create /proc entry for vicam!");
1158}
1159
1160static void
1161vicam_destroy_proc_root(void)
1162{
1163 if (vicam_proc_root)
1164 remove_proc_entry("video/vicam", 0);
1165}
1166
1167static void
1168vicam_create_proc_entry(struct vicam_camera *cam)
1169{
1170 char name[64];
1171 struct proc_dir_entry *ent;
1172
1173 DBG(KERN_INFO "vicam: creating proc entry\n");
1174
1175 if (!vicam_proc_root || !cam) {
1176 printk(KERN_INFO
1177 "vicam: could not create proc entry, %s pointer is null.\n",
1178 (!cam ? "camera" : "root"));
1179 return;
1180 }
1181
1182 sprintf(name, "video%d", cam->vdev.minor);
1183
1184 cam->proc_dir = create_proc_entry(name, S_IFDIR, vicam_proc_root);
1185
1186 if ( !cam->proc_dir )
1187 return; // FIXME: We should probably return an error here
1188
1189 ent = create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR,
1190 cam->proc_dir);
1191 if (ent) {
1192 ent->data = cam;
1193 ent->read_proc = vicam_read_proc_shutter;
1194 ent->write_proc = vicam_write_proc_shutter;
1195 ent->size = 64;
1196 }
1197
1198 ent = create_proc_entry("gain", S_IFREG | S_IRUGO | S_IWUSR,
1199 cam->proc_dir);
1200 if (ent) {
1201 ent->data = cam;
1202 ent->read_proc = vicam_read_proc_gain;
1203 ent->write_proc = vicam_write_proc_gain;
1204 ent->size = 64;
1205 }
1206}
1207
1208static void
1209vicam_destroy_proc_entry(void *ptr)
1210{
1211 struct vicam_camera *cam = (struct vicam_camera *) ptr;
1212 char name[16];
1213
1214 if ( !cam->proc_dir )
1215 return;
1216
1217 sprintf(name, "video%d", cam->vdev.minor);
1218 remove_proc_entry("shutter", cam->proc_dir);
1219 remove_proc_entry("gain", cam->proc_dir);
1220 remove_proc_entry(name,vicam_proc_root);
1221 cam->proc_dir = NULL;
1222
1223}
1224
1225#else
1226static inline void vicam_create_proc_root(void) { }
1227static inline void vicam_destroy_proc_root(void) { }
1228static inline void vicam_create_proc_entry(struct vicam_camera *cam) { }
1229static inline void vicam_destroy_proc_entry(void *ptr) { }
1230#endif
1231
1232static struct file_operations vicam_fops = {
1233 .owner = THIS_MODULE,
1234 .open = vicam_open,
1235 .release = vicam_close,
1236 .read = vicam_read,
1237 .mmap = vicam_mmap,
1238 .ioctl = vicam_ioctl,
1239 .llseek = no_llseek,
1240};
1241
1242static struct video_device vicam_template = {
1243 .owner = THIS_MODULE,
1244 .name = "ViCam-based USB Camera",
1245 .type = VID_TYPE_CAPTURE,
1246 .hardware = VID_HARDWARE_VICAM,
1247 .fops = &vicam_fops,
1248 .minor = -1,
1249};
1250
1251/* table of devices that work with this driver */
1252static struct usb_device_id vicam_table[] = {
1253 {USB_DEVICE(USB_VICAM_VENDOR_ID, USB_VICAM_PRODUCT_ID)},
1254 {} /* Terminating entry */
1255};
1256
1257MODULE_DEVICE_TABLE(usb, vicam_table);
1258
1259static struct usb_driver vicam_driver = {
1260 .owner = THIS_MODULE,
1261 .name = "vicam",
1262 .probe = vicam_probe,
1263 .disconnect = vicam_disconnect,
1264 .id_table = vicam_table
1265};
1266
1267/**
1268 * vicam_probe
1269 * @intf: the interface
1270 * @id: the device id
1271 *
1272 * Called by the usb core when a new device is connected that it thinks
1273 * this driver might be interested in.
1274 */
1275static int
1276vicam_probe( struct usb_interface *intf, const struct usb_device_id *id)
1277{
1278 struct usb_device *dev = interface_to_usbdev(intf);
1279 int bulkEndpoint = 0;
1280 const struct usb_host_interface *interface;
1281 const struct usb_endpoint_descriptor *endpoint;
1282 struct vicam_camera *cam;
1283
1284 printk(KERN_INFO "ViCam based webcam connected\n");
1285
1286 interface = intf->cur_altsetting;
1287
1288 DBG(KERN_DEBUG "Interface %d. has %u. endpoints!\n",
1289 interface->desc.bInterfaceNumber, (unsigned) (interface->desc.bNumEndpoints));
1290 endpoint = &interface->endpoint[0].desc;
1291
1292 if ((endpoint->bEndpointAddress & 0x80) &&
1293 ((endpoint->bmAttributes & 3) == 0x02)) {
1294 /* we found a bulk in endpoint */
1295 bulkEndpoint = endpoint->bEndpointAddress;
1296 } else {
1297 printk(KERN_ERR
1298 "No bulk in endpoint was found ?! (this is bad)\n");
1299 }
1300
1301 if ((cam =
1302 kmalloc(sizeof (struct vicam_camera), GFP_KERNEL)) == NULL) {
1303 printk(KERN_WARNING
1304 "could not allocate kernel memory for vicam_camera struct\n");
1305 return -ENOMEM;
1306 }
1307
1308 memset(cam, 0, sizeof (struct vicam_camera));
1309
1310 cam->shutter_speed = 15;
1311
1312 init_MUTEX(&cam->cam_lock);
1313
1314 memcpy(&cam->vdev, &vicam_template,
1315 sizeof (vicam_template));
1316 cam->vdev.priv = cam; // sort of a reverse mapping for those functions that get vdev only
1317
1318 cam->udev = dev;
1319 cam->bulkEndpoint = bulkEndpoint;
1320
1321 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1) == -1) {
1322 kfree(cam);
1323 printk(KERN_WARNING "video_register_device failed\n");
1324 return -EIO;
1325 }
1326
1327 vicam_create_proc_entry(cam);
1328
1329 printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n",cam->vdev.minor);
1330
1331 usb_set_intfdata (intf, cam);
1332
1333 return 0;
1334}
1335
1336static void
1337vicam_disconnect(struct usb_interface *intf)
1338{
1339 int open_count;
1340 struct vicam_camera *cam = usb_get_intfdata (intf);
1341 usb_set_intfdata (intf, NULL);
1342
1343 /* we must unregister the device before taking its
1344 * cam_lock. This is because the video open call
1345 * holds the same lock as video unregister. if we
1346 * unregister inside of the cam_lock and open also
1347 * uses the cam_lock, we get deadlock.
1348 */
1349
1350 video_unregister_device(&cam->vdev);
1351
1352 /* stop the camera from being used */
1353
1354 down(&cam->cam_lock);
1355
1356 /* mark the camera as gone */
1357
1358 cam->udev = NULL;
1359
1360 vicam_destroy_proc_entry(cam);
1361
1362 /* the only thing left to do is synchronize with
1363 * our close/release function on who should release
1364 * the camera memory. if there are any users using the
1365 * camera, it's their job. if there are no users,
1366 * it's ours.
1367 */
1368
1369 open_count = cam->open_count;
1370
1371 up(&cam->cam_lock);
1372
1373 if (!open_count) {
1374 kfree(cam);
1375 }
1376
1377 printk(KERN_DEBUG "ViCam-based WebCam disconnected\n");
1378}
1379
1380/*
1381 */
1382static int __init
1383usb_vicam_init(void)
1384{
1385 int retval;
1386 DBG(KERN_INFO "ViCam-based WebCam driver startup\n");
1387 vicam_create_proc_root();
1388 retval = usb_register(&vicam_driver);
1389 if (retval)
1390 printk(KERN_WARNING "usb_register failed!\n");
1391 return retval;
1392}
1393
1394static void __exit
1395usb_vicam_exit(void)
1396{
1397 DBG(KERN_INFO
1398 "ViCam-based WebCam driver shutdown\n");
1399
1400 usb_deregister(&vicam_driver);
1401 vicam_destroy_proc_root();
1402}
1403
1404module_init(usb_vicam_init);
1405module_exit(usb_vicam_exit);
1406
1407MODULE_AUTHOR(DRIVER_AUTHOR);
1408MODULE_DESCRIPTION(DRIVER_DESC);
1409MODULE_LICENSE("GPL");
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
new file mode 100644
index 000000000000..689e79e4bcee
--- /dev/null
+++ b/drivers/usb/media/w9968cf.c
@@ -0,0 +1,3822 @@
1/***************************************************************************
2 * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip. *
3 * *
4 * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * - Memory management code from bttv driver by Ralph Metzler, *
7 * Marcus Metzler and Gerd Knorr. *
8 * - I2C interface to kernel, high-level image sensor control routines and *
9 * some symbolic names from OV511 driver by Mark W. McClelland. *
10 * - Low-level I2C fast write function by Piotr Czerczak. *
11 * - Low-level I2C read function by Frederic Jouault. *
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 * This program is distributed in the hope that it will be useful, *
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21 * GNU General Public License for more details. *
22 * *
23 * You should have received a copy of the GNU General Public License *
24 * along with this program; if not, write to the Free Software *
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
26 ***************************************************************************/
27
28#include <linux/version.h>
29#include <linux/module.h>
30#include <linux/kernel.h>
31#include <linux/kmod.h>
32#include <linux/init.h>
33#include <linux/fs.h>
34#include <linux/vmalloc.h>
35#include <linux/slab.h>
36#include <linux/mm.h>
37#include <linux/string.h>
38#include <linux/errno.h>
39#include <linux/sched.h>
40#include <linux/ioctl.h>
41#include <linux/delay.h>
42#include <linux/stddef.h>
43#include <asm/page.h>
44#include <asm/uaccess.h>
45#include <linux/page-flags.h>
46#include <linux/moduleparam.h>
47
48#include "w9968cf.h"
49#include "w9968cf_decoder.h"
50
51
52
53/****************************************************************************
54 * Module macros and parameters *
55 ****************************************************************************/
56
57MODULE_DEVICE_TABLE(usb, winbond_id_table);
58
59MODULE_AUTHOR(W9968CF_MODULE_AUTHOR" "W9968CF_AUTHOR_EMAIL);
60MODULE_DESCRIPTION(W9968CF_MODULE_NAME);
61MODULE_VERSION(W9968CF_MODULE_VERSION);
62MODULE_LICENSE(W9968CF_MODULE_LICENSE);
63MODULE_SUPPORTED_DEVICE("Video");
64
65static int ovmod_load = W9968CF_OVMOD_LOAD;
66static int vppmod_load = W9968CF_VPPMOD_LOAD;
67static unsigned short simcams = W9968CF_SIMCAMS;
68static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/
69static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] =
70 W9968CF_PACKET_SIZE};
71static unsigned short max_buffers[] = {[0 ... W9968CF_MAX_DEVICES-1] =
72 W9968CF_BUFFERS};
73static int double_buffer[] = {[0 ... W9968CF_MAX_DEVICES-1] =
74 W9968CF_DOUBLE_BUFFER};
75static int clamping[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLAMPING};
76static unsigned short filter_type[]= {[0 ... W9968CF_MAX_DEVICES-1] =
77 W9968CF_FILTER_TYPE};
78static int largeview[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_LARGEVIEW};
79static unsigned short decompression[] = {[0 ... W9968CF_MAX_DEVICES-1] =
80 W9968CF_DECOMPRESSION};
81static int upscaling[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_UPSCALING};
82static unsigned short force_palette[] = {[0 ... W9968CF_MAX_DEVICES-1] = 0};
83static int force_rgb[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_FORCE_RGB};
84static int autobright[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOBRIGHT};
85static int autoexp[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOEXP};
86static unsigned short lightfreq[] = {[0 ... W9968CF_MAX_DEVICES-1] =
87 W9968CF_LIGHTFREQ};
88static int bandingfilter[] = {[0 ... W9968CF_MAX_DEVICES-1]=
89 W9968CF_BANDINGFILTER};
90static short clockdiv[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLOCKDIV};
91static int backlight[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BACKLIGHT};
92static int mirror[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_MIRROR};
93static int monochrome[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_MONOCHROME};
94static unsigned int brightness[] = {[0 ... W9968CF_MAX_DEVICES-1] =
95 W9968CF_BRIGHTNESS};
96static unsigned int hue[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_HUE};
97static unsigned int colour[]={[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_COLOUR};
98static unsigned int contrast[] = {[0 ... W9968CF_MAX_DEVICES-1] =
99 W9968CF_CONTRAST};
100static unsigned int whiteness[] = {[0 ... W9968CF_MAX_DEVICES-1] =
101 W9968CF_WHITENESS};
102#ifdef W9968CF_DEBUG
103static unsigned short debug = W9968CF_DEBUG_LEVEL;
104static int specific_debug = W9968CF_SPECIFIC_DEBUG;
105#endif
106
107static unsigned int param_nv[24]; /* number of values per parameter */
108
109#ifdef CONFIG_KMOD
110module_param(ovmod_load, bool, 0644);
111module_param(vppmod_load, bool, 0444);
112#endif
113module_param(simcams, ushort, 0644);
114module_param_array(video_nr, short, &param_nv[0], 0444);
115module_param_array(packet_size, uint, &param_nv[1], 0444);
116module_param_array(max_buffers, ushort, &param_nv[2], 0444);
117module_param_array(double_buffer, bool, &param_nv[3], 0444);
118module_param_array(clamping, bool, &param_nv[4], 0444);
119module_param_array(filter_type, ushort, &param_nv[5], 0444);
120module_param_array(largeview, bool, &param_nv[6], 0444);
121module_param_array(decompression, ushort, &param_nv[7], 0444);
122module_param_array(upscaling, bool, &param_nv[8], 0444);
123module_param_array(force_palette, ushort, &param_nv[9], 0444);
124module_param_array(force_rgb, ushort, &param_nv[10], 0444);
125module_param_array(autobright, bool, &param_nv[11], 0444);
126module_param_array(autoexp, bool, &param_nv[12], 0444);
127module_param_array(lightfreq, ushort, &param_nv[13], 0444);
128module_param_array(bandingfilter, bool, &param_nv[14], 0444);
129module_param_array(clockdiv, short, &param_nv[15], 0444);
130module_param_array(backlight, bool, &param_nv[16], 0444);
131module_param_array(mirror, bool, &param_nv[17], 0444);
132module_param_array(monochrome, bool, &param_nv[18], 0444);
133module_param_array(brightness, uint, &param_nv[19], 0444);
134module_param_array(hue, uint, &param_nv[20], 0444);
135module_param_array(colour, uint, &param_nv[21], 0444);
136module_param_array(contrast, uint, &param_nv[22], 0444);
137module_param_array(whiteness, uint, &param_nv[23], 0444);
138#ifdef W9968CF_DEBUG
139module_param(debug, ushort, 0644);
140module_param(specific_debug, bool, 0644);
141#endif
142
143#ifdef CONFIG_KMOD
144MODULE_PARM_DESC(ovmod_load,
145 "\n<0|1> Automatic 'ovcamchip' module loading."
146 "\n0 disabled, 1 enabled."
147 "\nIf enabled,'insmod' searches for the required 'ovcamchip'"
148 "\nmodule in the system, according to its configuration, and"
149 "\nattempts to load that module automatically. This action is"
150 "\nperformed once as soon as the 'w9968cf' module is loaded"
151 "\ninto memory."
152 "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"."
153 "\n");
154MODULE_PARM_DESC(vppmod_load,
155 "\n<0|1> Automatic 'w9968cf-vpp' module loading."
156 "\n0 disabled, 1 enabled."
157 "\nIf enabled, every time an application attempts to open a"
158 "\ncamera, 'insmod' searches for the video post-processing"
159 "\nmodule in the system and loads it automatically (if"
160 "\npresent). The optional 'w9968cf-vpp' module adds extra"
161 "\n image manipulation functions to the 'w9968cf' module,like"
162 "\nsoftware up-scaling,colour conversions and video decoding"
163 "\nfor very high frame rates."
164 "\nDefault value is "__MODULE_STRING(W9968CF_VPPMOD_LOAD)"."
165 "\n");
166#endif
167MODULE_PARM_DESC(simcams,
168 "\n<n> Number of cameras allowed to stream simultaneously."
169 "\nn may vary from 0 to "
170 __MODULE_STRING(W9968CF_MAX_DEVICES)"."
171 "\nDefault value is "__MODULE_STRING(W9968CF_SIMCAMS)"."
172 "\n");
173MODULE_PARM_DESC(video_nr,
174 "\n<-1|n[,...]> Specify V4L minor mode number."
175 "\n -1 = use next available (default)"
176 "\n n = use minor number n (integer >= 0)"
177 "\nYou can specify up to "__MODULE_STRING(W9968CF_MAX_DEVICES)
178 " cameras this way."
179 "\nFor example:"
180 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
181 "\nthe second camera and use auto for the first"
182 "\none and for every other camera."
183 "\n");
184MODULE_PARM_DESC(packet_size,
185 "\n<n[,...]> Specify the maximum data payload"
186 "\nsize in bytes for alternate settings, for each device."
187 "\nn is scaled between 63 and 1023 "
188 "(default is "__MODULE_STRING(W9968CF_PACKET_SIZE)")."
189 "\n");
190MODULE_PARM_DESC(max_buffers,
191 "\n<n[,...]> For advanced users."
192 "\nSpecify the maximum number of video frame buffers"
193 "\nto allocate for each device, from 2 to "
194 __MODULE_STRING(W9968CF_MAX_BUFFERS)
195 ". (default is "__MODULE_STRING(W9968CF_BUFFERS)")."
196 "\n");
197MODULE_PARM_DESC(double_buffer,
198 "\n<0|1[,...]> "
199 "Hardware double buffering: 0 disabled, 1 enabled."
200 "\nIt should be enabled if you want smooth video output: if"
201 "\nyou obtain out of sync. video, disable it, or try to"
202 "\ndecrease the 'clockdiv' module parameter value."
203 "\nDefault value is "__MODULE_STRING(W9968CF_DOUBLE_BUFFER)
204 " for every device."
205 "\n");
206MODULE_PARM_DESC(clamping,
207 "\n<0|1[,...]> Video data clamping: 0 disabled, 1 enabled."
208 "\nDefault value is "__MODULE_STRING(W9968CF_CLAMPING)
209 " for every device."
210 "\n");
211MODULE_PARM_DESC(filter_type,
212 "\n<0|1|2[,...]> Video filter type."
213 "\n0 none, 1 (1-2-1) 3-tap filter, "
214 "2 (2-3-6-3-2) 5-tap filter."
215 "\nDefault value is "__MODULE_STRING(W9968CF_FILTER_TYPE)
216 " for every device."
217 "\nThe filter is used to reduce noise and aliasing artifacts"
218 "\nproduced by the CCD or CMOS image sensor, and the scaling"
219 " process."
220 "\n");
221MODULE_PARM_DESC(largeview,
222 "\n<0|1[,...]> Large view: 0 disabled, 1 enabled."
223 "\nDefault value is "__MODULE_STRING(W9968CF_LARGEVIEW)
224 " for every device."
225 "\n");
226MODULE_PARM_DESC(upscaling,
227 "\n<0|1[,...]> Software scaling (for non-compressed video):"
228 "\n0 disabled, 1 enabled."
229 "\nDisable it if you have a slow CPU or you don't have"
230 " enough memory."
231 "\nDefault value is "__MODULE_STRING(W9968CF_UPSCALING)
232 " for every device."
233 "\nIf 'w9968cf-vpp' is not present, this parameter is"
234 " set to 0."
235 "\n");
236MODULE_PARM_DESC(decompression,
237 "\n<0|1|2[,...]> Software video decompression:"
238 "\n- 0 disables decompression (doesn't allow formats needing"
239 " decompression)"
240 "\n- 1 forces decompression (allows formats needing"
241 " decompression only);"
242 "\n- 2 allows any permitted formats."
243 "\nFormats supporting compressed video are YUV422P and"
244 " YUV420P/YUV420 "
245 "\nin any resolutions where both width and height are "
246 "a multiple of 16."
247 "\nDefault value is "__MODULE_STRING(W9968CF_DECOMPRESSION)
248 " for every device."
249 "\nIf 'w9968cf-vpp' is not present, forcing decompression is "
250 "\nnot allowed; in this case this parameter is set to 2."
251 "\n");
252MODULE_PARM_DESC(force_palette,
253 "\n<0"
254 "|" __MODULE_STRING(VIDEO_PALETTE_UYVY)
255 "|" __MODULE_STRING(VIDEO_PALETTE_YUV420)
256 "|" __MODULE_STRING(VIDEO_PALETTE_YUV422P)
257 "|" __MODULE_STRING(VIDEO_PALETTE_YUV420P)
258 "|" __MODULE_STRING(VIDEO_PALETTE_YUYV)
259 "|" __MODULE_STRING(VIDEO_PALETTE_YUV422)
260 "|" __MODULE_STRING(VIDEO_PALETTE_GREY)
261 "|" __MODULE_STRING(VIDEO_PALETTE_RGB555)
262 "|" __MODULE_STRING(VIDEO_PALETTE_RGB565)
263 "|" __MODULE_STRING(VIDEO_PALETTE_RGB24)
264 "|" __MODULE_STRING(VIDEO_PALETTE_RGB32)
265 "[,...]>"
266 " Force picture palette."
267 "\nIn order:"
268 "\n- 0 allows any of the following formats:"
269 "\n- UYVY 16 bpp - Original video, compression disabled"
270 "\n- YUV420 12 bpp - Original video, compression enabled"
271 "\n- YUV422P 16 bpp - Original video, compression enabled"
272 "\n- YUV420P 12 bpp - Original video, compression enabled"
273 "\n- YUVY 16 bpp - Software conversion from UYVY"
274 "\n- YUV422 16 bpp - Software conversion from UYVY"
275 "\n- GREY 8 bpp - Software conversion from UYVY"
276 "\n- RGB555 16 bpp - Software conversion from UYVY"
277 "\n- RGB565 16 bpp - Software conversion from UYVY"
278 "\n- RGB24 24 bpp - Software conversion from UYVY"
279 "\n- RGB32 32 bpp - Software conversion from UYVY"
280 "\nWhen not 0, this parameter will override 'decompression'."
281 "\nDefault value is 0 for every device."
282 "\nInitial palette is "
283 __MODULE_STRING(W9968CF_PALETTE_DECOMP_ON)"."
284 "\nIf 'w9968cf-vpp' is not present, this parameter is"
285 " set to 9 (UYVY)."
286 "\n");
287MODULE_PARM_DESC(force_rgb,
288 "\n<0|1[,...]> Read RGB video data instead of BGR:"
289 "\n 1 = use RGB component ordering."
290 "\n 0 = use BGR component ordering."
291 "\nThis parameter has effect when using RGBX palettes only."
292 "\nDefault value is "__MODULE_STRING(W9968CF_FORCE_RGB)
293 " for every device."
294 "\n");
295MODULE_PARM_DESC(autobright,
296 "\n<0|1[,...]> Image sensor automatically changes brightness:"
297 "\n 0 = no, 1 = yes"
298 "\nDefault value is "__MODULE_STRING(W9968CF_AUTOBRIGHT)
299 " for every device."
300 "\n");
301MODULE_PARM_DESC(autoexp,
302 "\n<0|1[,...]> Image sensor automatically changes exposure:"
303 "\n 0 = no, 1 = yes"
304 "\nDefault value is "__MODULE_STRING(W9968CF_AUTOEXP)
305 " for every device."
306 "\n");
307MODULE_PARM_DESC(lightfreq,
308 "\n<50|60[,...]> Light frequency in Hz:"
309 "\n 50 for European and Asian lighting,"
310 " 60 for American lighting."
311 "\nDefault value is "__MODULE_STRING(W9968CF_LIGHTFREQ)
312 " for every device."
313 "\n");
314MODULE_PARM_DESC(bandingfilter,
315 "\n<0|1[,...]> Banding filter to reduce effects of"
316 " fluorescent lighting:"
317 "\n 0 disabled, 1 enabled."
318 "\nThis filter tries to reduce the pattern of horizontal"
319 "\nlight/dark bands caused by some (usually fluorescent)"
320 " lighting."
321 "\nDefault value is "__MODULE_STRING(W9968CF_BANDINGFILTER)
322 " for every device."
323 "\n");
324MODULE_PARM_DESC(clockdiv,
325 "\n<-1|n[,...]> "
326 "Force pixel clock divisor to a specific value (for experts):"
327 "\n n may vary from 0 to 127."
328 "\n -1 for automatic value."
329 "\nSee also the 'double_buffer' module parameter."
330 "\nDefault value is "__MODULE_STRING(W9968CF_CLOCKDIV)
331 " for every device."
332 "\n");
333MODULE_PARM_DESC(backlight,
334 "\n<0|1[,...]> Objects are lit from behind:"
335 "\n 0 = no, 1 = yes"
336 "\nDefault value is "__MODULE_STRING(W9968CF_BACKLIGHT)
337 " for every device."
338 "\n");
339MODULE_PARM_DESC(mirror,
340 "\n<0|1[,...]> Reverse image horizontally:"
341 "\n 0 = no, 1 = yes"
342 "\nDefault value is "__MODULE_STRING(W9968CF_MIRROR)
343 " for every device."
344 "\n");
345MODULE_PARM_DESC(monochrome,
346 "\n<0|1[,...]> Use image sensor as monochrome sensor:"
347 "\n 0 = no, 1 = yes"
348 "\nNot all the sensors support monochrome color."
349 "\nDefault value is "__MODULE_STRING(W9968CF_MONOCHROME)
350 " for every device."
351 "\n");
352MODULE_PARM_DESC(brightness,
353 "\n<n[,...]> Set picture brightness (0-65535)."
354 "\nDefault value is "__MODULE_STRING(W9968CF_BRIGHTNESS)
355 " for every device."
356 "\nThis parameter has no effect if 'autobright' is enabled."
357 "\n");
358MODULE_PARM_DESC(hue,
359 "\n<n[,...]> Set picture hue (0-65535)."
360 "\nDefault value is "__MODULE_STRING(W9968CF_HUE)
361 " for every device."
362 "\n");
363MODULE_PARM_DESC(colour,
364 "\n<n[,...]> Set picture saturation (0-65535)."
365 "\nDefault value is "__MODULE_STRING(W9968CF_COLOUR)
366 " for every device."
367 "\n");
368MODULE_PARM_DESC(contrast,
369 "\n<n[,...]> Set picture contrast (0-65535)."
370 "\nDefault value is "__MODULE_STRING(W9968CF_CONTRAST)
371 " for every device."
372 "\n");
373MODULE_PARM_DESC(whiteness,
374 "\n<n[,...]> Set picture whiteness (0-65535)."
375 "\nDefault value is "__MODULE_STRING(W9968CF_WHITENESS)
376 " for every device."
377 "\n");
378#ifdef W9968CF_DEBUG
379MODULE_PARM_DESC(debug,
380 "\n<n> Debugging information level, from 0 to 6:"
381 "\n0 = none (use carefully)"
382 "\n1 = critical errors"
383 "\n2 = significant informations"
384 "\n3 = configuration or general messages"
385 "\n4 = warnings"
386 "\n5 = called functions"
387 "\n6 = function internals"
388 "\nLevel 5 and 6 are useful for testing only, when only "
389 "one device is used."
390 "\nDefault value is "__MODULE_STRING(W9968CF_DEBUG_LEVEL)"."
391 "\n");
392MODULE_PARM_DESC(specific_debug,
393 "\n<0|1> Enable or disable specific debugging messages:"
394 "\n0 = print messages concerning every level"
395 " <= 'debug' level."
396 "\n1 = print messages concerning the level"
397 " indicated by 'debug'."
398 "\nDefault value is "
399 __MODULE_STRING(W9968CF_SPECIFIC_DEBUG)"."
400 "\n");
401#endif /* W9968CF_DEBUG */
402
403
404
405/****************************************************************************
406 * Some prototypes *
407 ****************************************************************************/
408
409/* Video4linux interface */
410static struct file_operations w9968cf_fops;
411static int w9968cf_open(struct inode*, struct file*);
412static int w9968cf_release(struct inode*, struct file*);
413static int w9968cf_mmap(struct file*, struct vm_area_struct*);
414static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long);
415static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*);
416static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int,
417 void __user *);
418
419/* USB-specific */
420static int w9968cf_start_transfer(struct w9968cf_device*);
421static int w9968cf_stop_transfer(struct w9968cf_device*);
422static int w9968cf_write_reg(struct w9968cf_device*, u16 value, u16 index);
423static int w9968cf_read_reg(struct w9968cf_device*, u16 index);
424static int w9968cf_write_fsb(struct w9968cf_device*, u16* data);
425static int w9968cf_write_sb(struct w9968cf_device*, u16 value);
426static int w9968cf_read_sb(struct w9968cf_device*);
427static int w9968cf_upload_quantizationtables(struct w9968cf_device*);
428static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs);
429
430/* Low-level I2C (SMBus) I/O */
431static int w9968cf_smbus_start(struct w9968cf_device*);
432static int w9968cf_smbus_stop(struct w9968cf_device*);
433static int w9968cf_smbus_write_byte(struct w9968cf_device*, u8 v);
434static int w9968cf_smbus_read_byte(struct w9968cf_device*, u8* v);
435static int w9968cf_smbus_write_ack(struct w9968cf_device*);
436static int w9968cf_smbus_read_ack(struct w9968cf_device*);
437static int w9968cf_smbus_refresh_bus(struct w9968cf_device*);
438static int w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
439 u16 address, u8* value);
440static int w9968cf_i2c_adap_read_byte_data(struct w9968cf_device*, u16 address,
441 u8 subaddress, u8* value);
442static int w9968cf_i2c_adap_write_byte(struct w9968cf_device*,
443 u16 address, u8 subaddress);
444static int w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device*,
445 u16 address, u8 subaddress,
446 u8 value);
447
448/* I2C interface to kernel */
449static int w9968cf_i2c_init(struct w9968cf_device*);
450static int w9968cf_i2c_smbus_xfer(struct i2c_adapter*, u16 addr,
451 unsigned short flags, char read_write,
452 u8 command, int size, union i2c_smbus_data*);
453static u32 w9968cf_i2c_func(struct i2c_adapter*);
454static int w9968cf_i2c_attach_inform(struct i2c_client*);
455static int w9968cf_i2c_detach_inform(struct i2c_client*);
456static int w9968cf_i2c_control(struct i2c_adapter*, unsigned int cmd,
457 unsigned long arg);
458
459/* Memory management */
460static void* rvmalloc(unsigned long size);
461static void rvfree(void *mem, unsigned long size);
462static void w9968cf_deallocate_memory(struct w9968cf_device*);
463static int w9968cf_allocate_memory(struct w9968cf_device*);
464
465/* High-level image sensor control functions */
466static int w9968cf_sensor_set_control(struct w9968cf_device*,int cid,int val);
467static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val);
468static int w9968cf_sensor_cmd(struct w9968cf_device*,
469 unsigned int cmd, void *arg);
470static int w9968cf_sensor_init(struct w9968cf_device*);
471static int w9968cf_sensor_update_settings(struct w9968cf_device*);
472static int w9968cf_sensor_get_picture(struct w9968cf_device*);
473static int w9968cf_sensor_update_picture(struct w9968cf_device*,
474 struct video_picture pict);
475
476/* Other helper functions */
477static void w9968cf_configure_camera(struct w9968cf_device*,struct usb_device*,
478 enum w9968cf_model_id,
479 const unsigned short dev_nr);
480static void w9968cf_adjust_configuration(struct w9968cf_device*);
481static int w9968cf_turn_on_led(struct w9968cf_device*);
482static int w9968cf_init_chip(struct w9968cf_device*);
483static inline u16 w9968cf_valid_palette(u16 palette);
484static inline u16 w9968cf_valid_depth(u16 palette);
485static inline u8 w9968cf_need_decompression(u16 palette);
486static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture);
487static int w9968cf_set_window(struct w9968cf_device*, struct video_window);
488static int w9968cf_postprocess_frame(struct w9968cf_device*,
489 struct w9968cf_frame_t*);
490static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h);
491static void w9968cf_init_framelist(struct w9968cf_device*);
492static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num);
493static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**);
494static void w9968cf_release_resources(struct w9968cf_device*);
495
496/* Intermodule communication */
497static int w9968cf_vppmod_detect(struct w9968cf_device*);
498static void w9968cf_vppmod_release(struct w9968cf_device*);
499
500
501
502/****************************************************************************
503 * Symbolic names *
504 ****************************************************************************/
505
506/* Used to represent a list of values and their respective symbolic names */
507struct w9968cf_symbolic_list {
508 const int num;
509 const char *name;
510};
511
512/*--------------------------------------------------------------------------
513 Returns the name of the matching element in the symbolic_list array. The
514 end of the list must be marked with an element that has a NULL name.
515 --------------------------------------------------------------------------*/
516static inline const char *
517symbolic(struct w9968cf_symbolic_list list[], const int num)
518{
519 int i;
520
521 for (i = 0; list[i].name != NULL; i++)
522 if (list[i].num == num)
523 return (list[i].name);
524
525 return "Unknown";
526}
527
528static struct w9968cf_symbolic_list camlist[] = {
529 { W9968CF_MOD_GENERIC, "W996[87]CF JPEG USB Dual Mode Camera" },
530 { W9968CF_MOD_CLVBWGP, "Creative Labs Video Blaster WebCam Go Plus" },
531
532 /* Other cameras (having the same descriptors as Generic W996[87]CF) */
533 { W9968CF_MOD_ADPVDMA, "Aroma Digi Pen VGA Dual Mode ADG-5000" },
534 { W9986CF_MOD_AAU, "AVerMedia AVerTV USB" },
535 { W9968CF_MOD_CLVBWG, "Creative Labs Video Blaster WebCam Go" },
536 { W9968CF_MOD_LL, "Lebon LDC-035A" },
537 { W9968CF_MOD_EEEMC, "Ezonics EZ-802 EZMega Cam" },
538 { W9968CF_MOD_OOE, "OmniVision OV8610-EDE" },
539 { W9968CF_MOD_ODPVDMPC, "OPCOM Digi Pen VGA Dual Mode Pen Camera" },
540 { W9968CF_MOD_PDPII, "Pretec Digi Pen-II" },
541 { W9968CF_MOD_PDP480, "Pretec DigiPen-480" },
542
543 { -1, NULL }
544};
545
546static struct w9968cf_symbolic_list senlist[] = {
547 { CC_OV76BE, "OV76BE" },
548 { CC_OV7610, "OV7610" },
549 { CC_OV7620, "OV7620" },
550 { CC_OV7620AE, "OV7620AE" },
551 { CC_OV6620, "OV6620" },
552 { CC_OV6630, "OV6630" },
553 { CC_OV6630AE, "OV6630AE" },
554 { CC_OV6630AF, "OV6630AF" },
555 { -1, NULL }
556};
557
558/* Video4Linux1 palettes */
559static struct w9968cf_symbolic_list v4l1_plist[] = {
560 { VIDEO_PALETTE_GREY, "GREY" },
561 { VIDEO_PALETTE_HI240, "HI240" },
562 { VIDEO_PALETTE_RGB565, "RGB565" },
563 { VIDEO_PALETTE_RGB24, "RGB24" },
564 { VIDEO_PALETTE_RGB32, "RGB32" },
565 { VIDEO_PALETTE_RGB555, "RGB555" },
566 { VIDEO_PALETTE_YUV422, "YUV422" },
567 { VIDEO_PALETTE_YUYV, "YUYV" },
568 { VIDEO_PALETTE_UYVY, "UYVY" },
569 { VIDEO_PALETTE_YUV420, "YUV420" },
570 { VIDEO_PALETTE_YUV411, "YUV411" },
571 { VIDEO_PALETTE_RAW, "RAW" },
572 { VIDEO_PALETTE_YUV422P, "YUV422P" },
573 { VIDEO_PALETTE_YUV411P, "YUV411P" },
574 { VIDEO_PALETTE_YUV420P, "YUV420P" },
575 { VIDEO_PALETTE_YUV410P, "YUV410P" },
576 { -1, NULL }
577};
578
579/* Decoder error codes: */
580static struct w9968cf_symbolic_list decoder_errlist[] = {
581 { W9968CF_DEC_ERR_CORRUPTED_DATA, "Corrupted data" },
582 { W9968CF_DEC_ERR_BUF_OVERFLOW, "Buffer overflow" },
583 { W9968CF_DEC_ERR_NO_SOI, "SOI marker not found" },
584 { W9968CF_DEC_ERR_NO_SOF0, "SOF0 marker not found" },
585 { W9968CF_DEC_ERR_NO_SOS, "SOS marker not found" },
586 { W9968CF_DEC_ERR_NO_EOI, "EOI marker not found" },
587 { -1, NULL }
588};
589
590/* URB error codes: */
591static struct w9968cf_symbolic_list urb_errlist[] = {
592 { -ENOMEM, "No memory for allocation of internal structures" },
593 { -ENOSPC, "The host controller's bandwidth is already consumed" },
594 { -ENOENT, "URB was canceled by unlink_urb" },
595 { -EXDEV, "ISO transfer only partially completed" },
596 { -EAGAIN, "Too match scheduled for the future" },
597 { -ENXIO, "URB already queued" },
598 { -EFBIG, "Too much ISO frames requested" },
599 { -ENOSR, "Buffer error (overrun)" },
600 { -EPIPE, "Specified endpoint is stalled (device not responding)"},
601 { -EOVERFLOW, "Babble (bad cable?)" },
602 { -EPROTO, "Bit-stuff error (bad cable?)" },
603 { -EILSEQ, "CRC/Timeout" },
604 { -ETIMEDOUT, "NAK (device does not respond)" },
605 { -1, NULL }
606};
607
608
609
610/****************************************************************************
611 * Memory management functions *
612 ****************************************************************************/
613static void* rvmalloc(unsigned long size)
614{
615 void* mem;
616 unsigned long adr;
617
618 size = PAGE_ALIGN(size);
619 mem = vmalloc_32(size);
620 if (!mem)
621 return NULL;
622
623 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
624 adr = (unsigned long) mem;
625 while (size > 0) {
626 SetPageReserved(vmalloc_to_page((void *)adr));
627 adr += PAGE_SIZE;
628 size -= PAGE_SIZE;
629 }
630
631 return mem;
632}
633
634
635static void rvfree(void* mem, unsigned long size)
636{
637 unsigned long adr;
638
639 if (!mem)
640 return;
641
642 adr = (unsigned long) mem;
643 while ((long) size > 0) {
644 ClearPageReserved(vmalloc_to_page((void *)adr));
645 adr += PAGE_SIZE;
646 size -= PAGE_SIZE;
647 }
648 vfree(mem);
649}
650
651
652/*--------------------------------------------------------------------------
653 Deallocate previously allocated memory.
654 --------------------------------------------------------------------------*/
655static void w9968cf_deallocate_memory(struct w9968cf_device* cam)
656{
657 u8 i;
658
659 /* Free the isochronous transfer buffers */
660 for (i = 0; i < W9968CF_URBS; i++) {
661 kfree(cam->transfer_buffer[i]);
662 cam->transfer_buffer[i] = NULL;
663 }
664
665 /* Free temporary frame buffer */
666 if (cam->frame_tmp.buffer) {
667 rvfree(cam->frame_tmp.buffer, cam->frame_tmp.size);
668 cam->frame_tmp.buffer = NULL;
669 }
670
671 /* Free helper buffer */
672 if (cam->frame_vpp.buffer) {
673 rvfree(cam->frame_vpp.buffer, cam->frame_vpp.size);
674 cam->frame_vpp.buffer = NULL;
675 }
676
677 /* Free video frame buffers */
678 if (cam->frame[0].buffer) {
679 rvfree(cam->frame[0].buffer, cam->nbuffers*cam->frame[0].size);
680 cam->frame[0].buffer = NULL;
681 }
682
683 cam->nbuffers = 0;
684
685 DBG(5, "Memory successfully deallocated")
686}
687
688
689/*--------------------------------------------------------------------------
690 Allocate memory buffers for USB transfers and video frames.
691 This function is called by open() only.
692 Return 0 on success, a negative number otherwise.
693 --------------------------------------------------------------------------*/
694static int w9968cf_allocate_memory(struct w9968cf_device* cam)
695{
696 const u16 p_size = wMaxPacketSize[cam->altsetting-1];
697 void* buff = NULL;
698 unsigned long hw_bufsize, vpp_bufsize;
699 u8 i, bpp;
700
701 /* NOTE: Deallocation is done elsewhere in case of error */
702
703 /* Calculate the max amount of raw data per frame from the device */
704 hw_bufsize = cam->maxwidth*cam->maxheight*2;
705
706 /* Calculate the max buf. size needed for post-processing routines */
707 bpp = (w9968cf_vpp) ? 4 : 2;
708 if (cam->upscaling)
709 vpp_bufsize = max(W9968CF_MAX_WIDTH*W9968CF_MAX_HEIGHT*bpp,
710 cam->maxwidth*cam->maxheight*bpp);
711 else
712 vpp_bufsize = cam->maxwidth*cam->maxheight*bpp;
713
714 /* Allocate memory for the isochronous transfer buffers */
715 for (i = 0; i < W9968CF_URBS; i++) {
716 if (!(cam->transfer_buffer[i] =
717 kmalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) {
718 DBG(1, "Couldn't allocate memory for the isochronous "
719 "transfer buffers (%u bytes)",
720 p_size * W9968CF_ISO_PACKETS)
721 return -ENOMEM;
722 }
723 memset(cam->transfer_buffer[i], 0, W9968CF_ISO_PACKETS*p_size);
724 }
725
726 /* Allocate memory for the temporary frame buffer */
727 if (!(cam->frame_tmp.buffer = rvmalloc(hw_bufsize))) {
728 DBG(1, "Couldn't allocate memory for the temporary "
729 "video frame buffer (%lu bytes)", hw_bufsize)
730 return -ENOMEM;
731 }
732 cam->frame_tmp.size = hw_bufsize;
733 cam->frame_tmp.number = -1;
734
735 /* Allocate memory for the helper buffer */
736 if (w9968cf_vpp) {
737 if (!(cam->frame_vpp.buffer = rvmalloc(vpp_bufsize))) {
738 DBG(1, "Couldn't allocate memory for the helper buffer"
739 " (%lu bytes)", vpp_bufsize)
740 return -ENOMEM;
741 }
742 cam->frame_vpp.size = vpp_bufsize;
743 } else
744 cam->frame_vpp.buffer = NULL;
745
746 /* Allocate memory for video frame buffers */
747 cam->nbuffers = cam->max_buffers;
748 while (cam->nbuffers >= 2) {
749 if ((buff = rvmalloc(cam->nbuffers * vpp_bufsize)))
750 break;
751 else
752 cam->nbuffers--;
753 }
754
755 if (!buff) {
756 DBG(1, "Couldn't allocate memory for the video frame buffers")
757 cam->nbuffers = 0;
758 return -ENOMEM;
759 }
760
761 if (cam->nbuffers != cam->max_buffers)
762 DBG(2, "Couldn't allocate memory for %u video frame buffers. "
763 "Only memory for %u buffers has been allocated",
764 cam->max_buffers, cam->nbuffers)
765
766 for (i = 0; i < cam->nbuffers; i++) {
767 cam->frame[i].buffer = buff + i*vpp_bufsize;
768 cam->frame[i].size = vpp_bufsize;
769 cam->frame[i].number = i;
770 /* Circular list */
771 if (i != cam->nbuffers-1)
772 cam->frame[i].next = &cam->frame[i+1];
773 else
774 cam->frame[i].next = &cam->frame[0];
775 cam->frame[i].status = F_UNUSED;
776 }
777
778 DBG(5, "Memory successfully allocated")
779 return 0;
780}
781
782
783
784/****************************************************************************
785 * USB-specific functions *
786 ****************************************************************************/
787
788/*--------------------------------------------------------------------------
789 This is an handler function which is called after the URBs are completed.
790 It collects multiple data packets coming from the camera by putting them
791 into frame buffers: one or more zero data length data packets are used to
792 mark the end of a video frame; the first non-zero data packet is the start
793 of the next video frame; if an error is encountered in a packet, the entire
794 video frame is discarded and grabbed again.
795 If there are no requested frames in the FIFO list, packets are collected into
796 a temporary buffer.
797 --------------------------------------------------------------------------*/
798static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs)
799{
800 struct w9968cf_device* cam = (struct w9968cf_device*)urb->context;
801 struct w9968cf_frame_t** f;
802 unsigned int len, status;
803 void* pos;
804 u8 i;
805 int err = 0;
806
807 if ((!cam->streaming) || cam->disconnected) {
808 DBG(4, "Got interrupt, but not streaming")
809 return;
810 }
811
812 /* "(*f)" will be used instead of "cam->frame_current" */
813 f = &cam->frame_current;
814
815 /* If a frame has been requested and we are grabbing into
816 the temporary frame, we'll switch to that requested frame */
817 if ((*f) == &cam->frame_tmp && *cam->requested_frame) {
818 if (cam->frame_tmp.status == F_GRABBING) {
819 w9968cf_pop_frame(cam, &cam->frame_current);
820 (*f)->status = F_GRABBING;
821 (*f)->length = cam->frame_tmp.length;
822 memcpy((*f)->buffer, cam->frame_tmp.buffer,
823 (*f)->length);
824 DBG(6, "Switched from temp. frame to frame #%d",
825 (*f)->number)
826 }
827 }
828
829 for (i = 0; i < urb->number_of_packets; i++) {
830 len = urb->iso_frame_desc[i].actual_length;
831 status = urb->iso_frame_desc[i].status;
832 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
833
834 if (status && len != 0) {
835 DBG(4, "URB failed, error in data packet "
836 "(error #%u, %s)",
837 status, symbolic(urb_errlist, status))
838 (*f)->status = F_ERROR;
839 continue;
840 }
841
842 if (len) { /* start of frame */
843
844 if ((*f)->status == F_UNUSED) {
845 (*f)->status = F_GRABBING;
846 (*f)->length = 0;
847 }
848
849 /* Buffer overflows shouldn't happen, however...*/
850 if ((*f)->length + len > (*f)->size) {
851 DBG(4, "Buffer overflow: bad data packets")
852 (*f)->status = F_ERROR;
853 }
854
855 if ((*f)->status == F_GRABBING) {
856 memcpy((*f)->buffer + (*f)->length, pos, len);
857 (*f)->length += len;
858 }
859
860 } else if ((*f)->status == F_GRABBING) { /* end of frame */
861
862 DBG(6, "Frame #%d successfully grabbed", (*f)->number)
863
864 if (cam->vpp_flag & VPP_DECOMPRESSION) {
865 err = w9968cf_vpp->check_headers((*f)->buffer,
866 (*f)->length);
867 if (err) {
868 DBG(4, "Skip corrupted frame: %s",
869 symbolic(decoder_errlist, err))
870 (*f)->status = F_UNUSED;
871 continue; /* grab this frame again */
872 }
873 }
874
875 (*f)->status = F_READY;
876 (*f)->queued = 0;
877
878 /* Take a pointer to the new frame from the FIFO list.
879 If the list is empty,we'll use the temporary frame*/
880 if (*cam->requested_frame)
881 w9968cf_pop_frame(cam, &cam->frame_current);
882 else {
883 cam->frame_current = &cam->frame_tmp;
884 (*f)->status = F_UNUSED;
885 }
886
887 } else if ((*f)->status == F_ERROR)
888 (*f)->status = F_UNUSED; /* grab it again */
889
890 PDBGG("Frame length %lu | pack.#%u | pack.len. %u | state %d",
891 (unsigned long)(*f)->length, i, len, (*f)->status)
892
893 } /* end for */
894
895 /* Resubmit this URB */
896 urb->dev = cam->usbdev;
897 urb->status = 0;
898 spin_lock(&cam->urb_lock);
899 if (cam->streaming)
900 if ((err = usb_submit_urb(urb, GFP_ATOMIC))) {
901 cam->misconfigured = 1;
902 DBG(1, "Couldn't resubmit the URB: error %d, %s",
903 err, symbolic(urb_errlist, err))
904 }
905 spin_unlock(&cam->urb_lock);
906
907 /* Wake up the user process */
908 wake_up_interruptible(&cam->wait_queue);
909}
910
911
912/*---------------------------------------------------------------------------
913 Setup the URB structures for the isochronous transfer.
914 Submit the URBs so that the data transfer begins.
915 Return 0 on success, a negative number otherwise.
916 ---------------------------------------------------------------------------*/
917static int w9968cf_start_transfer(struct w9968cf_device* cam)
918{
919 struct usb_device *udev = cam->usbdev;
920 struct urb* urb;
921 const u16 p_size = wMaxPacketSize[cam->altsetting-1];
922 u16 w, h, d;
923 int vidcapt;
924 u32 t_size;
925 int err = 0;
926 s8 i, j;
927
928 for (i = 0; i < W9968CF_URBS; i++) {
929 urb = usb_alloc_urb(W9968CF_ISO_PACKETS, GFP_KERNEL);
930 cam->urb[i] = urb;
931 if (!urb) {
932 for (j = 0; j < i; j++)
933 usb_free_urb(cam->urb[j]);
934 DBG(1, "Couldn't allocate the URB structures")
935 return -ENOMEM;
936 }
937
938 urb->dev = udev;
939 urb->context = (void*)cam;
940 urb->pipe = usb_rcvisocpipe(udev, 1);
941 urb->transfer_flags = URB_ISO_ASAP;
942 urb->number_of_packets = W9968CF_ISO_PACKETS;
943 urb->complete = w9968cf_urb_complete;
944 urb->transfer_buffer = cam->transfer_buffer[i];
945 urb->transfer_buffer_length = p_size*W9968CF_ISO_PACKETS;
946 urb->interval = 1;
947 for (j = 0; j < W9968CF_ISO_PACKETS; j++) {
948 urb->iso_frame_desc[j].offset = p_size*j;
949 urb->iso_frame_desc[j].length = p_size;
950 }
951 }
952
953 /* Transfer size per frame, in WORD ! */
954 d = cam->hw_depth;
955 w = cam->hw_width;
956 h = cam->hw_height;
957
958 t_size = (w*h*d)/16;
959
960 err = w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
961 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
962
963 /* Transfer size */
964 err += w9968cf_write_reg(cam, t_size & 0xffff, 0x3d); /* low bits */
965 err += w9968cf_write_reg(cam, t_size >> 16, 0x3e); /* high bits */
966
967 if (cam->vpp_flag & VPP_DECOMPRESSION)
968 err += w9968cf_upload_quantizationtables(cam);
969
970 vidcapt = w9968cf_read_reg(cam, 0x16); /* read picture settings */
971 err += w9968cf_write_reg(cam, vidcapt|0x8000, 0x16); /* capt. enable */
972
973 err += usb_set_interface(udev, 0, cam->altsetting);
974 err += w9968cf_write_reg(cam, 0x8a05, 0x3c); /* USB FIFO enable */
975
976 if (err || (vidcapt < 0)) {
977 for (i = 0; i < W9968CF_URBS; i++)
978 usb_free_urb(cam->urb[i]);
979 DBG(1, "Couldn't tell the camera to start the data transfer")
980 return err;
981 }
982
983 w9968cf_init_framelist(cam);
984
985 /* Begin to grab into the temporary buffer */
986 cam->frame_tmp.status = F_UNUSED;
987 cam->frame_tmp.queued = 0;
988 cam->frame_current = &cam->frame_tmp;
989
990 if (!(cam->vpp_flag & VPP_DECOMPRESSION))
991 DBG(5, "Isochronous transfer size: %lu bytes/frame",
992 (unsigned long)t_size*2)
993
994 DBG(5, "Starting the isochronous transfer...")
995
996 cam->streaming = 1;
997
998 /* Submit the URBs */
999 for (i = 0; i < W9968CF_URBS; i++) {
1000 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
1001 if (err) {
1002 cam->streaming = 0;
1003 for (j = i-1; j >= 0; j--) {
1004 usb_kill_urb(cam->urb[j]);
1005 usb_free_urb(cam->urb[j]);
1006 }
1007 DBG(1, "Couldn't send a transfer request to the "
1008 "USB core (error #%d, %s)", err,
1009 symbolic(urb_errlist, err))
1010 return err;
1011 }
1012 }
1013
1014 return 0;
1015}
1016
1017
1018/*--------------------------------------------------------------------------
1019 Stop the isochronous transfer and set alternate setting to 0 (0Mb/s).
1020 Return 0 on success, a negative number otherwise.
1021 --------------------------------------------------------------------------*/
1022static int w9968cf_stop_transfer(struct w9968cf_device* cam)
1023{
1024 struct usb_device *udev = cam->usbdev;
1025 unsigned long lock_flags;
1026 int err = 0;
1027 s8 i;
1028
1029 if (!cam->streaming)
1030 return 0;
1031
1032 /* This avoids race conditions with usb_submit_urb()
1033 in the URB completition handler */
1034 spin_lock_irqsave(&cam->urb_lock, lock_flags);
1035 cam->streaming = 0;
1036 spin_unlock_irqrestore(&cam->urb_lock, lock_flags);
1037
1038 for (i = W9968CF_URBS-1; i >= 0; i--)
1039 if (cam->urb[i]) {
1040 usb_kill_urb(cam->urb[i]);
1041 usb_free_urb(cam->urb[i]);
1042 cam->urb[i] = NULL;
1043 }
1044
1045 if (cam->disconnected)
1046 goto exit;
1047
1048 err = w9968cf_write_reg(cam, 0x0a05, 0x3c); /* stop USB transfer */
1049 err += usb_set_interface(udev, 0, 0); /* 0 Mb/s */
1050 err += w9968cf_write_reg(cam, 0x0000, 0x39); /* disable JPEG encoder */
1051 err += w9968cf_write_reg(cam, 0x0000, 0x16); /* stop video capture */
1052
1053 if (err) {
1054 DBG(2, "Failed to tell the camera to stop the isochronous "
1055 "transfer. However this is not a critical error.")
1056 return -EIO;
1057 }
1058
1059exit:
1060 DBG(5, "Isochronous transfer stopped")
1061 return 0;
1062}
1063
1064
1065/*--------------------------------------------------------------------------
1066 Write a W9968CF register.
1067 Return 0 on success, -1 otherwise.
1068 --------------------------------------------------------------------------*/
1069static int w9968cf_write_reg(struct w9968cf_device* cam, u16 value, u16 index)
1070{
1071 struct usb_device* udev = cam->usbdev;
1072 int res;
1073
1074 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1075 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1076 value, index, NULL, 0, W9968CF_USB_CTRL_TIMEOUT);
1077
1078 if (res < 0)
1079 DBG(4, "Failed to write a register "
1080 "(value 0x%04X, index 0x%02X, error #%d, %s)",
1081 value, index, res, symbolic(urb_errlist, res))
1082
1083 return (res >= 0) ? 0 : -1;
1084}
1085
1086
1087/*--------------------------------------------------------------------------
1088 Read a W9968CF register.
1089 Return the register value on success, -1 otherwise.
1090 --------------------------------------------------------------------------*/
1091static int w9968cf_read_reg(struct w9968cf_device* cam, u16 index)
1092{
1093 struct usb_device* udev = cam->usbdev;
1094 u16* buff = cam->control_buffer;
1095 int res;
1096
1097 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 1,
1098 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1099 0, index, buff, 2, W9968CF_USB_CTRL_TIMEOUT);
1100
1101 if (res < 0)
1102 DBG(4, "Failed to read a register "
1103 "(index 0x%02X, error #%d, %s)",
1104 index, res, symbolic(urb_errlist, res))
1105
1106 return (res >= 0) ? (int)(*buff) : -1;
1107}
1108
1109
1110/*--------------------------------------------------------------------------
1111 Write 64-bit data to the fast serial bus registers.
1112 Return 0 on success, -1 otherwise.
1113 --------------------------------------------------------------------------*/
1114static int w9968cf_write_fsb(struct w9968cf_device* cam, u16* data)
1115{
1116 struct usb_device* udev = cam->usbdev;
1117 u16 value;
1118 int res;
1119
1120 value = *data++;
1121
1122 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1123 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1124 value, 0x06, data, 6, W9968CF_USB_CTRL_TIMEOUT);
1125
1126 if (res < 0)
1127 DBG(4, "Failed to write the FSB registers "
1128 "(error #%d, %s)", res, symbolic(urb_errlist, res))
1129
1130 return (res >= 0) ? 0 : -1;
1131}
1132
1133
1134/*--------------------------------------------------------------------------
1135 Write data to the serial bus control register.
1136 Return 0 on success, a negative number otherwise.
1137 --------------------------------------------------------------------------*/
1138static int w9968cf_write_sb(struct w9968cf_device* cam, u16 value)
1139{
1140 int err = 0;
1141
1142 err = w9968cf_write_reg(cam, value, 0x01);
1143 udelay(W9968CF_I2C_BUS_DELAY);
1144
1145 return err;
1146}
1147
1148
1149/*--------------------------------------------------------------------------
1150 Read data from the serial bus control register.
1151 Return 0 on success, a negative number otherwise.
1152 --------------------------------------------------------------------------*/
1153static int w9968cf_read_sb(struct w9968cf_device* cam)
1154{
1155 int v = 0;
1156
1157 v = w9968cf_read_reg(cam, 0x01);
1158 udelay(W9968CF_I2C_BUS_DELAY);
1159
1160 return v;
1161}
1162
1163
1164/*--------------------------------------------------------------------------
1165 Upload quantization tables for the JPEG compression.
1166 This function is called by w9968cf_start_transfer().
1167 Return 0 on success, a negative number otherwise.
1168 --------------------------------------------------------------------------*/
1169static int w9968cf_upload_quantizationtables(struct w9968cf_device* cam)
1170{
1171 u16 a, b;
1172 int err = 0, i, j;
1173
1174 err += w9968cf_write_reg(cam, 0x0010, 0x39); /* JPEG clock enable */
1175
1176 for (i = 0, j = 0; i < 32; i++, j += 2) {
1177 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
1178 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
1179 err += w9968cf_write_reg(cam, a, 0x40+i);
1180 err += w9968cf_write_reg(cam, b, 0x60+i);
1181 }
1182 err += w9968cf_write_reg(cam, 0x0012, 0x39); /* JPEG encoder enable */
1183
1184 return err;
1185}
1186
1187
1188
1189/****************************************************************************
1190 * Low-level I2C I/O functions. *
1191 * The adapter supports the following I2C transfer functions: *
1192 * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) *
1193 * i2c_adap_read_byte_data() *
1194 * i2c_adap_read_byte() *
1195 ****************************************************************************/
1196
1197static int w9968cf_smbus_start(struct w9968cf_device* cam)
1198{
1199 int err = 0;
1200
1201 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1202 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1203
1204 return err;
1205}
1206
1207
1208static int w9968cf_smbus_stop(struct w9968cf_device* cam)
1209{
1210 int err = 0;
1211
1212 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1213 err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1214
1215 return err;
1216}
1217
1218
1219static int w9968cf_smbus_write_byte(struct w9968cf_device* cam, u8 v)
1220{
1221 u8 bit;
1222 int err = 0, sda;
1223
1224 for (bit = 0 ; bit < 8 ; bit++) {
1225 sda = (v & 0x80) ? 2 : 0;
1226 v <<= 1;
1227 /* SDE=1, SDA=sda, SCL=0 */
1228 err += w9968cf_write_sb(cam, 0x10 | sda);
1229 /* SDE=1, SDA=sda, SCL=1 */
1230 err += w9968cf_write_sb(cam, 0x11 | sda);
1231 /* SDE=1, SDA=sda, SCL=0 */
1232 err += w9968cf_write_sb(cam, 0x10 | sda);
1233 }
1234
1235 return err;
1236}
1237
1238
1239static int w9968cf_smbus_read_byte(struct w9968cf_device* cam, u8* v)
1240{
1241 u8 bit;
1242 int err = 0;
1243
1244 *v = 0;
1245 for (bit = 0 ; bit < 8 ; bit++) {
1246 *v <<= 1;
1247 err += w9968cf_write_sb(cam, 0x0013);
1248 *v |= (w9968cf_read_sb(cam) & 0x0008) ? 1 : 0;
1249 err += w9968cf_write_sb(cam, 0x0012);
1250 }
1251
1252 return err;
1253}
1254
1255
1256static int w9968cf_smbus_write_ack(struct w9968cf_device* cam)
1257{
1258 int err = 0;
1259
1260 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1261 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1262 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1263
1264 return err;
1265}
1266
1267
1268static int w9968cf_smbus_read_ack(struct w9968cf_device* cam)
1269{
1270 int err = 0, sda;
1271
1272 err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1273 sda = (w9968cf_read_sb(cam) & 0x08) ? 1 : 0; /* sda = SDA */
1274 err += w9968cf_write_sb(cam, 0x0012); /* SDE=1, SDA=1, SCL=0 */
1275 if (sda < 0)
1276 err += sda;
1277 if (sda == 1) {
1278 DBG(6, "Couldn't receive the ACK")
1279 err += -1;
1280 }
1281
1282 return err;
1283}
1284
1285
1286/* This seems to refresh the communication through the serial bus */
1287static int w9968cf_smbus_refresh_bus(struct w9968cf_device* cam)
1288{
1289 int err = 0, j;
1290
1291 for (j = 1; j <= 10; j++) {
1292 err = w9968cf_write_reg(cam, 0x0020, 0x01);
1293 err += w9968cf_write_reg(cam, 0x0000, 0x01);
1294 if (err)
1295 break;
1296 }
1297
1298 return err;
1299}
1300
1301
1302/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
1303static int
1304w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam,
1305 u16 address, u8 subaddress,u8 value)
1306{
1307 u16* data = cam->data_buffer;
1308 int err = 0;
1309
1310 err += w9968cf_smbus_refresh_bus(cam);
1311
1312 /* Enable SBUS outputs */
1313 err += w9968cf_write_sb(cam, 0x0020);
1314
1315 data[0] = 0x082f | ((address & 0x80) ? 0x1500 : 0x0);
1316 data[0] |= (address & 0x40) ? 0x4000 : 0x0;
1317 data[1] = 0x2082 | ((address & 0x40) ? 0x0005 : 0x0);
1318 data[1] |= (address & 0x20) ? 0x0150 : 0x0;
1319 data[1] |= (address & 0x10) ? 0x5400 : 0x0;
1320 data[2] = 0x8208 | ((address & 0x08) ? 0x0015 : 0x0);
1321 data[2] |= (address & 0x04) ? 0x0540 : 0x0;
1322 data[2] |= (address & 0x02) ? 0x5000 : 0x0;
1323 data[3] = 0x1d20 | ((address & 0x02) ? 0x0001 : 0x0);
1324 data[3] |= (address & 0x01) ? 0x0054 : 0x0;
1325
1326 err += w9968cf_write_fsb(cam, data);
1327
1328 data[0] = 0x8208 | ((subaddress & 0x80) ? 0x0015 : 0x0);
1329 data[0] |= (subaddress & 0x40) ? 0x0540 : 0x0;
1330 data[0] |= (subaddress & 0x20) ? 0x5000 : 0x0;
1331 data[1] = 0x0820 | ((subaddress & 0x20) ? 0x0001 : 0x0);
1332 data[1] |= (subaddress & 0x10) ? 0x0054 : 0x0;
1333 data[1] |= (subaddress & 0x08) ? 0x1500 : 0x0;
1334 data[1] |= (subaddress & 0x04) ? 0x4000 : 0x0;
1335 data[2] = 0x2082 | ((subaddress & 0x04) ? 0x0005 : 0x0);
1336 data[2] |= (subaddress & 0x02) ? 0x0150 : 0x0;
1337 data[2] |= (subaddress & 0x01) ? 0x5400 : 0x0;
1338 data[3] = 0x001d;
1339
1340 err += w9968cf_write_fsb(cam, data);
1341
1342 data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
1343 data[0] |= (value & 0x40) ? 0x0540 : 0x0;
1344 data[0] |= (value & 0x20) ? 0x5000 : 0x0;
1345 data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
1346 data[1] |= (value & 0x10) ? 0x0054 : 0x0;
1347 data[1] |= (value & 0x08) ? 0x1500 : 0x0;
1348 data[1] |= (value & 0x04) ? 0x4000 : 0x0;
1349 data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
1350 data[2] |= (value & 0x02) ? 0x0150 : 0x0;
1351 data[2] |= (value & 0x01) ? 0x5400 : 0x0;
1352 data[3] = 0xfe1d;
1353
1354 err += w9968cf_write_fsb(cam, data);
1355
1356 /* Disable SBUS outputs */
1357 err += w9968cf_write_sb(cam, 0x0000);
1358
1359 if (!err)
1360 DBG(5, "I2C write byte data done, addr.0x%04X, subaddr.0x%02X "
1361 "value 0x%02X", address, subaddress, value)
1362 else
1363 DBG(5, "I2C write byte data failed, addr.0x%04X, "
1364 "subaddr.0x%02X, value 0x%02X",
1365 address, subaddress, value)
1366
1367 return err;
1368}
1369
1370
1371/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
1372static int
1373w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam,
1374 u16 address, u8 subaddress,
1375 u8* value)
1376{
1377 int err = 0;
1378
1379 /* Serial data enable */
1380 err += w9968cf_write_sb(cam, 0x0013); /* don't change ! */
1381
1382 err += w9968cf_smbus_start(cam);
1383 err += w9968cf_smbus_write_byte(cam, address);
1384 err += w9968cf_smbus_read_ack(cam);
1385 err += w9968cf_smbus_write_byte(cam, subaddress);
1386 err += w9968cf_smbus_read_ack(cam);
1387 err += w9968cf_smbus_stop(cam);
1388 err += w9968cf_smbus_start(cam);
1389 err += w9968cf_smbus_write_byte(cam, address + 1);
1390 err += w9968cf_smbus_read_ack(cam);
1391 err += w9968cf_smbus_read_byte(cam, value);
1392 err += w9968cf_smbus_write_ack(cam);
1393 err += w9968cf_smbus_stop(cam);
1394
1395 /* Serial data disable */
1396 err += w9968cf_write_sb(cam, 0x0000);
1397
1398 if (!err)
1399 DBG(5, "I2C read byte data done, addr.0x%04X, "
1400 "subaddr.0x%02X, value 0x%02X",
1401 address, subaddress, *value)
1402 else
1403 DBG(5, "I2C read byte data failed, addr.0x%04X, "
1404 "subaddr.0x%02X, wrong value 0x%02X",
1405 address, subaddress, *value)
1406
1407 return err;
1408}
1409
1410
1411/* SMBus protocol: S Addr+1 Rd [A] [Value] NA P */
1412static int
1413w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
1414 u16 address, u8* value)
1415{
1416 int err = 0;
1417
1418 /* Serial data enable */
1419 err += w9968cf_write_sb(cam, 0x0013);
1420
1421 err += w9968cf_smbus_start(cam);
1422 err += w9968cf_smbus_write_byte(cam, address + 1);
1423 err += w9968cf_smbus_read_ack(cam);
1424 err += w9968cf_smbus_read_byte(cam, value);
1425 err += w9968cf_smbus_write_ack(cam);
1426 err += w9968cf_smbus_stop(cam);
1427
1428 /* Serial data disable */
1429 err += w9968cf_write_sb(cam, 0x0000);
1430
1431 if (!err)
1432 DBG(5, "I2C read byte done, addr.0x%04X, "
1433 "value 0x%02X", address, *value)
1434 else
1435 DBG(5, "I2C read byte failed, addr.0x%04X, "
1436 "wrong value 0x%02X", address, *value)
1437
1438 return err;
1439}
1440
1441
1442/* SMBus protocol: S Addr Wr [A] Value [A] P */
1443static int
1444w9968cf_i2c_adap_write_byte(struct w9968cf_device* cam,
1445 u16 address, u8 value)
1446{
1447 DBG(4, "i2c_write_byte() is an unsupported transfer mode")
1448 return -EINVAL;
1449}
1450
1451
1452
1453/****************************************************************************
1454 * I2C interface to kernel *
1455 ****************************************************************************/
1456
1457static int
1458w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
1459 unsigned short flags, char read_write, u8 command,
1460 int size, union i2c_smbus_data *data)
1461{
1462 struct w9968cf_device* cam = i2c_get_adapdata(adapter);
1463 u8 i;
1464 int err = 0;
1465
1466 switch (addr) {
1467 case OV6xx0_SID:
1468 case OV7xx0_SID:
1469 break;
1470 default:
1471 DBG(4, "Rejected slave ID 0x%04X", addr)
1472 return -EINVAL;
1473 }
1474
1475 if (size == I2C_SMBUS_BYTE) {
1476 /* Why addr <<= 1? See OVXXX0_SID defines in ovcamchip.h */
1477 addr <<= 1;
1478
1479 if (read_write == I2C_SMBUS_WRITE)
1480 err = w9968cf_i2c_adap_write_byte(cam, addr, command);
1481 else if (read_write == I2C_SMBUS_READ)
1482 err = w9968cf_i2c_adap_read_byte(cam,addr,&data->byte);
1483
1484 } else if (size == I2C_SMBUS_BYTE_DATA) {
1485 addr <<= 1;
1486
1487 if (read_write == I2C_SMBUS_WRITE)
1488 err = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr,
1489 command, data->byte);
1490 else if (read_write == I2C_SMBUS_READ) {
1491 for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) {
1492 err = w9968cf_i2c_adap_read_byte_data(cam,addr,
1493 command, &data->byte);
1494 if (err) {
1495 if (w9968cf_smbus_refresh_bus(cam)) {
1496 err = -EIO;
1497 break;
1498 }
1499 } else
1500 break;
1501 }
1502
1503 } else
1504 return -EINVAL;
1505
1506 } else {
1507 DBG(4, "Unsupported I2C transfer mode (%d)", size)
1508 return -EINVAL;
1509 }
1510
1511 return err;
1512}
1513
1514
1515static u32 w9968cf_i2c_func(struct i2c_adapter* adap)
1516{
1517 return I2C_FUNC_SMBUS_READ_BYTE |
1518 I2C_FUNC_SMBUS_READ_BYTE_DATA |
1519 I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
1520}
1521
1522
1523static int w9968cf_i2c_attach_inform(struct i2c_client* client)
1524{
1525 struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1526 const char* clientname = i2c_clientname(client);
1527 int id = client->driver->id, err = 0;
1528
1529 if (id == I2C_DRIVERID_OVCAMCHIP) {
1530 cam->sensor_client = client;
1531 err = w9968cf_sensor_init(cam);
1532 if (err) {
1533 cam->sensor_client = NULL;
1534 return err;
1535 }
1536 } else {
1537 DBG(4, "Rejected client [%s] with driver [%s]",
1538 clientname, client->driver->name)
1539 return -EINVAL;
1540 }
1541
1542 DBG(5, "I2C attach client [%s] with driver [%s]",
1543 clientname, client->driver->name)
1544
1545 return 0;
1546}
1547
1548
1549static int w9968cf_i2c_detach_inform(struct i2c_client* client)
1550{
1551 struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1552 const char* clientname = i2c_clientname(client);
1553
1554 if (cam->sensor_client == client)
1555 cam->sensor_client = NULL;
1556
1557 DBG(5, "I2C detach client [%s]", clientname)
1558
1559 return 0;
1560}
1561
1562
1563static int
1564w9968cf_i2c_control(struct i2c_adapter* adapter, unsigned int cmd,
1565 unsigned long arg)
1566{
1567 return 0;
1568}
1569
1570
1571static int w9968cf_i2c_init(struct w9968cf_device* cam)
1572{
1573 int err = 0;
1574
1575 static struct i2c_algorithm algo = {
1576 .name = "W996[87]CF algorithm",
1577 .id = I2C_ALGO_SMBUS,
1578 .smbus_xfer = w9968cf_i2c_smbus_xfer,
1579 .algo_control = w9968cf_i2c_control,
1580 .functionality = w9968cf_i2c_func,
1581 };
1582
1583 static struct i2c_adapter adap = {
1584 .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_W9968CF,
1585 .class = I2C_CLASS_CAM_DIGITAL,
1586 .owner = THIS_MODULE,
1587 .client_register = w9968cf_i2c_attach_inform,
1588 .client_unregister = w9968cf_i2c_detach_inform,
1589 .algo = &algo,
1590 };
1591
1592 memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
1593 strcpy(cam->i2c_adapter.name, "w9968cf");
1594 i2c_set_adapdata(&cam->i2c_adapter, cam);
1595
1596 DBG(6, "Registering I2C adapter with kernel...")
1597
1598 err = i2c_add_adapter(&cam->i2c_adapter);
1599 if (err)
1600 DBG(1, "Failed to register the I2C adapter")
1601 else
1602 DBG(5, "I2C adapter registered")
1603
1604 return err;
1605}
1606
1607
1608
1609/****************************************************************************
1610 * Helper functions *
1611 ****************************************************************************/
1612
1613/*--------------------------------------------------------------------------
1614 Turn on the LED on some webcams. A beep should be heard too.
1615 Return 0 on success, a negative number otherwise.
1616 --------------------------------------------------------------------------*/
1617static int w9968cf_turn_on_led(struct w9968cf_device* cam)
1618{
1619 int err = 0;
1620
1621 err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power-down */
1622 err += w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
1623 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
1624 err += w9968cf_write_reg(cam, 0x0010, 0x01); /* serial bus, SDS high */
1625 err += w9968cf_write_reg(cam, 0x0000, 0x01); /* serial bus, SDS low */
1626 err += w9968cf_write_reg(cam, 0x0010, 0x01); /* ..high 'beep-beep' */
1627
1628 if (err)
1629 DBG(2, "Couldn't turn on the LED")
1630
1631 DBG(5, "LED turned on")
1632
1633 return err;
1634}
1635
1636
1637/*--------------------------------------------------------------------------
1638 Write some registers for the device initialization.
1639 This function is called once on open().
1640 Return 0 on success, a negative number otherwise.
1641 --------------------------------------------------------------------------*/
1642static int w9968cf_init_chip(struct w9968cf_device* cam)
1643{
1644 unsigned long hw_bufsize = cam->maxwidth*cam->maxheight*2,
1645 y0 = 0x0000,
1646 u0 = y0 + hw_bufsize/2,
1647 v0 = u0 + hw_bufsize/4,
1648 y1 = v0 + hw_bufsize/4,
1649 u1 = y1 + hw_bufsize/2,
1650 v1 = u1 + hw_bufsize/4;
1651 int err = 0;
1652
1653 err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power off */
1654 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* power on */
1655
1656 err += w9968cf_write_reg(cam, 0x405d, 0x03); /* DRAM timings */
1657 err += w9968cf_write_reg(cam, 0x0030, 0x04); /* SDRAM timings */
1658
1659 err += w9968cf_write_reg(cam, y0 & 0xffff, 0x20); /* Y buf.0, low */
1660 err += w9968cf_write_reg(cam, y0 >> 16, 0x21); /* Y buf.0, high */
1661 err += w9968cf_write_reg(cam, u0 & 0xffff, 0x24); /* U buf.0, low */
1662 err += w9968cf_write_reg(cam, u0 >> 16, 0x25); /* U buf.0, high */
1663 err += w9968cf_write_reg(cam, v0 & 0xffff, 0x28); /* V buf.0, low */
1664 err += w9968cf_write_reg(cam, v0 >> 16, 0x29); /* V buf.0, high */
1665
1666 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x22); /* Y buf.1, low */
1667 err += w9968cf_write_reg(cam, y1 >> 16, 0x23); /* Y buf.1, high */
1668 err += w9968cf_write_reg(cam, u1 & 0xffff, 0x26); /* U buf.1, low */
1669 err += w9968cf_write_reg(cam, u1 >> 16, 0x27); /* U buf.1, high */
1670 err += w9968cf_write_reg(cam, v1 & 0xffff, 0x2a); /* V buf.1, low */
1671 err += w9968cf_write_reg(cam, v1 >> 16, 0x2b); /* V buf.1, high */
1672
1673 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x32); /* JPEG buf 0 low */
1674 err += w9968cf_write_reg(cam, y1 >> 16, 0x33); /* JPEG buf 0 high */
1675
1676 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x34); /* JPEG buf 1 low */
1677 err += w9968cf_write_reg(cam, y1 >> 16, 0x35); /* JPEG bug 1 high */
1678
1679 err += w9968cf_write_reg(cam, 0x0000, 0x36);/* JPEG restart interval */
1680 err += w9968cf_write_reg(cam, 0x0804, 0x37);/*JPEG VLE FIFO threshold*/
1681 err += w9968cf_write_reg(cam, 0x0000, 0x38);/* disable hw up-scaling */
1682 err += w9968cf_write_reg(cam, 0x0000, 0x3f); /* JPEG/MCTL test data */
1683
1684 err += w9968cf_set_picture(cam, cam->picture); /* this before */
1685 err += w9968cf_set_window(cam, cam->window);
1686
1687 if (err)
1688 DBG(1, "Chip initialization failed")
1689 else
1690 DBG(5, "Chip successfully initialized")
1691
1692 return err;
1693}
1694
1695
1696/*--------------------------------------------------------------------------
1697 Return non-zero if the palette is supported, 0 otherwise.
1698 --------------------------------------------------------------------------*/
1699static inline u16 w9968cf_valid_palette(u16 palette)
1700{
1701 u8 i = 0;
1702 while (w9968cf_formatlist[i].palette != 0) {
1703 if (palette == w9968cf_formatlist[i].palette)
1704 return palette;
1705 i++;
1706 }
1707 return 0;
1708}
1709
1710
1711/*--------------------------------------------------------------------------
1712 Return the depth corresponding to the given palette.
1713 Palette _must_ be supported !
1714 --------------------------------------------------------------------------*/
1715static inline u16 w9968cf_valid_depth(u16 palette)
1716{
1717 u8 i=0;
1718 while (w9968cf_formatlist[i].palette != palette)
1719 i++;
1720
1721 return w9968cf_formatlist[i].depth;
1722}
1723
1724
1725/*--------------------------------------------------------------------------
1726 Return non-zero if the format requires decompression, 0 otherwise.
1727 --------------------------------------------------------------------------*/
1728static inline u8 w9968cf_need_decompression(u16 palette)
1729{
1730 u8 i = 0;
1731 while (w9968cf_formatlist[i].palette != 0) {
1732 if (palette == w9968cf_formatlist[i].palette)
1733 return w9968cf_formatlist[i].compression;
1734 i++;
1735 }
1736 return 0;
1737}
1738
1739
1740/*--------------------------------------------------------------------------
1741 Change the picture settings of the camera.
1742 Return 0 on success, a negative number otherwise.
1743 --------------------------------------------------------------------------*/
1744static int
1745w9968cf_set_picture(struct w9968cf_device* cam, struct video_picture pict)
1746{
1747 u16 fmt, hw_depth, hw_palette, reg_v = 0x0000;
1748 int err = 0;
1749
1750 /* Make sure we are using a valid depth */
1751 pict.depth = w9968cf_valid_depth(pict.palette);
1752
1753 fmt = pict.palette;
1754
1755 hw_depth = pict.depth; /* depth used by the winbond chip */
1756 hw_palette = pict.palette; /* palette used by the winbond chip */
1757
1758 /* VS & HS polarities */
1759 reg_v = (cam->vs_polarity << 12) | (cam->hs_polarity << 11);
1760
1761 switch (fmt)
1762 {
1763 case VIDEO_PALETTE_UYVY:
1764 reg_v |= 0x0000;
1765 cam->vpp_flag = VPP_NONE;
1766 break;
1767 case VIDEO_PALETTE_YUV422P:
1768 reg_v |= 0x0002;
1769 cam->vpp_flag = VPP_DECOMPRESSION;
1770 break;
1771 case VIDEO_PALETTE_YUV420:
1772 case VIDEO_PALETTE_YUV420P:
1773 reg_v |= 0x0003;
1774 cam->vpp_flag = VPP_DECOMPRESSION;
1775 break;
1776 case VIDEO_PALETTE_YUYV:
1777 case VIDEO_PALETTE_YUV422:
1778 reg_v |= 0x0000;
1779 cam->vpp_flag = VPP_SWAP_YUV_BYTES;
1780 hw_palette = VIDEO_PALETTE_UYVY;
1781 break;
1782 /* Original video is used instead of RGBX palettes.
1783 Software conversion later. */
1784 case VIDEO_PALETTE_GREY:
1785 case VIDEO_PALETTE_RGB555:
1786 case VIDEO_PALETTE_RGB565:
1787 case VIDEO_PALETTE_RGB24:
1788 case VIDEO_PALETTE_RGB32:
1789 reg_v |= 0x0000; /* UYVY 16 bit is used */
1790 hw_depth = 16;
1791 hw_palette = VIDEO_PALETTE_UYVY;
1792 cam->vpp_flag = VPP_UYVY_TO_RGBX;
1793 break;
1794 }
1795
1796 /* NOTE: due to memory issues, it is better to disable the hardware
1797 double buffering during compression */
1798 if (cam->double_buffer && !(cam->vpp_flag & VPP_DECOMPRESSION))
1799 reg_v |= 0x0080;
1800
1801 if (cam->clamping)
1802 reg_v |= 0x0020;
1803
1804 if (cam->filter_type == 1)
1805 reg_v |= 0x0008;
1806 else if (cam->filter_type == 2)
1807 reg_v |= 0x000c;
1808
1809 if ((err = w9968cf_write_reg(cam, reg_v, 0x16)))
1810 goto error;
1811
1812 if ((err = w9968cf_sensor_update_picture(cam, pict)))
1813 goto error;
1814
1815 /* If all went well, update the device data structure */
1816 memcpy(&cam->picture, &pict, sizeof(pict));
1817 cam->hw_depth = hw_depth;
1818 cam->hw_palette = hw_palette;
1819
1820 /* Settings changed, so we clear the frame buffers */
1821 memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
1822
1823 DBG(4, "Palette is %s, depth is %u bpp",
1824 symbolic(v4l1_plist, pict.palette), pict.depth)
1825
1826 return 0;
1827
1828error:
1829 DBG(1, "Failed to change picture settings")
1830 return err;
1831}
1832
1833
1834/*--------------------------------------------------------------------------
1835 Change the capture area size of the camera.
1836 This function _must_ be called _after_ w9968cf_set_picture().
1837 Return 0 on success, a negative number otherwise.
1838 --------------------------------------------------------------------------*/
1839static int
1840w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
1841{
1842 u16 x, y, w, h, scx, scy, cw, ch, ax, ay;
1843 unsigned long fw, fh;
1844 struct ovcamchip_window s_win;
1845 int err = 0;
1846
1847 /* Work around to avoid FP arithmetics */
1848 #define __SC(x) ((x) << 10)
1849 #define __UNSC(x) ((x) >> 10)
1850
1851 /* Make sure we are using a supported resolution */
1852 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
1853 (u16*)&win.height)))
1854 goto error;
1855
1856 /* Scaling factors */
1857 fw = __SC(win.width) / cam->maxwidth;
1858 fh = __SC(win.height) / cam->maxheight;
1859
1860 /* Set up the width and height values used by the chip */
1861 if ((win.width > cam->maxwidth) || (win.height > cam->maxheight)) {
1862 cam->vpp_flag |= VPP_UPSCALE;
1863 /* Calculate largest w,h mantaining the same w/h ratio */
1864 w = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1865 h = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1866 if (w < cam->minwidth) /* just in case */
1867 w = cam->minwidth;
1868 if (h < cam->minheight) /* just in case */
1869 h = cam->minheight;
1870 } else {
1871 cam->vpp_flag &= ~VPP_UPSCALE;
1872 w = win.width;
1873 h = win.height;
1874 }
1875
1876 /* x,y offsets of the cropped area */
1877 scx = cam->start_cropx;
1878 scy = cam->start_cropy;
1879
1880 /* Calculate cropped area manteining the right w/h ratio */
1881 if (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) {
1882 cw = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1883 ch = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1884 } else {
1885 cw = w;
1886 ch = h;
1887 }
1888
1889 /* Setup the window of the sensor */
1890 s_win.format = VIDEO_PALETTE_UYVY;
1891 s_win.width = cam->maxwidth;
1892 s_win.height = cam->maxheight;
1893 s_win.quarter = 0; /* full progressive video */
1894
1895 /* Center it */
1896 s_win.x = (s_win.width - cw) / 2;
1897 s_win.y = (s_win.height - ch) / 2;
1898
1899 /* Clock divisor */
1900 if (cam->clockdiv >= 0)
1901 s_win.clockdiv = cam->clockdiv; /* manual override */
1902 else
1903 switch (cam->sensor) {
1904 case CC_OV6620:
1905 s_win.clockdiv = 0;
1906 break;
1907 case CC_OV6630:
1908 s_win.clockdiv = 0;
1909 break;
1910 case CC_OV76BE:
1911 case CC_OV7610:
1912 case CC_OV7620:
1913 s_win.clockdiv = 0;
1914 break;
1915 default:
1916 s_win.clockdiv = W9968CF_DEF_CLOCKDIVISOR;
1917 }
1918
1919 /* We have to scale win.x and win.y offsets */
1920 if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1921 || (cam->vpp_flag & VPP_UPSCALE) ) {
1922 ax = __SC(win.x)/fw;
1923 ay = __SC(win.y)/fh;
1924 } else {
1925 ax = win.x;
1926 ay = win.y;
1927 }
1928
1929 if ((ax + cw) > cam->maxwidth)
1930 ax = cam->maxwidth - cw;
1931
1932 if ((ay + ch) > cam->maxheight)
1933 ay = cam->maxheight - ch;
1934
1935 /* Adjust win.x, win.y */
1936 if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1937 || (cam->vpp_flag & VPP_UPSCALE) ) {
1938 win.x = __UNSC(ax*fw);
1939 win.y = __UNSC(ay*fh);
1940 } else {
1941 win.x = ax;
1942 win.y = ay;
1943 }
1944
1945 /* Offsets used by the chip */
1946 x = ax + s_win.x;
1947 y = ay + s_win.y;
1948
1949 /* Go ! */
1950 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_MODE, &s_win)))
1951 goto error;
1952
1953 err += w9968cf_write_reg(cam, scx + x, 0x10);
1954 err += w9968cf_write_reg(cam, scy + y, 0x11);
1955 err += w9968cf_write_reg(cam, scx + x + cw, 0x12);
1956 err += w9968cf_write_reg(cam, scy + y + ch, 0x13);
1957 err += w9968cf_write_reg(cam, w, 0x14);
1958 err += w9968cf_write_reg(cam, h, 0x15);
1959
1960 /* JPEG width & height */
1961 err += w9968cf_write_reg(cam, w, 0x30);
1962 err += w9968cf_write_reg(cam, h, 0x31);
1963
1964 /* Y & UV frame buffer strides (in WORD) */
1965 if (cam->vpp_flag & VPP_DECOMPRESSION) {
1966 err += w9968cf_write_reg(cam, w/2, 0x2c);
1967 err += w9968cf_write_reg(cam, w/4, 0x2d);
1968 } else
1969 err += w9968cf_write_reg(cam, w, 0x2c);
1970
1971 if (err)
1972 goto error;
1973
1974 /* If all went well, update the device data structure */
1975 memcpy(&cam->window, &win, sizeof(win));
1976 cam->hw_width = w;
1977 cam->hw_height = h;
1978
1979 /* Settings changed, so we clear the frame buffers */
1980 memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
1981
1982 DBG(4, "The capture area is %dx%d, Offset (x,y)=(%u,%u)",
1983 win.width, win.height, win.x, win.y)
1984
1985 PDBGG("x=%u ,y=%u, w=%u, h=%u, ax=%u, ay=%u, s_win.x=%u, s_win.y=%u, "
1986 "cw=%u, ch=%u, win.x=%u, win.y=%u, win.width=%u, win.height=%u",
1987 x, y, w, h, ax, ay, s_win.x, s_win.y, cw, ch, win.x, win.y,
1988 win.width, win.height)
1989
1990 return 0;
1991
1992error:
1993 DBG(1, "Failed to change the capture area size")
1994 return err;
1995}
1996
1997
1998/*--------------------------------------------------------------------------
1999 Adjust the asked values for window width and height.
2000 Return 0 on success, -1 otherwise.
2001 --------------------------------------------------------------------------*/
2002static int
2003w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height)
2004{
2005 u16 maxw, maxh;
2006
2007 if ((*width < cam->minwidth) || (*height < cam->minheight))
2008 return -ERANGE;
2009
2010 maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
2011 w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
2012 : cam->maxwidth;
2013 maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
2014 w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
2015 : cam->maxheight;
2016
2017 if (*width > maxw)
2018 *width = maxw;
2019 if (*height > maxh)
2020 *height = maxh;
2021
2022 if (cam->vpp_flag & VPP_DECOMPRESSION) {
2023 *width &= ~15L; /* multiple of 16 */
2024 *height &= ~15L;
2025 }
2026
2027 PDBGG("Window size adjusted w=%u, h=%u ", *width, *height)
2028
2029 return 0;
2030}
2031
2032
2033/*--------------------------------------------------------------------------
2034 Initialize the FIFO list of requested frames.
2035 --------------------------------------------------------------------------*/
2036static void w9968cf_init_framelist(struct w9968cf_device* cam)
2037{
2038 u8 i;
2039
2040 for (i = 0; i < cam->nbuffers; i++) {
2041 cam->requested_frame[i] = NULL;
2042 cam->frame[i].queued = 0;
2043 cam->frame[i].status = F_UNUSED;
2044 }
2045}
2046
2047
2048/*--------------------------------------------------------------------------
2049 Add a frame in the FIFO list of requested frames.
2050 This function is called in process context.
2051 --------------------------------------------------------------------------*/
2052static void w9968cf_push_frame(struct w9968cf_device* cam, u8 f_num)
2053{
2054 u8 f;
2055 unsigned long lock_flags;
2056
2057 spin_lock_irqsave(&cam->flist_lock, lock_flags);
2058
2059 for (f=0; cam->requested_frame[f] != NULL; f++);
2060 cam->requested_frame[f] = &cam->frame[f_num];
2061 cam->frame[f_num].queued = 1;
2062 cam->frame[f_num].status = F_UNUSED; /* clear the status */
2063
2064 spin_unlock_irqrestore(&cam->flist_lock, lock_flags);
2065
2066 DBG(6, "Frame #%u pushed into the FIFO list. Position %u", f_num, f)
2067}
2068
2069
2070/*--------------------------------------------------------------------------
2071 Read, store and remove the first pointer in the FIFO list of requested
2072 frames. This function is called in interrupt context.
2073 --------------------------------------------------------------------------*/
2074static void
2075w9968cf_pop_frame(struct w9968cf_device* cam, struct w9968cf_frame_t** framep)
2076{
2077 u8 i;
2078
2079 spin_lock(&cam->flist_lock);
2080
2081 *framep = cam->requested_frame[0];
2082
2083 /* Shift the list of pointers */
2084 for (i = 0; i < cam->nbuffers-1; i++)
2085 cam->requested_frame[i] = cam->requested_frame[i+1];
2086 cam->requested_frame[i] = NULL;
2087
2088 spin_unlock(&cam->flist_lock);
2089
2090 DBG(6,"Popped frame #%d from the list", (*framep)->number)
2091}
2092
2093
2094/*--------------------------------------------------------------------------
2095 High-level video post-processing routine on grabbed frames.
2096 Return 0 on success, a negative number otherwise.
2097 --------------------------------------------------------------------------*/
2098static int
2099w9968cf_postprocess_frame(struct w9968cf_device* cam,
2100 struct w9968cf_frame_t* fr)
2101{
2102 void *pIn = fr->buffer, *pOut = cam->frame_vpp.buffer, *tmp;
2103 u16 w = cam->window.width,
2104 h = cam->window.height,
2105 d = cam->picture.depth,
2106 fmt = cam->picture.palette,
2107 rgb = cam->force_rgb,
2108 hw_w = cam->hw_width,
2109 hw_h = cam->hw_height,
2110 hw_d = cam->hw_depth;
2111 int err = 0;
2112
2113 #define _PSWAP(pIn, pOut) {tmp = (pIn); (pIn) = (pOut); (pOut) = tmp;}
2114
2115 if (cam->vpp_flag & VPP_DECOMPRESSION) {
2116 memcpy(pOut, pIn, fr->length);
2117 _PSWAP(pIn, pOut)
2118 err = w9968cf_vpp->decode(pIn, fr->length, hw_w, hw_h, pOut);
2119 PDBGG("Compressed frame length: %lu",(unsigned long)fr->length)
2120 fr->length = (hw_w*hw_h*hw_d)/8;
2121 _PSWAP(pIn, pOut)
2122 if (err) {
2123 DBG(4, "An error occurred while decoding the frame: "
2124 "%s", symbolic(decoder_errlist, err))
2125 return err;
2126 } else
2127 DBG(6, "Frame decoded")
2128 }
2129
2130 if (cam->vpp_flag & VPP_SWAP_YUV_BYTES) {
2131 w9968cf_vpp->swap_yuvbytes(pIn, fr->length);
2132 DBG(6, "Original UYVY component ordering changed")
2133 }
2134
2135 if (cam->vpp_flag & VPP_UPSCALE) {
2136 w9968cf_vpp->scale_up(pIn, pOut, hw_w, hw_h, hw_d, w, h);
2137 fr->length = (w*h*hw_d)/8;
2138 _PSWAP(pIn, pOut)
2139 DBG(6, "Vertical up-scaling done: %u,%u,%ubpp->%u,%u",
2140 hw_w, hw_h, hw_d, w, h)
2141 }
2142
2143 if (cam->vpp_flag & VPP_UYVY_TO_RGBX) {
2144 w9968cf_vpp->uyvy_to_rgbx(pIn, fr->length, pOut, fmt, rgb);
2145 fr->length = (w*h*d)/8;
2146 _PSWAP(pIn, pOut)
2147 DBG(6, "UYVY-16bit to %s conversion done",
2148 symbolic(v4l1_plist, fmt))
2149 }
2150
2151 if (pOut == fr->buffer)
2152 memcpy(fr->buffer, cam->frame_vpp.buffer, fr->length);
2153
2154 return 0;
2155}
2156
2157
2158
2159/****************************************************************************
2160 * Image sensor control routines *
2161 ****************************************************************************/
2162
2163static int
2164w9968cf_sensor_set_control(struct w9968cf_device* cam, int cid, int val)
2165{
2166 struct ovcamchip_control ctl;
2167 int err;
2168
2169 ctl.id = cid;
2170 ctl.value = val;
2171
2172 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_CTRL, &ctl);
2173
2174 return err;
2175}
2176
2177
2178static int
2179w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val)
2180{
2181 struct ovcamchip_control ctl;
2182 int err;
2183
2184 ctl.id = cid;
2185
2186 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_G_CTRL, &ctl);
2187 if (!err)
2188 *val = ctl.value;
2189
2190 return err;
2191}
2192
2193
2194static int
2195w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
2196{
2197 struct i2c_client* c = cam->sensor_client;
2198 int rc = 0;
2199
2200 if (!c || !c->driver || !c->driver->command)
2201 return -EINVAL;
2202
2203 rc = c->driver->command(c, cmd, arg);
2204 /* The I2C driver returns -EPERM on non-supported controls */
2205 return (rc < 0 && rc != -EPERM) ? rc : 0;
2206}
2207
2208
2209/*--------------------------------------------------------------------------
2210 Update some settings of the image sensor.
2211 Returns: 0 on success, a negative number otherwise.
2212 --------------------------------------------------------------------------*/
2213static int w9968cf_sensor_update_settings(struct w9968cf_device* cam)
2214{
2215 int err = 0;
2216
2217 /* Auto brightness */
2218 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT,
2219 cam->auto_brt);
2220 if (err)
2221 return err;
2222
2223 /* Auto exposure */
2224 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP,
2225 cam->auto_exp);
2226 if (err)
2227 return err;
2228
2229 /* Banding filter */
2230 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT,
2231 cam->bandfilt);
2232 if (err)
2233 return err;
2234
2235 /* Light frequency */
2236 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ,
2237 cam->lightfreq);
2238 if (err)
2239 return err;
2240
2241 /* Back light */
2242 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT,
2243 cam->backlight);
2244 if (err)
2245 return err;
2246
2247 /* Mirror */
2248 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR,
2249 cam->mirror);
2250 if (err)
2251 return err;
2252
2253 return 0;
2254}
2255
2256
2257/*--------------------------------------------------------------------------
2258 Get some current picture settings from the image sensor and update the
2259 internal 'picture' structure of the camera.
2260 Returns: 0 on success, a negative number otherwise.
2261 --------------------------------------------------------------------------*/
2262static int w9968cf_sensor_get_picture(struct w9968cf_device* cam)
2263{
2264 int err, v;
2265
2266 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_CONT, &v);
2267 if (err)
2268 return err;
2269 cam->picture.contrast = v;
2270
2271 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_BRIGHT, &v);
2272 if (err)
2273 return err;
2274 cam->picture.brightness = v;
2275
2276 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_SAT, &v);
2277 if (err)
2278 return err;
2279 cam->picture.colour = v;
2280
2281 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_HUE, &v);
2282 if (err)
2283 return err;
2284 cam->picture.hue = v;
2285
2286 DBG(5, "Got picture settings from the image sensor")
2287
2288 PDBGG("Brightness, contrast, hue, colour, whiteness are "
2289 "%u,%u,%u,%u,%u", cam->picture.brightness,cam->picture.contrast,
2290 cam->picture.hue, cam->picture.colour, cam->picture.whiteness)
2291
2292 return 0;
2293}
2294
2295
2296/*--------------------------------------------------------------------------
2297 Update picture settings of the image sensor.
2298 Returns: 0 on success, a negative number otherwise.
2299 --------------------------------------------------------------------------*/
2300static int
2301w9968cf_sensor_update_picture(struct w9968cf_device* cam,
2302 struct video_picture pict)
2303{
2304 int err = 0;
2305
2306 if ((!cam->sensor_initialized)
2307 || pict.contrast != cam->picture.contrast) {
2308 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_CONT,
2309 pict.contrast);
2310 if (err)
2311 goto fail;
2312 DBG(4, "Contrast changed from %u to %u",
2313 cam->picture.contrast, pict.contrast)
2314 cam->picture.contrast = pict.contrast;
2315 }
2316
2317 if (((!cam->sensor_initialized) ||
2318 pict.brightness != cam->picture.brightness) && (!cam->auto_brt)) {
2319 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT,
2320 pict.brightness);
2321 if (err)
2322 goto fail;
2323 DBG(4, "Brightness changed from %u to %u",
2324 cam->picture.brightness, pict.brightness)
2325 cam->picture.brightness = pict.brightness;
2326 }
2327
2328 if ((!cam->sensor_initialized) || pict.colour != cam->picture.colour) {
2329 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT,
2330 pict.colour);
2331 if (err)
2332 goto fail;
2333 DBG(4, "Colour changed from %u to %u",
2334 cam->picture.colour, pict.colour)
2335 cam->picture.colour = pict.colour;
2336 }
2337
2338 if ((!cam->sensor_initialized) || pict.hue != cam->picture.hue) {
2339 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE,
2340 pict.hue);
2341 if (err)
2342 goto fail;
2343 DBG(4, "Hue changed from %u to %u",
2344 cam->picture.hue, pict.hue)
2345 cam->picture.hue = pict.hue;
2346 }
2347
2348 return 0;
2349
2350fail:
2351 DBG(4, "Failed to change sensor picture setting")
2352 return err;
2353}
2354
2355
2356
2357/****************************************************************************
2358 * Camera configuration *
2359 ****************************************************************************/
2360
2361/*--------------------------------------------------------------------------
2362 This function is called when a supported image sensor is detected.
2363 Return 0 if the initialization succeeds, a negative number otherwise.
2364 --------------------------------------------------------------------------*/
2365static int w9968cf_sensor_init(struct w9968cf_device* cam)
2366{
2367 int err = 0;
2368
2369 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE,
2370 &cam->monochrome)))
2371 goto error;
2372
2373 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE,
2374 &cam->sensor)))
2375 goto error;
2376
2377 /* NOTE: Make sure width and height are a multiple of 16 */
2378 switch (cam->sensor_client->addr) {
2379 case OV6xx0_SID:
2380 cam->maxwidth = 352;
2381 cam->maxheight = 288;
2382 cam->minwidth = 64;
2383 cam->minheight = 48;
2384 break;
2385 case OV7xx0_SID:
2386 cam->maxwidth = 640;
2387 cam->maxheight = 480;
2388 cam->minwidth = 64;
2389 cam->minheight = 48;
2390 break;
2391 default:
2392 DBG(1, "Not supported image sensor detected for %s",
2393 symbolic(camlist, cam->id))
2394 return -EINVAL;
2395 }
2396
2397 /* These values depend on the ones in the ovxxx0.c sources */
2398 switch (cam->sensor) {
2399 case CC_OV7620:
2400 cam->start_cropx = 287;
2401 cam->start_cropy = 35;
2402 /* Seems to work around a bug in the image sensor */
2403 cam->vs_polarity = 1;
2404 cam->hs_polarity = 1;
2405 break;
2406 default:
2407 cam->start_cropx = 320;
2408 cam->start_cropy = 35;
2409 cam->vs_polarity = 1;
2410 cam->hs_polarity = 0;
2411 }
2412
2413 if ((err = w9968cf_sensor_update_settings(cam)))
2414 goto error;
2415
2416 if ((err = w9968cf_sensor_update_picture(cam, cam->picture)))
2417 goto error;
2418
2419 cam->sensor_initialized = 1;
2420
2421 DBG(2, "%s image sensor initialized", symbolic(senlist, cam->sensor))
2422 return 0;
2423
2424error:
2425 cam->sensor_initialized = 0;
2426 cam->sensor = CC_UNKNOWN;
2427 DBG(1, "Image sensor initialization failed for %s (/dev/video%d). "
2428 "Try to detach and attach this device again",
2429 symbolic(camlist, cam->id), cam->v4ldev->minor)
2430 return err;
2431}
2432
2433
2434/*--------------------------------------------------------------------------
2435 Fill some basic fields in the main device data structure.
2436 This function is called once on w9968cf_usb_probe() for each recognized
2437 camera.
2438 --------------------------------------------------------------------------*/
2439static void
2440w9968cf_configure_camera(struct w9968cf_device* cam,
2441 struct usb_device* udev,
2442 enum w9968cf_model_id mod_id,
2443 const unsigned short dev_nr)
2444{
2445 init_MUTEX(&cam->fileop_sem);
2446 init_waitqueue_head(&cam->open);
2447 spin_lock_init(&cam->urb_lock);
2448 spin_lock_init(&cam->flist_lock);
2449
2450 cam->users = 0;
2451 cam->disconnected = 0;
2452 cam->id = mod_id;
2453 cam->sensor = CC_UNKNOWN;
2454 cam->sensor_initialized = 0;
2455
2456 /* Calculate the alternate setting number (from 1 to 16)
2457 according to the 'packet_size' module parameter */
2458 if (packet_size[dev_nr] < W9968CF_MIN_PACKET_SIZE)
2459 packet_size[dev_nr] = W9968CF_MIN_PACKET_SIZE;
2460 for (cam->altsetting = 1;
2461 packet_size[dev_nr] < wMaxPacketSize[cam->altsetting-1];
2462 cam->altsetting++);
2463
2464 cam->max_buffers = (max_buffers[dev_nr] < 2 ||
2465 max_buffers[dev_nr] > W9968CF_MAX_BUFFERS)
2466 ? W9968CF_BUFFERS : (u8)max_buffers[dev_nr];
2467
2468 cam->double_buffer = (double_buffer[dev_nr] == 0 ||
2469 double_buffer[dev_nr] == 1)
2470 ? (u8)double_buffer[dev_nr]:W9968CF_DOUBLE_BUFFER;
2471
2472 cam->clamping = (clamping[dev_nr] == 0 || clamping[dev_nr] == 1)
2473 ? (u8)clamping[dev_nr] : W9968CF_CLAMPING;
2474
2475 cam->filter_type = (filter_type[dev_nr] == 0 ||
2476 filter_type[dev_nr] == 1 ||
2477 filter_type[dev_nr] == 2)
2478 ? (u8)filter_type[dev_nr] : W9968CF_FILTER_TYPE;
2479
2480 cam->capture = 1;
2481
2482 cam->largeview = (largeview[dev_nr] == 0 || largeview[dev_nr] == 1)
2483 ? (u8)largeview[dev_nr] : W9968CF_LARGEVIEW;
2484
2485 cam->decompression = (decompression[dev_nr] == 0 ||
2486 decompression[dev_nr] == 1 ||
2487 decompression[dev_nr] == 2)
2488 ? (u8)decompression[dev_nr]:W9968CF_DECOMPRESSION;
2489
2490 cam->upscaling = (upscaling[dev_nr] == 0 ||
2491 upscaling[dev_nr] == 1)
2492 ? (u8)upscaling[dev_nr] : W9968CF_UPSCALING;
2493
2494 cam->auto_brt = (autobright[dev_nr] == 0 || autobright[dev_nr] == 1)
2495 ? (u8)autobright[dev_nr] : W9968CF_AUTOBRIGHT;
2496
2497 cam->auto_exp = (autoexp[dev_nr] == 0 || autoexp[dev_nr] == 1)
2498 ? (u8)autoexp[dev_nr] : W9968CF_AUTOEXP;
2499
2500 cam->lightfreq = (lightfreq[dev_nr] == 50 || lightfreq[dev_nr] == 60)
2501 ? (u8)lightfreq[dev_nr] : W9968CF_LIGHTFREQ;
2502
2503 cam->bandfilt = (bandingfilter[dev_nr] == 0 ||
2504 bandingfilter[dev_nr] == 1)
2505 ? (u8)bandingfilter[dev_nr] : W9968CF_BANDINGFILTER;
2506
2507 cam->backlight = (backlight[dev_nr] == 0 || backlight[dev_nr] == 1)
2508 ? (u8)backlight[dev_nr] : W9968CF_BACKLIGHT;
2509
2510 cam->clockdiv = (clockdiv[dev_nr] == -1 || clockdiv[dev_nr] >= 0)
2511 ? (s8)clockdiv[dev_nr] : W9968CF_CLOCKDIV;
2512
2513 cam->mirror = (mirror[dev_nr] == 0 || mirror[dev_nr] == 1)
2514 ? (u8)mirror[dev_nr] : W9968CF_MIRROR;
2515
2516 cam->monochrome = (monochrome[dev_nr] == 0 || monochrome[dev_nr] == 1)
2517 ? monochrome[dev_nr] : W9968CF_MONOCHROME;
2518
2519 cam->picture.brightness = (u16)brightness[dev_nr];
2520 cam->picture.hue = (u16)hue[dev_nr];
2521 cam->picture.colour = (u16)colour[dev_nr];
2522 cam->picture.contrast = (u16)contrast[dev_nr];
2523 cam->picture.whiteness = (u16)whiteness[dev_nr];
2524 if (w9968cf_valid_palette((u16)force_palette[dev_nr])) {
2525 cam->picture.palette = (u16)force_palette[dev_nr];
2526 cam->force_palette = 1;
2527 } else {
2528 cam->force_palette = 0;
2529 if (cam->decompression == 0)
2530 cam->picture.palette = W9968CF_PALETTE_DECOMP_OFF;
2531 else if (cam->decompression == 1)
2532 cam->picture.palette = W9968CF_PALETTE_DECOMP_FORCE;
2533 else
2534 cam->picture.palette = W9968CF_PALETTE_DECOMP_ON;
2535 }
2536 cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2537
2538 cam->force_rgb = (force_rgb[dev_nr] == 0 || force_rgb[dev_nr] == 1)
2539 ? (u8)force_rgb[dev_nr] : W9968CF_FORCE_RGB;
2540
2541 cam->window.x = 0;
2542 cam->window.y = 0;
2543 cam->window.width = W9968CF_WIDTH;
2544 cam->window.height = W9968CF_HEIGHT;
2545 cam->window.chromakey = 0;
2546 cam->window.clipcount = 0;
2547 cam->window.flags = 0;
2548
2549 DBG(3, "%s configured with settings #%u:",
2550 symbolic(camlist, cam->id), dev_nr)
2551
2552 DBG(3, "- Data packet size for USB isochrnous transfer: %u bytes",
2553 wMaxPacketSize[cam->altsetting-1])
2554
2555 DBG(3, "- Number of requested video frame buffers: %u",
2556 cam->max_buffers)
2557
2558 if (cam->double_buffer)
2559 DBG(3, "- Hardware double buffering enabled")
2560 else
2561 DBG(3, "- Hardware double buffering disabled")
2562
2563 if (cam->filter_type == 0)
2564 DBG(3, "- Video filtering disabled")
2565 else if (cam->filter_type == 1)
2566 DBG(3, "- Video filtering enabled: type 1-2-1")
2567 else if (cam->filter_type == 2)
2568 DBG(3, "- Video filtering enabled: type 2-3-6-3-2")
2569
2570 if (cam->clamping)
2571 DBG(3, "- Video data clamping (CCIR-601 format) enabled")
2572 else
2573 DBG(3, "- Video data clamping (CCIR-601 format) disabled")
2574
2575 if (cam->largeview)
2576 DBG(3, "- Large view enabled")
2577 else
2578 DBG(3, "- Large view disabled")
2579
2580 if ((cam->decompression) == 0 && (!cam->force_palette))
2581 DBG(3, "- Decompression disabled")
2582 else if ((cam->decompression) == 1 && (!cam->force_palette))
2583 DBG(3, "- Decompression forced")
2584 else if ((cam->decompression) == 2 && (!cam->force_palette))
2585 DBG(3, "- Decompression allowed")
2586
2587 if (cam->upscaling)
2588 DBG(3, "- Software image scaling enabled")
2589 else
2590 DBG(3, "- Software image scaling disabled")
2591
2592 if (cam->force_palette)
2593 DBG(3, "- Image palette forced to %s",
2594 symbolic(v4l1_plist, cam->picture.palette))
2595
2596 if (cam->force_rgb)
2597 DBG(3, "- RGB component ordering will be used instead of BGR")
2598
2599 if (cam->auto_brt)
2600 DBG(3, "- Auto brightness enabled")
2601 else
2602 DBG(3, "- Auto brightness disabled")
2603
2604 if (cam->auto_exp)
2605 DBG(3, "- Auto exposure enabled")
2606 else
2607 DBG(3, "- Auto exposure disabled")
2608
2609 if (cam->backlight)
2610 DBG(3, "- Backlight exposure algorithm enabled")
2611 else
2612 DBG(3, "- Backlight exposure algorithm disabled")
2613
2614 if (cam->mirror)
2615 DBG(3, "- Mirror enabled")
2616 else
2617 DBG(3, "- Mirror disabled")
2618
2619 if (cam->bandfilt)
2620 DBG(3, "- Banding filter enabled")
2621 else
2622 DBG(3, "- Banding filter disabled")
2623
2624 DBG(3, "- Power lighting frequency: %u", cam->lightfreq)
2625
2626 if (cam->clockdiv == -1)
2627 DBG(3, "- Automatic clock divisor enabled")
2628 else
2629 DBG(3, "- Clock divisor: %d", cam->clockdiv)
2630
2631 if (cam->monochrome)
2632 DBG(3, "- Image sensor used as monochrome")
2633 else
2634 DBG(3, "- Image sensor not used as monochrome")
2635}
2636
2637
2638/*--------------------------------------------------------------------------
2639 If the video post-processing module is not loaded, some parameters
2640 must be overridden.
2641 --------------------------------------------------------------------------*/
2642static void w9968cf_adjust_configuration(struct w9968cf_device* cam)
2643{
2644 if (!w9968cf_vpp) {
2645 if (cam->decompression == 1) {
2646 cam->decompression = 2;
2647 DBG(2, "Video post-processing module not found: "
2648 "'decompression' parameter forced to 2")
2649 }
2650 if (cam->upscaling) {
2651 cam->upscaling = 0;
2652 DBG(2, "Video post-processing module not found: "
2653 "'upscaling' parameter forced to 0")
2654 }
2655 if (cam->picture.palette != VIDEO_PALETTE_UYVY) {
2656 cam->force_palette = 0;
2657 DBG(2, "Video post-processing module not found: "
2658 "'force_palette' parameter forced to 0")
2659 }
2660 cam->picture.palette = VIDEO_PALETTE_UYVY;
2661 cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2662 }
2663}
2664
2665
2666/*--------------------------------------------------------------------------
2667 Release the resources used by the driver.
2668 This function is called on disconnect
2669 (or on close if deallocation has been deferred)
2670 --------------------------------------------------------------------------*/
2671static void w9968cf_release_resources(struct w9968cf_device* cam)
2672{
2673 down(&w9968cf_devlist_sem);
2674
2675 DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
2676
2677 video_unregister_device(cam->v4ldev);
2678 list_del(&cam->v4llist);
2679 i2c_del_adapter(&cam->i2c_adapter);
2680 w9968cf_deallocate_memory(cam);
2681 kfree(cam->control_buffer);
2682 kfree(cam->data_buffer);
2683
2684 up(&w9968cf_devlist_sem);
2685}
2686
2687
2688
2689/****************************************************************************
2690 * Video4Linux interface *
2691 ****************************************************************************/
2692
2693static int w9968cf_open(struct inode* inode, struct file* filp)
2694{
2695 struct w9968cf_device* cam;
2696 int err;
2697
2698 /* This the only safe way to prevent race conditions with disconnect */
2699 if (!down_read_trylock(&w9968cf_disconnect))
2700 return -ERESTARTSYS;
2701
2702 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2703
2704 down(&cam->dev_sem);
2705
2706 if (cam->sensor == CC_UNKNOWN) {
2707 DBG(2, "No supported image sensor has been detected by the "
2708 "'ovcamchip' module for the %s (/dev/video%d). Make "
2709 "sure it is loaded *before* (re)connecting the camera.",
2710 symbolic(camlist, cam->id), cam->v4ldev->minor)
2711 up(&cam->dev_sem);
2712 up_read(&w9968cf_disconnect);
2713 return -ENODEV;
2714 }
2715
2716 if (cam->users) {
2717 DBG(2, "%s (/dev/video%d) has been already occupied by '%s'",
2718 symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command)
2719 if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
2720 up(&cam->dev_sem);
2721 up_read(&w9968cf_disconnect);
2722 return -EWOULDBLOCK;
2723 }
2724 up(&cam->dev_sem);
2725 err = wait_event_interruptible_exclusive(cam->open,
2726 cam->disconnected ||
2727 !cam->users);
2728 if (err) {
2729 up_read(&w9968cf_disconnect);
2730 return err;
2731 }
2732 if (cam->disconnected) {
2733 up_read(&w9968cf_disconnect);
2734 return -ENODEV;
2735 }
2736 down(&cam->dev_sem);
2737 }
2738
2739 DBG(5, "Opening '%s', /dev/video%d ...",
2740 symbolic(camlist, cam->id), cam->v4ldev->minor)
2741
2742 cam->streaming = 0;
2743 cam->misconfigured = 0;
2744
2745 if (!w9968cf_vpp)
2746 if ((err = w9968cf_vppmod_detect(cam)))
2747 goto out;
2748
2749 if ((err = w9968cf_allocate_memory(cam)))
2750 goto deallocate_memory;
2751
2752 if ((err = w9968cf_init_chip(cam)))
2753 goto deallocate_memory;
2754
2755 if ((err = w9968cf_start_transfer(cam)))
2756 goto deallocate_memory;
2757
2758 filp->private_data = cam;
2759
2760 cam->users++;
2761 strcpy(cam->command, current->comm);
2762
2763 init_waitqueue_head(&cam->wait_queue);
2764
2765 DBG(5, "Video device is open")
2766
2767 up(&cam->dev_sem);
2768 up_read(&w9968cf_disconnect);
2769
2770 return 0;
2771
2772deallocate_memory:
2773 w9968cf_deallocate_memory(cam);
2774out:
2775 DBG(2, "Failed to open the video device")
2776 up(&cam->dev_sem);
2777 up_read(&w9968cf_disconnect);
2778 return err;
2779}
2780
2781
2782static int w9968cf_release(struct inode* inode, struct file* filp)
2783{
2784 struct w9968cf_device* cam;
2785
2786 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2787
2788 down(&cam->dev_sem); /* prevent disconnect() to be called */
2789
2790 w9968cf_stop_transfer(cam);
2791
2792 w9968cf_vppmod_release(cam);
2793
2794 if (cam->disconnected) {
2795 w9968cf_release_resources(cam);
2796 up(&cam->dev_sem);
2797 kfree(cam);
2798 return 0;
2799 }
2800
2801 cam->users--;
2802 w9968cf_deallocate_memory(cam);
2803 wake_up_interruptible_nr(&cam->open, 1);
2804
2805 DBG(5, "Video device closed")
2806 up(&cam->dev_sem);
2807 return 0;
2808}
2809
2810
2811static ssize_t
2812w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
2813{
2814 struct w9968cf_device* cam;
2815 struct w9968cf_frame_t* fr;
2816 int err = 0;
2817
2818 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2819
2820 if (filp->f_flags & O_NONBLOCK)
2821 return -EWOULDBLOCK;
2822
2823 if (down_interruptible(&cam->fileop_sem))
2824 return -ERESTARTSYS;
2825
2826 if (cam->disconnected) {
2827 DBG(2, "Device not present")
2828 up(&cam->fileop_sem);
2829 return -ENODEV;
2830 }
2831
2832 if (cam->misconfigured) {
2833 DBG(2, "The camera is misconfigured. Close and open it again.")
2834 up(&cam->fileop_sem);
2835 return -EIO;
2836 }
2837
2838 if (!cam->frame[0].queued)
2839 w9968cf_push_frame(cam, 0);
2840
2841 if (!cam->frame[1].queued)
2842 w9968cf_push_frame(cam, 1);
2843
2844 err = wait_event_interruptible(cam->wait_queue,
2845 cam->frame[0].status == F_READY ||
2846 cam->frame[1].status == F_READY ||
2847 cam->disconnected);
2848 if (err) {
2849 up(&cam->fileop_sem);
2850 return err;
2851 }
2852 if (cam->disconnected) {
2853 up(&cam->fileop_sem);
2854 return -ENODEV;
2855 }
2856
2857 fr = (cam->frame[0].status == F_READY) ? &cam->frame[0]:&cam->frame[1];
2858
2859 if (w9968cf_vpp)
2860 w9968cf_postprocess_frame(cam, fr);
2861
2862 if (count > fr->length)
2863 count = fr->length;
2864
2865 if (copy_to_user(buf, fr->buffer, count)) {
2866 fr->status = F_UNUSED;
2867 up(&cam->fileop_sem);
2868 return -EFAULT;
2869 }
2870 *f_pos += count;
2871
2872 fr->status = F_UNUSED;
2873
2874 DBG(5, "%zu bytes read", count)
2875
2876 up(&cam->fileop_sem);
2877 return count;
2878}
2879
2880
2881static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma)
2882{
2883 struct w9968cf_device* cam = (struct w9968cf_device*)
2884 video_get_drvdata(video_devdata(filp));
2885 unsigned long vsize = vma->vm_end - vma->vm_start,
2886 psize = cam->nbuffers * cam->frame[0].size,
2887 start = vma->vm_start,
2888 pos = (unsigned long)cam->frame[0].buffer,
2889 page;
2890
2891 if (cam->disconnected) {
2892 DBG(2, "Device not present")
2893 return -ENODEV;
2894 }
2895
2896 if (cam->misconfigured) {
2897 DBG(2, "The camera is misconfigured. Close and open it again")
2898 return -EIO;
2899 }
2900
2901 PDBGG("mmapping %lu bytes...", vsize)
2902
2903 if (vsize > psize - (vma->vm_pgoff << PAGE_SHIFT))
2904 return -EINVAL;
2905
2906 while (vsize > 0) {
2907 page = vmalloc_to_pfn((void *)pos);
2908 if (remap_pfn_range(vma, start, page + vma->vm_pgoff,
2909 PAGE_SIZE, vma->vm_page_prot))
2910 return -EAGAIN;
2911 start += PAGE_SIZE;
2912 pos += PAGE_SIZE;
2913 vsize -= PAGE_SIZE;
2914 }
2915
2916 DBG(5, "mmap method successfully called")
2917 return 0;
2918}
2919
2920
2921static int
2922w9968cf_ioctl(struct inode* inode, struct file* filp,
2923 unsigned int cmd, unsigned long arg)
2924{
2925 struct w9968cf_device* cam;
2926 int err;
2927
2928 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2929
2930 if (down_interruptible(&cam->fileop_sem))
2931 return -ERESTARTSYS;
2932
2933 if (cam->disconnected) {
2934 DBG(2, "Device not present")
2935 up(&cam->fileop_sem);
2936 return -ENODEV;
2937 }
2938
2939 if (cam->misconfigured) {
2940 DBG(2, "The camera is misconfigured. Close and open it again.")
2941 up(&cam->fileop_sem);
2942 return -EIO;
2943 }
2944
2945 err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg);
2946
2947 up(&cam->fileop_sem);
2948 return err;
2949}
2950
2951
2952static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
2953 unsigned int cmd, void __user * arg)
2954{
2955 struct w9968cf_device* cam;
2956 const char* v4l1_ioctls[] = {
2957 "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER",
2958 "GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF",
2959 "SFBUF", "KEY", "GFREQ", "SFREQ", "GAUDIO", "SAUDIO",
2960 "SYNC", "MCAPTURE", "GMBUF", "GUNIT", "GCAPTURE", "SCAPTURE",
2961 "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", "SMICROCODE",
2962 "GVBIFMT", "SVBIFMT"
2963 };
2964
2965 #define V4L1_IOCTL(cmd) \
2966 ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \
2967 v4l1_ioctls[_IOC_NR((cmd))] : "?")
2968
2969 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2970
2971 switch (cmd) {
2972
2973 case VIDIOCGCAP: /* get video capability */
2974 {
2975 struct video_capability cap = {
2976 .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
2977 .channels = 1,
2978 .audios = 0,
2979 .minwidth = cam->minwidth,
2980 .minheight = cam->minheight,
2981 };
2982 sprintf(cap.name, "W996[87]CF USB Camera #%d",
2983 cam->v4ldev->minor);
2984 cap.maxwidth = (cam->upscaling && w9968cf_vpp)
2985 ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
2986 : cam->maxwidth;
2987 cap.maxheight = (cam->upscaling && w9968cf_vpp)
2988 ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
2989 : cam->maxheight;
2990
2991 if (copy_to_user(arg, &cap, sizeof(cap)))
2992 return -EFAULT;
2993
2994 DBG(5, "VIDIOCGCAP successfully called")
2995 return 0;
2996 }
2997
2998 case VIDIOCGCHAN: /* get video channel informations */
2999 {
3000 struct video_channel chan;
3001 if (copy_from_user(&chan, arg, sizeof(chan)))
3002 return -EFAULT;
3003
3004 if (chan.channel != 0)
3005 return -EINVAL;
3006
3007 strcpy(chan.name, "Camera");
3008 chan.tuners = 0;
3009 chan.flags = 0;
3010 chan.type = VIDEO_TYPE_CAMERA;
3011 chan.norm = VIDEO_MODE_AUTO;
3012
3013 if (copy_to_user(arg, &chan, sizeof(chan)))
3014 return -EFAULT;
3015
3016 DBG(5, "VIDIOCGCHAN successfully called")
3017 return 0;
3018 }
3019
3020 case VIDIOCSCHAN: /* set active channel */
3021 {
3022 struct video_channel chan;
3023
3024 if (copy_from_user(&chan, arg, sizeof(chan)))
3025 return -EFAULT;
3026
3027 if (chan.channel != 0)
3028 return -EINVAL;
3029
3030 DBG(5, "VIDIOCSCHAN successfully called")
3031 return 0;
3032 }
3033
3034 case VIDIOCGPICT: /* get image properties of the picture */
3035 {
3036 if (w9968cf_sensor_get_picture(cam))
3037 return -EIO;
3038
3039 if (copy_to_user(arg, &cam->picture, sizeof(cam->picture)))
3040 return -EFAULT;
3041
3042 DBG(5, "VIDIOCGPICT successfully called")
3043 return 0;
3044 }
3045
3046 case VIDIOCSPICT: /* change picture settings */
3047 {
3048 struct video_picture pict;
3049 int err = 0;
3050
3051 if (copy_from_user(&pict, arg, sizeof(pict)))
3052 return -EFAULT;
3053
3054 if ( (cam->force_palette || !w9968cf_vpp)
3055 && pict.palette != cam->picture.palette ) {
3056 DBG(4, "Palette %s rejected: only %s is allowed",
3057 symbolic(v4l1_plist, pict.palette),
3058 symbolic(v4l1_plist, cam->picture.palette))
3059 return -EINVAL;
3060 }
3061
3062 if (!w9968cf_valid_palette(pict.palette)) {
3063 DBG(4, "Palette %s not supported. VIDIOCSPICT failed",
3064 symbolic(v4l1_plist, pict.palette))
3065 return -EINVAL;
3066 }
3067
3068 if (!cam->force_palette) {
3069 if (cam->decompression == 0) {
3070 if (w9968cf_need_decompression(pict.palette)) {
3071 DBG(4, "Decompression disabled: palette %s is not "
3072 "allowed. VIDIOCSPICT failed",
3073 symbolic(v4l1_plist, pict.palette))
3074 return -EINVAL;
3075 }
3076 } else if (cam->decompression == 1) {
3077 if (!w9968cf_need_decompression(pict.palette)) {
3078 DBG(4, "Decompression forced: palette %s is not "
3079 "allowed. VIDIOCSPICT failed",
3080 symbolic(v4l1_plist, pict.palette))
3081 return -EINVAL;
3082 }
3083 }
3084 }
3085
3086 if (pict.depth != w9968cf_valid_depth(pict.palette)) {
3087 DBG(4, "Requested depth %u bpp is not valid for %s "
3088 "palette: ignored and changed to %u bpp",
3089 pict.depth, symbolic(v4l1_plist, pict.palette),
3090 w9968cf_valid_depth(pict.palette))
3091 pict.depth = w9968cf_valid_depth(pict.palette);
3092 }
3093
3094 if (pict.palette != cam->picture.palette) {
3095 if(*cam->requested_frame
3096 || cam->frame_current->queued) {
3097 err = wait_event_interruptible
3098 ( cam->wait_queue,
3099 cam->disconnected ||
3100 (!*cam->requested_frame &&
3101 !cam->frame_current->queued) );
3102 if (err)
3103 return err;
3104 if (cam->disconnected)
3105 return -ENODEV;
3106 }
3107
3108 if (w9968cf_stop_transfer(cam))
3109 goto ioctl_fail;
3110
3111 if (w9968cf_set_picture(cam, pict))
3112 goto ioctl_fail;
3113
3114 if (w9968cf_start_transfer(cam))
3115 goto ioctl_fail;
3116
3117 } else if (w9968cf_sensor_update_picture(cam, pict))
3118 return -EIO;
3119
3120
3121 DBG(5, "VIDIOCSPICT successfully called")
3122 return 0;
3123 }
3124
3125 case VIDIOCSWIN: /* set capture area */
3126 {
3127 struct video_window win;
3128 int err = 0;
3129
3130 if (copy_from_user(&win, arg, sizeof(win)))
3131 return -EFAULT;
3132
3133 DBG(6, "VIDIOCSWIN called: clipcount=%d, flags=%u, "
3134 "x=%u, y=%u, %ux%u", win.clipcount, win.flags,
3135 win.x, win.y, win.width, win.height)
3136
3137 if (win.clipcount != 0 || win.flags != 0)
3138 return -EINVAL;
3139
3140 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
3141 (u16*)&win.height))) {
3142 DBG(4, "Resolution not supported (%ux%u). "
3143 "VIDIOCSWIN failed", win.width, win.height)
3144 return err;
3145 }
3146
3147 if (win.x != cam->window.x ||
3148 win.y != cam->window.y ||
3149 win.width != cam->window.width ||
3150 win.height != cam->window.height) {
3151 if(*cam->requested_frame
3152 || cam->frame_current->queued) {
3153 err = wait_event_interruptible
3154 ( cam->wait_queue,
3155 cam->disconnected ||
3156 (!*cam->requested_frame &&
3157 !cam->frame_current->queued) );
3158 if (err)
3159 return err;
3160 if (cam->disconnected)
3161 return -ENODEV;
3162 }
3163
3164 if (w9968cf_stop_transfer(cam))
3165 goto ioctl_fail;
3166
3167 /* This _must_ be called before set_window() */
3168 if (w9968cf_set_picture(cam, cam->picture))
3169 goto ioctl_fail;
3170
3171 if (w9968cf_set_window(cam, win))
3172 goto ioctl_fail;
3173
3174 if (w9968cf_start_transfer(cam))
3175 goto ioctl_fail;
3176 }
3177
3178 DBG(5, "VIDIOCSWIN successfully called. ")
3179 return 0;
3180 }
3181
3182 case VIDIOCGWIN: /* get current window properties */
3183 {
3184 if (copy_to_user(arg,&cam->window,sizeof(struct video_window)))
3185 return -EFAULT;
3186
3187 DBG(5, "VIDIOCGWIN successfully called")
3188 return 0;
3189 }
3190
3191 case VIDIOCGMBUF: /* request for memory (mapped) buffer */
3192 {
3193 struct video_mbuf mbuf;
3194 u8 i;
3195
3196 mbuf.size = cam->nbuffers * cam->frame[0].size;
3197 mbuf.frames = cam->nbuffers;
3198 for (i = 0; i < cam->nbuffers; i++)
3199 mbuf.offsets[i] = (unsigned long)cam->frame[i].buffer -
3200 (unsigned long)cam->frame[0].buffer;
3201
3202 if (copy_to_user(arg, &mbuf, sizeof(mbuf)))
3203 return -EFAULT;
3204
3205 DBG(5, "VIDIOCGMBUF successfully called")
3206 return 0;
3207 }
3208
3209 case VIDIOCMCAPTURE: /* start the capture to a frame */
3210 {
3211 struct video_mmap mmap;
3212 struct w9968cf_frame_t* fr;
3213 int err = 0;
3214
3215 if (copy_from_user(&mmap, arg, sizeof(mmap)))
3216 return -EFAULT;
3217
3218 DBG(6, "VIDIOCMCAPTURE called: frame #%u, format=%s, %dx%d",
3219 mmap.frame, symbolic(v4l1_plist, mmap.format),
3220 mmap.width, mmap.height)
3221
3222 if (mmap.frame >= cam->nbuffers) {
3223 DBG(4, "Invalid frame number (%u). "
3224 "VIDIOCMCAPTURE failed", mmap.frame)
3225 return -EINVAL;
3226 }
3227
3228 if (mmap.format!=cam->picture.palette &&
3229 (cam->force_palette || !w9968cf_vpp)) {
3230 DBG(4, "Palette %s rejected: only %s is allowed",
3231 symbolic(v4l1_plist, mmap.format),
3232 symbolic(v4l1_plist, cam->picture.palette))
3233 return -EINVAL;
3234 }
3235
3236 if (!w9968cf_valid_palette(mmap.format)) {
3237 DBG(4, "Palette %s not supported. "
3238 "VIDIOCMCAPTURE failed",
3239 symbolic(v4l1_plist, mmap.format))
3240 return -EINVAL;
3241 }
3242
3243 if (!cam->force_palette) {
3244 if (cam->decompression == 0) {
3245 if (w9968cf_need_decompression(mmap.format)) {
3246 DBG(4, "Decompression disabled: palette %s is not "
3247 "allowed. VIDIOCSPICT failed",
3248 symbolic(v4l1_plist, mmap.format))
3249 return -EINVAL;
3250 }
3251 } else if (cam->decompression == 1) {
3252 if (!w9968cf_need_decompression(mmap.format)) {
3253 DBG(4, "Decompression forced: palette %s is not "
3254 "allowed. VIDIOCSPICT failed",
3255 symbolic(v4l1_plist, mmap.format))
3256 return -EINVAL;
3257 }
3258 }
3259 }
3260
3261 if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width,
3262 (u16*)&mmap.height))) {
3263 DBG(4, "Resolution not supported (%dx%d). "
3264 "VIDIOCMCAPTURE failed",
3265 mmap.width, mmap.height)
3266 return err;
3267 }
3268
3269 fr = &cam->frame[mmap.frame];
3270
3271 if (mmap.width != cam->window.width ||
3272 mmap.height != cam->window.height ||
3273 mmap.format != cam->picture.palette) {
3274
3275 struct video_window win;
3276 struct video_picture pict;
3277
3278 if(*cam->requested_frame
3279 || cam->frame_current->queued) {
3280 DBG(6, "VIDIOCMCAPTURE. Change settings for "
3281 "frame #%u: %dx%d, format %s. Wait...",
3282 mmap.frame, mmap.width, mmap.height,
3283 symbolic(v4l1_plist, mmap.format))
3284 err = wait_event_interruptible
3285 ( cam->wait_queue,
3286 cam->disconnected ||
3287 (!*cam->requested_frame &&
3288 !cam->frame_current->queued) );
3289 if (err)
3290 return err;
3291 if (cam->disconnected)
3292 return -ENODEV;
3293 }
3294
3295 memcpy(&win, &cam->window, sizeof(win));
3296 memcpy(&pict, &cam->picture, sizeof(pict));
3297 win.width = mmap.width;
3298 win.height = mmap.height;
3299 pict.palette = mmap.format;
3300
3301 if (w9968cf_stop_transfer(cam))
3302 goto ioctl_fail;
3303
3304 /* This before set_window */
3305 if (w9968cf_set_picture(cam, pict))
3306 goto ioctl_fail;
3307
3308 if (w9968cf_set_window(cam, win))
3309 goto ioctl_fail;
3310
3311 if (w9968cf_start_transfer(cam))
3312 goto ioctl_fail;
3313
3314 } else if (fr->queued) {
3315
3316 DBG(6, "Wait until frame #%u is free", mmap.frame)
3317
3318 err = wait_event_interruptible(cam->wait_queue,
3319 cam->disconnected ||
3320 (!fr->queued));
3321 if (err)
3322 return err;
3323 if (cam->disconnected)
3324 return -ENODEV;
3325 }
3326
3327 w9968cf_push_frame(cam, mmap.frame);
3328 DBG(5, "VIDIOCMCAPTURE(%u): successfully called", mmap.frame)
3329 return 0;
3330 }
3331
3332 case VIDIOCSYNC: /* wait until the capture of a frame is finished */
3333 {
3334 unsigned int f_num;
3335 struct w9968cf_frame_t* fr;
3336 int err = 0;
3337
3338 if (copy_from_user(&f_num, arg, sizeof(f_num)))
3339 return -EFAULT;
3340
3341 if (f_num >= cam->nbuffers) {
3342 DBG(4, "Invalid frame number (%u). "
3343 "VIDIOCMCAPTURE failed", f_num)
3344 return -EINVAL;
3345 }
3346
3347 DBG(6, "VIDIOCSYNC called for frame #%u", f_num)
3348
3349 fr = &cam->frame[f_num];
3350
3351 switch (fr->status) {
3352 case F_UNUSED:
3353 if (!fr->queued) {
3354 DBG(4, "VIDIOSYNC: Frame #%u not requested!",
3355 f_num)
3356 return -EFAULT;
3357 }
3358 case F_ERROR:
3359 case F_GRABBING:
3360 err = wait_event_interruptible(cam->wait_queue,
3361 (fr->status == F_READY)
3362 || cam->disconnected);
3363 if (err)
3364 return err;
3365 if (cam->disconnected)
3366 return -ENODEV;
3367 break;
3368 case F_READY:
3369 break;
3370 }
3371
3372 if (w9968cf_vpp)
3373 w9968cf_postprocess_frame(cam, fr);
3374
3375 fr->status = F_UNUSED;
3376
3377 DBG(5, "VIDIOCSYNC(%u) successfully called", f_num)
3378 return 0;
3379 }
3380
3381 case VIDIOCGUNIT:/* report the unit numbers of the associated devices*/
3382 {
3383 struct video_unit unit = {
3384 .video = cam->v4ldev->minor,
3385 .vbi = VIDEO_NO_UNIT,
3386 .radio = VIDEO_NO_UNIT,
3387 .audio = VIDEO_NO_UNIT,
3388 .teletext = VIDEO_NO_UNIT,
3389 };
3390
3391 if (copy_to_user(arg, &unit, sizeof(unit)))
3392 return -EFAULT;
3393
3394 DBG(5, "VIDIOCGUNIT successfully called")
3395 return 0;
3396 }
3397
3398 case VIDIOCKEY:
3399 return 0;
3400
3401 case VIDIOCGFBUF:
3402 {
3403 if (clear_user(arg, sizeof(struct video_buffer)))
3404 return -EFAULT;
3405
3406 DBG(5, "VIDIOCGFBUF successfully called")
3407 return 0;
3408 }
3409
3410 case VIDIOCGTUNER:
3411 {
3412 struct video_tuner tuner;
3413 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3414 return -EFAULT;
3415
3416 if (tuner.tuner != 0)
3417 return -EINVAL;
3418
3419 strcpy(tuner.name, "no_tuner");
3420 tuner.rangelow = 0;
3421 tuner.rangehigh = 0;
3422 tuner.flags = VIDEO_TUNER_NORM;
3423 tuner.mode = VIDEO_MODE_AUTO;
3424 tuner.signal = 0xffff;
3425
3426 if (copy_to_user(arg, &tuner, sizeof(tuner)))
3427 return -EFAULT;
3428
3429 DBG(5, "VIDIOCGTUNER successfully called")
3430 return 0;
3431 }
3432
3433 case VIDIOCSTUNER:
3434 {
3435 struct video_tuner tuner;
3436 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3437 return -EFAULT;
3438
3439 if (tuner.tuner != 0)
3440 return -EINVAL;
3441
3442 if (tuner.mode != VIDEO_MODE_AUTO)
3443 return -EINVAL;
3444
3445 DBG(5, "VIDIOCSTUNER successfully called")
3446 return 0;
3447 }
3448
3449 case VIDIOCSFBUF:
3450 case VIDIOCCAPTURE:
3451 case VIDIOCGFREQ:
3452 case VIDIOCSFREQ:
3453 case VIDIOCGAUDIO:
3454 case VIDIOCSAUDIO:
3455 case VIDIOCSPLAYMODE:
3456 case VIDIOCSWRITEMODE:
3457 case VIDIOCGPLAYINFO:
3458 case VIDIOCSMICROCODE:
3459 case VIDIOCGVBIFMT:
3460 case VIDIOCSVBIFMT:
3461 DBG(4, "Unsupported V4L1 IOCtl: VIDIOC%s "
3462 "(type 0x%01X, "
3463 "n. 0x%01X, "
3464 "dir. 0x%01X, "
3465 "size 0x%02X)",
3466 V4L1_IOCTL(cmd),
3467 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3468
3469 return -EINVAL;
3470
3471 default:
3472 DBG(4, "Invalid V4L1 IOCtl: VIDIOC%s "
3473 "type 0x%01X, "
3474 "n. 0x%01X, "
3475 "dir. 0x%01X, "
3476 "size 0x%02X",
3477 V4L1_IOCTL(cmd),
3478 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3479
3480 return -ENOIOCTLCMD;
3481
3482 } /* end of switch */
3483
3484ioctl_fail:
3485 cam->misconfigured = 1;
3486 DBG(1, "VIDIOC%s failed because of hardware problems. "
3487 "To use the camera, close and open it again.", V4L1_IOCTL(cmd))
3488 return -EFAULT;
3489}
3490
3491
3492static struct file_operations w9968cf_fops = {
3493 .owner = THIS_MODULE,
3494 .open = w9968cf_open,
3495 .release = w9968cf_release,
3496 .read = w9968cf_read,
3497 .ioctl = w9968cf_ioctl,
3498 .mmap = w9968cf_mmap,
3499 .llseek = no_llseek,
3500};
3501
3502
3503
3504/****************************************************************************
3505 * USB probe and V4L registration, disconnect and id_table[] definition *
3506 ****************************************************************************/
3507
3508static int
3509w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3510{
3511 struct usb_device *udev = interface_to_usbdev(intf);
3512 struct w9968cf_device* cam;
3513 int err = 0;
3514 enum w9968cf_model_id mod_id;
3515 struct list_head* ptr;
3516 u8 sc = 0; /* number of simultaneous cameras */
3517 static unsigned short dev_nr = 0; /* we are handling device number n */
3518
3519 if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[0].idVendor &&
3520 le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
3521 mod_id = W9968CF_MOD_CLVBWGP; /* see camlist[] table */
3522 else if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[1].idVendor &&
3523 le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[1].idProduct)
3524 mod_id = W9968CF_MOD_GENERIC; /* see camlist[] table */
3525 else
3526 return -ENODEV;
3527
3528 cam = (struct w9968cf_device*)
3529 kmalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
3530 if (!cam)
3531 return -ENOMEM;
3532
3533 memset(cam, 0, sizeof(*cam));
3534
3535 init_MUTEX(&cam->dev_sem);
3536 down(&cam->dev_sem);
3537
3538 cam->usbdev = udev;
3539 /* NOTE: a local copy is used to avoid possible race conditions */
3540 memcpy(&cam->dev, &udev->dev, sizeof(struct device));
3541
3542 DBG(2, "%s detected", symbolic(camlist, mod_id))
3543
3544 if (simcams > W9968CF_MAX_DEVICES)
3545 simcams = W9968CF_SIMCAMS;
3546
3547 /* How many cameras are connected ? */
3548 down(&w9968cf_devlist_sem);
3549 list_for_each(ptr, &w9968cf_dev_list)
3550 sc++;
3551 up(&w9968cf_devlist_sem);
3552
3553 if (sc >= simcams) {
3554 DBG(2, "Device rejected: too many connected cameras "
3555 "(max. %u)", simcams)
3556 err = -EPERM;
3557 goto fail;
3558 }
3559
3560
3561 /* Allocate 2 bytes of memory for camera control USB transfers */
3562 if (!(cam->control_buffer = (u16*)kmalloc(2, GFP_KERNEL))) {
3563 DBG(1,"Couldn't allocate memory for camera control transfers")
3564 err = -ENOMEM;
3565 goto fail;
3566 }
3567 memset(cam->control_buffer, 0, 2);
3568
3569 /* Allocate 8 bytes of memory for USB data transfers to the FSB */
3570 if (!(cam->data_buffer = (u16*)kmalloc(8, GFP_KERNEL))) {
3571 DBG(1, "Couldn't allocate memory for data "
3572 "transfers to the FSB")
3573 err = -ENOMEM;
3574 goto fail;
3575 }
3576 memset(cam->data_buffer, 0, 8);
3577
3578 /* Register the V4L device */
3579 cam->v4ldev = video_device_alloc();
3580 if (!cam->v4ldev) {
3581 DBG(1, "Could not allocate memory for a V4L structure")
3582 err = -ENOMEM;
3583 goto fail;
3584 }
3585
3586 strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
3587 cam->v4ldev->owner = THIS_MODULE;
3588 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
3589 cam->v4ldev->hardware = VID_HARDWARE_W9968CF;
3590 cam->v4ldev->fops = &w9968cf_fops;
3591 cam->v4ldev->minor = video_nr[dev_nr];
3592 cam->v4ldev->release = video_device_release;
3593 video_set_drvdata(cam->v4ldev, cam);
3594 cam->v4ldev->dev = &cam->dev;
3595
3596 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
3597 video_nr[dev_nr]);
3598 if (err) {
3599 DBG(1, "V4L device registration failed")
3600 if (err == -ENFILE && video_nr[dev_nr] == -1)
3601 DBG(2, "Couldn't find a free /dev/videoX node")
3602 video_nr[dev_nr] = -1;
3603 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3604 goto fail;
3605 }
3606
3607 DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->minor)
3608
3609 /* Set some basic constants */
3610 w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
3611
3612 /* Add a new entry into the list of V4L registered devices */
3613 down(&w9968cf_devlist_sem);
3614 list_add(&cam->v4llist, &w9968cf_dev_list);
3615 up(&w9968cf_devlist_sem);
3616 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3617
3618 w9968cf_turn_on_led(cam);
3619
3620 w9968cf_i2c_init(cam);
3621
3622 usb_set_intfdata(intf, cam);
3623 up(&cam->dev_sem);
3624 return 0;
3625
3626fail: /* Free unused memory */
3627 if (cam->control_buffer)
3628 kfree(cam->control_buffer);
3629 if (cam->data_buffer)
3630 kfree(cam->data_buffer);
3631 if (cam->v4ldev)
3632 video_device_release(cam->v4ldev);
3633 up(&cam->dev_sem);
3634 kfree(cam);
3635 return err;
3636}
3637
3638
3639static void w9968cf_usb_disconnect(struct usb_interface* intf)
3640{
3641 struct w9968cf_device* cam =
3642 (struct w9968cf_device*)usb_get_intfdata(intf);
3643
3644 down_write(&w9968cf_disconnect);
3645
3646 if (cam) {
3647 /* Prevent concurrent accesses to data */
3648 down(&cam->dev_sem);
3649
3650 cam->disconnected = 1;
3651
3652 DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id))
3653
3654 wake_up_interruptible_all(&cam->open);
3655
3656 if (cam->users) {
3657 DBG(2, "The device is open (/dev/video%d)! "
3658 "Process name: %s. Deregistration and memory "
3659 "deallocation are deferred on close.",
3660 cam->v4ldev->minor, cam->command)
3661 cam->misconfigured = 1;
3662 w9968cf_stop_transfer(cam);
3663 wake_up_interruptible(&cam->wait_queue);
3664 } else
3665 w9968cf_release_resources(cam);
3666
3667 up(&cam->dev_sem);
3668
3669 if (!cam->users)
3670 kfree(cam);
3671 }
3672
3673 up_write(&w9968cf_disconnect);
3674}
3675
3676
3677static struct usb_driver w9968cf_usb_driver = {
3678 .owner = THIS_MODULE,
3679 .name = "w9968cf",
3680 .id_table = winbond_id_table,
3681 .probe = w9968cf_usb_probe,
3682 .disconnect = w9968cf_usb_disconnect,
3683};
3684
3685
3686
3687/****************************************************************************
3688 * Module init, exit and intermodule communication *
3689 ****************************************************************************/
3690
3691static int w9968cf_vppmod_detect(struct w9968cf_device* cam)
3692{
3693 if (!w9968cf_vpp)
3694 if (vppmod_load)
3695 request_module("w9968cf-vpp");
3696
3697 down(&w9968cf_vppmod_lock);
3698
3699 if (!w9968cf_vpp) {
3700 DBG(4, "Video post-processing module not detected")
3701 w9968cf_adjust_configuration(cam);
3702 goto out;
3703 }
3704
3705 if (!try_module_get(w9968cf_vpp->owner)) {
3706 DBG(1, "Couldn't increment the reference count of "
3707 "the video post-processing module")
3708 up(&w9968cf_vppmod_lock);
3709 return -ENOSYS;
3710 }
3711
3712 w9968cf_vpp->busy++;
3713
3714 DBG(5, "Video post-processing module detected")
3715
3716out:
3717 up(&w9968cf_vppmod_lock);
3718 return 0;
3719}
3720
3721
3722static void w9968cf_vppmod_release(struct w9968cf_device* cam)
3723{
3724 down(&w9968cf_vppmod_lock);
3725
3726 if (w9968cf_vpp && w9968cf_vpp->busy) {
3727 module_put(w9968cf_vpp->owner);
3728 w9968cf_vpp->busy--;
3729 wake_up(&w9968cf_vppmod_wait);
3730 DBG(5, "Video post-processing module released")
3731 }
3732
3733 up(&w9968cf_vppmod_lock);
3734}
3735
3736
3737int w9968cf_vppmod_register(struct w9968cf_vpp_t* vpp)
3738{
3739 down(&w9968cf_vppmod_lock);
3740
3741 if (w9968cf_vpp) {
3742 KDBG(1, "Video post-processing module already registered")
3743 up(&w9968cf_vppmod_lock);
3744 return -EINVAL;
3745 }
3746
3747 w9968cf_vpp = vpp;
3748 w9968cf_vpp->busy = 0;
3749
3750 KDBG(2, "Video post-processing module registered")
3751 up(&w9968cf_vppmod_lock);
3752 return 0;
3753}
3754
3755
3756int w9968cf_vppmod_deregister(struct w9968cf_vpp_t* vpp)
3757{
3758 down(&w9968cf_vppmod_lock);
3759
3760 if (!w9968cf_vpp) {
3761 up(&w9968cf_vppmod_lock);
3762 return -EINVAL;
3763 }
3764
3765 if (w9968cf_vpp != vpp) {
3766 KDBG(1, "Only the owner can unregister the video "
3767 "post-processing module")
3768 up(&w9968cf_vppmod_lock);
3769 return -EINVAL;
3770 }
3771
3772 if (w9968cf_vpp->busy) {
3773 KDBG(2, "Video post-processing module busy. Wait for it to be "
3774 "released...")
3775 up(&w9968cf_vppmod_lock);
3776 wait_event(w9968cf_vppmod_wait, !w9968cf_vpp->busy);
3777 w9968cf_vpp = NULL;
3778 goto out;
3779 }
3780
3781 w9968cf_vpp = NULL;
3782
3783 up(&w9968cf_vppmod_lock);
3784
3785out:
3786 KDBG(2, "Video post-processing module unregistered")
3787 return 0;
3788}
3789
3790
3791static int __init w9968cf_module_init(void)
3792{
3793 int err;
3794
3795 KDBG(2, W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION)
3796 KDBG(3, W9968CF_MODULE_AUTHOR)
3797
3798 if (ovmod_load)
3799 request_module("ovcamchip");
3800
3801 if ((err = usb_register(&w9968cf_usb_driver)))
3802 return err;
3803
3804 return 0;
3805}
3806
3807
3808static void __exit w9968cf_module_exit(void)
3809{
3810 /* w9968cf_usb_disconnect() will be called */
3811 usb_deregister(&w9968cf_usb_driver);
3812
3813 KDBG(2, W9968CF_MODULE_NAME" deregistered")
3814}
3815
3816
3817module_init(w9968cf_module_init);
3818module_exit(w9968cf_module_exit);
3819
3820
3821EXPORT_SYMBOL(w9968cf_vppmod_register);
3822EXPORT_SYMBOL(w9968cf_vppmod_deregister);
diff --git a/drivers/usb/media/w9968cf.h b/drivers/usb/media/w9968cf.h
new file mode 100644
index 000000000000..8acbfe205bc7
--- /dev/null
+++ b/drivers/usb/media/w9968cf.h
@@ -0,0 +1,339 @@
1/***************************************************************************
2 * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip. *
3 * *
4 * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#ifndef _W9968CF_H_
22#define _W9968CF_H_
23
24#include <linux/videodev.h>
25#include <linux/usb.h>
26#include <linux/i2c.h>
27#include <linux/device.h>
28#include <linux/spinlock.h>
29#include <linux/list.h>
30#include <linux/wait.h>
31#include <linux/config.h>
32#include <linux/param.h>
33#include <linux/types.h>
34#include <linux/rwsem.h>
35#include <asm/semaphore.h>
36
37#include <media/ovcamchip.h>
38
39#include "w9968cf_vpp.h"
40
41
42/****************************************************************************
43 * Default values *
44 ****************************************************************************/
45
46#define W9968CF_OVMOD_LOAD 1 /* automatic 'ovcamchip' module loading */
47#define W9968CF_VPPMOD_LOAD 1 /* automatic 'w9968cf-vpp' module loading */
48
49/* Comment/uncomment the following line to enable/disable debugging messages */
50#define W9968CF_DEBUG
51
52/* These have effect only if W9968CF_DEBUG is defined */
53#define W9968CF_DEBUG_LEVEL 2 /* from 0 to 6. 0 for no debug informations */
54#define W9968CF_SPECIFIC_DEBUG 0 /* 0 or 1 */
55
56#define W9968CF_MAX_DEVICES 32
57#define W9968CF_SIMCAMS W9968CF_MAX_DEVICES /* simultaneous cameras */
58
59#define W9968CF_MAX_BUFFERS 32
60#define W9968CF_BUFFERS 2 /* n. of frame buffers from 2 to MAX_BUFFERS */
61
62/* Maximum data payload sizes in bytes for alternate settings */
63static const u16 wMaxPacketSize[] = {1023, 959, 895, 831, 767, 703, 639, 575,
64 511, 447, 383, 319, 255, 191, 127, 63};
65#define W9968CF_PACKET_SIZE 1023 /* according to wMaxPacketSizes[] */
66#define W9968CF_MIN_PACKET_SIZE 63 /* minimum value */
67#define W9968CF_ISO_PACKETS 5 /* n.of packets for isochronous transfers */
68#define W9968CF_USB_CTRL_TIMEOUT 1000 /* timeout (ms) for usb control commands */
69#define W9968CF_URBS 2 /* n. of scheduled URBs for ISO transfer */
70
71#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */
72#define W9968CF_I2C_RW_RETRIES 15 /* number of max I2C r/w retries */
73
74/* Available video formats */
75struct w9968cf_format {
76 const u16 palette;
77 const u16 depth;
78 const u8 compression;
79};
80
81static const struct w9968cf_format w9968cf_formatlist[] = {
82 { VIDEO_PALETTE_UYVY, 16, 0 }, /* original video */
83 { VIDEO_PALETTE_YUV422P, 16, 1 }, /* with JPEG compression */
84 { VIDEO_PALETTE_YUV420P, 12, 1 }, /* with JPEG compression */
85 { VIDEO_PALETTE_YUV420, 12, 1 }, /* same as YUV420P */
86 { VIDEO_PALETTE_YUYV, 16, 0 }, /* software conversion */
87 { VIDEO_PALETTE_YUV422, 16, 0 }, /* software conversion */
88 { VIDEO_PALETTE_GREY, 8, 0 }, /* software conversion */
89 { VIDEO_PALETTE_RGB555, 16, 0 }, /* software conversion */
90 { VIDEO_PALETTE_RGB565, 16, 0 }, /* software conversion */
91 { VIDEO_PALETTE_RGB24, 24, 0 }, /* software conversion */
92 { VIDEO_PALETTE_RGB32, 32, 0 }, /* software conversion */
93 { 0, 0, 0 } /* 0 is a terminating entry */
94};
95
96#define W9968CF_DECOMPRESSION 2 /* decomp:0=disable,1=force,2=any formats */
97#define W9968CF_PALETTE_DECOMP_OFF VIDEO_PALETTE_UYVY /* when decomp=0 */
98#define W9968CF_PALETTE_DECOMP_FORCE VIDEO_PALETTE_YUV420P /* when decomp=1 */
99#define W9968CF_PALETTE_DECOMP_ON VIDEO_PALETTE_UYVY /* when decomp=2 */
100
101#define W9968CF_FORCE_RGB 0 /* read RGB instead of BGR, yes=1/no=0 */
102
103#define W9968CF_MAX_WIDTH 800 /* Has effect if up-scaling is on */
104#define W9968CF_MAX_HEIGHT 600 /* Has effect if up-scaling is on */
105#define W9968CF_WIDTH 320 /* from 128 to 352, multiple of 16 */
106#define W9968CF_HEIGHT 240 /* from 96 to 288, multiple of 16 */
107
108#define W9968CF_CLAMPING 0 /* 0 disable, 1 enable video data clamping */
109#define W9968CF_FILTER_TYPE 0 /* 0 disable 1 (1-2-1), 2 (2-3-6-3-2) */
110#define W9968CF_DOUBLE_BUFFER 1 /* 0 disable, 1 enable double buffer */
111#define W9968CF_LARGEVIEW 1 /* 0 disable, 1 enable */
112#define W9968CF_UPSCALING 0 /* 0 disable, 1 enable */
113
114#define W9968CF_MONOCHROME 0 /* 0 not monochrome, 1 monochrome sensor */
115#define W9968CF_BRIGHTNESS 31000 /* from 0 to 65535 */
116#define W9968CF_HUE 32768 /* from 0 to 65535 */
117#define W9968CF_COLOUR 32768 /* from 0 to 65535 */
118#define W9968CF_CONTRAST 50000 /* from 0 to 65535 */
119#define W9968CF_WHITENESS 32768 /* from 0 to 65535 */
120
121#define W9968CF_AUTOBRIGHT 0 /* 0 disable, 1 enable automatic brightness */
122#define W9968CF_AUTOEXP 1 /* 0 disable, 1 enable automatic exposure */
123#define W9968CF_LIGHTFREQ 50 /* light frequency. 50Hz (Europe) or 60Hz */
124#define W9968CF_BANDINGFILTER 0 /* 0 disable, 1 enable banding filter */
125#define W9968CF_BACKLIGHT 0 /* 0 or 1, 1=object is lit from behind */
126#define W9968CF_MIRROR 0 /* 0 or 1 [don't] reverse image horizontally*/
127
128#define W9968CF_CLOCKDIV -1 /* -1 = automatic clock divisor */
129#define W9968CF_DEF_CLOCKDIVISOR 0 /* default sensor clock divisor value */
130
131
132/****************************************************************************
133 * Globals *
134 ****************************************************************************/
135
136#define W9968CF_MODULE_NAME "V4L driver for W996[87]CF JPEG USB " \
137 "Dual Mode Camera Chip"
138#define W9968CF_MODULE_VERSION "1:1.33-basic"
139#define W9968CF_MODULE_AUTHOR "(C) 2002-2004 Luca Risolia"
140#define W9968CF_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
141#define W9968CF_MODULE_LICENSE "GPL"
142
143static const struct usb_device_id winbond_id_table[] = {
144 {
145 /* Creative Labs Video Blaster WebCam Go Plus */
146 USB_DEVICE(0x041e, 0x4003),
147 .driver_info = (unsigned long)"w9968cf",
148 },
149 {
150 /* Generic W996[87]CF JPEG USB Dual Mode Camera */
151 USB_DEVICE(0x1046, 0x9967),
152 .driver_info = (unsigned long)"w9968cf",
153 },
154 { } /* terminating entry */
155};
156
157/* W996[87]CF camera models, internal ids: */
158enum w9968cf_model_id {
159 W9968CF_MOD_GENERIC = 1, /* Generic W996[87]CF based device */
160 W9968CF_MOD_CLVBWGP = 11,/*Creative Labs Video Blaster WebCam Go Plus*/
161 W9968CF_MOD_ADPVDMA = 21, /* Aroma Digi Pen VGA Dual Mode ADG-5000 */
162 W9986CF_MOD_AAU = 31, /* AVerMedia AVerTV USB */
163 W9968CF_MOD_CLVBWG = 34, /* Creative Labs Video Blaster WebCam Go */
164 W9968CF_MOD_LL = 37, /* Lebon LDC-035A */
165 W9968CF_MOD_EEEMC = 40, /* Ezonics EZ-802 EZMega Cam */
166 W9968CF_MOD_OOE = 42, /* OmniVision OV8610-EDE */
167 W9968CF_MOD_ODPVDMPC = 43,/* OPCOM Digi Pen VGA Dual Mode Pen Camera */
168 W9968CF_MOD_PDPII = 46, /* Pretec Digi Pen-II */
169 W9968CF_MOD_PDP480 = 49, /* Pretec DigiPen-480 */
170};
171
172enum w9968cf_frame_status {
173 F_READY, /* finished grabbing & ready to be read/synced */
174 F_GRABBING, /* in the process of being grabbed into */
175 F_ERROR, /* something bad happened while processing */
176 F_UNUSED /* unused (no VIDIOCMCAPTURE) */
177};
178
179struct w9968cf_frame_t {
180 void* buffer;
181 unsigned long size;
182 u32 length;
183 int number;
184 enum w9968cf_frame_status status;
185 struct w9968cf_frame_t* next;
186 u8 queued;
187};
188
189enum w9968cf_vpp_flag {
190 VPP_NONE = 0x00,
191 VPP_UPSCALE = 0x01,
192 VPP_SWAP_YUV_BYTES = 0x02,
193 VPP_DECOMPRESSION = 0x04,
194 VPP_UYVY_TO_RGBX = 0x08,
195};
196
197static struct w9968cf_vpp_t* w9968cf_vpp;
198static DECLARE_MUTEX(w9968cf_vppmod_lock);
199static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait);
200
201static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */
202static DECLARE_MUTEX(w9968cf_devlist_sem); /* semaphore for list traversal */
203
204static DECLARE_RWSEM(w9968cf_disconnect); /* prevent races with open() */
205
206/* Main device driver structure */
207struct w9968cf_device {
208 struct device dev; /* device structure */
209
210 enum w9968cf_model_id id; /* private device identifier */
211
212 struct video_device* v4ldev; /* -> V4L structure */
213 struct list_head v4llist; /* entry of the list of V4L cameras */
214
215 struct usb_device* usbdev; /* -> main USB structure */
216 struct urb* urb[W9968CF_URBS]; /* -> USB request block structs */
217 void* transfer_buffer[W9968CF_URBS]; /* -> ISO transfer buffers */
218 u16* control_buffer; /* -> buffer for control req.*/
219 u16* data_buffer; /* -> data to send to the FSB */
220
221 struct w9968cf_frame_t frame[W9968CF_MAX_BUFFERS];
222 struct w9968cf_frame_t frame_tmp; /* temporary frame */
223 struct w9968cf_frame_t frame_vpp; /* helper frame.*/
224 struct w9968cf_frame_t* frame_current; /* -> frame being grabbed */
225 struct w9968cf_frame_t* requested_frame[W9968CF_MAX_BUFFERS];
226
227 u8 max_buffers, /* number of requested buffers */
228 force_palette, /* yes=1/no=0 */
229 force_rgb, /* read RGB instead of BGR, yes=1, no=0 */
230 double_buffer, /* hardware double buffering yes=1/no=0 */
231 clamping, /* video data clamping yes=1/no=0 */
232 filter_type, /* 0=disabled, 1=3 tap, 2=5 tap filter */
233 capture, /* 0=disabled, 1=enabled */
234 largeview, /* 0=disabled, 1=enabled */
235 decompression, /* 0=disabled, 1=forced, 2=allowed */
236 upscaling; /* software image scaling, 0=enabled, 1=disabled */
237
238 struct video_picture picture; /* current picture settings */
239 struct video_window window; /* current window settings */
240
241 u16 hw_depth, /* depth (used by the chip) */
242 hw_palette, /* palette (used by the chip) */
243 hw_width, /* width (used by the chip) */
244 hw_height, /* height (used by the chip) */
245 hs_polarity, /* 0=negative sync pulse, 1=positive sync pulse */
246 vs_polarity, /* 0=negative sync pulse, 1=positive sync pulse */
247 start_cropx, /* pixels from HS inactive edge to 1st cropped pixel*/
248 start_cropy; /* pixels from VS inactive edge to 1st cropped pixel*/
249
250 enum w9968cf_vpp_flag vpp_flag; /* post-processing routines in use */
251
252 u8 nbuffers, /* number of allocated frame buffers */
253 altsetting, /* camera alternate setting */
254 disconnected, /* flag: yes=1, no=0 */
255 misconfigured, /* flag: yes=1, no=0 */
256 users, /* flag: number of users holding the device */
257 streaming; /* flag: yes=1, no=0 */
258
259 u8 sensor_initialized; /* flag: yes=1, no=0 */
260
261 /* Determined by the image sensor type: */
262 int sensor, /* type of image sensor chip (CC_*) */
263 monochrome; /* image sensor is (probably) monochrome */
264 u16 maxwidth, /* maximum width supported by the image sensor */
265 maxheight, /* maximum height supported by the image sensor */
266 minwidth, /* minimum width supported by the image sensor */
267 minheight; /* minimum height supported by the image sensor */
268 u8 auto_brt, /* auto brightness enabled flag */
269 auto_exp, /* auto exposure enabled flag */
270 backlight, /* backlight exposure algorithm flag */
271 mirror, /* image is reversed horizontally */
272 lightfreq, /* power (lighting) frequency */
273 bandfilt; /* banding filter enabled flag */
274 s8 clockdiv; /* clock divisor */
275
276 /* I2C interface to kernel */
277 struct i2c_adapter i2c_adapter;
278 struct i2c_client* sensor_client;
279
280 /* Locks */
281 struct semaphore dev_sem, /* for probe, disconnect,open and close */
282 fileop_sem; /* for read and ioctl */
283 spinlock_t urb_lock, /* for submit_urb() and unlink_urb() */
284 flist_lock; /* for requested frame list accesses */
285 wait_queue_head_t open, wait_queue;
286
287 char command[16]; /* name of the program holding the device */
288};
289
290
291/****************************************************************************
292 * Macros for debugging *
293 ****************************************************************************/
294
295#undef DBG
296#undef KDBG
297#ifdef W9968CF_DEBUG
298/* For device specific debugging messages */
299# define DBG(level, fmt, args...) \
300{ \
301 if ( ((specific_debug) && (debug == (level))) || \
302 ((!specific_debug) && (debug >= (level))) ) { \
303 if ((level) == 1) \
304 dev_err(&cam->dev, fmt "\n", ## args); \
305 else if ((level) == 2 || (level) == 3) \
306 dev_info(&cam->dev, fmt "\n", ## args); \
307 else if ((level) == 4) \
308 dev_warn(&cam->dev, fmt "\n", ## args); \
309 else if ((level) >= 5) \
310 dev_info(&cam->dev, "[%s:%d] " fmt "\n", \
311 __FUNCTION__, __LINE__ , ## args); \
312 } \
313}
314/* For generic kernel (not device specific) messages */
315# define KDBG(level, fmt, args...) \
316{ \
317 if ( ((specific_debug) && (debug == (level))) || \
318 ((!specific_debug) && (debug >= (level))) ) { \
319 if ((level) >= 1 && (level) <= 4) \
320 pr_info("w9968cf: " fmt "\n", ## args); \
321 else if ((level) >= 5) \
322 pr_debug("w9968cf: [%s:%d] " fmt "\n", __FUNCTION__, \
323 __LINE__ , ## args); \
324 } \
325}
326#else
327 /* Not debugging: nothing */
328# define DBG(level, fmt, args...) do {;} while(0);
329# define KDBG(level, fmt, args...) do {;} while(0);
330#endif
331
332#undef PDBG
333#define PDBG(fmt, args...) \
334dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args);
335
336#undef PDBGG
337#define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */
338
339#endif /* _W9968CF_H_ */
diff --git a/drivers/usb/media/w9968cf_decoder.h b/drivers/usb/media/w9968cf_decoder.h
new file mode 100644
index 000000000000..31faccbe8f03
--- /dev/null
+++ b/drivers/usb/media/w9968cf_decoder.h
@@ -0,0 +1,86 @@
1/***************************************************************************
2 * Video decoder for the W996[87]CF driver for Linux. *
3 * *
4 * Copyright (C) 2003 2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#ifndef _W9968CF_DECODER_H_
22#define _W9968CF_DECODER_H_
23
24/* Comment/uncomment this for high/low quality of compressed video */
25#define W9968CF_DEC_FAST_LOWQUALITY_VIDEO
26
27#ifdef W9968CF_DEC_FAST_LOWQUALITY_VIDEO
28static const unsigned char Y_QUANTABLE[64] = {
29 16, 11, 10, 16, 24, 40, 51, 61,
30 12, 12, 14, 19, 26, 58, 60, 55,
31 14, 13, 16, 24, 40, 57, 69, 56,
32 14, 17, 22, 29, 51, 87, 80, 62,
33 18, 22, 37, 56, 68, 109, 103, 77,
34 24, 35, 55, 64, 81, 104, 113, 92,
35 49, 64, 78, 87, 103, 121, 120, 101,
36 72, 92, 95, 98, 112, 100, 103, 99
37};
38
39static const unsigned char UV_QUANTABLE[64] = {
40 17, 18, 24, 47, 99, 99, 99, 99,
41 18, 21, 26, 66, 99, 99, 99, 99,
42 24, 26, 56, 99, 99, 99, 99, 99,
43 47, 66, 99, 99, 99, 99, 99, 99,
44 99, 99, 99, 99, 99, 99, 99, 99,
45 99, 99, 99, 99, 99, 99, 99, 99,
46 99, 99, 99, 99, 99, 99, 99, 99,
47 99, 99, 99, 99, 99, 99, 99, 99
48};
49#else
50static const unsigned char Y_QUANTABLE[64] = {
51 8, 5, 5, 8, 12, 20, 25, 30,
52 6, 6, 7, 9, 13, 29, 30, 27,
53 7, 6, 8, 12, 20, 28, 34, 28,
54 7, 8, 11, 14, 25, 43, 40, 31,
55 9, 11, 18, 28, 34, 54, 51, 38,
56 12, 17, 27, 32, 40, 52, 56, 46,
57 24, 32, 39, 43, 51, 60, 60, 50,
58 36, 46, 47, 49, 56, 50, 51, 49
59};
60
61static const unsigned char UV_QUANTABLE[64] = {
62 8, 9, 12, 23, 49, 49, 49, 49,
63 9, 10, 13, 33, 49, 49, 49, 49,
64 12, 13, 28, 49, 49, 49, 49, 49,
65 23, 33, 49, 49, 49, 49, 49, 49,
66 49, 49, 49, 49, 49, 49, 49, 49,
67 49, 49, 49, 49, 49, 49, 49, 49,
68 49, 49, 49, 49, 49, 49, 49, 49,
69 49, 49, 49, 49, 49, 49, 49, 49
70};
71#endif
72
73#define W9968CF_DEC_ERR_CORRUPTED_DATA -1
74#define W9968CF_DEC_ERR_BUF_OVERFLOW -2
75#define W9968CF_DEC_ERR_NO_SOI -3
76#define W9968CF_DEC_ERR_NO_SOF0 -4
77#define W9968CF_DEC_ERR_NO_SOS -5
78#define W9968CF_DEC_ERR_NO_EOI -6
79
80extern void w9968cf_init_decoder(void);
81extern int w9968cf_check_headers(const unsigned char* Pin,
82 const unsigned long BUF_SIZE);
83extern int w9968cf_decode(const char* Pin, const unsigned long BUF_SIZE,
84 const unsigned W, const unsigned H, char* Pout);
85
86#endif /* _W9968CF_DECODER_H_ */
diff --git a/drivers/usb/media/w9968cf_vpp.h b/drivers/usb/media/w9968cf_vpp.h
new file mode 100644
index 000000000000..3f5317dc4c29
--- /dev/null
+++ b/drivers/usb/media/w9968cf_vpp.h
@@ -0,0 +1,43 @@
1/***************************************************************************
2 * Interface for video post-processing functions for the W996[87]CF driver *
3 * for Linux. *
4 * *
5 * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#ifndef _W9968CF_VPP_H_
23#define _W9968CF_VPP_H_
24
25#include <linux/module.h>
26#include <asm/types.h>
27
28struct w9968cf_vpp_t {
29 struct module* owner;
30 int (*check_headers)(const unsigned char*, const unsigned long);
31 int (*decode)(const char*, const unsigned long, const unsigned,
32 const unsigned, char*);
33 void (*swap_yuvbytes)(void*, unsigned long);
34 void (*uyvy_to_rgbx)(u8*, unsigned long, u8*, u16, u8);
35 void (*scale_up)(u8*, u8*, u16, u16, u16, u16, u16);
36
37 u8 busy; /* read-only flag: module is/is not in use */
38};
39
40extern int w9968cf_vppmod_register(struct w9968cf_vpp_t*);
41extern int w9968cf_vppmod_deregister(struct w9968cf_vpp_t*);
42
43#endif /* _W9968CF_VPP_H_ */