1/* ---------------------------------------------------------------------------- 2 * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. 3 * Description: LiteOS USB Driver UVC Protocol 4 * Author: huangjieliang 5 * Create: 2017-04-17 6 * Redistribution and use in source and binary forms, with or without modification, 7 * are permitted provided that the following conditions are met: 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 * of conditions and the following disclaimer in the documentation and/or other materials 12 * provided with the distribution. 13 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 14 * to endorse or promote products derived from this software without specific prior written 15 * permission. 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * --------------------------------------------------------------------------- */ 28/* ---------------------------------------------------------------------------- 29 * Notice of Export Control Law 30 * =============================================== 31 * Huawei LiteOS may be subject to applicable export control laws and regulations, which might 32 * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. 33 * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such 34 * applicable export control laws and regulations. 35 * --------------------------------------------------------------------------- */ 36 37#include <los_mux.h> 38#include "gadget/f_uvc.h" 39#include "gadget/hicamera_control.h" 40#include "implementation/global_implementation.h" 41#ifdef LOSCFG_DRIVERS_USB2_DEVICE_CONTROLLER 42#include "controller/usb_device/dwc_otg_pcd.h" 43#endif 44 45#ifdef __cplusplus 46#if __cplusplus 47extern "C" { 48#endif /* __cplusplus */ 49#endif /* __cplusplus */ 50 51#ifdef F_UVC_DEBUG 52#define FUVC_DEBUG(x...) dprintf(x) 53#else 54#define FUVC_DEBUG(x...) do {} while (0) 55#endif 56 57#define FUVC_BULK_TO_ISO_CONVERT 1 /* 0: Bulk mode, 1: ISO mode */ 58 59#if FUVC_BULK_TO_ISO_CONVERT 60#define STREAM_BUF_SIZE 3072 61#ifdef LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER 62#define FRAME_BUF_SIZE_MAX 4147200 63#else 64#define FRAME_BUF_SIZE_MAX 1843200 65#endif 66#else 67#define STREAM_BUF_SIZE 16384 68#define FRAME_BUF_SIZE_MAX 1843200 69#endif 70 71int usbdev_uvc_initialize(struct module *mod, int n, void *arg); 72 73EVENT_CB_S g_uvc_event; 74 75static const driver_t g_fuvc_driver = 76{ 77 .name = "fuvc", 78 .methods = NULL, 79 .size = sizeof(struct uvc_softc) 80}; 81 82/* private device class information */ 83 84static devclass_t g_fuvc_devclass; 85 86DRIVER_MODULE(fuvc, simple, g_fuvc_driver, g_fuvc_devclass, usbdev_uvc_initialize, 0); 87 88static int usbclass_uvc_bind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev); 89static int usbclass_uvc_unbind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev); 90static int usbclass_uvc_setup(struct usbdevclass_driver_s *driver, struct usbdev_s *dev, 91 const struct usb_device_request *ctrl, uint8_t *dataout, size_t outlen); 92static void usbclass_uvc_disconnect(struct usbdevclass_driver_s *driver, 93 struct usbdev_s *dev); 94 95/* USB driver operations */ 96 97static const struct usbdevclass_driverops_s g_uvc_driverops = 98{ 99 usbclass_uvc_bind, 100 usbclass_uvc_unbind, 101 usbclass_uvc_setup, 102 usbclass_uvc_disconnect, 103 NULL, 104 NULL 105}; 106 107static const char g_fuvc_str_lang[] = 108{ 109 4, UDESC_STRING, 110 0x09, 0x04 111}; 112 113#define UVC_STR_IDX_MAN 1 114static const char g_fuvc_str_manufacturer[] = 115{ 116 14, UDESC_STRING, 117 'H', 0, 'U', 0, 'A', 0, 'W', 0, 'E', 0, 'I', 0 118}; 119 120#define UVC_STR_IDX_PRODUCT 2 121static const char g_fuvc_str_product[] = 122{ 123 14, UDESC_STRING, 124 'L', 0, 'i', 0, 't', 0, 'e', 0, 'O', 0, 'S', 0 125}; 126 127#define UVC_STR_IDX_CONFIG 5 128static const char g_fuvc_str_config[] = 129{ 130 22, UDESC_STRING, 131 'U', 0, 'V', 0, 'C', 0, ' ', 0, 'C', 0, 'A', 0, 132 'M', 0, 'E', 0, 'R', 0, 'A', 0 133}; 134 135#define UVC_STR_IDX_VIDEO 4 136static const char g_fuvc_str_video[] = 137{ 138 12, UDESC_STRING, 139 'V', 0, 'i', 0, 'd', 0, 'e', 0, 'o', 0 140}; 141 142#define UVC_STR_IDX_INTERFACE 6 143static const char g_fuvc_str_interface[] = 144{ 145 32, UDESC_STRING, 146 'V', 0, 'i', 0, 'd', 0, 'e', 0, 'o', 0, ' ', 0, 'S', 0, 't', 0, 147 'r', 0, 'e', 0, 'a', 0, 'm', 0, 'i', 0, 'n', 0, 'g', 0 148}; 149 150/* 151 * USB Video Class, Device Descriptor, for the details, 152 * please refer to USB 2.0 Specification, section 9.6.1 and 153 * USB Video Example 1.5, section 2.3.1 154 */ 155 156static const struct usb_device_descriptor g_fuvc_device_desc = 157{ 158 .bLength = sizeof(struct usb_device_descriptor), 159 .bDescriptorType = UDESC_DEVICE, /* Constant for device descriptor */ 160 HSETW(.bcdUSB, UD_BCD_USB), /* USB version required: 2.0 */ 161 .bDeviceClass = UICLASS_IAD, /* Miscellaneous Device Class */ 162 .bDeviceSubClass = 0x02, /* Common Class */ 163 .bDeviceProtocol = 0x01, /* Interface Association Descriptor */ 164 .bMaxPacketSize = UD_USB_MPS, /* Control Endpoint packet size */ 165 HSETW(.idVendor, 0x1d6b), /* Vendor ID of Huawei Technologies */ 166 HSETW(.idProduct, 0x0102), /* Product ID, webcamera? */ 167 HSETW(.bcdDevice, 0x0318), /* Device release code */ 168 .iManufacturer = UVC_STR_IDX_MAN, /* Manufacturer name, string index */ 169 .iProduct = UVC_STR_IDX_PRODUCT, /* Product name, string index */ 170 .iSerialNumber = 0, /* Not Used */ 171 .bNumConfigurations = 1 /* One Configuration */ 172}; 173 174/* 175 * USB Video Class, Configuration Descriptor, for the details, 176 * please refer to USB 2.0 Specification, section 9.6.3 and 177 * USB Video Example 1.5, section 2.3.2 178 */ 179 180static struct usb_config_descriptor g_fuvc_config_desc = 181{ 182 .bLength = sizeof(struct usb_config_descriptor), 183 .bDescriptorType = UDESC_CONFIG, 184 HSETW(.wTotalLength, 0), /* Size of all descriptors, set later */ 185 .bNumInterface = 0x2, /* Two Interfaces */ 186 .bConfigurationValue = 0x1, /* ID of this configuration */ 187 .iConfiguration = 0x4, /* Index of string descriptor */ 188 .bmAttributes = 0x80 | UC_SELF_POWERED, /* Self-powered */ 189 .bMaxPower = 1 /* Maximum power consumption from the bus */ 190}; 191 192/* 193 * USB Interface Association Descriptor, for the details, 194 * please refer to USB Video Class specification 1.5, section 3.6 or 195 * USB Video Example 1.5, section 2.3.3 196 */ 197 198static struct usb_interface_assoc_descriptor g_fuvc_iad = 199{ 200 .bLength = sizeof(struct usb_interface_assoc_descriptor), 201 .bDescriptorType = UDESC_IFACE_ASSOC, 202 .bFirstInterface = 0, /* Interface number of VideoControl interface */ 203 .bInterfaceCount = 2, /* Number of contiguous Video interfaces */ 204 .bFunctionClass = UICLASS_VIDEO, 205 .bFunctionSubClass = UICLASS_VIDEO_INTERFACE_COLLECTION, 206 .bFunctionProtocol = UICLASS_VIDEO_PROTOCOL_UNDEFINED, 207 .iFunction = UVC_STR_IDX_CONFIG /* index of string descriptor */ 208}; 209 210/* 211 * USB VideoControl Interface Descriptor, for the details, 212 * please refer to USB Video Class specification 1.5, section 3.7.1 213 * or USB Video Example 1.5, section 2.3.4.1 214 */ 215 216static struct usb_interface_descriptor g_fuvc_vc_intf_desc = 217{ 218 .bLength = sizeof(struct usb_interface_descriptor), 219 .bDescriptorType = UDESC_INTERFACE, 220 .bInterfaceNumber = 0, /* index number of this interface */ 221 .bAlternateSetting = 0, /* index of this settings */ 222 .bNumEndpoints = 1, /* one endpoint */ 223 .bInterfaceClass = UICLASS_VIDEO, 224 .bInterfaceSubClass = UICLASS_VIDEO_CONTROL, 225 .bInterfaceProtocol = UICLASS_VIDEO_PROTOCOL_UNDEFINED, 226 .iInterface = UVC_STR_IDX_CONFIG /* index of string descriptor */ 227}; 228 229/* UVC Class-specific VC interface header descriptor, UVC Example 1.5, section 2.3.4.2 */ 230 231static struct uvc_vc_header_descriptor g_fuvc_vc_head_desc = 232{ 233 .bLength = sizeof(struct uvc_vc_header_descriptor), 234 .bDescriptorType = USB_UVC_CS_INTERFACE, 235 .bDescriptorSubtype = UVC_VC_HEADER, 236 .bcdUVC = 0x0110, /* UVC specification version, 1.1 */ 237 .wTotalLength = 0, /* total length, currently not set */ 238 .dwClockFrequency = 48000000, /* clock frequency */ 239 .bInCollection = 0x1, /* Number of streaming interfaces */ 240 .bInterfaceNr = 0x1 /* Associated Video Streaming Interface */ 241}; 242 243#define UNIT_ID_CAMERA 1 244#define UNIT_ID_PROCESSING 2 245#define UNIT_ID_OUTPUT 3 246#define UNIT_ID_H264_EXTENSION 10 247#define UNIT_ID_HICAMERA_EXTENSION 0x11 248#define ENABLE_H264 1 249 250/* UVC input terminal descriptor, camera; UVC Example 1.5, section 2.3.4.3 */ 251 252static const struct uvc_ct_descriptor g_fuvc_vc_camera = 253{ 254 .bLength = sizeof(struct uvc_ct_descriptor), 255 .bDescriptorType = USB_UVC_CS_INTERFACE, /* CS_INTERFACE */ 256 .bDescriptorSubtype = UVC_VC_INPUT_TERMINAL, 257 .bTerminalID = UNIT_ID_CAMERA, /* ID of this input terminal */ 258 .wTerminalType = USB_UVC_ITT_CAMERA, 259 .bAssocTerminal = 0, /* No Association */ 260 .iTerminal = 0, /* Not used */ 261 .wObjectiveFocalLengthMin = 0, /* No optical zoom used */ 262 .wObjectiveFocalLengthMax = 0, /* No optical zoom used */ 263 .wOcularFocalLength = 0, /* No optical zoom used */ 264 .bControlSize = 3, /* Last Three bytes */ 265 .bmControls = { 0x0e, 0x0a, 0x00 } 266}; 267 268/* UVC Example 1.5, section 2.3.4.7 */ 269 270static const struct uvc_processing_descriptor g_fuvc_proc_desc = 271{ 272 .bLength = sizeof(struct uvc_processing_descriptor), 273 .bDescriptorType = USB_UVC_CS_INTERFACE, /* CS_INTERFACE */ 274 .bDescriptorSubtype = UVC_VC_PROCESSING_UNIT, 275 .bUnitID = UNIT_ID_PROCESSING, /* ID of this unit */ 276 .bSourceID = 0x01, /* input pin is connected to the output pin of unit 1 */ 277 .wMaxMultiplier = 16 * 1024, 278 .bControlSize = 0x3, /* sizeof `bmControls fields */ 279 .bmControls = { 0x5b, 0x17, 0x00 }, 280 .iProcessing = 0, /* no string index descriptor */ 281 .bmVideoStandards = 0 /* ignored */ 282}; 283 284/* UVC Example 1.5, section 2.3.4.5 */ 285 286static const struct uvc_ot_descriptor g_fuvc_vc_output_desc = 287{ 288 .bLength = sizeof(struct uvc_ot_descriptor), 289 .bDescriptorType = USB_UVC_CS_INTERFACE, /* CS_INTERFACE */ 290 .bDescriptorSubtype = UVC_VC_OUTPUT_TERMINAL, 291 .bTerminalID = UNIT_ID_OUTPUT, /* ID of this output terminal */ 292 .wTerminalType = USB_UVC_TT_STREAMING, 293 .bAssocTerminal = 0, /* No Association */ 294 .bSourceID = UNIT_ID_PROCESSING, /* input pin connected to the output pin of unit 2 */ 295 .iTerminal = 0 /* Not used */ 296}; 297 298#if ENABLE_H264 299static const struct uvc_extension_unit_descriptor1x2 g_fuvc_h264_ext_desc = 300{ 301 .bLength = sizeof(struct uvc_extension_unit_descriptor1x2), 302 .bDescriptorType = USB_UVC_CS_INTERFACE, 303 .bDescriptorSubtype = UVC_VC_EXTENSION_UNIT, 304 .bUnitID = UNIT_ID_H264_EXTENSION, 305 .guidExtensionCode = 306 { 307 /* refer UVC spec. 1.1, "USB_Video_Payload_H 264_1 0", Appendix-A */ 308 309 0x41, 0x76, 0x9e, 0xa2, 0x04, 0xde, 0xe3, 0x47, 310 0x8b, 0x2b, 0xf4, 0x34, 0x1a, 0xff, 0x00, 0x3b 311 }, 312 .bNumControls = 15, 313 .bNrInPins = 0x1, 314 .baSourceID = {0x02}, 315 .bControlSize = 2, 316 .bmControls = { 0xff, 0xff }, 317 .iExtension = 0 318}; 319#endif 320 321static const struct uvc_extension_unit_descriptor1x2 g_fuvc_hicamera_ext_desc = 322{ 323 .bLength = sizeof(struct uvc_extension_unit_descriptor1x2), 324 .bDescriptorType = USB_UVC_CS_INTERFACE, 325 .bDescriptorSubtype = UVC_VC_EXTENSION_UNIT, 326 .bUnitID = UNIT_ID_HICAMERA_EXTENSION, 327 .guidExtensionCode = 328 { 329 /* refer UVC spec. 1.1, "USB_Video_Payload_H 264_1 0", Appendix-A */ 330 331 0x91, 0x72, 0x1e, 0x9a, 0x43, 0x68, 0x83, 0x46, 332 0x6d, 0x92, 0x39, 0xbc, 0x79, 0x06, 0xee, 0x49 333 }, 334 .bNumControls = 0x15, 335 .bNrInPins = 0x1, 336 .baSourceID = {0x01}, 337 .bControlSize = 2, 338 .bmControls = { 0xff, 0xff }, 339 .iExtension = 0 340}; 341 342#if UVC_USE_CTRL_EP 343static struct usb_endpoint_descriptor g_fuvc_ctrl_ep_desc = 344{ 345 .bLength = sizeof(struct usb_endpoint_descriptor), 346 .bDescriptorType = UDESC_ENDPOINT, 347 348 /* Hi3516ev200 platform needs to specify endpoint number, otherwise the camera audio works abnormally. 349 * This way is compatible with other platforms. 350 */ 351 352 .bEndpointAddress = UE_DIR_IN | 0x3, 353 .bmAttributes = UE_XFERTYPE, 354 HSETW(.wMaxPacketSize, 16), 355 .bInterval = 8 356}; 357#endif 358 359#ifdef LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER 360static const struct usb_endpoint_ss_comp_descriptor g_fuvc_ctrl_ss_comp_desc = 361{ 362 .bLength = sizeof(struct usb_endpoint_ss_comp_descriptor), 363 .bDescriptorType = 0x30, 364 .bMaxBurst = 0, 365 .bmAttributes = 0, 366 HSETW(.wBytesPerInterval, 0x0010) 367}; 368#endif 369 370static const struct uvc_vc_int_endpoint_descriptor g_fuvc_int_ep_desc = 371{ 372 .bLength = sizeof(struct uvc_vc_int_endpoint_descriptor), 373 .bDescriptorType = USB_UVC_CS_ENDPOINT, 374 .bDescriptorSubtype = UVC_EP_INTERRUPT, 375 .wMaxTransferSize = 16 376}; 377 378static struct usb_interface_descriptor g_fuvc_vs_intf_alt0 = 379{ 380 .bLength = sizeof(struct usb_interface_descriptor), 381 .bDescriptorType = UDESC_INTERFACE, 382 .bInterfaceNumber = 0x1, 383 .bAlternateSetting = 0, 384#if FUVC_BULK_TO_ISO_CONVERT 385 .bNumEndpoints = 0, /* Isoc must be 0 */ 386#else 387 .bNumEndpoints = 1, /* Bulk must be 1 */ 388#endif 389 .bInterfaceClass = UICLASS_VIDEO, 390 .bInterfaceSubClass = UICLASS_VIDEO_STREAMING, 391 .bInterfaceProtocol = UICLASS_VIDEO_PROTOCOL_UNDEFINED, 392 .iInterface = UVC_STR_IDX_INTERFACE 393}; 394 395/* UVC Example 1.5, section 2.3.5.1.2 */ 396 397static struct uvc_vs_header_descriptor g_fuvc_vs_head_desc = 398{ 399 .bLength = sizeof(struct uvc_vs_header_descriptor), 400 .bDescriptorType = USB_UVC_CS_INTERFACE, 401 .bDescriptorSubtype = USB_UVC_VS_INPUT_HEADER, 402 .bNumFormats = 0x2 + ENABLE_H264, /* YUYV & H264 & MJPG */ 403 .wTotalLength = 0, /* total length, set later */ 404 .bmInfo = 0, /* do not support dynamic format change */ 405 .bTerminalLink = UNIT_ID_OUTPUT, /* terminal ID */ 406 .bStillCaptureMethod = 0, /* do not support still image capture */ 407 .bTriggerSupport = 0, /* do not support trigger */ 408 .bTriggerUsage = 0, /* ignored */ 409 .bControlSize = 1, 410 .bmaControls = { {0x00}, {0x00}, {0x00} } 411}; 412 413static struct uvc_uncompressed_format_descriptor g_fuvc_format_yuv = 414{ 415 .bLength = sizeof(struct uvc_uncompressed_format_descriptor), 416 .bDescriptorType = USB_UVC_CS_INTERFACE, 417 .bDescriptorSubtype = USB_UVC_VS_FORMAT_UNCOMPRESSED, 418 .bFormatIndex = 0x1, /* currently support only one format */ 419 .bNumFrameDescriptors = 0x6, /* only one frame descriptor follows */ 420 .guidFormat = 421 { 422 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, 0x80, 423 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 424 }, 425 .bBitsPerPixel = 16, /* two pixels share 4 bytes? */ 426 .bDefaultFrameIndex = 1, /* optimum Frame Index */ 427 .bAspectRatioX = 0, /* No Aspect Ratio */ 428 .bAspectRatioY = 0, 429 .bmInterlaceFlags = 0, /* No interlacing */ 430 .bCopyProtect = 0 /* No copy protect */ 431}; 432 433static struct uvc_uncompressed_frame_descriptor3 g_fuvc_frame_yuv_144p = 434{ 435 .bLength = sizeof(struct uvc_uncompressed_frame_descriptor3), 436 .bDescriptorType = USB_UVC_CS_INTERFACE, 437 .bDescriptorSubtype = USB_UVC_VS_FRAME_UNCOMPRESSED, 438 .bFrameIndex = 1, /* only one frame descriptor */ 439 .bmCapabilities = 0, 440 .wWidth = 176, 441 .wHeight = 144, 442 .dwMinBitRate = 18432000, 443 .dwMaxBitRate = 55296000, 444 .dwMaxVideoFrameBufferSize = 460800, 445 .dwDefaultFrameInterval = 333333, 446 .bFrameIntervalType = 3, 447 .dwFrameInterval = { 333333, 400000, 500000 } 448}; 449 450static struct uvc_uncompressed_frame_descriptor3 g_fuvc_frame_yuv_240p = 451{ 452 .bLength = sizeof(struct uvc_uncompressed_frame_descriptor3), 453 .bDescriptorType = USB_UVC_CS_INTERFACE, 454 .bDescriptorSubtype = USB_UVC_VS_FRAME_UNCOMPRESSED, 455 .bFrameIndex = 2, /* only one frame descriptor */ 456 .bmCapabilities = 0, 457 .wWidth = 320, 458 .wHeight = 240, 459 .dwMinBitRate = 18432000, 460 .dwMaxBitRate = 55296000, 461 .dwMaxVideoFrameBufferSize = 460800, 462 .dwDefaultFrameInterval = 333333, 463 .bFrameIntervalType = 3, 464 .dwFrameInterval = { 333333, 400000, 500000 } 465}; 466 467static struct uvc_uncompressed_frame_descriptor3 g_fuvc_frame_yuv_288p = 468{ 469 .bLength = sizeof(struct uvc_uncompressed_frame_descriptor3), 470 .bDescriptorType = USB_UVC_CS_INTERFACE, 471 .bDescriptorSubtype = USB_UVC_VS_FRAME_UNCOMPRESSED, 472 .bFrameIndex = 3, /* only one frame descriptor */ 473 .bmCapabilities = 0, 474 .wWidth = 352, 475 .wHeight = 288, 476 .dwMinBitRate = 18432000, 477 .dwMaxBitRate = 55296000, 478 .dwMaxVideoFrameBufferSize = 460800, 479 .dwDefaultFrameInterval = 333333, 480 .bFrameIntervalType = 3, 481 .dwFrameInterval = { 333333, 400000, 500000 } 482}; 483 484static struct uvc_uncompressed_frame_descriptor3 g_fuvc_frame_yuv_480p = 485{ 486 .bLength = sizeof(struct uvc_uncompressed_frame_descriptor3), 487 .bDescriptorType = USB_UVC_CS_INTERFACE, 488 .bDescriptorSubtype = USB_UVC_VS_FRAME_UNCOMPRESSED, 489 .bFrameIndex = 4, /* only one frame descriptor */ 490 .bmCapabilities = 0, 491 .wWidth = 640, 492 .wHeight = 480, 493 .dwMinBitRate = 55296000, 494 .dwMaxBitRate = 55296000, 495 .dwMaxVideoFrameBufferSize = 460800, 496 .dwDefaultFrameInterval = 333333, 497 .bFrameIntervalType = 3, 498 .dwFrameInterval = { 333333, 400000, 500000 } 499}; 500 501static struct uvc_uncompressed_frame_descriptor3 g_fuvc_frame_yuv_720p = 502{ 503 .bLength = sizeof(struct uvc_uncompressed_frame_descriptor3), 504 .bDescriptorType = USB_UVC_CS_INTERFACE, 505 .bDescriptorSubtype = USB_UVC_VS_FRAME_UNCOMPRESSED, 506 .bFrameIndex = 5, /* only one frame descriptor */ 507 .bmCapabilities = 0, 508 .wWidth = 1280, 509 .wHeight = 720, 510 .dwMinBitRate = 29491200, 511 .dwMaxBitRate = 29491200, 512 .dwMaxVideoFrameBufferSize = 1843200, 513 .dwDefaultFrameInterval = 333333, 514 .bFrameIntervalType = 3, 515 .dwFrameInterval = { 333333, 400000, 500000} 516}; 517 518static struct uvc_uncompressed_frame_descriptor3 g_fuvc_frame_yuv_1080p = 519{ 520 .bLength = sizeof(struct uvc_uncompressed_frame_descriptor3), 521 .bDescriptorType = USB_UVC_CS_INTERFACE, 522 .bDescriptorSubtype = USB_UVC_VS_FRAME_UNCOMPRESSED, 523 .bFrameIndex = 6, /* only one frame descriptor */ 524 .bmCapabilities = 0, 525 .wWidth = 1920, 526 .wHeight = 1080, 527 .dwMinBitRate = 29491200, 528 .dwMaxBitRate = 29491200, 529 .dwMaxVideoFrameBufferSize = 1843200, 530 .dwDefaultFrameInterval = 333333, 531 .bFrameIntervalType = 3, 532 .dwFrameInterval = { 333333, 400000, 500000 } 533}; 534 535static const struct uvc_color_matching_descriptor g_fuvc_color_matching_descriptor = 536{ 537 .bLength = sizeof(struct uvc_color_matching_descriptor), 538 .bDescriptorType = USB_UVC_CS_INTERFACE, 539 .bDescriptorSubtype = USB_UVC_VS_COLOR_FORMAT, 540 .bColorPrimaries = UVC_COLOR_BT709_SRGB, 541 .bTransferCharacteristics = UVC_COLOR_BT709_SRGB, 542 .bMatrixCoefficients = UVC_COLOR_MC_SMPTE_170M 543}; 544 545#if ENABLE_H264 546static struct uvc_frame_based_format_descriptor g_fuvc_format_h264 = 547{ 548 .bLength = sizeof(struct uvc_frame_based_format_descriptor), 549 .bDescriptorType = USB_UVC_CS_INTERFACE, 550 .bDescriptorSubtype = USB_UVC_VS_FORMAT_FRAME_BASED, 551 .bFormatIndex = 2, 552 .bNumFrameDescriptors = 6, 553 .guidFormat = 554 { 555 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, 0x80, 556 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 557 }, 558 .bBitsPerPixel = 16, 559 .bDefaultFrameIndex = 1, 560 .bAspectRatioX = 0, 561 .bAspectRatioY = 0, 562 .bmInterlaceFlags = 0, 563 .bCopyProtect = 0, 564 .bVariableSize = 1 565}; 566 567static struct uvc_frame_based_frame_descriptor3 g_fuvc_frame_h264_1080p = 568{ 569 .bLength = sizeof(struct uvc_frame_based_frame_descriptor3), 570 .bDescriptorType = USB_UVC_CS_INTERFACE, 571 .bDescriptorSubtype = USB_UVC_VS_FRAME_FRAME_BASED, 572 .bFrameIndex = 6, 573 .bmCapabilities = 0, 574 .wWidth = UVC_VIDEO_WIDTH_DEF, 575 .wHeight = UVC_VIDEO_HEIGHT_DEF, 576 .dwMinBitRate = 29491200, 577 .dwMaxBitRate = 29491200, 578 .dwDefaultFrameInterval = 333333, 579 .bFrameIntervalType = 3, /* number of supported Frame intervals */ 580 .dwBytesPerLine = 0, /* must be 0 */ 581 .dwFrameInterval = { 333333, 666667, 1000000 } 582}; 583 584static struct uvc_frame_based_frame_descriptor3 g_fuvc_frame_h264_720p = 585{ 586 .bLength = sizeof(struct uvc_frame_based_frame_descriptor3), 587 .bDescriptorType = USB_UVC_CS_INTERFACE, 588 .bDescriptorSubtype = USB_UVC_VS_FRAME_FRAME_BASED, 589 .bFrameIndex = 5, 590 .bmCapabilities = 0, 591 .wWidth = 1280, 592 .wHeight = 720, 593 .dwMinBitRate = 55296000, 594 .dwMaxBitRate = 55296000, 595 .dwDefaultFrameInterval = 333333, 596 .bFrameIntervalType = 3, /* number of supported Frame intervals */ 597 .dwBytesPerLine = 0, /* must be 0 */ 598 .dwFrameInterval = { 333333, 666667, 1000000 } 599}; 600 601static struct uvc_frame_based_frame_descriptor3 g_fuvc_frame_h264_480p = 602{ 603 .bLength = sizeof(struct uvc_frame_based_frame_descriptor3), 604 .bDescriptorType = USB_UVC_CS_INTERFACE, 605 .bDescriptorSubtype = USB_UVC_VS_FRAME_FRAME_BASED, 606 .bFrameIndex = 4, 607 .bmCapabilities = 0, 608 .wWidth = 640, 609 .wHeight = 480, 610 .dwMinBitRate = 29491200, 611 .dwMaxBitRate = 29491200, 612 .dwDefaultFrameInterval = 333333, 613 .bFrameIntervalType = 3, /* number of supported Frame intervals */ 614 .dwBytesPerLine = 0, /* must be 0 */ 615 .dwFrameInterval = { 333333, 666667, 1000000 } 616}; 617 618static struct uvc_frame_based_frame_descriptor3 g_fuvc_frame_h264_288p = 619{ 620 .bLength = sizeof(struct uvc_frame_based_frame_descriptor3), 621 .bDescriptorType = USB_UVC_CS_INTERFACE, 622 .bDescriptorSubtype = USB_UVC_VS_FRAME_FRAME_BASED, 623 .bFrameIndex = 3, 624 .bmCapabilities = 0, 625 .wWidth = 352, 626 .wHeight = 288, 627 .dwMinBitRate = 18432000, 628 .dwMaxBitRate = 29491200, 629 .dwDefaultFrameInterval = 333333, 630 .bFrameIntervalType = 3, /* number of supported Frame intervals */ 631 .dwBytesPerLine = 0, /* must be 0 */ 632 .dwFrameInterval = { 333333, 666667, 1000000 } 633}; 634 635static struct uvc_frame_based_frame_descriptor3 g_fuvc_frame_h264_240p = 636{ 637 .bLength = sizeof(struct uvc_frame_based_frame_descriptor3), 638 .bDescriptorType = USB_UVC_CS_INTERFACE, 639 .bDescriptorSubtype = USB_UVC_VS_FRAME_FRAME_BASED, 640 .bFrameIndex = 2, 641 .bmCapabilities = 0, 642 .wWidth = 320, 643 .wHeight = 240, 644 .dwMinBitRate = 18432000, 645 .dwMaxBitRate = 29491200, 646 .dwDefaultFrameInterval = 333333, 647 .bFrameIntervalType = 3, /* number of supported Frame intervals */ 648 .dwBytesPerLine = 0, /* must be 0 */ 649 .dwFrameInterval = { 333333, 666667, 1000000 } 650}; 651 652static struct uvc_frame_based_frame_descriptor3 g_fuvc_frame_h264_144p = 653{ 654 .bLength = sizeof(struct uvc_frame_based_frame_descriptor3), 655 .bDescriptorType = USB_UVC_CS_INTERFACE, 656 .bDescriptorSubtype = USB_UVC_VS_FRAME_FRAME_BASED, 657 .bFrameIndex = 1, 658 .bmCapabilities = 0, 659 .wWidth = 176, 660 .wHeight = 144, 661 .dwMinBitRate = 18432000, 662 .dwMaxBitRate = 29491200, 663 .dwDefaultFrameInterval = 333333, 664 .bFrameIntervalType = 3, /* number of supported Frame intervals */ 665 .dwBytesPerLine = 0, /* must be 0 */ 666 .dwFrameInterval = { 333333, 666667, 1000000 } 667}; 668#endif 669 670/************************ MJPG *******************************/ 671 672static struct uvc_format_mjpeg g_fuvc_format_mjpg = 673{ 674 .bLength = sizeof(struct uvc_format_mjpeg), 675 .bDescriptorType = USB_UVC_CS_INTERFACE, 676 .bDescriptorSubType = USB_UVC_VS_FORMAT_MJPEG, 677 .bFormatIndex = 3, 678 .bNumFrameDescriptors = 6, 679 .bmFlags = 0, 680 .bDefaultFrameIndex = 1, 681 .bAspectRatioX = 0, 682 .bAspectRatioY = 0, 683 .bmInterfaceFlags = 0, 684 .bCopyProtect = 0 685}; 686 687static struct uvc_mjpg_frame_descriptor1 g_fuvc_frame_mjpg_144p = 688{ 689 .bLength = sizeof(struct uvc_mjpg_frame_descriptor1), 690 .bDescriptorType = USB_UVC_CS_INTERFACE, 691 .bDescriptorSubType = USB_UVC_VS_FRAME_MJPEG, 692 .bFrameIndex = 1, 693 .bmCapabilities = 0, 694 .wWidth = 176, 695 .wHeight = 144, 696 .dwMinBitRate = 18432000, 697 .dwMaxBitRate = 55296000, 698 .dwMaxVideoFrameBufferSize = 460800, 699 .dwDefaultFrameInterval = 333333, 700 .bFrameIntervalType = 1, 701 .dwFrameInterval = {333333} 702}; 703 704static struct uvc_mjpg_frame_descriptor1 g_fuvc_frame_mjpg_240p = 705{ 706 .bLength = sizeof(struct uvc_mjpg_frame_descriptor1), 707 .bDescriptorType = USB_UVC_CS_INTERFACE, 708 .bDescriptorSubType = USB_UVC_VS_FRAME_MJPEG, 709 .bFrameIndex = 2, 710 .bmCapabilities = 0, 711 .wWidth = 320, 712 .wHeight = 240, 713 .dwMinBitRate = 18432000, 714 .dwMaxBitRate = 55296000, 715 .dwMaxVideoFrameBufferSize = 460800, 716 .dwDefaultFrameInterval = 333333, 717 .bFrameIntervalType = 1, 718 .dwFrameInterval = {333333} 719}; 720 721static struct uvc_mjpg_frame_descriptor1 g_fuvc_frame_mjpg_288p = 722{ 723 .bLength = sizeof(struct uvc_mjpg_frame_descriptor1), 724 .bDescriptorType = USB_UVC_CS_INTERFACE, 725 .bDescriptorSubType = USB_UVC_VS_FRAME_MJPEG, 726 .bFrameIndex = 3, 727 .bmCapabilities = 0, 728 .wWidth = 352, 729 .wHeight = 288, 730 .dwMinBitRate = 18432000, 731 .dwMaxBitRate = 55296000, 732 .dwMaxVideoFrameBufferSize = 460800, 733 .dwDefaultFrameInterval = 333333, 734 .bFrameIntervalType = 1, 735 .dwFrameInterval = {333333} 736}; 737 738static struct uvc_mjpg_frame_descriptor1 g_fuvc_frame_mjpg_480p = 739{ 740 .bLength = sizeof(struct uvc_mjpg_frame_descriptor1), 741 .bDescriptorType = USB_UVC_CS_INTERFACE, 742 .bDescriptorSubType = USB_UVC_VS_FRAME_MJPEG, 743 .bFrameIndex = 4, 744 .bmCapabilities = 0, 745 .wWidth = 640, 746 .wHeight = 480, 747 .dwMinBitRate = 55296000, 748 .dwMaxBitRate = 55296000, 749 .dwMaxVideoFrameBufferSize = 460800, 750 .dwDefaultFrameInterval = 333333, 751 .bFrameIntervalType = 1, 752 .dwFrameInterval = {333333} 753}; 754 755static struct uvc_mjpg_frame_descriptor1 g_fuvc_frame_mjpg_720p = 756{ 757 .bLength = sizeof(struct uvc_mjpg_frame_descriptor1), 758 .bDescriptorType = USB_UVC_CS_INTERFACE, 759 .bDescriptorSubType = USB_UVC_VS_FRAME_MJPEG, 760 .bFrameIndex = 5, 761 .bmCapabilities = 0, 762 .wWidth = 1280, 763 .wHeight = 720, 764 .dwMinBitRate = 29491200, 765 .dwMaxBitRate = 29491200, 766 .dwMaxVideoFrameBufferSize = 1843200, 767 .dwDefaultFrameInterval = 333333, 768 .bFrameIntervalType = 1, 769 .dwFrameInterval = {333333} 770}; 771 772static struct uvc_mjpg_frame_descriptor1 g_fuvc_frame_mjpg_1080p = 773{ 774 .bLength = sizeof(struct uvc_mjpg_frame_descriptor1), 775 .bDescriptorType = USB_UVC_CS_INTERFACE, 776 .bDescriptorSubType = USB_UVC_VS_FRAME_MJPEG, 777 .bFrameIndex = 6, 778 .bmCapabilities = 0, 779 .wWidth = 1920, 780 .wHeight = 1080, 781 .dwMinBitRate = 29491200, 782 .dwMaxBitRate = 29491200, 783 .dwMaxVideoFrameBufferSize = 1843200, 784 .dwDefaultFrameInterval = 333333, 785 .bFrameIntervalType = 1, 786 .dwFrameInterval = {333333} 787}; 788 789/************************ MJPG *******************************/ 790 791#if FUVC_BULK_TO_ISO_CONVERT 792static const struct usb_interface_descriptor g_fuvc_isoc_streaming_intf_alt1 = 793{ 794 .bLength = sizeof(struct usb_interface_descriptor), 795 .bDescriptorType = UDESC_INTERFACE, 796 .bInterfaceNumber = 0x1, 797 .bAlternateSetting = 1, 798 .bNumEndpoints = 1, 799 .bInterfaceClass = UICLASS_VIDEO, 800 .bInterfaceSubClass = UICLASS_VIDEO_STREAMING, 801 .bInterfaceProtocol = UICLASS_VIDEO_PROTOCOL_UNDEFINED, 802 .iInterface = UVC_STR_IDX_INTERFACE 803}; 804 805struct usb_endpoint_descriptor g_fuvc_hs_isoc_streaming_ep = 806{ 807 .bLength = sizeof(struct usb_endpoint_descriptor), 808 .bDescriptorType = UDESC_ENDPOINT, 809 810 /* Hi3516ev200 platform needs to specify endpoint number, otherwise the camera audio works abnormally. 811 * This way is compatible with other platforms. 812 */ 813 814 .bEndpointAddress = UE_DIR_IN | 0x2, 815 .bmAttributes = UE_ISO_ASYNC | UE_ISOCHRONOUS, 816 HSETW(.wMaxPacketSize, 0x1400), 817 .bInterval = 1 818}; 819 820#ifdef LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER 821static const struct usb_endpoint_ss_comp_descriptor g_fuvc_isoc_streaming_ss_comp_desc = 822{ 823 .bLength = sizeof(struct usb_endpoint_ss_comp_descriptor), 824 .bDescriptorType = 0x30, 825 .bMaxBurst = 0xe, 826 .bmAttributes = 2, 827 HSETW(.wBytesPerInterval, 0xa800) 828}; 829#endif 830#else 831 832/***********************BULK MODE***************************/ 833 834struct usb_endpoint_descriptor g_fuvc_hs_bulk_streaming_ep = 835{ 836 .bLength = USB_DT_ENDPOINT_SIZE, 837 .bDescriptorType = UDESC_ENDPOINT, 838 839 /* Hi3516ev200 platform needs to specify endpoint number, otherwise the camera audio works abnormally. 840 * This way is compatible with other platforms. 841 */ 842 843 .bEndpointAddress = UE_DIR_IN | 0x2, 844 .bmAttributes = USB_ENDPOINT_XFER_BULK, 845 846 /* The wMaxPacketSize and bInterval values will be initialized from 847 * module parameters. 848 */ 849 850#ifdef LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER 851 HSETW(.wMaxPacketSize, 0x0400), 852#else 853 HSETW(.wMaxPacketSize, 0x0200), 854#endif 855 .bInterval = 0 856}; 857 858#ifdef LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER 859static struct usb_endpoint_ss_comp_descriptor g_fuvc_bulk_streaming_ss_comp_desc = 860{ 861 .bLength = sizeof(struct usb_endpoint_ss_comp_descriptor), 862 .bDescriptorType = 0x30, 863 .bMaxBurst = 0x0, 864 .bmAttributes = 0, 865 HSETW(.wBytesPerInterval, 0) 866}; 867#endif 868#endif 869 870#ifdef LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER 871#if FUVC_BULK_TO_ISO_CONVERT 872#define DESCRIPTORS_NUM (39 + UVC_USE_CTRL_EP) 873#else 874#define DESCRIPTORS_NUM (38 + UVC_USE_CTRL_EP) 875#endif 876#else 877#if FUVC_BULK_TO_ISO_CONVERT 878#define DESCRIPTORS_NUM (37 + UVC_USE_CTRL_EP) 879#else 880#define DESCRIPTORS_NUM (36 + UVC_USE_CTRL_EP) 881#endif 882#endif 883 884/***********************BULK MODE***************************/ 885 886static const uint8_t *g_fuvc_descriptors_array[DESCRIPTORS_NUM] = 887{ 888 (const uint8_t *)&g_fuvc_config_desc, 889 (const uint8_t *)&g_fuvc_iad, 890 891/*******************video control***************************/ 892 893 (const uint8_t *)&g_fuvc_vc_intf_desc, 894 (const uint8_t *)&g_fuvc_vc_head_desc, 895 (const uint8_t *)&g_fuvc_vc_camera, 896 (const uint8_t *)&g_fuvc_proc_desc, 897#if ENABLE_H264 898 (const uint8_t *)&g_fuvc_h264_ext_desc, 899#endif 900 (const uint8_t *)&g_fuvc_hicamera_ext_desc, 901 902 (const uint8_t *)&g_fuvc_vc_output_desc, 903 904#if UVC_USE_CTRL_EP 905 (const uint8_t *)&g_fuvc_ctrl_ep_desc, 906#endif 907#ifdef LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER 908 (const uint8_t *)&g_fuvc_ctrl_ss_comp_desc, 909#endif 910 (const uint8_t *)&g_fuvc_int_ep_desc, 911 912/*******************video stream***************************/ 913 914 (const uint8_t *)&g_fuvc_vs_intf_alt0, 915 916#if FUVC_BULK_TO_ISO_CONVERT 917 (const uint8_t *)&g_fuvc_isoc_streaming_intf_alt1, 918 (const uint8_t *)&g_fuvc_hs_isoc_streaming_ep, 919#ifdef LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER 920 (const uint8_t *)&g_fuvc_isoc_streaming_ss_comp_desc, 921#endif 922#else 923 (const uint8_t *)&g_fuvc_hs_bulk_streaming_ep, 924#ifdef LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER 925 (const uint8_t *)&g_fuvc_bulk_streaming_ss_comp_desc, 926#endif 927#endif 928 929 (const uint8_t *)&g_fuvc_vs_head_desc, 930 931 (const uint8_t *)&g_fuvc_format_yuv, 932 (const uint8_t *)&g_fuvc_frame_yuv_144p, 933 (const uint8_t *)&g_fuvc_frame_yuv_240p, 934 (const uint8_t *)&g_fuvc_frame_yuv_288p, 935 (const uint8_t *)&g_fuvc_frame_yuv_480p, 936 (const uint8_t *)&g_fuvc_frame_yuv_720p, 937 (const uint8_t *)&g_fuvc_frame_yuv_1080p, 938 939#if ENABLE_H264 940 (const uint8_t *)&g_fuvc_format_h264, 941 (const uint8_t *)&g_fuvc_frame_h264_144p, 942 (const uint8_t *)&g_fuvc_frame_h264_240p, 943 (const uint8_t *)&g_fuvc_frame_h264_288p, 944 (const uint8_t *)&g_fuvc_frame_h264_480p, 945 (const uint8_t *)&g_fuvc_frame_h264_720p, 946 (const uint8_t *)&g_fuvc_frame_h264_1080p, 947#endif 948 949 (const uint8_t *)&g_fuvc_format_mjpg, 950 (const uint8_t *)&g_fuvc_frame_mjpg_144p, 951 (const uint8_t *)&g_fuvc_frame_mjpg_240p, 952 (const uint8_t *)&g_fuvc_frame_mjpg_288p, 953 (const uint8_t *)&g_fuvc_frame_mjpg_480p, 954 (const uint8_t *)&g_fuvc_frame_mjpg_720p, 955 (const uint8_t *)&g_fuvc_frame_mjpg_1080p, 956 (const uint8_t *)&g_fuvc_color_matching_descriptor, 957 NULL 958}; 959 960#define FRAME_NUM_MAX 7 961 962static struct fuvc_frame_info g_fuvc_frames_yuyv[FRAME_NUM_MAX] = 963{ 964 { 176, 144, { 333333, 0 }, }, 965 { 320, 240, { 333333, 0 }, }, 966 { 352, 288, { 333333, 0 }, }, 967 { 640, 480, { 333333, 0 }, }, 968 { 1280, 720, { 333333, 0 }, }, 969 { 1920, 1080, { 333333, 0 }, }, 970 { 0, 0, { 0, }, } 971}; 972 973static struct fuvc_frame_info g_fuvc_frames_mjpeg[FRAME_NUM_MAX] = 974{ 975 { 176, 144, { 333333, 0 }, }, 976 { 320, 240, { 333333, 0 }, }, 977 { 352, 288, { 333333, 0 }, }, 978 { 640, 480, { 333333, 0 }, }, 979 { 1280, 720, { 333333, 0 }, }, 980 { 1920, 1080, { 333333, 0 }, }, 981 { 0, 0, { 0, }, } 982}; 983 984#if ENABLE_H264 985static struct fuvc_frame_info g_fuvc_frames_h264[FRAME_NUM_MAX] = 986{ 987 { 176, 144, { 333333, 0 }, }, 988 { 320, 240, { 333333, 0 }, }, 989 { 352, 288, { 333333, 0 }, }, 990 { 640, 480, { 333333, 0 }, }, 991 { 1280, 720, { 333333, 0 }, }, 992 { 1920, 1080, { 333333, 0 }, }, 993 { 0, 0, { 0, }, } 994}; 995#endif 996 997static struct fuvc_format_info g_fuvc_formats[] = 998{ 999 { V4L2_PIX_FMT_YUYV, g_fuvc_frames_yuyv }, 1000#if ENABLE_H264 1001 { V4L2_PIX_FMT_H264, g_fuvc_frames_h264 }, 1002#endif 1003 { V4L2_PIX_FMT_MJPEG, g_fuvc_frames_mjpeg } 1004}; 1005 1006#define CLAMP(_val, _min, _max) ( \ 1007{ \ 1008 typeof(_val)__val = (_val); \ 1009 typeof(_min)__min = (_min); \ 1010 typeof(_max)__max = (_max); \ 1011 (void) (&__val == &__min); \ 1012 (void) (&__val == &__max); \ 1013 __val = __val < __min ? __min : __val; \ 1014 __val > __max ? __max : __val; \ 1015}) 1016 1017#define ARRAY_SIZE(a) ((sizeof(a) / sizeof(a[0]))) 1018 1019void fuvc_frame_descriptors_get(struct fuvc_format_info *format_info) 1020{ 1021 uint32_t nframes; 1022 errno_t err; 1023 1024 if (format_info == NULL) 1025 { 1026 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); 1027 return; 1028 } 1029 1030 nframes = 0; 1031 1032 while (format_info->frames[nframes].width != 0) 1033 { 1034 ++nframes; 1035 } 1036 1037 if (nframes >= FRAME_NUM_MAX || nframes == 0) 1038 { 1039 PRINT_ERR("%s %d %u \n", __FUNCTION__, __LINE__, nframes); 1040 return; 1041 } 1042 1043 if (format_info->fcc == V4L2_PIX_FMT_YUYV) 1044 { 1045 (void)memset_s(g_fuvc_frames_yuyv, sizeof(g_fuvc_frames_yuyv), 0, sizeof(g_fuvc_frames_yuyv)); 1046 err = memcpy_s(g_fuvc_frames_yuyv, sizeof(g_fuvc_frames_yuyv), 1047 format_info->frames, (sizeof(struct fuvc_frame_info) * nframes)); 1048 if (err != EOK) 1049 { 1050 PRINT_ERR("%s %d Memcpy fail!\n", __FUNCTION__, __LINE__); 1051 return; 1052 } 1053 } 1054#if ENABLE_H264 1055 else if (format_info->fcc == V4L2_PIX_FMT_H264) 1056 { 1057 (void)memset_s(g_fuvc_frames_h264, sizeof(g_fuvc_frames_h264), 0, sizeof(g_fuvc_frames_h264)); 1058 err = memcpy_s(g_fuvc_frames_h264, sizeof(g_fuvc_frames_h264), 1059 format_info->frames, (sizeof(struct fuvc_frame_info) * nframes)); 1060 if (err != EOK) 1061 { 1062 PRINT_ERR("%s %d Memcpy fail!\n", __FUNCTION__, __LINE__); 1063 return; 1064 } 1065 } 1066#endif 1067 else if (format_info->fcc == V4L2_PIX_FMT_MJPEG) 1068 { 1069 (void)memset_s(g_fuvc_frames_mjpeg, sizeof(g_fuvc_frames_mjpeg), 0, sizeof(g_fuvc_frames_mjpeg)); 1070 err = memcpy_s(g_fuvc_frames_mjpeg, sizeof(g_fuvc_frames_mjpeg), 1071 format_info->frames, (sizeof(struct fuvc_frame_info) * nframes)); 1072 if (err != EOK) 1073 { 1074 PRINT_ERR("%s %d Memcpy fail!\n", __FUNCTION__, __LINE__); 1075 return; 1076 } 1077 } 1078 else 1079 { 1080 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); 1081 return; 1082 } 1083} 1084 1085static void frames_descriptors_update(struct fuvc_format_info *format_info, uint32_t *index) 1086{ 1087 uint32_t num = *index; 1088 uint8_t nframes = 0; 1089 const struct fuvc_format_info *pformat = format_info; 1090 1091 while (pformat->frames[nframes].height != 0) 1092 { 1093 switch (pformat->frames[nframes].height) 1094 { 1095 case 144: 1096 if (pformat->fcc == V4L2_PIX_FMT_YUYV) 1097 { 1098 g_fuvc_frame_yuv_144p.bFrameIndex = nframes + 1; 1099 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_yuv_144p; 1100 } 1101#if ENABLE_H264 1102 else if (pformat->fcc == V4L2_PIX_FMT_H264) 1103 { 1104 g_fuvc_frame_h264_144p.bFrameIndex = nframes + 1; 1105 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_h264_144p; 1106 } 1107#endif 1108 else 1109 { 1110 g_fuvc_frame_mjpg_144p.bFrameIndex = nframes + 1; 1111 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_mjpg_144p; 1112 } 1113 break; 1114 1115 case 240: 1116 if (pformat->fcc == V4L2_PIX_FMT_YUYV) 1117 { 1118 g_fuvc_frame_yuv_240p.bFrameIndex = nframes + 1; 1119 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_yuv_240p; 1120 } 1121#if ENABLE_H264 1122 else if (pformat->fcc == V4L2_PIX_FMT_H264) 1123 { 1124 g_fuvc_frame_h264_240p.bFrameIndex = nframes + 1; 1125 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_h264_240p; 1126 } 1127#endif 1128 else 1129 { 1130 g_fuvc_frame_mjpg_240p.bFrameIndex = nframes + 1; 1131 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_mjpg_240p; 1132 } 1133 break; 1134 1135 case 288: 1136 if (pformat->fcc == V4L2_PIX_FMT_YUYV) 1137 { 1138 g_fuvc_frame_yuv_288p.bFrameIndex = nframes + 1; 1139 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_yuv_288p; 1140 } 1141#if ENABLE_H264 1142 else if (pformat->fcc == V4L2_PIX_FMT_H264) 1143 { 1144 g_fuvc_frame_h264_288p.bFrameIndex = nframes + 1; 1145 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_h264_288p; 1146 } 1147#endif 1148 else 1149 { 1150 g_fuvc_frame_mjpg_288p.bFrameIndex = nframes + 1; 1151 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_mjpg_288p; 1152 } 1153 break; 1154 1155 case 480: 1156 if (pformat->fcc == V4L2_PIX_FMT_YUYV) 1157 { 1158 g_fuvc_frame_yuv_480p.bFrameIndex = nframes + 1; 1159 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_yuv_480p; 1160 } 1161#if ENABLE_H264 1162 else if (pformat->fcc == V4L2_PIX_FMT_H264) 1163 { 1164 g_fuvc_frame_h264_480p.bFrameIndex = nframes + 1; 1165 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_h264_480p; 1166 } 1167#endif 1168 else 1169 { 1170 g_fuvc_frame_mjpg_480p.bFrameIndex = nframes + 1; 1171 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_mjpg_480p; 1172 } 1173 break; 1174 1175 case 720: 1176 if (pformat->fcc == V4L2_PIX_FMT_YUYV) 1177 { 1178 g_fuvc_frame_yuv_720p.bFrameIndex = nframes + 1; 1179 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_yuv_720p; 1180 } 1181#if ENABLE_H264 1182 else if (pformat->fcc == V4L2_PIX_FMT_H264) 1183 { 1184 g_fuvc_frame_h264_720p.bFrameIndex = nframes + 1; 1185 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_h264_720p; 1186 } 1187#endif 1188 else 1189 { 1190 g_fuvc_frame_mjpg_720p.bFrameIndex = nframes + 1; 1191 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_mjpg_720p; 1192 } 1193 break; 1194 1195 case 1080: 1196 if (pformat->fcc == V4L2_PIX_FMT_YUYV) 1197 { 1198 g_fuvc_frame_yuv_1080p.bFrameIndex = nframes + 1; 1199 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_yuv_1080p; 1200 } 1201#if ENABLE_H264 1202 else if (pformat->fcc == V4L2_PIX_FMT_H264) 1203 { 1204 g_fuvc_frame_h264_1080p.bFrameIndex = nframes + 1; 1205 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_h264_1080p; 1206 } 1207#endif 1208 else 1209 { 1210 g_fuvc_frame_mjpg_1080p.bFrameIndex = nframes + 1; 1211 g_fuvc_descriptors_array[num++] = (const uint8_t *)&g_fuvc_frame_mjpg_1080p; 1212 } 1213 break; 1214 1215 default: 1216 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); 1217 } 1218 1219 nframes++; 1220 } 1221 1222 *index = num; 1223} 1224 1225#ifdef LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER 1226#if FUVC_BULK_TO_ISO_CONVERT 1227#define DESC_UPDATE_INDEX (16 + UVC_USE_CTRL_EP) 1228#else 1229#define DESC_UPDATE_INDEX (15 + UVC_USE_CTRL_EP) 1230#endif 1231#else 1232#if FUVC_BULK_TO_ISO_CONVERT 1233#define DESC_UPDATE_INDEX (14 + UVC_USE_CTRL_EP) 1234#else 1235#define DESC_UPDATE_INDEX (13 + UVC_USE_CTRL_EP) 1236#endif 1237#endif 1238 1239static void fuvc_descriptors_update(void) 1240{ 1241 uint32_t index; 1242 uint8_t nframes = 0; 1243 struct fuvc_format_info *pformat; 1244 1245 for (index = DESC_UPDATE_INDEX; index < DESCRIPTORS_NUM; index++) 1246 { 1247 g_fuvc_descriptors_array[index] = NULL; 1248 } 1249 1250 /**************** yuyv format ***************/ 1251 1252 pformat = &g_fuvc_formats[UVC_VFF_YUY2]; 1253 while (pformat->frames[nframes].width != 0) 1254 { 1255 ++nframes; 1256 } 1257 g_fuvc_format_yuv.bNumFrameDescriptors = nframes; 1258 1259 index = DESC_UPDATE_INDEX; 1260 g_fuvc_descriptors_array[index++] = (const uint8_t *)&g_fuvc_format_yuv; 1261 1262 frames_descriptors_update(pformat, &index); 1263#if ENABLE_H264 1264 1265 /**************** h264 format ***************/ 1266 1267 nframes = 0; 1268 pformat = &g_fuvc_formats[UVC_VFF_H264]; 1269 while (pformat->frames[nframes].width != 0) 1270 { 1271 ++nframes; 1272 } 1273 g_fuvc_format_h264.bNumFrameDescriptors = nframes; 1274 1275 g_fuvc_descriptors_array[index++] = (const uint8_t *)&g_fuvc_format_h264; 1276 1277 frames_descriptors_update(pformat, &index); 1278#endif 1279 1280 /**************** mjpg format ***************/ 1281 1282 nframes = 0; 1283 pformat = &g_fuvc_formats[UVC_VFF_MJPG]; 1284 while (pformat->frames[nframes].width != 0) 1285 { 1286 ++nframes; 1287 } 1288 g_fuvc_format_mjpg.bNumFrameDescriptors = nframes; 1289 1290 g_fuvc_descriptors_array[index++] = (const uint8_t *)&g_fuvc_format_mjpg; 1291 1292 frames_descriptors_update(pformat, &index); 1293 1294 if (g_fuvc_descriptors_array[index] != NULL) 1295 { 1296 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); 1297 return; 1298 } 1299 1300 g_fuvc_descriptors_array[index++] = (const uint8_t *)&g_fuvc_color_matching_descriptor; 1301 return; 1302} 1303 1304/* 1305 * process the descriptors, link them together 1306 */ 1307 1308#define DESC_ARRAY_INDEX (DESC_UPDATE_INDEX - 1) 1309uint8_t *link_fuvc_descriptors(uint8_t *prefer, uint16_t ps, uint16_t *total_size) 1310{ 1311 int i; 1312 uint8_t *des; 1313 uint8_t *pdes; 1314 uint16_t ds = 0; 1315 uint16_t cs; 1316 errno_t err; 1317 1318 (void)prefer; 1319 (void)ps; 1320 1321 fuvc_descriptors_update(); 1322 1323 /* Add the length of descriptors one by one */ 1324 1325 for (i = 0; g_fuvc_descriptors_array[i] != NULL; ++i) 1326 { 1327 ds += (uint16_t)(*g_fuvc_descriptors_array[i]); 1328 } 1329 1330 FUVC_DEBUG("Total Length of descriptors: %u i=%d\n", ds, i); 1331 if (total_size != NULL) 1332 { 1333 *total_size = ds; 1334 } 1335 1336 des = memalign(64, SKB_DATA_ALIGN(ds)); 1337 if (des == NULL) 1338 { 1339 usb_err("System out of memory! Descriptors length: %u\n", ds); 1340 return NULL; 1341 } 1342 (void)memset_s(des, SKB_DATA_ALIGN(ds), 0, SKB_DATA_ALIGN(ds)); 1343 pdes = des; 1344 1345 /* configuration descriptor needs to have the full length of rest of descriptors */ 1346 1347 g_fuvc_config_desc.wTotalLength[0] = (uint8_t)ds; 1348 g_fuvc_config_desc.wTotalLength[1] = (uint8_t)(ds >> 8); 1349 1350 /* Add the length of video control descriptors */ 1351 1352 cs = (uint32_t)g_fuvc_vc_head_desc.bLength; 1353 cs += (uint32_t)g_fuvc_vc_camera.bLength; 1354 cs += (uint32_t)g_fuvc_proc_desc.bLength; 1355 cs += (uint32_t)g_fuvc_vc_output_desc.bLength; 1356 1357#if ENABLE_H264 1358 cs += (uint32_t)g_fuvc_h264_ext_desc.bLength; 1359#endif 1360 cs += (uint32_t)g_fuvc_hicamera_ext_desc.bLength; 1361 g_fuvc_vc_head_desc.wTotalLength = (uint16_t)cs; 1362 1363 ds = 0; 1364 for (i = DESC_ARRAY_INDEX; g_fuvc_descriptors_array[i] != NULL; i++) 1365 { 1366 ds += (uint16_t)*(g_fuvc_descriptors_array[i]); 1367 } 1368 1369 g_fuvc_vs_head_desc.wTotalLength = (uint16_t)ds; 1370#if FUVC_BULK_TO_ISO_CONVERT 1371 g_fuvc_vs_head_desc.bEndpointAddress = g_fuvc_hs_isoc_streaming_ep.bEndpointAddress; 1372#else 1373 g_fuvc_vs_head_desc.bEndpointAddress = g_fuvc_hs_bulk_streaming_ep.bEndpointAddress; 1374#endif 1375 1376 for (i = 0; g_fuvc_descriptors_array[i] != NULL; i++) 1377 { 1378 const u8 *des_src = g_fuvc_descriptors_array[i]; 1379 u8 des_len = *des_src; 1380 err = memcpy_s(pdes, des_len, des_src, des_len); 1381 if (err != EOK) 1382 { 1383 usb_err("memcpy fail!\n"); 1384 free(des); 1385 return NULL; 1386 } 1387 pdes += des_len; 1388 } 1389 1390 return des; 1391} 1392 1393#define FUVC_FUNCNAME_SIZE 32 1394static const char *func_msg = "Entering function [%s]\n"; 1395 1396int fuvc_host_connected(struct uvc_dev_s *fuvc) 1397{ 1398 if (fuvc == NULL) 1399 { 1400 return 0; 1401 } 1402 1403 return fuvc->connected; 1404} 1405 1406static void fuvc_vs_req_complete(struct usbdev_ep_s *ep, struct usbdev_req_s *req); 1407 1408int fuvc_transfer_initiate(struct uvc_dev_s *fuvc) 1409{ 1410 struct usbdev_req_s *req; 1411 struct usbdev_ep_s *vs_ep; 1412 1413 fuvc->fid ^= 1; 1414 vs_ep = fuvc->vs_ep; 1415 req = &(fuvc->streamreq); 1416 req->result = 0; 1417 1418 fuvc_vs_req_complete(vs_ep, req); 1419 1420 return UVC_OK; 1421} 1422 1423static void set_probe_status(struct uvc_dev_s *fuvc, int cs, int req) 1424{ 1425 if (cs == 0x01) 1426 { 1427 switch (req) 1428 { 1429 case 0x01: 1430 { 1431 fuvc->probe_status.set = 1; 1432 } 1433 break; 1434 1435 case 0x81: 1436 { 1437 fuvc->probe_status.get = 1; 1438 } 1439 break; 1440 1441 case 0x82: 1442 { 1443 fuvc->probe_status.min = 1; 1444 } 1445 break; 1446 1447 case 0x83: 1448 { 1449 fuvc->probe_status.max = 1; 1450 } 1451 break; 1452 1453 default: 1454 break; 1455 } 1456 } 1457} 1458 1459static int check_probe_status(struct uvc_dev_s *fuvc) 1460{ 1461 if (fuvc->probe_status.get == 1 && 1462 fuvc->probe_status.set == 1 && 1463 fuvc->probe_status.min == 1 && 1464 fuvc->probe_status.max == 1) 1465 { 1466 return 1; 1467 } 1468 1469 return 0; 1470} 1471 1472uint32_t g_com_flag = 0; 1473volatile uint32_t g_start_transfer = 0; 1474 1475static void fuvc_streaming_set(struct uvc_dev_s *fuvc, 1476 struct usbdev_req_s *req, 1477 const struct usb_device_request *ctrl) 1478{ 1479 struct uvc_probe_commit_control1_1 *target; 1480 struct uvc_probe_commit_control1_1 com; 1481 struct uvc_probe_commit_control1_1 *pcom; 1482 const struct fuvc_format_info *pformat; 1483 const struct fuvc_frame_info *frame; 1484 const uint32_t *interval; 1485 uint8_t iformat, iframe, nframes; 1486 1487 (void)ctrl; 1488 1489 switch (fuvc->control) 1490 { 1491 case USB_UVC_VS_PROBE_CONTROL: 1492 if (g_com_flag == 0) 1493 { 1494 return; 1495 } 1496 g_com_flag = 0; 1497 1498 target = &fuvc->probe; 1499 break; 1500 1501 case USB_UVC_VS_COMMIT_CONTROL: 1502 target = &fuvc->commit; 1503 break; 1504 1505 default: 1506 usb_err("setting unknown control\n"); 1507 return; 1508 } 1509 1510 pcom = (struct uvc_probe_commit_control1_1 *)(req->buf); 1511 com.bFormatIndex = pcom->bFormatIndex; 1512 com.bFrameIndex = pcom->bFrameIndex; 1513 com.dwFrameInterval = pcom->dwFrameInterval; 1514 1515 iformat = CLAMP((uint32_t)com.bFormatIndex, 1U, 1516 (uint32_t)ARRAY_SIZE(g_fuvc_formats)); 1517 1518 pformat = &g_fuvc_formats[iformat - 1]; 1519 1520 nframes = 0; 1521 1522 while (pformat->frames[nframes].width != 0) 1523 { 1524 ++nframes; 1525 } 1526 1527 iframe = CLAMP((uint32_t)com.bFrameIndex, 1U, (uint32_t)nframes); 1528 frame = &pformat->frames[iframe - 1]; 1529 interval = frame->intervals; 1530 1531 while (interval[0] < com.dwFrameInterval && interval[1]) 1532 { 1533 ++interval; 1534 } 1535 1536 target->bFormatIndex = iformat; 1537 target->bFrameIndex = iframe; 1538 1539 switch (pformat->fcc) 1540 { 1541 case V4L2_PIX_FMT_YUYV: 1542 target->dwMaxVideoFrameSize = frame->width * frame->height * 2; 1543 break; 1544 1545 case V4L2_PIX_FMT_MJPEG: 1546 case V4L2_PIX_FMT_H264: 1547 if (fuvc->imgsize == 0) 1548 { 1549 dprintf("WARNING: MJPEG requested and no image loaded.\n"); 1550 } 1551 1552 target->dwMaxVideoFrameSize = 1843200; 1553 break; 1554 1555 default: 1556 break; 1557 } 1558 1559 target->dwMaxPayloadTransferSize = STREAM_BUF_SIZE; 1560 target->dwFrameInterval = interval[0]; 1561 if (fuvc->control == USB_UVC_VS_COMMIT_CONTROL && check_probe_status(fuvc)) 1562 { 1563 fuvc->format_info.format = pformat->fcc; 1564 fuvc->format_info.width = frame->width; 1565 fuvc->format_info.height = frame->height; 1566 fuvc->format_info.status = FORMAT_SWITCH_PENDING; 1567 fuvc->connected = 0x1; 1568 g_start_transfer = 1; 1569 fuvc->transfer_status = STREAM_ON; 1570 if (!LOS_ListEmpty(&g_uvc_event.stEventList)) 1571 { 1572 (void)LOS_EventWrite(&g_uvc_event, 0x01); 1573 } 1574 } 1575 1576 if (fuvc->control == USB_UVC_VS_COMMIT_CONTROL) 1577 { 1578 (void)memset_s(&fuvc->probe_status, sizeof(fuvc->probe_status), 0, sizeof(fuvc->probe_status)); 1579 } 1580} 1581 1582static void fuvc_request_complete(struct usbdev_ep_s *ep, struct usbdev_req_s *req) 1583{ 1584 struct uvc_dev_s *fuvc; 1585 1586 (void)ep; /* ignored */ 1587 1588 fuvc = (struct uvc_dev_s *)req->priv; 1589 switch (fuvc->control) 1590 { 1591 case ~0u: 1592 break; 1593 1594 case USB_UVC_VS_PROBE_CONTROL: 1595 fuvc_streaming_set(fuvc, req, NULL); 1596 fuvc->control = ~0; 1597 break; 1598 1599 case USB_UVC_VS_COMMIT_CONTROL: 1600 fuvc_streaming_set(fuvc, req, NULL); 1601 fuvc->control = ~0; 1602 break; 1603 1604 default: 1605 fuvc->control = ~0; 1606 break; 1607 } 1608} 1609 1610#if UVC_USE_CTRL_EP 1611static void fuvc_vc_request_complete(struct usbdev_ep_s *ep, struct usbdev_req_s *req) 1612{ 1613 (void)ep; 1614 (void)req; 1615 dprintf(func_msg, __FUNCTION__); 1616} 1617#endif 1618 1619static int fuvc_vs_req_complete_sub(struct uvc_dev_s *fuvc, struct uvc_isoc_transfer *transfer, 1620 struct usbdev_req_s *req) 1621{ 1622 uint8_t *temp_buf; 1623 int ret; 1624 1625 if (req->result) 1626 { 1627 usb_err("req status is %d\n", req->result); 1628 req->result = 0; 1629 return -1; 1630 } 1631 1632 if (fuvc->transfer_status == STREAM_OFF) 1633 { 1634 if (!LOS_ListEmpty(&g_uvc_event.stEventList)) 1635 { 1636 if (LOS_EventWrite(&g_uvc_event, 0x01) == LOS_OK) 1637 { 1638 /* Write OK */ 1639 1640 } 1641 } 1642 return -1; 1643 } 1644 1645 temp_buf = fuvc->stream_buf; 1646 1647 /* The first two bytes of the uvc frame are the protocol headers. */ 1648 1649 transfer->data = &(temp_buf[0x2]); 1650 transfer->length = STREAM_BUF_SIZE - 2; 1651 transfer->reserved = 0x2; 1652 transfer->res_next = 0x2; 1653 1654 transfer->last = 0; 1655 ret = uvc_continue_transfer(fuvc, transfer); 1656 if (ret != UVC_OK) 1657 { 1658 /* Transfer should discontinue */ 1659 1660 FUVC_DEBUG("Fatal error, uvc_continue_transfer(...): %d\n", ret); 1661 return -1; 1662 } 1663 1664 return 0; 1665} 1666 1667#if FUVC_BULK_TO_ISO_CONVERT 1668static void fuvc_vs_req_complete(struct usbdev_ep_s *ep, struct usbdev_req_s *req) 1669{ 1670 int ret; 1671 uint8_t *temp_buf; 1672 struct uvc_dev_s *fuvc; 1673 struct uvc_isoc_transfer transfer; 1674 fuvc = (struct uvc_dev_s *)ep->priv; 1675 1676 ret = fuvc_vs_req_complete_sub(fuvc, &transfer, req); 1677 if (ret) 1678 { 1679 usb_err("data init failed!\n"); 1680 return; 1681 } 1682 1683 if (transfer.length == 0) 1684 { 1685 (void)LOS_EventWrite(&g_uvc_event, 0x01); 1686 return; 1687 } 1688 1689 temp_buf = fuvc->stream_buf; 1690 req->buf = (uint8_t *)VMM_TO_DMA_ADDR((UINTPTR)temp_buf); 1691 req->len = transfer.length + 0x2; 1692 1693 temp_buf[0] = 0x2; 1694 if (transfer.last) 1695 { 1696 temp_buf[1] = (uint8_t)(UVC_STREAM_HEADER_EOH | 1697 (fuvc->fid & UVC_STREAM_HEADER_FID) | UVC_STREAM_HEADER_EOF); 1698 } 1699 else 1700 { 1701 temp_buf[1] = (uint8_t)(UVC_STREAM_HEADER_EOH | (fuvc->fid & UVC_STREAM_HEADER_FID)); 1702 } 1703 1704 fuvc->last_complete = LOS_TickCountGet(); 1705 (void)EP_SUBMIT(ep, req); 1706} 1707#else 1708static void fuvc_vs_req_complete(struct usbdev_ep_s *ep, struct usbdev_req_s *req) 1709{ 1710 int ret; 1711 uint8_t *temp_buf; 1712 struct uvc_dev_s *fuvc; 1713 struct uvc_isoc_transfer transfer; 1714 fuvc = (struct uvc_dev_s *)ep->priv; 1715 1716 ret = fuvc_vs_req_complete_sub(fuvc, &transfer, req); 1717 if (ret) 1718 { 1719 usb_err("data init failed!\n"); 1720 return; 1721 } 1722 1723 if (fuvc->dyn_fc > 0x1) 1724 { 1725 /* 1726 * UVC Device Initated Dynamic Format Change Support 1727 * Refer to UVC spec. 1.5, section 2.4.3.6 for the details 1728 */ 1729 } 1730 1731 temp_buf = fuvc->stream_buf; 1732 if (transfer.length == 0) 1733 { 1734 if (fuvc->zero_packet_flag) 1735 { 1736 fuvc->zero_packet_flag = 0; 1737 req->buf = (uint8_t *)VMM_TO_DMA_ADDR((UINTPTR)temp_buf); 1738 req->len = transfer.length; 1739 (void)EP_SUBMIT(ep, req); 1740 return; 1741 } 1742 1743 (void)LOS_EventWrite(&g_uvc_event, 0x01); 1744 1745 return; 1746 } 1747 req->buf = (uint8_t *)VMM_TO_DMA_ADDR((UINTPTR)temp_buf); 1748 req->len = transfer.length + 0x2; 1749 temp_buf[0] = 0x2; 1750 temp_buf[1] = (uint8_t)(UVC_STREAM_HEADER_EOH | (fuvc->fid & UVC_STREAM_HEADER_FID)); 1751 1752 if (transfer.last && ((req->len % UGETW(ep->maxpacket)) == 0)) 1753 { 1754 fuvc->zero_packet_flag = 1; 1755 } 1756 1757 if (transfer.last) 1758 { 1759 if (fuvc->dyn_fc) 1760 { 1761 fuvc->dyn_fc++; 1762 } 1763 } 1764 1765 fuvc->last_complete = LOS_TickCountGet(); 1766 (void)EP_SUBMIT(ep, req); 1767} 1768#endif 1769 1770void fuvc_fill_streaming_control(struct uvc_dev_s *fuvc, 1771 struct uvc_probe_commit_control1_1 *ctrl, 1772 int iframe, int iformat) 1773{ 1774 const struct fuvc_format_info *pformat; 1775 const struct fuvc_frame_info *frame; 1776 uint32_t nframes; 1777 1778 if (iformat < 0) 1779 { 1780 iformat = ARRAY_SIZE(g_fuvc_formats) + iformat; 1781 } 1782 1783 if (iformat < 0 || iformat >= (int)ARRAY_SIZE(g_fuvc_formats)) 1784 { 1785 return; 1786 } 1787 1788 pformat = &g_fuvc_formats[iformat]; 1789 1790 nframes = 0; 1791 1792 while (pformat->frames[nframes].width != 0) 1793 { 1794 ++nframes; 1795 } 1796 1797 if (iframe < 0) 1798 { 1799 iframe = nframes + iframe; 1800 } 1801 1802 if (iframe < 0 || iframe >= (int)nframes) 1803 { 1804 return; 1805 } 1806 1807 frame = &pformat->frames[iframe]; 1808 1809 (void)memset_s(ctrl, sizeof(struct uvc_probe_commit_control1_1), 1810 0, sizeof(struct uvc_probe_commit_control1_1)); 1811 1812 ctrl->bmHint = 1; 1813 ctrl->bFormatIndex = iformat + 1; /* 1 is yuv, 2 is mjpeg */ 1814 ctrl->bFrameIndex = iframe + 1; /* 360 1 720 2 */ 1815 ctrl->dwFrameInterval = frame->intervals[0]; 1816 1817 switch (pformat->fcc) 1818 { 1819 case V4L2_PIX_FMT_YUYV: 1820 ctrl->dwMaxVideoFrameSize = frame->width * frame->height * 2; 1821 break; 1822 1823 case V4L2_PIX_FMT_MJPEG: 1824 case V4L2_PIX_FMT_H264: 1825 ctrl->dwMaxVideoFrameSize = 1843200; 1826 break; 1827 1828 default: 1829 break; 1830 } 1831 1832 ctrl->dwMaxPayloadTransferSize = STREAM_BUF_SIZE; 1833 ctrl->bmFramingInfo = 3; 1834 ctrl->bPreferedVersion = 1; 1835 ctrl->bMaxVersion = 1; 1836} 1837 1838static void fuvc_get_default_streaming_ctrl(struct uvc_dev_s *fuvc, 1839 struct uvc_probe_commit_control1_1 *ctrl, uint32_t fint) 1840{ 1841 fuvc_fill_streaming_control(fuvc, ctrl, 0, 0); 1842} 1843 1844static void fuvc_control_unit_callback(struct usbdev_ep_s *ep, struct usbdev_req_s *req) 1845{ 1846 struct uvc_dev_s *fuvc; 1847 int ret; 1848 1849 (void)ep; 1850 1851 fuvc = (struct uvc_dev_s *)req->priv; 1852 1853 ret = run_cmd_func(req->buf, req->xfrd, fuvc->event_id, UVC_RC_SETCUR, fuvc->unit_id); 1854 if (ret < 0) 1855 { 1856 usb_err("run_cmd_func return error!\n"); 1857 } 1858} 1859 1860static int fuvc_handle_camera_control(struct uvc_dev_s *fuvc, 1861 struct usbdev_req_s *req, 1862 const struct usb_device_request *ctrl) 1863{ 1864 uint16_t w_value; 1865 int ret = 0; 1866 1867 (void)fuvc; /* ignored for now */ 1868 (void)req; 1869 w_value = UGETW(ctrl->wValue); 1870 1871 /* The high byte of wValue contains the Control Selector 1872 * Refer to UVC spec. 1.5, section 4.1.1 & 4.1.2 1873 */ 1874 1875 switch (ctrl->bRequest) 1876 { 1877 case UVC_RC_SETCUR: 1878 req->callback = fuvc_control_unit_callback; 1879 fuvc->event_id = w_value >> 8; 1880 fuvc->unit_id = UNIT_ID_CAMERA; 1881 break; 1882 1883 default: 1884 ret = run_cmd_func(req->buf, req->xfrd, w_value >> 8, ctrl->bRequest, UNIT_ID_CAMERA); 1885 if (ret < 0) 1886 { 1887 usb_err("run_cmd_func return error!\n"); 1888 } 1889 break; 1890 } 1891 1892 return ret; 1893} 1894 1895static int fuvc_handle_process_control(struct uvc_dev_s *fuvc, 1896 struct usbdev_req_s *req, const struct usb_device_request *ctrl) 1897{ 1898 uint16_t w_value; 1899 int ret = 0; 1900 1901 (void)fuvc; 1902 (void)req; 1903 w_value = UGETW(ctrl->wValue); 1904 1905 switch (ctrl->bRequest) 1906 { 1907 case UVC_RC_SETCUR: 1908 req->callback = fuvc_control_unit_callback; 1909 fuvc->event_id = w_value >> 8; 1910 fuvc->unit_id = UNIT_ID_PROCESSING; 1911 break; 1912 1913 default: 1914 ret = run_cmd_func(req->buf, req->xfrd, w_value >> 8, ctrl->bRequest, UNIT_ID_PROCESSING); 1915 if (ret < 0) 1916 { 1917 usb_err("run_cmd_func return error!\n"); 1918 } 1919 break; 1920 } 1921 1922 return ret; 1923} 1924 1925#if ENABLE_H264 1926 1927/* We have two UVC specifications, version 1.1 & 1.5 1928 * The latter added H264 stream format/frame definition, 1929 * but the former supports H264 stream via extension unit. 1930 * After careful consideration, I think we'd better support 1931 * version 1.1, because it's better supported by windows 7 1932 */ 1933 1934static int fuvc_handle_ext_control(struct uvc_dev_s *fuvc, struct usbdev_req_s *req, 1935 const struct usb_device_request *ctrl) 1936{ 1937 uint16_t w_value; 1938 int ret = 0; 1939 1940 w_value = UGETW(ctrl->wValue); 1941 1942 switch (ctrl->bRequest) 1943 { 1944 case UVC_RC_SETCUR: 1945 req->callback = fuvc_control_unit_callback; 1946 fuvc->event_id = w_value >> 8; 1947 fuvc->unit_id = UNIT_ID_H264_EXTENSION; 1948 break; 1949 1950 default: 1951 ret = run_cmd_func(req->buf, req->xfrd, w_value >> 8, ctrl->bRequest, UNIT_ID_H264_EXTENSION); 1952 if (ret < 0) 1953 { 1954 usb_err("run_cmd_func return error!\n"); 1955 } 1956 break; 1957 } 1958 1959 return ret; 1960} 1961#endif 1962 1963static int fuvc_handle_xu_hicamera_control(struct uvc_dev_s *fuvc, struct usbdev_req_s *req, 1964 const struct usb_device_request *ctrl) 1965{ 1966 uint16_t w_value = UGETW(ctrl->wValue); 1967 int ret = 0; 1968 1969 switch (ctrl->bRequest) 1970 { 1971 case UVC_RC_SETCUR: 1972 req->callback = fuvc_control_unit_callback; 1973 fuvc->event_id = w_value >> 8; 1974 fuvc->unit_id = UNIT_ID_HICAMERA_EXTENSION; 1975 break; 1976 1977 default: 1978 ret = run_cmd_func(req->buf, req->xfrd, w_value >> 8, ctrl->bRequest, UNIT_ID_HICAMERA_EXTENSION); 1979 if (ret < 0) 1980 { 1981 usb_err("run_cmd_func return error!\n"); 1982 } 1983 break; 1984 } 1985 1986 return ret; 1987} 1988 1989static void fuvc_handle_class_setup_control(struct uvc_dev_s *fuvc, struct usbdev_req_s *req, 1990 const struct usb_device_request *ctrl) 1991{ 1992 int retval; 1993 errno_t err; 1994 uint16_t n_len; 1995 uint16_t w_length = UGETW(ctrl->wLength); 1996 uint16_t w_index = UGETW(ctrl->wIndex); 1997 uint16_t w_value = UGETW(ctrl->wValue); 1998 1999 retval = 0; 2000 err = memset_s(req->buf, USB_COMP_EP0_BUFSIZ, 0, 64); 2001 if (err != EOK) 2002 { 2003 usb_err("memset fail\n"); 2004 } 2005 2006 n_len = 32; 2007 if (n_len > w_length) 2008 { 2009 n_len = w_length; 2010 } 2011 2012 /* The high byte of wIndex indicates which entity the request addresses. 2013 * Refer to UVC spec. 1.5, section 4.1.1 & 4.1.2 2014 */ 2015 2016 switch (w_index >> 8) 2017 { 2018 case UNIT_ID_CAMERA: 2019 retval = fuvc_handle_camera_control(fuvc, req, ctrl); 2020 break; 2021 2022 case UNIT_ID_PROCESSING: 2023 retval = fuvc_handle_process_control(fuvc, req, ctrl); 2024 break; 2025 2026#if ENABLE_H264 2027 case UNIT_ID_H264_EXTENSION: 2028 retval = fuvc_handle_ext_control(fuvc, req, ctrl); 2029 break; 2030#endif 2031 2032 case UNIT_ID_HICAMERA_EXTENSION: 2033 retval = fuvc_handle_xu_hicamera_control(fuvc, req, ctrl); 2034 break; 2035 2036 default: 2037 dprintf("Control Requests not supported, index: %#x, w_value: %#x\n", w_index, w_value); 2038 break; 2039 } 2040 2041 if (retval <= 0) 2042 { 2043 req->len = n_len; 2044 } 2045 else 2046 { 2047 req->len = (unsigned)retval; 2048 } 2049} 2050 2051static int fuvc_handle_streaming_probe(struct uvc_dev_s *fuvc, struct usbdev_req_s *req, 2052 const struct usb_device_request *ctrl) 2053{ 2054 int retval; 2055 uint8_t breq; 2056 errno_t errnum; 2057 const char *errmsg = "UVC Streaming Probe: %s\n"; 2058 struct uvc_probe_commit_control1_1 commit1_1; 2059 2060 retval = 0; 2061 breq = ctrl->bRequest; 2062 switch (breq) 2063 { 2064 case UVC_RC_SETCUR: 2065 g_com_flag = 1; 2066 retval = 1; 2067 break; 2068 2069 case UVC_RC_SETCUR_ALL: 2070 dprintf(errmsg, "UVC_RC_SETCUR_ALL"); 2071 break; 2072 2073 case UVC_RC_GETINFO: 2074 dprintf(errmsg, "UVC_RC_GETINFO"); 2075 break; 2076 2077 case UVC_RC_GETCUR: 2078 if ((UGETW(ctrl->wValue) >> 8) == USB_UVC_VS_PROBE_CONTROL) 2079 { 2080 errnum = memcpy_s(req->buf, USB_COMP_EP0_BUFSIZ, 2081 &fuvc->probe, SKB_DATA_ALIGN(sizeof(struct uvc_probe_commit_control1_1))); 2082 } 2083 else 2084 { 2085 errnum = memcpy_s(req->buf, USB_COMP_EP0_BUFSIZ, 2086 &fuvc->commit, SKB_DATA_ALIGN(sizeof(struct uvc_probe_commit_control1_1))); 2087 } 2088 2089 if (errnum != EOK) 2090 { 2091 usb_err("memcpy fail %d\n", errnum); 2092 break; 2093 } 2094 2095 retval = 0; 2096 break; 2097 2098 case UVC_RC_GETMIN: 2099 case UVC_RC_GETMAX: 2100 case UVC_RC_GETRES: 2101 case UVC_RC_GETLEN: 2102 case UVC_RC_GETDEF: 2103 case UVC_RC_GETCUR_ALL: 2104 case UVC_RC_GETMIN_ALL: 2105 case UVC_RC_GETMAX_ALL: 2106 case UVC_RC_GETRES_ALL: 2107 case UVC_RC_GETDEF_ALL: 2108 fuvc_get_default_streaming_ctrl(fuvc, &commit1_1, 333333); 2109 errnum = memcpy_s(req->buf, USB_COMP_EP0_BUFSIZ, 2110 (void *)&commit1_1, SKB_DATA_ALIGN(sizeof(struct uvc_probe_commit_control1_1))); 2111 if (errnum != EOK) 2112 { 2113 usb_err("memcpy fail %d\n", errnum); 2114 break; 2115 } 2116 2117 retval = 0; 2118 break; 2119 2120 default: 2121 usb_err("Fatal Error, un-supported request from host: %#x\n", breq); 2122 break; 2123 } 2124 2125 return retval; 2126} 2127 2128static int fuvc_handle_class_setup_streaming(struct uvc_dev_s *fuvc, 2129 struct usbdev_req_s *req, const struct usb_device_request *ctrl) 2130{ 2131 int ret; 2132 errno_t errnum; 2133 const char * errmsg = NULL; 2134 uint16_t n_len, w_length, w_value; 2135 2136 ret = 0; 2137 n_len = (uint16_t)sizeof(struct uvc_probe_commit_control1_1); 2138 2139 w_value = UGETW(ctrl->wValue); 2140 w_length = UGETW(ctrl->wLength); 2141 2142 switch (w_value >> 8) 2143 { 2144 case USB_UVC_VS_PROBE_CONTROL: 2145 fuvc->control = USB_UVC_VS_PROBE_CONTROL; 2146 ret = fuvc_handle_streaming_probe(fuvc, req, ctrl); 2147 if (ret) 2148 { 2149 errnum = memcpy_s(req->buf, USB_COMP_EP0_BUFSIZ, &fuvc->probe, SKB_DATA_ALIGN(n_len)); 2150 if (errnum != EOK) 2151 { 2152 usb_err("memcpy fail, %d\n", errnum); 2153 break; 2154 } 2155 } 2156 2157 ret = 1; 2158 break; 2159 2160 case USB_UVC_VS_COMMIT_CONTROL: 2161 fuvc->control = USB_UVC_VS_COMMIT_CONTROL; 2162 (void)fuvc_handle_streaming_probe(fuvc, req, ctrl); 2163 ret = 1; 2164 break; 2165 2166 case USB_UVC_VS_STILL_PROBE_CONTROL: 2167 errmsg = "USB_UVC_VS_STILL_PROBE_CONTROL"; 2168 break; 2169 2170 case USB_UVC_VS_STILL_COMMIT_CONTROL: 2171 errmsg = "USB_UVC_VS_STILL_COMMIT_CONTROL"; 2172 break; 2173 2174 case USB_UVC_VS_STILL_IMAGE_TRIGGER_CONTROL: 2175 errmsg = "USB_UVC_VS_STILL_IMAGE_TRIGGER_CONTROL"; 2176 break; 2177 2178 case USB_UVC_VS_STREAM_ERROR_CODE_CONTROL: 2179 errmsg = "USB_UVC_VS_STREAM_ERROR_CODE_CONTROL"; 2180 break; 2181 2182 case USB_UVC_VS_GENERATE_KEY_FRAME_CONTROL: 2183 errmsg = "USB_UVC_VS_GENERATE_KEY_FRAME_CONTROL"; 2184 break; 2185 2186 case USB_UVC_VS_UPDATE_FRAME_SEGMENT_CONTROL: 2187 errmsg = "USB_UVC_VS_UPDATE_FRAME_SEGMENT_CONTROL"; 2188 break; 2189 2190 case USB_UVC_VS_SYNCH_DELAY_CONTROL: 2191 errmsg = "USB_UVC_VS_SYNCH_DELAY_CONTROL"; 2192 break; 2193 2194 default: 2195 dprintf("Invalid streaming control request: %#x\n", w_value); 2196 break; 2197 } 2198 2199 if (errmsg != NULL) 2200 { 2201 dprintf("UVC stream control %s not supported!\n", errmsg); 2202 } 2203 if (ret) 2204 { 2205 req->len = (n_len > w_length) ? w_length : n_len; 2206 } 2207 return ret; 2208} 2209 2210static void fuvc_source_free(struct usbdevclass_driver_s *driver, struct usbdev_s *dev) 2211{ 2212 struct uvc_driver_s *drvr = (struct uvc_driver_s *)driver; 2213 struct uvc_dev_s *fuvc = drvr->dev; 2214 2215 (void)EP_DISABLE(fuvc->ctrl_ep); 2216 (void)EP_DISABLE(fuvc->vs_ep); 2217 2218 DEV_FREEEP(dev, fuvc->ctrl_ep); 2219 DEV_FREEEP(dev, fuvc->vs_ep); 2220 2221 (void)LOS_EventDestroy(&g_uvc_event); 2222 2223 /* free allocated stream buffer pointer */ 2224 2225 if (fuvc->stream_buf != NULL) 2226 { 2227 free(fuvc->stream_buf); 2228 fuvc->stream_buf = NULL; 2229 } 2230} 2231 2232static int usbclass_uvc_bind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev) 2233{ 2234 int ret; 2235 struct usbdev_ep_s *ep; 2236 struct uvc_driver_s *uvc_drvr; 2237 struct uvc_dev_s *uvc_dev; 2238 struct composite_dev_s *cdev; 2239 struct composite_devobj_s *devobj; 2240 struct usbdev_devinfo_s *devinfo; 2241 2242 if (driver == NULL || dev == NULL) 2243 { 2244 return -1; 2245 } 2246 2247 cdev = dev->ep0->priv; 2248 if (cdev == NULL) 2249 { 2250 return -1; 2251 } 2252 uvc_drvr = (struct uvc_driver_s *)driver; 2253 uvc_dev = uvc_drvr->dev; 2254 if (uvc_dev == NULL) 2255 { 2256 return -1; 2257 } 2258 2259 devobj = usbclass_devobj_get(cdev, DEV_UVC); 2260 if (devobj == NULL) 2261 { 2262 return -1; 2263 } 2264 devinfo = &devobj->compdesc.devinfo; 2265 (void)memset_s(&uvc_dev->format_info, sizeof(struct uvc_format_info), 0, sizeof(struct uvc_format_info)); 2266 2267#if UVC_USE_CTRL_EP 2268 2269 /* initialize control endpoint */ 2270 2271 ep = DEV_ALLOCEP(dev, g_fuvc_ctrl_ep_desc.bEndpointAddress, 2272 (struct usb_endpoint_descriptor *)&g_fuvc_ctrl_ep_desc); 2273 if (ep == NULL) 2274 { 2275 goto fail; 2276 } 2277#ifdef LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER 2278 ep->comp_desc = &g_fuvc_ctrl_ss_comp_desc; 2279#endif 2280 ep->priv = (void *)uvc_dev; 2281 (void)memset_s(&(uvc_dev->vc_ctrlreq), sizeof(struct usbdev_req_s), 0, sizeof(struct usbdev_req_s)); 2282 uvc_dev->vc_ctrlreq.callback = fuvc_vc_request_complete; 2283 uvc_dev->vc_ctrlreq.priv = (void *)uvc_dev; 2284 ep->handle_req = &uvc_dev->vc_ctrlreq; 2285 uvc_dev->ctrl_ep = ep; 2286 devinfo->epno[0] = ep->eplog; 2287#endif 2288 2289 /* initialize VideoStreaming endpoint */ 2290 2291#if FUVC_BULK_TO_ISO_CONVERT 2292 ep = DEV_ALLOCEP(dev, g_fuvc_hs_isoc_streaming_ep.bEndpointAddress, 2293 (struct usb_endpoint_descriptor *)&g_fuvc_hs_isoc_streaming_ep); 2294 g_fuvc_vs_head_desc.bEndpointAddress = g_fuvc_hs_isoc_streaming_ep.bEndpointAddress; 2295#else 2296 ep = DEV_ALLOCEP(dev, g_fuvc_hs_bulk_streaming_ep.bEndpointAddress, 2297 (struct usb_endpoint_descriptor *)&g_fuvc_hs_bulk_streaming_ep); 2298 g_fuvc_vs_head_desc.bEndpointAddress = g_fuvc_hs_bulk_streaming_ep.bEndpointAddress; 2299#endif 2300 if (ep == NULL) 2301 { 2302 goto fail; 2303 } 2304 2305#ifdef LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER 2306#if FUVC_BULK_TO_ISO_CONVERT 2307 ep->comp_desc = &g_fuvc_isoc_streaming_ss_comp_desc; 2308#else 2309 ep->comp_desc = &g_fuvc_bulk_streaming_ss_comp_desc; 2310#endif 2311#endif 2312 (void)memset_s(&uvc_dev->streamreq, sizeof(struct usbdev_req_s), 0, sizeof(struct usbdev_req_s)); 2313 uvc_dev->streamreq.callback = fuvc_vs_req_complete; 2314 uvc_dev->streamreq.priv = (void *)uvc_dev; 2315 uvc_dev->streamreq.buf = NULL; 2316 2317 uvc_dev->stream_buf = (void *)memalign(USB_CACHE_ALIGN_SIZE, STREAM_BUF_SIZE); 2318 if (uvc_dev->stream_buf == NULL) 2319 { 2320 PRINT_ERR("No memory at line: %d!\n", __LINE__); 2321 goto fail; 2322 } 2323 ep->priv = (void *)uvc_dev; 2324 ep->handle_req = &uvc_dev->streamreq; 2325 uvc_dev->vs_ep = ep; 2326 devinfo->epno[1] = ep->eplog; 2327 2328 /* set the descriptors */ 2329 2330 uvc_dev->control = ~0; 2331 uvc_dev->uvc_handle = (void *)UVC_INVALID_HANDLE; 2332 spin_lock_init(&uvc_dev->lock); 2333 (void)LOS_EventInit(&g_uvc_event); 2334 2335 ret = uvc_stream_init(uvc_dev); 2336 if (ret != 0) 2337 { 2338 goto fail; 2339 } 2340 2341 uvc_dev->transfer_status = STREAM_OFF; 2342 2343 uvc_unit_control_register(); 2344 2345 return 0; 2346fail: 2347 (void)usbclass_uvc_unbind(driver, dev); 2348 return -1; 2349} 2350 2351static int usbclass_uvc_unbind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev) 2352{ 2353 struct composite_dev_s *cdev; 2354 struct composite_devobj_s *devobj; 2355 struct usbdev_devinfo_s *devinfo; 2356 struct uvc_driver_s *drvr; 2357 struct uvc_dev_s *fuvc; 2358 uint32_t ret; 2359 2360 if (driver == NULL || dev == NULL) 2361 { 2362 PRINT_ERR("fuvc_unbind_gadget failed!\n"); 2363 return -1; 2364 } 2365 2366 drvr = (struct uvc_driver_s *)driver; 2367 fuvc = drvr->dev; 2368 if (fuvc == NULL) 2369 { 2370 return -1; 2371 } 2372 2373 ret = LOS_MuxPend(g_uvc_mutex, LOS_WAIT_FOREVER); 2374 if (ret != LOS_OK) 2375 { 2376 return -1; 2377 } 2378 2379 if (uvc_is_running()) 2380 { 2381 (void)LOS_MuxPost(g_uvc_mutex); 2382 usb_err("uvc busy, unbind fail\n"); 2383 return -1; 2384 } 2385 2386 hi_camera_cmd_init(); 2387 usbclass_uvc_disconnect(driver, dev); 2388 2389 cdev = dev->ep0->priv; 2390 if (cdev == NULL) 2391 { 2392 return -1; 2393 } 2394 devobj = usbclass_devobj_get(cdev, DEV_UVC); 2395 if (devobj == NULL) 2396 { 2397 (void)LOS_MuxPost(g_uvc_mutex); 2398 return -1; 2399 } 2400 devinfo = &devobj->compdesc.devinfo; 2401 (void)memset_s(devinfo, sizeof(struct usbdev_devinfo_s), 0, sizeof(struct usbdev_devinfo_s)); 2402 fuvc_source_free(driver, dev); 2403 (void)LOS_MuxPost(g_uvc_mutex); 2404 uvc_delete_mutex(); 2405 return 0; 2406} 2407 2408void usbclass_uvc_stream_ep_reset(struct uvc_dev_s *fuvc) 2409{ 2410 (void)EP_DISABLE(fuvc->vs_ep); 2411 (void)EP_FLUSH(fuvc->vs_ep); 2412#if FUVC_BULK_TO_ISO_CONVERT 2413 (void)EP_CONFIGURE(fuvc->vs_ep, (const usb_endpoint_descriptor_t *)&g_fuvc_hs_isoc_streaming_ep, 0); 2414#else 2415 (void)EP_CONFIGURE(fuvc->vs_ep, (const usb_endpoint_descriptor_t *)&g_fuvc_hs_bulk_streaming_ep, 0); 2416#endif 2417} 2418 2419#if FUVC_BULK_TO_ISO_CONVERT 2420static void fuvc_streaming_on(struct uvc_dev_s *fuvc) 2421{ 2422 struct usbdev_req_s *req; 2423 2424 fuvc->connected = 1; 2425 g_start_transfer = 1; 2426 fuvc->transfer_status = STREAM_ON; 2427 2428 req = &(fuvc->streamreq); 2429 req->len = 0; 2430 req->buf = (uint8_t *)VMM_TO_DMA_ADDR((UINTPTR)fuvc->stream_buf); 2431 req->callback = fuvc->streamreq.callback; 2432 (void)EP_SUBMIT(fuvc->vs_ep, req); 2433 2434 return; 2435} 2436 2437static void fuvc_streaming_off(struct uvc_dev_s *fuvc) 2438{ 2439 fuvc->transfer_status = STREAM_OFF; 2440 g_start_transfer = 0; 2441 fuvc->connected = 0; 2442} 2443 2444static int usbclass_uvc_set_alt(struct uvc_dev_s *fuvc, struct usbdev_s *dev, 2445 unsigned intf, unsigned alt) 2446{ 2447 int ret = 0; 2448 2449 if (fuvc == NULL) 2450 { 2451 return -1; 2452 } 2453 2454 if (g_fuvc_vc_intf_desc.bInterfaceNumber == intf) 2455 { 2456#if UVC_USE_CTRL_EP 2457 if (fuvc->ctrl_ep->priv) 2458 { 2459 (void)EP_DISABLE(fuvc->ctrl_ep); 2460 fuvc->ctrl_ep->priv = NULL; 2461 } 2462 2463 ret = EP_CONFIGURE(fuvc->ctrl_ep, (const usb_endpoint_descriptor_t *)&g_fuvc_ctrl_ep_desc, 0); 2464 if (ret) 2465 { 2466 usb_err("Error enabling endpoint: %d\n", ret); 2467 return -1; 2468 } 2469 fuvc->ctrl_ep->priv = (void *)fuvc; 2470#endif 2471 } 2472 else if (g_fuvc_vs_intf_alt0.bInterfaceNumber == intf) 2473 { 2474 if (alt == 0) 2475 { 2476 if (fuvc->transfer_status != STREAM_ON) 2477 { 2478 return 0; 2479 } 2480 2481 if (fuvc->vs_ep) 2482 { 2483 (void)EP_DISABLE(fuvc->vs_ep); 2484 } 2485 2486 fuvc_streaming_off(fuvc); 2487 } 2488 else 2489 { 2490 if (fuvc->vs_ep->priv) 2491 { 2492 (void)EP_DISABLE(fuvc->vs_ep); 2493 fuvc->vs_ep->priv = NULL; 2494 } 2495 2496 ret = EP_CONFIGURE(fuvc->vs_ep, (const usb_endpoint_descriptor_t *)&g_fuvc_hs_isoc_streaming_ep, 0); 2497 if (ret) 2498 { 2499 usb_err("Error enabling endpoint: %d\n", ret); 2500 return -1; 2501 } 2502 fuvc->vs_ep->priv = (void *)fuvc; 2503 2504 fuvc_streaming_on(fuvc); 2505 } 2506 } 2507 else 2508 { 2509 return -EINVAL; 2510 } 2511 2512 return ret; 2513} 2514#else 2515static int usbclass_uvc_set_alt(struct uvc_dev_s *fuvc, struct usbdev_s *dev) 2516{ 2517 int ret = 0; 2518 2519 if (fuvc != NULL) 2520 { 2521#if UVC_USE_CTRL_EP 2522 if (fuvc->ctrl_ep->priv) 2523 { 2524 (void)EP_DISABLE(fuvc->ctrl_ep); 2525 fuvc->ctrl_ep->priv = NULL; 2526 } 2527 ret = EP_CONFIGURE(fuvc->ctrl_ep, (const usb_endpoint_descriptor_t *)&g_fuvc_ctrl_ep_desc, 0); 2528 if (ret) 2529 { 2530 usb_err("Error enabling endpoint: %d\n", ret); 2531 return -1; 2532 } 2533 fuvc->ctrl_ep->priv = (void *)fuvc; 2534#endif 2535 2536 if (fuvc->vs_ep->priv) 2537 { 2538 (void)EP_DISABLE(fuvc->vs_ep); 2539 fuvc->vs_ep->priv = NULL; 2540 } 2541 2542#if FUVC_BULK_TO_ISO_CONVERT 2543 usbd_configep_byspeed(dev, &g_fuvc_hs_isoc_streaming_ep); 2544 ret = EP_CONFIGURE(fuvc->vs_ep, (const usb_endpoint_descriptor_t *)&g_fuvc_hs_isoc_streaming_ep, 0); 2545#else 2546 usbd_configep_byspeed(dev, &g_fuvc_hs_bulk_streaming_ep); 2547 ret = EP_CONFIGURE(fuvc->vs_ep, (const usb_endpoint_descriptor_t *)&g_fuvc_hs_bulk_streaming_ep, 0); 2548#endif 2549 if (ret) 2550 { 2551 usb_err("Error enabling endpoint: %d\n", ret); 2552 return -1; 2553 } 2554 fuvc->vs_ep->priv = (void *)fuvc; 2555 2556 if (!LOS_ListEmpty(&g_uvc_event.stEventList)) 2557 { 2558 if (LOS_EventWrite(&g_uvc_event, 0x01) == LOS_OK) 2559 { 2560 /* Write OK */ 2561 2562 } 2563 } 2564 2565 if (g_start_transfer && fuvc->connected) 2566 { 2567 usbclass_uvc_stream_ep_reset(fuvc); 2568 fuvc->transfer_status = STREAM_OFF; 2569 g_start_transfer = 0; 2570 fuvc->connected = 0; 2571 } 2572 } 2573 2574 return ret; 2575} 2576#endif 2577 2578static int usbclass_uvc_setup(struct usbdevclass_driver_s *driver, struct usbdev_s *dev, 2579 const struct usb_device_request *ctrl, uint8_t *dataout, size_t outlen) 2580{ 2581 uint8_t req_type; 2582 uint8_t new_req = 0; 2583 uint16_t w_index; 2584 uint16_t w_value; 2585 struct uvc_dev_s *fuvc; 2586 struct uvc_driver_s *drvr; 2587 struct usbdev_req_s *req; 2588 2589 (void)dataout; 2590 (void)outlen; 2591 2592 if (driver == NULL || dev == NULL || ctrl == NULL) 2593 { 2594 return -1; 2595 } 2596 w_index = UGETW(ctrl->wIndex); 2597 w_value = UGETW(ctrl->wValue); 2598 2599 drvr = (struct uvc_driver_s *)driver; 2600 fuvc = drvr->dev; 2601 if (fuvc == NULL) 2602 { 2603 return -1; 2604 } 2605 2606 req = dev->ep0->handle_req; 2607 req->callback = fuvc_request_complete; 2608 req->priv = fuvc; 2609 2610 req_type = ctrl->bmRequestType; 2611 if (UT_GET_TYPE(req_type) == UT_STANDARD) 2612 { 2613 switch (ctrl->bRequest) 2614 { 2615 case USB_REQ_SET_CONFIGURATION: 2616 case USB_REQ_SET_INTERFACE: 2617#if FUVC_BULK_TO_ISO_CONVERT 2618 (void)usbclass_uvc_set_alt(fuvc, dev, w_index, w_value); 2619#else 2620 (void)usbclass_uvc_set_alt(fuvc, dev); 2621#endif 2622 break; 2623 2624 default: 2625 break; 2626 } 2627 } 2628 else 2629 { 2630 /* refer to section UVC spec. 1.5, section 4.1.2 */ 2631 2632 if ((req_type & 0x1f) == 0x2) 2633 { 2634 /* handle request directed to an endpoint */ 2635 2636 dprintf("Support request for endpoint: %#x\n", req_type); 2637 return 0; 2638 } 2639 2640 /* make sure that the request is directed to an interface */ 2641 2642 if ((req_type & 0x1f) != 0x1) 2643 { 2644 dprintf("Fatal Error at line: %d, req_type: %#x\n", __LINE__, req_type); 2645 return 0; 2646 } 2647 2648 if ((ctrl->bmRequestType & USB_RECIP_MASK) == USB_RECIP_INTERFACE) 2649 { 2650 set_probe_status(fuvc, (UGETW(ctrl->wValue) >> 8), ctrl->bRequest); 2651 } 2652 2653 w_index = UGETW(ctrl->wIndex); 2654 switch (w_index & 0xff) 2655 { 2656 case USB_UVC_INTERFACE_CONTROL: 2657 fuvc_handle_class_setup_control(fuvc, req, ctrl); 2658 new_req++; 2659 break; 2660 2661 case USB_UVC_INTERFACE_STREAMING: 2662 if (fuvc_handle_class_setup_streaming(fuvc, req, ctrl)) 2663 { 2664 new_req++; 2665 } 2666 break; 2667 2668 default: 2669 dprintf("Unknown index in [%s]: %#x\n", __FUNCTION__, w_index); 2670 break; 2671 } 2672 2673 if (new_req) 2674 { 2675 (void)EP_SUBMIT(dev->ep0, req); 2676 } 2677 } 2678 2679 return 0; 2680} 2681 2682static void usbclass_uvc_disconnect(struct usbdevclass_driver_s *driver, 2683 struct usbdev_s *dev) 2684{ 2685 struct uvc_driver_s *drvr; 2686 struct uvc_dev_s *fuvc; 2687 2688 if (driver == NULL || dev == NULL) 2689 { 2690 return; 2691 } 2692 2693 drvr = (struct uvc_driver_s *)driver; 2694 fuvc = drvr->dev; 2695 if (fuvc == NULL) 2696 { 2697 return; 2698 } 2699 2700 if (fuvc->connected) 2701 { 2702 fuvc->transfer_status = STREAM_OFF; 2703 g_start_transfer = 0; 2704 } 2705 2706 fuvc->connected = 0; 2707} 2708 2709struct usbd_string g_fuvc_device_strings[8] = 2710{ 2711 { 0, g_fuvc_str_lang }, 2712 { 1, g_fuvc_str_manufacturer }, 2713 { 2, g_fuvc_str_product }, 2714 { 4, g_fuvc_str_video }, 2715 { 5, g_fuvc_str_config }, 2716 { 6, g_fuvc_str_interface }, 2717 USBD_DEVICE_STRINGS_END 2718}; 2719 2720void uvc_mkdevdesc(uint8_t *buf) 2721{ 2722 errno_t ret; 2723 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, &g_fuvc_device_desc, sizeof(g_fuvc_device_desc)); 2724 if (ret != EOK) 2725 { 2726 usb_err("memcpy fail\n"); 2727 } 2728} 2729 2730int16_t uvc_mkcfgdesc(uint8_t *buf, struct usbdev_devinfo_s *devinfo) 2731{ 2732 uint16_t total_len; 2733 uint8_t *des; 2734 errno_t ret; 2735 2736 g_fuvc_iad.bFirstInterface = devinfo->ifnobase; 2737 g_fuvc_vc_intf_desc.bInterfaceNumber = devinfo->ifnobase; 2738 g_fuvc_vs_intf_alt0.bInterfaceNumber = devinfo->ifnobase + 1; 2739 2740 des = link_fuvc_descriptors(NULL, 0, &total_len); 2741 if (des != NULL) 2742 { 2743 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, des, total_len); 2744 if (ret != EOK) 2745 { 2746 usb_err("memcpy_s fail!, ret:%d\n", ret); 2747 free(des); 2748 return 0; 2749 } 2750 free(des); 2751 } 2752 2753 return (int16_t)total_len; 2754} 2755 2756int uvc_mkstrdesc(uint8_t id, uint8_t *buf) 2757{ 2758 errno_t ret; 2759 const char *str; 2760 int i; 2761 2762 for (i = 0; g_fuvc_device_strings[i].s != NULL; i++) 2763 { 2764 str = g_fuvc_device_strings[i].s; 2765 if (g_fuvc_device_strings[i].id == id) 2766 { 2767 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, str, str[0]); 2768 if (ret != EOK) 2769 { 2770 usb_err("memcpy_s failed, ret = %d\n", ret); 2771 return -1; 2772 } 2773 return str[0]; 2774 } 2775 } 2776 2777 usb_err("Can not find the id = %u of string\n", id); 2778 return -1; 2779} 2780 2781#define UVC_NCONFIGS 1 2782#define UVC_CONFIGID 0 2783#define UVC_NINTERFACES 2 2784#define UVC_NSTRIDS 6 2785#define UVC_NUM_EPS 2 2786void uvc_get_composite_devdesc(struct composite_devdesc_s *dev) 2787{ 2788 (void)memset_s(dev, sizeof(struct composite_devdesc_s), 0, sizeof(struct composite_devdesc_s)); 2789 2790 dev->mkdevdesc = uvc_mkdevdesc; 2791 dev->mkconfdesc = uvc_mkcfgdesc; 2792 dev->mkstrdesc = uvc_mkstrdesc; 2793 2794 dev->nconfigs = UVC_NCONFIGS; /* Number of configurations supported */ 2795 dev->configid = UVC_CONFIGID; /* The only supported configuration ID */ 2796 2797 /* Interfaces. 2798 * 2799 * ifnobase must be provided by board-specific logic 2800 */ 2801 2802 dev->devinfo.ninterfaces = UVC_NINTERFACES; /* Number of interfaces in the configuration */ 2803 2804 /* Strings. 2805 * 2806 * strbase must be provided by board-specific logic 2807 */ 2808 2809 dev->devinfo.nstrings = UVC_NSTRIDS; /* Number of Strings */ 2810 2811 /* Endpoints. 2812 * 2813 * Endpoint numbers must be provided by board-specific logic. 2814 */ 2815 2816 dev->devinfo.nendpoints = UVC_NUM_EPS; 2817} 2818 2819int uvc_classobject(int minor, struct usbdev_devinfo_s *devinfo, 2820 struct usbdevclass_driver_s **classdev) 2821{ 2822 struct uvc_softc *uvc_s; 2823 struct uvc_dev_s *priv; 2824 struct uvc_driver_s *drvr; 2825 2826 (void)minor; 2827 (void)devinfo; 2828 2829 /* Allocate the structures needed */ 2830 2831 uvc_s = (struct uvc_softc *)malloc(sizeof(struct uvc_softc)); 2832 if (uvc_s == NULL) 2833 { 2834 return -1; 2835 } 2836 2837 /* Convenience pointers into the allocated blob */ 2838 2839 priv = &uvc_s->dev; 2840 drvr = &uvc_s->drvr; 2841 2842 /* Initialize the USB serial driver structure */ 2843 2844 (void)memset_s(priv, sizeof(struct uvc_dev_s), 0, sizeof(struct uvc_dev_s)); 2845 2846 /* Initialize the USB class driver structure */ 2847 2848 drvr->drvr.speed = USB_SPEED_HIGH; 2849 drvr->drvr.ops = &g_uvc_driverops; 2850 drvr->dev = priv; 2851 2852 *classdev = &drvr->drvr; 2853 return 0; 2854} 2855 2856void uvc_uninitialize(struct usbdevclass_driver_s *classdev) 2857{ 2858 struct uvc_driver_s *uvc_drvr = (struct uvc_driver_s *)classdev; 2859 struct uvc_dev_s *priv; 2860 struct uvc_softc *uvc_s; 2861 2862 if (uvc_drvr == NULL) 2863 { 2864 return; 2865 } 2866 2867 priv = uvc_drvr->dev; 2868 if (priv == NULL) 2869 { 2870 return; 2871 } 2872 2873 uvc_s = container_of(uvc_drvr, struct uvc_softc, drvr); 2874 free(uvc_s); 2875} 2876 2877void usbdev_uvc_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor) 2878{ 2879 /* Ask the UVC driver to fill in the constants we didn't 2880 * know here. 2881 */ 2882 2883 uvc_get_composite_devdesc(dev); 2884 2885 /* Overwrite and correct some values... */ 2886 /* The callback functions for the UVC class */ 2887 2888 dev->classobject = uvc_classobject; 2889 dev->uninitialize = uvc_uninitialize; 2890 2891 /* Interfaces */ 2892 2893 dev->devinfo.ifnobase = ifnobase; /* Offset to Interface-IDs */ 2894 dev->minor = minor; /* The minor interface number */ 2895 2896 /* Strings */ 2897 2898 dev->devinfo.strbase = 0; /* Offset to String Numbers */ 2899} 2900 2901int usbdev_uvc_initialize(struct module *mod, int n, void *arg) 2902{ 2903 struct composite_softc *com_s = (struct composite_softc *)arg; 2904 struct composite_devdesc_s dev; 2905 int ret; 2906 2907 (void)mod; 2908 (void)n; 2909 2910 if (com_s == NULL) 2911 { 2912 return -1; 2913 } 2914 2915 usbdev_uvc_initialize_sub(&dev, 0, DEV_UVC); 2916 2917 ret = composite_initialize(com_s, 1, &dev); 2918 if (ret < 0) 2919 { 2920 return -1; 2921 } 2922 2923 PRINTK(" ** uvc device initialized successfully! **\n"); 2924 return 0; 2925} 2926 2927#ifdef __cplusplus 2928#if __cplusplus 2929} 2930#endif /* __cplusplus */ 2931#endif /* __cplusplus */ 2932