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