uvc_status.c revision 6833c917b4de1757febdbf946d709ece6dc7a86f
1c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart/* 2c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * uvc_status.c -- USB Video Class driver - Status endpoint 3c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * 4c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * Copyright (C) 2007-2008 5c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * Laurent Pinchart (laurent.pinchart@skynet.be) 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/version.h> 16c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart#include <linux/input.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 usb_device *udev = dev->udev; 29c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart struct input_dev *input; 30c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart char *phys = NULL; 31c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart int ret; 32c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 33c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart input = input_allocate_device(); 34c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (input == NULL) 35c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return -ENOMEM; 36c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 37c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart phys = kmalloc(6 + strlen(udev->bus->bus_name) + strlen(udev->devpath), 38c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart GFP_KERNEL); 39c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (phys == NULL) { 40c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart ret = -ENOMEM; 41c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart goto error; 42c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 43c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart sprintf(phys, "usb-%s-%s", udev->bus->bus_name, udev->devpath); 44c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 45c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart input->name = dev->name; 46c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart input->phys = phys; 47c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart usb_to_input_id(udev, &input->id); 48c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart input->dev.parent = &dev->intf->dev; 49c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 50c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart set_bit(EV_KEY, input->evbit); 51c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart set_bit(BTN_0, input->keybit); 52c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 53c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if ((ret = input_register_device(input)) < 0) 54c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart goto error; 55c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 56c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart dev->input = input; 57c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return 0; 58c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 59c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pincharterror: 60c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart input_free_device(input); 61c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart kfree(phys); 62c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return ret; 63c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 64c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 65c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartstatic void uvc_input_cleanup(struct uvc_device *dev) 66c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 67c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (dev->input) 68c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart input_unregister_device(dev->input); 69c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 70c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 716833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchartstatic void uvc_input_report_key(struct uvc_device *dev, unsigned int code, 726833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart int value) 736833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart{ 746833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart if (dev->input) 756833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart input_report_key(dev->input, code, value); 766833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart} 776833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart 786833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart#else 796833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart#define uvc_input_init(dev) 806833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart#define uvc_input_cleanup(dev) 816833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart#define uvc_input_report_key(dev, code, value) 826833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart#endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */ 836833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart 84c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart/* -------------------------------------------------------------------------- 85c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * Status interrupt endpoint 86c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart */ 87c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartstatic void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) 88c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 89c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (len < 3) { 90c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_trace(UVC_TRACE_STATUS, "Invalid streaming status event " 91c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart "received.\n"); 92c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return; 93c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 94c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 95c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (data[2] == 0) { 96c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (len < 4) 97c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return; 98c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n", 99c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart data[1], data[3] ? "pressed" : "released", len); 1006833c917b4de1757febdbf946d709ece6dc7a86fLaurent Pinchart uvc_input_report_key(dev, BTN_0, data[3]); 101c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } else { 102c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x " 103c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart "len %d.\n", data[1], data[2], data[3], len); 104c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 105c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 106c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 107c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartstatic void uvc_event_control(struct uvc_device *dev, __u8 *data, int len) 108c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 109c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart char *attrs[3] = { "value", "info", "failure" }; 110c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 111c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (len < 6 || data[2] != 0 || data[4] > 2) { 112c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_trace(UVC_TRACE_STATUS, "Invalid control status event " 113c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart "received.\n"); 114c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return; 115c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 116c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 117c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_trace(UVC_TRACE_STATUS, "Control %u/%u %s change len %d.\n", 118c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart data[1], data[3], attrs[data[4]], len); 119c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 120c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 121c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartstatic void uvc_status_complete(struct urb *urb) 122c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 123c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart struct uvc_device *dev = urb->context; 124c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart int len, ret; 125c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 126c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart switch (urb->status) { 127c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case 0: 128c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart break; 129c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 130c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case -ENOENT: /* usb_kill_urb() called. */ 131c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case -ECONNRESET: /* usb_unlink_urb() called. */ 132c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case -ESHUTDOWN: /* The endpoint is being disabled. */ 133c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case -EPROTO: /* Device is disconnected (reported by some 134c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart * host controller). */ 135c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return; 136c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 137c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart default: 138c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_printk(KERN_WARNING, "Non-zero status (%d) in status " 139c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart "completion handler.\n", urb->status); 140c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return; 141c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 142c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 143c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart len = urb->actual_length; 144c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (len > 0) { 145c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart switch (dev->status[0] & 0x0f) { 146c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case UVC_STATUS_TYPE_CONTROL: 147c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_event_control(dev, dev->status, len); 148c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart break; 149c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 150c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart case UVC_STATUS_TYPE_STREAMING: 151c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_event_streaming(dev, dev->status, len); 152c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart break; 153c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 154c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart default: 155c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_printk(KERN_INFO, "unknown event type %u.\n", 156c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart dev->status[0]); 157c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart break; 158c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 159c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 160c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 161c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart /* Resubmit the URB. */ 162c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart urb->interval = dev->int_ep->desc.bInterval; 163c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { 164c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_printk(KERN_ERR, "Failed to resubmit status URB (%d).\n", 165c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart ret); 166c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart } 167c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 168c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 169c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartint uvc_status_init(struct uvc_device *dev) 170c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 171c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart struct usb_host_endpoint *ep = dev->int_ep; 172c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart unsigned int pipe; 173c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart int interval; 174c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 175c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (ep == NULL) 176c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return 0; 177c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 178c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_input_init(dev); 179c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 180c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart dev->int_urb = usb_alloc_urb(0, GFP_KERNEL); 181c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (dev->int_urb == NULL) 182c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return -ENOMEM; 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, 195c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart dev->status, sizeof dev->status, uvc_status_complete, 196c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart dev, interval); 197c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 198c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return usb_submit_urb(dev->int_urb, GFP_KERNEL); 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); 205c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart uvc_input_cleanup(dev); 206c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 207c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 208c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartint uvc_status_suspend(struct uvc_device *dev) 209c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 210c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart usb_kill_urb(dev->int_urb); 211c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return 0; 212c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 213c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 214c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchartint uvc_status_resume(struct uvc_device *dev) 215c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart{ 216c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart if (dev->int_urb == NULL) 217c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart return 0; 218c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart 219291358785cde5536d98a4f3cae77efd8ca626486Laurent Pinchart return usb_submit_urb(dev->int_urb, GFP_NOIO); 220c0efd232929c2cd87238de2cccdaf4e845be5b0cLaurent Pinchart} 221f87086e302300fdff1bd32049deb7a7f3e3de7daHans Verkuil 222