/* * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2024 Dell Inc. * * Alvin Chen * Zhichao Li * Pillar Liang * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * UVC spec:https://www.usb.org/sites/default/files/USB_Video_Class_1_5.zip */ #ifndef _DEV_USB_UVC_DRV_H #define _DEV_USB_UVC_DRV_H #include "uvc_buf.h" /* Vendor */ #define USB_VENDOR_ID_LOGITECH 0x046D /* Driver */ #define UVC_DRIVER_NAME "uvcvideo" /* V4l2 Version */ #define V4L_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) #define UVC_DEVICE_NAME "video" /* UVC Transfer */ #define UVC_N_TRANSFER 2 #define UVC_N_BULKTRANSFER 3 #define UVC_N_ISOFRAMES 0x8 #define UVCINTR_N_TRANSFER 1 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 #define UVC_FMT_FLAG_STREAM 0x00000002 #define UDESCSUB_VC_HEADER 0x1 #define UDESCSUB_VC_INPUT_TERMINAL 0x2 #define UDESCSUB_VC_OUTPUT_TERMINAL 0x3 #define UDESCSUB_VC_SELECTOR_UNIT 0x4 #define UDESCSUB_VC_PROCESSING_UNIT 0x5 #define UDESCSUB_VC_EXTENSION_UNIT 0x6 /* VideoStreaming class specific interface descriptor */ #define UDESCSUB_VS_UNDEFINED 0x00 #define UDESCSUB_VS_INPUT_HEADER 0x01 #define UDESCSUB_VS_OUTPUT_HEADER 0x02 #define UDESCSUB_VS_STILL_IMAGE_FRAME 0x03 #define UDESCSUB_VS_FORMAT_UNCOMPRESSED 0x04 #define UDESCSUB_VS_FRAME_UNCOMPRESSED 0x05 #define UDESCSUB_VS_FORMAT_MJPEG 0x06 #define UDESCSUB_VS_FRAME_MJPEG 0x07 #define UDESCSUB_VS_FORMAT_MPEG2TS 0x0a #define UDESCSUB_VS_FORMAT_DV 0x0c #define UDESCSUB_VS_COLORFORMAT 0x0d #define UDESCSUB_VS_FORMAT_FRAME_BASED 0x10 #define UDESCSUB_VS_FRAME_FRAME_BASED 0x11 /* VideoStreaming interface controls */ #define VS_CONTROL_UNDEFINED 0x00 #define VS_PROBE_CONTROL 0x01 #define VS_COMMIT_CONTROL 0x02 #define VS_STILL_PROBE_CONTROL 0x03 #define VS_STILL_COMMIT_CONTROL 0x04 #define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05 #define VS_STREAM_ERROR_CODE_CONTROL 0x06 #define VS_GENERATE_KEY_FRAME_CONTROL 0x07 #define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08 #define VS_SYNC_DELAY_CONTROL 0x09 /* Selector Unit controls */ #define SU_CONTROL_UNDEFINED 0x00 #define SU_INPUT_SELECT_CONTROL 0x01 /* Input Terminal types */ #define UVC_ITT_VENDOR_SPECIFIC 0x0200 #define UVC_ITT_CAMERA 0x0201 #define UVC_ITT_MEDIA_TRANSPORT_INPUT 0x0202 /* Request codes */ #define RC_UNDEFINED 0x00 #define SET_CUR 0x01 #define GET_CUR 0x81 #define GET_MIN 0x82 #define GET_MAX 0x83 #define GET_RES 0x84 #define GET_LEN 0x85 #define GET_INFO 0x86 #define GET_DEF 0x87 /* A.9.1. VideoControl Interface Control Selectors */ #define UVC_VC_CONTROL_UNDEFINED 0x00 #define UVC_VC_VIDEO_POWER_MODE_CONTROL 0x01 #define UVC_VC_REQUEST_ERROR_CODE_CONTROL 0x02 /* A.9.2. Terminal Control Selectors */ #define UVC_TE_CONTROL_UNDEFINED 0x00 /* A.9.3. Selector Unit Control Selectors */ #define UVC_SU_CONTROL_UNDEFINED 0x00 #define UVC_SU_INPUT_SELECT_CONTROL 0x01 /* A.9.4. Camera Terminal Control Selectors */ #define UVC_CT_CONTROL_UNDEFINED 0x00 #define UVC_CT_SCANNING_MODE_CONTROL 0x01 #define UVC_CT_AE_MODE_CONTROL 0x02 #define UVC_CT_AE_PRIORITY_CONTROL 0x03 #define UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04 #define UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05 #define UVC_CT_FOCUS_ABSOLUTE_CONTROL 0x06 #define UVC_CT_FOCUS_RELATIVE_CONTROL 0x07 #define UVC_CT_FOCUS_AUTO_CONTROL 0x08 #define UVC_CT_IRIS_ABSOLUTE_CONTROL 0x09 #define UVC_CT_IRIS_RELATIVE_CONTROL 0x0a #define UVC_CT_ZOOM_ABSOLUTE_CONTROL 0x0b #define UVC_CT_ZOOM_RELATIVE_CONTROL 0x0c #define UVC_CT_PANTILT_ABSOLUTE_CONTROL 0x0d #define UVC_CT_PANTILT_RELATIVE_CONTROL 0x0e #define UVC_CT_ROLL_ABSOLUTE_CONTROL 0x0f #define UVC_CT_ROLL_RELATIVE_CONTROL 0x10 #define UVC_CT_PRIVACY_CONTROL 0x11 /* A.9.5. Processing Unit Control Selectors */ #define UVC_PU_CONTROL_UNDEFINED 0x00 #define UVC_PU_BACKLIGHT_COMPENSATION_CONTROL 0x01 #define UVC_PU_BRIGHTNESS_CONTROL 0x02 #define UVC_PU_CONTRAST_CONTROL 0x03 #define UVC_PU_GAIN_CONTROL 0x04 #define UVC_PU_POWER_LINE_FREQUENCY_CONTROL 0x05 #define UVC_PU_HUE_CONTROL 0x06 #define UVC_PU_SATURATION_CONTROL 0x07 #define UVC_PU_SHARPNESS_CONTROL 0x08 #define UVC_PU_GAMMA_CONTROL 0x09 #define UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a #define UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b #define UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c #define UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d #define UVC_PU_DIGITAL_MULTIPLIER_CONTROL 0x0e #define UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f #define UVC_PU_HUE_AUTO_CONTROL 0x10 #define UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11 #define UVC_PU_ANALOG_LOCK_STATUS_CONTROL 0x12 /* -------------------------------------------------------------------------- * UVC constants */ #define UVC_TERM_INPUT 0x0000 #define UVC_TERM_OUTPUT 0x8000 #define UVC_TERM_DIRECTION(term) ((term)->type & 0x8000) #define UVC_ENT_TYPE(ent) ((ent)->node_type & 0x7fff) #define UVC_ENT_IS_UNIT(ent) (((ent)->node_type & 0xff00) == 0) #define UVC_ENT_IS_TERM(ent) (((ent)->node_type & 0xff00) != 0) #define UVC_ENT_IS_ITERM(ent) \ (UVC_ENT_IS_TERM(ent) && \ ((ent)->node_type & 0x8000) == UVC_TERM_INPUT) #define UVC_ENT_IS_OTERM(ent) \ (UVC_ENT_IS_TERM(ent) && \ ((ent)->node_type & 0x8000) == UVC_TERM_OUTPUT) // 2.3 Video Function Topology enum uvc_topo_type { UVC_TOPO_TYPE_UNKNOWN, UVC_TOPO_TYPE_INPUT_TERMINAL, UVC_TOPO_TYPE_OUTPUT_TERMINAL, UVC_TOPO_TYPE_SELECTOR_UNIT, UVC_TOPO_TYPE_PROCESSING_UNIT, UVC_TOPO_TYPE_ENCODING_UNIT, UVC_TOPO_TYPE_EXTENSION_UNIT, UVC_TOPO_TYPE_CAMERA_TERMINAL, UVC_TOPO_TYPE_MEDIA_TRANSPORT_TERMINAL }; /* ------------------------------------------------------------------------ * GUIDs */ #define UVC_GUID_LOGITECH_DEV_INFO \ {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1e} #define UVC_GUID_LOGITECH_USER_HW \ {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1f} #define UVC_GUID_LOGITECH_VIDEO \ {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x50} #define UVC_GUID_LOGITECH_MOTOR \ {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x56} #define UVC_GUID_FORMAT_MJPEG \ { 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_YUY2 \ { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_NV12 \ { 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_YV12 \ { 'Y', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_I420 \ { 'I', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_UYVY \ { 'U', 'Y', 'V', 'Y', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_Y800 \ { 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_BY8 \ { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_H264 \ { 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} struct uvc_softc; struct uvc_v4l2; struct uvc_buf_queue; /* Video Descriptor */ struct uvc_vc_header_desc { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; uWord wRevision; uWord wTotalLen; uDWord dClockFreq; uByte bIfaceNums; uByte bIfaceList[0]; /* Interface Index Lists */ } __packed; struct uvc_vc_input_terminal_desc { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; uByte bTerminalID; uWord wTerminalType; uByte bAssocTerminal; uByte bITerminal; } __packed; struct uvc_vc_output_terminal_desc { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubType; uByte bTerminalID; uWord wTerminalType; uByte bAssocTerminal; uByte bSourceID; uByte bITerminal; } __packed; struct uvc_vc_selector_unit_desc { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubType; uByte bUnitID; uByte bNrInPins; uByte baSourceID[0]; uByte iSelector; } __packed; struct uvc_vc_processing_unit_desc { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubType; uByte bUnitID; uByte bSourceID; uWord wMaxMultiplier; uByte bControlSize; uByte bmControls[2]; uByte iProcessing; uByte bmVideoStandards; } __packed; struct uvc_vc_extension_unit_desc { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubType; uByte bUnitID; uByte guidExtensionCode[16]; uByte bNumControls; uByte bNrInPins; uByte baSourceID[0]; uByte bControlSize; uByte bmControls[0]; uByte iExtension; } __packed; struct uvc_vs_in_header_desc { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; uByte bFormatNum; uWord wTotalLen; uByte bEp; uByte bInfo; uByte bTerminalLink; uByte bStillCaptureMethod; uByte bTriggerSupport; uByte bTriggerUsage; uByte bControlSize; uByte bControls[0]; /* Controls */ } __packed; struct uvc_vs_color_desc { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; uByte bColorPris; uByte bTranChars; uByte bMatrix; }; struct uvc_vs_uncompressed_format_desc { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; uByte bFormatIndex; uByte bFrameNum; uByte bGuidFmt[16]; uByte bBpp; uByte bDefaultFrameIndex; uByte bAspectRadiox; uByte bAspectRadioy; uByte bInterlaceFlags; uByte bCopyProtect; } __packed; struct uvc_vs_frame_based_format_desc { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; uByte bFormatIndex; uByte bFrameNum; uByte bGuidFmt[16]; uByte bBitsPerpixel; uByte bDefaultFrameIndex; uByte bAspectRadiox; uByte bAspectRadioy; uByte bInterlaceFlags; uByte bCopyProtect; uByte bVariableSize; } __packed; struct uvc_vs_frame_desc { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; uByte bFrameIndex; uByte bCapabilities; uWord wWidth; uWord wHeight; uDWord dMinBitRate; uDWord dMaxBitRate; uDWord dMaxFrameBufferSize; uDWord dDefaultFrameInterval; uByte bFrameIntervalType; uDWord dFrameInterval[0]; } __packed; struct uvc_vs_frame_based_desc { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; uByte bFrameIndex; uByte bCapabilities; uWord wWidth; uWord wHeight; uDWord dMinBitRate; uDWord dMaxBitRate; uDWord dDefaultFrameInterval; uByte bFrameIntervalType; uDWord dwBytesPerLine; uDWord dFrameInterval[0]; } __packed; struct uvc_data_request { uWord wHint; uByte bFormatIndex; uByte bFrameIndex; uDWord dwFrameInterval; uWord wKeyFrameRate; uWord wPFrameRate; uWord wCompQuality; uWord wCompWindowSize; uWord wDelay; uDWord dwMaxFrameSize; uDWord dwMaxPayloadSize; uDWord dwClockFrequency; uByte bFramingInfo; uByte bPreferedVersion; uByte bMinVersion; uByte bMaxVersion; uByte __dummy[14]; } __packed; typedef char assert_uvc_data_request_is_48_bytes[(!!(sizeof(struct uvc_data_request)==48))*2-1]; struct uvc_data_payload_header { uint8_t len; #define UVC_PL_HEADER_BIT_FID (1) #define UVC_PL_HEADER_BIT_EOF (1 << 1) #define UVC_PL_HEADER_BIT_PTS (1 << 2) #define UVC_PL_HEADER_BIT_SCR (1 << 3) #define UVC_PL_HEADER_BIT_RES (1 << 4) #define UVC_PL_HEADER_BIT_STI (1 << 5) #define UVC_PL_HEADER_BIT_ERR (1 << 6) #define UVC_PL_HEADER_BIT_EOH (1 << 7) uint8_t header; #if 0 uint32_t pts; uint8_t scr[6]; #endif } __attribute__ ((packed)); /* * * Dynamic controls */ /* Data types for UVC control data */ #define UVC_CTRL_DATA_RAW 0 #define UVC_CTRL_DATA_SIGNED 1 #define UVC_CTRL_DATA_UNSIGNED 2 #define UVC_CTRL_DATA_BOOLEAN 3 #define UVC_CTRL_DATA_ENUM 4 #define UVC_CTRL_DATA_BITMASK 5 /* Control flags */ #define UVC_CTRL_SET_CUR 0x0001 #define UVC_CTRL_GET_CUR 0x0002 #define UVC_CTRL_GET_MIN 0x0004 #define UVC_CTRL_GET_MAX 0x0008 #define UVC_CTRL_GET_RES 0x0010 #define UVC_CTRL_GET_DEF 0x0020 #define UVC_CTRL_RESTORE 0x0040 #define UVC_CTRL_AUTO_UPDATE 0x0080 #define UVC_CTRL_ASYNCHRONOUS 0x0100 #define UVC_CTRL_GET_RANGE \ (UVC_CTRL_GET_CUR | UVC_CTRL_GET_MIN | \ UVC_CTRL_GET_MAX | UVC_CTRL_GET_RES | \ UVC_CTRL_GET_DEF) struct uvc_ctrl_menu_item { uint32_t value; char name[32]; }; struct uvc_ctrl_menu { uint32_t item_num; struct uvc_ctrl_menu_item* menu_data; }; struct uvc_ctrl_info { uint8_t index; /* Bit index in bmControls */ enum uvc_topo_type topo_type; uint8_t selector; uint16_t byte_size; uint32_t flags; uint32_t data_type; #define MAX_MAPPING_NUM 5 uint8_t sub_info_num; struct uvc_ctrl_sub_info* sub_infos[MAX_MAPPING_NUM]; struct uvc_ctrl_menu menus[MAX_MAPPING_NUM]; uint8_t cached_sub_info_idx; }; struct uvc_ctrl_sub_info { struct uvc_ctrl_info* uvc_info; uint32_t v4l2_id; uint8_t v4l2_name[32]; enum v4l2_ctrl_type v4l2_type; uint8_t bit_offset; uint8_t bit_size; /* superior & inferior is used to determine flag 'inactive'; E.g. Setting the V4L2_CID_HUE when V4L2_CID_HUE_AUTO is selected doesn't do anything. Only when the V4L2_CID_HUE_AUTO is turned off can you set the gain control. In this case, V4L2_CID_HUE_AUTO is superior of V4L2_CID_HUE. */ uint32_t superior_v4l2_id; uint32_t superior_manual; uint32_t inferior_v4l2_ids[2]; int32_t (*get)(struct uvc_ctrl_sub_info *this, uint8_t query, const uint8_t *data); void (*set)(struct uvc_ctrl_sub_info *this, int32_t value, uint8_t *data); }; struct uvc_control { struct uvc_topo_node *topo_node; struct uvc_ctrl_info info; uint8_t index; /* * Used to match the uvc_control entry * with a uvc_ctrl_info */ uint8_t dirty:1, loaded:1, modified:1, cached:1, initialized:1; uint8_t *uvc_data; /* File handle that last changed the control. */ struct uvc_drv_video *video; }; struct uvc_ct_node_info { uint16_t wObjectiveFocalLengthMin; uint16_t wObjectiveFocalLengthMax; uint16_t wOcularFocalLength; uint8_t bControlSize; uint8_t *bmControls; }; // Camera Terminal struct uvc_media_node_info { uint8_t bControlSize; uint8_t *bmControls; uint8_t bTransportModeSize; uint8_t *bmTransportModes; }; // MEDIA Transport Terminal struct uvc_pu_node_info { uint16_t wMaxMultiplier; uint8_t bControlSize; uint8_t *bmControls; uint8_t bmVideoStandards; }; // Processing Unit struct uvc_xu_node_info { uint8_t guidExtensionCode[16]; uint8_t bNumControls; uint8_t bControlSize; uint8_t *bmControls; uint8_t *bmControlsType; }; // Extension Unit struct uvc_topo_node { STAILQ_ENTRY(uvc_topo_node) link; char node_name[64]; uint16_t node_type; uint32_t flags; uint8_t node_id; // e.g.: // If Video Function Topology like this: // o---o // | 2 | // o---o // \___ o---o // ___ | 5 | // / o---o // o---o // | 3 | // o---o // // node 5 has two source ids, // one is node 2, another is node 3. uint16_t src_ids_num; uint8_t *src_ids; // mask of controls uint16_t controls_mask_len; uint8_t *controls_mask; uint32_t controls_num; struct uvc_control *controls; // data pointed by node_info is specified by topo_type void *node_info; }; struct uvc_data_interval { uint32_t val; }; struct uvc_data_frame { /* begin interval for this frame */ struct uvc_data_interval *interval; /* interval nums, desc string */ uint8_t interval_type; /* attribute */ uint8_t index; uint8_t cap; uint8_t nouse; uint32_t min_bit_rate; uint32_t max_bit_rate; uint32_t default_interval; uint32_t max_buffer_size; /* important */ uint16_t width; uint16_t height; }; struct uvc_data_format { /* begin frame for this format */ struct uvc_data_frame *frm; uint64_t nfrm; /* for COMPRESSED or not */ uint64_t flags; /* attributes */ uint32_t fcc; uint8_t index; uint8_t bpp; uint8_t colorspace; uint8_t unuse; char name[64]; }; struct uvc_drv_data { /* interface */ struct usb_interface *iface; /* for device configure iface_num + unit */ uint8_t iface_num; /* for usb framework */ uint8_t iface_index; /*for distinguishing bulk and iso uvc*/ uint8_t num_altsetting; uint16_t maxpsize; /* transfer */ //struct usb_xfer *xfer[UVC_N_TRANSFER]; struct usb_xfer *xfer[UVC_N_BULKTRANSFER]; /* data format */ uint8_t nfmt; uint8_t nfrm; uint8_t nitv; uint8_t unuse[3]; struct uvc_data_format *fmt; }; struct uvc_drv_ctrl { /* interface */ struct usb_interface *iface; /* for device configure iface_num + unit */ uint8_t iface_num; /* for usb framework */ uint8_t iface_index; struct lock mtx; /* desc infomation */ STAILQ_HEAD(, uvc_topo_node) topo_nodes; uint8_t sid; uint8_t h264id; uint8_t unuse; uint16_t revision; uint16_t clock_freq; }; struct uvc_drv_video { uint64_t unit; uint64_t users; uint64_t pri; uint64_t htsf; struct uvc_softc *sc; struct uvc_drv_ctrl *ctrl; struct uvc_drv_data *data; struct usb_xfer *intr_xfer[UVCINTR_N_TRANSFER]; struct lock mtx; struct uvc_data_request req; struct uvc_data_format *cur_fmt; struct uvc_data_frame *cur_frm; uint64_t enable; uint64_t bad_frame; enum v4l2_buf_type type; uint8_t last_fid; struct { uint8_t header[256]; uint8_t last_fid; uint32_t header_size; uint32_t skip_payload; uint32_t payload_size; uint32_t max_payload_size; } bulk; struct uvc_v4l2 *v4l2; struct uvc_buf_queue bq; }; struct uvc_drv_format_desc { char *name; uint8_t guid[16]; uint32_t fcc; }; struct uvc_softc { char name[64]; device_t dev; struct usb_device *udev; struct usb_interface *iface; struct uvc_drv_ctrl *ctrl; /* TODO: not only one */ struct uvc_drv_data *data; struct uvc_drv_video *video; enum v4l2_buf_type type; //struct uvc_buf_queue *bq; #define UVC_DROP_UNCOMPRESS_FORMAT 0x1 #define UVC_QUIRK_PROBE_MINMAX 0x2 #define UVC_BIGGER_TRANSFER_BUF 0x4 #define UVC_COMMIT_IN_ADVANCE 0x8 #define UVC_DISABLE_HUB_U1U2 0x16 #define UVC_NO_EOF (1<<6) uint8_t quirks; }; extern int uvc_debug; struct uvc_xu_control_query; MALLOC_DECLARE(M_UVC); int uvc_drv_check_video_context(struct uvc_drv_video *v, unsigned char *data, uint32_t len); int uvc_drv_get_v4l2_fmt(struct uvc_drv_video *v, struct v4l2_format *f); int uvc_drv_enum_v4l2_fmt(struct uvc_drv_video *v, struct v4l2_fmtdesc *vfmt); int uvc_drv_enum_v4l2_framesizes(struct uvc_drv_video *v, struct v4l2_frmsizeenum *fs); int uvc_drv_enum_v4l2_frameintervals(struct uvc_drv_video *v, struct v4l2_frmivalenum *itv); int uvc_drv_try_v4l2_fmt(struct uvc_drv_video *video, struct v4l2_format *vfmt, struct uvc_data_request *req, struct uvc_data_format **rfmt, struct uvc_data_frame **rfrm); int uvc_drv_set_video(struct uvc_drv_video *video, struct uvc_data_request *req, struct uvc_data_format *fmt, struct uvc_data_frame *frm); int uvc_drv_xu_ctrl_query(struct uvc_drv_video *v, struct uvc_xu_control_query *q); int uvc_drv_start_video(struct uvc_drv_video *video); int uvc_drv_stop_video(struct uvc_drv_video *video, int close); int uvc_drv_set_streampar(struct uvc_drv_video *v, struct v4l2_streamparm *a); int uvc_drv_get_selection(struct uvc_drv_video *v, struct v4l2_selection *sel); int uvc_drv_get_pixelaspect(void); //uvc controls int uvc_ctrl_init_dev(struct uvc_softc *sc, struct uvc_drv_ctrl *ctrls); void uvc_ctrl_destroy_mappings(struct uvc_control *ctrl); int uvc_query_v4l2_ctrl(struct uvc_drv_video *video, struct v4l2_queryctrl *v4l2_ctrl); int uvc_query_v4l2_menu(struct uvc_drv_video *video, struct v4l2_querymenu *qm); #endif /* end _DEV_USB_UVC_DRV_H */