18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef GSPCAV2_H
38c2ecf20Sopenharmony_ci#define GSPCAV2_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <linux/module.h>
68c2ecf20Sopenharmony_ci#include <linux/kernel.h>
78c2ecf20Sopenharmony_ci#include <linux/usb.h>
88c2ecf20Sopenharmony_ci#include <linux/videodev2.h>
98c2ecf20Sopenharmony_ci#include <media/v4l2-common.h>
108c2ecf20Sopenharmony_ci#include <media/v4l2-ctrls.h>
118c2ecf20Sopenharmony_ci#include <media/v4l2-device.h>
128c2ecf20Sopenharmony_ci#include <media/videobuf2-v4l2.h>
138c2ecf20Sopenharmony_ci#include <media/videobuf2-vmalloc.h>
148c2ecf20Sopenharmony_ci#include <linux/mutex.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/* GSPCA debug codes */
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#define D_PROBE  1
218c2ecf20Sopenharmony_ci#define D_CONF   2
228c2ecf20Sopenharmony_ci#define D_STREAM 3
238c2ecf20Sopenharmony_ci#define D_FRAM   4
248c2ecf20Sopenharmony_ci#define D_PACK   5
258c2ecf20Sopenharmony_ci#define D_USBI   6
268c2ecf20Sopenharmony_ci#define D_USBO   7
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ciextern int gspca_debug;
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#define gspca_dbg(gspca_dev, level, fmt, ...)			\
328c2ecf20Sopenharmony_ci	v4l2_dbg(level, gspca_debug, &(gspca_dev)->v4l2_dev,	\
338c2ecf20Sopenharmony_ci		 fmt, ##__VA_ARGS__)
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#define gspca_err(gspca_dev, fmt, ...)				\
368c2ecf20Sopenharmony_ci	v4l2_err(&(gspca_dev)->v4l2_dev, fmt, ##__VA_ARGS__)
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#define GSPCA_MAX_FRAMES 16	/* maximum number of video frame buffers */
398c2ecf20Sopenharmony_ci/* image transfers */
408c2ecf20Sopenharmony_ci#define MAX_NURBS 4		/* max number of URBs */
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci/* used to list framerates supported by a camera mode (resolution) */
448c2ecf20Sopenharmony_cistruct framerates {
458c2ecf20Sopenharmony_ci	const u8 *rates;
468c2ecf20Sopenharmony_ci	int nrates;
478c2ecf20Sopenharmony_ci};
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci/* device information - set at probe time */
508c2ecf20Sopenharmony_cistruct cam {
518c2ecf20Sopenharmony_ci	const struct v4l2_pix_format *cam_mode;	/* size nmodes */
528c2ecf20Sopenharmony_ci	const struct framerates *mode_framerates; /* must have size nmodes,
538c2ecf20Sopenharmony_ci						   * just like cam_mode */
548c2ecf20Sopenharmony_ci	u32 bulk_size;		/* buffer size when image transfer by bulk */
558c2ecf20Sopenharmony_ci	u32 input_flags;	/* value for ENUM_INPUT status flags */
568c2ecf20Sopenharmony_ci	u8 nmodes;		/* size of cam_mode */
578c2ecf20Sopenharmony_ci	u8 no_urb_create;	/* don't create transfer URBs */
588c2ecf20Sopenharmony_ci	u8 bulk_nurbs;		/* number of URBs in bulk mode
598c2ecf20Sopenharmony_ci				 * - cannot be > MAX_NURBS
608c2ecf20Sopenharmony_ci				 * - when 0 and bulk_size != 0 means
618c2ecf20Sopenharmony_ci				 *   1 URB and submit done by subdriver */
628c2ecf20Sopenharmony_ci	u8 bulk;		/* image transfer by 0:isoc / 1:bulk */
638c2ecf20Sopenharmony_ci	u8 npkt;		/* number of packets in an ISOC message
648c2ecf20Sopenharmony_ci				 * 0 is the default value: 32 packets */
658c2ecf20Sopenharmony_ci	u8 needs_full_bandwidth;/* Set this flag to notify the bandwidth calc.
668c2ecf20Sopenharmony_ci				 * code that the cam fills all image buffers to
678c2ecf20Sopenharmony_ci				 * the max, even when using compression. */
688c2ecf20Sopenharmony_ci};
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_cistruct gspca_dev;
718c2ecf20Sopenharmony_cistruct gspca_frame;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci/* subdriver operations */
748c2ecf20Sopenharmony_citypedef int (*cam_op) (struct gspca_dev *);
758c2ecf20Sopenharmony_citypedef void (*cam_v_op) (struct gspca_dev *);
768c2ecf20Sopenharmony_citypedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *);
778c2ecf20Sopenharmony_citypedef int (*cam_get_jpg_op) (struct gspca_dev *,
788c2ecf20Sopenharmony_ci				struct v4l2_jpegcompression *);
798c2ecf20Sopenharmony_citypedef int (*cam_set_jpg_op) (struct gspca_dev *,
808c2ecf20Sopenharmony_ci				const struct v4l2_jpegcompression *);
818c2ecf20Sopenharmony_citypedef int (*cam_get_reg_op) (struct gspca_dev *,
828c2ecf20Sopenharmony_ci				struct v4l2_dbg_register *);
838c2ecf20Sopenharmony_citypedef int (*cam_set_reg_op) (struct gspca_dev *,
848c2ecf20Sopenharmony_ci				const struct v4l2_dbg_register *);
858c2ecf20Sopenharmony_citypedef int (*cam_chip_info_op) (struct gspca_dev *,
868c2ecf20Sopenharmony_ci				struct v4l2_dbg_chip_info *);
878c2ecf20Sopenharmony_citypedef void (*cam_streamparm_op) (struct gspca_dev *,
888c2ecf20Sopenharmony_ci				  struct v4l2_streamparm *);
898c2ecf20Sopenharmony_citypedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
908c2ecf20Sopenharmony_ci				u8 *data,
918c2ecf20Sopenharmony_ci				int len);
928c2ecf20Sopenharmony_citypedef int (*cam_int_pkt_op) (struct gspca_dev *gspca_dev,
938c2ecf20Sopenharmony_ci				u8 *data,
948c2ecf20Sopenharmony_ci				int len);
958c2ecf20Sopenharmony_citypedef void (*cam_format_op) (struct gspca_dev *gspca_dev,
968c2ecf20Sopenharmony_ci				struct v4l2_format *fmt);
978c2ecf20Sopenharmony_citypedef int (*cam_frmsize_op) (struct gspca_dev *gspca_dev,
988c2ecf20Sopenharmony_ci				struct v4l2_frmsizeenum *fsize);
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci/* subdriver description */
1018c2ecf20Sopenharmony_cistruct sd_desc {
1028c2ecf20Sopenharmony_ci/* information */
1038c2ecf20Sopenharmony_ci	const char *name;	/* sub-driver name */
1048c2ecf20Sopenharmony_ci/* mandatory operations */
1058c2ecf20Sopenharmony_ci	cam_cf_op config;	/* called on probe */
1068c2ecf20Sopenharmony_ci	cam_op init;		/* called on probe and resume */
1078c2ecf20Sopenharmony_ci	cam_op init_controls;	/* called on probe */
1088c2ecf20Sopenharmony_ci	cam_v_op probe_error;	/* called if probe failed, do cleanup here */
1098c2ecf20Sopenharmony_ci	cam_op start;		/* called on stream on after URBs creation */
1108c2ecf20Sopenharmony_ci	cam_pkt_op pkt_scan;
1118c2ecf20Sopenharmony_ci/* optional operations */
1128c2ecf20Sopenharmony_ci	cam_op isoc_init;	/* called on stream on before getting the EP */
1138c2ecf20Sopenharmony_ci	cam_op isoc_nego;	/* called when URB submit failed with NOSPC */
1148c2ecf20Sopenharmony_ci	cam_v_op stopN;		/* called on stream off - main alt */
1158c2ecf20Sopenharmony_ci	cam_v_op stop0;		/* called on stream off & disconnect - alt 0 */
1168c2ecf20Sopenharmony_ci	cam_v_op dq_callback;	/* called when a frame has been dequeued */
1178c2ecf20Sopenharmony_ci	cam_get_jpg_op get_jcomp;
1188c2ecf20Sopenharmony_ci	cam_set_jpg_op set_jcomp;
1198c2ecf20Sopenharmony_ci	cam_streamparm_op get_streamparm;
1208c2ecf20Sopenharmony_ci	cam_streamparm_op set_streamparm;
1218c2ecf20Sopenharmony_ci	cam_format_op try_fmt;
1228c2ecf20Sopenharmony_ci	cam_frmsize_op enum_framesizes;
1238c2ecf20Sopenharmony_ci#ifdef CONFIG_VIDEO_ADV_DEBUG
1248c2ecf20Sopenharmony_ci	cam_set_reg_op set_register;
1258c2ecf20Sopenharmony_ci	cam_get_reg_op get_register;
1268c2ecf20Sopenharmony_ci	cam_chip_info_op get_chip_info;
1278c2ecf20Sopenharmony_ci#endif
1288c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
1298c2ecf20Sopenharmony_ci	cam_int_pkt_op int_pkt_scan;
1308c2ecf20Sopenharmony_ci	/* other_input makes the gspca core create gspca_dev->input even when
1318c2ecf20Sopenharmony_ci	   int_pkt_scan is NULL, for cams with non interrupt driven buttons */
1328c2ecf20Sopenharmony_ci	u8 other_input;
1338c2ecf20Sopenharmony_ci#endif
1348c2ecf20Sopenharmony_ci};
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci/* packet types when moving from iso buf to frame buf */
1378c2ecf20Sopenharmony_cienum gspca_packet_type {
1388c2ecf20Sopenharmony_ci	DISCARD_PACKET,
1398c2ecf20Sopenharmony_ci	FIRST_PACKET,
1408c2ecf20Sopenharmony_ci	INTER_PACKET,
1418c2ecf20Sopenharmony_ci	LAST_PACKET
1428c2ecf20Sopenharmony_ci};
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_cistruct gspca_buffer {
1458c2ecf20Sopenharmony_ci	struct vb2_v4l2_buffer vb;
1468c2ecf20Sopenharmony_ci	struct list_head list;
1478c2ecf20Sopenharmony_ci};
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_cistatic inline struct gspca_buffer *to_gspca_buffer(struct vb2_buffer *vb2)
1508c2ecf20Sopenharmony_ci{
1518c2ecf20Sopenharmony_ci	return container_of(vb2, struct gspca_buffer, vb.vb2_buf);
1528c2ecf20Sopenharmony_ci}
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_cistruct gspca_dev {
1558c2ecf20Sopenharmony_ci	struct video_device vdev;	/* !! must be the first item */
1568c2ecf20Sopenharmony_ci	struct module *module;		/* subdriver handling the device */
1578c2ecf20Sopenharmony_ci	struct v4l2_device v4l2_dev;
1588c2ecf20Sopenharmony_ci	struct usb_device *dev;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
1618c2ecf20Sopenharmony_ci	struct input_dev *input_dev;
1628c2ecf20Sopenharmony_ci	char phys[64];			/* physical device path */
1638c2ecf20Sopenharmony_ci#endif
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci	struct cam cam;				/* device information */
1668c2ecf20Sopenharmony_ci	const struct sd_desc *sd_desc;		/* subdriver description */
1678c2ecf20Sopenharmony_ci	struct v4l2_ctrl_handler ctrl_handler;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	/* autogain and exposure or gain control cluster, these are global as
1708c2ecf20Sopenharmony_ci	   the autogain/exposure functions in autogain_functions.c use them */
1718c2ecf20Sopenharmony_ci	struct {
1728c2ecf20Sopenharmony_ci		struct v4l2_ctrl *autogain;
1738c2ecf20Sopenharmony_ci		struct v4l2_ctrl *exposure;
1748c2ecf20Sopenharmony_ci		struct v4l2_ctrl *gain;
1758c2ecf20Sopenharmony_ci		int exp_too_low_cnt, exp_too_high_cnt;
1768c2ecf20Sopenharmony_ci	};
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci#define USB_BUF_SZ 64
1798c2ecf20Sopenharmony_ci	__u8 *usb_buf;				/* buffer for USB exchanges */
1808c2ecf20Sopenharmony_ci	struct urb *urb[MAX_NURBS];
1818c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
1828c2ecf20Sopenharmony_ci	struct urb *int_urb;
1838c2ecf20Sopenharmony_ci#endif
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	u8 *image;				/* image being filled */
1868c2ecf20Sopenharmony_ci	u32 image_len;				/* current length of image */
1878c2ecf20Sopenharmony_ci	__u8 last_packet_type;
1888c2ecf20Sopenharmony_ci	__s8 empty_packet;		/* if (-1) don't check empty packets */
1898c2ecf20Sopenharmony_ci	bool streaming;
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci	__u8 curr_mode;			/* current camera mode */
1928c2ecf20Sopenharmony_ci	struct v4l2_pix_format pixfmt;	/* current mode parameters */
1938c2ecf20Sopenharmony_ci	__u32 sequence;			/* frame sequence number */
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci	struct vb2_queue queue;
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci	spinlock_t qlock;
1988c2ecf20Sopenharmony_ci	struct list_head buf_list;
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	wait_queue_head_t wq;		/* wait queue */
2018c2ecf20Sopenharmony_ci	struct mutex usb_lock;		/* usb exchange protection */
2028c2ecf20Sopenharmony_ci	int usb_err;			/* USB error - protected by usb_lock */
2038c2ecf20Sopenharmony_ci	u16 pkt_size;			/* ISOC packet size */
2048c2ecf20Sopenharmony_ci#ifdef CONFIG_PM
2058c2ecf20Sopenharmony_ci	char frozen;			/* suspend - resume */
2068c2ecf20Sopenharmony_ci#endif
2078c2ecf20Sopenharmony_ci	bool present;
2088c2ecf20Sopenharmony_ci	char memory;			/* memory type (V4L2_MEMORY_xxx) */
2098c2ecf20Sopenharmony_ci	__u8 iface;			/* USB interface number */
2108c2ecf20Sopenharmony_ci	__u8 alt;			/* USB alternate setting */
2118c2ecf20Sopenharmony_ci	int xfer_ep;			/* USB transfer endpoint address */
2128c2ecf20Sopenharmony_ci	u8 audio;			/* presence of audio device */
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	/* (*) These variables are proteced by both usb_lock and queue_lock,
2158c2ecf20Sopenharmony_ci	   that is any code setting them is holding *both*, which means that
2168c2ecf20Sopenharmony_ci	   any code getting them needs to hold at least one of them */
2178c2ecf20Sopenharmony_ci};
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ciint gspca_dev_probe(struct usb_interface *intf,
2208c2ecf20Sopenharmony_ci		const struct usb_device_id *id,
2218c2ecf20Sopenharmony_ci		const struct sd_desc *sd_desc,
2228c2ecf20Sopenharmony_ci		int dev_size,
2238c2ecf20Sopenharmony_ci		struct module *module);
2248c2ecf20Sopenharmony_ciint gspca_dev_probe2(struct usb_interface *intf,
2258c2ecf20Sopenharmony_ci		const struct usb_device_id *id,
2268c2ecf20Sopenharmony_ci		const struct sd_desc *sd_desc,
2278c2ecf20Sopenharmony_ci		int dev_size,
2288c2ecf20Sopenharmony_ci		struct module *module);
2298c2ecf20Sopenharmony_civoid gspca_disconnect(struct usb_interface *intf);
2308c2ecf20Sopenharmony_civoid gspca_frame_add(struct gspca_dev *gspca_dev,
2318c2ecf20Sopenharmony_ci			enum gspca_packet_type packet_type,
2328c2ecf20Sopenharmony_ci			const u8 *data,
2338c2ecf20Sopenharmony_ci			int len);
2348c2ecf20Sopenharmony_ci#ifdef CONFIG_PM
2358c2ecf20Sopenharmony_ciint gspca_suspend(struct usb_interface *intf, pm_message_t message);
2368c2ecf20Sopenharmony_ciint gspca_resume(struct usb_interface *intf);
2378c2ecf20Sopenharmony_ci#endif
2388c2ecf20Sopenharmony_ciint gspca_expo_autogain(struct gspca_dev *gspca_dev, int avg_lum,
2398c2ecf20Sopenharmony_ci	int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee);
2408c2ecf20Sopenharmony_ciint gspca_coarse_grained_expo_autogain(struct gspca_dev *gspca_dev,
2418c2ecf20Sopenharmony_ci	int avg_lum, int desired_avg_lum, int deadzone);
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_ci#endif /* GSPCAV2_H */
244