diff options
Diffstat (limited to 'drivers/media/usb/uvc/uvcvideo.h')
| -rw-r--r-- | drivers/media/usb/uvc/uvcvideo.h | 139 |
1 files changed, 70 insertions, 69 deletions
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 3653b2c8a86c..ed7bad31f75c 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -41,6 +41,8 @@ #define UVC_EXT_GPIO_UNIT 0x7ffe #define UVC_EXT_GPIO_UNIT_ID 0x100 +#define UVC_INVALID_ENTITY_ID 0xffff + /* ------------------------------------------------------------------------ * Driver specific constants. */ @@ -75,6 +77,9 @@ #define UVC_QUIRK_WAKE_AUTOSUSPEND 0x00002000 #define UVC_QUIRK_NO_RESET_RESUME 0x00004000 #define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000 +#define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000 +#define UVC_QUIRK_MJPEG_NO_EOF 0x00020000 +#define UVC_QUIRK_MSXU_META 0x00040000 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 @@ -86,7 +91,9 @@ struct gpio_desc; struct sg_table; +struct uvc_control; struct uvc_device; +struct uvc_video_chain; /* * TODO: Put the most frequently accessed fields at the beginning of @@ -112,7 +119,12 @@ struct uvc_control_mapping { u8 entity[16]; u8 selector; + /* + * Size of the control data in the payload of the UVC control GET and + * SET requests, expressed in bits. + */ u8 size; + u8 offset; enum v4l2_ctrl_type v4l2_type; u32 data_type; @@ -125,10 +137,15 @@ struct uvc_control_mapping { s32 master_manual; u32 slave_ids[2]; - s32 (*get)(struct uvc_control_mapping *mapping, u8 query, - const u8 *data); - void (*set)(struct uvc_control_mapping *mapping, s32 value, - u8 *data); + bool disabled; + + const struct uvc_control_mapping *(*filter_mapping) + (struct uvc_video_chain *chain, + struct uvc_control *ctrl); + int (*get)(struct uvc_control_mapping *mapping, u8 query, + const void *uvc_in, size_t v4l2_size, void *v4l2_out); + int (*set)(struct uvc_control_mapping *mapping, size_t v4l2_size, + const void *v4l2_in, void *uvc_out); }; struct uvc_control { @@ -228,6 +245,7 @@ struct uvc_entity { u8 *bmControls; struct gpio_desc *gpio_privacy; int irq; + bool initialized; } gpio; }; @@ -310,11 +328,14 @@ struct uvc_buffer { }; #define UVC_QUEUE_DISCONNECTED (1 << 0) -#define UVC_QUEUE_DROP_CORRUPTED (1 << 1) struct uvc_video_queue { + struct video_device vdev; struct vb2_queue queue; - struct mutex mutex; /* Protects queue */ + struct mutex mutex; /* + * Serializes vb2_queue and + * fops + */ unsigned int flags; unsigned int buf_used; @@ -331,7 +352,11 @@ struct uvc_video_chain { struct uvc_entity *processing; /* Processing unit */ struct uvc_entity *selector; /* Selector unit */ - struct mutex ctrl_mutex; /* Protects ctrl.info */ + struct mutex ctrl_mutex; /* + * Protects ctrl.info, + * ctrl.handle and + * uvc_fh.pending_async_ctrls + */ struct v4l2_prio_state prio; /* V4L2 priority state */ u32 caps; /* V4L2 chain-wide caps */ @@ -428,13 +453,12 @@ struct uvc_urb { struct uvc_streaming { struct list_head list; struct uvc_device *dev; - struct video_device vdev; struct uvc_video_chain *chain; atomic_t active; struct usb_interface *intf; int intfnum; - u16 maxpsize; + u32 maxpsize; struct uvc_streaming_header header; enum v4l2_buf_type type; @@ -447,12 +471,6 @@ struct uvc_streaming { const struct uvc_format *cur_format; const struct uvc_frame *cur_frame; - /* - * Protect access to ctrl, cur_format, cur_frame and hardware video - * probe control. - */ - struct mutex mutex; - /* Buffers queue. */ unsigned int frozen : 1; struct uvc_video_queue queue; @@ -461,7 +479,6 @@ struct uvc_streaming { struct uvc_buffer *meta_buf); struct { - struct video_device vdev; struct uvc_video_queue queue; u32 format; } meta; @@ -500,6 +517,7 @@ struct uvc_streaming { unsigned int head; unsigned int count; unsigned int size; + unsigned int last_sof_overflow; u16 last_sof; u16 sof_offset; @@ -524,9 +542,15 @@ struct uvc_device_info { u32 quirks; u32 meta_format; u16 uvc_version; - const struct uvc_control_mapping **mappings; }; +struct uvc_rect { + u16 top; + u16 left; + u16 bottom; + u16 right; +} __packed; + struct uvc_status_streaming { u8 button; } __packed; @@ -547,6 +571,8 @@ struct uvc_status { }; } __packed; +#define UVC_MAX_META_DATA_FORMATS 3 + struct uvc_device { struct usb_device *udev; struct usb_interface *intf; @@ -557,8 +583,9 @@ struct uvc_device { const struct uvc_device_info *info; - struct mutex lock; /* Protects users */ - unsigned int users; + u32 meta_formats[UVC_MAX_META_DATA_FORMATS]; + unsigned int nmeta_formats; + atomic_t nmappings; /* Video control interface */ @@ -580,6 +607,8 @@ struct uvc_device { struct usb_host_endpoint *int_ep; struct urb *int_urb; struct uvc_status *status; + struct mutex status_lock; /* Protects status_users */ + unsigned int status_users; bool flush_status; struct input_dev *input; @@ -596,21 +625,17 @@ struct uvc_device { struct uvc_entity *gpio_unit; }; -enum uvc_handle_state { - UVC_HANDLE_PASSIVE = 0, - UVC_HANDLE_ACTIVE = 1, -}; - struct uvc_fh { struct v4l2_fh vfh; struct uvc_video_chain *chain; struct uvc_streaming *stream; - enum uvc_handle_state state; + unsigned int pending_async_ctrls; }; -struct uvc_driver { - struct usb_driver driver; -}; +static inline struct uvc_fh *to_uvc_fh(struct file *filp) +{ + return container_of(file_to_v4l2_fh(filp), struct uvc_fh, vfh); +} /* ------------------------------------------------------------------------ * Debugging, printing and logging @@ -642,7 +667,7 @@ extern unsigned int uvc_hw_timestamps_param; #define uvc_dbg(_dev, flag, fmt, ...) \ do { \ if (uvc_dbg_param & UVC_DBG_##flag) \ - dev_printk(KERN_DEBUG, &(_dev)->udev->dev, fmt, \ + dev_printk(KERN_DEBUG, &(_dev)->intf->dev, fmt, \ ##__VA_ARGS__); \ } while (0) @@ -655,51 +680,22 @@ do { \ #define uvc_warn_once(_dev, warn, fmt, ...) \ do { \ if (!test_and_set_bit(warn, &(_dev)->warnings)) \ - dev_info(&(_dev)->udev->dev, fmt, ##__VA_ARGS__); \ + dev_info(&(_dev)->intf->dev, fmt, ##__VA_ARGS__); \ } while (0) /* -------------------------------------------------------------------------- * Internal functions. */ -/* Core driver */ -extern struct uvc_driver uvc_driver; - struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); /* Video buffers queue management. */ -int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, - int drop_corrupted); -void uvc_queue_release(struct uvc_video_queue *queue); -int uvc_request_buffers(struct uvc_video_queue *queue, - struct v4l2_requestbuffers *rb); -int uvc_query_buffer(struct uvc_video_queue *queue, - struct v4l2_buffer *v4l2_buf); -int uvc_create_buffers(struct uvc_video_queue *queue, - struct v4l2_create_buffers *v4l2_cb); -int uvc_queue_buffer(struct uvc_video_queue *queue, - struct media_device *mdev, - struct v4l2_buffer *v4l2_buf); -int uvc_export_buffer(struct uvc_video_queue *queue, - struct v4l2_exportbuffer *exp); -int uvc_dequeue_buffer(struct uvc_video_queue *queue, - struct v4l2_buffer *v4l2_buf, int nonblocking); -int uvc_queue_streamon(struct uvc_video_queue *queue, enum v4l2_buf_type type); -int uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type); +int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type); void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf); struct uvc_buffer *uvc_queue_get_current_buffer(struct uvc_video_queue *queue); void uvc_queue_buffer_release(struct uvc_buffer *buf); -int uvc_queue_mmap(struct uvc_video_queue *queue, - struct vm_area_struct *vma); -__poll_t uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, - poll_table *wait); -#ifndef CONFIG_MMU -unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, - unsigned long pgoff); -#endif -int uvc_queue_allocated(struct uvc_video_queue *queue); static inline int uvc_queue_streaming(struct uvc_video_queue *queue) { return vb2_is_streaming(&queue->queue); @@ -732,11 +728,11 @@ int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit, void uvc_video_clock_update(struct uvc_streaming *stream, struct vb2_v4l2_buffer *vbuf, struct uvc_buffer *buf); +int uvc_meta_init(struct uvc_device *dev); int uvc_meta_register(struct uvc_streaming *stream); int uvc_register_video_device(struct uvc_device *dev, struct uvc_streaming *stream, - struct video_device *vdev, struct uvc_video_queue *queue, enum v4l2_buf_type type, const struct v4l2_file_operations *fops, @@ -746,16 +742,20 @@ int uvc_register_video_device(struct uvc_device *dev, int uvc_status_init(struct uvc_device *dev); void uvc_status_unregister(struct uvc_device *dev); void uvc_status_cleanup(struct uvc_device *dev); -int uvc_status_start(struct uvc_device *dev, gfp_t flags); -void uvc_status_stop(struct uvc_device *dev); +int uvc_status_resume(struct uvc_device *dev); +void uvc_status_suspend(struct uvc_device *dev); +int uvc_status_get(struct uvc_device *dev); +void uvc_status_put(struct uvc_device *dev); + +/* PM */ +int uvc_pm_get(struct uvc_device *dev); +void uvc_pm_put(struct uvc_device *dev); /* Controls */ -extern const struct uvc_control_mapping uvc_ctrl_power_line_mapping_limited; -extern const struct uvc_control_mapping uvc_ctrl_power_line_mapping_uvc11; extern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops; int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, - struct v4l2_queryctrl *v4l2_ctrl); + struct v4l2_query_ext_ctrl *v4l2_ctrl); int uvc_query_v4l2_menu(struct uvc_video_chain *chain, struct v4l2_querymenu *query_menu); @@ -782,7 +782,8 @@ static inline int uvc_ctrl_rollback(struct uvc_fh *handle) return __uvc_ctrl_commit(handle, 1, NULL); } -int uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl); +int uvc_ctrl_get(struct uvc_video_chain *chain, u32 which, + struct v4l2_ext_control *xctrl); int uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl); int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id, const struct v4l2_ext_controls *ctrls, @@ -791,11 +792,11 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id, int uvc_xu_ctrl_query(struct uvc_video_chain *chain, struct uvc_xu_control_query *xqry); +void uvc_ctrl_cleanup_fh(struct uvc_fh *handle); + /* Utility functions */ struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts, u8 epaddr); -u16 uvc_endpoint_max_bpi(struct usb_device *dev, struct usb_host_endpoint *ep); - /* Quirks support */ void uvc_video_decode_isight(struct uvc_urb *uvc_urb, struct uvc_buffer *buf, |
