1c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart/* 2c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * uvc_status.c -- USB Video Class driver - Status endpoint 3c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * 411fc5baf1dab2d30f03a391cabc5fd1808cfbe29Laurent Pinchart * Copyright (C) 2005-2009 511fc5baf1dab2d30f03a391cabc5fd1808cfbe29Laurent Pinchart * Laurent Pinchart (laurent.pinchart@ideasonboard.com) 6c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * 7c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * This program is free software; you can redistribute it and/or modify 8c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * it under the terms of the GNU General Public License as published by 9c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * the Free Software Foundation; either version 2 of the License, or 10c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * (at your option) any later version. 11c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * 12c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart */ 13c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 14c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart#include <linux/kernel.h> 15c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart#include <linux/input.h> 165a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 17c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart#include <linux/usb.h> 18c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart#include <linux/usb/input.h> 19c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 20c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart#include "uvcvideo.h" 21c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 22c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart/* -------------------------------------------------------------------------- 23c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * Input device 24c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart */ 256833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart#ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV 26c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartstatic int uvc_input_init(struct uvc_device *dev) 27c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 28c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart struct input_dev *input; 29c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart int ret; 30c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 31c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart input = input_allocate_device(); 32c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (input == NULL) 33c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return -ENOMEM; 34c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 35f180152376c984a6faa9decb8f2811c373da9141Laurent Pinchart usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys)); 36f180152376c984a6faa9decb8f2811c373da9141Laurent Pinchart strlcat(dev->input_phys, "/button", sizeof(dev->input_phys)); 37c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 38c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart input->name = dev->name; 39f180152376c984a6faa9decb8f2811c373da9141Laurent Pinchart input->phys = dev->input_phys; 40f180152376c984a6faa9decb8f2811c373da9141Laurent Pinchart usb_to_input_id(dev->udev, &input->id); 41c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart input->dev.parent = &dev->intf->dev; 42c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 4374ca11c2056d01d9ebb3615cd781a148450c3c82Bastien Nocera __set_bit(EV_KEY, input->evbit); 4474ca11c2056d01d9ebb3615cd781a148450c3c82Bastien Nocera __set_bit(KEY_CAMERA, input->keybit); 45c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 46c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if ((ret = input_register_device(input)) < 0) 47c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart goto error; 48c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 49c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart dev->input = input; 50c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return 0; 51c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 52c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pincharterror: 53c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart input_free_device(input); 54c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return ret; 55c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 56c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 57c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartstatic void uvc_input_cleanup(struct uvc_device *dev) 58c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 59c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (dev->input) 60c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart input_unregister_device(dev->input); 61c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 62c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 636833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchartstatic void uvc_input_report_key(struct uvc_device *dev, unsigned int code, 646833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart int value) 656833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart{ 6674ca11c2056d01d9ebb3615cd781a148450c3c82Bastien Nocera if (dev->input) { 676833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart input_report_key(dev->input, code, value); 6874ca11c2056d01d9ebb3615cd781a148450c3c82Bastien Nocera input_sync(dev->input); 6974ca11c2056d01d9ebb3615cd781a148450c3c82Bastien Nocera } 706833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart} 716833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart 726833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart#else 736833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart#define uvc_input_init(dev) 746833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart#define uvc_input_cleanup(dev) 756833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart#define uvc_input_report_key(dev, code, value) 766833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart#endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */ 776833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart 78c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart/* -------------------------------------------------------------------------- 79c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * Status interrupt endpoint 80c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart */ 81c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartstatic void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) 82c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 83c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (len < 3) { 84c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_trace(UVC_TRACE_STATUS, "Invalid streaming status event " 85c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart "received.\n"); 86c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return; 87c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 88c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 89c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (data[2] == 0) { 90c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (len < 4) 91c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return; 92c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n", 93c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart data[1], data[3] ? "pressed" : "released", len); 9474ca11c2056d01d9ebb3615cd781a148450c3c82Bastien Nocera uvc_input_report_key(dev, KEY_CAMERA, data[3]); 95c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } else { 96c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x " 97c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart "len %d.\n", data[1], data[2], data[3], len); 98c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 99c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 100c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 101c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartstatic void uvc_event_control(struct uvc_device *dev, __u8 *data, int len) 102c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 103c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart char *attrs[3] = { "value", "info", "failure" }; 104c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 105c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (len < 6 || data[2] != 0 || data[4] > 2) { 106c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_trace(UVC_TRACE_STATUS, "Invalid control status event " 107c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart "received.\n"); 108c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return; 109c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 110c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 111c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_trace(UVC_TRACE_STATUS, "Control %u/%u %s change len %d.\n", 112c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart data[1], data[3], attrs[data[4]], len); 113c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 114c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 115c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartstatic void uvc_status_complete(struct urb *urb) 116c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 117c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart struct uvc_device *dev = urb->context; 118c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart int len, ret; 119c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 120c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart switch (urb->status) { 121c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case 0: 122c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart break; 123c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 124c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case -ENOENT: /* usb_kill_urb() called. */ 125c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case -ECONNRESET: /* usb_unlink_urb() called. */ 126c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case -ESHUTDOWN: /* The endpoint is being disabled. */ 127c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case -EPROTO: /* Device is disconnected (reported by some 128c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * host controller). */ 129c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return; 130c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 131c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart default: 132c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_printk(KERN_WARNING, "Non-zero status (%d) in status " 133c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart "completion handler.\n", urb->status); 134c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return; 135c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 136c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 137c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart len = urb->actual_length; 138c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (len > 0) { 139c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart switch (dev->status[0] & 0x0f) { 140c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case UVC_STATUS_TYPE_CONTROL: 141c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_event_control(dev, dev->status, len); 142c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart break; 143c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 144c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case UVC_STATUS_TYPE_STREAMING: 145c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_event_streaming(dev, dev->status, len); 146c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart break; 147c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 148c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart default: 149bd0232c13419b7ce51e02942082ff6af231e0f84Laurent Pinchart uvc_trace(UVC_TRACE_STATUS, "Unknown status event " 150bd0232c13419b7ce51e02942082ff6af231e0f84Laurent Pinchart "type %u.\n", dev->status[0]); 151c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart break; 152c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 153c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 154c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 155c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart /* Resubmit the URB. */ 156c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart urb->interval = dev->int_ep->desc.bInterval; 157c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { 158c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_printk(KERN_ERR, "Failed to resubmit status URB (%d).\n", 159c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart ret); 160c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 161c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 162c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 163c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartint uvc_status_init(struct uvc_device *dev) 164c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 165c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart struct usb_host_endpoint *ep = dev->int_ep; 166c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart unsigned int pipe; 167c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart int interval; 168c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 169c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (ep == NULL) 170c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return 0; 171c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 172c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_input_init(dev); 173c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 174a31a4055473bf0a7b2b06cb2262347200d0711e1Ming Lei dev->status = kzalloc(UVC_MAX_STATUS_SIZE, GFP_KERNEL); 175a31a4055473bf0a7b2b06cb2262347200d0711e1Ming Lei if (dev->status == NULL) 176a31a4055473bf0a7b2b06cb2262347200d0711e1Ming Lei return -ENOMEM; 177a31a4055473bf0a7b2b06cb2262347200d0711e1Ming Lei 178c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart dev->int_urb = usb_alloc_urb(0, GFP_KERNEL); 179a31a4055473bf0a7b2b06cb2262347200d0711e1Ming Lei if (dev->int_urb == NULL) { 180a31a4055473bf0a7b2b06cb2262347200d0711e1Ming Lei kfree(dev->status); 181c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return -ENOMEM; 182a31a4055473bf0a7b2b06cb2262347200d0711e1Ming Lei } 183c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 184c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress); 185c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 186c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart /* For high-speed interrupt endpoints, the bInterval value is used as 187c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * an exponent of two. Some developers forgot about it. 188c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart */ 189c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart interval = ep->desc.bInterval; 190c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (interval > 16 && dev->udev->speed == USB_SPEED_HIGH && 191c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart (dev->quirks & UVC_QUIRK_STATUS_INTERVAL)) 192c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart interval = fls(interval) - 1; 193c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 194c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart usb_fill_int_urb(dev->int_urb, dev->udev, pipe, 195a31a4055473bf0a7b2b06cb2262347200d0711e1Ming Lei dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete, 196c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart dev, interval); 197c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 19804a37e0f32f9882430bc1899899d2ed91b8aaf5bLaurent Pinchart return 0; 199c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 200c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 201c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartvoid uvc_status_cleanup(struct uvc_device *dev) 202c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 203c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart usb_kill_urb(dev->int_urb); 204c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart usb_free_urb(dev->int_urb); 205a31a4055473bf0a7b2b06cb2262347200d0711e1Ming Lei kfree(dev->status); 206c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_input_cleanup(dev); 207c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 208c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 20917706f5653a90ff277b5b36c2eb60ff872df5e7aLaurent Pinchartint uvc_status_start(struct uvc_device *dev, gfp_t flags) 21004a37e0f32f9882430bc1899899d2ed91b8aaf5bLaurent Pinchart{ 21104a37e0f32f9882430bc1899899d2ed91b8aaf5bLaurent Pinchart if (dev->int_urb == NULL) 21204a37e0f32f9882430bc1899899d2ed91b8aaf5bLaurent Pinchart return 0; 21304a37e0f32f9882430bc1899899d2ed91b8aaf5bLaurent Pinchart 21417706f5653a90ff277b5b36c2eb60ff872df5e7aLaurent Pinchart return usb_submit_urb(dev->int_urb, flags); 21504a37e0f32f9882430bc1899899d2ed91b8aaf5bLaurent Pinchart} 21604a37e0f32f9882430bc1899899d2ed91b8aaf5bLaurent Pinchart 21704a37e0f32f9882430bc1899899d2ed91b8aaf5bLaurent Pinchartvoid uvc_status_stop(struct uvc_device *dev) 218c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 219c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart usb_kill_urb(dev->int_urb); 22004a37e0f32f9882430bc1899899d2ed91b8aaf5bLaurent Pinchart} 221