162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _USB_VIDEO_H_
362306a36Sopenharmony_ci#define _USB_VIDEO_H_
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#ifndef __KERNEL__
662306a36Sopenharmony_ci#error "The uvcvideo.h header is deprecated, use linux/uvcvideo.h instead."
762306a36Sopenharmony_ci#endif /* __KERNEL__ */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/atomic.h>
1062306a36Sopenharmony_ci#include <linux/kernel.h>
1162306a36Sopenharmony_ci#include <linux/poll.h>
1262306a36Sopenharmony_ci#include <linux/usb.h>
1362306a36Sopenharmony_ci#include <linux/usb/video.h>
1462306a36Sopenharmony_ci#include <linux/uvcvideo.h>
1562306a36Sopenharmony_ci#include <linux/videodev2.h>
1662306a36Sopenharmony_ci#include <linux/workqueue.h>
1762306a36Sopenharmony_ci#include <media/media-device.h>
1862306a36Sopenharmony_ci#include <media/v4l2-device.h>
1962306a36Sopenharmony_ci#include <media/v4l2-event.h>
2062306a36Sopenharmony_ci#include <media/v4l2-fh.h>
2162306a36Sopenharmony_ci#include <media/videobuf2-v4l2.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci/* --------------------------------------------------------------------------
2462306a36Sopenharmony_ci * UVC constants
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#define UVC_TERM_INPUT			0x0000
2862306a36Sopenharmony_ci#define UVC_TERM_OUTPUT			0x8000
2962306a36Sopenharmony_ci#define UVC_TERM_DIRECTION(term)	((term)->type & 0x8000)
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define UVC_ENTITY_TYPE(entity)		((entity)->type & 0x7fff)
3262306a36Sopenharmony_ci#define UVC_ENTITY_IS_UNIT(entity)	(((entity)->type & 0xff00) == 0)
3362306a36Sopenharmony_ci#define UVC_ENTITY_IS_TERM(entity)	(((entity)->type & 0xff00) != 0)
3462306a36Sopenharmony_ci#define UVC_ENTITY_IS_ITERM(entity) \
3562306a36Sopenharmony_ci	(UVC_ENTITY_IS_TERM(entity) && \
3662306a36Sopenharmony_ci	((entity)->type & 0x8000) == UVC_TERM_INPUT)
3762306a36Sopenharmony_ci#define UVC_ENTITY_IS_OTERM(entity) \
3862306a36Sopenharmony_ci	(UVC_ENTITY_IS_TERM(entity) && \
3962306a36Sopenharmony_ci	((entity)->type & 0x8000) == UVC_TERM_OUTPUT)
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#define UVC_EXT_GPIO_UNIT		0x7ffe
4262306a36Sopenharmony_ci#define UVC_EXT_GPIO_UNIT_ID		0x100
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/* ------------------------------------------------------------------------
4562306a36Sopenharmony_ci * Driver specific constants.
4662306a36Sopenharmony_ci */
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci#define DRIVER_VERSION		"1.1.1"
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci/* Number of isochronous URBs. */
5162306a36Sopenharmony_ci#define UVC_URBS		5
5262306a36Sopenharmony_ci/* Maximum number of packets per URB. */
5362306a36Sopenharmony_ci#define UVC_MAX_PACKETS		32
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci#define UVC_CTRL_CONTROL_TIMEOUT	5000
5662306a36Sopenharmony_ci#define UVC_CTRL_STREAMING_TIMEOUT	5000
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci/* Maximum allowed number of control mappings per device */
5962306a36Sopenharmony_ci#define UVC_MAX_CONTROL_MAPPINGS	1024
6062306a36Sopenharmony_ci#define UVC_MAX_CONTROL_MENU_ENTRIES	32
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci/* Devices quirks */
6362306a36Sopenharmony_ci#define UVC_QUIRK_STATUS_INTERVAL	0x00000001
6462306a36Sopenharmony_ci#define UVC_QUIRK_PROBE_MINMAX		0x00000002
6562306a36Sopenharmony_ci#define UVC_QUIRK_PROBE_EXTRAFIELDS	0x00000004
6662306a36Sopenharmony_ci#define UVC_QUIRK_BUILTIN_ISIGHT	0x00000008
6762306a36Sopenharmony_ci#define UVC_QUIRK_STREAM_NO_FID		0x00000010
6862306a36Sopenharmony_ci#define UVC_QUIRK_IGNORE_SELECTOR_UNIT	0x00000020
6962306a36Sopenharmony_ci#define UVC_QUIRK_FIX_BANDWIDTH		0x00000080
7062306a36Sopenharmony_ci#define UVC_QUIRK_PROBE_DEF		0x00000100
7162306a36Sopenharmony_ci#define UVC_QUIRK_RESTRICT_FRAME_RATE	0x00000200
7262306a36Sopenharmony_ci#define UVC_QUIRK_RESTORE_CTRLS_ON_INIT	0x00000400
7362306a36Sopenharmony_ci#define UVC_QUIRK_FORCE_Y8		0x00000800
7462306a36Sopenharmony_ci#define UVC_QUIRK_FORCE_BPP		0x00001000
7562306a36Sopenharmony_ci#define UVC_QUIRK_WAKE_AUTOSUSPEND	0x00002000
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci/* Format flags */
7862306a36Sopenharmony_ci#define UVC_FMT_FLAG_COMPRESSED		0x00000001
7962306a36Sopenharmony_ci#define UVC_FMT_FLAG_STREAM		0x00000002
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci/* ------------------------------------------------------------------------
8262306a36Sopenharmony_ci * Structures.
8362306a36Sopenharmony_ci */
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cistruct gpio_desc;
8662306a36Sopenharmony_cistruct sg_table;
8762306a36Sopenharmony_cistruct uvc_device;
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/*
9062306a36Sopenharmony_ci * TODO: Put the most frequently accessed fields at the beginning of
9162306a36Sopenharmony_ci * structures to maximize cache efficiency.
9262306a36Sopenharmony_ci */
9362306a36Sopenharmony_cistruct uvc_control_info {
9462306a36Sopenharmony_ci	struct list_head mappings;
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	u8 entity[16];
9762306a36Sopenharmony_ci	u8 index;	/* Bit index in bmControls */
9862306a36Sopenharmony_ci	u8 selector;
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	u16 size;
10162306a36Sopenharmony_ci	u32 flags;
10262306a36Sopenharmony_ci};
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_cistruct uvc_control_mapping {
10562306a36Sopenharmony_ci	struct list_head list;
10662306a36Sopenharmony_ci	struct list_head ev_subs;
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci	u32 id;
10962306a36Sopenharmony_ci	char *name;
11062306a36Sopenharmony_ci	u8 entity[16];
11162306a36Sopenharmony_ci	u8 selector;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	u8 size;
11462306a36Sopenharmony_ci	u8 offset;
11562306a36Sopenharmony_ci	enum v4l2_ctrl_type v4l2_type;
11662306a36Sopenharmony_ci	u32 data_type;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	const u32 *menu_mapping;
11962306a36Sopenharmony_ci	const char (*menu_names)[UVC_MENU_NAME_LEN];
12062306a36Sopenharmony_ci	unsigned long menu_mask;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	u32 master_id;
12362306a36Sopenharmony_ci	s32 master_manual;
12462306a36Sopenharmony_ci	u32 slave_ids[2];
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	s32 (*get)(struct uvc_control_mapping *mapping, u8 query,
12762306a36Sopenharmony_ci		   const u8 *data);
12862306a36Sopenharmony_ci	void (*set)(struct uvc_control_mapping *mapping, s32 value,
12962306a36Sopenharmony_ci		    u8 *data);
13062306a36Sopenharmony_ci};
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_cistruct uvc_control {
13362306a36Sopenharmony_ci	struct uvc_entity *entity;
13462306a36Sopenharmony_ci	struct uvc_control_info info;
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	u8 index;	/* Used to match the uvc_control entry with a uvc_control_info. */
13762306a36Sopenharmony_ci	u8 dirty:1,
13862306a36Sopenharmony_ci	   loaded:1,
13962306a36Sopenharmony_ci	   modified:1,
14062306a36Sopenharmony_ci	   cached:1,
14162306a36Sopenharmony_ci	   initialized:1;
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	u8 *uvc_data;
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci	struct uvc_fh *handle;	/* File handle that last changed the control. */
14662306a36Sopenharmony_ci};
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci/*
14962306a36Sopenharmony_ci * The term 'entity' refers to both UVC units and UVC terminals.
15062306a36Sopenharmony_ci *
15162306a36Sopenharmony_ci * The type field is either the terminal type (wTerminalType in the terminal
15262306a36Sopenharmony_ci * descriptor), or the unit type (bDescriptorSubtype in the unit descriptor).
15362306a36Sopenharmony_ci * As the bDescriptorSubtype field is one byte long, the type value will
15462306a36Sopenharmony_ci * always have a null MSB for units. All terminal types defined by the UVC
15562306a36Sopenharmony_ci * specification have a non-null MSB, so it is safe to use the MSB to
15662306a36Sopenharmony_ci * differentiate between units and terminals as long as the descriptor parsing
15762306a36Sopenharmony_ci * code makes sure terminal types have a non-null MSB.
15862306a36Sopenharmony_ci *
15962306a36Sopenharmony_ci * For terminals, the type's most significant bit stores the terminal
16062306a36Sopenharmony_ci * direction (either UVC_TERM_INPUT or UVC_TERM_OUTPUT). The type field should
16162306a36Sopenharmony_ci * always be accessed with the UVC_ENTITY_* macros and never directly.
16262306a36Sopenharmony_ci */
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci#define UVC_ENTITY_FLAG_DEFAULT		(1 << 0)
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_cistruct uvc_entity {
16762306a36Sopenharmony_ci	struct list_head list;		/* Entity as part of a UVC device. */
16862306a36Sopenharmony_ci	struct list_head chain;		/* Entity as part of a video device chain. */
16962306a36Sopenharmony_ci	unsigned int flags;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	/*
17262306a36Sopenharmony_ci	 * Entities exposed by the UVC device use IDs 0-255, extra entities
17362306a36Sopenharmony_ci	 * implemented by the driver (such as the GPIO entity) use IDs 256 and
17462306a36Sopenharmony_ci	 * up.
17562306a36Sopenharmony_ci	 */
17662306a36Sopenharmony_ci	u16 id;
17762306a36Sopenharmony_ci	u16 type;
17862306a36Sopenharmony_ci	char name[64];
17962306a36Sopenharmony_ci	u8 guid[16];
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	/* Media controller-related fields. */
18262306a36Sopenharmony_ci	struct video_device *vdev;
18362306a36Sopenharmony_ci	struct v4l2_subdev subdev;
18462306a36Sopenharmony_ci	unsigned int num_pads;
18562306a36Sopenharmony_ci	unsigned int num_links;
18662306a36Sopenharmony_ci	struct media_pad *pads;
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	union {
18962306a36Sopenharmony_ci		struct {
19062306a36Sopenharmony_ci			u16 wObjectiveFocalLengthMin;
19162306a36Sopenharmony_ci			u16 wObjectiveFocalLengthMax;
19262306a36Sopenharmony_ci			u16 wOcularFocalLength;
19362306a36Sopenharmony_ci			u8  bControlSize;
19462306a36Sopenharmony_ci			u8  *bmControls;
19562306a36Sopenharmony_ci		} camera;
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci		struct {
19862306a36Sopenharmony_ci			u8  bControlSize;
19962306a36Sopenharmony_ci			u8  *bmControls;
20062306a36Sopenharmony_ci			u8  bTransportModeSize;
20162306a36Sopenharmony_ci			u8  *bmTransportModes;
20262306a36Sopenharmony_ci		} media;
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci		struct {
20562306a36Sopenharmony_ci		} output;
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci		struct {
20862306a36Sopenharmony_ci			u16 wMaxMultiplier;
20962306a36Sopenharmony_ci			u8  bControlSize;
21062306a36Sopenharmony_ci			u8  *bmControls;
21162306a36Sopenharmony_ci			u8  bmVideoStandards;
21262306a36Sopenharmony_ci		} processing;
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci		struct {
21562306a36Sopenharmony_ci		} selector;
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci		struct {
21862306a36Sopenharmony_ci			u8  bNumControls;
21962306a36Sopenharmony_ci			u8  bControlSize;
22062306a36Sopenharmony_ci			u8  *bmControls;
22162306a36Sopenharmony_ci			u8  *bmControlsType;
22262306a36Sopenharmony_ci		} extension;
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci		struct {
22562306a36Sopenharmony_ci			u8  bControlSize;
22662306a36Sopenharmony_ci			u8  *bmControls;
22762306a36Sopenharmony_ci			struct gpio_desc *gpio_privacy;
22862306a36Sopenharmony_ci			int irq;
22962306a36Sopenharmony_ci		} gpio;
23062306a36Sopenharmony_ci	};
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	u8 bNrInPins;
23362306a36Sopenharmony_ci	u8 *baSourceID;
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci	int (*get_info)(struct uvc_device *dev, struct uvc_entity *entity,
23662306a36Sopenharmony_ci			u8 cs, u8 *caps);
23762306a36Sopenharmony_ci	int (*get_cur)(struct uvc_device *dev, struct uvc_entity *entity,
23862306a36Sopenharmony_ci		       u8 cs, void *data, u16 size);
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	unsigned int ncontrols;
24162306a36Sopenharmony_ci	struct uvc_control *controls;
24262306a36Sopenharmony_ci};
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_cistruct uvc_frame {
24562306a36Sopenharmony_ci	u8  bFrameIndex;
24662306a36Sopenharmony_ci	u8  bmCapabilities;
24762306a36Sopenharmony_ci	u16 wWidth;
24862306a36Sopenharmony_ci	u16 wHeight;
24962306a36Sopenharmony_ci	u32 dwMinBitRate;
25062306a36Sopenharmony_ci	u32 dwMaxBitRate;
25162306a36Sopenharmony_ci	u32 dwMaxVideoFrameBufferSize;
25262306a36Sopenharmony_ci	u8  bFrameIntervalType;
25362306a36Sopenharmony_ci	u32 dwDefaultFrameInterval;
25462306a36Sopenharmony_ci	const u32 *dwFrameInterval;
25562306a36Sopenharmony_ci};
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_cistruct uvc_format {
25862306a36Sopenharmony_ci	u8 type;
25962306a36Sopenharmony_ci	u8 index;
26062306a36Sopenharmony_ci	u8 bpp;
26162306a36Sopenharmony_ci	enum v4l2_colorspace colorspace;
26262306a36Sopenharmony_ci	enum v4l2_xfer_func xfer_func;
26362306a36Sopenharmony_ci	enum v4l2_ycbcr_encoding ycbcr_enc;
26462306a36Sopenharmony_ci	u32 fcc;
26562306a36Sopenharmony_ci	u32 flags;
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	unsigned int nframes;
26862306a36Sopenharmony_ci	const struct uvc_frame *frames;
26962306a36Sopenharmony_ci};
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_cistruct uvc_streaming_header {
27262306a36Sopenharmony_ci	u8 bNumFormats;
27362306a36Sopenharmony_ci	u8 bEndpointAddress;
27462306a36Sopenharmony_ci	u8 bTerminalLink;
27562306a36Sopenharmony_ci	u8 bControlSize;
27662306a36Sopenharmony_ci	u8 *bmaControls;
27762306a36Sopenharmony_ci	/* The following fields are used by input headers only. */
27862306a36Sopenharmony_ci	u8 bmInfo;
27962306a36Sopenharmony_ci	u8 bStillCaptureMethod;
28062306a36Sopenharmony_ci	u8 bTriggerSupport;
28162306a36Sopenharmony_ci	u8 bTriggerUsage;
28262306a36Sopenharmony_ci};
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_cienum uvc_buffer_state {
28562306a36Sopenharmony_ci	UVC_BUF_STATE_IDLE	= 0,
28662306a36Sopenharmony_ci	UVC_BUF_STATE_QUEUED	= 1,
28762306a36Sopenharmony_ci	UVC_BUF_STATE_ACTIVE	= 2,
28862306a36Sopenharmony_ci	UVC_BUF_STATE_READY	= 3,
28962306a36Sopenharmony_ci	UVC_BUF_STATE_DONE	= 4,
29062306a36Sopenharmony_ci	UVC_BUF_STATE_ERROR	= 5,
29162306a36Sopenharmony_ci};
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_cistruct uvc_buffer {
29462306a36Sopenharmony_ci	struct vb2_v4l2_buffer buf;
29562306a36Sopenharmony_ci	struct list_head queue;
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	enum uvc_buffer_state state;
29862306a36Sopenharmony_ci	unsigned int error;
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	void *mem;
30162306a36Sopenharmony_ci	unsigned int length;
30262306a36Sopenharmony_ci	unsigned int bytesused;
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	u32 pts;
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci	/* Asynchronous buffer handling. */
30762306a36Sopenharmony_ci	struct kref ref;
30862306a36Sopenharmony_ci};
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci#define UVC_QUEUE_DISCONNECTED		(1 << 0)
31162306a36Sopenharmony_ci#define UVC_QUEUE_DROP_CORRUPTED	(1 << 1)
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_cistruct uvc_video_queue {
31462306a36Sopenharmony_ci	struct vb2_queue queue;
31562306a36Sopenharmony_ci	struct mutex mutex;			/* Protects queue */
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	unsigned int flags;
31862306a36Sopenharmony_ci	unsigned int buf_used;
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci	spinlock_t irqlock;			/* Protects irqqueue */
32162306a36Sopenharmony_ci	struct list_head irqqueue;
32262306a36Sopenharmony_ci};
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_cistruct uvc_video_chain {
32562306a36Sopenharmony_ci	struct uvc_device *dev;
32662306a36Sopenharmony_ci	struct list_head list;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	struct list_head entities;		/* All entities */
32962306a36Sopenharmony_ci	struct uvc_entity *processing;		/* Processing unit */
33062306a36Sopenharmony_ci	struct uvc_entity *selector;		/* Selector unit */
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci	struct mutex ctrl_mutex;		/* Protects ctrl.info */
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	struct v4l2_prio_state prio;		/* V4L2 priority state */
33562306a36Sopenharmony_ci	u32 caps;				/* V4L2 chain-wide caps */
33662306a36Sopenharmony_ci	u8 ctrl_class_bitmap;			/* Bitmap of valid classes */
33762306a36Sopenharmony_ci};
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_cistruct uvc_stats_frame {
34062306a36Sopenharmony_ci	unsigned int size;		/* Number of bytes captured */
34162306a36Sopenharmony_ci	unsigned int first_data;	/* Index of the first non-empty packet */
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	unsigned int nb_packets;	/* Number of packets */
34462306a36Sopenharmony_ci	unsigned int nb_empty;		/* Number of empty packets */
34562306a36Sopenharmony_ci	unsigned int nb_invalid;	/* Number of packets with an invalid header */
34662306a36Sopenharmony_ci	unsigned int nb_errors;		/* Number of packets with the error bit set */
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	unsigned int nb_pts;		/* Number of packets with a PTS timestamp */
34962306a36Sopenharmony_ci	unsigned int nb_pts_diffs;	/* Number of PTS differences inside a frame */
35062306a36Sopenharmony_ci	unsigned int last_pts_diff;	/* Index of the last PTS difference */
35162306a36Sopenharmony_ci	bool has_initial_pts;		/* Whether the first non-empty packet has a PTS */
35262306a36Sopenharmony_ci	bool has_early_pts;		/* Whether a PTS is present before the first non-empty packet */
35362306a36Sopenharmony_ci	u32 pts;			/* PTS of the last packet */
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	unsigned int nb_scr;		/* Number of packets with a SCR timestamp */
35662306a36Sopenharmony_ci	unsigned int nb_scr_diffs;	/* Number of SCR.STC differences inside a frame */
35762306a36Sopenharmony_ci	u16 scr_sof;			/* SCR.SOF of the last packet */
35862306a36Sopenharmony_ci	u32 scr_stc;			/* SCR.STC of the last packet */
35962306a36Sopenharmony_ci};
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_cistruct uvc_stats_stream {
36262306a36Sopenharmony_ci	ktime_t start_ts;		/* Stream start timestamp */
36362306a36Sopenharmony_ci	ktime_t stop_ts;		/* Stream stop timestamp */
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	unsigned int nb_frames;		/* Number of frames */
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci	unsigned int nb_packets;	/* Number of packets */
36862306a36Sopenharmony_ci	unsigned int nb_empty;		/* Number of empty packets */
36962306a36Sopenharmony_ci	unsigned int nb_invalid;	/* Number of packets with an invalid header */
37062306a36Sopenharmony_ci	unsigned int nb_errors;		/* Number of packets with the error bit set */
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci	unsigned int nb_pts_constant;	/* Number of frames with constant PTS */
37362306a36Sopenharmony_ci	unsigned int nb_pts_early;	/* Number of frames with early PTS */
37462306a36Sopenharmony_ci	unsigned int nb_pts_initial;	/* Number of frames with initial PTS */
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci	unsigned int nb_scr_count_ok;	/* Number of frames with at least one SCR per non empty packet */
37762306a36Sopenharmony_ci	unsigned int nb_scr_diffs_ok;	/* Number of frames with varying SCR.STC */
37862306a36Sopenharmony_ci	unsigned int scr_sof_count;	/* STC.SOF counter accumulated since stream start */
37962306a36Sopenharmony_ci	unsigned int scr_sof;		/* STC.SOF of the last packet */
38062306a36Sopenharmony_ci	unsigned int min_sof;		/* Minimum STC.SOF value */
38162306a36Sopenharmony_ci	unsigned int max_sof;		/* Maximum STC.SOF value */
38262306a36Sopenharmony_ci};
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci#define UVC_METADATA_BUF_SIZE 10240
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci/**
38762306a36Sopenharmony_ci * struct uvc_copy_op: Context structure to schedule asynchronous memcpy
38862306a36Sopenharmony_ci *
38962306a36Sopenharmony_ci * @buf: active buf object for this operation
39062306a36Sopenharmony_ci * @dst: copy destination address
39162306a36Sopenharmony_ci * @src: copy source address
39262306a36Sopenharmony_ci * @len: copy length
39362306a36Sopenharmony_ci */
39462306a36Sopenharmony_cistruct uvc_copy_op {
39562306a36Sopenharmony_ci	struct uvc_buffer *buf;
39662306a36Sopenharmony_ci	void *dst;
39762306a36Sopenharmony_ci	const __u8 *src;
39862306a36Sopenharmony_ci	size_t len;
39962306a36Sopenharmony_ci};
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci/**
40262306a36Sopenharmony_ci * struct uvc_urb - URB context management structure
40362306a36Sopenharmony_ci *
40462306a36Sopenharmony_ci * @urb: the URB described by this context structure
40562306a36Sopenharmony_ci * @stream: UVC streaming context
40662306a36Sopenharmony_ci * @buffer: memory storage for the URB
40762306a36Sopenharmony_ci * @dma: Allocated DMA handle
40862306a36Sopenharmony_ci * @sgt: sgt_table with the urb locations in memory
40962306a36Sopenharmony_ci * @async_operations: counter to indicate the number of copy operations
41062306a36Sopenharmony_ci * @copy_operations: work descriptors for asynchronous copy operations
41162306a36Sopenharmony_ci * @work: work queue entry for asynchronous decode
41262306a36Sopenharmony_ci */
41362306a36Sopenharmony_cistruct uvc_urb {
41462306a36Sopenharmony_ci	struct urb *urb;
41562306a36Sopenharmony_ci	struct uvc_streaming *stream;
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci	char *buffer;
41862306a36Sopenharmony_ci	dma_addr_t dma;
41962306a36Sopenharmony_ci	struct sg_table *sgt;
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci	unsigned int async_operations;
42262306a36Sopenharmony_ci	struct uvc_copy_op copy_operations[UVC_MAX_PACKETS];
42362306a36Sopenharmony_ci	struct work_struct work;
42462306a36Sopenharmony_ci};
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_cistruct uvc_streaming {
42762306a36Sopenharmony_ci	struct list_head list;
42862306a36Sopenharmony_ci	struct uvc_device *dev;
42962306a36Sopenharmony_ci	struct video_device vdev;
43062306a36Sopenharmony_ci	struct uvc_video_chain *chain;
43162306a36Sopenharmony_ci	atomic_t active;
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci	struct usb_interface *intf;
43462306a36Sopenharmony_ci	int intfnum;
43562306a36Sopenharmony_ci	u16 maxpsize;
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci	struct uvc_streaming_header header;
43862306a36Sopenharmony_ci	enum v4l2_buf_type type;
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci	unsigned int nformats;
44162306a36Sopenharmony_ci	const struct uvc_format *formats;
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci	struct uvc_streaming_control ctrl;
44462306a36Sopenharmony_ci	const struct uvc_format *def_format;
44562306a36Sopenharmony_ci	const struct uvc_format *cur_format;
44662306a36Sopenharmony_ci	const struct uvc_frame *cur_frame;
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	/*
44962306a36Sopenharmony_ci	 * Protect access to ctrl, cur_format, cur_frame and hardware video
45062306a36Sopenharmony_ci	 * probe control.
45162306a36Sopenharmony_ci	 */
45262306a36Sopenharmony_ci	struct mutex mutex;
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci	/* Buffers queue. */
45562306a36Sopenharmony_ci	unsigned int frozen : 1;
45662306a36Sopenharmony_ci	struct uvc_video_queue queue;
45762306a36Sopenharmony_ci	struct workqueue_struct *async_wq;
45862306a36Sopenharmony_ci	void (*decode)(struct uvc_urb *uvc_urb, struct uvc_buffer *buf,
45962306a36Sopenharmony_ci		       struct uvc_buffer *meta_buf);
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci	struct {
46262306a36Sopenharmony_ci		struct video_device vdev;
46362306a36Sopenharmony_ci		struct uvc_video_queue queue;
46462306a36Sopenharmony_ci		u32 format;
46562306a36Sopenharmony_ci	} meta;
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci	/* Context data used by the bulk completion handler. */
46862306a36Sopenharmony_ci	struct {
46962306a36Sopenharmony_ci		u8 header[256];
47062306a36Sopenharmony_ci		unsigned int header_size;
47162306a36Sopenharmony_ci		int skip_payload;
47262306a36Sopenharmony_ci		u32 payload_size;
47362306a36Sopenharmony_ci		u32 max_payload_size;
47462306a36Sopenharmony_ci	} bulk;
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci	struct uvc_urb uvc_urb[UVC_URBS];
47762306a36Sopenharmony_ci	unsigned int urb_size;
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci	u32 sequence;
48062306a36Sopenharmony_ci	u8 last_fid;
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci	/* debugfs */
48362306a36Sopenharmony_ci	struct dentry *debugfs_dir;
48462306a36Sopenharmony_ci	struct {
48562306a36Sopenharmony_ci		struct uvc_stats_frame frame;
48662306a36Sopenharmony_ci		struct uvc_stats_stream stream;
48762306a36Sopenharmony_ci	} stats;
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci	/* Timestamps support. */
49062306a36Sopenharmony_ci	struct uvc_clock {
49162306a36Sopenharmony_ci		struct uvc_clock_sample {
49262306a36Sopenharmony_ci			u32 dev_stc;
49362306a36Sopenharmony_ci			u16 dev_sof;
49462306a36Sopenharmony_ci			u16 host_sof;
49562306a36Sopenharmony_ci			ktime_t host_time;
49662306a36Sopenharmony_ci		} *samples;
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci		unsigned int head;
49962306a36Sopenharmony_ci		unsigned int count;
50062306a36Sopenharmony_ci		unsigned int size;
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci		u16 last_sof;
50362306a36Sopenharmony_ci		u16 sof_offset;
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci		u8 last_scr[6];
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci		spinlock_t lock;
50862306a36Sopenharmony_ci	} clock;
50962306a36Sopenharmony_ci};
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci#define for_each_uvc_urb(uvc_urb, uvc_streaming) \
51262306a36Sopenharmony_ci	for ((uvc_urb) = &(uvc_streaming)->uvc_urb[0]; \
51362306a36Sopenharmony_ci	     (uvc_urb) < &(uvc_streaming)->uvc_urb[UVC_URBS]; \
51462306a36Sopenharmony_ci	     ++(uvc_urb))
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_cistatic inline u32 uvc_urb_index(const struct uvc_urb *uvc_urb)
51762306a36Sopenharmony_ci{
51862306a36Sopenharmony_ci	return uvc_urb - &uvc_urb->stream->uvc_urb[0];
51962306a36Sopenharmony_ci}
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_cistruct uvc_device_info {
52262306a36Sopenharmony_ci	u32	quirks;
52362306a36Sopenharmony_ci	u32	meta_format;
52462306a36Sopenharmony_ci	u16	uvc_version;
52562306a36Sopenharmony_ci	const struct uvc_control_mapping **mappings;
52662306a36Sopenharmony_ci};
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_cistruct uvc_status_streaming {
52962306a36Sopenharmony_ci	u8	button;
53062306a36Sopenharmony_ci} __packed;
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_cistruct uvc_status_control {
53362306a36Sopenharmony_ci	u8	bSelector;
53462306a36Sopenharmony_ci	u8	bAttribute;
53562306a36Sopenharmony_ci	u8	bValue[11];
53662306a36Sopenharmony_ci} __packed;
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_cistruct uvc_status {
53962306a36Sopenharmony_ci	u8	bStatusType;
54062306a36Sopenharmony_ci	u8	bOriginator;
54162306a36Sopenharmony_ci	u8	bEvent;
54262306a36Sopenharmony_ci	union {
54362306a36Sopenharmony_ci		struct uvc_status_control control;
54462306a36Sopenharmony_ci		struct uvc_status_streaming streaming;
54562306a36Sopenharmony_ci	};
54662306a36Sopenharmony_ci} __packed;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_cistruct uvc_device {
54962306a36Sopenharmony_ci	struct usb_device *udev;
55062306a36Sopenharmony_ci	struct usb_interface *intf;
55162306a36Sopenharmony_ci	unsigned long warnings;
55262306a36Sopenharmony_ci	u32 quirks;
55362306a36Sopenharmony_ci	int intfnum;
55462306a36Sopenharmony_ci	char name[32];
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci	const struct uvc_device_info *info;
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci	struct mutex lock;		/* Protects users */
55962306a36Sopenharmony_ci	unsigned int users;
56062306a36Sopenharmony_ci	atomic_t nmappings;
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	/* Video control interface */
56362306a36Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER
56462306a36Sopenharmony_ci	struct media_device mdev;
56562306a36Sopenharmony_ci#endif
56662306a36Sopenharmony_ci	struct v4l2_device vdev;
56762306a36Sopenharmony_ci	u16 uvc_version;
56862306a36Sopenharmony_ci	u32 clock_frequency;
56962306a36Sopenharmony_ci
57062306a36Sopenharmony_ci	struct list_head entities;
57162306a36Sopenharmony_ci	struct list_head chains;
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci	/* Video Streaming interfaces */
57462306a36Sopenharmony_ci	struct list_head streams;
57562306a36Sopenharmony_ci	struct kref ref;
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_ci	/* Status Interrupt Endpoint */
57862306a36Sopenharmony_ci	struct usb_host_endpoint *int_ep;
57962306a36Sopenharmony_ci	struct urb *int_urb;
58062306a36Sopenharmony_ci	struct uvc_status *status;
58162306a36Sopenharmony_ci	bool flush_status;
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci	struct input_dev *input;
58462306a36Sopenharmony_ci	char input_phys[64];
58562306a36Sopenharmony_ci
58662306a36Sopenharmony_ci	struct uvc_ctrl_work {
58762306a36Sopenharmony_ci		struct work_struct work;
58862306a36Sopenharmony_ci		struct urb *urb;
58962306a36Sopenharmony_ci		struct uvc_video_chain *chain;
59062306a36Sopenharmony_ci		struct uvc_control *ctrl;
59162306a36Sopenharmony_ci		const void *data;
59262306a36Sopenharmony_ci	} async_ctrl;
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci	struct uvc_entity *gpio_unit;
59562306a36Sopenharmony_ci};
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_cienum uvc_handle_state {
59862306a36Sopenharmony_ci	UVC_HANDLE_PASSIVE	= 0,
59962306a36Sopenharmony_ci	UVC_HANDLE_ACTIVE	= 1,
60062306a36Sopenharmony_ci};
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_cistruct uvc_fh {
60362306a36Sopenharmony_ci	struct v4l2_fh vfh;
60462306a36Sopenharmony_ci	struct uvc_video_chain *chain;
60562306a36Sopenharmony_ci	struct uvc_streaming *stream;
60662306a36Sopenharmony_ci	enum uvc_handle_state state;
60762306a36Sopenharmony_ci};
60862306a36Sopenharmony_ci
60962306a36Sopenharmony_cistruct uvc_driver {
61062306a36Sopenharmony_ci	struct usb_driver driver;
61162306a36Sopenharmony_ci};
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci/* ------------------------------------------------------------------------
61462306a36Sopenharmony_ci * Debugging, printing and logging
61562306a36Sopenharmony_ci */
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci#define UVC_DBG_PROBE		(1 << 0)
61862306a36Sopenharmony_ci#define UVC_DBG_DESCR		(1 << 1)
61962306a36Sopenharmony_ci#define UVC_DBG_CONTROL		(1 << 2)
62062306a36Sopenharmony_ci#define UVC_DBG_FORMAT		(1 << 3)
62162306a36Sopenharmony_ci#define UVC_DBG_CAPTURE		(1 << 4)
62262306a36Sopenharmony_ci#define UVC_DBG_CALLS		(1 << 5)
62362306a36Sopenharmony_ci#define UVC_DBG_FRAME		(1 << 7)
62462306a36Sopenharmony_ci#define UVC_DBG_SUSPEND		(1 << 8)
62562306a36Sopenharmony_ci#define UVC_DBG_STATUS		(1 << 9)
62662306a36Sopenharmony_ci#define UVC_DBG_VIDEO		(1 << 10)
62762306a36Sopenharmony_ci#define UVC_DBG_STATS		(1 << 11)
62862306a36Sopenharmony_ci#define UVC_DBG_CLOCK		(1 << 12)
62962306a36Sopenharmony_ci
63062306a36Sopenharmony_ci#define UVC_WARN_MINMAX		0
63162306a36Sopenharmony_ci#define UVC_WARN_PROBE_DEF	1
63262306a36Sopenharmony_ci#define UVC_WARN_XU_GET_RES	2
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ciextern unsigned int uvc_clock_param;
63562306a36Sopenharmony_ciextern unsigned int uvc_no_drop_param;
63662306a36Sopenharmony_ciextern unsigned int uvc_dbg_param;
63762306a36Sopenharmony_ciextern unsigned int uvc_timeout_param;
63862306a36Sopenharmony_ciextern unsigned int uvc_hw_timestamps_param;
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci#define uvc_dbg(_dev, flag, fmt, ...)					\
64162306a36Sopenharmony_cido {									\
64262306a36Sopenharmony_ci	if (uvc_dbg_param & UVC_DBG_##flag)				\
64362306a36Sopenharmony_ci		dev_printk(KERN_DEBUG, &(_dev)->udev->dev, fmt,		\
64462306a36Sopenharmony_ci			   ##__VA_ARGS__);				\
64562306a36Sopenharmony_ci} while (0)
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_ci#define uvc_dbg_cont(flag, fmt, ...)					\
64862306a36Sopenharmony_cido {									\
64962306a36Sopenharmony_ci	if (uvc_dbg_param & UVC_DBG_##flag)				\
65062306a36Sopenharmony_ci		pr_cont(fmt, ##__VA_ARGS__);				\
65162306a36Sopenharmony_ci} while (0)
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_ci#define uvc_warn_once(_dev, warn, fmt, ...)				\
65462306a36Sopenharmony_cido {									\
65562306a36Sopenharmony_ci	if (!test_and_set_bit(warn, &(_dev)->warnings))			\
65662306a36Sopenharmony_ci		dev_info(&(_dev)->udev->dev, fmt, ##__VA_ARGS__);	\
65762306a36Sopenharmony_ci} while (0)
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci/* --------------------------------------------------------------------------
66062306a36Sopenharmony_ci * Internal functions.
66162306a36Sopenharmony_ci */
66262306a36Sopenharmony_ci
66362306a36Sopenharmony_ci/* Core driver */
66462306a36Sopenharmony_ciextern struct uvc_driver uvc_driver;
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_cistruct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id);
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_ci/* Video buffers queue management. */
66962306a36Sopenharmony_ciint uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
67062306a36Sopenharmony_ci		   int drop_corrupted);
67162306a36Sopenharmony_civoid uvc_queue_release(struct uvc_video_queue *queue);
67262306a36Sopenharmony_ciint uvc_request_buffers(struct uvc_video_queue *queue,
67362306a36Sopenharmony_ci			struct v4l2_requestbuffers *rb);
67462306a36Sopenharmony_ciint uvc_query_buffer(struct uvc_video_queue *queue,
67562306a36Sopenharmony_ci		     struct v4l2_buffer *v4l2_buf);
67662306a36Sopenharmony_ciint uvc_create_buffers(struct uvc_video_queue *queue,
67762306a36Sopenharmony_ci		       struct v4l2_create_buffers *v4l2_cb);
67862306a36Sopenharmony_ciint uvc_queue_buffer(struct uvc_video_queue *queue,
67962306a36Sopenharmony_ci		     struct media_device *mdev,
68062306a36Sopenharmony_ci		     struct v4l2_buffer *v4l2_buf);
68162306a36Sopenharmony_ciint uvc_export_buffer(struct uvc_video_queue *queue,
68262306a36Sopenharmony_ci		      struct v4l2_exportbuffer *exp);
68362306a36Sopenharmony_ciint uvc_dequeue_buffer(struct uvc_video_queue *queue,
68462306a36Sopenharmony_ci		       struct v4l2_buffer *v4l2_buf, int nonblocking);
68562306a36Sopenharmony_ciint uvc_queue_streamon(struct uvc_video_queue *queue, enum v4l2_buf_type type);
68662306a36Sopenharmony_ciint uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type);
68762306a36Sopenharmony_civoid uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
68862306a36Sopenharmony_cistruct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
68962306a36Sopenharmony_ci					 struct uvc_buffer *buf);
69062306a36Sopenharmony_cistruct uvc_buffer *uvc_queue_get_current_buffer(struct uvc_video_queue *queue);
69162306a36Sopenharmony_civoid uvc_queue_buffer_release(struct uvc_buffer *buf);
69262306a36Sopenharmony_ciint uvc_queue_mmap(struct uvc_video_queue *queue,
69362306a36Sopenharmony_ci		   struct vm_area_struct *vma);
69462306a36Sopenharmony_ci__poll_t uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
69562306a36Sopenharmony_ci			poll_table *wait);
69662306a36Sopenharmony_ci#ifndef CONFIG_MMU
69762306a36Sopenharmony_ciunsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
69862306a36Sopenharmony_ci					  unsigned long pgoff);
69962306a36Sopenharmony_ci#endif
70062306a36Sopenharmony_ciint uvc_queue_allocated(struct uvc_video_queue *queue);
70162306a36Sopenharmony_cistatic inline int uvc_queue_streaming(struct uvc_video_queue *queue)
70262306a36Sopenharmony_ci{
70362306a36Sopenharmony_ci	return vb2_is_streaming(&queue->queue);
70462306a36Sopenharmony_ci}
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_cistatic inline struct uvc_streaming *
70762306a36Sopenharmony_ciuvc_queue_to_stream(struct uvc_video_queue *queue)
70862306a36Sopenharmony_ci{
70962306a36Sopenharmony_ci	return container_of(queue, struct uvc_streaming, queue);
71062306a36Sopenharmony_ci}
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_ci/* V4L2 interface */
71362306a36Sopenharmony_ciextern const struct v4l2_ioctl_ops uvc_ioctl_ops;
71462306a36Sopenharmony_ciextern const struct v4l2_file_operations uvc_fops;
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci/* Media controller */
71762306a36Sopenharmony_ciint uvc_mc_register_entities(struct uvc_video_chain *chain);
71862306a36Sopenharmony_civoid uvc_mc_cleanup_entity(struct uvc_entity *entity);
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci/* Video */
72162306a36Sopenharmony_ciint uvc_video_init(struct uvc_streaming *stream);
72262306a36Sopenharmony_ciint uvc_video_suspend(struct uvc_streaming *stream);
72362306a36Sopenharmony_ciint uvc_video_resume(struct uvc_streaming *stream, int reset);
72462306a36Sopenharmony_ciint uvc_video_start_streaming(struct uvc_streaming *stream);
72562306a36Sopenharmony_civoid uvc_video_stop_streaming(struct uvc_streaming *stream);
72662306a36Sopenharmony_ciint uvc_probe_video(struct uvc_streaming *stream,
72762306a36Sopenharmony_ci		    struct uvc_streaming_control *probe);
72862306a36Sopenharmony_ciint uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit,
72962306a36Sopenharmony_ci		   u8 intfnum, u8 cs, void *data, u16 size);
73062306a36Sopenharmony_civoid uvc_video_clock_update(struct uvc_streaming *stream,
73162306a36Sopenharmony_ci			    struct vb2_v4l2_buffer *vbuf,
73262306a36Sopenharmony_ci			    struct uvc_buffer *buf);
73362306a36Sopenharmony_ciint uvc_meta_register(struct uvc_streaming *stream);
73462306a36Sopenharmony_ci
73562306a36Sopenharmony_ciint uvc_register_video_device(struct uvc_device *dev,
73662306a36Sopenharmony_ci			      struct uvc_streaming *stream,
73762306a36Sopenharmony_ci			      struct video_device *vdev,
73862306a36Sopenharmony_ci			      struct uvc_video_queue *queue,
73962306a36Sopenharmony_ci			      enum v4l2_buf_type type,
74062306a36Sopenharmony_ci			      const struct v4l2_file_operations *fops,
74162306a36Sopenharmony_ci			      const struct v4l2_ioctl_ops *ioctl_ops);
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ci/* Status */
74462306a36Sopenharmony_ciint uvc_status_init(struct uvc_device *dev);
74562306a36Sopenharmony_civoid uvc_status_unregister(struct uvc_device *dev);
74662306a36Sopenharmony_civoid uvc_status_cleanup(struct uvc_device *dev);
74762306a36Sopenharmony_ciint uvc_status_start(struct uvc_device *dev, gfp_t flags);
74862306a36Sopenharmony_civoid uvc_status_stop(struct uvc_device *dev);
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ci/* Controls */
75162306a36Sopenharmony_ciextern const struct uvc_control_mapping uvc_ctrl_power_line_mapping_limited;
75262306a36Sopenharmony_ciextern const struct uvc_control_mapping uvc_ctrl_power_line_mapping_uvc11;
75362306a36Sopenharmony_ciextern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops;
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_ciint uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
75662306a36Sopenharmony_ci			struct v4l2_queryctrl *v4l2_ctrl);
75762306a36Sopenharmony_ciint uvc_query_v4l2_menu(struct uvc_video_chain *chain,
75862306a36Sopenharmony_ci			struct v4l2_querymenu *query_menu);
75962306a36Sopenharmony_ci
76062306a36Sopenharmony_ciint uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
76162306a36Sopenharmony_ci			 const struct uvc_control_mapping *mapping);
76262306a36Sopenharmony_ciint uvc_ctrl_init_device(struct uvc_device *dev);
76362306a36Sopenharmony_civoid uvc_ctrl_cleanup_device(struct uvc_device *dev);
76462306a36Sopenharmony_ciint uvc_ctrl_restore_values(struct uvc_device *dev);
76562306a36Sopenharmony_cibool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain,
76662306a36Sopenharmony_ci				 struct uvc_control *ctrl, const u8 *data);
76762306a36Sopenharmony_civoid uvc_ctrl_status_event(struct uvc_video_chain *chain,
76862306a36Sopenharmony_ci			   struct uvc_control *ctrl, const u8 *data);
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_ciint uvc_ctrl_begin(struct uvc_video_chain *chain);
77162306a36Sopenharmony_ciint __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
77262306a36Sopenharmony_ci		      struct v4l2_ext_controls *ctrls);
77362306a36Sopenharmony_cistatic inline int uvc_ctrl_commit(struct uvc_fh *handle,
77462306a36Sopenharmony_ci				  struct v4l2_ext_controls *ctrls)
77562306a36Sopenharmony_ci{
77662306a36Sopenharmony_ci	return __uvc_ctrl_commit(handle, 0, ctrls);
77762306a36Sopenharmony_ci}
77862306a36Sopenharmony_cistatic inline int uvc_ctrl_rollback(struct uvc_fh *handle)
77962306a36Sopenharmony_ci{
78062306a36Sopenharmony_ci	return __uvc_ctrl_commit(handle, 1, NULL);
78162306a36Sopenharmony_ci}
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_ciint uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl);
78462306a36Sopenharmony_ciint uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl);
78562306a36Sopenharmony_ciint uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
78662306a36Sopenharmony_ci			   const struct v4l2_ext_controls *ctrls,
78762306a36Sopenharmony_ci			   unsigned long ioctl);
78862306a36Sopenharmony_ci
78962306a36Sopenharmony_ciint uvc_xu_ctrl_query(struct uvc_video_chain *chain,
79062306a36Sopenharmony_ci		      struct uvc_xu_control_query *xqry);
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_ci/* Utility functions */
79362306a36Sopenharmony_cistruct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts,
79462306a36Sopenharmony_ci					    u8 epaddr);
79562306a36Sopenharmony_ciu16 uvc_endpoint_max_bpi(struct usb_device *dev, struct usb_host_endpoint *ep);
79662306a36Sopenharmony_ci
79762306a36Sopenharmony_ci/* Quirks support */
79862306a36Sopenharmony_civoid uvc_video_decode_isight(struct uvc_urb *uvc_urb,
79962306a36Sopenharmony_ci			     struct uvc_buffer *buf,
80062306a36Sopenharmony_ci			     struct uvc_buffer *meta_buf);
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci/* debugfs and statistics */
80362306a36Sopenharmony_civoid uvc_debugfs_init(void);
80462306a36Sopenharmony_civoid uvc_debugfs_cleanup(void);
80562306a36Sopenharmony_civoid uvc_debugfs_init_stream(struct uvc_streaming *stream);
80662306a36Sopenharmony_civoid uvc_debugfs_cleanup_stream(struct uvc_streaming *stream);
80762306a36Sopenharmony_ci
80862306a36Sopenharmony_cisize_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf,
80962306a36Sopenharmony_ci			    size_t size);
81062306a36Sopenharmony_ci
81162306a36Sopenharmony_ci#endif
812