• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
47 extern "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 
71 int usbdev_uvc_initialize(struct module *mod, int n, void *arg);
72 
73 EVENT_CB_S g_uvc_event;
74 
75 static 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 
84 static devclass_t g_fuvc_devclass;
85 
86 DRIVER_MODULE(fuvc, simple, g_fuvc_driver, g_fuvc_devclass, usbdev_uvc_initialize, 0);
87 
88 static int usbclass_uvc_bind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev);
89 static int usbclass_uvc_unbind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev);
90 static 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);
92 static void usbclass_uvc_disconnect(struct usbdevclass_driver_s *driver,
93                                     struct usbdev_s *dev);
94 
95 /* USB driver operations */
96 
97 static 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 
107 static const char g_fuvc_str_lang[] =
108 {
109   4, UDESC_STRING,
110   0x09, 0x04
111 };
112 
113 #define UVC_STR_IDX_MAN   1
114 static 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
121 static 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
128 static 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
136 static 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
143 static 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 
156 static 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 
180 static 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 
198 static 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 
216 static 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 
231 static 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 
252 static 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 
270 static 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 
286 static 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
299 static 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 
321 static 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
343 static 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
360 static 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 
370 static 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 
378 static 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 
397 static 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 
413 static 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 
433 static 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 
450 static 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 
467 static 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 
484 static 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 
501 static 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 
518 static 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 
535 static 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
546 static 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 
567 static 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 
584 static 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 
601 static 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 
618 static 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 
635 static 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 
652 static 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 
672 static 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 
687 static 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 
704 static 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 
721 static 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 
738 static 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 
755 static 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 
772 static 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
792 static 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 
805 struct 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
821 static 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 
834 struct 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
859 static 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 
886 static 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 
962 static 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 
973 static 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
985 static 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 
997 static 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 
fuvc_frame_descriptors_get(struct fuvc_format_info * format_info)1019 void 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 
frames_descriptors_update(struct fuvc_format_info * format_info,uint32_t * index)1085 static 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 
fuvc_descriptors_update(void)1239 static 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)
link_fuvc_descriptors(uint8_t * prefer,uint16_t ps,uint16_t * total_size)1309 uint8_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
1394 static const char *func_msg = "Entering function [%s]\n";
1395 
fuvc_host_connected(struct uvc_dev_s * fuvc)1396 int 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 
1406 static void fuvc_vs_req_complete(struct usbdev_ep_s *ep, struct usbdev_req_s *req);
1407 
fuvc_transfer_initiate(struct uvc_dev_s * fuvc)1408 int 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 
set_probe_status(struct uvc_dev_s * fuvc,int cs,int req)1423 static 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 
check_probe_status(struct uvc_dev_s * fuvc)1459 static 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 
1472 uint32_t g_com_flag = 0;
1473 volatile uint32_t g_start_transfer = 0;
1474 
fuvc_streaming_set(struct uvc_dev_s * fuvc,struct usbdev_req_s * req,const struct usb_device_request * ctrl)1475 static 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 
fuvc_request_complete(struct usbdev_ep_s * ep,struct usbdev_req_s * req)1582 static 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
fuvc_vc_request_complete(struct usbdev_ep_s * ep,struct usbdev_req_s * req)1611 static 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 
fuvc_vs_req_complete_sub(struct uvc_dev_s * fuvc,struct uvc_isoc_transfer * transfer,struct usbdev_req_s * req)1619 static 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
fuvc_vs_req_complete(struct usbdev_ep_s * ep,struct usbdev_req_s * req)1668 static 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
fuvc_vs_req_complete(struct usbdev_ep_s * ep,struct usbdev_req_s * req)1708 static 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 
fuvc_fill_streaming_control(struct uvc_dev_s * fuvc,struct uvc_probe_commit_control1_1 * ctrl,int iframe,int iformat)1770 void 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 
fuvc_get_default_streaming_ctrl(struct uvc_dev_s * fuvc,struct uvc_probe_commit_control1_1 * ctrl,uint32_t fint)1838 static 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 
fuvc_control_unit_callback(struct usbdev_ep_s * ep,struct usbdev_req_s * req)1844 static 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 
fuvc_handle_camera_control(struct uvc_dev_s * fuvc,struct usbdev_req_s * req,const struct usb_device_request * ctrl)1860 static 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 
fuvc_handle_process_control(struct uvc_dev_s * fuvc,struct usbdev_req_s * req,const struct usb_device_request * ctrl)1895 static 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 
fuvc_handle_ext_control(struct uvc_dev_s * fuvc,struct usbdev_req_s * req,const struct usb_device_request * ctrl)1934 static 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 
fuvc_handle_xu_hicamera_control(struct uvc_dev_s * fuvc,struct usbdev_req_s * req,const struct usb_device_request * ctrl)1963 static 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 
fuvc_handle_class_setup_control(struct uvc_dev_s * fuvc,struct usbdev_req_s * req,const struct usb_device_request * ctrl)1989 static 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 
fuvc_handle_streaming_probe(struct uvc_dev_s * fuvc,struct usbdev_req_s * req,const struct usb_device_request * ctrl)2051 static 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 
fuvc_handle_class_setup_streaming(struct uvc_dev_s * fuvc,struct usbdev_req_s * req,const struct usb_device_request * ctrl)2128 static 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 
fuvc_source_free(struct usbdevclass_driver_s * driver,struct usbdev_s * dev)2210 static 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 
usbclass_uvc_bind(struct usbdevclass_driver_s * driver,struct usbdev_s * dev)2232 static 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;
2346 fail:
2347   (void)usbclass_uvc_unbind(driver, dev);
2348   return -1;
2349 }
2350 
usbclass_uvc_unbind(struct usbdevclass_driver_s * driver,struct usbdev_s * dev)2351 static 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 
usbclass_uvc_stream_ep_reset(struct uvc_dev_s * fuvc)2408 void 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
fuvc_streaming_on(struct uvc_dev_s * fuvc)2420 static 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 
fuvc_streaming_off(struct uvc_dev_s * fuvc)2437 static 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 
usbclass_uvc_set_alt(struct uvc_dev_s * fuvc,struct usbdev_s * dev,unsigned intf,unsigned alt)2444 static 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
usbclass_uvc_set_alt(struct uvc_dev_s * fuvc,struct usbdev_s * dev)2515 static 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 
usbclass_uvc_setup(struct usbdevclass_driver_s * driver,struct usbdev_s * dev,const struct usb_device_request * ctrl,uint8_t * dataout,size_t outlen)2578 static 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 
usbclass_uvc_disconnect(struct usbdevclass_driver_s * driver,struct usbdev_s * dev)2682 static 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 
2709 struct 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 
uvc_mkdevdesc(uint8_t * buf)2720 void 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 
uvc_mkcfgdesc(uint8_t * buf,struct usbdev_devinfo_s * devinfo)2730 int16_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 
uvc_mkstrdesc(uint8_t id,uint8_t * buf)2756 int 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
uvc_get_composite_devdesc(struct composite_devdesc_s * dev)2786 void 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 
uvc_classobject(int minor,struct usbdev_devinfo_s * devinfo,struct usbdevclass_driver_s ** classdev)2819 int 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 
uvc_uninitialize(struct usbdevclass_driver_s * classdev)2856 void 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 
usbdev_uvc_initialize_sub(struct composite_devdesc_s * dev,int ifnobase,int minor)2877 void 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 
usbdev_uvc_initialize(struct module * mod,int n,void * arg)2901 int 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