diff options
-rw-r--r-- | Documentation/feature-removal-schedule.txt | 15 | ||||
-rw-r--r-- | drivers/staging/Kconfig | 2 | ||||
-rw-r--r-- | drivers/staging/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/se401/Kconfig | 13 | ||||
-rw-r--r-- | drivers/staging/se401/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/se401/TODO | 5 | ||||
-rw-r--r-- | drivers/staging/se401/se401.c | 1492 | ||||
-rw-r--r-- | drivers/staging/se401/se401.h | 236 | ||||
-rw-r--r-- | drivers/staging/se401/videodev.h | 318 |
9 files changed, 0 insertions, 2083 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index b3f35e5f9c95..08e0df12df37 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -97,21 +97,6 @@ Who: Pavel Machek <pavel@ucw.cz> | |||
97 | 97 | ||
98 | --------------------------- | 98 | --------------------------- |
99 | 99 | ||
100 | What: Video4Linux obsolete drivers using V4L1 API | ||
101 | When: kernel 2.6.39 | ||
102 | Files: drivers/staging/se401/* drivers/staging/usbvideo/* | ||
103 | Check: drivers/staging/se401/se401.c drivers/staging/usbvideo/usbvideo.c | ||
104 | Why: There are some drivers still using V4L1 API, despite all efforts we've done | ||
105 | to migrate. Those drivers are for obsolete hardware that the old maintainer | ||
106 | didn't care (or not have the hardware anymore), and that no other developer | ||
107 | could find any hardware to buy. They probably have no practical usage today, | ||
108 | and people with such old hardware could probably keep using an older version | ||
109 | of the kernel. Those drivers will be moved to staging on 2.6.38 and, if nobody | ||
110 | cares enough to port and test them with V4L2 API, they'll be removed on 2.6.39. | ||
111 | Who: Mauro Carvalho Chehab <mchehab@infradead.org> | ||
112 | |||
113 | --------------------------- | ||
114 | |||
115 | What: Video4Linux: Remove obsolete ioctl's | 100 | What: Video4Linux: Remove obsolete ioctl's |
116 | When: kernel 2.6.39 | 101 | When: kernel 2.6.39 |
117 | Files: include/media/videodev2.h | 102 | Files: include/media/videodev2.h |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index a3f340bb6b59..fa5c007e74c8 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -55,8 +55,6 @@ source "drivers/staging/cxd2099/Kconfig" | |||
55 | 55 | ||
56 | source "drivers/staging/dabusb/Kconfig" | 56 | source "drivers/staging/dabusb/Kconfig" |
57 | 57 | ||
58 | source "drivers/staging/se401/Kconfig" | ||
59 | |||
60 | source "drivers/staging/usbip/Kconfig" | 58 | source "drivers/staging/usbip/Kconfig" |
61 | 59 | ||
62 | source "drivers/staging/winbond/Kconfig" | 60 | source "drivers/staging/winbond/Kconfig" |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 532331ceb12d..2bdd703ed208 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -10,7 +10,6 @@ obj-$(CONFIG_VIDEO_CX25821) += cx25821/ | |||
10 | obj-$(CONFIG_VIDEO_TM6000) += tm6000/ | 10 | obj-$(CONFIG_VIDEO_TM6000) += tm6000/ |
11 | obj-$(CONFIG_DVB_CXD2099) += cxd2099/ | 11 | obj-$(CONFIG_DVB_CXD2099) += cxd2099/ |
12 | obj-$(CONFIG_USB_DABUSB) += dabusb/ | 12 | obj-$(CONFIG_USB_DABUSB) += dabusb/ |
13 | obj-$(CONFIG_USB_SE401) += se401/ | ||
14 | obj-$(CONFIG_LIRC_STAGING) += lirc/ | 13 | obj-$(CONFIG_LIRC_STAGING) += lirc/ |
15 | obj-$(CONFIG_USB_IP_COMMON) += usbip/ | 14 | obj-$(CONFIG_USB_IP_COMMON) += usbip/ |
16 | obj-$(CONFIG_W35UND) += winbond/ | 15 | obj-$(CONFIG_W35UND) += winbond/ |
diff --git a/drivers/staging/se401/Kconfig b/drivers/staging/se401/Kconfig deleted file mode 100644 index b7f8222ad21b..000000000000 --- a/drivers/staging/se401/Kconfig +++ /dev/null | |||
@@ -1,13 +0,0 @@ | |||
1 | config USB_SE401 | ||
2 | tristate "USB SE401 Camera support (DEPRECATED)" | ||
3 | depends on VIDEO_DEV && VIDEO_V4L2_COMMON && USB | ||
4 | ---help--- | ||
5 | Say Y here if you want to connect this type of camera to your | ||
6 | computer's USB port. See <file:Documentation/video4linux/se401.txt> | ||
7 | for more information and for a list of supported cameras. | ||
8 | |||
9 | This driver uses the deprecated V4L1 API and will be removed in | ||
10 | 2.6.39, unless someone converts it to the V4L2 API. | ||
11 | |||
12 | To compile this driver as a module, choose M here: the | ||
13 | module will be called se401. | ||
diff --git a/drivers/staging/se401/Makefile b/drivers/staging/se401/Makefile deleted file mode 100644 index b465d49783af..000000000000 --- a/drivers/staging/se401/Makefile +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | obj-$(CONFIG_USB_SE401) += se401.o | ||
diff --git a/drivers/staging/se401/TODO b/drivers/staging/se401/TODO deleted file mode 100644 index 3b2c03836286..000000000000 --- a/drivers/staging/se401/TODO +++ /dev/null | |||
@@ -1,5 +0,0 @@ | |||
1 | This is an obsolete driver for some old webcams that still use V4L1 API. | ||
2 | As V4L1 support is being removed from kernel, if nobody take care on it, | ||
3 | the driver will be removed for 2.6.39. | ||
4 | |||
5 | Please send patches to linux-media@vger.kernel.org | ||
diff --git a/drivers/staging/se401/se401.c b/drivers/staging/se401/se401.c deleted file mode 100644 index 41360d7c3e96..000000000000 --- a/drivers/staging/se401/se401.c +++ /dev/null | |||
@@ -1,1492 +0,0 @@ | |||
1 | /* | ||
2 | * Endpoints (formerly known as AOX) se401 USB Camera Driver | ||
3 | * | ||
4 | * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org) | ||
5 | * | ||
6 | * Still somewhat based on the Linux ov511 driver. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
15 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
16 | * for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software Foundation, | ||
20 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * | ||
23 | * Thanks to Endpoints Inc. (www.endpoints.com) for making documentation on | ||
24 | * their chipset available and supporting me while writing this driver. | ||
25 | * - Jeroen Vreeken | ||
26 | */ | ||
27 | |||
28 | static const char version[] = "0.24"; | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/vmalloc.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/pagemap.h> | ||
35 | #include <linux/usb.h> | ||
36 | #include "se401.h" | ||
37 | |||
38 | static int flickerless; | ||
39 | static int video_nr = -1; | ||
40 | |||
41 | static struct usb_device_id device_table[] = { | ||
42 | { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */ | ||
43 | { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */ | ||
44 | { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */ | ||
45 | { USB_DEVICE(0x047d, 0x5002) },/* Kensington 6701(5/7) */ | ||
46 | { USB_DEVICE(0x047d, 0x5003) },/* Kensington 67016 */ | ||
47 | { } | ||
48 | }; | ||
49 | |||
50 | MODULE_DEVICE_TABLE(usb, device_table); | ||
51 | |||
52 | MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>"); | ||
53 | MODULE_DESCRIPTION("SE401 USB Camera Driver"); | ||
54 | MODULE_LICENSE("GPL"); | ||
55 | module_param(flickerless, int, 0); | ||
56 | MODULE_PARM_DESC(flickerless, | ||
57 | "Net frequency to adjust exposure time to (0/50/60)"); | ||
58 | module_param(video_nr, int, 0); | ||
59 | |||
60 | static struct usb_driver se401_driver; | ||
61 | |||
62 | |||
63 | /********************************************************************** | ||
64 | * | ||
65 | * Memory management | ||
66 | * | ||
67 | **********************************************************************/ | ||
68 | static void *rvmalloc(unsigned long size) | ||
69 | { | ||
70 | void *mem; | ||
71 | unsigned long adr; | ||
72 | |||
73 | size = PAGE_ALIGN(size); | ||
74 | mem = vmalloc_32(size); | ||
75 | if (!mem) | ||
76 | return NULL; | ||
77 | |||
78 | memset(mem, 0, size); /* Clear the ram out, no junk to the user */ | ||
79 | adr = (unsigned long) mem; | ||
80 | while (size > 0) { | ||
81 | SetPageReserved(vmalloc_to_page((void *)adr)); | ||
82 | adr += PAGE_SIZE; | ||
83 | size -= PAGE_SIZE; | ||
84 | } | ||
85 | |||
86 | return mem; | ||
87 | } | ||
88 | |||
89 | static void rvfree(void *mem, unsigned long size) | ||
90 | { | ||
91 | unsigned long adr; | ||
92 | |||
93 | if (!mem) | ||
94 | return; | ||
95 | |||
96 | adr = (unsigned long) mem; | ||
97 | while ((long) size > 0) { | ||
98 | ClearPageReserved(vmalloc_to_page((void *)adr)); | ||
99 | adr += PAGE_SIZE; | ||
100 | size -= PAGE_SIZE; | ||
101 | } | ||
102 | vfree(mem); | ||
103 | } | ||
104 | |||
105 | |||
106 | |||
107 | /**************************************************************************** | ||
108 | * | ||
109 | * se401 register read/write functions | ||
110 | * | ||
111 | ***************************************************************************/ | ||
112 | |||
113 | static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req, | ||
114 | unsigned short value, unsigned char *cp, int size) | ||
115 | { | ||
116 | return usb_control_msg( | ||
117 | se401->dev, | ||
118 | set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0), | ||
119 | req, | ||
120 | (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
121 | value, | ||
122 | 0, | ||
123 | cp, | ||
124 | size, | ||
125 | 1000 | ||
126 | ); | ||
127 | } | ||
128 | |||
129 | static int se401_set_feature(struct usb_se401 *se401, unsigned short selector, | ||
130 | unsigned short param) | ||
131 | { | ||
132 | /* specs say that the selector (address) should go in the value field | ||
133 | and the param in index, but in the logs of the windows driver they do | ||
134 | this the other way around... | ||
135 | */ | ||
136 | return usb_control_msg( | ||
137 | se401->dev, | ||
138 | usb_sndctrlpipe(se401->dev, 0), | ||
139 | SE401_REQ_SET_EXT_FEATURE, | ||
140 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
141 | param, | ||
142 | selector, | ||
143 | NULL, | ||
144 | 0, | ||
145 | 1000 | ||
146 | ); | ||
147 | } | ||
148 | |||
149 | static unsigned short se401_get_feature(struct usb_se401 *se401, | ||
150 | unsigned short selector) | ||
151 | { | ||
152 | /* For 'set' the selecetor should be in index, not sure if the spec is | ||
153 | wrong here to.... | ||
154 | */ | ||
155 | unsigned char cp[2]; | ||
156 | usb_control_msg( | ||
157 | se401->dev, | ||
158 | usb_rcvctrlpipe(se401->dev, 0), | ||
159 | SE401_REQ_GET_EXT_FEATURE, | ||
160 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
161 | 0, | ||
162 | selector, | ||
163 | cp, | ||
164 | 2, | ||
165 | 1000 | ||
166 | ); | ||
167 | return cp[0]+cp[1]*256; | ||
168 | } | ||
169 | |||
170 | /**************************************************************************** | ||
171 | * | ||
172 | * Camera control | ||
173 | * | ||
174 | ***************************************************************************/ | ||
175 | |||
176 | |||
177 | static int se401_send_pict(struct usb_se401 *se401) | ||
178 | { | ||
179 | /* integration time low */ | ||
180 | se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l); | ||
181 | /* integration time mid */ | ||
182 | se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m); | ||
183 | /* integration time mid */ | ||
184 | se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h); | ||
185 | /* reset level value */ | ||
186 | se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel); | ||
187 | /* red color gain */ | ||
188 | se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain); | ||
189 | /* green color gain */ | ||
190 | se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain); | ||
191 | /* blue color gain */ | ||
192 | se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain); | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | static void se401_set_exposure(struct usb_se401 *se401, int brightness) | ||
198 | { | ||
199 | int integration = brightness << 5; | ||
200 | |||
201 | if (flickerless == 50) | ||
202 | integration = integration-integration % 106667; | ||
203 | if (flickerless == 60) | ||
204 | integration = integration-integration % 88889; | ||
205 | se401->brightness = integration >> 5; | ||
206 | se401->expose_h = (integration >> 16) & 0xff; | ||
207 | se401->expose_m = (integration >> 8) & 0xff; | ||
208 | se401->expose_l = integration & 0xff; | ||
209 | } | ||
210 | |||
211 | static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p) | ||
212 | { | ||
213 | p->brightness = se401->brightness; | ||
214 | if (se401->enhance) | ||
215 | p->whiteness = 32768; | ||
216 | else | ||
217 | p->whiteness = 0; | ||
218 | |||
219 | p->colour = 65535; | ||
220 | p->contrast = 65535; | ||
221 | p->hue = se401->rgain << 10; | ||
222 | p->palette = se401->palette; | ||
223 | p->depth = 3; /* rgb24 */ | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | |||
228 | static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p) | ||
229 | { | ||
230 | if (p->palette != VIDEO_PALETTE_RGB24) | ||
231 | return 1; | ||
232 | se401->palette = p->palette; | ||
233 | if (p->hue != se401->hue) { | ||
234 | se401->rgain = p->hue >> 10; | ||
235 | se401->bgain = 0x40-(p->hue >> 10); | ||
236 | se401->hue = p->hue; | ||
237 | } | ||
238 | if (p->brightness != se401->brightness) | ||
239 | se401_set_exposure(se401, p->brightness); | ||
240 | |||
241 | if (p->whiteness >= 32768) | ||
242 | se401->enhance = 1; | ||
243 | else | ||
244 | se401->enhance = 0; | ||
245 | se401_send_pict(se401); | ||
246 | se401_send_pict(se401); | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | Hyundai have some really nice docs about this and other sensor related | ||
252 | stuff on their homepage: www.hei.co.kr | ||
253 | */ | ||
254 | static void se401_auto_resetlevel(struct usb_se401 *se401) | ||
255 | { | ||
256 | unsigned int ahrc, alrc; | ||
257 | int oldreset = se401->resetlevel; | ||
258 | |||
259 | /* For some reason this normally read-only register doesn't get reset | ||
260 | to zero after reading them just once... | ||
261 | */ | ||
262 | se401_get_feature(se401, HV7131_REG_HIREFNOH); | ||
263 | se401_get_feature(se401, HV7131_REG_HIREFNOL); | ||
264 | se401_get_feature(se401, HV7131_REG_LOREFNOH); | ||
265 | se401_get_feature(se401, HV7131_REG_LOREFNOL); | ||
266 | ahrc = 256*se401_get_feature(se401, HV7131_REG_HIREFNOH) + | ||
267 | se401_get_feature(se401, HV7131_REG_HIREFNOL); | ||
268 | alrc = 256*se401_get_feature(se401, HV7131_REG_LOREFNOH) + | ||
269 | se401_get_feature(se401, HV7131_REG_LOREFNOL); | ||
270 | |||
271 | /* Not an exact science, but it seems to work pretty well... */ | ||
272 | if (alrc > 10) { | ||
273 | while (alrc >= 10 && se401->resetlevel < 63) { | ||
274 | se401->resetlevel++; | ||
275 | alrc /= 2; | ||
276 | } | ||
277 | } else if (ahrc > 20) { | ||
278 | while (ahrc >= 20 && se401->resetlevel > 0) { | ||
279 | se401->resetlevel--; | ||
280 | ahrc /= 2; | ||
281 | } | ||
282 | } | ||
283 | if (se401->resetlevel != oldreset) | ||
284 | se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel); | ||
285 | |||
286 | return; | ||
287 | } | ||
288 | |||
289 | /* irq handler for snapshot button */ | ||
290 | static void se401_button_irq(struct urb *urb) | ||
291 | { | ||
292 | struct usb_se401 *se401 = urb->context; | ||
293 | int status; | ||
294 | |||
295 | if (!se401->dev) { | ||
296 | dev_info(&urb->dev->dev, "device vapourished\n"); | ||
297 | return; | ||
298 | } | ||
299 | |||
300 | switch (urb->status) { | ||
301 | case 0: | ||
302 | /* success */ | ||
303 | break; | ||
304 | case -ECONNRESET: | ||
305 | case -ENOENT: | ||
306 | case -ESHUTDOWN: | ||
307 | /* this urb is terminated, clean up */ | ||
308 | dbg("%s - urb shutting down with status: %d", | ||
309 | __func__, urb->status); | ||
310 | return; | ||
311 | default: | ||
312 | dbg("%s - nonzero urb status received: %d", | ||
313 | __func__, urb->status); | ||
314 | goto exit; | ||
315 | } | ||
316 | |||
317 | if (urb->actual_length >= 2) | ||
318 | if (se401->button) | ||
319 | se401->buttonpressed = 1; | ||
320 | exit: | ||
321 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
322 | if (status) | ||
323 | err("%s - usb_submit_urb failed with result %d", | ||
324 | __func__, status); | ||
325 | } | ||
326 | |||
327 | static void se401_video_irq(struct urb *urb) | ||
328 | { | ||
329 | struct usb_se401 *se401 = urb->context; | ||
330 | int length = urb->actual_length; | ||
331 | |||
332 | /* ohoh... */ | ||
333 | if (!se401->streaming) | ||
334 | return; | ||
335 | |||
336 | if (!se401->dev) { | ||
337 | dev_info(&urb->dev->dev, "device vapourished\n"); | ||
338 | return; | ||
339 | } | ||
340 | |||
341 | /* 0 sized packets happen if we are to fast, but sometimes the camera | ||
342 | keeps sending them forever... | ||
343 | */ | ||
344 | if (length && !urb->status) { | ||
345 | se401->nullpackets = 0; | ||
346 | switch (se401->scratch[se401->scratch_next].state) { | ||
347 | case BUFFER_READY: | ||
348 | case BUFFER_BUSY: | ||
349 | se401->dropped++; | ||
350 | break; | ||
351 | case BUFFER_UNUSED: | ||
352 | memcpy(se401->scratch[se401->scratch_next].data, | ||
353 | (unsigned char *)urb->transfer_buffer, length); | ||
354 | se401->scratch[se401->scratch_next].state | ||
355 | = BUFFER_READY; | ||
356 | se401->scratch[se401->scratch_next].offset | ||
357 | = se401->bayeroffset; | ||
358 | se401->scratch[se401->scratch_next].length = length; | ||
359 | if (waitqueue_active(&se401->wq)) | ||
360 | wake_up_interruptible(&se401->wq); | ||
361 | se401->scratch_overflow = 0; | ||
362 | se401->scratch_next++; | ||
363 | if (se401->scratch_next >= SE401_NUMSCRATCH) | ||
364 | se401->scratch_next = 0; | ||
365 | break; | ||
366 | } | ||
367 | se401->bayeroffset += length; | ||
368 | if (se401->bayeroffset >= se401->cheight * se401->cwidth) | ||
369 | se401->bayeroffset = 0; | ||
370 | } else { | ||
371 | se401->nullpackets++; | ||
372 | if (se401->nullpackets > SE401_MAX_NULLPACKETS) | ||
373 | if (waitqueue_active(&se401->wq)) | ||
374 | wake_up_interruptible(&se401->wq); | ||
375 | } | ||
376 | |||
377 | /* Resubmit urb for new data */ | ||
378 | urb->status = 0; | ||
379 | urb->dev = se401->dev; | ||
380 | if (usb_submit_urb(urb, GFP_KERNEL)) | ||
381 | dev_info(&urb->dev->dev, "urb burned down\n"); | ||
382 | return; | ||
383 | } | ||
384 | |||
385 | static void se401_send_size(struct usb_se401 *se401, int width, int height) | ||
386 | { | ||
387 | int i = 0; | ||
388 | int mode = 0x03; /* No compression */ | ||
389 | int sendheight = height; | ||
390 | int sendwidth = width; | ||
391 | |||
392 | /* JangGu compression can only be used with the camera supported sizes, | ||
393 | but bayer seems to work with any size that fits on the sensor. | ||
394 | We check if we can use compression with the current size with either | ||
395 | 4 or 16 times subcapturing, if not we use uncompressed bayer data | ||
396 | but this will result in cutouts of the maximum size.... | ||
397 | */ | ||
398 | while (i < se401->sizes && !(se401->width[i] == width && | ||
399 | se401->height[i] == height)) | ||
400 | i++; | ||
401 | while (i < se401->sizes) { | ||
402 | if (se401->width[i] == width * 2 && | ||
403 | se401->height[i] == height * 2) { | ||
404 | sendheight = se401->height[i]; | ||
405 | sendwidth = se401->width[i]; | ||
406 | mode = 0x40; | ||
407 | } | ||
408 | if (se401->width[i] == width * 4 && | ||
409 | se401->height[i] == height * 4) { | ||
410 | sendheight = se401->height[i]; | ||
411 | sendwidth = se401->width[i]; | ||
412 | mode = 0x42; | ||
413 | } | ||
414 | i++; | ||
415 | } | ||
416 | |||
417 | se401_sndctrl(1, se401, SE401_REQ_SET_WIDTH, sendwidth, NULL, 0); | ||
418 | se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0); | ||
419 | se401_set_feature(se401, SE401_OPERATINGMODE, mode); | ||
420 | |||
421 | if (mode == 0x03) | ||
422 | se401->format = FMT_BAYER; | ||
423 | else | ||
424 | se401->format = FMT_JANGGU; | ||
425 | } | ||
426 | |||
427 | /* | ||
428 | In this function se401_send_pict is called several times, | ||
429 | for some reason (depending on the state of the sensor and the phase of | ||
430 | the moon :) doing this only in either place doesn't always work... | ||
431 | */ | ||
432 | static int se401_start_stream(struct usb_se401 *se401) | ||
433 | { | ||
434 | struct urb *urb; | ||
435 | int err = 0, i; | ||
436 | se401->streaming = 1; | ||
437 | |||
438 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); | ||
439 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); | ||
440 | |||
441 | /* Set picture settings */ | ||
442 | /* windowed + pix intg */ | ||
443 | se401_set_feature(se401, HV7131_REG_MODE_B, 0x05); | ||
444 | se401_send_pict(se401); | ||
445 | |||
446 | se401_send_size(se401, se401->cwidth, se401->cheight); | ||
447 | |||
448 | se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, | ||
449 | 0, NULL, 0); | ||
450 | |||
451 | /* Do some memory allocation */ | ||
452 | for (i = 0; i < SE401_NUMFRAMES; i++) { | ||
453 | se401->frame[i].data = se401->fbuf + i * se401->maxframesize; | ||
454 | se401->frame[i].curpix = 0; | ||
455 | } | ||
456 | for (i = 0; i < SE401_NUMSBUF; i++) { | ||
457 | se401->sbuf[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL); | ||
458 | if (!se401->sbuf[i].data) { | ||
459 | for (i = i - 1; i >= 0; i--) { | ||
460 | kfree(se401->sbuf[i].data); | ||
461 | se401->sbuf[i].data = NULL; | ||
462 | } | ||
463 | return -ENOMEM; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | se401->bayeroffset = 0; | ||
468 | se401->scratch_next = 0; | ||
469 | se401->scratch_use = 0; | ||
470 | se401->scratch_overflow = 0; | ||
471 | for (i = 0; i < SE401_NUMSCRATCH; i++) { | ||
472 | se401->scratch[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL); | ||
473 | if (!se401->scratch[i].data) { | ||
474 | for (i = i - 1; i >= 0; i--) { | ||
475 | kfree(se401->scratch[i].data); | ||
476 | se401->scratch[i].data = NULL; | ||
477 | } | ||
478 | goto nomem_sbuf; | ||
479 | } | ||
480 | se401->scratch[i].state = BUFFER_UNUSED; | ||
481 | } | ||
482 | |||
483 | for (i = 0; i < SE401_NUMSBUF; i++) { | ||
484 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
485 | if (!urb) { | ||
486 | for (i = i - 1; i >= 0; i--) { | ||
487 | usb_kill_urb(se401->urb[i]); | ||
488 | usb_free_urb(se401->urb[i]); | ||
489 | se401->urb[i] = NULL; | ||
490 | } | ||
491 | goto nomem_scratch; | ||
492 | } | ||
493 | |||
494 | usb_fill_bulk_urb(urb, se401->dev, | ||
495 | usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT), | ||
496 | se401->sbuf[i].data, SE401_PACKETSIZE, | ||
497 | se401_video_irq, | ||
498 | se401); | ||
499 | |||
500 | se401->urb[i] = urb; | ||
501 | |||
502 | err = usb_submit_urb(se401->urb[i], GFP_KERNEL); | ||
503 | if (err) | ||
504 | err("urb burned down"); | ||
505 | } | ||
506 | |||
507 | se401->framecount = 0; | ||
508 | |||
509 | return 0; | ||
510 | |||
511 | nomem_scratch: | ||
512 | for (i = 0; i < SE401_NUMSCRATCH; i++) { | ||
513 | kfree(se401->scratch[i].data); | ||
514 | se401->scratch[i].data = NULL; | ||
515 | } | ||
516 | nomem_sbuf: | ||
517 | for (i = 0; i < SE401_NUMSBUF; i++) { | ||
518 | kfree(se401->sbuf[i].data); | ||
519 | se401->sbuf[i].data = NULL; | ||
520 | } | ||
521 | return -ENOMEM; | ||
522 | } | ||
523 | |||
524 | static int se401_stop_stream(struct usb_se401 *se401) | ||
525 | { | ||
526 | int i; | ||
527 | |||
528 | if (!se401->streaming || !se401->dev) | ||
529 | return 1; | ||
530 | |||
531 | se401->streaming = 0; | ||
532 | |||
533 | se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0); | ||
534 | |||
535 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0); | ||
536 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0); | ||
537 | |||
538 | for (i = 0; i < SE401_NUMSBUF; i++) | ||
539 | if (se401->urb[i]) { | ||
540 | usb_kill_urb(se401->urb[i]); | ||
541 | usb_free_urb(se401->urb[i]); | ||
542 | se401->urb[i] = NULL; | ||
543 | kfree(se401->sbuf[i].data); | ||
544 | } | ||
545 | for (i = 0; i < SE401_NUMSCRATCH; i++) { | ||
546 | kfree(se401->scratch[i].data); | ||
547 | se401->scratch[i].data = NULL; | ||
548 | } | ||
549 | |||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | static int se401_set_size(struct usb_se401 *se401, int width, int height) | ||
554 | { | ||
555 | int wasstreaming = se401->streaming; | ||
556 | /* Check to see if we need to change */ | ||
557 | if (se401->cwidth == width && se401->cheight == height) | ||
558 | return 0; | ||
559 | |||
560 | /* Check for a valid mode */ | ||
561 | if (!width || !height) | ||
562 | return 1; | ||
563 | if ((width & 1) || (height & 1)) | ||
564 | return 1; | ||
565 | if (width > se401->width[se401->sizes-1]) | ||
566 | return 1; | ||
567 | if (height > se401->height[se401->sizes-1]) | ||
568 | return 1; | ||
569 | |||
570 | /* Stop a current stream and start it again at the new size */ | ||
571 | if (wasstreaming) | ||
572 | se401_stop_stream(se401); | ||
573 | se401->cwidth = width; | ||
574 | se401->cheight = height; | ||
575 | if (wasstreaming) | ||
576 | se401_start_stream(se401); | ||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | |||
581 | /**************************************************************************** | ||
582 | * | ||
583 | * Video Decoding | ||
584 | * | ||
585 | ***************************************************************************/ | ||
586 | |||
587 | /* | ||
588 | This shouldn't really be done in a v4l driver.... | ||
589 | But it does make the image look a lot more usable. | ||
590 | Basically it lifts the dark pixels more than the light pixels. | ||
591 | */ | ||
592 | static inline void enhance_picture(unsigned char *frame, int len) | ||
593 | { | ||
594 | while (len--) { | ||
595 | *frame = (((*frame^255)*(*frame^255))/255)^255; | ||
596 | frame++; | ||
597 | } | ||
598 | } | ||
599 | |||
600 | static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data) | ||
601 | { | ||
602 | struct se401_frame *frame = &se401->frame[se401->curframe]; | ||
603 | int linelength = se401->cwidth * 3; | ||
604 | |||
605 | if (frame->curlinepix >= linelength) { | ||
606 | frame->curlinepix = 0; | ||
607 | frame->curline += linelength; | ||
608 | } | ||
609 | |||
610 | /* First three are absolute, all others relative. | ||
611 | * Format is rgb from right to left (mirrorred image), | ||
612 | * we flip it to get bgr from left to right. */ | ||
613 | if (frame->curlinepix < 3) | ||
614 | *(frame->curline-frame->curlinepix) = 1 + data * 4; | ||
615 | else | ||
616 | *(frame->curline-frame->curlinepix) = | ||
617 | *(frame->curline-frame->curlinepix + 3) + data * 4; | ||
618 | frame->curlinepix++; | ||
619 | } | ||
620 | |||
621 | static inline void decode_JangGu_vlc(struct usb_se401 *se401, | ||
622 | unsigned char *data, int bit_exp, int packetlength) | ||
623 | { | ||
624 | int pos = 0; | ||
625 | int vlc_cod = 0; | ||
626 | int vlc_size = 0; | ||
627 | int vlc_data = 0; | ||
628 | int bit_cur; | ||
629 | int bit; | ||
630 | data += 4; | ||
631 | while (pos < packetlength) { | ||
632 | bit_cur = 8; | ||
633 | while (bit_cur && bit_exp) { | ||
634 | bit = ((*data) >> (bit_cur-1))&1; | ||
635 | if (!vlc_cod) { | ||
636 | if (bit) { | ||
637 | vlc_size++; | ||
638 | } else { | ||
639 | if (!vlc_size) | ||
640 | decode_JangGu_integrate(se401, 0); | ||
641 | else { | ||
642 | vlc_cod = 2; | ||
643 | vlc_data = 0; | ||
644 | } | ||
645 | } | ||
646 | } else { | ||
647 | if (vlc_cod == 2) { | ||
648 | if (!bit) | ||
649 | vlc_data = -(1 << vlc_size) + 1; | ||
650 | vlc_cod--; | ||
651 | } | ||
652 | vlc_size--; | ||
653 | vlc_data += bit << vlc_size; | ||
654 | if (!vlc_size) { | ||
655 | decode_JangGu_integrate(se401, vlc_data); | ||
656 | vlc_cod = 0; | ||
657 | } | ||
658 | } | ||
659 | bit_cur--; | ||
660 | bit_exp--; | ||
661 | } | ||
662 | pos++; | ||
663 | data++; | ||
664 | } | ||
665 | } | ||
666 | |||
667 | static inline void decode_JangGu(struct usb_se401 *se401, | ||
668 | struct se401_scratch *buffer) | ||
669 | { | ||
670 | unsigned char *data = buffer->data; | ||
671 | int len = buffer->length; | ||
672 | int bit_exp = 0, pix_exp = 0, frameinfo = 0, packetlength = 0, size; | ||
673 | int datapos = 0; | ||
674 | |||
675 | /* New image? */ | ||
676 | if (!se401->frame[se401->curframe].curpix) { | ||
677 | se401->frame[se401->curframe].curlinepix = 0; | ||
678 | se401->frame[se401->curframe].curline = | ||
679 | se401->frame[se401->curframe].data+ | ||
680 | se401->cwidth * 3 - 1; | ||
681 | if (se401->frame[se401->curframe].grabstate == FRAME_READY) | ||
682 | se401->frame[se401->curframe].grabstate = FRAME_GRABBING; | ||
683 | se401->vlcdatapos = 0; | ||
684 | } | ||
685 | while (datapos < len) { | ||
686 | size = 1024 - se401->vlcdatapos; | ||
687 | if (size+datapos > len) | ||
688 | size = len-datapos; | ||
689 | memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size); | ||
690 | se401->vlcdatapos += size; | ||
691 | packetlength = 0; | ||
692 | if (se401->vlcdatapos >= 4) { | ||
693 | bit_exp = se401->vlcdata[3] + (se401->vlcdata[2] << 8); | ||
694 | pix_exp = se401->vlcdata[1] + | ||
695 | ((se401->vlcdata[0] & 0x3f) << 8); | ||
696 | frameinfo = se401->vlcdata[0] & 0xc0; | ||
697 | packetlength = ((bit_exp + 47) >> 4) << 1; | ||
698 | if (packetlength > 1024) { | ||
699 | se401->vlcdatapos = 0; | ||
700 | datapos = len; | ||
701 | packetlength = 0; | ||
702 | se401->error++; | ||
703 | se401->frame[se401->curframe].curpix = 0; | ||
704 | } | ||
705 | } | ||
706 | if (packetlength && se401->vlcdatapos >= packetlength) { | ||
707 | decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, | ||
708 | packetlength); | ||
709 | se401->frame[se401->curframe].curpix += pix_exp * 3; | ||
710 | datapos += size-(se401->vlcdatapos-packetlength); | ||
711 | se401->vlcdatapos = 0; | ||
712 | if (se401->frame[se401->curframe].curpix >= se401->cwidth * se401->cheight * 3) { | ||
713 | if (se401->frame[se401->curframe].curpix == se401->cwidth * se401->cheight * 3) { | ||
714 | if (se401->frame[se401->curframe].grabstate == FRAME_GRABBING) { | ||
715 | se401->frame[se401->curframe].grabstate = FRAME_DONE; | ||
716 | se401->framecount++; | ||
717 | se401->readcount++; | ||
718 | } | ||
719 | if (se401->frame[(se401->curframe + 1) & (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) | ||
720 | se401->curframe = (se401->curframe + 1) & (SE401_NUMFRAMES - 1); | ||
721 | } else | ||
722 | se401->error++; | ||
723 | se401->frame[se401->curframe].curpix = 0; | ||
724 | datapos = len; | ||
725 | } | ||
726 | } else | ||
727 | datapos += size; | ||
728 | } | ||
729 | } | ||
730 | |||
731 | static inline void decode_bayer(struct usb_se401 *se401, | ||
732 | struct se401_scratch *buffer) | ||
733 | { | ||
734 | unsigned char *data = buffer->data; | ||
735 | int len = buffer->length; | ||
736 | int offset = buffer->offset; | ||
737 | int datasize = se401->cwidth * se401->cheight; | ||
738 | struct se401_frame *frame = &se401->frame[se401->curframe]; | ||
739 | unsigned char *framedata = frame->data, *curline, *nextline; | ||
740 | int width = se401->cwidth; | ||
741 | int blineoffset = 0, bline; | ||
742 | int linelength = width * 3, i; | ||
743 | |||
744 | |||
745 | if (frame->curpix == 0) { | ||
746 | if (frame->grabstate == FRAME_READY) | ||
747 | frame->grabstate = FRAME_GRABBING; | ||
748 | |||
749 | frame->curline = framedata + linelength; | ||
750 | frame->curlinepix = 0; | ||
751 | } | ||
752 | |||
753 | if (offset != frame->curpix) { | ||
754 | /* Regard frame as lost :( */ | ||
755 | frame->curpix = 0; | ||
756 | se401->error++; | ||
757 | return; | ||
758 | } | ||
759 | |||
760 | /* Check if we have to much data */ | ||
761 | if (frame->curpix + len > datasize) | ||
762 | len = datasize-frame->curpix; | ||
763 | |||
764 | if (se401->cheight % 4) | ||
765 | blineoffset = 1; | ||
766 | bline = frame->curpix / se401->cwidth+blineoffset; | ||
767 | |||
768 | curline = frame->curline; | ||
769 | nextline = curline + linelength; | ||
770 | if (nextline >= framedata+datasize * 3) | ||
771 | nextline = curline; | ||
772 | while (len) { | ||
773 | if (frame->curlinepix >= width) { | ||
774 | frame->curlinepix -= width; | ||
775 | bline = frame->curpix / width + blineoffset; | ||
776 | curline += linelength*2; | ||
777 | nextline += linelength*2; | ||
778 | if (curline >= framedata+datasize * 3) { | ||
779 | frame->curlinepix++; | ||
780 | curline -= 3; | ||
781 | nextline -= 3; | ||
782 | len--; | ||
783 | data++; | ||
784 | frame->curpix++; | ||
785 | } | ||
786 | if (nextline >= framedata+datasize*3) | ||
787 | nextline = curline; | ||
788 | } | ||
789 | if (bline & 1) { | ||
790 | if (frame->curlinepix & 1) { | ||
791 | *(curline + 2) = *data; | ||
792 | *(curline - 1) = *data; | ||
793 | *(nextline + 2) = *data; | ||
794 | *(nextline - 1) = *data; | ||
795 | } else { | ||
796 | *(curline + 1) = | ||
797 | (*(curline + 1) + *data) / 2; | ||
798 | *(curline-2) = | ||
799 | (*(curline - 2) + *data) / 2; | ||
800 | *(nextline + 1) = *data; | ||
801 | *(nextline - 2) = *data; | ||
802 | } | ||
803 | } else { | ||
804 | if (frame->curlinepix & 1) { | ||
805 | *(curline + 1) = | ||
806 | (*(curline + 1) + *data) / 2; | ||
807 | *(curline - 2) = | ||
808 | (*(curline - 2) + *data) / 2; | ||
809 | *(nextline + 1) = *data; | ||
810 | *(nextline - 2) = *data; | ||
811 | } else { | ||
812 | *curline = *data; | ||
813 | *(curline - 3) = *data; | ||
814 | *nextline = *data; | ||
815 | *(nextline - 3) = *data; | ||
816 | } | ||
817 | } | ||
818 | frame->curlinepix++; | ||
819 | curline -= 3; | ||
820 | nextline -= 3; | ||
821 | len--; | ||
822 | data++; | ||
823 | frame->curpix++; | ||
824 | } | ||
825 | frame->curline = curline; | ||
826 | |||
827 | if (frame->curpix >= datasize) { | ||
828 | /* Fix the top line */ | ||
829 | framedata += linelength; | ||
830 | for (i = 0; i < linelength; i++) { | ||
831 | framedata--; | ||
832 | *framedata = *(framedata + linelength); | ||
833 | } | ||
834 | /* Fix the left side (green is already present) */ | ||
835 | for (i = 0; i < se401->cheight; i++) { | ||
836 | *framedata = *(framedata + 3); | ||
837 | *(framedata + 1) = *(framedata + 4); | ||
838 | *(framedata + 2) = *(framedata + 5); | ||
839 | framedata += linelength; | ||
840 | } | ||
841 | frame->curpix = 0; | ||
842 | frame->grabstate = FRAME_DONE; | ||
843 | se401->framecount++; | ||
844 | se401->readcount++; | ||
845 | if (se401->frame[(se401->curframe + 1) & | ||
846 | (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) { | ||
847 | se401->curframe = (se401->curframe+1) & | ||
848 | (SE401_NUMFRAMES-1); | ||
849 | } | ||
850 | } | ||
851 | } | ||
852 | |||
853 | static int se401_newframe(struct usb_se401 *se401, int framenr) | ||
854 | { | ||
855 | DECLARE_WAITQUEUE(wait, current); | ||
856 | int errors = 0; | ||
857 | |||
858 | while (se401->streaming && | ||
859 | (se401->frame[framenr].grabstate == FRAME_READY || | ||
860 | se401->frame[framenr].grabstate == FRAME_GRABBING)) { | ||
861 | if (!se401->frame[framenr].curpix) | ||
862 | errors++; | ||
863 | |||
864 | wait_interruptible( | ||
865 | se401->scratch[se401->scratch_use].state != BUFFER_READY, | ||
866 | &se401->wq, &wait); | ||
867 | if (se401->nullpackets > SE401_MAX_NULLPACKETS) { | ||
868 | se401->nullpackets = 0; | ||
869 | dev_info(&se401->dev->dev, | ||
870 | "too many null length packets, restarting capture\n"); | ||
871 | se401_stop_stream(se401); | ||
872 | se401_start_stream(se401); | ||
873 | } else { | ||
874 | if (se401->scratch[se401->scratch_use].state != | ||
875 | BUFFER_READY) { | ||
876 | se401->frame[framenr].grabstate = FRAME_ERROR; | ||
877 | return -EIO; | ||
878 | } | ||
879 | se401->scratch[se401->scratch_use].state = BUFFER_BUSY; | ||
880 | if (se401->format == FMT_JANGGU) | ||
881 | decode_JangGu(se401, | ||
882 | &se401->scratch[se401->scratch_use]); | ||
883 | else | ||
884 | decode_bayer(se401, | ||
885 | &se401->scratch[se401->scratch_use]); | ||
886 | |||
887 | se401->scratch[se401->scratch_use].state = | ||
888 | BUFFER_UNUSED; | ||
889 | se401->scratch_use++; | ||
890 | if (se401->scratch_use >= SE401_NUMSCRATCH) | ||
891 | se401->scratch_use = 0; | ||
892 | if (errors > SE401_MAX_ERRORS) { | ||
893 | errors = 0; | ||
894 | dev_info(&se401->dev->dev, | ||
895 | "too many errors, restarting capture\n"); | ||
896 | se401_stop_stream(se401); | ||
897 | se401_start_stream(se401); | ||
898 | } | ||
899 | } | ||
900 | } | ||
901 | |||
902 | if (se401->frame[framenr].grabstate == FRAME_DONE) | ||
903 | if (se401->enhance) | ||
904 | enhance_picture(se401->frame[framenr].data, | ||
905 | se401->cheight * se401->cwidth * 3); | ||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | static void usb_se401_remove_disconnected(struct usb_se401 *se401) | ||
910 | { | ||
911 | int i; | ||
912 | |||
913 | se401->dev = NULL; | ||
914 | |||
915 | for (i = 0; i < SE401_NUMSBUF; i++) | ||
916 | if (se401->urb[i]) { | ||
917 | usb_kill_urb(se401->urb[i]); | ||
918 | usb_free_urb(se401->urb[i]); | ||
919 | se401->urb[i] = NULL; | ||
920 | kfree(se401->sbuf[i].data); | ||
921 | } | ||
922 | |||
923 | for (i = 0; i < SE401_NUMSCRATCH; i++) | ||
924 | kfree(se401->scratch[i].data); | ||
925 | |||
926 | if (se401->inturb) { | ||
927 | usb_kill_urb(se401->inturb); | ||
928 | usb_free_urb(se401->inturb); | ||
929 | } | ||
930 | dev_info(&se401->dev->dev, "%s disconnected", se401->camera_name); | ||
931 | |||
932 | /* Free the memory */ | ||
933 | kfree(se401->width); | ||
934 | kfree(se401->height); | ||
935 | kfree(se401); | ||
936 | } | ||
937 | |||
938 | |||
939 | |||
940 | /**************************************************************************** | ||
941 | * | ||
942 | * Video4Linux | ||
943 | * | ||
944 | ***************************************************************************/ | ||
945 | |||
946 | |||
947 | static int se401_open(struct file *file) | ||
948 | { | ||
949 | struct video_device *dev = video_devdata(file); | ||
950 | struct usb_se401 *se401 = (struct usb_se401 *)dev; | ||
951 | int err = 0; | ||
952 | |||
953 | mutex_lock(&se401->lock); | ||
954 | if (se401->user) { | ||
955 | mutex_unlock(&se401->lock); | ||
956 | return -EBUSY; | ||
957 | } | ||
958 | se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES); | ||
959 | if (se401->fbuf) | ||
960 | file->private_data = dev; | ||
961 | else | ||
962 | err = -ENOMEM; | ||
963 | se401->user = !err; | ||
964 | mutex_unlock(&se401->lock); | ||
965 | |||
966 | return err; | ||
967 | } | ||
968 | |||
969 | static int se401_close(struct file *file) | ||
970 | { | ||
971 | struct video_device *dev = file->private_data; | ||
972 | struct usb_se401 *se401 = (struct usb_se401 *)dev; | ||
973 | int i; | ||
974 | |||
975 | rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES); | ||
976 | if (se401->removed) { | ||
977 | dev_info(&se401->dev->dev, "device unregistered\n"); | ||
978 | usb_se401_remove_disconnected(se401); | ||
979 | } else { | ||
980 | for (i = 0; i < SE401_NUMFRAMES; i++) | ||
981 | se401->frame[i].grabstate = FRAME_UNUSED; | ||
982 | if (se401->streaming) | ||
983 | se401_stop_stream(se401); | ||
984 | se401->user = 0; | ||
985 | } | ||
986 | file->private_data = NULL; | ||
987 | return 0; | ||
988 | } | ||
989 | |||
990 | static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) | ||
991 | { | ||
992 | struct video_device *vdev = file->private_data; | ||
993 | struct usb_se401 *se401 = (struct usb_se401 *)vdev; | ||
994 | |||
995 | if (!se401->dev) | ||
996 | return -EIO; | ||
997 | |||
998 | switch (cmd) { | ||
999 | case VIDIOCGCAP: | ||
1000 | { | ||
1001 | struct video_capability *b = arg; | ||
1002 | strcpy(b->name, se401->camera_name); | ||
1003 | b->type = VID_TYPE_CAPTURE; | ||
1004 | b->channels = 1; | ||
1005 | b->audios = 0; | ||
1006 | b->maxwidth = se401->width[se401->sizes-1]; | ||
1007 | b->maxheight = se401->height[se401->sizes-1]; | ||
1008 | b->minwidth = se401->width[0]; | ||
1009 | b->minheight = se401->height[0]; | ||
1010 | return 0; | ||
1011 | } | ||
1012 | case VIDIOCGCHAN: | ||
1013 | { | ||
1014 | struct video_channel *v = arg; | ||
1015 | |||
1016 | if (v->channel != 0) | ||
1017 | return -EINVAL; | ||
1018 | v->flags = 0; | ||
1019 | v->tuners = 0; | ||
1020 | v->type = VIDEO_TYPE_CAMERA; | ||
1021 | strcpy(v->name, "Camera"); | ||
1022 | return 0; | ||
1023 | } | ||
1024 | case VIDIOCSCHAN: | ||
1025 | { | ||
1026 | struct video_channel *v = arg; | ||
1027 | |||
1028 | if (v->channel != 0) | ||
1029 | return -EINVAL; | ||
1030 | return 0; | ||
1031 | } | ||
1032 | case VIDIOCGPICT: | ||
1033 | { | ||
1034 | struct video_picture *p = arg; | ||
1035 | |||
1036 | se401_get_pict(se401, p); | ||
1037 | return 0; | ||
1038 | } | ||
1039 | case VIDIOCSPICT: | ||
1040 | { | ||
1041 | struct video_picture *p = arg; | ||
1042 | |||
1043 | if (se401_set_pict(se401, p)) | ||
1044 | return -EINVAL; | ||
1045 | return 0; | ||
1046 | } | ||
1047 | case VIDIOCSWIN: | ||
1048 | { | ||
1049 | struct video_window *vw = arg; | ||
1050 | |||
1051 | if (vw->flags) | ||
1052 | return -EINVAL; | ||
1053 | if (vw->clipcount) | ||
1054 | return -EINVAL; | ||
1055 | if (se401_set_size(se401, vw->width, vw->height)) | ||
1056 | return -EINVAL; | ||
1057 | return 0; | ||
1058 | } | ||
1059 | case VIDIOCGWIN: | ||
1060 | { | ||
1061 | struct video_window *vw = arg; | ||
1062 | |||
1063 | vw->x = 0; /* FIXME */ | ||
1064 | vw->y = 0; | ||
1065 | vw->chromakey = 0; | ||
1066 | vw->flags = 0; | ||
1067 | vw->clipcount = 0; | ||
1068 | vw->width = se401->cwidth; | ||
1069 | vw->height = se401->cheight; | ||
1070 | return 0; | ||
1071 | } | ||
1072 | case VIDIOCGMBUF: | ||
1073 | { | ||
1074 | struct video_mbuf *vm = arg; | ||
1075 | int i; | ||
1076 | |||
1077 | memset(vm, 0, sizeof(*vm)); | ||
1078 | vm->size = SE401_NUMFRAMES * se401->maxframesize; | ||
1079 | vm->frames = SE401_NUMFRAMES; | ||
1080 | for (i = 0; i < SE401_NUMFRAMES; i++) | ||
1081 | vm->offsets[i] = se401->maxframesize * i; | ||
1082 | return 0; | ||
1083 | } | ||
1084 | case VIDIOCMCAPTURE: | ||
1085 | { | ||
1086 | struct video_mmap *vm = arg; | ||
1087 | |||
1088 | if (vm->format != VIDEO_PALETTE_RGB24) | ||
1089 | return -EINVAL; | ||
1090 | if (vm->frame >= SE401_NUMFRAMES) | ||
1091 | return -EINVAL; | ||
1092 | if (se401->frame[vm->frame].grabstate != FRAME_UNUSED) | ||
1093 | return -EBUSY; | ||
1094 | |||
1095 | /* Is this according to the v4l spec??? */ | ||
1096 | if (se401_set_size(se401, vm->width, vm->height)) | ||
1097 | return -EINVAL; | ||
1098 | se401->frame[vm->frame].grabstate = FRAME_READY; | ||
1099 | |||
1100 | if (!se401->streaming) | ||
1101 | se401_start_stream(se401); | ||
1102 | |||
1103 | /* Set the picture properties */ | ||
1104 | if (se401->framecount == 0) | ||
1105 | se401_send_pict(se401); | ||
1106 | /* Calibrate the reset level after a few frames. */ | ||
1107 | if (se401->framecount % 20 == 1) | ||
1108 | se401_auto_resetlevel(se401); | ||
1109 | |||
1110 | return 0; | ||
1111 | } | ||
1112 | case VIDIOCSYNC: | ||
1113 | { | ||
1114 | int *frame = arg; | ||
1115 | int ret = 0; | ||
1116 | |||
1117 | if (*frame < 0 || *frame >= SE401_NUMFRAMES) | ||
1118 | return -EINVAL; | ||
1119 | |||
1120 | ret = se401_newframe(se401, *frame); | ||
1121 | se401->frame[*frame].grabstate = FRAME_UNUSED; | ||
1122 | return ret; | ||
1123 | } | ||
1124 | case VIDIOCGFBUF: | ||
1125 | { | ||
1126 | struct video_buffer *vb = arg; | ||
1127 | |||
1128 | memset(vb, 0, sizeof(*vb)); | ||
1129 | return 0; | ||
1130 | } | ||
1131 | case VIDIOCKEY: | ||
1132 | return 0; | ||
1133 | case VIDIOCCAPTURE: | ||
1134 | return -EINVAL; | ||
1135 | case VIDIOCSFBUF: | ||
1136 | return -EINVAL; | ||
1137 | case VIDIOCGTUNER: | ||
1138 | case VIDIOCSTUNER: | ||
1139 | return -EINVAL; | ||
1140 | case VIDIOCGFREQ: | ||
1141 | case VIDIOCSFREQ: | ||
1142 | return -EINVAL; | ||
1143 | case VIDIOCGAUDIO: | ||
1144 | case VIDIOCSAUDIO: | ||
1145 | return -EINVAL; | ||
1146 | default: | ||
1147 | return -ENOIOCTLCMD; | ||
1148 | } /* end switch */ | ||
1149 | |||
1150 | return 0; | ||
1151 | } | ||
1152 | |||
1153 | static long se401_ioctl(struct file *file, | ||
1154 | unsigned int cmd, unsigned long arg) | ||
1155 | { | ||
1156 | return video_usercopy(file, cmd, arg, se401_do_ioctl); | ||
1157 | } | ||
1158 | |||
1159 | static ssize_t se401_read(struct file *file, char __user *buf, | ||
1160 | size_t count, loff_t *ppos) | ||
1161 | { | ||
1162 | int realcount = count, ret = 0; | ||
1163 | struct video_device *dev = file->private_data; | ||
1164 | struct usb_se401 *se401 = (struct usb_se401 *)dev; | ||
1165 | |||
1166 | |||
1167 | if (se401->dev == NULL) | ||
1168 | return -EIO; | ||
1169 | if (realcount > se401->cwidth*se401->cheight*3) | ||
1170 | realcount = se401->cwidth*se401->cheight*3; | ||
1171 | |||
1172 | /* Shouldn't happen: */ | ||
1173 | if (se401->frame[0].grabstate == FRAME_GRABBING) | ||
1174 | return -EBUSY; | ||
1175 | se401->frame[0].grabstate = FRAME_READY; | ||
1176 | se401->frame[1].grabstate = FRAME_UNUSED; | ||
1177 | se401->curframe = 0; | ||
1178 | |||
1179 | if (!se401->streaming) | ||
1180 | se401_start_stream(se401); | ||
1181 | |||
1182 | /* Set the picture properties */ | ||
1183 | if (se401->framecount == 0) | ||
1184 | se401_send_pict(se401); | ||
1185 | /* Calibrate the reset level after a few frames. */ | ||
1186 | if (se401->framecount%20 == 1) | ||
1187 | se401_auto_resetlevel(se401); | ||
1188 | |||
1189 | ret = se401_newframe(se401, 0); | ||
1190 | |||
1191 | se401->frame[0].grabstate = FRAME_UNUSED; | ||
1192 | if (ret) | ||
1193 | return ret; | ||
1194 | if (copy_to_user(buf, se401->frame[0].data, realcount)) | ||
1195 | return -EFAULT; | ||
1196 | |||
1197 | return realcount; | ||
1198 | } | ||
1199 | |||
1200 | static int se401_mmap(struct file *file, struct vm_area_struct *vma) | ||
1201 | { | ||
1202 | struct video_device *dev = file->private_data; | ||
1203 | struct usb_se401 *se401 = (struct usb_se401 *)dev; | ||
1204 | unsigned long start = vma->vm_start; | ||
1205 | unsigned long size = vma->vm_end-vma->vm_start; | ||
1206 | unsigned long page, pos; | ||
1207 | |||
1208 | mutex_lock(&se401->lock); | ||
1209 | |||
1210 | if (se401->dev == NULL) { | ||
1211 | mutex_unlock(&se401->lock); | ||
1212 | return -EIO; | ||
1213 | } | ||
1214 | if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) | ||
1215 | & ~(PAGE_SIZE - 1))) { | ||
1216 | mutex_unlock(&se401->lock); | ||
1217 | return -EINVAL; | ||
1218 | } | ||
1219 | pos = (unsigned long)se401->fbuf; | ||
1220 | while (size > 0) { | ||
1221 | page = vmalloc_to_pfn((void *)pos); | ||
1222 | if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { | ||
1223 | mutex_unlock(&se401->lock); | ||
1224 | return -EAGAIN; | ||
1225 | } | ||
1226 | start += PAGE_SIZE; | ||
1227 | pos += PAGE_SIZE; | ||
1228 | if (size > PAGE_SIZE) | ||
1229 | size -= PAGE_SIZE; | ||
1230 | else | ||
1231 | size = 0; | ||
1232 | } | ||
1233 | mutex_unlock(&se401->lock); | ||
1234 | |||
1235 | return 0; | ||
1236 | } | ||
1237 | |||
1238 | static const struct v4l2_file_operations se401_fops = { | ||
1239 | .owner = THIS_MODULE, | ||
1240 | .open = se401_open, | ||
1241 | .release = se401_close, | ||
1242 | .read = se401_read, | ||
1243 | .mmap = se401_mmap, | ||
1244 | .ioctl = se401_ioctl, | ||
1245 | }; | ||
1246 | static struct video_device se401_template = { | ||
1247 | .name = "se401 USB camera", | ||
1248 | .fops = &se401_fops, | ||
1249 | .release = video_device_release_empty, | ||
1250 | }; | ||
1251 | |||
1252 | |||
1253 | |||
1254 | /***************************/ | ||
1255 | static int se401_init(struct usb_se401 *se401, int button) | ||
1256 | { | ||
1257 | int i = 0, rc; | ||
1258 | unsigned char cp[0x40]; | ||
1259 | char temp[200]; | ||
1260 | int slen; | ||
1261 | |||
1262 | /* led on */ | ||
1263 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); | ||
1264 | |||
1265 | /* get camera descriptor */ | ||
1266 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, | ||
1267 | cp, sizeof(cp)); | ||
1268 | if (cp[1] != 0x41) { | ||
1269 | err("Wrong descriptor type"); | ||
1270 | return 1; | ||
1271 | } | ||
1272 | slen = snprintf(temp, 200, "ExtraFeatures: %d", cp[3]); | ||
1273 | |||
1274 | se401->sizes = cp[4] + cp[5] * 256; | ||
1275 | se401->width = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); | ||
1276 | if (!se401->width) | ||
1277 | return 1; | ||
1278 | se401->height = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); | ||
1279 | if (!se401->height) { | ||
1280 | kfree(se401->width); | ||
1281 | return 1; | ||
1282 | } | ||
1283 | for (i = 0; i < se401->sizes; i++) { | ||
1284 | se401->width[i] = cp[6 + i * 4 + 0] + cp[6 + i*4 + 1] * 256; | ||
1285 | se401->height[i] = cp[6 + i * 4 + 2] + cp[6 + i * 4 + 3] * 256; | ||
1286 | } | ||
1287 | slen += snprintf(temp + slen, 200 - slen, " Sizes:"); | ||
1288 | for (i = 0; i < se401->sizes; i++) { | ||
1289 | slen += snprintf(temp + slen, 200 - slen, | ||
1290 | " %dx%d", se401->width[i], se401->height[i]); | ||
1291 | } | ||
1292 | dev_info(&se401->dev->dev, "%s\n", temp); | ||
1293 | se401->maxframesize = se401->width[se401->sizes-1] * | ||
1294 | se401->height[se401->sizes - 1] * 3; | ||
1295 | |||
1296 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp)); | ||
1297 | se401->cwidth = cp[0]+cp[1]*256; | ||
1298 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp)); | ||
1299 | se401->cheight = cp[0]+cp[1]*256; | ||
1300 | |||
1301 | if (!(cp[2] & SE401_FORMAT_BAYER)) { | ||
1302 | err("Bayer format not supported!"); | ||
1303 | return 1; | ||
1304 | } | ||
1305 | /* set output mode (BAYER) */ | ||
1306 | se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, | ||
1307 | SE401_FORMAT_BAYER, NULL, 0); | ||
1308 | |||
1309 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp)); | ||
1310 | se401->brightness = cp[0]+cp[1]*256; | ||
1311 | /* some default values */ | ||
1312 | se401->resetlevel = 0x2d; | ||
1313 | se401->rgain = 0x20; | ||
1314 | se401->ggain = 0x20; | ||
1315 | se401->bgain = 0x20; | ||
1316 | se401_set_exposure(se401, 20000); | ||
1317 | se401->palette = VIDEO_PALETTE_RGB24; | ||
1318 | se401->enhance = 1; | ||
1319 | se401->dropped = 0; | ||
1320 | se401->error = 0; | ||
1321 | se401->framecount = 0; | ||
1322 | se401->readcount = 0; | ||
1323 | |||
1324 | /* Start interrupt transfers for snapshot button */ | ||
1325 | if (button) { | ||
1326 | se401->inturb = usb_alloc_urb(0, GFP_KERNEL); | ||
1327 | if (!se401->inturb) { | ||
1328 | dev_info(&se401->dev->dev, | ||
1329 | "Allocation of inturb failed\n"); | ||
1330 | return 1; | ||
1331 | } | ||
1332 | usb_fill_int_urb(se401->inturb, se401->dev, | ||
1333 | usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT), | ||
1334 | &se401->button, sizeof(se401->button), | ||
1335 | se401_button_irq, | ||
1336 | se401, | ||
1337 | 8 | ||
1338 | ); | ||
1339 | if (usb_submit_urb(se401->inturb, GFP_KERNEL)) { | ||
1340 | dev_info(&se401->dev->dev, "int urb burned down\n"); | ||
1341 | return 1; | ||
1342 | } | ||
1343 | } else | ||
1344 | se401->inturb = NULL; | ||
1345 | |||
1346 | /* Flash the led */ | ||
1347 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); | ||
1348 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); | ||
1349 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0); | ||
1350 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0); | ||
1351 | |||
1352 | return 0; | ||
1353 | } | ||
1354 | |||
1355 | static int se401_probe(struct usb_interface *intf, | ||
1356 | const struct usb_device_id *id) | ||
1357 | { | ||
1358 | struct usb_device *dev = interface_to_usbdev(intf); | ||
1359 | struct usb_interface_descriptor *interface; | ||
1360 | struct usb_se401 *se401; | ||
1361 | char *camera_name = NULL; | ||
1362 | int button = 1; | ||
1363 | |||
1364 | /* We don't handle multi-config cameras */ | ||
1365 | if (dev->descriptor.bNumConfigurations != 1) | ||
1366 | return -ENODEV; | ||
1367 | |||
1368 | interface = &intf->cur_altsetting->desc; | ||
1369 | |||
1370 | /* Is it an se401? */ | ||
1371 | if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 && | ||
1372 | le16_to_cpu(dev->descriptor.idProduct) == 0x0004) { | ||
1373 | camera_name = "Endpoints/Aox SE401"; | ||
1374 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 && | ||
1375 | le16_to_cpu(dev->descriptor.idProduct) == 0x030b) { | ||
1376 | camera_name = "Philips PCVC665K"; | ||
1377 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && | ||
1378 | le16_to_cpu(dev->descriptor.idProduct) == 0x5001) { | ||
1379 | camera_name = "Kensington VideoCAM 67014"; | ||
1380 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && | ||
1381 | le16_to_cpu(dev->descriptor.idProduct) == 0x5002) { | ||
1382 | camera_name = "Kensington VideoCAM 6701(5/7)"; | ||
1383 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && | ||
1384 | le16_to_cpu(dev->descriptor.idProduct) == 0x5003) { | ||
1385 | camera_name = "Kensington VideoCAM 67016"; | ||
1386 | button = 0; | ||
1387 | } else | ||
1388 | return -ENODEV; | ||
1389 | |||
1390 | /* Checking vendor/product should be enough, but what the hell */ | ||
1391 | if (interface->bInterfaceClass != 0x00) | ||
1392 | return -ENODEV; | ||
1393 | if (interface->bInterfaceSubClass != 0x00) | ||
1394 | return -ENODEV; | ||
1395 | |||
1396 | /* We found one */ | ||
1397 | dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name); | ||
1398 | |||
1399 | se401 = kzalloc(sizeof(*se401), GFP_KERNEL); | ||
1400 | if (se401 == NULL) { | ||
1401 | err("couldn't kmalloc se401 struct"); | ||
1402 | return -ENOMEM; | ||
1403 | } | ||
1404 | |||
1405 | se401->dev = dev; | ||
1406 | se401->iface = interface->bInterfaceNumber; | ||
1407 | se401->camera_name = camera_name; | ||
1408 | |||
1409 | dev_info(&intf->dev, "firmware version: %02x\n", | ||
1410 | le16_to_cpu(dev->descriptor.bcdDevice) & 255); | ||
1411 | |||
1412 | if (se401_init(se401, button)) { | ||
1413 | kfree(se401); | ||
1414 | return -EIO; | ||
1415 | } | ||
1416 | |||
1417 | memcpy(&se401->vdev, &se401_template, sizeof(se401_template)); | ||
1418 | memcpy(se401->vdev.name, se401->camera_name, | ||
1419 | strlen(se401->camera_name)); | ||
1420 | init_waitqueue_head(&se401->wq); | ||
1421 | mutex_init(&se401->lock); | ||
1422 | wmb(); | ||
1423 | |||
1424 | if (video_register_device(&se401->vdev, | ||
1425 | VFL_TYPE_GRABBER, video_nr) < 0) { | ||
1426 | kfree(se401); | ||
1427 | err("video_register_device failed"); | ||
1428 | return -EIO; | ||
1429 | } | ||
1430 | dev_info(&intf->dev, "registered new video device: %s\n", | ||
1431 | video_device_node_name(&se401->vdev)); | ||
1432 | |||
1433 | usb_set_intfdata(intf, se401); | ||
1434 | return 0; | ||
1435 | } | ||
1436 | |||
1437 | static void se401_disconnect(struct usb_interface *intf) | ||
1438 | { | ||
1439 | struct usb_se401 *se401 = usb_get_intfdata(intf); | ||
1440 | |||
1441 | usb_set_intfdata(intf, NULL); | ||
1442 | if (se401) { | ||
1443 | video_unregister_device(&se401->vdev); | ||
1444 | if (!se401->user) | ||
1445 | usb_se401_remove_disconnected(se401); | ||
1446 | else { | ||
1447 | se401->frame[0].grabstate = FRAME_ERROR; | ||
1448 | se401->frame[0].grabstate = FRAME_ERROR; | ||
1449 | |||
1450 | se401->streaming = 0; | ||
1451 | |||
1452 | wake_up_interruptible(&se401->wq); | ||
1453 | se401->removed = 1; | ||
1454 | } | ||
1455 | } | ||
1456 | } | ||
1457 | |||
1458 | static struct usb_driver se401_driver = { | ||
1459 | .name = "se401", | ||
1460 | .id_table = device_table, | ||
1461 | .probe = se401_probe, | ||
1462 | .disconnect = se401_disconnect, | ||
1463 | }; | ||
1464 | |||
1465 | |||
1466 | |||
1467 | /**************************************************************************** | ||
1468 | * | ||
1469 | * Module routines | ||
1470 | * | ||
1471 | ***************************************************************************/ | ||
1472 | |||
1473 | static int __init usb_se401_init(void) | ||
1474 | { | ||
1475 | printk(KERN_INFO "SE401 usb camera driver version %s registering\n", | ||
1476 | version); | ||
1477 | if (flickerless) | ||
1478 | if (flickerless != 50 && flickerless != 60) { | ||
1479 | printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n"); | ||
1480 | return -1; | ||
1481 | } | ||
1482 | return usb_register(&se401_driver); | ||
1483 | } | ||
1484 | |||
1485 | static void __exit usb_se401_exit(void) | ||
1486 | { | ||
1487 | usb_deregister(&se401_driver); | ||
1488 | printk(KERN_INFO "SE401 driver deregistered\frame"); | ||
1489 | } | ||
1490 | |||
1491 | module_init(usb_se401_init); | ||
1492 | module_exit(usb_se401_exit); | ||
diff --git a/drivers/staging/se401/se401.h b/drivers/staging/se401/se401.h deleted file mode 100644 index 2758f4716c3d..000000000000 --- a/drivers/staging/se401/se401.h +++ /dev/null | |||
@@ -1,236 +0,0 @@ | |||
1 | |||
2 | #ifndef __LINUX_se401_H | ||
3 | #define __LINUX_se401_H | ||
4 | |||
5 | #include <linux/uaccess.h> | ||
6 | #include "videodev.h" | ||
7 | #include <media/v4l2-common.h> | ||
8 | #include <media/v4l2-ioctl.h> | ||
9 | #include <linux/mutex.h> | ||
10 | |||
11 | #define se401_DEBUG /* Turn on debug messages */ | ||
12 | |||
13 | #ifdef se401_DEBUG | ||
14 | # define PDEBUG(level, fmt, args...) \ | ||
15 | if (debug >= level) \ | ||
16 | info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args) | ||
17 | #else | ||
18 | # define PDEBUG(level, fmt, args...) do {} while (0) | ||
19 | #endif | ||
20 | |||
21 | /* An almost drop-in replacement for sleep_on_interruptible */ | ||
22 | #define wait_interruptible(test, queue, wait) \ | ||
23 | { \ | ||
24 | add_wait_queue(queue, wait); \ | ||
25 | set_current_state(TASK_INTERRUPTIBLE); \ | ||
26 | if (test) \ | ||
27 | schedule(); \ | ||
28 | remove_wait_queue(queue, wait); \ | ||
29 | set_current_state(TASK_RUNNING); \ | ||
30 | if (signal_pending(current)) \ | ||
31 | break; \ | ||
32 | } | ||
33 | |||
34 | #define SE401_REQ_GET_CAMERA_DESCRIPTOR 0x06 | ||
35 | #define SE401_REQ_START_CONTINUOUS_CAPTURE 0x41 | ||
36 | #define SE401_REQ_STOP_CONTINUOUS_CAPTURE 0x42 | ||
37 | #define SE401_REQ_CAPTURE_FRAME 0x43 | ||
38 | #define SE401_REQ_GET_BRT 0x44 | ||
39 | #define SE401_REQ_SET_BRT 0x45 | ||
40 | #define SE401_REQ_GET_WIDTH 0x4c | ||
41 | #define SE401_REQ_SET_WIDTH 0x4d | ||
42 | #define SE401_REQ_GET_HEIGHT 0x4e | ||
43 | #define SE401_REQ_SET_HEIGHT 0x4f | ||
44 | #define SE401_REQ_GET_OUTPUT_MODE 0x50 | ||
45 | #define SE401_REQ_SET_OUTPUT_MODE 0x51 | ||
46 | #define SE401_REQ_GET_EXT_FEATURE 0x52 | ||
47 | #define SE401_REQ_SET_EXT_FEATURE 0x53 | ||
48 | #define SE401_REQ_CAMERA_POWER 0x56 | ||
49 | #define SE401_REQ_LED_CONTROL 0x57 | ||
50 | #define SE401_REQ_BIOS 0xff | ||
51 | |||
52 | #define SE401_BIOS_READ 0x07 | ||
53 | |||
54 | #define SE401_FORMAT_BAYER 0x40 | ||
55 | |||
56 | /* Hyundai hv7131b registers | ||
57 | 7121 and 7141 should be the same (haven't really checked...) */ | ||
58 | /* Mode registers: */ | ||
59 | #define HV7131_REG_MODE_A 0x00 | ||
60 | #define HV7131_REG_MODE_B 0x01 | ||
61 | #define HV7131_REG_MODE_C 0x02 | ||
62 | /* Frame registers: */ | ||
63 | #define HV7131_REG_FRSU 0x10 | ||
64 | #define HV7131_REG_FRSL 0x11 | ||
65 | #define HV7131_REG_FCSU 0x12 | ||
66 | #define HV7131_REG_FCSL 0x13 | ||
67 | #define HV7131_REG_FWHU 0x14 | ||
68 | #define HV7131_REG_FWHL 0x15 | ||
69 | #define HV7131_REG_FWWU 0x16 | ||
70 | #define HV7131_REG_FWWL 0x17 | ||
71 | /* Timing registers: */ | ||
72 | #define HV7131_REG_THBU 0x20 | ||
73 | #define HV7131_REG_THBL 0x21 | ||
74 | #define HV7131_REG_TVBU 0x22 | ||
75 | #define HV7131_REG_TVBL 0x23 | ||
76 | #define HV7131_REG_TITU 0x25 | ||
77 | #define HV7131_REG_TITM 0x26 | ||
78 | #define HV7131_REG_TITL 0x27 | ||
79 | #define HV7131_REG_TMCD 0x28 | ||
80 | /* Adjust Registers: */ | ||
81 | #define HV7131_REG_ARLV 0x30 | ||
82 | #define HV7131_REG_ARCG 0x31 | ||
83 | #define HV7131_REG_AGCG 0x32 | ||
84 | #define HV7131_REG_ABCG 0x33 | ||
85 | #define HV7131_REG_APBV 0x34 | ||
86 | #define HV7131_REG_ASLP 0x54 | ||
87 | /* Offset Registers: */ | ||
88 | #define HV7131_REG_OFSR 0x50 | ||
89 | #define HV7131_REG_OFSG 0x51 | ||
90 | #define HV7131_REG_OFSB 0x52 | ||
91 | /* REset level statistics registers: */ | ||
92 | #define HV7131_REG_LOREFNOH 0x57 | ||
93 | #define HV7131_REG_LOREFNOL 0x58 | ||
94 | #define HV7131_REG_HIREFNOH 0x59 | ||
95 | #define HV7131_REG_HIREFNOL 0x5a | ||
96 | |||
97 | /* se401 registers */ | ||
98 | #define SE401_OPERATINGMODE 0x2000 | ||
99 | |||
100 | |||
101 | /* size of usb transfers */ | ||
102 | #define SE401_PACKETSIZE 4096 | ||
103 | /* number of queued bulk transfers to use, should be about 8 */ | ||
104 | #define SE401_NUMSBUF 1 | ||
105 | /* read the usb specs for this one :) */ | ||
106 | #define SE401_VIDEO_ENDPOINT 1 | ||
107 | #define SE401_BUTTON_ENDPOINT 2 | ||
108 | /* number of frames supported by the v4l part */ | ||
109 | #define SE401_NUMFRAMES 2 | ||
110 | /* scratch buffers for passing data to the decoders */ | ||
111 | #define SE401_NUMSCRATCH 32 | ||
112 | /* maximum amount of data in a JangGu packet */ | ||
113 | #define SE401_VLCDATALEN 1024 | ||
114 | /* number of nul sized packets to receive before kicking the camera */ | ||
115 | #define SE401_MAX_NULLPACKETS 4000 | ||
116 | /* number of decoding errors before kicking the camera */ | ||
117 | #define SE401_MAX_ERRORS 200 | ||
118 | |||
119 | struct usb_device; | ||
120 | |||
121 | struct se401_sbuf { | ||
122 | unsigned char *data; | ||
123 | }; | ||
124 | |||
125 | enum { | ||
126 | FRAME_UNUSED, /* Unused (no MCAPTURE) */ | ||
127 | FRAME_READY, /* Ready to start grabbing */ | ||
128 | FRAME_GRABBING, /* In the process of being grabbed into */ | ||
129 | FRAME_DONE, /* Finished grabbing, but not been synced yet */ | ||
130 | FRAME_ERROR, /* Something bad happened while processing */ | ||
131 | }; | ||
132 | |||
133 | enum { | ||
134 | FMT_BAYER, | ||
135 | FMT_JANGGU, | ||
136 | }; | ||
137 | |||
138 | enum { | ||
139 | BUFFER_UNUSED, | ||
140 | BUFFER_READY, | ||
141 | BUFFER_BUSY, | ||
142 | BUFFER_DONE, | ||
143 | }; | ||
144 | |||
145 | struct se401_scratch { | ||
146 | unsigned char *data; | ||
147 | volatile int state; | ||
148 | int offset; | ||
149 | int length; | ||
150 | }; | ||
151 | |||
152 | struct se401_frame { | ||
153 | unsigned char *data; /* Frame buffer */ | ||
154 | |||
155 | volatile int grabstate; /* State of grabbing */ | ||
156 | |||
157 | unsigned char *curline; | ||
158 | int curlinepix; | ||
159 | int curpix; | ||
160 | }; | ||
161 | |||
162 | struct usb_se401 { | ||
163 | struct video_device vdev; | ||
164 | |||
165 | /* Device structure */ | ||
166 | struct usb_device *dev; | ||
167 | |||
168 | unsigned char iface; | ||
169 | |||
170 | char *camera_name; | ||
171 | |||
172 | int change; | ||
173 | int brightness; | ||
174 | int hue; | ||
175 | int rgain; | ||
176 | int ggain; | ||
177 | int bgain; | ||
178 | int expose_h; | ||
179 | int expose_m; | ||
180 | int expose_l; | ||
181 | int resetlevel; | ||
182 | |||
183 | int enhance; | ||
184 | |||
185 | int format; | ||
186 | int sizes; | ||
187 | int *width; | ||
188 | int *height; | ||
189 | int cwidth; /* current width */ | ||
190 | int cheight; /* current height */ | ||
191 | int palette; | ||
192 | int maxframesize; | ||
193 | int cframesize; /* current framesize */ | ||
194 | |||
195 | struct mutex lock; | ||
196 | int user; /* user count for exclusive use */ | ||
197 | int removed; /* device disconnected */ | ||
198 | |||
199 | int streaming; /* Are we streaming video? */ | ||
200 | |||
201 | char *fbuf; /* Videodev buffer area */ | ||
202 | |||
203 | struct urb *urb[SE401_NUMSBUF]; | ||
204 | struct urb *inturb; | ||
205 | |||
206 | int button; | ||
207 | int buttonpressed; | ||
208 | |||
209 | int curframe; /* Current receiving frame */ | ||
210 | struct se401_frame frame[SE401_NUMFRAMES]; | ||
211 | int readcount; | ||
212 | int framecount; | ||
213 | int error; | ||
214 | int dropped; | ||
215 | |||
216 | int scratch_next; | ||
217 | int scratch_use; | ||
218 | int scratch_overflow; | ||
219 | struct se401_scratch scratch[SE401_NUMSCRATCH]; | ||
220 | |||
221 | /* Decoder specific data: */ | ||
222 | unsigned char vlcdata[SE401_VLCDATALEN]; | ||
223 | int vlcdatapos; | ||
224 | int bayeroffset; | ||
225 | |||
226 | struct se401_sbuf sbuf[SE401_NUMSBUF]; | ||
227 | |||
228 | wait_queue_head_t wq; /* Processes waiting */ | ||
229 | |||
230 | int nullpackets; | ||
231 | }; | ||
232 | |||
233 | |||
234 | |||
235 | #endif | ||
236 | |||
diff --git a/drivers/staging/se401/videodev.h b/drivers/staging/se401/videodev.h deleted file mode 100644 index f11efbef1c05..000000000000 --- a/drivers/staging/se401/videodev.h +++ /dev/null | |||
@@ -1,318 +0,0 @@ | |||
1 | /* | ||
2 | * Video for Linux version 1 - OBSOLETE | ||
3 | * | ||
4 | * Header file for v4l1 drivers and applications, for | ||
5 | * Linux kernels 2.2.x or 2.4.x. | ||
6 | * | ||
7 | * Provides header for legacy drivers and applications | ||
8 | * | ||
9 | * See http://linuxtv.org for more info | ||
10 | * | ||
11 | */ | ||
12 | #ifndef __LINUX_VIDEODEV_H | ||
13 | #define __LINUX_VIDEODEV_H | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | #include <linux/ioctl.h> | ||
17 | #include <linux/videodev2.h> | ||
18 | |||
19 | #define VID_TYPE_CAPTURE 1 /* Can capture */ | ||
20 | #define VID_TYPE_TUNER 2 /* Can tune */ | ||
21 | #define VID_TYPE_TELETEXT 4 /* Does teletext */ | ||
22 | #define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ | ||
23 | #define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ | ||
24 | #define VID_TYPE_CLIPPING 32 /* Can clip */ | ||
25 | #define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ | ||
26 | #define VID_TYPE_SCALES 128 /* Scalable */ | ||
27 | #define VID_TYPE_MONOCHROME 256 /* Monochrome only */ | ||
28 | #define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ | ||
29 | #define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ | ||
30 | #define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ | ||
31 | #define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ | ||
32 | #define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ | ||
33 | |||
34 | struct video_capability | ||
35 | { | ||
36 | char name[32]; | ||
37 | int type; | ||
38 | int channels; /* Num channels */ | ||
39 | int audios; /* Num audio devices */ | ||
40 | int maxwidth; /* Supported width */ | ||
41 | int maxheight; /* And height */ | ||
42 | int minwidth; /* Supported width */ | ||
43 | int minheight; /* And height */ | ||
44 | }; | ||
45 | |||
46 | |||
47 | struct video_channel | ||
48 | { | ||
49 | int channel; | ||
50 | char name[32]; | ||
51 | int tuners; | ||
52 | __u32 flags; | ||
53 | #define VIDEO_VC_TUNER 1 /* Channel has a tuner */ | ||
54 | #define VIDEO_VC_AUDIO 2 /* Channel has audio */ | ||
55 | __u16 type; | ||
56 | #define VIDEO_TYPE_TV 1 | ||
57 | #define VIDEO_TYPE_CAMERA 2 | ||
58 | __u16 norm; /* Norm set by channel */ | ||
59 | }; | ||
60 | |||
61 | struct video_tuner | ||
62 | { | ||
63 | int tuner; | ||
64 | char name[32]; | ||
65 | unsigned long rangelow, rangehigh; /* Tuner range */ | ||
66 | __u32 flags; | ||
67 | #define VIDEO_TUNER_PAL 1 | ||
68 | #define VIDEO_TUNER_NTSC 2 | ||
69 | #define VIDEO_TUNER_SECAM 4 | ||
70 | #define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */ | ||
71 | #define VIDEO_TUNER_NORM 16 /* Tuner can set norm */ | ||
72 | #define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */ | ||
73 | #define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */ | ||
74 | #define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */ | ||
75 | __u16 mode; /* PAL/NTSC/SECAM/OTHER */ | ||
76 | #define VIDEO_MODE_PAL 0 | ||
77 | #define VIDEO_MODE_NTSC 1 | ||
78 | #define VIDEO_MODE_SECAM 2 | ||
79 | #define VIDEO_MODE_AUTO 3 | ||
80 | __u16 signal; /* Signal strength 16bit scale */ | ||
81 | }; | ||
82 | |||
83 | struct video_picture | ||
84 | { | ||
85 | __u16 brightness; | ||
86 | __u16 hue; | ||
87 | __u16 colour; | ||
88 | __u16 contrast; | ||
89 | __u16 whiteness; /* Black and white only */ | ||
90 | __u16 depth; /* Capture depth */ | ||
91 | __u16 palette; /* Palette in use */ | ||
92 | #define VIDEO_PALETTE_GREY 1 /* Linear greyscale */ | ||
93 | #define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */ | ||
94 | #define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */ | ||
95 | #define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */ | ||
96 | #define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */ | ||
97 | #define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */ | ||
98 | #define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */ | ||
99 | #define VIDEO_PALETTE_YUYV 8 | ||
100 | #define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */ | ||
101 | #define VIDEO_PALETTE_YUV420 10 | ||
102 | #define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */ | ||
103 | #define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */ | ||
104 | #define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */ | ||
105 | #define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */ | ||
106 | #define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */ | ||
107 | #define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */ | ||
108 | #define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */ | ||
109 | #define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */ | ||
110 | }; | ||
111 | |||
112 | struct video_audio | ||
113 | { | ||
114 | int audio; /* Audio channel */ | ||
115 | __u16 volume; /* If settable */ | ||
116 | __u16 bass, treble; | ||
117 | __u32 flags; | ||
118 | #define VIDEO_AUDIO_MUTE 1 | ||
119 | #define VIDEO_AUDIO_MUTABLE 2 | ||
120 | #define VIDEO_AUDIO_VOLUME 4 | ||
121 | #define VIDEO_AUDIO_BASS 8 | ||
122 | #define VIDEO_AUDIO_TREBLE 16 | ||
123 | #define VIDEO_AUDIO_BALANCE 32 | ||
124 | char name[16]; | ||
125 | #define VIDEO_SOUND_MONO 1 | ||
126 | #define VIDEO_SOUND_STEREO 2 | ||
127 | #define VIDEO_SOUND_LANG1 4 | ||
128 | #define VIDEO_SOUND_LANG2 8 | ||
129 | __u16 mode; | ||
130 | __u16 balance; /* Stereo balance */ | ||
131 | __u16 step; /* Step actual volume uses */ | ||
132 | }; | ||
133 | |||
134 | struct video_clip | ||
135 | { | ||
136 | __s32 x,y; | ||
137 | __s32 width, height; | ||
138 | struct video_clip *next; /* For user use/driver use only */ | ||
139 | }; | ||
140 | |||
141 | struct video_window | ||
142 | { | ||
143 | __u32 x,y; /* Position of window */ | ||
144 | __u32 width,height; /* Its size */ | ||
145 | __u32 chromakey; | ||
146 | __u32 flags; | ||
147 | struct video_clip __user *clips; /* Set only */ | ||
148 | int clipcount; | ||
149 | #define VIDEO_WINDOW_INTERLACE 1 | ||
150 | #define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */ | ||
151 | #define VIDEO_CLIP_BITMAP -1 | ||
152 | /* bitmap is 1024x625, a '1' bit represents a clipped pixel */ | ||
153 | #define VIDEO_CLIPMAP_SIZE (128 * 625) | ||
154 | }; | ||
155 | |||
156 | struct video_capture | ||
157 | { | ||
158 | __u32 x,y; /* Offsets into image */ | ||
159 | __u32 width, height; /* Area to capture */ | ||
160 | __u16 decimation; /* Decimation divider */ | ||
161 | __u16 flags; /* Flags for capture */ | ||
162 | #define VIDEO_CAPTURE_ODD 0 /* Temporal */ | ||
163 | #define VIDEO_CAPTURE_EVEN 1 | ||
164 | }; | ||
165 | |||
166 | struct video_buffer | ||
167 | { | ||
168 | void *base; | ||
169 | int height,width; | ||
170 | int depth; | ||
171 | int bytesperline; | ||
172 | }; | ||
173 | |||
174 | struct video_mmap | ||
175 | { | ||
176 | unsigned int frame; /* Frame (0 - n) for double buffer */ | ||
177 | int height,width; | ||
178 | unsigned int format; /* should be VIDEO_PALETTE_* */ | ||
179 | }; | ||
180 | |||
181 | struct video_key | ||
182 | { | ||
183 | __u8 key[8]; | ||
184 | __u32 flags; | ||
185 | }; | ||
186 | |||
187 | struct video_mbuf | ||
188 | { | ||
189 | int size; /* Total memory to map */ | ||
190 | int frames; /* Frames */ | ||
191 | int offsets[VIDEO_MAX_FRAME]; | ||
192 | }; | ||
193 | |||
194 | #define VIDEO_NO_UNIT (-1) | ||
195 | |||
196 | struct video_unit | ||
197 | { | ||
198 | int video; /* Video minor */ | ||
199 | int vbi; /* VBI minor */ | ||
200 | int radio; /* Radio minor */ | ||
201 | int audio; /* Audio minor */ | ||
202 | int teletext; /* Teletext minor */ | ||
203 | }; | ||
204 | |||
205 | struct vbi_format { | ||
206 | __u32 sampling_rate; /* in Hz */ | ||
207 | __u32 samples_per_line; | ||
208 | __u32 sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */ | ||
209 | __s32 start[2]; /* starting line for each frame */ | ||
210 | __u32 count[2]; /* count of lines for each frame */ | ||
211 | __u32 flags; | ||
212 | #define VBI_UNSYNC 1 /* can distingues between top/bottom field */ | ||
213 | #define VBI_INTERLACED 2 /* lines are interlaced */ | ||
214 | }; | ||
215 | |||
216 | /* video_info is biased towards hardware mpeg encode/decode */ | ||
217 | /* but it could apply generically to any hardware compressor/decompressor */ | ||
218 | struct video_info | ||
219 | { | ||
220 | __u32 frame_count; /* frames output since decode/encode began */ | ||
221 | __u32 h_size; /* current unscaled horizontal size */ | ||
222 | __u32 v_size; /* current unscaled veritcal size */ | ||
223 | __u32 smpte_timecode; /* current SMPTE timecode (for current GOP) */ | ||
224 | __u32 picture_type; /* current picture type */ | ||
225 | __u32 temporal_reference; /* current temporal reference */ | ||
226 | __u8 user_data[256]; /* user data last found in compressed stream */ | ||
227 | /* user_data[0] contains user data flags, user_data[1] has count */ | ||
228 | }; | ||
229 | |||
230 | /* generic structure for setting playback modes */ | ||
231 | struct video_play_mode | ||
232 | { | ||
233 | int mode; | ||
234 | int p1; | ||
235 | int p2; | ||
236 | }; | ||
237 | |||
238 | /* for loading microcode / fpga programming */ | ||
239 | struct video_code | ||
240 | { | ||
241 | char loadwhat[16]; /* name or tag of file being passed */ | ||
242 | int datasize; | ||
243 | __u8 *data; | ||
244 | }; | ||
245 | |||
246 | #define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */ | ||
247 | #define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */ | ||
248 | #define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */ | ||
249 | #define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */ | ||
250 | #define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */ | ||
251 | #define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */ | ||
252 | #define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */ | ||
253 | #define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */ | ||
254 | #define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */ | ||
255 | #define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */ | ||
256 | #define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */ | ||
257 | #define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */ | ||
258 | #define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */ | ||
259 | #define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */ | ||
260 | #define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */ | ||
261 | #define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */ | ||
262 | #define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */ | ||
263 | #define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */ | ||
264 | #define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */ | ||
265 | #define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */ | ||
266 | #define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */ | ||
267 | #define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */ | ||
268 | #define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */ | ||
269 | #define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */ | ||
270 | #define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */ | ||
271 | #define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */ | ||
272 | #define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */ | ||
273 | #define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */ | ||
274 | #define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */ | ||
275 | |||
276 | |||
277 | #define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */ | ||
278 | |||
279 | /* VIDIOCSWRITEMODE */ | ||
280 | #define VID_WRITE_MPEG_AUD 0 | ||
281 | #define VID_WRITE_MPEG_VID 1 | ||
282 | #define VID_WRITE_OSD 2 | ||
283 | #define VID_WRITE_TTX 3 | ||
284 | #define VID_WRITE_CC 4 | ||
285 | #define VID_WRITE_MJPEG 5 | ||
286 | |||
287 | /* VIDIOCSPLAYMODE */ | ||
288 | #define VID_PLAY_VID_OUT_MODE 0 | ||
289 | /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */ | ||
290 | #define VID_PLAY_GENLOCK 1 | ||
291 | /* p1: 0 = OFF, 1 = ON */ | ||
292 | /* p2: GENLOCK FINE DELAY value */ | ||
293 | #define VID_PLAY_NORMAL 2 | ||
294 | #define VID_PLAY_PAUSE 3 | ||
295 | #define VID_PLAY_SINGLE_FRAME 4 | ||
296 | #define VID_PLAY_FAST_FORWARD 5 | ||
297 | #define VID_PLAY_SLOW_MOTION 6 | ||
298 | #define VID_PLAY_IMMEDIATE_NORMAL 7 | ||
299 | #define VID_PLAY_SWITCH_CHANNELS 8 | ||
300 | #define VID_PLAY_FREEZE_FRAME 9 | ||
301 | #define VID_PLAY_STILL_MODE 10 | ||
302 | #define VID_PLAY_MASTER_MODE 11 | ||
303 | /* p1: see below */ | ||
304 | #define VID_PLAY_MASTER_NONE 1 | ||
305 | #define VID_PLAY_MASTER_VIDEO 2 | ||
306 | #define VID_PLAY_MASTER_AUDIO 3 | ||
307 | #define VID_PLAY_ACTIVE_SCANLINES 12 | ||
308 | /* p1 = first active; p2 = last active */ | ||
309 | #define VID_PLAY_RESET 13 | ||
310 | #define VID_PLAY_END_MARK 14 | ||
311 | |||
312 | #endif /* __LINUX_VIDEODEV_H */ | ||
313 | |||
314 | /* | ||
315 | * Local variables: | ||
316 | * c-basic-offset: 8 | ||
317 | * End: | ||
318 | */ | ||