Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *      uvc_status.c  --  USB Video Class driver - Status endpoint
0004  *
0005  *      Copyright (C) 2005-2009
0006  *          Laurent Pinchart (laurent.pinchart@ideasonboard.com)
0007  */
0008 
0009 #include <linux/kernel.h>
0010 #include <linux/input.h>
0011 #include <linux/slab.h>
0012 #include <linux/usb.h>
0013 #include <linux/usb/input.h>
0014 
0015 #include "uvcvideo.h"
0016 
0017 /* --------------------------------------------------------------------------
0018  * Input device
0019  */
0020 #ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV
0021 static int uvc_input_init(struct uvc_device *dev)
0022 {
0023     struct input_dev *input;
0024     int ret;
0025 
0026     input = input_allocate_device();
0027     if (input == NULL)
0028         return -ENOMEM;
0029 
0030     usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys));
0031     strlcat(dev->input_phys, "/button", sizeof(dev->input_phys));
0032 
0033     input->name = dev->name;
0034     input->phys = dev->input_phys;
0035     usb_to_input_id(dev->udev, &input->id);
0036     input->dev.parent = &dev->intf->dev;
0037 
0038     __set_bit(EV_KEY, input->evbit);
0039     __set_bit(KEY_CAMERA, input->keybit);
0040 
0041     if ((ret = input_register_device(input)) < 0)
0042         goto error;
0043 
0044     dev->input = input;
0045     return 0;
0046 
0047 error:
0048     input_free_device(input);
0049     return ret;
0050 }
0051 
0052 static void uvc_input_unregister(struct uvc_device *dev)
0053 {
0054     if (dev->input)
0055         input_unregister_device(dev->input);
0056 }
0057 
0058 static void uvc_input_report_key(struct uvc_device *dev, unsigned int code,
0059     int value)
0060 {
0061     if (dev->input) {
0062         input_report_key(dev->input, code, value);
0063         input_sync(dev->input);
0064     }
0065 }
0066 
0067 #else
0068 #define uvc_input_init(dev)
0069 #define uvc_input_unregister(dev)
0070 #define uvc_input_report_key(dev, code, value)
0071 #endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */
0072 
0073 /* --------------------------------------------------------------------------
0074  * Status interrupt endpoint
0075  */
0076 struct uvc_streaming_status {
0077     u8  bStatusType;
0078     u8  bOriginator;
0079     u8  bEvent;
0080     u8  bValue[];
0081 } __packed;
0082 
0083 struct uvc_control_status {
0084     u8  bStatusType;
0085     u8  bOriginator;
0086     u8  bEvent;
0087     u8  bSelector;
0088     u8  bAttribute;
0089     u8  bValue[];
0090 } __packed;
0091 
0092 static void uvc_event_streaming(struct uvc_device *dev,
0093                 struct uvc_streaming_status *status, int len)
0094 {
0095     if (len < 3) {
0096         uvc_dbg(dev, STATUS,
0097             "Invalid streaming status event received\n");
0098         return;
0099     }
0100 
0101     if (status->bEvent == 0) {
0102         if (len < 4)
0103             return;
0104         uvc_dbg(dev, STATUS, "Button (intf %u) %s len %d\n",
0105             status->bOriginator,
0106             status->bValue[0] ? "pressed" : "released", len);
0107         uvc_input_report_key(dev, KEY_CAMERA, status->bValue[0]);
0108     } else {
0109         uvc_dbg(dev, STATUS, "Stream %u error event %02x len %d\n",
0110             status->bOriginator, status->bEvent, len);
0111     }
0112 }
0113 
0114 #define UVC_CTRL_VALUE_CHANGE   0
0115 #define UVC_CTRL_INFO_CHANGE    1
0116 #define UVC_CTRL_FAILURE_CHANGE 2
0117 #define UVC_CTRL_MIN_CHANGE 3
0118 #define UVC_CTRL_MAX_CHANGE 4
0119 
0120 static struct uvc_control *uvc_event_entity_find_ctrl(struct uvc_entity *entity,
0121                               u8 selector)
0122 {
0123     struct uvc_control *ctrl;
0124     unsigned int i;
0125 
0126     for (i = 0, ctrl = entity->controls; i < entity->ncontrols; i++, ctrl++)
0127         if (ctrl->info.selector == selector)
0128             return ctrl;
0129 
0130     return NULL;
0131 }
0132 
0133 static struct uvc_control *uvc_event_find_ctrl(struct uvc_device *dev,
0134                     const struct uvc_control_status *status,
0135                     struct uvc_video_chain **chain)
0136 {
0137     list_for_each_entry((*chain), &dev->chains, list) {
0138         struct uvc_entity *entity;
0139         struct uvc_control *ctrl;
0140 
0141         list_for_each_entry(entity, &(*chain)->entities, chain) {
0142             if (entity->id != status->bOriginator)
0143                 continue;
0144 
0145             ctrl = uvc_event_entity_find_ctrl(entity,
0146                               status->bSelector);
0147             if (ctrl)
0148                 return ctrl;
0149         }
0150     }
0151 
0152     return NULL;
0153 }
0154 
0155 static bool uvc_event_control(struct urb *urb,
0156                   const struct uvc_control_status *status, int len)
0157 {
0158     static const char *attrs[] = { "value", "info", "failure", "min", "max" };
0159     struct uvc_device *dev = urb->context;
0160     struct uvc_video_chain *chain;
0161     struct uvc_control *ctrl;
0162 
0163     if (len < 6 || status->bEvent != 0 ||
0164         status->bAttribute >= ARRAY_SIZE(attrs)) {
0165         uvc_dbg(dev, STATUS, "Invalid control status event received\n");
0166         return false;
0167     }
0168 
0169     uvc_dbg(dev, STATUS, "Control %u/%u %s change len %d\n",
0170         status->bOriginator, status->bSelector,
0171         attrs[status->bAttribute], len);
0172 
0173     /* Find the control. */
0174     ctrl = uvc_event_find_ctrl(dev, status, &chain);
0175     if (!ctrl)
0176         return false;
0177 
0178     switch (status->bAttribute) {
0179     case UVC_CTRL_VALUE_CHANGE:
0180         return uvc_ctrl_status_event_async(urb, chain, ctrl,
0181                            status->bValue);
0182 
0183     case UVC_CTRL_INFO_CHANGE:
0184     case UVC_CTRL_FAILURE_CHANGE:
0185     case UVC_CTRL_MIN_CHANGE:
0186     case UVC_CTRL_MAX_CHANGE:
0187         break;
0188     }
0189 
0190     return false;
0191 }
0192 
0193 static void uvc_status_complete(struct urb *urb)
0194 {
0195     struct uvc_device *dev = urb->context;
0196     int len, ret;
0197 
0198     switch (urb->status) {
0199     case 0:
0200         break;
0201 
0202     case -ENOENT:       /* usb_kill_urb() called. */
0203     case -ECONNRESET:   /* usb_unlink_urb() called. */
0204     case -ESHUTDOWN:    /* The endpoint is being disabled. */
0205     case -EPROTO:       /* Device is disconnected (reported by some host controllers). */
0206         return;
0207 
0208     default:
0209         dev_warn(&dev->udev->dev,
0210              "Non-zero status (%d) in status completion handler.\n",
0211              urb->status);
0212         return;
0213     }
0214 
0215     len = urb->actual_length;
0216     if (len > 0) {
0217         switch (dev->status[0] & 0x0f) {
0218         case UVC_STATUS_TYPE_CONTROL: {
0219             struct uvc_control_status *status =
0220                 (struct uvc_control_status *)dev->status;
0221 
0222             if (uvc_event_control(urb, status, len))
0223                 /* The URB will be resubmitted in work context. */
0224                 return;
0225             break;
0226         }
0227 
0228         case UVC_STATUS_TYPE_STREAMING: {
0229             struct uvc_streaming_status *status =
0230                 (struct uvc_streaming_status *)dev->status;
0231 
0232             uvc_event_streaming(dev, status, len);
0233             break;
0234         }
0235 
0236         default:
0237             uvc_dbg(dev, STATUS, "Unknown status event type %u\n",
0238                 dev->status[0]);
0239             break;
0240         }
0241     }
0242 
0243     /* Resubmit the URB. */
0244     urb->interval = dev->int_ep->desc.bInterval;
0245     ret = usb_submit_urb(urb, GFP_ATOMIC);
0246     if (ret < 0)
0247         dev_err(&dev->udev->dev,
0248             "Failed to resubmit status URB (%d).\n", ret);
0249 }
0250 
0251 int uvc_status_init(struct uvc_device *dev)
0252 {
0253     struct usb_host_endpoint *ep = dev->int_ep;
0254     unsigned int pipe;
0255     int interval;
0256 
0257     if (ep == NULL)
0258         return 0;
0259 
0260     uvc_input_init(dev);
0261 
0262     dev->status = kzalloc(UVC_MAX_STATUS_SIZE, GFP_KERNEL);
0263     if (dev->status == NULL)
0264         return -ENOMEM;
0265 
0266     dev->int_urb = usb_alloc_urb(0, GFP_KERNEL);
0267     if (dev->int_urb == NULL) {
0268         kfree(dev->status);
0269         return -ENOMEM;
0270     }
0271 
0272     pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);
0273 
0274     /*
0275      * For high-speed interrupt endpoints, the bInterval value is used as
0276      * an exponent of two. Some developers forgot about it.
0277      */
0278     interval = ep->desc.bInterval;
0279     if (interval > 16 && dev->udev->speed == USB_SPEED_HIGH &&
0280         (dev->quirks & UVC_QUIRK_STATUS_INTERVAL))
0281         interval = fls(interval) - 1;
0282 
0283     usb_fill_int_urb(dev->int_urb, dev->udev, pipe,
0284         dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete,
0285         dev, interval);
0286 
0287     return 0;
0288 }
0289 
0290 void uvc_status_unregister(struct uvc_device *dev)
0291 {
0292     usb_kill_urb(dev->int_urb);
0293     uvc_input_unregister(dev);
0294 }
0295 
0296 void uvc_status_cleanup(struct uvc_device *dev)
0297 {
0298     usb_free_urb(dev->int_urb);
0299     kfree(dev->status);
0300 }
0301 
0302 int uvc_status_start(struct uvc_device *dev, gfp_t flags)
0303 {
0304     if (dev->int_urb == NULL)
0305         return 0;
0306 
0307     return usb_submit_urb(dev->int_urb, flags);
0308 }
0309 
0310 void uvc_status_stop(struct uvc_device *dev)
0311 {
0312     usb_kill_urb(dev->int_urb);
0313 }