216 lines · 5.4 KB · C
RawDownload
/* SPDX-License-Identifier: GPL-2.0+ *//* *	uvc_gadget.h  --  USB Video Class Gadget driver * *	Copyright (C) 2009-2010 *	    Laurent Pinchart (laurent.pinchart@ideasonboard.com) */ #ifndef _UVC_GADGET_H_#define _UVC_GADGET_H_ #include <linux/list.h>#include <linux/mutex.h>#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>#include <media/v4l2-fh.h> #include "uvc_queue.h" struct usb_ep;struct usb_request;struct uvc_descriptor_header;struct uvc_device; /* ------------------------------------------------------------------------ * Debugging, printing and logging */ #define UVC_TRACE_PROBE				(1 << 0)#define UVC_TRACE_DESCR				(1 << 1)#define UVC_TRACE_CONTROL			(1 << 2)#define UVC_TRACE_FORMAT			(1 << 3)#define UVC_TRACE_CAPTURE			(1 << 4)#define UVC_TRACE_CALLS				(1 << 5)#define UVC_TRACE_IOCTL				(1 << 6)#define UVC_TRACE_FRAME				(1 << 7)#define UVC_TRACE_SUSPEND			(1 << 8)#define UVC_TRACE_STATUS			(1 << 9) #define UVC_WARN_MINMAX				0#define UVC_WARN_PROBE_DEF			1 extern unsigned int uvc_gadget_trace_param; #define uvc_trace(flag, msg...) \	do { \		if (uvc_gadget_trace_param & flag) \			printk(KERN_DEBUG "uvcvideo: " msg); \	} while (0) #define uvcg_dbg(f, fmt, args...) \	dev_dbg(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args)#define uvcg_info(f, fmt, args...) \	dev_info(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args)#define uvcg_warn(f, fmt, args...) \	dev_warn(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args)#define uvcg_err(f, fmt, args...) \	dev_err(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args) /* ------------------------------------------------------------------------ * Driver specific constants */ #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;	u32 fcc;	unsigned int width;	unsigned int height;	unsigned int imagesize;	unsigned int interval;	/* in 100ns units */	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;	unsigned int max_req_size;	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); 	/* Context data used by the completion handler */	__u32 payload_size;	__u32 max_payload_size; 	struct uvc_video_queue queue;	unsigned int fid;}; enum uvc_state {	UVC_STATE_DISCONNECTED,	UVC_STATE_CONNECTED,	UVC_STATE_STREAMING,}; struct uvc_device {	struct video_device vdev;	struct v4l2_device v4l2_dev;	enum uvc_state state;	struct usb_function func;	struct uvc_video video;	struct completion *vdev_release_done;	struct mutex lock;	/* protects func_unbound and func_connected */	bool func_unbound;	bool func_connected;	wait_queue_head_t func_connected_queue; 	struct uvcg_streaming_header *header; 	/* Descriptors */	struct {		const struct uvc_descriptor_header * const *fs_control;		const struct uvc_descriptor_header * const *ss_control;		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 *interrupt_ep;	struct usb_request *control_req;	void *control_buf;	bool enable_interrupt_ep; 	unsigned int streaming_intf; 	/* Events */	unsigned int event_length;	unsigned int event_setup_out : 1;}; static inline struct uvc_device *to_uvc(struct usb_function *f){	return container_of(f, struct uvc_device, func);} 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, int disable_ep);extern void uvc_function_connect(struct uvc_device *uvc);extern void uvc_function_disconnect(struct uvc_device *uvc); #endif /* _UVC_GADGET_H_ */