diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-13 23:13:22 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-15 15:25:07 -0400 |
commit | 0c0d06cac63ee327ceaab4b5ffe2206574ab86bd (patch) | |
tree | e759f0dc3185d97f2a0c6b5cd5e32ea6faa74d40 /drivers/media/usb/pwc/pwc-if.c | |
parent | 84cfe9e79bd5ac11c963f4841158454fefa872f6 (diff) |
[media] rename most media/video usb drivers to media/usb
Rename all USB drivers with their own directory under
drivers/media/video into drivers/media/usb and update the
building system.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/pwc/pwc-if.c')
-rw-r--r-- | drivers/media/usb/pwc/pwc-if.c | 1165 |
1 files changed, 1165 insertions, 0 deletions
diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c new file mode 100644 index 000000000000..de7c7ba99ef4 --- /dev/null +++ b/drivers/media/usb/pwc/pwc-if.c | |||
@@ -0,0 +1,1165 @@ | |||
1 | /* Linux driver for Philips webcam | ||
2 | USB and Video4Linux interface part. | ||
3 | (C) 1999-2004 Nemosoft Unv. | ||
4 | (C) 2004-2006 Luc Saillard (luc@saillard.org) | ||
5 | (C) 2011 Hans de Goede <hdegoede@redhat.com> | ||
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 | |||
29 | /* | ||
30 | This code forms the interface between the USB layers and the Philips | ||
31 | specific stuff. Some adanved stuff of the driver falls under an | ||
32 | NDA, signed between me and Philips B.V., Eindhoven, the Netherlands, and | ||
33 | is thus not distributed in source form. The binary pwcx.o module | ||
34 | contains the code that falls under the NDA. | ||
35 | |||
36 | In case you're wondering: 'pwc' stands for "Philips WebCam", but | ||
37 | I really didn't want to type 'philips_web_cam' every time (I'm lazy as | ||
38 | any Linux kernel hacker, but I don't like uncomprehensible abbreviations | ||
39 | without explanation). | ||
40 | |||
41 | Oh yes, convention: to disctinguish between all the various pointers to | ||
42 | device-structures, I use these names for the pointer variables: | ||
43 | udev: struct usb_device * | ||
44 | vdev: struct video_device (member of pwc_dev) | ||
45 | pdev: struct pwc_devive * | ||
46 | */ | ||
47 | |||
48 | /* Contributors: | ||
49 | - Alvarado: adding whitebalance code | ||
50 | - Alistar Moire: QuickCam 3000 Pro device/product ID | ||
51 | - Tony Hoyle: Creative Labs Webcam 5 device/product ID | ||
52 | - Mark Burazin: solving hang in VIDIOCSYNC when camera gets unplugged | ||
53 | - Jk Fang: Sotec Afina Eye ID | ||
54 | - Xavier Roche: QuickCam Pro 4000 ID | ||
55 | - Jens Knudsen: QuickCam Zoom ID | ||
56 | - J. Debert: QuickCam for Notebooks ID | ||
57 | - Pham Thanh Nam: webcam snapshot button as an event input device | ||
58 | */ | ||
59 | |||
60 | #include <linux/errno.h> | ||
61 | #include <linux/init.h> | ||
62 | #include <linux/mm.h> | ||
63 | #include <linux/module.h> | ||
64 | #include <linux/poll.h> | ||
65 | #include <linux/slab.h> | ||
66 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | ||
67 | #include <linux/usb/input.h> | ||
68 | #endif | ||
69 | #include <linux/vmalloc.h> | ||
70 | #include <asm/io.h> | ||
71 | #include <linux/kernel.h> /* simple_strtol() */ | ||
72 | |||
73 | #include "pwc.h" | ||
74 | #include "pwc-kiara.h" | ||
75 | #include "pwc-timon.h" | ||
76 | #include "pwc-dec23.h" | ||
77 | #include "pwc-dec1.h" | ||
78 | |||
79 | /* Function prototypes and driver templates */ | ||
80 | |||
81 | /* hotplug device table support */ | ||
82 | static const struct usb_device_id pwc_device_table [] = { | ||
83 | { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */ | ||
84 | { USB_DEVICE(0x0471, 0x0303) }, | ||
85 | { USB_DEVICE(0x0471, 0x0304) }, | ||
86 | { USB_DEVICE(0x0471, 0x0307) }, | ||
87 | { USB_DEVICE(0x0471, 0x0308) }, | ||
88 | { USB_DEVICE(0x0471, 0x030C) }, | ||
89 | { USB_DEVICE(0x0471, 0x0310) }, | ||
90 | { USB_DEVICE(0x0471, 0x0311) }, /* Philips ToUcam PRO II */ | ||
91 | { USB_DEVICE(0x0471, 0x0312) }, | ||
92 | { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */ | ||
93 | { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */ | ||
94 | { USB_DEVICE(0x069A, 0x0001) }, /* Askey */ | ||
95 | { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */ | ||
96 | { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */ | ||
97 | { USB_DEVICE(0x046D, 0x08B2) }, /* Logitech QuickCam Pro 4000 */ | ||
98 | { USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */ | ||
99 | { USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */ | ||
100 | { USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */ | ||
101 | { USB_DEVICE(0x046D, 0x08B6) }, /* Cisco VT Camera */ | ||
102 | { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech ViewPort AV 100 */ | ||
103 | { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */ | ||
104 | { USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */ | ||
105 | { USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */ | ||
106 | { USB_DEVICE(0x055D, 0x9002) }, /* Samsung SNC-35E (Ver3.0) */ | ||
107 | { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */ | ||
108 | { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */ | ||
109 | { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */ | ||
110 | { USB_DEVICE(0x06BE, 0x8116) }, /* new Afina Eye */ | ||
111 | { USB_DEVICE(0x0d81, 0x1910) }, /* Visionite */ | ||
112 | { USB_DEVICE(0x0d81, 0x1900) }, | ||
113 | { } | ||
114 | }; | ||
115 | MODULE_DEVICE_TABLE(usb, pwc_device_table); | ||
116 | |||
117 | static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id); | ||
118 | static void usb_pwc_disconnect(struct usb_interface *intf); | ||
119 | static void pwc_isoc_cleanup(struct pwc_device *pdev); | ||
120 | |||
121 | static struct usb_driver pwc_driver = { | ||
122 | .name = "Philips webcam", /* name */ | ||
123 | .id_table = pwc_device_table, | ||
124 | .probe = usb_pwc_probe, /* probe() */ | ||
125 | .disconnect = usb_pwc_disconnect, /* disconnect() */ | ||
126 | }; | ||
127 | |||
128 | #define MAX_DEV_HINTS 20 | ||
129 | #define MAX_ISOC_ERRORS 20 | ||
130 | |||
131 | #ifdef CONFIG_USB_PWC_DEBUG | ||
132 | int pwc_trace = PWC_DEBUG_LEVEL; | ||
133 | #endif | ||
134 | static int power_save = -1; | ||
135 | static int leds[2] = { 100, 0 }; | ||
136 | |||
137 | /***/ | ||
138 | |||
139 | static const struct v4l2_file_operations pwc_fops = { | ||
140 | .owner = THIS_MODULE, | ||
141 | .open = v4l2_fh_open, | ||
142 | .release = vb2_fop_release, | ||
143 | .read = vb2_fop_read, | ||
144 | .poll = vb2_fop_poll, | ||
145 | .mmap = vb2_fop_mmap, | ||
146 | .unlocked_ioctl = video_ioctl2, | ||
147 | }; | ||
148 | static struct video_device pwc_template = { | ||
149 | .name = "Philips Webcam", /* Filled in later */ | ||
150 | .release = video_device_release_empty, | ||
151 | .fops = &pwc_fops, | ||
152 | .ioctl_ops = &pwc_ioctl_ops, | ||
153 | }; | ||
154 | |||
155 | /***************************************************************************/ | ||
156 | /* Private functions */ | ||
157 | |||
158 | struct pwc_frame_buf *pwc_get_next_fill_buf(struct pwc_device *pdev) | ||
159 | { | ||
160 | unsigned long flags = 0; | ||
161 | struct pwc_frame_buf *buf = NULL; | ||
162 | |||
163 | spin_lock_irqsave(&pdev->queued_bufs_lock, flags); | ||
164 | if (list_empty(&pdev->queued_bufs)) | ||
165 | goto leave; | ||
166 | |||
167 | buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf, list); | ||
168 | list_del(&buf->list); | ||
169 | leave: | ||
170 | spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags); | ||
171 | return buf; | ||
172 | } | ||
173 | |||
174 | static void pwc_snapshot_button(struct pwc_device *pdev, int down) | ||
175 | { | ||
176 | if (down) { | ||
177 | PWC_TRACE("Snapshot button pressed.\n"); | ||
178 | } else { | ||
179 | PWC_TRACE("Snapshot button released.\n"); | ||
180 | } | ||
181 | |||
182 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | ||
183 | if (pdev->button_dev) { | ||
184 | input_report_key(pdev->button_dev, KEY_CAMERA, down); | ||
185 | input_sync(pdev->button_dev); | ||
186 | } | ||
187 | #endif | ||
188 | } | ||
189 | |||
190 | static void pwc_frame_complete(struct pwc_device *pdev) | ||
191 | { | ||
192 | struct pwc_frame_buf *fbuf = pdev->fill_buf; | ||
193 | |||
194 | /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus | ||
195 | frames on the USB wire after an exposure change. This conditition is | ||
196 | however detected in the cam and a bit is set in the header. | ||
197 | */ | ||
198 | if (pdev->type == 730) { | ||
199 | unsigned char *ptr = (unsigned char *)fbuf->data; | ||
200 | |||
201 | if (ptr[1] == 1 && ptr[0] & 0x10) { | ||
202 | PWC_TRACE("Hyundai CMOS sensor bug. Dropping frame.\n"); | ||
203 | pdev->drop_frames += 2; | ||
204 | } | ||
205 | if ((ptr[0] ^ pdev->vmirror) & 0x01) { | ||
206 | pwc_snapshot_button(pdev, ptr[0] & 0x01); | ||
207 | } | ||
208 | if ((ptr[0] ^ pdev->vmirror) & 0x02) { | ||
209 | if (ptr[0] & 0x02) | ||
210 | PWC_TRACE("Image is mirrored.\n"); | ||
211 | else | ||
212 | PWC_TRACE("Image is normal.\n"); | ||
213 | } | ||
214 | pdev->vmirror = ptr[0] & 0x03; | ||
215 | /* Sometimes the trailer of the 730 is still sent as a 4 byte packet | ||
216 | after a short frame; this condition is filtered out specifically. A 4 byte | ||
217 | frame doesn't make sense anyway. | ||
218 | So we get either this sequence: | ||
219 | drop_bit set -> 4 byte frame -> short frame -> good frame | ||
220 | Or this one: | ||
221 | drop_bit set -> short frame -> good frame | ||
222 | So we drop either 3 or 2 frames in all! | ||
223 | */ | ||
224 | if (fbuf->filled == 4) | ||
225 | pdev->drop_frames++; | ||
226 | } else if (pdev->type == 740 || pdev->type == 720) { | ||
227 | unsigned char *ptr = (unsigned char *)fbuf->data; | ||
228 | if ((ptr[0] ^ pdev->vmirror) & 0x01) { | ||
229 | pwc_snapshot_button(pdev, ptr[0] & 0x01); | ||
230 | } | ||
231 | pdev->vmirror = ptr[0] & 0x03; | ||
232 | } | ||
233 | |||
234 | /* In case we were instructed to drop the frame, do so silently. */ | ||
235 | if (pdev->drop_frames > 0) { | ||
236 | pdev->drop_frames--; | ||
237 | } else { | ||
238 | /* Check for underflow first */ | ||
239 | if (fbuf->filled < pdev->frame_total_size) { | ||
240 | PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);" | ||
241 | " discarded.\n", fbuf->filled); | ||
242 | } else { | ||
243 | fbuf->vb.v4l2_buf.field = V4L2_FIELD_NONE; | ||
244 | fbuf->vb.v4l2_buf.sequence = pdev->vframe_count; | ||
245 | vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE); | ||
246 | pdev->fill_buf = NULL; | ||
247 | pdev->vsync = 0; | ||
248 | } | ||
249 | } /* !drop_frames */ | ||
250 | pdev->vframe_count++; | ||
251 | } | ||
252 | |||
253 | /* This gets called for the Isochronous pipe (video). This is done in | ||
254 | * interrupt time, so it has to be fast, not crash, and not stall. Neat. | ||
255 | */ | ||
256 | static void pwc_isoc_handler(struct urb *urb) | ||
257 | { | ||
258 | struct pwc_device *pdev = (struct pwc_device *)urb->context; | ||
259 | int i, fst, flen; | ||
260 | unsigned char *iso_buf = NULL; | ||
261 | |||
262 | if (urb->status == -ENOENT || urb->status == -ECONNRESET || | ||
263 | urb->status == -ESHUTDOWN) { | ||
264 | PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a"); | ||
265 | return; | ||
266 | } | ||
267 | |||
268 | if (pdev->fill_buf == NULL) | ||
269 | pdev->fill_buf = pwc_get_next_fill_buf(pdev); | ||
270 | |||
271 | if (urb->status != 0) { | ||
272 | const char *errmsg; | ||
273 | |||
274 | errmsg = "Unknown"; | ||
275 | switch(urb->status) { | ||
276 | case -ENOSR: errmsg = "Buffer error (overrun)"; break; | ||
277 | case -EPIPE: errmsg = "Stalled (device not responding)"; break; | ||
278 | case -EOVERFLOW: errmsg = "Babble (bad cable?)"; break; | ||
279 | case -EPROTO: errmsg = "Bit-stuff error (bad cable?)"; break; | ||
280 | case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break; | ||
281 | case -ETIME: errmsg = "Device does not respond"; break; | ||
282 | } | ||
283 | PWC_ERROR("pwc_isoc_handler() called with status %d [%s].\n", | ||
284 | urb->status, errmsg); | ||
285 | /* Give up after a number of contiguous errors */ | ||
286 | if (++pdev->visoc_errors > MAX_ISOC_ERRORS) | ||
287 | { | ||
288 | PWC_ERROR("Too many ISOC errors, bailing out.\n"); | ||
289 | if (pdev->fill_buf) { | ||
290 | vb2_buffer_done(&pdev->fill_buf->vb, | ||
291 | VB2_BUF_STATE_ERROR); | ||
292 | pdev->fill_buf = NULL; | ||
293 | } | ||
294 | } | ||
295 | pdev->vsync = 0; /* Drop the current frame */ | ||
296 | goto handler_end; | ||
297 | } | ||
298 | |||
299 | /* Reset ISOC error counter. We did get here, after all. */ | ||
300 | pdev->visoc_errors = 0; | ||
301 | |||
302 | /* vsync: 0 = don't copy data | ||
303 | 1 = sync-hunt | ||
304 | 2 = synched | ||
305 | */ | ||
306 | /* Compact data */ | ||
307 | for (i = 0; i < urb->number_of_packets; i++) { | ||
308 | fst = urb->iso_frame_desc[i].status; | ||
309 | flen = urb->iso_frame_desc[i].actual_length; | ||
310 | iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | ||
311 | if (fst != 0) { | ||
312 | PWC_ERROR("Iso frame %d has error %d\n", i, fst); | ||
313 | continue; | ||
314 | } | ||
315 | if (flen > 0 && pdev->vsync) { | ||
316 | struct pwc_frame_buf *fbuf = pdev->fill_buf; | ||
317 | |||
318 | if (pdev->vsync == 1) { | ||
319 | do_gettimeofday(&fbuf->vb.v4l2_buf.timestamp); | ||
320 | pdev->vsync = 2; | ||
321 | } | ||
322 | |||
323 | if (flen + fbuf->filled > pdev->frame_total_size) { | ||
324 | PWC_ERROR("Frame overflow (%d > %d)\n", | ||
325 | flen + fbuf->filled, | ||
326 | pdev->frame_total_size); | ||
327 | pdev->vsync = 0; /* Let's wait for an EOF */ | ||
328 | } else { | ||
329 | memcpy(fbuf->data + fbuf->filled, iso_buf, | ||
330 | flen); | ||
331 | fbuf->filled += flen; | ||
332 | } | ||
333 | } | ||
334 | if (flen < pdev->vlast_packet_size) { | ||
335 | /* Shorter packet... end of frame */ | ||
336 | if (pdev->vsync == 2) | ||
337 | pwc_frame_complete(pdev); | ||
338 | if (pdev->fill_buf == NULL) | ||
339 | pdev->fill_buf = pwc_get_next_fill_buf(pdev); | ||
340 | if (pdev->fill_buf) { | ||
341 | pdev->fill_buf->filled = 0; | ||
342 | pdev->vsync = 1; | ||
343 | } | ||
344 | } | ||
345 | pdev->vlast_packet_size = flen; | ||
346 | } | ||
347 | |||
348 | handler_end: | ||
349 | i = usb_submit_urb(urb, GFP_ATOMIC); | ||
350 | if (i != 0) | ||
351 | PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i); | ||
352 | } | ||
353 | |||
354 | /* Both v4l2_lock and vb_queue_lock should be locked when calling this */ | ||
355 | static int pwc_isoc_init(struct pwc_device *pdev) | ||
356 | { | ||
357 | struct usb_device *udev; | ||
358 | struct urb *urb; | ||
359 | int i, j, ret; | ||
360 | struct usb_interface *intf; | ||
361 | struct usb_host_interface *idesc = NULL; | ||
362 | int compression = 0; /* 0..3 = uncompressed..high */ | ||
363 | |||
364 | pdev->vsync = 0; | ||
365 | pdev->vlast_packet_size = 0; | ||
366 | pdev->fill_buf = NULL; | ||
367 | pdev->vframe_count = 0; | ||
368 | pdev->visoc_errors = 0; | ||
369 | udev = pdev->udev; | ||
370 | |||
371 | retry: | ||
372 | /* We first try with low compression and then retry with a higher | ||
373 | compression setting if there is not enough bandwidth. */ | ||
374 | ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt, | ||
375 | pdev->vframes, &compression, 1); | ||
376 | |||
377 | /* Get the current alternate interface, adjust packet size */ | ||
378 | intf = usb_ifnum_to_if(udev, 0); | ||
379 | if (intf) | ||
380 | idesc = usb_altnum_to_altsetting(intf, pdev->valternate); | ||
381 | if (!idesc) | ||
382 | return -EIO; | ||
383 | |||
384 | /* Search video endpoint */ | ||
385 | pdev->vmax_packet_size = -1; | ||
386 | for (i = 0; i < idesc->desc.bNumEndpoints; i++) { | ||
387 | if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) { | ||
388 | pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize); | ||
389 | break; | ||
390 | } | ||
391 | } | ||
392 | |||
393 | if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) { | ||
394 | PWC_ERROR("Failed to find packet size for video endpoint in current alternate setting.\n"); | ||
395 | return -ENFILE; /* Odd error, that should be noticeable */ | ||
396 | } | ||
397 | |||
398 | /* Set alternate interface */ | ||
399 | PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate); | ||
400 | ret = usb_set_interface(pdev->udev, 0, pdev->valternate); | ||
401 | if (ret == -ENOSPC && compression < 3) { | ||
402 | compression++; | ||
403 | goto retry; | ||
404 | } | ||
405 | if (ret < 0) | ||
406 | return ret; | ||
407 | |||
408 | /* Allocate and init Isochronuous urbs */ | ||
409 | for (i = 0; i < MAX_ISO_BUFS; i++) { | ||
410 | urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); | ||
411 | if (urb == NULL) { | ||
412 | PWC_ERROR("Failed to allocate urb %d\n", i); | ||
413 | pwc_isoc_cleanup(pdev); | ||
414 | return -ENOMEM; | ||
415 | } | ||
416 | pdev->urbs[i] = urb; | ||
417 | PWC_DEBUG_MEMORY("Allocated URB at 0x%p\n", urb); | ||
418 | |||
419 | urb->interval = 1; // devik | ||
420 | urb->dev = udev; | ||
421 | urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint); | ||
422 | urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; | ||
423 | urb->transfer_buffer = usb_alloc_coherent(udev, | ||
424 | ISO_BUFFER_SIZE, | ||
425 | GFP_KERNEL, | ||
426 | &urb->transfer_dma); | ||
427 | if (urb->transfer_buffer == NULL) { | ||
428 | PWC_ERROR("Failed to allocate urb buffer %d\n", i); | ||
429 | pwc_isoc_cleanup(pdev); | ||
430 | return -ENOMEM; | ||
431 | } | ||
432 | urb->transfer_buffer_length = ISO_BUFFER_SIZE; | ||
433 | urb->complete = pwc_isoc_handler; | ||
434 | urb->context = pdev; | ||
435 | urb->start_frame = 0; | ||
436 | urb->number_of_packets = ISO_FRAMES_PER_DESC; | ||
437 | for (j = 0; j < ISO_FRAMES_PER_DESC; j++) { | ||
438 | urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE; | ||
439 | urb->iso_frame_desc[j].length = pdev->vmax_packet_size; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | /* link */ | ||
444 | for (i = 0; i < MAX_ISO_BUFS; i++) { | ||
445 | ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL); | ||
446 | if (ret == -ENOSPC && compression < 3) { | ||
447 | compression++; | ||
448 | pwc_isoc_cleanup(pdev); | ||
449 | goto retry; | ||
450 | } | ||
451 | if (ret) { | ||
452 | PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); | ||
453 | pwc_isoc_cleanup(pdev); | ||
454 | return ret; | ||
455 | } | ||
456 | PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->urbs[i]); | ||
457 | } | ||
458 | |||
459 | /* All is done... */ | ||
460 | PWC_DEBUG_OPEN("<< pwc_isoc_init()\n"); | ||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | static void pwc_iso_stop(struct pwc_device *pdev) | ||
465 | { | ||
466 | int i; | ||
467 | |||
468 | /* Unlinking ISOC buffers one by one */ | ||
469 | for (i = 0; i < MAX_ISO_BUFS; i++) { | ||
470 | if (pdev->urbs[i]) { | ||
471 | PWC_DEBUG_MEMORY("Unlinking URB %p\n", pdev->urbs[i]); | ||
472 | usb_kill_urb(pdev->urbs[i]); | ||
473 | } | ||
474 | } | ||
475 | } | ||
476 | |||
477 | static void pwc_iso_free(struct pwc_device *pdev) | ||
478 | { | ||
479 | int i; | ||
480 | |||
481 | /* Freeing ISOC buffers one by one */ | ||
482 | for (i = 0; i < MAX_ISO_BUFS; i++) { | ||
483 | if (pdev->urbs[i]) { | ||
484 | PWC_DEBUG_MEMORY("Freeing URB\n"); | ||
485 | if (pdev->urbs[i]->transfer_buffer) { | ||
486 | usb_free_coherent(pdev->udev, | ||
487 | pdev->urbs[i]->transfer_buffer_length, | ||
488 | pdev->urbs[i]->transfer_buffer, | ||
489 | pdev->urbs[i]->transfer_dma); | ||
490 | } | ||
491 | usb_free_urb(pdev->urbs[i]); | ||
492 | pdev->urbs[i] = NULL; | ||
493 | } | ||
494 | } | ||
495 | } | ||
496 | |||
497 | /* Both v4l2_lock and vb_queue_lock should be locked when calling this */ | ||
498 | static void pwc_isoc_cleanup(struct pwc_device *pdev) | ||
499 | { | ||
500 | PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n"); | ||
501 | |||
502 | pwc_iso_stop(pdev); | ||
503 | pwc_iso_free(pdev); | ||
504 | usb_set_interface(pdev->udev, 0, 0); | ||
505 | |||
506 | PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); | ||
507 | } | ||
508 | |||
509 | /* Must be called with vb_queue_lock hold */ | ||
510 | static void pwc_cleanup_queued_bufs(struct pwc_device *pdev) | ||
511 | { | ||
512 | unsigned long flags = 0; | ||
513 | |||
514 | spin_lock_irqsave(&pdev->queued_bufs_lock, flags); | ||
515 | while (!list_empty(&pdev->queued_bufs)) { | ||
516 | struct pwc_frame_buf *buf; | ||
517 | |||
518 | buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf, | ||
519 | list); | ||
520 | list_del(&buf->list); | ||
521 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); | ||
522 | } | ||
523 | spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags); | ||
524 | } | ||
525 | |||
526 | #ifdef CONFIG_USB_PWC_DEBUG | ||
527 | static const char *pwc_sensor_type_to_string(unsigned int sensor_type) | ||
528 | { | ||
529 | switch(sensor_type) { | ||
530 | case 0x00: | ||
531 | return "Hyundai CMOS sensor"; | ||
532 | case 0x20: | ||
533 | return "Sony CCD sensor + TDA8787"; | ||
534 | case 0x2E: | ||
535 | return "Sony CCD sensor + Exas 98L59"; | ||
536 | case 0x2F: | ||
537 | return "Sony CCD sensor + ADI 9804"; | ||
538 | case 0x30: | ||
539 | return "Sharp CCD sensor + TDA8787"; | ||
540 | case 0x3E: | ||
541 | return "Sharp CCD sensor + Exas 98L59"; | ||
542 | case 0x3F: | ||
543 | return "Sharp CCD sensor + ADI 9804"; | ||
544 | case 0x40: | ||
545 | return "UPA 1021 sensor"; | ||
546 | case 0x100: | ||
547 | return "VGA sensor"; | ||
548 | case 0x101: | ||
549 | return "PAL MR sensor"; | ||
550 | default: | ||
551 | return "unknown type of sensor"; | ||
552 | } | ||
553 | } | ||
554 | #endif | ||
555 | |||
556 | /***************************************************************************/ | ||
557 | /* Video4Linux functions */ | ||
558 | |||
559 | static void pwc_video_release(struct v4l2_device *v) | ||
560 | { | ||
561 | struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev); | ||
562 | |||
563 | v4l2_ctrl_handler_free(&pdev->ctrl_handler); | ||
564 | v4l2_device_unregister(&pdev->v4l2_dev); | ||
565 | kfree(pdev->ctrl_buf); | ||
566 | kfree(pdev); | ||
567 | } | ||
568 | |||
569 | /***************************************************************************/ | ||
570 | /* Videobuf2 operations */ | ||
571 | |||
572 | static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | ||
573 | unsigned int *nbuffers, unsigned int *nplanes, | ||
574 | unsigned int sizes[], void *alloc_ctxs[]) | ||
575 | { | ||
576 | struct pwc_device *pdev = vb2_get_drv_priv(vq); | ||
577 | int size; | ||
578 | |||
579 | if (*nbuffers < MIN_FRAMES) | ||
580 | *nbuffers = MIN_FRAMES; | ||
581 | else if (*nbuffers > MAX_FRAMES) | ||
582 | *nbuffers = MAX_FRAMES; | ||
583 | |||
584 | *nplanes = 1; | ||
585 | |||
586 | size = pwc_get_size(pdev, MAX_WIDTH, MAX_HEIGHT); | ||
587 | sizes[0] = PAGE_ALIGN(pwc_image_sizes[size][0] * | ||
588 | pwc_image_sizes[size][1] * 3 / 2); | ||
589 | |||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | static int buffer_init(struct vb2_buffer *vb) | ||
594 | { | ||
595 | struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); | ||
596 | |||
597 | /* need vmalloc since frame buffer > 128K */ | ||
598 | buf->data = vzalloc(PWC_FRAME_SIZE); | ||
599 | if (buf->data == NULL) | ||
600 | return -ENOMEM; | ||
601 | |||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | static int buffer_prepare(struct vb2_buffer *vb) | ||
606 | { | ||
607 | struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue); | ||
608 | |||
609 | /* Don't allow queing new buffers after device disconnection */ | ||
610 | if (!pdev->udev) | ||
611 | return -ENODEV; | ||
612 | |||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | static int buffer_finish(struct vb2_buffer *vb) | ||
617 | { | ||
618 | struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue); | ||
619 | struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); | ||
620 | |||
621 | /* | ||
622 | * Application has called dqbuf and is getting back a buffer we've | ||
623 | * filled, take the pwc data we've stored in buf->data and decompress | ||
624 | * it into a usable format, storing the result in the vb2_buffer | ||
625 | */ | ||
626 | return pwc_decompress(pdev, buf); | ||
627 | } | ||
628 | |||
629 | static void buffer_cleanup(struct vb2_buffer *vb) | ||
630 | { | ||
631 | struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); | ||
632 | |||
633 | vfree(buf->data); | ||
634 | } | ||
635 | |||
636 | static void buffer_queue(struct vb2_buffer *vb) | ||
637 | { | ||
638 | struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue); | ||
639 | struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); | ||
640 | unsigned long flags = 0; | ||
641 | |||
642 | /* Check the device has not disconnected between prep and queuing */ | ||
643 | if (!pdev->udev) { | ||
644 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); | ||
645 | return; | ||
646 | } | ||
647 | |||
648 | spin_lock_irqsave(&pdev->queued_bufs_lock, flags); | ||
649 | list_add_tail(&buf->list, &pdev->queued_bufs); | ||
650 | spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags); | ||
651 | } | ||
652 | |||
653 | static int start_streaming(struct vb2_queue *vq, unsigned int count) | ||
654 | { | ||
655 | struct pwc_device *pdev = vb2_get_drv_priv(vq); | ||
656 | int r; | ||
657 | |||
658 | if (!pdev->udev) | ||
659 | return -ENODEV; | ||
660 | |||
661 | if (mutex_lock_interruptible(&pdev->v4l2_lock)) | ||
662 | return -ERESTARTSYS; | ||
663 | /* Turn on camera and set LEDS on */ | ||
664 | pwc_camera_power(pdev, 1); | ||
665 | pwc_set_leds(pdev, leds[0], leds[1]); | ||
666 | |||
667 | r = pwc_isoc_init(pdev); | ||
668 | if (r) { | ||
669 | /* If we failed turn camera and LEDS back off */ | ||
670 | pwc_set_leds(pdev, 0, 0); | ||
671 | pwc_camera_power(pdev, 0); | ||
672 | /* And cleanup any queued bufs!! */ | ||
673 | pwc_cleanup_queued_bufs(pdev); | ||
674 | } | ||
675 | mutex_unlock(&pdev->v4l2_lock); | ||
676 | |||
677 | return r; | ||
678 | } | ||
679 | |||
680 | static int stop_streaming(struct vb2_queue *vq) | ||
681 | { | ||
682 | struct pwc_device *pdev = vb2_get_drv_priv(vq); | ||
683 | |||
684 | if (mutex_lock_interruptible(&pdev->v4l2_lock)) | ||
685 | return -ERESTARTSYS; | ||
686 | if (pdev->udev) { | ||
687 | pwc_set_leds(pdev, 0, 0); | ||
688 | pwc_camera_power(pdev, 0); | ||
689 | pwc_isoc_cleanup(pdev); | ||
690 | } | ||
691 | |||
692 | pwc_cleanup_queued_bufs(pdev); | ||
693 | mutex_unlock(&pdev->v4l2_lock); | ||
694 | |||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | static struct vb2_ops pwc_vb_queue_ops = { | ||
699 | .queue_setup = queue_setup, | ||
700 | .buf_init = buffer_init, | ||
701 | .buf_prepare = buffer_prepare, | ||
702 | .buf_finish = buffer_finish, | ||
703 | .buf_cleanup = buffer_cleanup, | ||
704 | .buf_queue = buffer_queue, | ||
705 | .start_streaming = start_streaming, | ||
706 | .stop_streaming = stop_streaming, | ||
707 | .wait_prepare = vb2_ops_wait_prepare, | ||
708 | .wait_finish = vb2_ops_wait_finish, | ||
709 | }; | ||
710 | |||
711 | /***************************************************************************/ | ||
712 | /* USB functions */ | ||
713 | |||
714 | /* This function gets called when a new device is plugged in or the usb core | ||
715 | * is loaded. | ||
716 | */ | ||
717 | |||
718 | static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
719 | { | ||
720 | struct usb_device *udev = interface_to_usbdev(intf); | ||
721 | struct pwc_device *pdev = NULL; | ||
722 | int vendor_id, product_id, type_id; | ||
723 | int rc; | ||
724 | int features = 0; | ||
725 | int compression = 0; | ||
726 | int my_power_save = power_save; | ||
727 | char serial_number[30], *name; | ||
728 | |||
729 | vendor_id = le16_to_cpu(udev->descriptor.idVendor); | ||
730 | product_id = le16_to_cpu(udev->descriptor.idProduct); | ||
731 | |||
732 | /* Check if we can handle this device */ | ||
733 | PWC_DEBUG_PROBE("probe() called [%04X %04X], if %d\n", | ||
734 | vendor_id, product_id, | ||
735 | intf->altsetting->desc.bInterfaceNumber); | ||
736 | |||
737 | /* the interfaces are probed one by one. We are only interested in the | ||
738 | video interface (0) now. | ||
739 | Interface 1 is the Audio Control, and interface 2 Audio itself. | ||
740 | */ | ||
741 | if (intf->altsetting->desc.bInterfaceNumber > 0) | ||
742 | return -ENODEV; | ||
743 | |||
744 | if (vendor_id == 0x0471) { | ||
745 | switch (product_id) { | ||
746 | case 0x0302: | ||
747 | PWC_INFO("Philips PCA645VC USB webcam detected.\n"); | ||
748 | name = "Philips 645 webcam"; | ||
749 | type_id = 645; | ||
750 | break; | ||
751 | case 0x0303: | ||
752 | PWC_INFO("Philips PCA646VC USB webcam detected.\n"); | ||
753 | name = "Philips 646 webcam"; | ||
754 | type_id = 646; | ||
755 | break; | ||
756 | case 0x0304: | ||
757 | PWC_INFO("Askey VC010 type 2 USB webcam detected.\n"); | ||
758 | name = "Askey VC010 webcam"; | ||
759 | type_id = 646; | ||
760 | break; | ||
761 | case 0x0307: | ||
762 | PWC_INFO("Philips PCVC675K (Vesta) USB webcam detected.\n"); | ||
763 | name = "Philips 675 webcam"; | ||
764 | type_id = 675; | ||
765 | break; | ||
766 | case 0x0308: | ||
767 | PWC_INFO("Philips PCVC680K (Vesta Pro) USB webcam detected.\n"); | ||
768 | name = "Philips 680 webcam"; | ||
769 | type_id = 680; | ||
770 | break; | ||
771 | case 0x030C: | ||
772 | PWC_INFO("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n"); | ||
773 | name = "Philips 690 webcam"; | ||
774 | type_id = 690; | ||
775 | break; | ||
776 | case 0x0310: | ||
777 | PWC_INFO("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n"); | ||
778 | name = "Philips 730 webcam"; | ||
779 | type_id = 730; | ||
780 | break; | ||
781 | case 0x0311: | ||
782 | PWC_INFO("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n"); | ||
783 | name = "Philips 740 webcam"; | ||
784 | type_id = 740; | ||
785 | break; | ||
786 | case 0x0312: | ||
787 | PWC_INFO("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n"); | ||
788 | name = "Philips 750 webcam"; | ||
789 | type_id = 750; | ||
790 | break; | ||
791 | case 0x0313: | ||
792 | PWC_INFO("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n"); | ||
793 | name = "Philips 720K/40 webcam"; | ||
794 | type_id = 720; | ||
795 | break; | ||
796 | case 0x0329: | ||
797 | PWC_INFO("Philips SPC 900NC USB webcam detected.\n"); | ||
798 | name = "Philips SPC 900NC webcam"; | ||
799 | type_id = 740; | ||
800 | break; | ||
801 | default: | ||
802 | return -ENODEV; | ||
803 | break; | ||
804 | } | ||
805 | } | ||
806 | else if (vendor_id == 0x069A) { | ||
807 | switch(product_id) { | ||
808 | case 0x0001: | ||
809 | PWC_INFO("Askey VC010 type 1 USB webcam detected.\n"); | ||
810 | name = "Askey VC010 webcam"; | ||
811 | type_id = 645; | ||
812 | break; | ||
813 | default: | ||
814 | return -ENODEV; | ||
815 | break; | ||
816 | } | ||
817 | } | ||
818 | else if (vendor_id == 0x046d) { | ||
819 | switch(product_id) { | ||
820 | case 0x08b0: | ||
821 | PWC_INFO("Logitech QuickCam Pro 3000 USB webcam detected.\n"); | ||
822 | name = "Logitech QuickCam Pro 3000"; | ||
823 | type_id = 740; /* CCD sensor */ | ||
824 | break; | ||
825 | case 0x08b1: | ||
826 | PWC_INFO("Logitech QuickCam Notebook Pro USB webcam detected.\n"); | ||
827 | name = "Logitech QuickCam Notebook Pro"; | ||
828 | type_id = 740; /* CCD sensor */ | ||
829 | break; | ||
830 | case 0x08b2: | ||
831 | PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n"); | ||
832 | name = "Logitech QuickCam Pro 4000"; | ||
833 | type_id = 740; /* CCD sensor */ | ||
834 | if (my_power_save == -1) | ||
835 | my_power_save = 1; | ||
836 | break; | ||
837 | case 0x08b3: | ||
838 | PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n"); | ||
839 | name = "Logitech QuickCam Zoom"; | ||
840 | type_id = 740; /* CCD sensor */ | ||
841 | break; | ||
842 | case 0x08B4: | ||
843 | PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n"); | ||
844 | name = "Logitech QuickCam Zoom"; | ||
845 | type_id = 740; /* CCD sensor */ | ||
846 | if (my_power_save == -1) | ||
847 | my_power_save = 1; | ||
848 | break; | ||
849 | case 0x08b5: | ||
850 | PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n"); | ||
851 | name = "Logitech QuickCam Orbit"; | ||
852 | type_id = 740; /* CCD sensor */ | ||
853 | if (my_power_save == -1) | ||
854 | my_power_save = 1; | ||
855 | features |= FEATURE_MOTOR_PANTILT; | ||
856 | break; | ||
857 | case 0x08b6: | ||
858 | PWC_INFO("Logitech/Cisco VT Camera webcam detected.\n"); | ||
859 | name = "Cisco VT Camera"; | ||
860 | type_id = 740; /* CCD sensor */ | ||
861 | break; | ||
862 | case 0x08b7: | ||
863 | PWC_INFO("Logitech ViewPort AV 100 webcam detected.\n"); | ||
864 | name = "Logitech ViewPort AV 100"; | ||
865 | type_id = 740; /* CCD sensor */ | ||
866 | break; | ||
867 | case 0x08b8: /* Where this released? */ | ||
868 | PWC_INFO("Logitech QuickCam detected (reserved ID).\n"); | ||
869 | name = "Logitech QuickCam (res.)"; | ||
870 | type_id = 730; /* Assuming CMOS */ | ||
871 | break; | ||
872 | default: | ||
873 | return -ENODEV; | ||
874 | break; | ||
875 | } | ||
876 | } | ||
877 | else if (vendor_id == 0x055d) { | ||
878 | /* I don't know the difference between the C10 and the C30; | ||
879 | I suppose the difference is the sensor, but both cameras | ||
880 | work equally well with a type_id of 675 | ||
881 | */ | ||
882 | switch(product_id) { | ||
883 | case 0x9000: | ||
884 | PWC_INFO("Samsung MPC-C10 USB webcam detected.\n"); | ||
885 | name = "Samsung MPC-C10"; | ||
886 | type_id = 675; | ||
887 | break; | ||
888 | case 0x9001: | ||
889 | PWC_INFO("Samsung MPC-C30 USB webcam detected.\n"); | ||
890 | name = "Samsung MPC-C30"; | ||
891 | type_id = 675; | ||
892 | break; | ||
893 | case 0x9002: | ||
894 | PWC_INFO("Samsung SNC-35E (v3.0) USB webcam detected.\n"); | ||
895 | name = "Samsung MPC-C30"; | ||
896 | type_id = 740; | ||
897 | break; | ||
898 | default: | ||
899 | return -ENODEV; | ||
900 | break; | ||
901 | } | ||
902 | } | ||
903 | else if (vendor_id == 0x041e) { | ||
904 | switch(product_id) { | ||
905 | case 0x400c: | ||
906 | PWC_INFO("Creative Labs Webcam 5 detected.\n"); | ||
907 | name = "Creative Labs Webcam 5"; | ||
908 | type_id = 730; | ||
909 | if (my_power_save == -1) | ||
910 | my_power_save = 1; | ||
911 | break; | ||
912 | case 0x4011: | ||
913 | PWC_INFO("Creative Labs Webcam Pro Ex detected.\n"); | ||
914 | name = "Creative Labs Webcam Pro Ex"; | ||
915 | type_id = 740; | ||
916 | break; | ||
917 | default: | ||
918 | return -ENODEV; | ||
919 | break; | ||
920 | } | ||
921 | } | ||
922 | else if (vendor_id == 0x04cc) { | ||
923 | switch(product_id) { | ||
924 | case 0x8116: | ||
925 | PWC_INFO("Sotec Afina Eye USB webcam detected.\n"); | ||
926 | name = "Sotec Afina Eye"; | ||
927 | type_id = 730; | ||
928 | break; | ||
929 | default: | ||
930 | return -ENODEV; | ||
931 | break; | ||
932 | } | ||
933 | } | ||
934 | else if (vendor_id == 0x06be) { | ||
935 | switch(product_id) { | ||
936 | case 0x8116: | ||
937 | /* This is essentially the same cam as the Sotec Afina Eye */ | ||
938 | PWC_INFO("AME Co. Afina Eye USB webcam detected.\n"); | ||
939 | name = "AME Co. Afina Eye"; | ||
940 | type_id = 750; | ||
941 | break; | ||
942 | default: | ||
943 | return -ENODEV; | ||
944 | break; | ||
945 | } | ||
946 | |||
947 | } | ||
948 | else if (vendor_id == 0x0d81) { | ||
949 | switch(product_id) { | ||
950 | case 0x1900: | ||
951 | PWC_INFO("Visionite VCS-UC300 USB webcam detected.\n"); | ||
952 | name = "Visionite VCS-UC300"; | ||
953 | type_id = 740; /* CCD sensor */ | ||
954 | break; | ||
955 | case 0x1910: | ||
956 | PWC_INFO("Visionite VCS-UM100 USB webcam detected.\n"); | ||
957 | name = "Visionite VCS-UM100"; | ||
958 | type_id = 730; /* CMOS sensor */ | ||
959 | break; | ||
960 | default: | ||
961 | return -ENODEV; | ||
962 | break; | ||
963 | } | ||
964 | } | ||
965 | else | ||
966 | return -ENODEV; /* Not any of the know types; but the list keeps growing. */ | ||
967 | |||
968 | if (my_power_save == -1) | ||
969 | my_power_save = 0; | ||
970 | |||
971 | memset(serial_number, 0, 30); | ||
972 | usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29); | ||
973 | PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number); | ||
974 | |||
975 | if (udev->descriptor.bNumConfigurations > 1) | ||
976 | PWC_WARNING("Warning: more than 1 configuration available.\n"); | ||
977 | |||
978 | /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */ | ||
979 | pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL); | ||
980 | if (pdev == NULL) { | ||
981 | PWC_ERROR("Oops, could not allocate memory for pwc_device.\n"); | ||
982 | return -ENOMEM; | ||
983 | } | ||
984 | pdev->type = type_id; | ||
985 | pdev->features = features; | ||
986 | pwc_construct(pdev); /* set min/max sizes correct */ | ||
987 | |||
988 | mutex_init(&pdev->v4l2_lock); | ||
989 | mutex_init(&pdev->vb_queue_lock); | ||
990 | spin_lock_init(&pdev->queued_bufs_lock); | ||
991 | INIT_LIST_HEAD(&pdev->queued_bufs); | ||
992 | |||
993 | pdev->udev = udev; | ||
994 | pdev->power_save = my_power_save; | ||
995 | |||
996 | /* Init videobuf2 queue structure */ | ||
997 | memset(&pdev->vb_queue, 0, sizeof(pdev->vb_queue)); | ||
998 | pdev->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
999 | pdev->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; | ||
1000 | pdev->vb_queue.drv_priv = pdev; | ||
1001 | pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf); | ||
1002 | pdev->vb_queue.ops = &pwc_vb_queue_ops; | ||
1003 | pdev->vb_queue.mem_ops = &vb2_vmalloc_memops; | ||
1004 | vb2_queue_init(&pdev->vb_queue); | ||
1005 | |||
1006 | /* Init video_device structure */ | ||
1007 | memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template)); | ||
1008 | strcpy(pdev->vdev.name, name); | ||
1009 | pdev->vdev.queue = &pdev->vb_queue; | ||
1010 | pdev->vdev.queue->lock = &pdev->vb_queue_lock; | ||
1011 | set_bit(V4L2_FL_USE_FH_PRIO, &pdev->vdev.flags); | ||
1012 | video_set_drvdata(&pdev->vdev, pdev); | ||
1013 | |||
1014 | pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); | ||
1015 | PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); | ||
1016 | |||
1017 | /* Allocate USB command buffers */ | ||
1018 | pdev->ctrl_buf = kmalloc(sizeof(pdev->cmd_buf), GFP_KERNEL); | ||
1019 | if (!pdev->ctrl_buf) { | ||
1020 | PWC_ERROR("Oops, could not allocate memory for pwc_device.\n"); | ||
1021 | rc = -ENOMEM; | ||
1022 | goto err_free_mem; | ||
1023 | } | ||
1024 | |||
1025 | #ifdef CONFIG_USB_PWC_DEBUG | ||
1026 | /* Query sensor type */ | ||
1027 | if (pwc_get_cmos_sensor(pdev, &rc) >= 0) { | ||
1028 | PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n", | ||
1029 | pdev->vdev.name, | ||
1030 | pwc_sensor_type_to_string(rc), rc); | ||
1031 | } | ||
1032 | #endif | ||
1033 | |||
1034 | /* Set the leds off */ | ||
1035 | pwc_set_leds(pdev, 0, 0); | ||
1036 | |||
1037 | /* Setup intial videomode */ | ||
1038 | rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, | ||
1039 | V4L2_PIX_FMT_YUV420, 30, &compression, 1); | ||
1040 | if (rc) | ||
1041 | goto err_free_mem; | ||
1042 | |||
1043 | /* Register controls (and read default values from camera */ | ||
1044 | rc = pwc_init_controls(pdev); | ||
1045 | if (rc) { | ||
1046 | PWC_ERROR("Failed to register v4l2 controls (%d).\n", rc); | ||
1047 | goto err_free_mem; | ||
1048 | } | ||
1049 | |||
1050 | /* And powerdown the camera until streaming starts */ | ||
1051 | pwc_camera_power(pdev, 0); | ||
1052 | |||
1053 | /* Register the v4l2_device structure */ | ||
1054 | pdev->v4l2_dev.release = pwc_video_release; | ||
1055 | rc = v4l2_device_register(&intf->dev, &pdev->v4l2_dev); | ||
1056 | if (rc) { | ||
1057 | PWC_ERROR("Failed to register v4l2-device (%d).\n", rc); | ||
1058 | goto err_free_controls; | ||
1059 | } | ||
1060 | |||
1061 | pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler; | ||
1062 | pdev->vdev.v4l2_dev = &pdev->v4l2_dev; | ||
1063 | pdev->vdev.lock = &pdev->v4l2_lock; | ||
1064 | |||
1065 | rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1); | ||
1066 | if (rc < 0) { | ||
1067 | PWC_ERROR("Failed to register as video device (%d).\n", rc); | ||
1068 | goto err_unregister_v4l2_dev; | ||
1069 | } | ||
1070 | PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev)); | ||
1071 | |||
1072 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | ||
1073 | /* register webcam snapshot button input device */ | ||
1074 | pdev->button_dev = input_allocate_device(); | ||
1075 | if (!pdev->button_dev) { | ||
1076 | PWC_ERROR("Err, insufficient memory for webcam snapshot button device."); | ||
1077 | rc = -ENOMEM; | ||
1078 | goto err_video_unreg; | ||
1079 | } | ||
1080 | |||
1081 | usb_make_path(udev, pdev->button_phys, sizeof(pdev->button_phys)); | ||
1082 | strlcat(pdev->button_phys, "/input0", sizeof(pdev->button_phys)); | ||
1083 | |||
1084 | pdev->button_dev->name = "PWC snapshot button"; | ||
1085 | pdev->button_dev->phys = pdev->button_phys; | ||
1086 | usb_to_input_id(pdev->udev, &pdev->button_dev->id); | ||
1087 | pdev->button_dev->dev.parent = &pdev->udev->dev; | ||
1088 | pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
1089 | pdev->button_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA); | ||
1090 | |||
1091 | rc = input_register_device(pdev->button_dev); | ||
1092 | if (rc) { | ||
1093 | input_free_device(pdev->button_dev); | ||
1094 | pdev->button_dev = NULL; | ||
1095 | goto err_video_unreg; | ||
1096 | } | ||
1097 | #endif | ||
1098 | |||
1099 | return 0; | ||
1100 | |||
1101 | err_video_unreg: | ||
1102 | video_unregister_device(&pdev->vdev); | ||
1103 | err_unregister_v4l2_dev: | ||
1104 | v4l2_device_unregister(&pdev->v4l2_dev); | ||
1105 | err_free_controls: | ||
1106 | v4l2_ctrl_handler_free(&pdev->ctrl_handler); | ||
1107 | err_free_mem: | ||
1108 | kfree(pdev->ctrl_buf); | ||
1109 | kfree(pdev); | ||
1110 | return rc; | ||
1111 | } | ||
1112 | |||
1113 | /* The user yanked out the cable... */ | ||
1114 | static void usb_pwc_disconnect(struct usb_interface *intf) | ||
1115 | { | ||
1116 | struct v4l2_device *v = usb_get_intfdata(intf); | ||
1117 | struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev); | ||
1118 | |||
1119 | mutex_lock(&pdev->vb_queue_lock); | ||
1120 | mutex_lock(&pdev->v4l2_lock); | ||
1121 | /* No need to keep the urbs around after disconnection */ | ||
1122 | if (pdev->vb_queue.streaming) | ||
1123 | pwc_isoc_cleanup(pdev); | ||
1124 | pdev->udev = NULL; | ||
1125 | pwc_cleanup_queued_bufs(pdev); | ||
1126 | |||
1127 | v4l2_device_disconnect(&pdev->v4l2_dev); | ||
1128 | video_unregister_device(&pdev->vdev); | ||
1129 | mutex_unlock(&pdev->v4l2_lock); | ||
1130 | mutex_unlock(pdev->vb_queue.lock); | ||
1131 | |||
1132 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | ||
1133 | if (pdev->button_dev) | ||
1134 | input_unregister_device(pdev->button_dev); | ||
1135 | #endif | ||
1136 | |||
1137 | v4l2_device_put(&pdev->v4l2_dev); | ||
1138 | } | ||
1139 | |||
1140 | |||
1141 | /* | ||
1142 | * Initialization code & module stuff | ||
1143 | */ | ||
1144 | |||
1145 | static unsigned int leds_nargs; | ||
1146 | |||
1147 | #ifdef CONFIG_USB_PWC_DEBUG | ||
1148 | module_param_named(trace, pwc_trace, int, 0644); | ||
1149 | #endif | ||
1150 | module_param(power_save, int, 0644); | ||
1151 | module_param_array(leds, int, &leds_nargs, 0444); | ||
1152 | |||
1153 | #ifdef CONFIG_USB_PWC_DEBUG | ||
1154 | MODULE_PARM_DESC(trace, "For debugging purposes"); | ||
1155 | #endif | ||
1156 | MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off"); | ||
1157 | MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); | ||
1158 | |||
1159 | MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); | ||
1160 | MODULE_AUTHOR("Luc Saillard <luc@saillard.org>"); | ||
1161 | MODULE_LICENSE("GPL"); | ||
1162 | MODULE_ALIAS("pwcx"); | ||
1163 | MODULE_VERSION( PWC_VERSION ); | ||
1164 | |||
1165 | module_usb_driver(pwc_driver); | ||