blob: 4e94197094ad1b39a2fa7f55c60d33d8b88957a9 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* Linux driver for Philips webcam
2 USB and Video4Linux interface part.
3 (C) 1999-2004 Nemosoft Unv.
Luc Saillard2b455db2006-04-24 10:29:46 -03004 (C) 2004-2006 Luc Saillard (luc@saillard.org)
Hans de Goede6eba9352011-06-26 06:49:59 -03005 (C) 2011 Hans de Goede <hdegoede@redhat.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -07006
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
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -030029/*
Linus Torvalds1da177e2005-04-16 15:20:36 -070030 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
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -030033 is thus not distributed in source form. The binary pwcx.o module
Linus Torvalds1da177e2005-04-16 15:20:36 -070034 contains the code that falls under the NDA.
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -030035
36 In case you're wondering: 'pwc' stands for "Philips WebCam", but
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 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).
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -030040
Linus Torvalds1da177e2005-04-16 15:20:36 -070041 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 *
Hans de Goede9a7b2d12011-06-06 14:43:39 -030044 vdev: struct video_device (member of pwc_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 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
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -030057 - Pham Thanh Nam: webcam snapshot button as an event input device
Linus Torvalds1da177e2005-04-16 15:20:36 -070058*/
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>
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -030066#ifdef CONFIG_USB_PWC_INPUT_EVDEV
67#include <linux/usb/input.h>
68#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070069#include <linux/vmalloc.h>
70#include <asm/io.h>
Andy Shevchenko2d8d7762009-09-24 07:58:09 -030071#include <linux/kernel.h> /* simple_strtol() */
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
73#include "pwc.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070074#include "pwc-kiara.h"
75#include "pwc-timon.h"
Luc Saillard2b455db2006-04-24 10:29:46 -030076#include "pwc-dec23.h"
77#include "pwc-dec1.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070078
Matwey V. Kornilovc1d5fb02018-11-09 14:03:26 -050079#define CREATE_TRACE_POINTS
80#include <trace/events/pwc.h>
81
Linus Torvalds1da177e2005-04-16 15:20:36 -070082/* Function prototypes and driver templates */
83
84/* hotplug device table support */
Luc Saillard2b455db2006-04-24 10:29:46 -030085static const struct usb_device_id pwc_device_table [] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */
87 { USB_DEVICE(0x0471, 0x0303) },
88 { USB_DEVICE(0x0471, 0x0304) },
89 { USB_DEVICE(0x0471, 0x0307) },
90 { USB_DEVICE(0x0471, 0x0308) },
91 { USB_DEVICE(0x0471, 0x030C) },
92 { USB_DEVICE(0x0471, 0x0310) },
Luc Saillard2b455db2006-04-24 10:29:46 -030093 { USB_DEVICE(0x0471, 0x0311) }, /* Philips ToUcam PRO II */
Linus Torvalds1da177e2005-04-16 15:20:36 -070094 { USB_DEVICE(0x0471, 0x0312) },
95 { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
Luc Saillard2b455db2006-04-24 10:29:46 -030096 { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */
Hans de Goede7445e452016-01-22 08:53:55 -020097 { USB_DEVICE(0x0471, 0x032C) }, /* Philips SPC 880NC PC Camera */
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 { USB_DEVICE(0x069A, 0x0001) }, /* Askey */
99 { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
100 { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
101 { USB_DEVICE(0x046D, 0x08B2) }, /* Logitech QuickCam Pro 4000 */
102 { USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */
103 { USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */
104 { USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */
Mauro Carvalho Chehab6b1ce3c2007-03-21 16:35:28 -0300105 { USB_DEVICE(0x046D, 0x08B6) }, /* Cisco VT Camera */
106 { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech ViewPort AV 100 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */
Luc Saillard2b455db2006-04-24 10:29:46 -0300108 { USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */
109 { USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */
110 { USB_DEVICE(0x055D, 0x9002) }, /* Samsung SNC-35E (Ver3.0) */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */
112 { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */
113 { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */
114 { USB_DEVICE(0x06BE, 0x8116) }, /* new Afina Eye */
115 { USB_DEVICE(0x0d81, 0x1910) }, /* Visionite */
116 { USB_DEVICE(0x0d81, 0x1900) },
117 { }
118};
119MODULE_DEVICE_TABLE(usb, pwc_device_table);
120
121static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id);
122static void usb_pwc_disconnect(struct usb_interface *intf);
Hans de Goede885fe182011-06-06 15:33:44 -0300123static void pwc_isoc_cleanup(struct pwc_device *pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124
125static struct usb_driver pwc_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 .name = "Philips webcam", /* name */
127 .id_table = pwc_device_table,
128 .probe = usb_pwc_probe, /* probe() */
129 .disconnect = usb_pwc_disconnect, /* disconnect() */
130};
131
132#define MAX_DEV_HINTS 20
133#define MAX_ISOC_ERRORS 20
134
Trent Piepho05ad3902007-01-30 23:26:01 -0300135#ifdef CONFIG_USB_PWC_DEBUG
Michael Krufkyb930e1d2007-08-27 18:16:54 -0300136 int pwc_trace = PWC_DEBUG_LEVEL;
Luc Saillard2b455db2006-04-24 10:29:46 -0300137#endif
Hans de Goede3b4d0ec2011-06-26 03:51:19 -0300138static int power_save = -1;
Hans de Goedec24e1372012-01-10 17:51:12 -0300139static int leds[2] = { 100, 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140
141/***/
142
Hans Verkuilbec43662008-12-30 06:58:20 -0300143static const struct v4l2_file_operations pwc_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 .owner = THIS_MODULE,
Hans de Goede76ae8532011-07-19 07:14:22 -0300145 .open = v4l2_fh_open,
Hans Verkuil2e43dec2012-07-02 05:51:58 -0300146 .release = vb2_fop_release,
147 .read = vb2_fop_read,
148 .poll = vb2_fop_poll,
149 .mmap = vb2_fop_mmap,
Hans Verkuilafa38522011-01-22 06:34:55 -0300150 .unlocked_ioctl = video_ioctl2,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151};
Bhumika Goyal86844942017-08-26 09:11:30 -0400152static const struct video_device pwc_template = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153 .name = "Philips Webcam", /* Filled in later */
Hans de Goede76ae8532011-07-19 07:14:22 -0300154 .release = video_device_release_empty,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 .fops = &pwc_fops,
Hans de Goede9a7b2d12011-06-06 14:43:39 -0300156 .ioctl_ops = &pwc_ioctl_ops,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157};
158
159/***************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160/* Private functions */
161
Matwey V. Kornilov1161db62018-11-09 14:03:27 -0500162static void *pwc_alloc_urb_buffer(struct device *dev,
163 size_t size, dma_addr_t *dma_handle)
164{
165 void *buffer = kmalloc(size, GFP_KERNEL);
166
167 if (!buffer)
168 return NULL;
169
170 *dma_handle = dma_map_single(dev, buffer, size, DMA_FROM_DEVICE);
171 if (dma_mapping_error(dev, *dma_handle)) {
172 kfree(buffer);
173 return NULL;
174 }
175
176 return buffer;
177}
178
179static void pwc_free_urb_buffer(struct device *dev,
180 size_t size,
181 void *buffer,
182 dma_addr_t dma_handle)
183{
184 dma_unmap_single(dev, dma_handle, size, DMA_FROM_DEVICE);
185 kfree(buffer);
186}
187
Mauro Carvalho Chehab0dc6eb92012-10-27 14:26:35 -0300188static struct pwc_frame_buf *pwc_get_next_fill_buf(struct pwc_device *pdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189{
Hans de Goede885fe182011-06-06 15:33:44 -0300190 unsigned long flags = 0;
191 struct pwc_frame_buf *buf = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192
Hans de Goede885fe182011-06-06 15:33:44 -0300193 spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
194 if (list_empty(&pdev->queued_bufs))
195 goto leave;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
Hans de Goede885fe182011-06-06 15:33:44 -0300197 buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf, list);
198 list_del(&buf->list);
199leave:
200 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
201 return buf;
Luc Saillard2b455db2006-04-24 10:29:46 -0300202}
203
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -0300204static void pwc_snapshot_button(struct pwc_device *pdev, int down)
205{
206 if (down) {
207 PWC_TRACE("Snapshot button pressed.\n");
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -0300208 } else {
209 PWC_TRACE("Snapshot button released.\n");
210 }
211
212#ifdef CONFIG_USB_PWC_INPUT_EVDEV
213 if (pdev->button_dev) {
Lennart Poetteringbcd3e4b2009-06-11 11:19:33 -0300214 input_report_key(pdev->button_dev, KEY_CAMERA, down);
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -0300215 input_sync(pdev->button_dev);
216 }
217#endif
218}
219
Hans de Goede885fe182011-06-06 15:33:44 -0300220static void pwc_frame_complete(struct pwc_device *pdev)
Luc Saillard2b455db2006-04-24 10:29:46 -0300221{
Hans de Goede885fe182011-06-06 15:33:44 -0300222 struct pwc_frame_buf *fbuf = pdev->fill_buf;
Luc Saillard2b455db2006-04-24 10:29:46 -0300223
224 /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus
225 frames on the USB wire after an exposure change. This conditition is
226 however detected in the cam and a bit is set in the header.
227 */
228 if (pdev->type == 730) {
229 unsigned char *ptr = (unsigned char *)fbuf->data;
230
231 if (ptr[1] == 1 && ptr[0] & 0x10) {
232 PWC_TRACE("Hyundai CMOS sensor bug. Dropping frame.\n");
233 pdev->drop_frames += 2;
Luc Saillard2b455db2006-04-24 10:29:46 -0300234 }
235 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -0300236 pwc_snapshot_button(pdev, ptr[0] & 0x01);
Luc Saillard2b455db2006-04-24 10:29:46 -0300237 }
238 if ((ptr[0] ^ pdev->vmirror) & 0x02) {
239 if (ptr[0] & 0x02)
240 PWC_TRACE("Image is mirrored.\n");
241 else
242 PWC_TRACE("Image is normal.\n");
243 }
244 pdev->vmirror = ptr[0] & 0x03;
245 /* Sometimes the trailer of the 730 is still sent as a 4 byte packet
246 after a short frame; this condition is filtered out specifically. A 4 byte
247 frame doesn't make sense anyway.
248 So we get either this sequence:
249 drop_bit set -> 4 byte frame -> short frame -> good frame
250 Or this one:
251 drop_bit set -> short frame -> good frame
252 So we drop either 3 or 2 frames in all!
253 */
254 if (fbuf->filled == 4)
255 pdev->drop_frames++;
Hans de Goede885fe182011-06-06 15:33:44 -0300256 } else if (pdev->type == 740 || pdev->type == 720) {
Luc Saillard2b455db2006-04-24 10:29:46 -0300257 unsigned char *ptr = (unsigned char *)fbuf->data;
258 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -0300259 pwc_snapshot_button(pdev, ptr[0] & 0x01);
Luc Saillard2b455db2006-04-24 10:29:46 -0300260 }
261 pdev->vmirror = ptr[0] & 0x03;
262 }
263
Hans de Goede885fe182011-06-06 15:33:44 -0300264 /* In case we were instructed to drop the frame, do so silently. */
265 if (pdev->drop_frames > 0) {
Luc Saillard2b455db2006-04-24 10:29:46 -0300266 pdev->drop_frames--;
Hans de Goede885fe182011-06-06 15:33:44 -0300267 } else {
Luc Saillard2b455db2006-04-24 10:29:46 -0300268 /* Check for underflow first */
269 if (fbuf->filled < pdev->frame_total_size) {
Mauro Carvalho Chehabc91e42f2016-10-18 17:44:18 -0200270 PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes); discarded.\n",
271 fbuf->filled);
Hans de Goede885fe182011-06-06 15:33:44 -0300272 } else {
Junghak Sung2d700712015-09-22 10:30:30 -0300273 fbuf->vb.field = V4L2_FIELD_NONE;
274 fbuf->vb.sequence = pdev->vframe_count;
275 vb2_buffer_done(&fbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
Hans de Goede885fe182011-06-06 15:33:44 -0300276 pdev->fill_buf = NULL;
277 pdev->vsync = 0;
Luc Saillard2b455db2006-04-24 10:29:46 -0300278 }
279 } /* !drop_frames */
280 pdev->vframe_count++;
Luc Saillard2b455db2006-04-24 10:29:46 -0300281}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282
283/* This gets called for the Isochronous pipe (video). This is done in
284 * interrupt time, so it has to be fast, not crash, and not stall. Neat.
285 */
David Howells7d12e782006-10-05 14:55:46 +0100286static void pwc_isoc_handler(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287{
Hans de Goede885fe182011-06-06 15:33:44 -0300288 struct pwc_device *pdev = (struct pwc_device *)urb->context;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289 int i, fst, flen;
Hans de Goede885fe182011-06-06 15:33:44 -0300290 unsigned char *iso_buf = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291
Matwey V. Kornilovc1d5fb02018-11-09 14:03:26 -0500292 trace_pwc_handler_enter(urb, pdev);
293
Hans de Goede885fe182011-06-06 15:33:44 -0300294 if (urb->status == -ENOENT || urb->status == -ECONNRESET ||
295 urb->status == -ESHUTDOWN) {
Colin Ian Kingb436e262017-11-02 06:11:53 -0400296 PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronously.\n",
297 urb, urb->status == -ENOENT ? "" : "a");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 return;
299 }
Hans de Goede885fe182011-06-06 15:33:44 -0300300
301 if (pdev->fill_buf == NULL)
302 pdev->fill_buf = pwc_get_next_fill_buf(pdev);
303
304 if (urb->status != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 const char *errmsg;
306
307 errmsg = "Unknown";
308 switch(urb->status) {
309 case -ENOSR: errmsg = "Buffer error (overrun)"; break;
310 case -EPIPE: errmsg = "Stalled (device not responding)"; break;
311 case -EOVERFLOW: errmsg = "Babble (bad cable?)"; break;
312 case -EPROTO: errmsg = "Bit-stuff error (bad cable?)"; break;
313 case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break;
Pete Zaitcev38e2bfc2006-09-18 22:49:02 -0700314 case -ETIME: errmsg = "Device does not respond"; break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 }
Hans de Goede885fe182011-06-06 15:33:44 -0300316 PWC_ERROR("pwc_isoc_handler() called with status %d [%s].\n",
317 urb->status, errmsg);
318 /* Give up after a number of contiguous errors */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 if (++pdev->visoc_errors > MAX_ISOC_ERRORS)
320 {
Hans de Goede885fe182011-06-06 15:33:44 -0300321 PWC_ERROR("Too many ISOC errors, bailing out.\n");
322 if (pdev->fill_buf) {
Junghak Sung2d700712015-09-22 10:30:30 -0300323 vb2_buffer_done(&pdev->fill_buf->vb.vb2_buf,
Hans de Goede885fe182011-06-06 15:33:44 -0300324 VB2_BUF_STATE_ERROR);
325 pdev->fill_buf = NULL;
326 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327 }
Hans de Goede885fe182011-06-06 15:33:44 -0300328 pdev->vsync = 0; /* Drop the current frame */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 goto handler_end;
330 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331
332 /* Reset ISOC error counter. We did get here, after all. */
333 pdev->visoc_errors = 0;
334
Matwey V. Kornilov1161db62018-11-09 14:03:27 -0500335 dma_sync_single_for_cpu(&urb->dev->dev,
336 urb->transfer_dma,
337 urb->transfer_buffer_length,
338 DMA_FROM_DEVICE);
339
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 /* vsync: 0 = don't copy data
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300341 1 = sync-hunt
342 2 = synched
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343 */
344 /* Compact data */
345 for (i = 0; i < urb->number_of_packets; i++) {
346 fst = urb->iso_frame_desc[i].status;
347 flen = urb->iso_frame_desc[i].actual_length;
348 iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
Hans de Goede885fe182011-06-06 15:33:44 -0300349 if (fst != 0) {
350 PWC_ERROR("Iso frame %d has error %d\n", i, fst);
351 continue;
352 }
353 if (flen > 0 && pdev->vsync) {
354 struct pwc_frame_buf *fbuf = pdev->fill_buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355
Hans de Goede885fe182011-06-06 15:33:44 -0300356 if (pdev->vsync == 1) {
Junghak Sungd6dd6452015-11-03 08:16:37 -0200357 fbuf->vb.vb2_buf.timestamp = ktime_get_ns();
Hans de Goede885fe182011-06-06 15:33:44 -0300358 pdev->vsync = 2;
Luc Saillard2b455db2006-04-24 10:29:46 -0300359 }
360
Hans de Goede885fe182011-06-06 15:33:44 -0300361 if (flen + fbuf->filled > pdev->frame_total_size) {
362 PWC_ERROR("Frame overflow (%d > %d)\n",
363 flen + fbuf->filled,
364 pdev->frame_total_size);
365 pdev->vsync = 0; /* Let's wait for an EOF */
366 } else {
367 memcpy(fbuf->data + fbuf->filled, iso_buf,
368 flen);
369 fbuf->filled += flen;
370 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 }
Hans de Goede885fe182011-06-06 15:33:44 -0300372 if (flen < pdev->vlast_packet_size) {
373 /* Shorter packet... end of frame */
374 if (pdev->vsync == 2)
375 pwc_frame_complete(pdev);
376 if (pdev->fill_buf == NULL)
377 pdev->fill_buf = pwc_get_next_fill_buf(pdev);
378 if (pdev->fill_buf) {
379 pdev->fill_buf->filled = 0;
380 pdev->vsync = 1;
381 }
382 }
383 pdev->vlast_packet_size = flen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 }
385
Matwey V. Kornilov1161db62018-11-09 14:03:27 -0500386 dma_sync_single_for_device(&urb->dev->dev,
387 urb->transfer_dma,
388 urb->transfer_buffer_length,
389 DMA_FROM_DEVICE);
390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391handler_end:
Matwey V. Kornilovc1d5fb02018-11-09 14:03:26 -0500392 trace_pwc_handler_exit(urb, pdev);
393
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 i = usb_submit_urb(urb, GFP_ATOMIC);
395 if (i != 0)
Luc Saillard2b455db2006-04-24 10:29:46 -0300396 PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397}
398
Hans de Goedeceede9f2012-05-09 04:43:12 -0300399/* Both v4l2_lock and vb_queue_lock should be locked when calling this */
Hans de Goede885fe182011-06-06 15:33:44 -0300400static int pwc_isoc_init(struct pwc_device *pdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401{
402 struct usb_device *udev;
403 struct urb *urb;
404 int i, j, ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 struct usb_interface *intf;
406 struct usb_host_interface *idesc = NULL;
Hans de Goede5bbe18d2012-01-04 18:48:05 -0300407 int compression = 0; /* 0..3 = uncompressed..high */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 pdev->vsync = 0;
Hans de Goede6eba9352011-06-26 06:49:59 -0300410 pdev->vlast_packet_size = 0;
Hans de Goede885fe182011-06-06 15:33:44 -0300411 pdev->fill_buf = NULL;
412 pdev->vframe_count = 0;
Hans de Goede6eba9352011-06-26 06:49:59 -0300413 pdev->visoc_errors = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 udev = pdev->udev;
415
Hans de Goede5bbe18d2012-01-04 18:48:05 -0300416retry:
417 /* We first try with low compression and then retry with a higher
418 compression setting if there is not enough bandwidth. */
Hans de Goede938d5b92012-01-10 13:14:46 -0300419 ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt,
420 pdev->vframes, &compression, 1);
Hans de Goede5bbe18d2012-01-04 18:48:05 -0300421
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 /* Get the current alternate interface, adjust packet size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 intf = usb_ifnum_to_if(udev, 0);
424 if (intf)
425 idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 if (!idesc)
Hans de Goedec2464122011-06-06 15:25:18 -0300427 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428
429 /* Search video endpoint */
430 pdev->vmax_packet_size = -1;
Luc Saillard2b455db2006-04-24 10:29:46 -0300431 for (i = 0; i < idesc->desc.bNumEndpoints; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) {
433 pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize);
434 break;
435 }
Luc Saillard2b455db2006-04-24 10:29:46 -0300436 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300437
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
Luc Saillard2b455db2006-04-24 10:29:46 -0300439 PWC_ERROR("Failed to find packet size for video endpoint in current alternate setting.\n");
Steven Cole093cf722005-05-03 19:07:24 -0600440 return -ENFILE; /* Odd error, that should be noticeable */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 }
442
443 /* Set alternate interface */
Luc Saillard2b455db2006-04-24 10:29:46 -0300444 PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 ret = usb_set_interface(pdev->udev, 0, pdev->valternate);
Hans de Goede5bbe18d2012-01-04 18:48:05 -0300446 if (ret == -ENOSPC && compression < 3) {
447 compression++;
448 goto retry;
449 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 if (ret < 0)
451 return ret;
452
Hans de Goede04613c52011-06-26 13:57:15 -0300453 /* Allocate and init Isochronuous urbs */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454 for (i = 0; i < MAX_ISO_BUFS; i++) {
455 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
456 if (urb == NULL) {
Hans de Goede6eba9352011-06-26 06:49:59 -0300457 pwc_isoc_cleanup(pdev);
458 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 }
Hans de Goede04613c52011-06-26 13:57:15 -0300460 pdev->urbs[i] = urb;
Luc Saillard2b455db2006-04-24 10:29:46 -0300461 PWC_DEBUG_MEMORY("Allocated URB at 0x%p\n", urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462
463 urb->interval = 1; // devik
464 urb->dev = udev;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300465 urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint);
Hans de Goede04613c52011-06-26 13:57:15 -0300466 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
Matwey V. Kornilov1161db62018-11-09 14:03:27 -0500467 urb->transfer_buffer_length = ISO_BUFFER_SIZE;
468 urb->transfer_buffer = pwc_alloc_urb_buffer(&udev->dev,
469 urb->transfer_buffer_length,
470 &urb->transfer_dma);
Hans de Goede04613c52011-06-26 13:57:15 -0300471 if (urb->transfer_buffer == NULL) {
472 PWC_ERROR("Failed to allocate urb buffer %d\n", i);
Hans de Goede04613c52011-06-26 13:57:15 -0300473 pwc_isoc_cleanup(pdev);
474 return -ENOMEM;
475 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300476 urb->complete = pwc_isoc_handler;
477 urb->context = pdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 urb->start_frame = 0;
479 urb->number_of_packets = ISO_FRAMES_PER_DESC;
480 for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
481 urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE;
482 urb->iso_frame_desc[j].length = pdev->vmax_packet_size;
483 }
484 }
485
486 /* link */
487 for (i = 0; i < MAX_ISO_BUFS; i++) {
Hans de Goede04613c52011-06-26 13:57:15 -0300488 ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL);
Hans de Goede5bbe18d2012-01-04 18:48:05 -0300489 if (ret == -ENOSPC && compression < 3) {
490 compression++;
Hans de Goede5bbe18d2012-01-04 18:48:05 -0300491 pwc_isoc_cleanup(pdev);
492 goto retry;
493 }
Hans de Goede622d9f52010-11-16 12:32:09 -0300494 if (ret) {
Luc Saillard2b455db2006-04-24 10:29:46 -0300495 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
Hans de Goede622d9f52010-11-16 12:32:09 -0300496 pwc_isoc_cleanup(pdev);
497 return ret;
498 }
Hans de Goede04613c52011-06-26 13:57:15 -0300499 PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->urbs[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 }
501
502 /* All is done... */
Luc Saillard2b455db2006-04-24 10:29:46 -0300503 PWC_DEBUG_OPEN("<< pwc_isoc_init()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 return 0;
505}
506
Oliver Neukum0b67f5c2007-09-26 10:19:01 -0300507static void pwc_iso_stop(struct pwc_device *pdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508{
509 int i;
510
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 /* Unlinking ISOC buffers one by one */
512 for (i = 0; i < MAX_ISO_BUFS; i++) {
Hans de Goede04613c52011-06-26 13:57:15 -0300513 if (pdev->urbs[i]) {
514 PWC_DEBUG_MEMORY("Unlinking URB %p\n", pdev->urbs[i]);
515 usb_kill_urb(pdev->urbs[i]);
Oliver Neukum0b67f5c2007-09-26 10:19:01 -0300516 }
517 }
518}
519
520static void pwc_iso_free(struct pwc_device *pdev)
521{
522 int i;
523
524 /* Freeing ISOC buffers one by one */
525 for (i = 0; i < MAX_ISO_BUFS; i++) {
Matwey V. Kornilov1161db62018-11-09 14:03:27 -0500526 struct urb *urb = pdev->urbs[i];
527
528 if (urb) {
Luc Saillard2b455db2006-04-24 10:29:46 -0300529 PWC_DEBUG_MEMORY("Freeing URB\n");
Matwey V. Kornilov1161db62018-11-09 14:03:27 -0500530 if (urb->transfer_buffer)
531 pwc_free_urb_buffer(&urb->dev->dev,
532 urb->transfer_buffer_length,
533 urb->transfer_buffer,
534 urb->transfer_dma);
535 usb_free_urb(urb);
Hans de Goede04613c52011-06-26 13:57:15 -0300536 pdev->urbs[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 }
538 }
Oliver Neukum0b67f5c2007-09-26 10:19:01 -0300539}
540
Hans de Goedeceede9f2012-05-09 04:43:12 -0300541/* Both v4l2_lock and vb_queue_lock should be locked when calling this */
Hans de Goede885fe182011-06-06 15:33:44 -0300542static void pwc_isoc_cleanup(struct pwc_device *pdev)
Oliver Neukum0b67f5c2007-09-26 10:19:01 -0300543{
544 PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n");
Hans de Goedec2464122011-06-06 15:25:18 -0300545
Oliver Neukum0b67f5c2007-09-26 10:19:01 -0300546 pwc_iso_stop(pdev);
547 pwc_iso_free(pdev);
Hans de Goedeb824bb42011-06-25 17:39:19 -0300548 usb_set_interface(pdev->udev, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
Luc Saillard2b455db2006-04-24 10:29:46 -0300550 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551}
552
Hans de Goedeceede9f2012-05-09 04:43:12 -0300553/* Must be called with vb_queue_lock hold */
Hans Verkuil80b09632014-08-04 07:29:59 -0300554static void pwc_cleanup_queued_bufs(struct pwc_device *pdev,
555 enum vb2_buffer_state state)
Hans de Goede885fe182011-06-06 15:33:44 -0300556{
Hans de Goedec20d78c2011-10-09 09:16:46 -0300557 unsigned long flags = 0;
558
559 spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
Hans de Goede885fe182011-06-06 15:33:44 -0300560 while (!list_empty(&pdev->queued_bufs)) {
561 struct pwc_frame_buf *buf;
562
563 buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf,
564 list);
565 list_del(&buf->list);
Junghak Sung2d700712015-09-22 10:30:30 -0300566 vb2_buffer_done(&buf->vb.vb2_buf, state);
Hans de Goede885fe182011-06-06 15:33:44 -0300567 }
Hans de Goedec20d78c2011-10-09 09:16:46 -0300568 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
Hans de Goede885fe182011-06-06 15:33:44 -0300569}
570
Trent Piepho05ad3902007-01-30 23:26:01 -0300571#ifdef CONFIG_USB_PWC_DEBUG
Luc Saillard2b455db2006-04-24 10:29:46 -0300572static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
573{
574 switch(sensor_type) {
575 case 0x00:
576 return "Hyundai CMOS sensor";
577 case 0x20:
578 return "Sony CCD sensor + TDA8787";
579 case 0x2E:
580 return "Sony CCD sensor + Exas 98L59";
581 case 0x2F:
582 return "Sony CCD sensor + ADI 9804";
583 case 0x30:
584 return "Sharp CCD sensor + TDA8787";
585 case 0x3E:
586 return "Sharp CCD sensor + Exas 98L59";
587 case 0x3F:
588 return "Sharp CCD sensor + ADI 9804";
589 case 0x40:
590 return "UPA 1021 sensor";
591 case 0x100:
592 return "VGA sensor";
593 case 0x101:
594 return "PAL MR sensor";
595 default:
Trent Piepho657de3c2006-06-20 00:30:57 -0300596 return "unknown type of sensor";
Luc Saillard2b455db2006-04-24 10:29:46 -0300597 }
598}
599#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
601/***************************************************************************/
602/* Video4Linux functions */
603
Hans de Goede76ae8532011-07-19 07:14:22 -0300604static void pwc_video_release(struct v4l2_device *v)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605{
Hans de Goede76ae8532011-07-19 07:14:22 -0300606 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
Dmitry Torokhov89dec012009-08-14 02:22:52 -0300607
Hans de Goede6c9cac82011-06-26 12:52:01 -0300608 v4l2_ctrl_handler_free(&pdev->ctrl_handler);
Hans de Goedeceede9f2012-05-09 04:43:12 -0300609 v4l2_device_unregister(&pdev->v4l2_dev);
Hans de Goede24be6892012-01-10 17:02:04 -0300610 kfree(pdev->ctrl_buf);
Dmitry Torokhov89dec012009-08-14 02:22:52 -0300611 kfree(pdev);
Oliver Neukum85237f22007-08-21 07:10:42 +0200612}
613
Hans de Goede885fe182011-06-06 15:33:44 -0300614/***************************************************************************/
615/* Videobuf2 operations */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616
Hans Verkuildf9ecb0c2015-10-28 00:50:37 -0200617static int queue_setup(struct vb2_queue *vq,
Guennadi Liakhovetskifc714e702011-08-24 10:30:21 -0300618 unsigned int *nbuffers, unsigned int *nplanes,
Hans Verkuil36c0f8b2016-04-15 09:15:05 -0300619 unsigned int sizes[], struct device *alloc_devs[])
Hans de Goede885fe182011-06-06 15:33:44 -0300620{
621 struct pwc_device *pdev = vb2_get_drv_priv(vq);
Hans de Goede795e6eb2012-01-04 16:58:44 -0300622 int size;
Luc Saillard2b455db2006-04-24 10:29:46 -0300623
Hans de Goede885fe182011-06-06 15:33:44 -0300624 if (*nbuffers < MIN_FRAMES)
625 *nbuffers = MIN_FRAMES;
626 else if (*nbuffers > MAX_FRAMES)
627 *nbuffers = MAX_FRAMES;
628
629 *nplanes = 1;
630
Hans de Goede795e6eb2012-01-04 16:58:44 -0300631 size = pwc_get_size(pdev, MAX_WIDTH, MAX_HEIGHT);
632 sizes[0] = PAGE_ALIGN(pwc_image_sizes[size][0] *
633 pwc_image_sizes[size][1] * 3 / 2);
Hans de Goede885fe182011-06-06 15:33:44 -0300634
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 return 0;
636}
637
Hans de Goede885fe182011-06-06 15:33:44 -0300638static int buffer_init(struct vb2_buffer *vb)
639{
Junghak Sung2d700712015-09-22 10:30:30 -0300640 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
641 struct pwc_frame_buf *buf =
642 container_of(vbuf, struct pwc_frame_buf, vb);
Hans de Goede885fe182011-06-06 15:33:44 -0300643
644 /* need vmalloc since frame buffer > 128K */
645 buf->data = vzalloc(PWC_FRAME_SIZE);
646 if (buf->data == NULL)
647 return -ENOMEM;
648
649 return 0;
650}
651
652static int buffer_prepare(struct vb2_buffer *vb)
653{
654 struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
655
Mauro Carvalho Chehab3e4d8f42019-02-18 14:29:03 -0500656 /* Don't allow queueing new buffers after device disconnection */
Hans de Goedeb824bb42011-06-25 17:39:19 -0300657 if (!pdev->udev)
658 return -ENODEV;
Hans de Goede885fe182011-06-06 15:33:44 -0300659
660 return 0;
661}
662
Hans Verkuil06470642014-03-04 07:27:13 -0300663static void buffer_finish(struct vb2_buffer *vb)
Hans de Goede885fe182011-06-06 15:33:44 -0300664{
665 struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
Junghak Sung2d700712015-09-22 10:30:30 -0300666 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
667 struct pwc_frame_buf *buf =
668 container_of(vbuf, struct pwc_frame_buf, vb);
Hans de Goede885fe182011-06-06 15:33:44 -0300669
Hans Verkuil1a179482014-03-04 07:28:11 -0300670 if (vb->state == VB2_BUF_STATE_DONE) {
671 /*
672 * Application has called dqbuf and is getting back a buffer
673 * we've filled, take the pwc data we've stored in buf->data
674 * and decompress it into a usable format, storing the result
675 * in the vb2_buffer.
676 */
677 pwc_decompress(pdev, buf);
678 }
Hans de Goede885fe182011-06-06 15:33:44 -0300679}
680
681static void buffer_cleanup(struct vb2_buffer *vb)
682{
Junghak Sung2d700712015-09-22 10:30:30 -0300683 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
684 struct pwc_frame_buf *buf =
685 container_of(vbuf, struct pwc_frame_buf, vb);
Hans de Goede885fe182011-06-06 15:33:44 -0300686
687 vfree(buf->data);
688}
689
690static void buffer_queue(struct vb2_buffer *vb)
691{
692 struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
Junghak Sung2d700712015-09-22 10:30:30 -0300693 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
694 struct pwc_frame_buf *buf =
695 container_of(vbuf, struct pwc_frame_buf, vb);
Hans de Goede885fe182011-06-06 15:33:44 -0300696 unsigned long flags = 0;
697
Hans de Goedec20d78c2011-10-09 09:16:46 -0300698 /* Check the device has not disconnected between prep and queuing */
Hans de Goedeceede9f2012-05-09 04:43:12 -0300699 if (!pdev->udev) {
Junghak Sung2d700712015-09-22 10:30:30 -0300700 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
Hans de Goedeceede9f2012-05-09 04:43:12 -0300701 return;
702 }
703
704 spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
705 list_add_tail(&buf->list, &pdev->queued_bufs);
Hans de Goede885fe182011-06-06 15:33:44 -0300706 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
707}
708
Marek Szyprowskibd323e22011-08-29 08:51:49 -0300709static int start_streaming(struct vb2_queue *vq, unsigned int count)
Hans de Goede885fe182011-06-06 15:33:44 -0300710{
711 struct pwc_device *pdev = vb2_get_drv_priv(vq);
Hans de Goedec20d78c2011-10-09 09:16:46 -0300712 int r;
Hans de Goede885fe182011-06-06 15:33:44 -0300713
Hans de Goedeceede9f2012-05-09 04:43:12 -0300714 if (!pdev->udev)
715 return -ENODEV;
Hans de Goedeb824bb42011-06-25 17:39:19 -0300716
Hans Verkuil2e43dec2012-07-02 05:51:58 -0300717 if (mutex_lock_interruptible(&pdev->v4l2_lock))
718 return -ERESTARTSYS;
Hans de Goede6eba9352011-06-26 06:49:59 -0300719 /* Turn on camera and set LEDS on */
720 pwc_camera_power(pdev, 1);
Hans de Goedec24e1372012-01-10 17:51:12 -0300721 pwc_set_leds(pdev, leds[0], leds[1]);
Hans de Goede6eba9352011-06-26 06:49:59 -0300722
Hans de Goedec20d78c2011-10-09 09:16:46 -0300723 r = pwc_isoc_init(pdev);
Hans de Goede5bbe18d2012-01-04 18:48:05 -0300724 if (r) {
725 /* If we failed turn camera and LEDS back off */
726 pwc_set_leds(pdev, 0, 0);
727 pwc_camera_power(pdev, 0);
728 /* And cleanup any queued bufs!! */
Hans Verkuil80b09632014-08-04 07:29:59 -0300729 pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED);
Hans de Goede5bbe18d2012-01-04 18:48:05 -0300730 }
Hans Verkuil2e43dec2012-07-02 05:51:58 -0300731 mutex_unlock(&pdev->v4l2_lock);
Hans de Goedeceede9f2012-05-09 04:43:12 -0300732
Hans de Goedec20d78c2011-10-09 09:16:46 -0300733 return r;
Hans de Goede885fe182011-06-06 15:33:44 -0300734}
735
Hans Verkuile37559b2014-04-17 02:47:21 -0300736static void stop_streaming(struct vb2_queue *vq)
Hans de Goede885fe182011-06-06 15:33:44 -0300737{
738 struct pwc_device *pdev = vb2_get_drv_priv(vq);
739
Hans Verkuile37559b2014-04-17 02:47:21 -0300740 mutex_lock(&pdev->v4l2_lock);
Hans de Goede6eba9352011-06-26 06:49:59 -0300741 if (pdev->udev) {
742 pwc_set_leds(pdev, 0, 0);
743 pwc_camera_power(pdev, 0);
Hans de Goedeb824bb42011-06-25 17:39:19 -0300744 pwc_isoc_cleanup(pdev);
Hans de Goede6eba9352011-06-26 06:49:59 -0300745 }
Hans de Goedec20d78c2011-10-09 09:16:46 -0300746
Hans Verkuil80b09632014-08-04 07:29:59 -0300747 pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_ERROR);
748 if (pdev->fill_buf)
Junghak Sung2d700712015-09-22 10:30:30 -0300749 vb2_buffer_done(&pdev->fill_buf->vb.vb2_buf,
750 VB2_BUF_STATE_ERROR);
Hans Verkuil2e43dec2012-07-02 05:51:58 -0300751 mutex_unlock(&pdev->v4l2_lock);
Hans de Goede885fe182011-06-06 15:33:44 -0300752}
753
Julia Lawall1bc17712016-09-08 20:59:01 -0300754static const struct vb2_ops pwc_vb_queue_ops = {
Hans de Goede885fe182011-06-06 15:33:44 -0300755 .queue_setup = queue_setup,
756 .buf_init = buffer_init,
757 .buf_prepare = buffer_prepare,
758 .buf_finish = buffer_finish,
759 .buf_cleanup = buffer_cleanup,
760 .buf_queue = buffer_queue,
761 .start_streaming = start_streaming,
762 .stop_streaming = stop_streaming,
Hans Verkuil2e43dec2012-07-02 05:51:58 -0300763 .wait_prepare = vb2_ops_wait_prepare,
764 .wait_finish = vb2_ops_wait_finish,
Hans de Goede885fe182011-06-06 15:33:44 -0300765};
766
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767/***************************************************************************/
768/* USB functions */
769
770/* This function gets called when a new device is plugged in or the usb core
771 * is loaded.
772 */
773
774static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id)
775{
776 struct usb_device *udev = interface_to_usbdev(intf);
777 struct pwc_device *pdev = NULL;
778 int vendor_id, product_id, type_id;
Hans de Goedea081c342012-01-10 17:47:25 -0300779 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 int features = 0;
Hans de Goede5bbe18d2012-01-04 18:48:05 -0300781 int compression = 0;
Hans de Goede3b4d0ec2011-06-26 03:51:19 -0300782 int my_power_save = power_save;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783 char serial_number[30], *name;
784
Luc Saillard2b455db2006-04-24 10:29:46 -0300785 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
786 product_id = le16_to_cpu(udev->descriptor.idProduct);
787
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 /* Check if we can handle this device */
Luc Saillard2b455db2006-04-24 10:29:46 -0300789 PWC_DEBUG_PROBE("probe() called [%04X %04X], if %d\n",
790 vendor_id, product_id,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 intf->altsetting->desc.bInterfaceNumber);
792
793 /* the interfaces are probed one by one. We are only interested in the
794 video interface (0) now.
795 Interface 1 is the Audio Control, and interface 2 Audio itself.
796 */
797 if (intf->altsetting->desc.bInterfaceNumber > 0)
798 return -ENODEV;
799
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 if (vendor_id == 0x0471) {
801 switch (product_id) {
802 case 0x0302:
Luc Saillard2b455db2006-04-24 10:29:46 -0300803 PWC_INFO("Philips PCA645VC USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804 name = "Philips 645 webcam";
805 type_id = 645;
806 break;
807 case 0x0303:
Luc Saillard2b455db2006-04-24 10:29:46 -0300808 PWC_INFO("Philips PCA646VC USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 name = "Philips 646 webcam";
810 type_id = 646;
811 break;
812 case 0x0304:
Luc Saillard2b455db2006-04-24 10:29:46 -0300813 PWC_INFO("Askey VC010 type 2 USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 name = "Askey VC010 webcam";
815 type_id = 646;
816 break;
817 case 0x0307:
Luc Saillard2b455db2006-04-24 10:29:46 -0300818 PWC_INFO("Philips PCVC675K (Vesta) USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 name = "Philips 675 webcam";
820 type_id = 675;
821 break;
822 case 0x0308:
Luc Saillard2b455db2006-04-24 10:29:46 -0300823 PWC_INFO("Philips PCVC680K (Vesta Pro) USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 name = "Philips 680 webcam";
825 type_id = 680;
826 break;
827 case 0x030C:
Luc Saillard2b455db2006-04-24 10:29:46 -0300828 PWC_INFO("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829 name = "Philips 690 webcam";
830 type_id = 690;
831 break;
832 case 0x0310:
Luc Saillard2b455db2006-04-24 10:29:46 -0300833 PWC_INFO("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834 name = "Philips 730 webcam";
835 type_id = 730;
836 break;
837 case 0x0311:
Luc Saillard2b455db2006-04-24 10:29:46 -0300838 PWC_INFO("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 name = "Philips 740 webcam";
840 type_id = 740;
841 break;
842 case 0x0312:
Luc Saillard2b455db2006-04-24 10:29:46 -0300843 PWC_INFO("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844 name = "Philips 750 webcam";
845 type_id = 750;
846 break;
847 case 0x0313:
Luc Saillard2b455db2006-04-24 10:29:46 -0300848 PWC_INFO("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 name = "Philips 720K/40 webcam";
850 type_id = 720;
851 break;
Luc Saillard2b455db2006-04-24 10:29:46 -0300852 case 0x0329:
853 PWC_INFO("Philips SPC 900NC USB webcam detected.\n");
854 name = "Philips SPC 900NC webcam";
Luc Saillard9ee6d782007-04-22 23:54:36 -0300855 type_id = 740;
Luc Saillard2b455db2006-04-24 10:29:46 -0300856 break;
Hans de Goede7445e452016-01-22 08:53:55 -0200857 case 0x032C:
858 PWC_INFO("Philips SPC 880NC USB webcam detected.\n");
859 name = "Philips SPC 880NC webcam";
860 type_id = 740;
861 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862 default:
863 return -ENODEV;
864 break;
865 }
866 }
867 else if (vendor_id == 0x069A) {
868 switch(product_id) {
869 case 0x0001:
Luc Saillard2b455db2006-04-24 10:29:46 -0300870 PWC_INFO("Askey VC010 type 1 USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 name = "Askey VC010 webcam";
872 type_id = 645;
873 break;
874 default:
875 return -ENODEV;
876 break;
877 }
878 }
879 else if (vendor_id == 0x046d) {
880 switch(product_id) {
881 case 0x08b0:
Luc Saillard2b455db2006-04-24 10:29:46 -0300882 PWC_INFO("Logitech QuickCam Pro 3000 USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 name = "Logitech QuickCam Pro 3000";
884 type_id = 740; /* CCD sensor */
885 break;
886 case 0x08b1:
Luc Saillard2b455db2006-04-24 10:29:46 -0300887 PWC_INFO("Logitech QuickCam Notebook Pro USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 name = "Logitech QuickCam Notebook Pro";
889 type_id = 740; /* CCD sensor */
890 break;
891 case 0x08b2:
Luc Saillard2b455db2006-04-24 10:29:46 -0300892 PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 name = "Logitech QuickCam Pro 4000";
894 type_id = 740; /* CCD sensor */
Hans de Goede51886df2011-07-03 15:52:54 -0300895 if (my_power_save == -1)
896 my_power_save = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 break;
898 case 0x08b3:
Luc Saillard2b455db2006-04-24 10:29:46 -0300899 PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 name = "Logitech QuickCam Zoom";
901 type_id = 740; /* CCD sensor */
902 break;
903 case 0x08B4:
Luc Saillard2b455db2006-04-24 10:29:46 -0300904 PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 name = "Logitech QuickCam Zoom";
906 type_id = 740; /* CCD sensor */
Hans de Goede3b4d0ec2011-06-26 03:51:19 -0300907 if (my_power_save == -1)
908 my_power_save = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 break;
910 case 0x08b5:
Luc Saillard2b455db2006-04-24 10:29:46 -0300911 PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912 name = "Logitech QuickCam Orbit";
913 type_id = 740; /* CCD sensor */
Hans de Goede51886df2011-07-03 15:52:54 -0300914 if (my_power_save == -1)
915 my_power_save = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 features |= FEATURE_MOTOR_PANTILT;
917 break;
918 case 0x08b6:
Jean Tourrilhesa63e1572007-03-21 16:29:16 -0300919 PWC_INFO("Logitech/Cisco VT Camera webcam detected.\n");
920 name = "Cisco VT Camera";
921 type_id = 740; /* CCD sensor */
922 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923 case 0x08b7:
Mauro Carvalho Chehab6b1ce3c2007-03-21 16:35:28 -0300924 PWC_INFO("Logitech ViewPort AV 100 webcam detected.\n");
925 name = "Logitech ViewPort AV 100";
926 type_id = 740; /* CCD sensor */
927 break;
928 case 0x08b8: /* Where this released? */
Luc Saillard2b455db2006-04-24 10:29:46 -0300929 PWC_INFO("Logitech QuickCam detected (reserved ID).\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 name = "Logitech QuickCam (res.)";
931 type_id = 730; /* Assuming CMOS */
932 break;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300933 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 return -ENODEV;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300935 break;
936 }
937 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 else if (vendor_id == 0x055d) {
939 /* I don't know the difference between the C10 and the C30;
940 I suppose the difference is the sensor, but both cameras
941 work equally well with a type_id of 675
942 */
943 switch(product_id) {
944 case 0x9000:
Luc Saillard2b455db2006-04-24 10:29:46 -0300945 PWC_INFO("Samsung MPC-C10 USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 name = "Samsung MPC-C10";
947 type_id = 675;
948 break;
949 case 0x9001:
Luc Saillard2b455db2006-04-24 10:29:46 -0300950 PWC_INFO("Samsung MPC-C30 USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951 name = "Samsung MPC-C30";
952 type_id = 675;
953 break;
Luc Saillard2b455db2006-04-24 10:29:46 -0300954 case 0x9002:
955 PWC_INFO("Samsung SNC-35E (v3.0) USB webcam detected.\n");
956 name = "Samsung MPC-C30";
957 type_id = 740;
958 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959 default:
960 return -ENODEV;
961 break;
962 }
963 }
964 else if (vendor_id == 0x041e) {
965 switch(product_id) {
966 case 0x400c:
Luc Saillard2b455db2006-04-24 10:29:46 -0300967 PWC_INFO("Creative Labs Webcam 5 detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968 name = "Creative Labs Webcam 5";
969 type_id = 730;
Hans de Goede51886df2011-07-03 15:52:54 -0300970 if (my_power_save == -1)
971 my_power_save = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972 break;
973 case 0x4011:
Luc Saillard2b455db2006-04-24 10:29:46 -0300974 PWC_INFO("Creative Labs Webcam Pro Ex detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 name = "Creative Labs Webcam Pro Ex";
976 type_id = 740;
977 break;
978 default:
979 return -ENODEV;
980 break;
981 }
982 }
983 else if (vendor_id == 0x04cc) {
984 switch(product_id) {
985 case 0x8116:
Luc Saillard2b455db2006-04-24 10:29:46 -0300986 PWC_INFO("Sotec Afina Eye USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987 name = "Sotec Afina Eye";
988 type_id = 730;
989 break;
990 default:
991 return -ENODEV;
992 break;
993 }
994 }
995 else if (vendor_id == 0x06be) {
996 switch(product_id) {
997 case 0x8116:
998 /* This is essentially the same cam as the Sotec Afina Eye */
Luc Saillard2b455db2006-04-24 10:29:46 -0300999 PWC_INFO("AME Co. Afina Eye USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 name = "AME Co. Afina Eye";
1001 type_id = 750;
1002 break;
1003 default:
1004 return -ENODEV;
1005 break;
1006 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001007
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008 }
1009 else if (vendor_id == 0x0d81) {
1010 switch(product_id) {
1011 case 0x1900:
Luc Saillard2b455db2006-04-24 10:29:46 -03001012 PWC_INFO("Visionite VCS-UC300 USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 name = "Visionite VCS-UC300";
1014 type_id = 740; /* CCD sensor */
1015 break;
1016 case 0x1910:
Luc Saillard2b455db2006-04-24 10:29:46 -03001017 PWC_INFO("Visionite VCS-UM100 USB webcam detected.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 name = "Visionite VCS-UM100";
1019 type_id = 730; /* CMOS sensor */
1020 break;
1021 default:
1022 return -ENODEV;
1023 break;
1024 }
1025 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001026 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 return -ENODEV; /* Not any of the know types; but the list keeps growing. */
1028
Hans de Goede3b4d0ec2011-06-26 03:51:19 -03001029 if (my_power_save == -1)
1030 my_power_save = 0;
1031
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 memset(serial_number, 0, 30);
1033 usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
Luc Saillard2b455db2006-04-24 10:29:46 -03001034 PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035
1036 if (udev->descriptor.bNumConfigurations > 1)
Luc Saillard2b455db2006-04-24 10:29:46 -03001037 PWC_WARNING("Warning: more than 1 configuration available.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038
1039 /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */
Eric Sesterhenn80b6ca42006-02-27 21:29:43 +01001040 pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 if (pdev == NULL) {
Luc Saillard2b455db2006-04-24 10:29:46 -03001042 PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043 return -ENOMEM;
1044 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 pdev->type = type_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046 pdev->features = features;
Hans de Goede3b4d0ec2011-06-26 03:51:19 -03001047 pwc_construct(pdev); /* set min/max sizes correct */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
Hans de Goedeceede9f2012-05-09 04:43:12 -03001049 mutex_init(&pdev->v4l2_lock);
1050 mutex_init(&pdev->vb_queue_lock);
Hans de Goede885fe182011-06-06 15:33:44 -03001051 spin_lock_init(&pdev->queued_bufs_lock);
1052 INIT_LIST_HEAD(&pdev->queued_bufs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053
1054 pdev->udev = udev;
Hans de Goede3b4d0ec2011-06-26 03:51:19 -03001055 pdev->power_save = my_power_save;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056
Hans de Goede885fe182011-06-06 15:33:44 -03001057 /* Init videobuf2 queue structure */
Hans de Goede885fe182011-06-06 15:33:44 -03001058 pdev->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1059 pdev->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1060 pdev->vb_queue.drv_priv = pdev;
1061 pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf);
1062 pdev->vb_queue.ops = &pwc_vb_queue_ops;
1063 pdev->vb_queue.mem_ops = &vb2_vmalloc_memops;
Sakari Ailusade48682014-02-25 19:12:19 -03001064 pdev->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
Mauro Carvalho Chehabeda94712012-10-27 14:26:25 -03001065 rc = vb2_queue_init(&pdev->vb_queue);
1066 if (rc < 0) {
1067 PWC_ERROR("Oops, could not initialize vb2 queue.\n");
1068 goto err_free_mem;
1069 }
Hans de Goede885fe182011-06-06 15:33:44 -03001070
Hans de Goede9a7b2d12011-06-06 14:43:39 -03001071 /* Init video_device structure */
Ezequiel Garcia5c2edef2012-10-23 15:57:08 -03001072 pdev->vdev = pwc_template;
Mauro Carvalho Chehabcc1e6312018-09-10 16:20:42 -04001073 strscpy(pdev->vdev.name, name, sizeof(pdev->vdev.name));
Hans Verkuil2e43dec2012-07-02 05:51:58 -03001074 pdev->vdev.queue = &pdev->vb_queue;
1075 pdev->vdev.queue->lock = &pdev->vb_queue_lock;
Hans de Goede9a7b2d12011-06-06 14:43:39 -03001076 video_set_drvdata(&pdev->vdev, pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077
1078 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
Luc Saillard2b455db2006-04-24 10:29:46 -03001079 PWC_DEBUG_PROBE("Release: %04x\n", pdev->release);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080
Hans de Goede24be6892012-01-10 17:02:04 -03001081 /* Allocate USB command buffers */
1082 pdev->ctrl_buf = kmalloc(sizeof(pdev->cmd_buf), GFP_KERNEL);
1083 if (!pdev->ctrl_buf) {
1084 PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
1085 rc = -ENOMEM;
1086 goto err_free_mem;
1087 }
1088
Hans de Goede6eba9352011-06-26 06:49:59 -03001089#ifdef CONFIG_USB_PWC_DEBUG
1090 /* Query sensor type */
1091 if (pwc_get_cmos_sensor(pdev, &rc) >= 0) {
1092 PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n",
1093 pdev->vdev.name,
1094 pwc_sensor_type_to_string(rc), rc);
1095 }
1096#endif
1097
Luc Saillard2b455db2006-04-24 10:29:46 -03001098 /* Set the leds off */
1099 pwc_set_leds(pdev, 0, 0);
Hans de Goede6eba9352011-06-26 06:49:59 -03001100
Jonathan McCrohan39c1cb22013-10-20 21:34:01 -03001101 /* Setup initial videomode */
Hans de Goeded167a852012-01-10 13:01:41 -03001102 rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT,
Hans de Goede938d5b92012-01-10 13:14:46 -03001103 V4L2_PIX_FMT_YUV420, 30, &compression, 1);
Hans de Goede6eba9352011-06-26 06:49:59 -03001104 if (rc)
1105 goto err_free_mem;
1106
Hans de Goede6c9cac82011-06-26 12:52:01 -03001107 /* Register controls (and read default values from camera */
1108 rc = pwc_init_controls(pdev);
1109 if (rc) {
1110 PWC_ERROR("Failed to register v4l2 controls (%d).\n", rc);
1111 goto err_free_mem;
1112 }
1113
Hans de Goede6eba9352011-06-26 06:49:59 -03001114 /* And powerdown the camera until streaming starts */
Luc Saillard2b455db2006-04-24 10:29:46 -03001115 pwc_camera_power(pdev, 0);
1116
Hans de Goede76ae8532011-07-19 07:14:22 -03001117 /* Register the v4l2_device structure */
1118 pdev->v4l2_dev.release = pwc_video_release;
1119 rc = v4l2_device_register(&intf->dev, &pdev->v4l2_dev);
1120 if (rc) {
1121 PWC_ERROR("Failed to register v4l2-device (%d).\n", rc);
1122 goto err_free_controls;
1123 }
1124
1125 pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler;
1126 pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
Hans de Goedeceede9f2012-05-09 04:43:12 -03001127 pdev->vdev.lock = &pdev->v4l2_lock;
1128
Hans de Goedea081c342012-01-10 17:47:25 -03001129 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1);
Hans Verkuil479567c2010-09-12 17:05:11 -03001130 if (rc < 0) {
1131 PWC_ERROR("Failed to register as video device (%d).\n", rc);
Hans de Goede76ae8532011-07-19 07:14:22 -03001132 goto err_unregister_v4l2_dev;
Hans Verkuil479567c2010-09-12 17:05:11 -03001133 }
Hans de Goede9a7b2d12011-06-06 14:43:39 -03001134 PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev));
Hans Verkuil479567c2010-09-12 17:05:11 -03001135
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -03001136#ifdef CONFIG_USB_PWC_INPUT_EVDEV
1137 /* register webcam snapshot button input device */
1138 pdev->button_dev = input_allocate_device();
1139 if (!pdev->button_dev) {
Dmitry Torokhov89dec012009-08-14 02:22:52 -03001140 rc = -ENOMEM;
Dmitry Torokhov89dec012009-08-14 02:22:52 -03001141 goto err_video_unreg;
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -03001142 }
1143
Dmitry Torokhov89dec012009-08-14 02:22:52 -03001144 usb_make_path(udev, pdev->button_phys, sizeof(pdev->button_phys));
1145 strlcat(pdev->button_phys, "/input0", sizeof(pdev->button_phys));
1146
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -03001147 pdev->button_dev->name = "PWC snapshot button";
Dmitry Torokhov89dec012009-08-14 02:22:52 -03001148 pdev->button_dev->phys = pdev->button_phys;
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -03001149 usb_to_input_id(pdev->udev, &pdev->button_dev->id);
1150 pdev->button_dev->dev.parent = &pdev->udev->dev;
1151 pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
Lennart Poetteringbcd3e4b2009-06-11 11:19:33 -03001152 pdev->button_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -03001153
1154 rc = input_register_device(pdev->button_dev);
1155 if (rc) {
1156 input_free_device(pdev->button_dev);
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -03001157 pdev->button_dev = NULL;
Dmitry Torokhov89dec012009-08-14 02:22:52 -03001158 goto err_video_unreg;
Nam Phạm Thànhe32a7ecc2009-01-12 02:50:17 -03001159 }
1160#endif
1161
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162 return 0;
Jeff Garzikc12e3be2006-10-13 07:17:32 -03001163
Arnd Bergmann1f6bcd012016-01-26 14:17:24 -02001164#ifdef CONFIG_USB_PWC_INPUT_EVDEV
Dmitry Torokhov89dec012009-08-14 02:22:52 -03001165err_video_unreg:
Hans de Goede9a7b2d12011-06-06 14:43:39 -03001166 video_unregister_device(&pdev->vdev);
Arnd Bergmann1f6bcd012016-01-26 14:17:24 -02001167#endif
Hans de Goede76ae8532011-07-19 07:14:22 -03001168err_unregister_v4l2_dev:
1169 v4l2_device_unregister(&pdev->v4l2_dev);
Hans de Goede6c9cac82011-06-26 12:52:01 -03001170err_free_controls:
1171 v4l2_ctrl_handler_free(&pdev->ctrl_handler);
Dmitry Torokhov89dec012009-08-14 02:22:52 -03001172err_free_mem:
Hans de Goede24be6892012-01-10 17:02:04 -03001173 kfree(pdev->ctrl_buf);
Dmitry Torokhov89dec012009-08-14 02:22:52 -03001174 kfree(pdev);
Jeff Garzikc12e3be2006-10-13 07:17:32 -03001175 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176}
1177
Dmitry Torokhov89dec012009-08-14 02:22:52 -03001178/* The user yanked out the cable... */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179static void usb_pwc_disconnect(struct usb_interface *intf)
1180{
Hans de Goede76ae8532011-07-19 07:14:22 -03001181 struct v4l2_device *v = usb_get_intfdata(intf);
1182 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183
Hans de Goedeceede9f2012-05-09 04:43:12 -03001184 mutex_lock(&pdev->vb_queue_lock);
Hans Verkuil2e43dec2012-07-02 05:51:58 -03001185 mutex_lock(&pdev->v4l2_lock);
Hans de Goede9a7b2d12011-06-06 14:43:39 -03001186 /* No need to keep the urbs around after disconnection */
Hans de Goedeceede9f2012-05-09 04:43:12 -03001187 if (pdev->vb_queue.streaming)
1188 pwc_isoc_cleanup(pdev);
Hans de Goedeb824bb42011-06-25 17:39:19 -03001189 pdev->udev = NULL;
Hans de Goedec20d78c2011-10-09 09:16:46 -03001190
Hans de Goedeceede9f2012-05-09 04:43:12 -03001191 v4l2_device_disconnect(&pdev->v4l2_dev);
Hans de Goede9a7b2d12011-06-06 14:43:39 -03001192 video_unregister_device(&pdev->vdev);
Hans de Goedeceede9f2012-05-09 04:43:12 -03001193 mutex_unlock(&pdev->v4l2_lock);
Ezequiel Garcia0ab61192012-07-15 03:00:33 -03001194 mutex_unlock(&pdev->vb_queue_lock);
Hans de Goede9a7b2d12011-06-06 14:43:39 -03001195
1196#ifdef CONFIG_USB_PWC_INPUT_EVDEV
1197 if (pdev->button_dev)
1198 input_unregister_device(pdev->button_dev);
1199#endif
Hans de Goede76ae8532011-07-19 07:14:22 -03001200
1201 v4l2_device_put(&pdev->v4l2_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202}
1203
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001205/*
1206 * Initialization code & module stuff
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 */
1208
Al Viro64a6f952007-10-14 19:35:30 +01001209static unsigned int leds_nargs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210
Trent Piepho05ad3902007-01-30 23:26:01 -03001211#ifdef CONFIG_USB_PWC_DEBUG
Luc Saillard2b455db2006-04-24 10:29:46 -03001212module_param_named(trace, pwc_trace, int, 0644);
1213#endif
Hans de Goede3b4d0ec2011-06-26 03:51:19 -03001214module_param(power_save, int, 0644);
Luc Saillard2b455db2006-04-24 10:29:46 -03001215module_param_array(leds, int, &leds_nargs, 0444);
Luc Saillard2b455db2006-04-24 10:29:46 -03001216
Andrea Odetti4315c412009-12-10 16:26:10 -03001217#ifdef CONFIG_USB_PWC_DEBUG
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218MODULE_PARM_DESC(trace, "For debugging purposes");
Andrea Odetti4315c412009-12-10 16:26:10 -03001219#endif
Hans de Goede3b4d0ec2011-06-26 03:51:19 -03001220MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222
1223MODULE_DESCRIPTION("Philips & OEM USB webcam driver");
1224MODULE_AUTHOR("Luc Saillard <luc@saillard.org>");
1225MODULE_LICENSE("GPL");
Luc Saillard2b455db2006-04-24 10:29:46 -03001226MODULE_ALIAS("pwcx");
1227MODULE_VERSION( PWC_VERSION );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228
Hans de Goedeceede9f2012-05-09 04:43:12 -03001229module_usb_driver(pwc_driver);