1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "hikey-usb.h" 6 7#include <assert.h> 8#include <stdint.h> 9#include <stdio.h> 10#include <stdlib.h> 11#include <string.h> 12 13#include <ddk/binding.h> 14#include <ddk/debug.h> 15#include <ddk/device.h> 16#include <ddk/driver.h> 17#include <ddk/protocol/gpio.h> 18#include <ddk/protocol/platform-defs.h> 19#include <ddk/protocol/platform-device.h> 20#include <fbl/algorithm.h> 21#include <fbl/unique_ptr.h> 22 23namespace hikey_usb { 24 25zx_status_t HikeyUsb::Create(zx_device_t* parent) { 26 fbl::AllocChecker ac; 27 auto bus = fbl::make_unique_checked<HikeyUsb>(&ac, parent); 28 if (!ac.check()) { 29 return ZX_ERR_NO_MEMORY; 30 } 31 32 auto status = bus->Init(); 33 if (status != ZX_OK) { 34 return status; 35 } 36 37 // devmgr is now in charge of the device. 38 __UNUSED auto* dummy = bus.release(); 39 return ZX_OK; 40} 41 42zx_status_t HikeyUsb::Init() { 43 platform_device_protocol_t pdev; 44 45 auto status = device_get_protocol(parent(), ZX_PROTOCOL_PLATFORM_DEV, &pdev); 46 if (status != ZX_OK) { 47 return status; 48 } 49 for (uint32_t i = 0; i < countof(gpios_); i++) { 50 status = pdev_get_protocol(&pdev, ZX_PROTOCOL_GPIO, i, &gpios_[i]); 51 if (status != ZX_OK) { 52 return status; 53 } 54 gpio_config_out(&gpios_[i], 0); 55 } 56 57 zx_device_prop_t props[] = { 58 {BIND_PLATFORM_DEV_VID, 0, PDEV_VID_GENERIC}, 59 {BIND_PLATFORM_DEV_PID, 0, PDEV_PID_GENERIC}, 60 {BIND_PLATFORM_DEV_DID, 0, PDEV_DID_USB_DWC3}, 61 }; 62 63 device_add_args_t args = {}; 64 args.version = DEVICE_ADD_ARGS_VERSION; 65 args.name = "dwc3"; 66 args.ctx = this; 67 args.ops = &ddk_device_proto_; 68 args.props = props; 69 args.prop_count = static_cast<uint32_t>(fbl::count_of(props)); 70 args.proto_id = ddk_proto_id_; 71 args.proto_ops = ddk_proto_ops_; 72 73 return pdev_device_add(&pdev, 0, &args, &zxdev_); 74} 75 76zx_status_t HikeyUsb::UmsSetMode(usb_mode_t mode) { 77 if (mode == usb_mode_) { 78 return ZX_OK; 79 } 80 if (mode == USB_MODE_OTG) { 81 return ZX_ERR_NOT_SUPPORTED; 82 } 83 84 gpio_write(&gpios_[HUB_VDD33_EN], mode == USB_MODE_HOST); 85 gpio_write(&gpios_[VBUS_TYPEC], mode == USB_MODE_HOST); 86 gpio_write(&gpios_[USBSW_SW_SEL], mode == USB_MODE_HOST); 87 88 usb_mode_ = mode; 89 return ZX_OK; 90 91 92 return ZX_OK; 93} 94 95void HikeyUsb::DdkRelease() { 96 delete this; 97} 98 99} // namespace hikey_usb 100 101zx_status_t hikey_usb_bind(void* ctx, zx_device_t* parent) { 102 return hikey_usb::HikeyUsb::Create(parent); 103} 104