blob: cdb3ad7e1d2aaa426079ba1502bcffd97e188fa3 [file] [log] [blame]
// Copyright 2019 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_CLOCK_DRIVERS_CLOCK_CLOCK_H_
#define SRC_DEVICES_CLOCK_DRIVERS_CLOCK_CLOCK_H_
#include <fidl/fuchsia.hardware.clock/cpp/wire.h>
#include <fidl/fuchsia.hardware.clockimpl/cpp/driver/wire.h>
#include <fuchsia/hardware/clockimpl/cpp/banjo.h>
#include <lib/component/outgoing/cpp/outgoing_directory.h>
#include <lib/ddk/platform-defs.h>
#include <ddktl/device.h>
class ClockImplProxy {
public:
ClockImplProxy(const ddk::ClockImplProtocolClient& clock_banjo,
fdf::WireSyncClient<fuchsia_hardware_clockimpl::ClockImpl> clock_fidl)
: clock_banjo_(clock_banjo), clock_fidl_(std::move(clock_fidl)) {}
zx_status_t Enable(uint32_t id) const;
zx_status_t Disable(uint32_t id) const;
zx_status_t IsEnabled(uint32_t id, bool* out_enabled) const;
zx_status_t SetRate(uint32_t id, uint64_t hz) const;
zx_status_t QuerySupportedRate(uint32_t id, uint64_t hz, uint64_t* out_hz) const;
zx_status_t GetRate(uint32_t id, uint64_t* out_hz) const;
zx_status_t SetInput(uint32_t id, uint32_t idx) const;
zx_status_t GetNumInputs(uint32_t id, uint32_t* out_n) const;
zx_status_t GetInput(uint32_t id, uint32_t* out_index) const;
private:
ddk::ClockImplProtocolClient clock_banjo_;
fdf::WireSyncClient<fuchsia_hardware_clockimpl::ClockImpl> clock_fidl_;
};
class ClockDevice;
using ClockDeviceType = ddk::Device<ClockDevice>;
class ClockDevice : public ClockDeviceType, public fidl::WireServer<fuchsia_hardware_clock::Clock> {
public:
ClockDevice(zx_device_t* parent, ClockImplProxy clock, uint32_t id)
: ClockDeviceType(parent), clock_(std::move(clock)), id_(id) {}
static zx_status_t Create(void* ctx, zx_device_t* parent);
// Device protocol implementation
void DdkRelease();
zx_status_t ServeOutgoing(fidl::ServerEnd<fuchsia_io::Directory> server_end);
private:
// fuchsia.hardware.clock/Clock protocol implementation
void Enable(EnableCompleter::Sync& completer) override;
void Disable(DisableCompleter::Sync& completer) override;
void IsEnabled(IsEnabledCompleter::Sync& completer) override;
void SetRate(SetRateRequestView request, SetRateCompleter::Sync& completer) override;
void QuerySupportedRate(QuerySupportedRateRequestView request,
QuerySupportedRateCompleter::Sync& completer) override;
void GetRate(GetRateCompleter::Sync& completer) override;
void SetInput(SetInputRequestView request, SetInputCompleter::Sync& completer) override;
void GetNumInputs(GetNumInputsCompleter::Sync& completer) override;
void GetInput(GetInputCompleter::Sync& completer) override;
void handle_unknown_method(fidl::UnknownMethodMetadata<fuchsia_hardware_clock::Clock> metadata,
fidl::UnknownMethodCompleter::Sync& completer) override;
const ClockImplProxy clock_;
const uint32_t id_;
async_dispatcher_t* dispatcher_{fdf::Dispatcher::GetCurrent()->async_dispatcher()};
component::OutgoingDirectory outgoing_{dispatcher_};
fidl::ServerBindingGroup<fuchsia_hardware_clock::Clock> bindings_;
};
class ClockInitDevice;
using ClockInitDeviceType = ddk::Device<ClockInitDevice>;
class ClockInitDevice : public ClockInitDeviceType {
public:
static void Create(zx_device_t* parent, const ClockImplProxy& clock);
explicit ClockInitDevice(zx_device_t* parent) : ClockInitDeviceType(parent) {}
void DdkRelease() { delete this; }
private:
static zx_status_t ConfigureClocks(const fuchsia_hardware_clockimpl::wire::InitMetadata& metadata,
const ClockImplProxy& clock);
};
#endif // SRC_DEVICES_CLOCK_DRIVERS_CLOCK_CLOCK_H_