| // 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_ |