summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/function/uvc.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/function/uvc.h')
-rw-r--r--drivers/usb/gadget/function/uvc.h61
1 files changed, 54 insertions, 7 deletions
diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h
index 23ee25383c1f..9e79cbe50715 100644
--- a/drivers/usb/gadget/function/uvc.h
+++ b/drivers/usb/gadget/function/uvc.h
@@ -14,6 +14,7 @@
#include <linux/spinlock.h>
#include <linux/usb/composite.h>
#include <linux/videodev2.h>
+#include <linux/wait.h>
#include <media/v4l2-device.h>
#include <media/v4l2-dev.h>
@@ -65,19 +66,40 @@ extern unsigned int uvc_gadget_trace_param;
* Driver specific constants
*/
-#define UVC_NUM_REQUESTS 4
#define UVC_MAX_REQUEST_SIZE 64
#define UVC_MAX_EVENTS 4
+#define UVCG_REQUEST_HEADER_LEN 12
+
+#define UVCG_REQ_MAX_INT_COUNT 16
+#define UVCG_REQ_MAX_ZERO_COUNT (2 * UVCG_REQ_MAX_INT_COUNT)
+
+#define UVCG_STREAMING_MIN_BUFFERS 2
+
/* ------------------------------------------------------------------------
* Structures
*/
+struct uvc_request {
+ struct usb_request *req;
+ u8 *req_buffer;
+ struct uvc_video *video;
+ struct sg_table sgt;
+ u8 header[UVCG_REQUEST_HEADER_LEN];
+ struct uvc_buffer *last_buf;
+ struct list_head list;
+};
struct uvc_video {
struct uvc_device *uvc;
struct usb_ep *ep;
struct work_struct pump;
+ struct workqueue_struct *async_wq;
+
+ struct kthread_worker *kworker;
+ struct kthread_work hw_submit;
+
+ atomic_t queued;
/* Frame parameters */
u8 bpp;
@@ -85,15 +107,30 @@ struct uvc_video {
unsigned int width;
unsigned int height;
unsigned int imagesize;
+ unsigned int interval;
struct mutex mutex; /* protects frame parameters */
+ unsigned int uvc_num_requests;
+
+ unsigned int reqs_per_frame;
+
/* Requests */
+ bool is_enabled; /* tracks whether video stream is enabled */
unsigned int req_size;
- struct usb_request *req[UVC_NUM_REQUESTS];
- __u8 *req_buffer[UVC_NUM_REQUESTS];
+ struct list_head ureqs; /* all uvc_requests allocated by uvc_video */
+
+ /* USB requests that the video pump thread can encode into */
struct list_head req_free;
+
+ /*
+ * USB requests video pump thread has already encoded into. These are
+ * ready to be queued to the endpoint.
+ */
+ struct list_head req_ready;
spinlock_t req_lock;
+ unsigned int req_int_count;
+
void (*encode) (struct usb_request *req, struct uvc_video *video,
struct uvc_buffer *buf);
@@ -117,6 +154,10 @@ struct uvc_device {
enum uvc_state state;
struct usb_function func;
struct uvc_video video;
+ bool func_connected;
+ wait_queue_head_t func_connected_queue;
+
+ struct uvcg_streaming_header *header;
/* Descriptors */
struct {
@@ -125,12 +166,14 @@ struct uvc_device {
const struct uvc_descriptor_header * const *fs_streaming;
const struct uvc_descriptor_header * const *hs_streaming;
const struct uvc_descriptor_header * const *ss_streaming;
+ struct list_head *extension_units;
} desc;
unsigned int control_intf;
- struct usb_ep *control_ep;
+ struct usb_ep *interrupt_ep;
struct usb_request *control_req;
void *control_buf;
+ bool enable_interrupt_ep;
unsigned int streaming_intf;
@@ -147,18 +190,22 @@ static inline struct uvc_device *to_uvc(struct usb_function *f)
struct uvc_file_handle {
struct v4l2_fh vfh;
struct uvc_video *device;
+ bool is_uvc_app_handle;
};
#define to_uvc_file_handle(handle) \
container_of(handle, struct uvc_file_handle, vfh)
+static inline struct uvc_file_handle *file_to_uvc_file_handle(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct uvc_file_handle, vfh);
+}
+
/* ------------------------------------------------------------------------
* Functions
*/
-extern void uvc_function_setup_continue(struct uvc_device *uvc);
-extern void uvc_endpoint_stream(struct uvc_device *dev);
-
+extern void uvc_function_setup_continue(struct uvc_device *uvc, int disable_ep);
extern void uvc_function_connect(struct uvc_device *uvc);
extern void uvc_function_disconnect(struct uvc_device *uvc);