| 1 |
|
| 2 | |
| 3 | * uvc_gadget.h -- USB Video Class Gadget driver
|
| 4 | *
|
| 5 | * Copyright (C) 2009-2010
|
| 6 | * Laurent Pinchart ([email protected])
|
| 7 |
|
| 8 |
|
| 9 | #ifndef _UVC_GADGET_H_
|
| 10 | #define _UVC_GADGET_H_
|
| 11 |
|
| 12 | #include <linux/list.h>
|
| 13 | #include <linux/mutex.h>
|
| 14 | #include <linux/spinlock.h>
|
| 15 | #include <linux/usb/composite.h>
|
| 16 | #include <linux/videodev2.h>
|
| 17 | #include <linux/wait.h>
|
| 18 |
|
| 19 | #include <media/v4l2-device.h>
|
| 20 | #include <media/v4l2-dev.h>
|
| 21 | #include <media/v4l2-fh.h>
|
| 22 |
|
| 23 | #include "uvc_queue.h"
|
| 24 |
|
| 25 | struct usb_ep;
|
| 26 | struct usb_request;
|
| 27 | struct uvc_descriptor_header;
|
| 28 | struct uvc_device;
|
| 29 |
|
| 30 | |
| 31 | * Debugging, printing and logging
|
| 32 |
|
| 33 |
|
| 34 | #define UVC_TRACE_PROBE (1 << 0)
|
| 35 | #define UVC_TRACE_DESCR (1 << 1)
|
| 36 | #define UVC_TRACE_CONTROL (1 << 2)
|
| 37 | #define UVC_TRACE_FORMAT (1 << 3)
|
| 38 | #define UVC_TRACE_CAPTURE (1 << 4)
|
| 39 | #define UVC_TRACE_CALLS (1 << 5)
|
| 40 | #define UVC_TRACE_IOCTL (1 << 6)
|
| 41 | #define UVC_TRACE_FRAME (1 << 7)
|
| 42 | #define UVC_TRACE_SUSPEND (1 << 8)
|
| 43 | #define UVC_TRACE_STATUS (1 << 9)
|
| 44 |
|
| 45 | #define UVC_WARN_MINMAX 0
|
| 46 | #define UVC_WARN_PROBE_DEF 1
|
| 47 |
|
| 48 | extern unsigned int uvc_gadget_trace_param;
|
| 49 |
|
| 50 | #define uvc_trace(flag, msg...) \
|
| 51 | do { \
|
| 52 | if (uvc_gadget_trace_param & flag) \
|
| 53 | printk(KERN_DEBUG "uvcvideo: " msg); \
|
| 54 | } while (0)
|
| 55 |
|
| 56 | #define uvcg_dbg(f, fmt, args...) \
|
| 57 | dev_dbg(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args)
|
| 58 | #define uvcg_info(f, fmt, args...) \
|
| 59 | dev_info(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args)
|
| 60 | #define uvcg_warn(f, fmt, args...) \
|
| 61 | dev_warn(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args)
|
| 62 | #define uvcg_err(f, fmt, args...) \
|
| 63 | dev_err(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args)
|
| 64 |
|
| 65 | |
| 66 | * Driver specific constants
|
| 67 |
|
| 68 |
|
| 69 | #define UVC_MAX_REQUEST_SIZE 64
|
| 70 | #define UVC_MAX_EVENTS 4
|
| 71 |
|
| 72 | #define UVCG_REQUEST_HEADER_LEN 12
|
| 73 |
|
| 74 | #define UVCG_REQ_MAX_INT_COUNT 16
|
| 75 | #define UVCG_REQ_MAX_ZERO_COUNT (2 * UVCG_REQ_MAX_INT_COUNT)
|
| 76 |
|
| 77 | #define UVCG_STREAMING_MIN_BUFFERS 2
|
| 78 |
|
| 79 | |
| 80 | * Structures
|
| 81 |
|
| 82 | struct uvc_request {
|
| 83 | struct usb_request *req;
|
| 84 | u8 *req_buffer;
|
| 85 | struct uvc_video *video;
|
| 86 | struct sg_table sgt;
|
| 87 | u8 header[UVCG_REQUEST_HEADER_LEN];
|
| 88 | struct uvc_buffer *last_buf;
|
| 89 | struct list_head list;
|
| 90 | };
|
| 91 |
|
| 92 | struct uvc_video {
|
| 93 | struct uvc_device *uvc;
|
| 94 | struct usb_ep *ep;
|
| 95 |
|
| 96 | struct work_struct pump;
|
| 97 | struct workqueue_struct *async_wq;
|
| 98 |
|
| 99 | struct kthread_worker *kworker;
|
| 100 | struct kthread_work hw_submit;
|
| 101 |
|
| 102 | atomic_t queued;
|
| 103 |
|
| 104 |
|
| 105 | u8 bpp;
|
| 106 | u32 fcc;
|
| 107 | unsigned int width;
|
| 108 | unsigned int height;
|
| 109 | unsigned int imagesize;
|
| 110 | unsigned int interval;
|
| 111 | struct mutex mutex;
|
| 112 |
|
| 113 | unsigned int uvc_num_requests;
|
| 114 |
|
| 115 | unsigned int reqs_per_frame;
|
| 116 |
|
| 117 |
|
| 118 | bool is_enabled;
|
| 119 | unsigned int req_size;
|
| 120 | unsigned int max_req_size;
|
| 121 | struct list_head ureqs;
|
| 122 |
|
| 123 |
|
| 124 | struct list_head req_free;
|
| 125 |
|
| 126 | |
| 127 | * USB requests video pump thread has already encoded into. These are
|
| 128 | * ready to be queued to the endpoint.
|
| 129 |
|
| 130 | struct list_head req_ready;
|
| 131 | spinlock_t req_lock;
|
| 132 |
|
| 133 | unsigned int req_int_count;
|
| 134 |
|
| 135 | void (*encode) (struct usb_request *req, struct uvc_video *video,
|
| 136 | struct uvc_buffer *buf);
|
| 137 |
|
| 138 |
|
| 139 | __u32 payload_size;
|
| 140 | __u32 max_payload_size;
|
| 141 |
|
| 142 | struct uvc_video_queue queue;
|
| 143 | unsigned int fid;
|
| 144 | };
|
| 145 |
|
| 146 | enum uvc_state {
|
| 147 | UVC_STATE_DISCONNECTED,
|
| 148 | UVC_STATE_CONNECTED,
|
| 149 | UVC_STATE_STREAMING,
|
| 150 | };
|
| 151 |
|
| 152 | struct uvc_device {
|
| 153 | struct video_device vdev;
|
| 154 | struct v4l2_device v4l2_dev;
|
| 155 | enum uvc_state state;
|
| 156 | struct usb_function func;
|
| 157 | struct uvc_video video;
|
| 158 | struct completion *vdev_release_done;
|
| 159 | struct mutex lock;
|
| 160 | bool func_unbound;
|
| 161 | bool func_connected;
|
| 162 | wait_queue_head_t func_connected_queue;
|
| 163 |
|
| 164 | struct uvcg_streaming_header *header;
|
| 165 |
|
| 166 |
|
| 167 | struct {
|
| 168 | const struct uvc_descriptor_header * const *fs_control;
|
| 169 | const struct uvc_descriptor_header * const *ss_control;
|
| 170 | const struct uvc_descriptor_header * const *fs_streaming;
|
| 171 | const struct uvc_descriptor_header * const *hs_streaming;
|
| 172 | const struct uvc_descriptor_header * const *ss_streaming;
|
| 173 | struct list_head *extension_units;
|
| 174 | } desc;
|
| 175 |
|
| 176 | unsigned int control_intf;
|
| 177 | struct usb_ep *interrupt_ep;
|
| 178 | struct usb_request *control_req;
|
| 179 | void *control_buf;
|
| 180 | bool enable_interrupt_ep;
|
| 181 |
|
| 182 | unsigned int streaming_intf;
|
| 183 |
|
| 184 |
|
| 185 | unsigned int event_length;
|
| 186 | unsigned int event_setup_out : 1;
|
| 187 | };
|
| 188 |
|
| 189 | static inline struct uvc_device *to_uvc(struct usb_function *f)
|
| 190 | {
|
| 191 | return container_of(f, struct uvc_device, func);
|
| 192 | }
|
| 193 |
|
| 194 | struct uvc_file_handle {
|
| 195 | struct v4l2_fh vfh;
|
| 196 | struct uvc_video *device;
|
| 197 | bool is_uvc_app_handle;
|
| 198 | };
|
| 199 |
|
| 200 | #define to_uvc_file_handle(handle) \
|
| 201 | container_of(handle, struct uvc_file_handle, vfh)
|
| 202 |
|
| 203 | static inline struct uvc_file_handle *file_to_uvc_file_handle(struct file *filp)
|
| 204 | {
|
| 205 | return container_of(file_to_v4l2_fh(filp), struct uvc_file_handle, vfh);
|
| 206 | }
|
| 207 |
|
| 208 | |
| 209 | * Functions
|
| 210 |
|
| 211 |
|
| 212 | extern void uvc_function_setup_continue(struct uvc_device *uvc, int disable_ep);
|
| 213 | extern void uvc_function_connect(struct uvc_device *uvc);
|
| 214 | extern void uvc_function_disconnect(struct uvc_device *uvc);
|
| 215 |
|
| 216 | #endif
|