1beacf11bSopenharmony_ci/* ---------------------------------------------------------------------------- 2beacf11bSopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. 3beacf11bSopenharmony_ci * Description: LiteOS USB Driver Composite Devices 4beacf11bSopenharmony_ci * Author: huangjieliang 5beacf11bSopenharmony_ci * Create: 2017-04-21 6beacf11bSopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 7beacf11bSopenharmony_ci * are permitted provided that the following conditions are met: 8beacf11bSopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 9beacf11bSopenharmony_ci * conditions and the following disclaimer. 10beacf11bSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11beacf11bSopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 12beacf11bSopenharmony_ci * provided with the distribution. 13beacf11bSopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 14beacf11bSopenharmony_ci * to endorse or promote products derived from this software without specific prior written 15beacf11bSopenharmony_ci * permission. 16beacf11bSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17beacf11bSopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18beacf11bSopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19beacf11bSopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 20beacf11bSopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21beacf11bSopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22beacf11bSopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23beacf11bSopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24beacf11bSopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25beacf11bSopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26beacf11bSopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27beacf11bSopenharmony_ci * --------------------------------------------------------------------------- */ 28beacf11bSopenharmony_ci/* ---------------------------------------------------------------------------- 29beacf11bSopenharmony_ci * Notice of Export Control Law 30beacf11bSopenharmony_ci * =============================================== 31beacf11bSopenharmony_ci * Huawei LiteOS may be subject to applicable export control laws and regulations, which might 32beacf11bSopenharmony_ci * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. 33beacf11bSopenharmony_ci * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such 34beacf11bSopenharmony_ci * applicable export control laws and regulations. 35beacf11bSopenharmony_ci * --------------------------------------------------------------------------- */ 36beacf11bSopenharmony_ci 37beacf11bSopenharmony_ci#include "gadget/composite.h" 38beacf11bSopenharmony_ci#include "gadget/cdcacm.h" 39beacf11bSopenharmony_ci#include "gadget/rndis.h" 40beacf11bSopenharmony_ci 41beacf11bSopenharmony_ci#ifdef __cplusplus 42beacf11bSopenharmony_ci#if __cplusplus 43beacf11bSopenharmony_ciextern "C" { 44beacf11bSopenharmony_ci#endif /* __cplusplus */ 45beacf11bSopenharmony_ci#endif /* __cplusplus */ 46beacf11bSopenharmony_ci 47beacf11bSopenharmony_ci#define FMULTI_DEBUG 48beacf11bSopenharmony_ci#ifdef FMULTI_DEBUG 49beacf11bSopenharmony_ci#define FMSLOG(x...) dprintf(x) 50beacf11bSopenharmony_ci#else 51beacf11bSopenharmony_ci#define FMSLOG(x...) do {} while(0) 52beacf11bSopenharmony_ci#endif 53beacf11bSopenharmony_ci 54beacf11bSopenharmony_ci#define USB_ETHER_FIRST_INTERFACE_NUM 0 55beacf11bSopenharmony_ci#define USB_SERIAL_FIRST_INTERFACE_NUM 2 56beacf11bSopenharmony_ci 57beacf11bSopenharmony_ciint usbdev_multi_initialize(struct module *mod, int n, void *arg); 58beacf11bSopenharmony_ci 59beacf11bSopenharmony_ci/* device driver structure definition */ 60beacf11bSopenharmony_ci 61beacf11bSopenharmony_cistatic driver_t g_fmulti_driver_t = 62beacf11bSopenharmony_ci{ 63beacf11bSopenharmony_ci .name = "fmulti", 64beacf11bSopenharmony_ci .methods = NULL, 65beacf11bSopenharmony_ci .size = 0 66beacf11bSopenharmony_ci}; 67beacf11bSopenharmony_ci 68beacf11bSopenharmony_ci/* private device class information */ 69beacf11bSopenharmony_ci 70beacf11bSopenharmony_cistatic devclass_t g_fmulti_devclass; 71beacf11bSopenharmony_ciDRIVER_MODULE(fmulti, simple, g_fmulti_driver_t, g_fmulti_devclass, usbdev_multi_initialize, 0); 72beacf11bSopenharmony_ci 73beacf11bSopenharmony_ci#define MULTI_VENDOR_ID 0x1d6b 74beacf11bSopenharmony_ci#define MULTI_PRODUCT_ID 0x0104 75beacf11bSopenharmony_ci 76beacf11bSopenharmony_ci/* This struct is aimed at enumerating index for composite device strings. */ 77beacf11bSopenharmony_ci 78beacf11bSopenharmony_cienum 79beacf11bSopenharmony_ci{ 80beacf11bSopenharmony_ci /* Rndis Device */ 81beacf11bSopenharmony_ci 82beacf11bSopenharmony_ci MULTI_RNDIS_CTRL_IDX = 6, 83beacf11bSopenharmony_ci MULTI_RNDIS_DATA_IDX, 84beacf11bSopenharmony_ci MULTI_RNDIS_IAD_IDX, 85beacf11bSopenharmony_ci 86beacf11bSopenharmony_ci /* ACM Device */ 87beacf11bSopenharmony_ci 88beacf11bSopenharmony_ci MULTI_ACM_CTRL_IDX = 0xa, 89beacf11bSopenharmony_ci MULTI_ACM_DATA_IDX, 90beacf11bSopenharmony_ci MULTI_ACM_IAD_IDX 91beacf11bSopenharmony_ci}; 92beacf11bSopenharmony_ci 93beacf11bSopenharmony_ci/* Define and initialize multi device descriptor. */ 94beacf11bSopenharmony_ci 95beacf11bSopenharmony_cistatic const struct usb_device_descriptor g_fmulti_device_desc = 96beacf11bSopenharmony_ci{ 97beacf11bSopenharmony_ci .bLength = sizeof(struct usb_device_descriptor), 98beacf11bSopenharmony_ci .bDescriptorType = UDESC_DEVICE, 99beacf11bSopenharmony_ci HSETW(.bcdUSB, UD_BCD_USB), /* USB version */ 100beacf11bSopenharmony_ci .bDeviceClass = UDCLASS_MISC, 101beacf11bSopenharmony_ci .bDeviceSubClass = 2, 102beacf11bSopenharmony_ci .bDeviceProtocol = 1, 103beacf11bSopenharmony_ci .bMaxPacketSize = UD_USB_MPS, 104beacf11bSopenharmony_ci HSETW(.idVendor, MULTI_VENDOR_ID), /* vendor */ 105beacf11bSopenharmony_ci HSETW(.idProduct, MULTI_PRODUCT_ID), /* product */ 106beacf11bSopenharmony_ci HSETW(.bcdDevice, 0x0318), /* device version */ 107beacf11bSopenharmony_ci .iManufacturer = 1, 108beacf11bSopenharmony_ci .iProduct = 2, 109beacf11bSopenharmony_ci .iSerialNumber = 0, 110beacf11bSopenharmony_ci .bNumConfigurations = 1, 111beacf11bSopenharmony_ci}; 112beacf11bSopenharmony_ci 113beacf11bSopenharmony_ci#define MULTI_STRING_ID_LEN 4 114beacf11bSopenharmony_cistatic const char g_multi_string_id[MULTI_STRING_ID_LEN] = 115beacf11bSopenharmony_ci{ 116beacf11bSopenharmony_ci MULTI_STRING_ID_LEN, 117beacf11bSopenharmony_ci UDESC_STRING, 118beacf11bSopenharmony_ci 0x09, 119beacf11bSopenharmony_ci 0x04, 120beacf11bSopenharmony_ci}; 121beacf11bSopenharmony_ci 122beacf11bSopenharmony_ci#define MULTI_VERSION_STRING_LEN 62 123beacf11bSopenharmony_cistatic const char g_multi_version_string[MULTI_VERSION_STRING_LEN] = 124beacf11bSopenharmony_ci{ 125beacf11bSopenharmony_ci MULTI_VERSION_STRING_LEN, UDESC_STRING, 126beacf11bSopenharmony_ci 'M', 0, 'u', 0, 'l', 0, 't', 0, 'i', 0, 'f', 0, 'u', 0, 'n', 0, 'c', 0, 't', 0, 127beacf11bSopenharmony_ci 'i', 0, 'o', 0, 'n', 0, ' ', 0, 'C', 0, 'o', 0, 'm', 0, 'p', 0, 'o', 0, 's', 0, 128beacf11bSopenharmony_ci 'i', 0, 't', 0, 'e', 0, ' ', 0, 'G', 0, 'a', 0, 'd', 0, 'g', 0, 'e', 0, 't', 0 129beacf11bSopenharmony_ci}; 130beacf11bSopenharmony_ci 131beacf11bSopenharmony_ci#define MULTI_STRING_4_LEN 38 132beacf11bSopenharmony_cistatic const char g_dt_string_4[MULTI_STRING_4_LEN] = 133beacf11bSopenharmony_ci{ 134beacf11bSopenharmony_ci MULTI_STRING_4_LEN, 135beacf11bSopenharmony_ci UDESC_STRING, 136beacf11bSopenharmony_ci 0x47, 0, 0x61, 0, 0x64, 0, 0x67, 0, 0x65, 0, 0x74, 0, 0x20, 0, 137beacf11bSopenharmony_ci 0x53, 0, 0x65, 0, 0x72, 0, 0x69, 0, 0x61, 0, 0x6c, 0, 0x20, 0, 138beacf11bSopenharmony_ci 0x76, 0, 0x32, 0, 0x2e, 0, 0x34, 0 139beacf11bSopenharmony_ci}; 140beacf11bSopenharmony_ci 141beacf11bSopenharmony_ci#define DT_STRING_6_LEN 26 142beacf11bSopenharmony_cistatic const char g_dt_string_6[DT_STRING_6_LEN] = 143beacf11bSopenharmony_ci{ 144beacf11bSopenharmony_ci DT_STRING_6_LEN, 145beacf11bSopenharmony_ci UDESC_STRING, 146beacf11bSopenharmony_ci 0x43, 0, 0x44, 0, 0x43, 0, 0x20, 0, 0x41, 0, 147beacf11bSopenharmony_ci 0x43, 0, 0x4d, 0, 0x20, 0, 0x44, 0, 0x61, 0, 0x74, 0, 0x61, 0 148beacf11bSopenharmony_ci}; 149beacf11bSopenharmony_ci 150beacf11bSopenharmony_ci#define DT_STRING_7_LEN 22 151beacf11bSopenharmony_cistatic const char g_dt_string_7[DT_STRING_7_LEN] = 152beacf11bSopenharmony_ci{ 153beacf11bSopenharmony_ci DT_STRING_7_LEN, 154beacf11bSopenharmony_ci UDESC_STRING, 155beacf11bSopenharmony_ci 0x43, 0, 0x44, 0, 0x43, 0, 0x20, 0, 0x53, 0, 0x65, 0, 156beacf11bSopenharmony_ci 0x72, 0, 0x69, 0, 0x61, 0, 0x6c, 0 157beacf11bSopenharmony_ci}; 158beacf11bSopenharmony_ci 159beacf11bSopenharmony_ci#define MULTI_RNDIS_STRING_LEN 12 160beacf11bSopenharmony_cistatic const char g_multi_rndis_string[MULTI_RNDIS_STRING_LEN] = 161beacf11bSopenharmony_ci{ 162beacf11bSopenharmony_ci MULTI_RNDIS_STRING_LEN, 163beacf11bSopenharmony_ci UDESC_STRING, 164beacf11bSopenharmony_ci 'R',0,'N',0,'D',0,'I',0,'S',0 165beacf11bSopenharmony_ci}; 166beacf11bSopenharmony_ci 167beacf11bSopenharmony_ci#define MULTI_SERIAL_STRING_LEN 22 168beacf11bSopenharmony_cistatic const char g_multi_serial_string[MULTI_SERIAL_STRING_LEN] = 169beacf11bSopenharmony_ci{ 170beacf11bSopenharmony_ci MULTI_SERIAL_STRING_LEN, 171beacf11bSopenharmony_ci UDESC_STRING, 172beacf11bSopenharmony_ci 'C',0,'D',0,'C',0,' ',0,'S',0,'e',0,'i',0,'a',0,'l',0 173beacf11bSopenharmony_ci}; 174beacf11bSopenharmony_ci 175beacf11bSopenharmony_ci#define FMULTI_DSTR_IDX 8 176beacf11bSopenharmony_cistruct usbd_string g_fmulti_device_strings[FMULTI_DSTR_IDX] = 177beacf11bSopenharmony_ci{ 178beacf11bSopenharmony_ci { 0, g_multi_string_id }, 179beacf11bSopenharmony_ci { 2, g_multi_version_string }, 180beacf11bSopenharmony_ci { 4, g_dt_string_4 }, 181beacf11bSopenharmony_ci { 6, g_dt_string_6 }, 182beacf11bSopenharmony_ci { 7, g_dt_string_7 }, 183beacf11bSopenharmony_ci { MULTI_RNDIS_IAD_IDX, g_multi_rndis_string }, 184beacf11bSopenharmony_ci { MULTI_ACM_IAD_IDX, g_multi_serial_string }, 185beacf11bSopenharmony_ci USBD_DEVICE_STRINGS_END 186beacf11bSopenharmony_ci}; 187beacf11bSopenharmony_ci 188beacf11bSopenharmony_civoid multi_mkdevdesc(uint8_t *buf) 189beacf11bSopenharmony_ci{ 190beacf11bSopenharmony_ci errno_t ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, &g_fmulti_device_desc, sizeof(g_fmulti_device_desc)); 191beacf11bSopenharmony_ci if (ret != EOK) 192beacf11bSopenharmony_ci { 193beacf11bSopenharmony_ci usb_err("memcpy_s fail!, ret:%d\n", ret); 194beacf11bSopenharmony_ci return; 195beacf11bSopenharmony_ci } 196beacf11bSopenharmony_ci} 197beacf11bSopenharmony_ci 198beacf11bSopenharmony_ciint multi_mkstrdesc(uint8_t id, uint8_t *buf) 199beacf11bSopenharmony_ci{ 200beacf11bSopenharmony_ci errno_t ret; 201beacf11bSopenharmony_ci const char *str; 202beacf11bSopenharmony_ci int i; 203beacf11bSopenharmony_ci 204beacf11bSopenharmony_ci for (i = 0; g_fmulti_device_strings[i].s != NULL; i++) 205beacf11bSopenharmony_ci { 206beacf11bSopenharmony_ci str = g_fmulti_device_strings[i].s; 207beacf11bSopenharmony_ci if (g_fmulti_device_strings[i].id == id) 208beacf11bSopenharmony_ci { 209beacf11bSopenharmony_ci ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, str, str[0]); 210beacf11bSopenharmony_ci if (ret != EOK) 211beacf11bSopenharmony_ci { 212beacf11bSopenharmony_ci usb_err("memcpy_s failed, ret = %d\n", ret); 213beacf11bSopenharmony_ci return -1; 214beacf11bSopenharmony_ci } 215beacf11bSopenharmony_ci return str[0]; 216beacf11bSopenharmony_ci } 217beacf11bSopenharmony_ci } 218beacf11bSopenharmony_ci 219beacf11bSopenharmony_ci usb_err("Can not find the id = %u of string\n", id); 220beacf11bSopenharmony_ci return -1; 221beacf11bSopenharmony_ci} 222beacf11bSopenharmony_ci 223beacf11bSopenharmony_civoid multi_get_composite_devdesc(struct composite_devdesc_s *dev) 224beacf11bSopenharmony_ci{ 225beacf11bSopenharmony_ci dev->mkdevdesc = multi_mkdevdesc; 226beacf11bSopenharmony_ci dev->mkstrdesc = multi_mkstrdesc; 227beacf11bSopenharmony_ci} 228beacf11bSopenharmony_ci 229beacf11bSopenharmony_ciint usbdev_multi_initialize (struct module *mod, int n, void *arg) 230beacf11bSopenharmony_ci{ 231beacf11bSopenharmony_ci struct composite_softc *com_s = (struct composite_softc *)arg; 232beacf11bSopenharmony_ci struct composite_devdesc_s dev[USB_COMPOSITE_DEV_NUM]; 233beacf11bSopenharmony_ci int ret; 234beacf11bSopenharmony_ci 235beacf11bSopenharmony_ci (void)mod; 236beacf11bSopenharmony_ci (void)n; 237beacf11bSopenharmony_ci if (com_s == NULL) 238beacf11bSopenharmony_ci { 239beacf11bSopenharmony_ci PRINTK("com_s is NULL!\n"); 240beacf11bSopenharmony_ci return -1; 241beacf11bSopenharmony_ci } 242beacf11bSopenharmony_ci 243beacf11bSopenharmony_ci usbdev_rndis_initialize_sub(&dev[0], USB_ETHER_FIRST_INTERFACE_NUM, DEV_ETHERNET); 244beacf11bSopenharmony_ci multi_get_composite_devdesc(&dev[0]); 245beacf11bSopenharmony_ci usbdev_cdcacm_initialize_sub(&dev[1], USB_SERIAL_FIRST_INTERFACE_NUM, DEV_SERIAL); 246beacf11bSopenharmony_ci multi_get_composite_devdesc(&dev[1]); 247beacf11bSopenharmony_ci 248beacf11bSopenharmony_ci ret = composite_initialize(com_s, USB_COMPOSITE_DEV_NUM, dev); 249beacf11bSopenharmony_ci if (ret < 0) 250beacf11bSopenharmony_ci { 251beacf11bSopenharmony_ci PRINTK(" ** multi device initialized failed! **\n"); 252beacf11bSopenharmony_ci return -1; 253beacf11bSopenharmony_ci } 254beacf11bSopenharmony_ci 255beacf11bSopenharmony_ci PRINTK(" ** multi device initialized successfully! **\n"); 256beacf11bSopenharmony_ci return 0; 257beacf11bSopenharmony_ci} 258beacf11bSopenharmony_ci 259beacf11bSopenharmony_ci#ifdef __cplusplus 260beacf11bSopenharmony_ci#if __cplusplus 261beacf11bSopenharmony_ci} 262beacf11bSopenharmony_ci#endif /* __cplusplus */ 263beacf11bSopenharmony_ci#endif /* __cplusplus */