1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 20c0d06caSMauro Carvalho Chehab #ifndef GSPCAV2_H 30c0d06caSMauro Carvalho Chehab #define GSPCAV2_H 40c0d06caSMauro Carvalho Chehab 50c0d06caSMauro Carvalho Chehab #include <linux/module.h> 60c0d06caSMauro Carvalho Chehab #include <linux/kernel.h> 70c0d06caSMauro Carvalho Chehab #include <linux/usb.h> 80c0d06caSMauro Carvalho Chehab #include <linux/videodev2.h> 90c0d06caSMauro Carvalho Chehab #include <media/v4l2-common.h> 100c0d06caSMauro Carvalho Chehab #include <media/v4l2-ctrls.h> 110c0d06caSMauro Carvalho Chehab #include <media/v4l2-device.h> 120c0d06caSMauro Carvalho Chehab #include <linux/mutex.h> 130c0d06caSMauro Carvalho Chehab 140c0d06caSMauro Carvalho Chehab 15c93396e1STheodore Kilgore 16c93396e1STheodore Kilgore /* GSPCA debug codes */ 17c93396e1STheodore Kilgore 18c93396e1STheodore Kilgore #define D_PROBE 1 19c93396e1STheodore Kilgore #define D_CONF 2 20c93396e1STheodore Kilgore #define D_STREAM 3 21c93396e1STheodore Kilgore #define D_FRAM 4 22c93396e1STheodore Kilgore #define D_PACK 5 23c93396e1STheodore Kilgore #define D_USBI 6 24c93396e1STheodore Kilgore #define D_USBO 7 25c93396e1STheodore Kilgore 260c0d06caSMauro Carvalho Chehab extern int gspca_debug; 270c0d06caSMauro Carvalho Chehab 28c93396e1STheodore Kilgore 29c93396e1STheodore Kilgore #define PDEBUG(level, fmt, ...) \ 30c93396e1STheodore Kilgore v4l2_dbg(level, gspca_debug, &gspca_dev->v4l2_dev, fmt, ##__VA_ARGS__) 31c93396e1STheodore Kilgore 3252173c5fSJoe Perches #define gspca_err(gspca_dev, fmt, ...) \ 3352173c5fSJoe Perches v4l2_err(&(gspca_dev)->v4l2_dev, fmt, ##__VA_ARGS__) 340c0d06caSMauro Carvalho Chehab 350c0d06caSMauro Carvalho Chehab #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ 360c0d06caSMauro Carvalho Chehab /* image transfers */ 370c0d06caSMauro Carvalho Chehab #define MAX_NURBS 4 /* max number of URBs */ 380c0d06caSMauro Carvalho Chehab 390c0d06caSMauro Carvalho Chehab 400c0d06caSMauro Carvalho Chehab /* used to list framerates supported by a camera mode (resolution) */ 410c0d06caSMauro Carvalho Chehab struct framerates { 420c0d06caSMauro Carvalho Chehab const u8 *rates; 430c0d06caSMauro Carvalho Chehab int nrates; 440c0d06caSMauro Carvalho Chehab }; 450c0d06caSMauro Carvalho Chehab 460c0d06caSMauro Carvalho Chehab /* device information - set at probe time */ 470c0d06caSMauro Carvalho Chehab struct cam { 480c0d06caSMauro Carvalho Chehab const struct v4l2_pix_format *cam_mode; /* size nmodes */ 490c0d06caSMauro Carvalho Chehab const struct framerates *mode_framerates; /* must have size nmodes, 500c0d06caSMauro Carvalho Chehab * just like cam_mode */ 510c0d06caSMauro Carvalho Chehab u32 bulk_size; /* buffer size when image transfer by bulk */ 520c0d06caSMauro Carvalho Chehab u32 input_flags; /* value for ENUM_INPUT status flags */ 530c0d06caSMauro Carvalho Chehab u8 nmodes; /* size of cam_mode */ 540c0d06caSMauro Carvalho Chehab u8 no_urb_create; /* don't create transfer URBs */ 550c0d06caSMauro Carvalho Chehab u8 bulk_nurbs; /* number of URBs in bulk mode 560c0d06caSMauro Carvalho Chehab * - cannot be > MAX_NURBS 570c0d06caSMauro Carvalho Chehab * - when 0 and bulk_size != 0 means 580c0d06caSMauro Carvalho Chehab * 1 URB and submit done by subdriver */ 590c0d06caSMauro Carvalho Chehab u8 bulk; /* image transfer by 0:isoc / 1:bulk */ 600c0d06caSMauro Carvalho Chehab u8 npkt; /* number of packets in an ISOC message 610c0d06caSMauro Carvalho Chehab * 0 is the default value: 32 packets */ 620c0d06caSMauro Carvalho Chehab u8 needs_full_bandwidth;/* Set this flag to notify the bandwidth calc. 630c0d06caSMauro Carvalho Chehab * code that the cam fills all image buffers to 640c0d06caSMauro Carvalho Chehab * the max, even when using compression. */ 650c0d06caSMauro Carvalho Chehab }; 660c0d06caSMauro Carvalho Chehab 670c0d06caSMauro Carvalho Chehab struct gspca_dev; 680c0d06caSMauro Carvalho Chehab struct gspca_frame; 690c0d06caSMauro Carvalho Chehab 700c0d06caSMauro Carvalho Chehab /* subdriver operations */ 710c0d06caSMauro Carvalho Chehab typedef int (*cam_op) (struct gspca_dev *); 720c0d06caSMauro Carvalho Chehab typedef void (*cam_v_op) (struct gspca_dev *); 730c0d06caSMauro Carvalho Chehab typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); 74d88aab53SHans Verkuil typedef int (*cam_get_jpg_op) (struct gspca_dev *, 750c0d06caSMauro Carvalho Chehab struct v4l2_jpegcompression *); 76d88aab53SHans Verkuil typedef int (*cam_set_jpg_op) (struct gspca_dev *, 77d88aab53SHans Verkuil const struct v4l2_jpegcompression *); 78977ba3b1SHans Verkuil typedef int (*cam_get_reg_op) (struct gspca_dev *, 790c0d06caSMauro Carvalho Chehab struct v4l2_dbg_register *); 80977ba3b1SHans Verkuil typedef int (*cam_set_reg_op) (struct gspca_dev *, 81977ba3b1SHans Verkuil const struct v4l2_dbg_register *); 82b1c85cc0SHans Verkuil typedef int (*cam_chip_info_op) (struct gspca_dev *, 83b1c85cc0SHans Verkuil struct v4l2_dbg_chip_info *); 840c0d06caSMauro Carvalho Chehab typedef void (*cam_streamparm_op) (struct gspca_dev *, 850c0d06caSMauro Carvalho Chehab struct v4l2_streamparm *); 860c0d06caSMauro Carvalho Chehab typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, 870c0d06caSMauro Carvalho Chehab u8 *data, 880c0d06caSMauro Carvalho Chehab int len); 890c0d06caSMauro Carvalho Chehab typedef int (*cam_int_pkt_op) (struct gspca_dev *gspca_dev, 900c0d06caSMauro Carvalho Chehab u8 *data, 910c0d06caSMauro Carvalho Chehab int len); 927d687af4SOndrej Zary typedef void (*cam_format_op) (struct gspca_dev *gspca_dev, 937d687af4SOndrej Zary struct v4l2_format *fmt); 947d687af4SOndrej Zary typedef int (*cam_frmsize_op) (struct gspca_dev *gspca_dev, 957d687af4SOndrej Zary struct v4l2_frmsizeenum *fsize); 960c0d06caSMauro Carvalho Chehab 970c0d06caSMauro Carvalho Chehab /* subdriver description */ 980c0d06caSMauro Carvalho Chehab struct sd_desc { 990c0d06caSMauro Carvalho Chehab /* information */ 1000c0d06caSMauro Carvalho Chehab const char *name; /* sub-driver name */ 1010c0d06caSMauro Carvalho Chehab /* mandatory operations */ 1020c0d06caSMauro Carvalho Chehab cam_cf_op config; /* called on probe */ 1030c0d06caSMauro Carvalho Chehab cam_op init; /* called on probe and resume */ 1040c0d06caSMauro Carvalho Chehab cam_op init_controls; /* called on probe */ 1050c0d06caSMauro Carvalho Chehab cam_op start; /* called on stream on after URBs creation */ 1060c0d06caSMauro Carvalho Chehab cam_pkt_op pkt_scan; 1070c0d06caSMauro Carvalho Chehab /* optional operations */ 1080c0d06caSMauro Carvalho Chehab cam_op isoc_init; /* called on stream on before getting the EP */ 1090c0d06caSMauro Carvalho Chehab cam_op isoc_nego; /* called when URB submit failed with NOSPC */ 1100c0d06caSMauro Carvalho Chehab cam_v_op stopN; /* called on stream off - main alt */ 1110c0d06caSMauro Carvalho Chehab cam_v_op stop0; /* called on stream off & disconnect - alt 0 */ 1120c0d06caSMauro Carvalho Chehab cam_v_op dq_callback; /* called when a frame has been dequeued */ 113d88aab53SHans Verkuil cam_get_jpg_op get_jcomp; 114d88aab53SHans Verkuil cam_set_jpg_op set_jcomp; 1150c0d06caSMauro Carvalho Chehab cam_streamparm_op get_streamparm; 1160c0d06caSMauro Carvalho Chehab cam_streamparm_op set_streamparm; 1177d687af4SOndrej Zary cam_format_op try_fmt; 1187d687af4SOndrej Zary cam_frmsize_op enum_framesizes; 1190c0d06caSMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG 120977ba3b1SHans Verkuil cam_set_reg_op set_register; 121977ba3b1SHans Verkuil cam_get_reg_op get_register; 122b1c85cc0SHans Verkuil cam_chip_info_op get_chip_info; 1230c0d06caSMauro Carvalho Chehab #endif 12413a00fabSPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT) 1250c0d06caSMauro Carvalho Chehab cam_int_pkt_op int_pkt_scan; 1260c0d06caSMauro Carvalho Chehab /* other_input makes the gspca core create gspca_dev->input even when 1270c0d06caSMauro Carvalho Chehab int_pkt_scan is NULL, for cams with non interrupt driven buttons */ 1280c0d06caSMauro Carvalho Chehab u8 other_input; 1290c0d06caSMauro Carvalho Chehab #endif 1300c0d06caSMauro Carvalho Chehab }; 1310c0d06caSMauro Carvalho Chehab 1320c0d06caSMauro Carvalho Chehab /* packet types when moving from iso buf to frame buf */ 1330c0d06caSMauro Carvalho Chehab enum gspca_packet_type { 1340c0d06caSMauro Carvalho Chehab DISCARD_PACKET, 1350c0d06caSMauro Carvalho Chehab FIRST_PACKET, 1360c0d06caSMauro Carvalho Chehab INTER_PACKET, 1370c0d06caSMauro Carvalho Chehab LAST_PACKET 1380c0d06caSMauro Carvalho Chehab }; 1390c0d06caSMauro Carvalho Chehab 1400c0d06caSMauro Carvalho Chehab struct gspca_frame { 1410c0d06caSMauro Carvalho Chehab __u8 *data; /* frame buffer */ 1420c0d06caSMauro Carvalho Chehab int vma_use_count; 1430c0d06caSMauro Carvalho Chehab struct v4l2_buffer v4l2_buf; 1440c0d06caSMauro Carvalho Chehab }; 1450c0d06caSMauro Carvalho Chehab 1460c0d06caSMauro Carvalho Chehab struct gspca_dev { 1470c0d06caSMauro Carvalho Chehab struct video_device vdev; /* !! must be the first item */ 1480c0d06caSMauro Carvalho Chehab struct module *module; /* subdriver handling the device */ 1490c0d06caSMauro Carvalho Chehab struct v4l2_device v4l2_dev; 1500c0d06caSMauro Carvalho Chehab struct usb_device *dev; 1510c0d06caSMauro Carvalho Chehab struct file *capt_file; /* file doing video capture */ 1520c0d06caSMauro Carvalho Chehab /* protected by queue_lock */ 15313a00fabSPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT) 1540c0d06caSMauro Carvalho Chehab struct input_dev *input_dev; 1550c0d06caSMauro Carvalho Chehab char phys[64]; /* physical device path */ 1560c0d06caSMauro Carvalho Chehab #endif 1570c0d06caSMauro Carvalho Chehab 1580c0d06caSMauro Carvalho Chehab struct cam cam; /* device information */ 1590c0d06caSMauro Carvalho Chehab const struct sd_desc *sd_desc; /* subdriver description */ 1600c0d06caSMauro Carvalho Chehab struct v4l2_ctrl_handler ctrl_handler; 1610c0d06caSMauro Carvalho Chehab 1620c0d06caSMauro Carvalho Chehab /* autogain and exposure or gain control cluster, these are global as 1630c0d06caSMauro Carvalho Chehab the autogain/exposure functions in autogain_functions.c use them */ 1640c0d06caSMauro Carvalho Chehab struct { 1650c0d06caSMauro Carvalho Chehab struct v4l2_ctrl *autogain; 1660c0d06caSMauro Carvalho Chehab struct v4l2_ctrl *exposure; 1670c0d06caSMauro Carvalho Chehab struct v4l2_ctrl *gain; 1680c0d06caSMauro Carvalho Chehab int exp_too_low_cnt, exp_too_high_cnt; 1690c0d06caSMauro Carvalho Chehab }; 1700c0d06caSMauro Carvalho Chehab 1710c0d06caSMauro Carvalho Chehab #define USB_BUF_SZ 64 1720c0d06caSMauro Carvalho Chehab __u8 *usb_buf; /* buffer for USB exchanges */ 1730c0d06caSMauro Carvalho Chehab struct urb *urb[MAX_NURBS]; 17413a00fabSPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT) 1750c0d06caSMauro Carvalho Chehab struct urb *int_urb; 1760c0d06caSMauro Carvalho Chehab #endif 1770c0d06caSMauro Carvalho Chehab 1780c0d06caSMauro Carvalho Chehab __u8 *frbuf; /* buffer for nframes */ 1790c0d06caSMauro Carvalho Chehab struct gspca_frame frame[GSPCA_MAX_FRAMES]; 1800c0d06caSMauro Carvalho Chehab u8 *image; /* image beeing filled */ 1810c0d06caSMauro Carvalho Chehab __u32 frsz; /* frame size */ 1820c0d06caSMauro Carvalho Chehab u32 image_len; /* current length of image */ 1830c0d06caSMauro Carvalho Chehab atomic_t fr_q; /* next frame to queue */ 1840c0d06caSMauro Carvalho Chehab atomic_t fr_i; /* frame being filled */ 1850c0d06caSMauro Carvalho Chehab signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */ 1860c0d06caSMauro Carvalho Chehab char nframes; /* number of frames */ 1870c0d06caSMauro Carvalho Chehab u8 fr_o; /* next frame to dequeue */ 1880c0d06caSMauro Carvalho Chehab __u8 last_packet_type; 1890c0d06caSMauro Carvalho Chehab __s8 empty_packet; /* if (-1) don't check empty packets */ 1900c0d06caSMauro Carvalho Chehab __u8 streaming; /* protected by both mutexes (*) */ 1910c0d06caSMauro Carvalho Chehab 1920c0d06caSMauro Carvalho Chehab __u8 curr_mode; /* current camera mode */ 1931966bc2aSOndrej Zary struct v4l2_pix_format pixfmt; /* current mode parameters */ 1940c0d06caSMauro Carvalho Chehab __u32 sequence; /* frame sequence number */ 1950c0d06caSMauro Carvalho Chehab 1960c0d06caSMauro Carvalho Chehab wait_queue_head_t wq; /* wait queue */ 1970c0d06caSMauro Carvalho Chehab struct mutex usb_lock; /* usb exchange protection */ 1980c0d06caSMauro Carvalho Chehab struct mutex queue_lock; /* ISOC queue protection */ 1990c0d06caSMauro Carvalho Chehab int usb_err; /* USB error - protected by usb_lock */ 2000c0d06caSMauro Carvalho Chehab u16 pkt_size; /* ISOC packet size */ 2010c0d06caSMauro Carvalho Chehab #ifdef CONFIG_PM 2020c0d06caSMauro Carvalho Chehab char frozen; /* suspend - resume */ 2030c0d06caSMauro Carvalho Chehab #endif 2040c0d06caSMauro Carvalho Chehab char present; /* device connected */ 2050c0d06caSMauro Carvalho Chehab char nbufread; /* number of buffers for read() */ 2060c0d06caSMauro Carvalho Chehab char memory; /* memory type (V4L2_MEMORY_xxx) */ 2070c0d06caSMauro Carvalho Chehab __u8 iface; /* USB interface number */ 2080c0d06caSMauro Carvalho Chehab __u8 alt; /* USB alternate setting */ 2092fe15245SAntonio Ospite int xfer_ep; /* USB transfer endpoint address */ 2100c0d06caSMauro Carvalho Chehab u8 audio; /* presence of audio device */ 2110c0d06caSMauro Carvalho Chehab 2120c0d06caSMauro Carvalho Chehab /* (*) These variables are proteced by both usb_lock and queue_lock, 2130c0d06caSMauro Carvalho Chehab that is any code setting them is holding *both*, which means that 2140c0d06caSMauro Carvalho Chehab any code getting them needs to hold at least one of them */ 2150c0d06caSMauro Carvalho Chehab }; 2160c0d06caSMauro Carvalho Chehab 2170c0d06caSMauro Carvalho Chehab int gspca_dev_probe(struct usb_interface *intf, 2180c0d06caSMauro Carvalho Chehab const struct usb_device_id *id, 2190c0d06caSMauro Carvalho Chehab const struct sd_desc *sd_desc, 2200c0d06caSMauro Carvalho Chehab int dev_size, 2210c0d06caSMauro Carvalho Chehab struct module *module); 2220c0d06caSMauro Carvalho Chehab int gspca_dev_probe2(struct usb_interface *intf, 2230c0d06caSMauro Carvalho Chehab const struct usb_device_id *id, 2240c0d06caSMauro Carvalho Chehab const struct sd_desc *sd_desc, 2250c0d06caSMauro Carvalho Chehab int dev_size, 2260c0d06caSMauro Carvalho Chehab struct module *module); 2270c0d06caSMauro Carvalho Chehab void gspca_disconnect(struct usb_interface *intf); 2280c0d06caSMauro Carvalho Chehab void gspca_frame_add(struct gspca_dev *gspca_dev, 2290c0d06caSMauro Carvalho Chehab enum gspca_packet_type packet_type, 2300c0d06caSMauro Carvalho Chehab const u8 *data, 2310c0d06caSMauro Carvalho Chehab int len); 2320c0d06caSMauro Carvalho Chehab #ifdef CONFIG_PM 2330c0d06caSMauro Carvalho Chehab int gspca_suspend(struct usb_interface *intf, pm_message_t message); 2340c0d06caSMauro Carvalho Chehab int gspca_resume(struct usb_interface *intf); 2350c0d06caSMauro Carvalho Chehab #endif 2360c0d06caSMauro Carvalho Chehab int gspca_expo_autogain(struct gspca_dev *gspca_dev, int avg_lum, 2370c0d06caSMauro Carvalho Chehab int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee); 2380c0d06caSMauro Carvalho Chehab int gspca_coarse_grained_expo_autogain(struct gspca_dev *gspca_dev, 2390c0d06caSMauro Carvalho Chehab int avg_lum, int desired_avg_lum, int deadzone); 2400c0d06caSMauro Carvalho Chehab 2410c0d06caSMauro Carvalho Chehab #endif /* GSPCAV2_H */ 242