blob: c9ec309c2e7a4290026e592e9bac77a14016a390 [file] [log] [blame]
// Copyright 2024 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.
library fuchsia.hardware.hrtimer;
using zx;
using fuchsia.power.broker;
/// Maximum count of timers supported by this protocol, arbitrary,
const MAX_COUNT_TIMERS uint32 = 64;
/// Maximum count of resolutions supported by a given timer, arbitrary,
const MAX_COUNT_RESOLUTIONS uint32 = 64;
/// Errors that this driver may return.
type DriverError = flexible enum {
/// The driver encountered an otherwise unspecified error while performing the operation.
INTERNAL_ERROR = 1;
/// The operation is not implemented, supported, or enabled.
NOT_SUPPORTED = 2;
/// An argument is invalid.
INVALID_ARGS = 3;
/// The operation failed because the current state of the driver does not allow it, or a
/// precondition of the operation is not satisfied.
BAD_STATE = 4;
/// The in-progress operation has been canceled.
CANCELED = 5;
};
/// Amount of time for one tick of a timer.
type Resolution = flexible union {
/// The resolution specified for one tick.
1: duration zx.Duration;
};
/// Properties for a specific timer abstracted by the driver.
type TimerProperties = table {
/// Unique identifier for this timer.
///
/// The `id` is stable for a given timer, i.e. it does not change across different clients
/// or different connections from the same client.
///
/// Required.
1: id uint64;
/// Retrieves the resolutions supported by this timer.
///
/// Required.
2: supported_resolutions vector<Resolution>:MAX_COUNT_RESOLUTIONS;
/// Range in ticks.
///
/// This is the maximum amount of time that can be set in terms of ticks when a timer is
/// started. The maximum range in actual time (e.g. nanoseconds) depends on the resolution used.
///
/// Required.
3: max_ticks uint64;
/// If true then the `SetEvent` method is supported, if false or not present it is not
/// supported.
///
/// Optional.
4: supports_event bool;
/// If true then the `StartAndWait` method is supported, if false or not present it is not
/// supported.
///
/// Optional.
5: supports_wait bool;
};
/// Driver properties.
type Properties = resource table {
/// Retrieves the supported timers properties.
///
/// Optional.
1: timers_properties vector<TimerProperties>:MAX_COUNT_TIMERS;
};
/// A driver providing high resolution timers support.
/// This API is intended for timers that are provided by hardware separate from the CPU
/// For instance this driver may abstract hardware provided by an SoC.
@discoverable
open protocol Device {
/// Start the timer `id` to expire after `ticks`.
///
/// If `ticks` is 0 then the timer will expire in 0 ticks (immediately).
/// If the timer `id` was already started, then the previous `Start` is canceled and the driver
/// will restart the timer. Note that this may race with the expiration of the previous timer,
/// for instance the notification process may be already started and a new `Start` call won't
/// be able to stop a notification that is already in flight.
/// If the specified `id` is invalid, then this call will return `INVALID_ARGS`.
/// If the specified `resolution` is not supported per the `resolutions` provided by
/// `GetProperties`, then this call will return `INVALID_ARGS`.
/// If the specified `ticks` is beyond the range supported for the timer as provided by
/// `GetProperties`, then this call will return `INVALID_ARGS`.
/// If the driver encounters an internal error, then this call will return `INTERNAL_ERROR`.
flexible Start(struct {
id uint64;
resolution Resolution;
ticks uint64;
}) -> () error DriverError;
/// Stops the timer `id`.
///
/// Note that this may race with the expiration of the timer, for instance notification via
/// an event set with `SetEvent` may be already in flight.
/// If the specified `id` is invalid, then this call will return `INVALID_ARGS`.
/// If the driver encounters an internal error, then this call will return `INTERNAL_ERROR`.
flexible Stop(struct {
id uint64;
}) -> () error DriverError;
/// Get the current time in ticks left in timer `id` until expiration.
///
/// If the specified `id` is invalid, then this call will return `INVALID_ARGS`.
flexible GetTicksLeft(struct {
id uint64;
}) -> (struct {
ticks uint64;
}) error DriverError;
/// Sets a Zircon Event to be notified of the timer expiration.
///
/// The timer expiration will be notified via the ZX_EVENT_SIGNALED signal.
/// The client is responsible for clearing the ZX_EVENT_SIGNALED signal.
/// Any previously event set for the specific `id` is replaced. Note that this may race with
/// the event signaling from the expiration of a timer already started.
/// To guarantee that an event is delivered upon timer expiration, this method must be
/// called before calling `Start`.
///
/// If the specified `id` is invalid, then this call will return `INVALID_ARGS`.
/// If this method is not supported for the given `id`, then this call will return
/// `NOT_SUPPORTED`.
/// If the driver encounters an internal error, then this call will return `INTERNAL_ERROR`.
flexible SetEvent(resource struct {
id uint64;
event zx.Handle:EVENT;
}) -> () error DriverError;
/// Start the timer `id` to expire after `ticks` and waits until the timer expires with
/// support for preventing suspension via the Power Framework.
///
/// The driver will not respond to this call (hang) until the timer has triggered.
/// Calling `Stop` on the timer will abort this call and return `CANCELED`. Note that this
/// may race with the expiration of the timer.
///
/// A driver supporting this call must be able to get a lease on a power element that keeps
/// the system from suspending. This lease is returned to the client via the `keep_alive`
/// LeaseControl channel field. When `keep_alive` is closed, then the driver lease keeping the
/// system from suspending will be dropped. Hence, to guarantee that the system is not
/// suspended by the Power Framework a client must either keep this `keep_alive` channel for
/// as long as the system needs to not suspend, or a client must get its own lease from the
/// Power Framework to prevent suspension before it drops `keep_alive`.
///
/// If the specified `id` is invalid, then this call will return `INVALID_ARGS`.
/// If this method is not supported for the given `id`, then this call will return
/// `NOT_SUPPORTED`.
/// If the driver does not have a `keep_alive` channel to provide to the client, then this
/// call will return `BAD_STATE`.
/// If the driver encounters an internal error, then this call will return `INTERNAL_ERROR`.
flexible StartAndWait(struct {
id uint64;
resolution Resolution;
ticks uint64;
}) -> (resource struct {
keep_alive client_end:fuchsia.power.broker.LeaseControl;
}) error DriverError;
/// Get driver properties.
flexible GetProperties() -> (resource struct {
properties Properties;
});
};
service Service {
device client_end:Device;
};