1 /* ----------------------------------------------------------------------------
2 * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
3 * Description: LiteOS USB Driver Camera
4 * Author: huangjieliang
5 * Create: 2018-05-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 "gadget/f_uvc.h"
38 #include "gadget/hicamera_control.h"
39 #include "gadget/f_uac.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 int usbdev_camera_initialize(struct module *mod, int n, void *arg);
52
53 static const driver_t g_fcamera_driver =
54 {
55 .name = "fcamera",
56 .methods = NULL,
57 .size = 0
58 };
59
60 /* private device class information */
61
62 static devclass_t g_fcamera_devclass;
63 DRIVER_MODULE(fcamera, simple, g_fcamera_driver, g_fcamera_devclass, usbdev_camera_initialize, 0);
64
65 #define CAMERA_STR_LANG 0
66 static const char g_fcamera_str_lang[] =
67 {
68 4, UDESC_STRING,
69 0x09, 0x04
70 };
71
72 #define CAMERA_STR_IDX_MAN 1
73 static const char g_fcamera_str_manufacturer[] =
74 {
75 14, UDESC_STRING,
76 'H', 0, 'U', 0, 'A', 0, 'W', 0, 'E', 0, 'I', 0
77 };
78
79 #define CAMERA_STR_IDX_PRODUCT 2
80 static const char g_fcamera_str_product[] =
81 {
82 14, UDESC_STRING,
83 'L', 0, 'i', 0, 't', 0, 'e', 0, 'O', 0, 'S', 0
84 };
85
86 #define CAMERA_STR_IDX_CONFIG 5
87 static const char g_fcamera_str_config[] =
88 {
89 22, UDESC_STRING,
90 'U', 0, 'V', 0, 'C', 0, ' ', 0, 'C', 0, 'A', 0, 'M', 0,
91 'E', 0, 'R', 0, 'A', 0
92 };
93
94 #define CAMERA_STR_IDX_VIDEO 4
95 static const char g_fcamera_str_video[] =
96 {
97 12, UDESC_STRING,
98 'V', 0, 'i', 0, 'd', 0, 'e', 0, 'o', 0
99 };
100
101 #define CAMERA_STR_IDX_INTERFACE 6
102 static const char g_fcamera_str_interface[] =
103 {
104 32, UDESC_STRING,
105 'V', 0, 'i', 0, 'd', 0, 'e', 0, 'o', 0, ' ', 0, 'S', 0, 't', 0, 'r', 0,
106 'e', 0, 'a', 0, 'm', 0, 'i', 0, 'n', 0, 'g', 0
107 };
108
109 #define CAMERA_IN_TERMINAL 8
110 static const char g_fcamera_input_terminal[] =
111 {
112 46, UDESC_STRING,
113 'C', 0, 'a', 0, 'p', 0, 't', 0, 'u', 0, 'r', 0, 'e', 0, ' ', 0,
114 'I', 0, 'n', 0, 'p', 0, 'u', 0, 't', 0, ' ', 0, 't', 0, 'e', 0,
115 'r', 0, 'm', 0, 'i', 0, 'n', 0, 'a', 0, 'l', 0
116 };
117
118 #define CAMERA_OUT_TERMINAL 11
119 static const char g_fcamera_output_terminal[] =
120 {
121 48, UDESC_STRING,
122 'C', 0, 'a', 0, 'p', 0, 't', 0, 'u', 0, 'r', 0, 'e', 0, ' ', 0, 'O', 0,
123 'u', 0, 't', 0, 'p', 0, 'u', 0, 't', 0, ' ', 0, 't', 0, 'e', 0, 'r', 0,
124 'm', 0, 'i', 0, 'n', 0, 'a', 0, 'l', 0
125 };
126
127 static const struct usb_device_descriptor g_fcamera_device_desc =
128 {
129 .bLength = sizeof(struct usb_device_descriptor),
130 .bDescriptorType = UDESC_DEVICE, /* Constant for device descriptor */
131 HSETW(.bcdUSB, UD_BCD_USB), /* USB version required: 2.0 */
132 .bDeviceClass = UICLASS_IAD, /* Miscellaneous Device Class */
133 .bDeviceSubClass = 0x02, /* Common Class */
134 .bDeviceProtocol = 0x01, /* Interface Association Descriptor */
135 .bMaxPacketSize = UD_USB_MPS, /* Control Endpoint packet size */
136 HSETW(.idVendor, 0x1d6b), /* Vendor ID of Huawei Technologies */
137 HSETW(.idProduct, 0x0102), /* Product ID, webcamera? */
138 HSETW(.bcdDevice, 0x0318), /* Device release code */
139 .iManufacturer = CAMERA_STR_IDX_MAN, /* Manufacturer name, string index */
140 .iProduct = CAMERA_STR_IDX_PRODUCT, /* Product name, string index */
141 .iSerialNumber = 0, /* Not Used */
142 .bNumConfigurations = 1 /* One Configuration */
143 };
144
145 struct usbd_string g_fcamera_device_strings[9] =
146 {
147 { CAMERA_STR_LANG, g_fcamera_str_lang },
148 { CAMERA_STR_IDX_MAN, g_fcamera_str_manufacturer },
149 { CAMERA_STR_IDX_PRODUCT, g_fcamera_str_product },
150 { CAMERA_STR_IDX_VIDEO, g_fcamera_str_video },
151 { CAMERA_STR_IDX_CONFIG, g_fcamera_str_config },
152 { CAMERA_STR_IDX_INTERFACE, g_fcamera_str_interface },
153 { CAMERA_IN_TERMINAL, g_fcamera_input_terminal },
154 { CAMERA_OUT_TERMINAL, g_fcamera_output_terminal },
155 USBD_DEVICE_STRINGS_END
156 };
157
camera_mkdevdesc(uint8_t * buf)158 void camera_mkdevdesc(uint8_t *buf)
159 {
160 errno_t ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, &g_fcamera_device_desc, sizeof(g_fcamera_device_desc));
161 if (ret != EOK)
162 {
163 usb_err("memcpy_s fail!, ret:%d\n", ret);
164 return;
165 }
166 }
167
camera_mkstrdesc(uint8_t id,uint8_t * buf)168 int camera_mkstrdesc(uint8_t id, uint8_t *buf)
169 {
170 errno_t ret;
171 const char *str;
172 int i;
173
174 for (i = 0; g_fcamera_device_strings[i].s != NULL; i++)
175 {
176 str = g_fcamera_device_strings[i].s;
177 if (g_fcamera_device_strings[i].id == id)
178 {
179 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, str, str[0]);
180 if (ret != EOK)
181 {
182 usb_err("memcpy_s failed, ret = %d\n", ret);
183 return -1;
184 }
185 return str[0];
186 }
187 }
188
189 usb_err("Can not find the id = %u of string\n", id);
190 return -1;
191 }
192
camera_get_composite_devdesc(struct composite_devdesc_s * dev)193 void camera_get_composite_devdesc(struct composite_devdesc_s *dev)
194 {
195 dev->mkdevdesc = camera_mkdevdesc;
196 dev->mkstrdesc = camera_mkstrdesc;
197 }
198
199 #define USB_UVC_FIRST_INTERFACE_NUM 0
200 #define USB_UAC_FIRST_INTERFACE_NUM 2
usbdev_camera_initialize(struct module * mod,int n,void * arg)201 int usbdev_camera_initialize(struct module *mod, int n, void *arg)
202 {
203 struct composite_softc *com_s = (struct composite_softc *)arg;
204 struct composite_devdesc_s dev[USB_COMPOSITE_DEV_NUM];
205 int ret;
206
207 (void)mod;
208 (void)n;
209 if (com_s == NULL)
210 {
211 return -1;
212 }
213
214 usbdev_uvc_initialize_sub(&dev[0], USB_UVC_FIRST_INTERFACE_NUM, DEV_UVC);
215 camera_get_composite_devdesc(&dev[0]);
216 usbdev_uac_initialize_sub(&dev[1], USB_UAC_FIRST_INTERFACE_NUM, DEV_UAC);
217 camera_get_composite_devdesc(&dev[1]);
218
219 ret = composite_initialize(com_s, USB_COMPOSITE_DEV_NUM, dev);
220 if (ret < 0)
221 {
222 return -1;
223 }
224
225 PRINTK(" ** camera device initialized successfully! **\n");
226 return 0;
227 }
228
229 #ifdef __cplusplus
230 #if __cplusplus
231 }
232 #endif /* __cplusplus */
233 #endif /* __cplusplus */