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