1f9f848faSopenharmony_ci/* 2f9f848faSopenharmony_ci * Copyright (c) 2013-2023, Huawei Technologies Co., Ltd. All rights reserved. 3f9f848faSopenharmony_ci * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. 4f9f848faSopenharmony_ci * 5f9f848faSopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 6f9f848faSopenharmony_ci * are permitted provided that the following conditions are met: 7f9f848faSopenharmony_ci * 8f9f848faSopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 9f9f848faSopenharmony_ci * conditions and the following disclaimer. 10f9f848faSopenharmony_ci * 11f9f848faSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 12f9f848faSopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 13f9f848faSopenharmony_ci * provided with the distribution. 14f9f848faSopenharmony_ci * 15f9f848faSopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 16f9f848faSopenharmony_ci * to endorse or promote products derived from this software without specific prior written 17f9f848faSopenharmony_ci * permission. 18f9f848faSopenharmony_ci * 19f9f848faSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20f9f848faSopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21f9f848faSopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22f9f848faSopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23f9f848faSopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24f9f848faSopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25f9f848faSopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26f9f848faSopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27f9f848faSopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28f9f848faSopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29f9f848faSopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30f9f848faSopenharmony_ci */ 31f9f848faSopenharmony_ci 32f9f848faSopenharmony_ci#include "usb_init.h" 33f9f848faSopenharmony_ci#include "usb_api_pri.h" 34f9f848faSopenharmony_ci#include "devmgr_service.h" 35f9f848faSopenharmony_ci#include "devsvc_manager_clnt.h" 36f9f848faSopenharmony_ci#include "hdf_device_object.h" 37f9f848faSopenharmony_ci 38f9f848faSopenharmony_citypedef struct usb_info { 39f9f848faSopenharmony_ci bool b_init; 40f9f848faSopenharmony_ci controller_type ctype; 41f9f848faSopenharmony_ci device_type dtype; 42f9f848faSopenharmony_ci} usb_info_t; 43f9f848faSopenharmony_ci 44f9f848faSopenharmony_cistatic char *dev_name = NULL; 45f9f848faSopenharmony_cistatic bool uvc_enable = false; 46f9f848faSopenharmony_cistatic usb_info_t usb_info = { false, (controller_type)0xFFFF, (device_type)0xFFFF }; 47f9f848faSopenharmony_cistatic struct mtx usb_mtx = PTHREAD_MUTEX_INITIALIZER; 48f9f848faSopenharmony_ci 49f9f848faSopenharmony_cistatic struct driver_module_data* usb_driver_mode_list[] = { 50f9f848faSopenharmony_ci#ifdef LOSCFG_DRIVERS_USB_HOST_EHCI 51f9f848faSopenharmony_ci /* xxx controller modules */ 52f9f848faSopenharmony_ci /* usb generial controller modules */ 53f9f848faSopenharmony_ci &usbus_ehci_driver_mod, 54f9f848faSopenharmony_ci#endif 55f9f848faSopenharmony_ci 56f9f848faSopenharmony_ci#if defined (LOSCFG_DRIVERS_USB_HOST_XHCI) 57f9f848faSopenharmony_ci &usbus_xhci_driver_mod, 58f9f848faSopenharmony_ci#endif 59f9f848faSopenharmony_ci 60f9f848faSopenharmony_ci#ifdef LOSCFG_DRIVERS_USB_HOST_DRIVER 61f9f848faSopenharmony_ci /* xxx driver modules */ 62f9f848faSopenharmony_ci &uhub_uhub_driver_mod, 63f9f848faSopenharmony_ci &uhub_usbus_driver_mod, 64f9f848faSopenharmony_ci#endif 65f9f848faSopenharmony_ci 66f9f848faSopenharmony_ci#ifdef LOSCFG_DRIVERS_USB_4G_MODEM 67f9f848faSopenharmony_ci#ifndef LOSCFG_DRIVERS_HDF_USB_DDK_HOST 68f9f848faSopenharmony_ci &cdce_uhub_driver_mod, 69f9f848faSopenharmony_ci#endif 70f9f848faSopenharmony_ci //&bsd_u3g_uhub_driver_mod, 71f9f848faSopenharmony_ci#endif 72f9f848faSopenharmony_ci 73f9f848faSopenharmony_ci#if defined (LOSCFG_DRIVERS_USB_SERIAL) || defined (LOSCFG_DRIVERS_USB_4G_MODEM) 74f9f848faSopenharmony_ci &u3g_uhub_driver_mod, 75f9f848faSopenharmony_ci#endif 76f9f848faSopenharmony_ci 77f9f848faSopenharmony_ci#ifdef LOSCFG_DRIVERS_USB_MASS_STORAGE 78f9f848faSopenharmony_ci &umass_uhub_driver_mod, 79f9f848faSopenharmony_ci#endif 80f9f848faSopenharmony_ci 81f9f848faSopenharmony_ci#ifdef LOSCFG_DRIVERS_USB_ETHERNET 82f9f848faSopenharmony_ci &axe_uhub_driver_mod, 83f9f848faSopenharmony_ci &axge_uhub_driver_mod, 84f9f848faSopenharmony_ci#endif 85f9f848faSopenharmony_ci 86f9f848faSopenharmony_ci#ifdef LOSCFG_DRIVERS_USB_RNDIS_HOST 87f9f848faSopenharmony_ci &urndis_uhub_driver_mod, 88f9f848faSopenharmony_ci#endif 89f9f848faSopenharmony_ci 90f9f848faSopenharmony_ci#ifdef LOSCFG_DRIVERS_USB_WIRELESS 91f9f848faSopenharmony_ci &usb_linux_uhub_driver_mod, 92f9f848faSopenharmony_ci#endif 93f9f848faSopenharmony_ci 94f9f848faSopenharmony_ci#if defined (LOSCFG_DRIVERS_USB_HID_CLASS) && defined (LOSCFG_DRIVERS_HDF_INPUT) 95f9f848faSopenharmony_ci &uhid_uhub_driver_mod, 96f9f848faSopenharmony_ci#endif 97f9f848faSopenharmony_ci 98f9f848faSopenharmony_ci#ifdef LOSCFG_DRIVERS_HDF_USB_DDK_DEVICE 99f9f848faSopenharmony_ci &composite_hiudc3_driver_mod, 100f9f848faSopenharmony_ci#endif 101f9f848faSopenharmony_ci NULL 102f9f848faSopenharmony_ci}; 103f9f848faSopenharmony_ci 104f9f848faSopenharmony_ciextern device_t 105f9f848faSopenharmony_cibus_get_device(device_t dev, const char *name); 106f9f848faSopenharmony_ci 107f9f848faSopenharmony_civoid 108f9f848faSopenharmony_ciusbinfo_clean(void) 109f9f848faSopenharmony_ci{ 110f9f848faSopenharmony_ci dev_name = NULL; 111f9f848faSopenharmony_ci uvc_enable = false; 112f9f848faSopenharmony_ci usb_info.ctype = (controller_type)0xFFFF; 113f9f848faSopenharmony_ci usb_info.dtype = (device_type)0xFFFF; 114f9f848faSopenharmony_ci usb_info.b_init = false; 115f9f848faSopenharmony_ci return; 116f9f848faSopenharmony_ci} 117f9f848faSopenharmony_ci 118f9f848faSopenharmony_cichar * 119f9f848faSopenharmony_cidev_name_get(void) 120f9f848faSopenharmony_ci{ 121f9f848faSopenharmony_ci return (dev_name); 122f9f848faSopenharmony_ci} 123f9f848faSopenharmony_ci 124f9f848faSopenharmony_cistatic uint32_t 125f9f848faSopenharmony_ciusb_loadonce(void) 126f9f848faSopenharmony_ci{ 127f9f848faSopenharmony_ci struct driver_module_data *data; 128f9f848faSopenharmony_ci uint32_t i; 129f9f848faSopenharmony_ci 130f9f848faSopenharmony_ci dprintf("usb %s\n",fetach_usbversion()); 131f9f848faSopenharmony_ci 132f9f848faSopenharmony_ci#ifdef LOSCFG_DRIVERS_USB 133f9f848faSopenharmony_ci /* init quirk */ 134f9f848faSopenharmony_ci usb_quirk_init(NULL); 135f9f848faSopenharmony_ci 136f9f848faSopenharmony_ci for (i = 0; (data = usb_driver_mode_list[i]) && (data != NULL); i++) { 137f9f848faSopenharmony_ci driver_module_handler(NULL, MOD_LOAD, data); 138f9f848faSopenharmony_ci } 139f9f848faSopenharmony_ci#endif 140f9f848faSopenharmony_ci 141f9f848faSopenharmony_ci#ifdef LOSCFG_USB_DEBUG 142f9f848faSopenharmony_ci usb_debug_module_regsiter(); 143f9f848faSopenharmony_ci#endif 144f9f848faSopenharmony_ci 145f9f848faSopenharmony_ci return (0); 146f9f848faSopenharmony_ci} 147f9f848faSopenharmony_ci 148f9f848faSopenharmony_cistatic void 149f9f848faSopenharmony_ciusb_unloadonce(void) 150f9f848faSopenharmony_ci{ 151f9f848faSopenharmony_ci uint32_t i; 152f9f848faSopenharmony_ci 153f9f848faSopenharmony_ci#ifdef LOSCFG_USB_DEBUG 154f9f848faSopenharmony_ci usb_debug_module_unregsiter(); 155f9f848faSopenharmony_ci#endif 156f9f848faSopenharmony_ci 157f9f848faSopenharmony_ci#ifdef LOSCFG_DRIVERS_USB 158f9f848faSopenharmony_ci for (i = 0; usb_driver_mode_list[i] != NULL; i++) { 159f9f848faSopenharmony_ci driver_module_handler(NULL, MOD_UNLOAD, usb_driver_mode_list[i]); 160f9f848faSopenharmony_ci } 161f9f848faSopenharmony_ci#endif 162f9f848faSopenharmony_ci 163f9f848faSopenharmony_ci return; 164f9f848faSopenharmony_ci} 165f9f848faSopenharmony_ci#ifdef LOSCFG_DRIVERS_HDF_USB_DDK_DEVICE 166f9f848faSopenharmony_cistatic struct HdfDeviceObject *HdfLoadUsbDevice(const char *serv_name) 167f9f848faSopenharmony_ci{ 168f9f848faSopenharmony_ci struct IDevmgrService *devmgr = DevmgrServiceGetInstance(); 169f9f848faSopenharmony_ci if(devmgr== NULL || devmgr->LoadDevice(devmgr, serv_name) != HDF_SUCCESS) { 170f9f848faSopenharmony_ci dprintf("failed to load %s", serv_name); 171f9f848faSopenharmony_ci return NULL; 172f9f848faSopenharmony_ci } 173f9f848faSopenharmony_ci 174f9f848faSopenharmony_ci return DevSvcManagerClntGetDeviceObject(serv_name); 175f9f848faSopenharmony_ci} 176f9f848faSopenharmony_ci 177f9f848faSopenharmony_cistruct HdfDeviceObject *HdfRegisterUsbDevice(struct HdfDeviceObject *usb_fn_master, 178f9f848faSopenharmony_ci const char *driver_name, const char *serv_name) 179f9f848faSopenharmony_ci{ 180f9f848faSopenharmony_ci struct HdfDeviceObject *dev = HdfDeviceObjectAlloc(usb_fn_master, driver_name); 181f9f848faSopenharmony_ci if (dev == NULL) { 182f9f848faSopenharmony_ci dprintf("%s: failed to alloc device object", __func__); 183f9f848faSopenharmony_ci return NULL; 184f9f848faSopenharmony_ci } 185f9f848faSopenharmony_ci 186f9f848faSopenharmony_ci if (HdfDeviceObjectRegister(dev) != HDF_SUCCESS) { 187f9f848faSopenharmony_ci dprintf("%s: failed to regitst device %s", __func__, serv_name); 188f9f848faSopenharmony_ci HdfDeviceObjectRelease(dev); 189f9f848faSopenharmony_ci return NULL; 190f9f848faSopenharmony_ci } 191f9f848faSopenharmony_ci 192f9f848faSopenharmony_ci if (HdfDeviceObjectPublishService(dev, serv_name, SERVICE_POLICY_PUBLIC, 0664) != HDF_SUCCESS) { 193f9f848faSopenharmony_ci dprintf("%s: failed to regitst device %s", __func__, serv_name); 194f9f848faSopenharmony_ci HdfDeviceObjectRelease(dev); 195f9f848faSopenharmony_ci return NULL; 196f9f848faSopenharmony_ci } 197f9f848faSopenharmony_ci 198f9f848faSopenharmony_ci return dev; 199f9f848faSopenharmony_ci} 200f9f848faSopenharmony_ci 201f9f848faSopenharmony_cistatic int composite_add(void) 202f9f848faSopenharmony_ci{ 203f9f848faSopenharmony_ci device_t udc; 204f9f848faSopenharmony_ci device_t composite; 205f9f848faSopenharmony_ci 206f9f848faSopenharmony_ci udc = bus_get_device(nexus, "hiudc3"); 207f9f848faSopenharmony_ci if (udc == NULL) { 208f9f848faSopenharmony_ci return -1; 209f9f848faSopenharmony_ci } 210f9f848faSopenharmony_ci 211f9f848faSopenharmony_ci composite = device_add_child(udc, "composite", -1); 212f9f848faSopenharmony_ci if (composite == NULL) { 213f9f848faSopenharmony_ci return -1; 214f9f848faSopenharmony_ci } 215f9f848faSopenharmony_ci 216f9f848faSopenharmony_ci if (device_probe_and_attach(composite)) { 217f9f848faSopenharmony_ci device_printf(composite, "WARNING: Probe and attach failed!\n"); 218f9f848faSopenharmony_ci return -1; 219f9f848faSopenharmony_ci } 220f9f848faSopenharmony_ci struct HdfDeviceObject *usb_fn_dev = HdfLoadUsbDevice("usbfn"); 221f9f848faSopenharmony_ci if (usb_fn_dev == NULL) { 222f9f848faSopenharmony_ci dprintf("%s register usbfn may failed\n", __func__); 223f9f848faSopenharmony_ci } 224f9f848faSopenharmony_ci 225f9f848faSopenharmony_ci struct HdfDeviceObject *devobj = HdfRegisterUsbDevice(usb_fn_dev, "usbfn_cdcacm", "usbfn_cdcacm"); 226f9f848faSopenharmony_ci if (devobj == NULL) { 227f9f848faSopenharmony_ci dprintf("%s register usbfn_cdcacm may failed\n", __func__); 228f9f848faSopenharmony_ci } 229f9f848faSopenharmony_ci 230f9f848faSopenharmony_ci devobj = HdfRegisterUsbDevice(usb_fn_dev, "usbfn_cdcecm", "usbfn_cdcecm"); 231f9f848faSopenharmony_ci if (devobj == NULL) { 232f9f848faSopenharmony_ci dprintf("%s register usbfn_cdcecm may failed\n", __func__); 233f9f848faSopenharmony_ci } 234f9f848faSopenharmony_ci dprintf("%s success\n", __func__); 235f9f848faSopenharmony_ci return 0; 236f9f848faSopenharmony_ci} 237f9f848faSopenharmony_ci#endif 238f9f848faSopenharmony_ci/* 239f9f848faSopenharmony_ci * step1: modify DRIVER_MODULE,register all driver module 240f9f848faSopenharmony_ci * step2: make ehci/ohci device (direct skip pci bus) 241f9f848faSopenharmony_ci * step3: insert ehci/ohci device into usb controller 242f9f848faSopenharmony_ci * step4: create ehci/ohci root hub device 243f9f848faSopenharmony_ci * step5: ehci/ohci transfer setup/start 244f9f848faSopenharmony_ci */ 245f9f848faSopenharmony_ciuint32_t 246f9f848faSopenharmony_ciusb_init(controller_type ctype, device_type dtype) 247f9f848faSopenharmony_ci{ 248f9f848faSopenharmony_ci uint32_t ret; 249f9f848faSopenharmony_ci static int usb_loaded = 0; 250f9f848faSopenharmony_ci 251f9f848faSopenharmony_ci dprintf("\n******** %s in **********\n", __FUNCTION__); 252f9f848faSopenharmony_ci 253f9f848faSopenharmony_ci mtx_lock(&usb_mtx); 254f9f848faSopenharmony_ci if (usb_info.b_init) { 255f9f848faSopenharmony_ci dprintf("\n duplicate usb_init %s, ctype:%d dtype:%d\n", __FUNCTION__, usb_info.ctype, usb_info.dtype); 256f9f848faSopenharmony_ci mtx_unlock(&usb_mtx); 257f9f848faSopenharmony_ci return (LOS_NOK); 258f9f848faSopenharmony_ci } 259f9f848faSopenharmony_ci 260f9f848faSopenharmony_ci if (usb_loaded == 0) { 261f9f848faSopenharmony_ci ret = usb_loadonce(); 262f9f848faSopenharmony_ci if (ret) { 263f9f848faSopenharmony_ci goto err; 264f9f848faSopenharmony_ci } 265f9f848faSopenharmony_ci usb_loaded = 1; 266f9f848faSopenharmony_ci } 267f9f848faSopenharmony_ci 268f9f848faSopenharmony_ci usb_dev_init(NULL); 269f9f848faSopenharmony_ci 270f9f848faSopenharmony_ci if (ctype == HOST) { 271f9f848faSopenharmony_ci#if defined (LOSCFG_DRIVERS_USB_HOST_XHCI) 272f9f848faSopenharmony_ci ret = hixhci_init(); 273f9f848faSopenharmony_ci#endif 274f9f848faSopenharmony_ci#ifdef LOSCFG_DRIVERS_USB_HOST_EHCI 275f9f848faSopenharmony_ci ret = hiehci_init(); 276f9f848faSopenharmony_ci#endif 277f9f848faSopenharmony_ci } else { 278f9f848faSopenharmony_ci#ifdef LOSCFG_DRIVERS_HDF_USB_DDK_DEVICE 279f9f848faSopenharmony_ci ret = usbd_load_driver(); 280f9f848faSopenharmony_ci if (ret != LOS_OK) { 281f9f848faSopenharmony_ci dprintf("usbd_load_driver failed ,ret = %d\n", ret); 282f9f848faSopenharmony_ci goto err; 283f9f848faSopenharmony_ci } 284f9f848faSopenharmony_ci ret = composite_add(); 285f9f848faSopenharmony_ci if (ret != LOS_OK) { 286f9f848faSopenharmony_ci dprintf("composite_add failed ,ret = %d\n", ret); 287f9f848faSopenharmony_ci goto err; 288f9f848faSopenharmony_ci } 289f9f848faSopenharmony_ci ret = usbd_enable_interrupt(); 290f9f848faSopenharmony_ci if (ret != LOS_OK) { 291f9f848faSopenharmony_ci dprintf("usbd_enable_interrupt failed, ret = %d\n", ret); 292f9f848faSopenharmony_ci goto err; 293f9f848faSopenharmony_ci } 294f9f848faSopenharmony_ci#endif 295f9f848faSopenharmony_ci } 296f9f848faSopenharmony_ci 297f9f848faSopenharmony_ci usb_info.b_init = true; 298f9f848faSopenharmony_ci usb_info.ctype = ctype; 299f9f848faSopenharmony_ci usb_info.dtype = dtype; 300f9f848faSopenharmony_ci 301f9f848faSopenharmony_ci mtx_unlock(&usb_mtx); 302f9f848faSopenharmony_ci dprintf("******** %s ok**********\n\n", __FUNCTION__); 303f9f848faSopenharmony_ci return (LOS_OK); 304f9f848faSopenharmony_ci 305f9f848faSopenharmony_cierr: 306f9f848faSopenharmony_ci mtx_unlock(&usb_mtx); 307f9f848faSopenharmony_ci if (!usb_loaded) { 308f9f848faSopenharmony_ci usb_unloadonce(); 309f9f848faSopenharmony_ci } 310f9f848faSopenharmony_ci dprintf("******** %s fail**********\n\n", __FUNCTION__); 311f9f848faSopenharmony_ci 312f9f848faSopenharmony_ci return (LOS_NOK); 313f9f848faSopenharmony_ci} 314f9f848faSopenharmony_ci 315f9f848faSopenharmony_ciuint32_t 316f9f848faSopenharmony_ciusb_deinit(void) 317f9f848faSopenharmony_ci{ 318f9f848faSopenharmony_ci uint32_t ret = LOS_OK; 319f9f848faSopenharmony_ci 320f9f848faSopenharmony_ci dprintf("******** %s in **********\n\n", __FUNCTION__); 321f9f848faSopenharmony_ci mtx_lock(&usb_mtx); 322f9f848faSopenharmony_ci 323f9f848faSopenharmony_ci if (usb_info.b_init == false) { 324f9f848faSopenharmony_ci dprintf("******** %s out, no init **********\n\n", __FUNCTION__); 325f9f848faSopenharmony_ci goto err; 326f9f848faSopenharmony_ci } 327f9f848faSopenharmony_ci 328f9f848faSopenharmony_ci if (usb_info.ctype == HOST) { 329f9f848faSopenharmony_ci dprintf("******** %s fail, host not support **********\n\n", __FUNCTION__); 330f9f848faSopenharmony_ci goto err; 331f9f848faSopenharmony_ci } 332f9f848faSopenharmony_ci 333f9f848faSopenharmony_ci if (ret) { 334f9f848faSopenharmony_ci dprintf("******** %s fail, %d **********\n\n", __FUNCTION__, ret); 335f9f848faSopenharmony_ci goto err; 336f9f848faSopenharmony_ci } 337f9f848faSopenharmony_ci 338f9f848faSopenharmony_ci usb_dev_uninit(NULL); 339f9f848faSopenharmony_ci 340f9f848faSopenharmony_ci dprintf(" ** %s uninit success **\n", dev_name_get()); 341f9f848faSopenharmony_ci usbinfo_clean(); 342f9f848faSopenharmony_ci mtx_unlock(&usb_mtx); 343f9f848faSopenharmony_ci return (LOS_OK); 344f9f848faSopenharmony_ci 345f9f848faSopenharmony_cierr: 346f9f848faSopenharmony_ci mtx_unlock(&usb_mtx); 347f9f848faSopenharmony_ci return (LOS_NOK); 348f9f848faSopenharmony_ci} 349f9f848faSopenharmony_ci 350f9f848faSopenharmony_cibool 351f9f848faSopenharmony_ciusb_is_devicemode(void) 352f9f848faSopenharmony_ci{ 353f9f848faSopenharmony_ci return (HiUsbIsDeviceMode()); 354f9f848faSopenharmony_ci} 355f9f848faSopenharmony_ci 356