| // Copyright 2023 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_DEVICES_USB_DRIVERS_A1_USB_PHY_A1_USB_PHY_H_ |
| #define SRC_DEVICES_USB_DRIVERS_A1_USB_PHY_A1_USB_PHY_H_ |
| |
| #include <fuchsia/hardware/usb/phy/cpp/banjo.h> |
| #include <lib/device-protocol/pdev-fidl.h> |
| #include <lib/mmio/mmio.h> |
| #include <lib/zx/interrupt.h> |
| #include <threads.h> |
| |
| #include <ddktl/device.h> |
| #include <fbl/auto_lock.h> |
| #include <fbl/mutex.h> |
| #include <soc/aml-common/aml-registers.h> |
| #include <usb/usb.h> |
| |
| namespace a1_usb_phy { |
| |
| class A1UsbPhy; |
| using A1UsbPhyType = ddk::Device<A1UsbPhy, ddk::Initializable, ddk::Unbindable>; |
| |
| // This is the main class for the platform bus driver. |
| class A1UsbPhy : public A1UsbPhyType, public ddk::UsbPhyProtocol<A1UsbPhy, ddk::base_protocol> { |
| public: |
| // Public for testing. |
| enum class UsbMode { |
| UNKNOWN, |
| HOST, |
| PERIPHERAL, |
| }; |
| |
| // TODO(123426) Remove. See issue details. |
| struct TestMetadata { |
| // True to short circuit (not invoke) the zx_smc_call syscall. |
| bool smc_short_circuit; |
| }; |
| |
| explicit A1UsbPhy(zx_device_t* parent) : A1UsbPhyType(parent) {} |
| |
| static zx_status_t Create(void* ctx, zx_device_t* parent); |
| |
| // USB PHY protocol implementation. |
| void UsbPhyConnectStatusChanged(bool connected); |
| |
| // Device protocol implementation. |
| void DdkInit(ddk::InitTxn txn); |
| void DdkUnbind(ddk::UnbindTxn txn); |
| void DdkRelease(); |
| |
| // Public for testing. |
| UsbMode mode() { |
| fbl::AutoLock lock(&lock_); |
| return phy_mode_; |
| } |
| |
| private: |
| DISALLOW_COPY_ASSIGN_AND_MOVE(A1UsbPhy); |
| |
| void InitPll(fdf::MmioBuffer* mmio); |
| zx_status_t InitPhy(); |
| zx_status_t InitOtg(); |
| |
| // Called when |SetMode| completes. |
| using SetModeCompletion = fit::callback<void(void)>; |
| void SetMode(UsbMode mode, SetModeCompletion completion) __TA_REQUIRES(lock_); |
| |
| zx_status_t AddXhciDevice() __TA_REQUIRES(lock_); |
| void RemoveXhciDevice() __TA_REQUIRES(lock_); |
| |
| zx_status_t Init(); |
| void InitUsbClk(); |
| |
| bool smc_short_circuit_ = false; |
| zx_status_t UsbPowerOn(); |
| |
| std::optional<fdf::MmioBuffer> usbctrl_mmio_; |
| std::optional<fdf::MmioBuffer> usbphy_mmio_; |
| std::optional<fdf::MmioBuffer> reset_mmio_; |
| std::optional<fdf::MmioBuffer> clk_mmio_; |
| |
| // Control PowerDomain |
| zx::resource smc_monitor_; |
| |
| fbl::Mutex lock_; |
| |
| // Magic numbers for PLL from metadata |
| uint32_t pll_settings_[8]; |
| |
| // Device node for binding XHCI driver. |
| zx_device_t* xhci_device_ __TA_GUARDED(lock_) = nullptr; |
| |
| UsbMode phy_mode_ __TA_GUARDED(lock_) = UsbMode::UNKNOWN; // Physical USB mode. |
| usb_mode_t dr_mode_ = USB_MODE_OTG; // USB Controller Mode. Internal to Driver. |
| bool dwc2_connected_ = false; |
| }; |
| |
| } // namespace a1_usb_phy |
| |
| #endif // SRC_DEVICES_USB_DRIVERS_A1_USB_PHY_A1_USB_PHY_H_ |