162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef GSPCAV2_H
362306a36Sopenharmony_ci#define GSPCAV2_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/module.h>
662306a36Sopenharmony_ci#include <linux/kernel.h>
762306a36Sopenharmony_ci#include <linux/usb.h>
862306a36Sopenharmony_ci#include <linux/videodev2.h>
962306a36Sopenharmony_ci#include <media/v4l2-common.h>
1062306a36Sopenharmony_ci#include <media/v4l2-ctrls.h>
1162306a36Sopenharmony_ci#include <media/v4l2-device.h>
1262306a36Sopenharmony_ci#include <media/videobuf2-v4l2.h>
1362306a36Sopenharmony_ci#include <media/videobuf2-vmalloc.h>
1462306a36Sopenharmony_ci#include <linux/mutex.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/* GSPCA debug codes */
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#define D_PROBE  1
2162306a36Sopenharmony_ci#define D_CONF   2
2262306a36Sopenharmony_ci#define D_STREAM 3
2362306a36Sopenharmony_ci#define D_FRAM   4
2462306a36Sopenharmony_ci#define D_PACK   5
2562306a36Sopenharmony_ci#define D_USBI   6
2662306a36Sopenharmony_ci#define D_USBO   7
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ciextern int gspca_debug;
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define gspca_dbg(gspca_dev, level, fmt, ...)			\
3262306a36Sopenharmony_ci	v4l2_dbg(level, gspca_debug, &(gspca_dev)->v4l2_dev,	\
3362306a36Sopenharmony_ci		 fmt, ##__VA_ARGS__)
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#define gspca_err(gspca_dev, fmt, ...)				\
3662306a36Sopenharmony_ci	v4l2_err(&(gspca_dev)->v4l2_dev, fmt, ##__VA_ARGS__)
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define GSPCA_MAX_FRAMES 16	/* maximum number of video frame buffers */
3962306a36Sopenharmony_ci/* image transfers */
4062306a36Sopenharmony_ci#define MAX_NURBS 4		/* max number of URBs */
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci/* used to list framerates supported by a camera mode (resolution) */
4462306a36Sopenharmony_cistruct framerates {
4562306a36Sopenharmony_ci	const u8 *rates;
4662306a36Sopenharmony_ci	int nrates;
4762306a36Sopenharmony_ci};
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/* device information - set at probe time */
5062306a36Sopenharmony_cistruct cam {
5162306a36Sopenharmony_ci	const struct v4l2_pix_format *cam_mode;	/* size nmodes */
5262306a36Sopenharmony_ci	const struct framerates *mode_framerates; /* must have size nmodes,
5362306a36Sopenharmony_ci						   * just like cam_mode */
5462306a36Sopenharmony_ci	u32 bulk_size;		/* buffer size when image transfer by bulk */
5562306a36Sopenharmony_ci	u32 input_flags;	/* value for ENUM_INPUT status flags */
5662306a36Sopenharmony_ci	u8 nmodes;		/* size of cam_mode */
5762306a36Sopenharmony_ci	u8 no_urb_create;	/* don't create transfer URBs */
5862306a36Sopenharmony_ci	u8 bulk_nurbs;		/* number of URBs in bulk mode
5962306a36Sopenharmony_ci				 * - cannot be > MAX_NURBS
6062306a36Sopenharmony_ci				 * - when 0 and bulk_size != 0 means
6162306a36Sopenharmony_ci				 *   1 URB and submit done by subdriver */
6262306a36Sopenharmony_ci	u8 bulk;		/* image transfer by 0:isoc / 1:bulk */
6362306a36Sopenharmony_ci	u8 npkt;		/* number of packets in an ISOC message
6462306a36Sopenharmony_ci				 * 0 is the default value: 32 packets */
6562306a36Sopenharmony_ci	u8 needs_full_bandwidth;/* Set this flag to notify the bandwidth calc.
6662306a36Sopenharmony_ci				 * code that the cam fills all image buffers to
6762306a36Sopenharmony_ci				 * the max, even when using compression. */
6862306a36Sopenharmony_ci};
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistruct gspca_dev;
7162306a36Sopenharmony_cistruct gspca_frame;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/* subdriver operations */
7462306a36Sopenharmony_citypedef int (*cam_op) (struct gspca_dev *);
7562306a36Sopenharmony_citypedef void (*cam_v_op) (struct gspca_dev *);
7662306a36Sopenharmony_citypedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *);
7762306a36Sopenharmony_citypedef int (*cam_get_jpg_op) (struct gspca_dev *,
7862306a36Sopenharmony_ci				struct v4l2_jpegcompression *);
7962306a36Sopenharmony_citypedef int (*cam_set_jpg_op) (struct gspca_dev *,
8062306a36Sopenharmony_ci				const struct v4l2_jpegcompression *);
8162306a36Sopenharmony_citypedef int (*cam_get_reg_op) (struct gspca_dev *,
8262306a36Sopenharmony_ci				struct v4l2_dbg_register *);
8362306a36Sopenharmony_citypedef int (*cam_set_reg_op) (struct gspca_dev *,
8462306a36Sopenharmony_ci				const struct v4l2_dbg_register *);
8562306a36Sopenharmony_citypedef int (*cam_chip_info_op) (struct gspca_dev *,
8662306a36Sopenharmony_ci				struct v4l2_dbg_chip_info *);
8762306a36Sopenharmony_citypedef void (*cam_streamparm_op) (struct gspca_dev *,
8862306a36Sopenharmony_ci				  struct v4l2_streamparm *);
8962306a36Sopenharmony_citypedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
9062306a36Sopenharmony_ci				u8 *data,
9162306a36Sopenharmony_ci				int len);
9262306a36Sopenharmony_citypedef int (*cam_int_pkt_op) (struct gspca_dev *gspca_dev,
9362306a36Sopenharmony_ci				u8 *data,
9462306a36Sopenharmony_ci				int len);
9562306a36Sopenharmony_citypedef void (*cam_format_op) (struct gspca_dev *gspca_dev,
9662306a36Sopenharmony_ci				struct v4l2_format *fmt);
9762306a36Sopenharmony_citypedef int (*cam_frmsize_op) (struct gspca_dev *gspca_dev,
9862306a36Sopenharmony_ci				struct v4l2_frmsizeenum *fsize);
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci/* subdriver description */
10162306a36Sopenharmony_cistruct sd_desc {
10262306a36Sopenharmony_ci/* information */
10362306a36Sopenharmony_ci	const char *name;	/* sub-driver name */
10462306a36Sopenharmony_ci/* mandatory operations */
10562306a36Sopenharmony_ci	cam_cf_op config;	/* called on probe */
10662306a36Sopenharmony_ci	cam_op init;		/* called on probe and resume */
10762306a36Sopenharmony_ci	cam_op init_controls;	/* called on probe */
10862306a36Sopenharmony_ci	cam_v_op probe_error;	/* called if probe failed, do cleanup here */
10962306a36Sopenharmony_ci	cam_op start;		/* called on stream on after URBs creation */
11062306a36Sopenharmony_ci	cam_pkt_op pkt_scan;
11162306a36Sopenharmony_ci/* optional operations */
11262306a36Sopenharmony_ci	cam_op isoc_init;	/* called on stream on before getting the EP */
11362306a36Sopenharmony_ci	cam_op isoc_nego;	/* called when URB submit failed with NOSPC */
11462306a36Sopenharmony_ci	cam_v_op stopN;		/* called on stream off - main alt */
11562306a36Sopenharmony_ci	cam_v_op stop0;		/* called on stream off & disconnect - alt 0 */
11662306a36Sopenharmony_ci	cam_v_op dq_callback;	/* called when a frame has been dequeued */
11762306a36Sopenharmony_ci	cam_get_jpg_op get_jcomp;
11862306a36Sopenharmony_ci	cam_set_jpg_op set_jcomp;
11962306a36Sopenharmony_ci	cam_streamparm_op get_streamparm;
12062306a36Sopenharmony_ci	cam_streamparm_op set_streamparm;
12162306a36Sopenharmony_ci	cam_format_op try_fmt;
12262306a36Sopenharmony_ci	cam_frmsize_op enum_framesizes;
12362306a36Sopenharmony_ci#ifdef CONFIG_VIDEO_ADV_DEBUG
12462306a36Sopenharmony_ci	cam_set_reg_op set_register;
12562306a36Sopenharmony_ci	cam_get_reg_op get_register;
12662306a36Sopenharmony_ci	cam_chip_info_op get_chip_info;
12762306a36Sopenharmony_ci#endif
12862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
12962306a36Sopenharmony_ci	cam_int_pkt_op int_pkt_scan;
13062306a36Sopenharmony_ci	/* other_input makes the gspca core create gspca_dev->input even when
13162306a36Sopenharmony_ci	   int_pkt_scan is NULL, for cams with non interrupt driven buttons */
13262306a36Sopenharmony_ci	u8 other_input;
13362306a36Sopenharmony_ci#endif
13462306a36Sopenharmony_ci};
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci/* packet types when moving from iso buf to frame buf */
13762306a36Sopenharmony_cienum gspca_packet_type {
13862306a36Sopenharmony_ci	DISCARD_PACKET,
13962306a36Sopenharmony_ci	FIRST_PACKET,
14062306a36Sopenharmony_ci	INTER_PACKET,
14162306a36Sopenharmony_ci	LAST_PACKET
14262306a36Sopenharmony_ci};
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_cistruct gspca_buffer {
14562306a36Sopenharmony_ci	struct vb2_v4l2_buffer vb;
14662306a36Sopenharmony_ci	struct list_head list;
14762306a36Sopenharmony_ci};
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_cistatic inline struct gspca_buffer *to_gspca_buffer(struct vb2_buffer *vb2)
15062306a36Sopenharmony_ci{
15162306a36Sopenharmony_ci	return container_of(vb2, struct gspca_buffer, vb.vb2_buf);
15262306a36Sopenharmony_ci}
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_cistruct gspca_dev {
15562306a36Sopenharmony_ci	struct video_device vdev;	/* !! must be the first item */
15662306a36Sopenharmony_ci	struct module *module;		/* subdriver handling the device */
15762306a36Sopenharmony_ci	struct v4l2_device v4l2_dev;
15862306a36Sopenharmony_ci	struct usb_device *dev;
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
16162306a36Sopenharmony_ci	struct input_dev *input_dev;
16262306a36Sopenharmony_ci	char phys[64];			/* physical device path */
16362306a36Sopenharmony_ci#endif
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	struct cam cam;				/* device information */
16662306a36Sopenharmony_ci	const struct sd_desc *sd_desc;		/* subdriver description */
16762306a36Sopenharmony_ci	struct v4l2_ctrl_handler ctrl_handler;
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	/* autogain and exposure or gain control cluster, these are global as
17062306a36Sopenharmony_ci	   the autogain/exposure functions in autogain_functions.c use them */
17162306a36Sopenharmony_ci	struct {
17262306a36Sopenharmony_ci		struct v4l2_ctrl *autogain;
17362306a36Sopenharmony_ci		struct v4l2_ctrl *exposure;
17462306a36Sopenharmony_ci		struct v4l2_ctrl *gain;
17562306a36Sopenharmony_ci		int exp_too_low_cnt, exp_too_high_cnt;
17662306a36Sopenharmony_ci	};
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci#define USB_BUF_SZ 64
17962306a36Sopenharmony_ci	__u8 *usb_buf;				/* buffer for USB exchanges */
18062306a36Sopenharmony_ci	struct urb *urb[MAX_NURBS];
18162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
18262306a36Sopenharmony_ci	struct urb *int_urb;
18362306a36Sopenharmony_ci#endif
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	u8 *image;				/* image being filled */
18662306a36Sopenharmony_ci	u32 image_len;				/* current length of image */
18762306a36Sopenharmony_ci	__u8 last_packet_type;
18862306a36Sopenharmony_ci	__s8 empty_packet;		/* if (-1) don't check empty packets */
18962306a36Sopenharmony_ci	bool streaming;
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	__u8 curr_mode;			/* current camera mode */
19262306a36Sopenharmony_ci	struct v4l2_pix_format pixfmt;	/* current mode parameters */
19362306a36Sopenharmony_ci	__u32 sequence;			/* frame sequence number */
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	struct vb2_queue queue;
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	spinlock_t qlock;
19862306a36Sopenharmony_ci	struct list_head buf_list;
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci	wait_queue_head_t wq;		/* wait queue */
20162306a36Sopenharmony_ci	struct mutex usb_lock;		/* usb exchange protection */
20262306a36Sopenharmony_ci	int usb_err;			/* USB error - protected by usb_lock */
20362306a36Sopenharmony_ci	u16 pkt_size;			/* ISOC packet size */
20462306a36Sopenharmony_ci#ifdef CONFIG_PM
20562306a36Sopenharmony_ci	char frozen;			/* suspend - resume */
20662306a36Sopenharmony_ci#endif
20762306a36Sopenharmony_ci	bool present;
20862306a36Sopenharmony_ci	char memory;			/* memory type (V4L2_MEMORY_xxx) */
20962306a36Sopenharmony_ci	__u8 iface;			/* USB interface number */
21062306a36Sopenharmony_ci	__u8 alt;			/* USB alternate setting */
21162306a36Sopenharmony_ci	int xfer_ep;			/* USB transfer endpoint address */
21262306a36Sopenharmony_ci	u8 audio;			/* presence of audio device */
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	/* (*) These variables are proteced by both usb_lock and queue_lock,
21562306a36Sopenharmony_ci	   that is any code setting them is holding *both*, which means that
21662306a36Sopenharmony_ci	   any code getting them needs to hold at least one of them */
21762306a36Sopenharmony_ci};
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ciint gspca_dev_probe(struct usb_interface *intf,
22062306a36Sopenharmony_ci		const struct usb_device_id *id,
22162306a36Sopenharmony_ci		const struct sd_desc *sd_desc,
22262306a36Sopenharmony_ci		int dev_size,
22362306a36Sopenharmony_ci		struct module *module);
22462306a36Sopenharmony_ciint gspca_dev_probe2(struct usb_interface *intf,
22562306a36Sopenharmony_ci		const struct usb_device_id *id,
22662306a36Sopenharmony_ci		const struct sd_desc *sd_desc,
22762306a36Sopenharmony_ci		int dev_size,
22862306a36Sopenharmony_ci		struct module *module);
22962306a36Sopenharmony_civoid gspca_disconnect(struct usb_interface *intf);
23062306a36Sopenharmony_civoid gspca_frame_add(struct gspca_dev *gspca_dev,
23162306a36Sopenharmony_ci			enum gspca_packet_type packet_type,
23262306a36Sopenharmony_ci			const u8 *data,
23362306a36Sopenharmony_ci			int len);
23462306a36Sopenharmony_ci#ifdef CONFIG_PM
23562306a36Sopenharmony_ciint gspca_suspend(struct usb_interface *intf, pm_message_t message);
23662306a36Sopenharmony_ciint gspca_resume(struct usb_interface *intf);
23762306a36Sopenharmony_ci#endif
23862306a36Sopenharmony_ciint gspca_expo_autogain(struct gspca_dev *gspca_dev, int avg_lum,
23962306a36Sopenharmony_ci	int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee);
24062306a36Sopenharmony_ciint gspca_coarse_grained_expo_autogain(struct gspca_dev *gspca_dev,
24162306a36Sopenharmony_ci	int avg_lum, int desired_avg_lum, int deadzone);
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci#endif /* GSPCAV2_H */
244