blob: 9a0c0eda291542398f0307725d7a7c0d9bfcbd5f [file] [log] [blame]
// Copyright 2022 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_AML_USB_PHY_AML_USB_PHY_H_
#define SRC_DEVICES_USB_DRIVERS_AML_USB_PHY_AML_USB_PHY_H_
#include <fidl/fuchsia.hardware.registers/cpp/wire.h>
#include <lib/async/cpp/irq.h>
#include <lib/mmio/mmio.h>
#include <lib/zx/interrupt.h>
#include <fbl/macros.h>
#include "src/devices/usb/drivers/aml-usb-phy/aml-usb-phy-device.h"
#include "src/devices/usb/drivers/aml-usb-phy/usb-phy2.h"
#include "src/devices/usb/drivers/aml-usb-phy/usb-phy3.h"
namespace aml_usb_phy {
class AmlUsbPhy : public fidl::Server<fuchsia_hardware_usb_phy::UsbPhy> {
public:
AmlUsbPhy(AmlUsbPhyDevice* controller, fuchsia_hardware_usb_phy::AmlogicPhyType type,
fidl::ClientEnd<fuchsia_hardware_registers::Device> reset_register,
fdf::MmioBuffer usbctrl_mmio, zx::interrupt irq, std::vector<UsbPhy2> usbphy2,
std::vector<UsbPhy3> usbphy3, bool needs_hack)
: type_(type),
controller_(controller),
reset_register_(std::move(reset_register)),
usbctrl_mmio_(std::move(usbctrl_mmio)),
usbphy2_(std::move(usbphy2)),
usbphy3_(std::move(usbphy3)),
irq_(std::move(irq)),
needs_hack_(needs_hack) {}
~AmlUsbPhy() override {
irq_handler_.Cancel();
irq_.destroy();
}
zx_status_t Init();
// fuchsia_hardware_usb_phy::UsbPhy required methods
void ConnectStatusChanged(ConnectStatusChangedRequest& request,
ConnectStatusChangedCompleter::Sync& completer) override;
void handle_unknown_method(fidl::UnknownMethodMetadata<fuchsia_hardware_usb_phy::UsbPhy> metadata,
fidl::UnknownMethodCompleter::Sync& completer) override {
fdf::error("Unknown method {}", metadata.method_ordinal);
}
// For testing.
bool dwc2_connected() const { return dwc2_connected_; }
UsbPhyBase* usbphy(fuchsia_hardware_usb_phy::ProtocolVersion proto, uint32_t idx) {
return proto == fuchsia_hardware_usb_phy::ProtocolVersion::kUsb20
? static_cast<UsbPhyBase*>(&usbphy2_.at(idx))
: static_cast<UsbPhyBase*>(&usbphy3_.at(idx));
}
private:
DISALLOW_COPY_ASSIGN_AND_MOVE(AmlUsbPhy);
zx_status_t InitPhy2();
zx_status_t InitPhy3();
zx_status_t InitOtg();
zx::result<> ChangeMode(UsbPhyBase& phy, fuchsia_hardware_usb_phy::Mode new_mode);
void HandleIrq(async_dispatcher_t* dispatcher, async::IrqBase* irq, zx_status_t status,
const zx_packet_interrupt_t* interrupt);
// Used for debugging.
void dump_regs();
const fuchsia_hardware_usb_phy::AmlogicPhyType type_;
AmlUsbPhyDevice* controller_;
fidl::WireSyncClient<fuchsia_hardware_registers::Device> reset_register_;
fdf::MmioBuffer usbctrl_mmio_;
std::vector<UsbPhy2> usbphy2_;
std::vector<UsbPhy3> usbphy3_;
zx::interrupt irq_;
async::IrqMethod<AmlUsbPhy, &AmlUsbPhy::HandleIrq> irq_handler_{this};
// S905D2 and S905D3 set a few PLL values differently. needs_hack_ is true if PID is S905D2 or
// S905D3.
const bool needs_hack_;
bool dwc2_connected_ = false;
};
} // namespace aml_usb_phy
#endif // SRC_DEVICES_USB_DRIVERS_AML_USB_PHY_AML_USB_PHY_H_