// Copyright 2018 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.

#pragma once

#include <ddktl/device.h>
#include <ddktl/protocol/platform/bus.h>
#include <ddktl/protocol/platform/device.h>
#include <fbl/unique_ptr.h>
#include <fbl/vector.h>

#include "device-resources.h"
#include "proxy-protocol.h"

namespace platform_bus {

class PlatformBus;

// This class is used for binding protocol implementation drivers.
// It implements the platform device protocol, and also provides access to the
// a subset of the platform bus protocol, and also the other protocols that are
// available to platform devices.
// Unlike platform device drivers, proto implementation drivers run in the same
// devhost as the platform bus driver.

class ProtocolDevice;
using ProtocolDeviceType = ddk::Device<ProtocolDevice, ddk::GetProtocolable>;

// This class represents a platform device attached to the platform bus.
// Instances of this class are created by PlatformBus at boot time when the board driver
// calls the platform bus protocol method pbus_device_add().

class ProtocolDevice : public ProtocolDeviceType,
                       public ddk::PDevProtocol<ProtocolDevice, ddk::base_protocol> {
public:
    // Creates a new ProtocolDevice instance.
    // *flags* contains zero or more PDEV_ADD_* flags from the platform bus protocol.
    static zx_status_t Create(const pbus_dev_t* pdev, zx_device_t* parent, PlatformBus* bus,
                              fbl::unique_ptr<platform_bus::ProtocolDevice>* out);

    inline uint32_t vid() const { return vid_; }
    inline uint32_t pid() const { return pid_; }
    inline uint32_t did() const { return did_; }

    // Device protocol implementation.
    zx_status_t DdkGetProtocol(uint32_t proto_id, void* out);
    void DdkRelease();

    // Platform device protocol implementation.
    zx_status_t PDevGetMmio(uint32_t index, pdev_mmio_t* out_mmio);
    zx_status_t PDevGetInterrupt(uint32_t index, uint32_t flags, zx::interrupt* out_irq);
    zx_status_t PDevGetBti(uint32_t index, zx::bti* out_handle);
    zx_status_t PDevGetSmc(uint32_t index, zx::resource* out_resource);
    zx_status_t PDevGetDeviceInfo(pdev_device_info_t* out_info);
    zx_status_t PDevGetBoardInfo(pdev_board_info_t* out_info);
    zx_status_t PDevDeviceAdd(uint32_t index, const device_add_args_t* args, zx_device_t** device);
    zx_status_t PDevGetProtocol(uint32_t proto_id, uint32_t index, void* out_protocol,
                                size_t protocol_size, size_t* protocol_actual);

    // Starts the underlying devmgr device.
    zx_status_t Start();

private:
    explicit ProtocolDevice(zx_device_t* parent, PlatformBus* bus, const pbus_dev_t* pdev);
    zx_status_t Init(const pbus_dev_t* pdev);

    PlatformBus* bus_;
    char name_[ZX_DEVICE_NAME_MAX + 1];
    const uint32_t vid_;
    const uint32_t pid_;
    const uint32_t did_;

    // Platform bus resources for this device.
    DeviceResources resources_;

    // Restricted subset of the platform bus protocol.
    // We do not allow protocol devices call pbus_device_add() or pbus_protocol_device_add()
    pbus_protocol_ops_t pbus_ops_;
    void* pbus_ctx_;
};

} // namespace platform_bus
