// 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.
@available(added=25)
library fuchsia.hardware.pin;

using fuchsia.hardware.gpio;
using zx;

/// Maximum length of the pin name.
const MAX_PIN_NAME_LEN uint32 = 64;

/// Maximum length of the function name.
@available(added=31)
const MAX_FUNCTION_NAME_LEN uint32 = 32;


@strict_audit(bug="https://fxbug.dev/467128430", state="PENDING_REVIEW")
type Pull = strict enum {
    DOWN = 0;
    UP = 1;
    NONE = 2;
    @available(added=30)
    BUS_HOLD = 3;
};

type DriveType = flexible enum {
    PUSH_PULL = 0;
    OPEN_DRAIN = 1;
    OPEN_SOURCE = 2;
};

type Configuration = table {
    /// Whether to enable the built-in pull-down resistor, pull-up resistor, or neither.
    1: pull Pull;
    /// Configures the pin for an alternate function (I2C, SPI, etc). The interpretation of
    /// `function` is controller dependent.
    /// Either `function` or `function_name` can be specified, but not both.
    2: function uint64;
    /// The pin drive strength in microamps. Rounds up to the nearest supported drive strength.
    3: drive_strength_ua uint64;
    /// The pin drive type.
    4: drive_type DriveType;
    /// Selects the power source. Interpretation is controller dependent.
    5: power_source uint64;
    /// Determines whether the interrupt is wakeable or not.
    @available(added=30)
    6: wake_vector bool;
    /// Configures how quickly the pin can transition between high and low states. The
    /// interpretation of `slew_rate` is controller dependent.
    @available(added=30)
    7: slew_rate uint64;

    /// The name of the function to configure the pin for.
    /// Either `function` or `function_name` can be specified, but not both.
    @available(added=31)
    8: function_name string:MAX_FUNCTION_NAME_LEN;
};

open protocol Pin {
    /// Applies the configuration passed in `config`; see `Configuration` above. Fields not set in
    /// `config` are not changed. The drive strength is rounded up or capped to a value that the
    /// controller supports.
    ///
    /// `new_config` contains the configuration of the pin after all supported fields have been set.
    /// `Configure()` can be called with an empty `config` to return the current configuration
    /// without making any changes.
    strict Configure(struct {
        config Configuration;
    }) -> (struct {
        new_config Configuration;
    }) error zx.Status;
};

service Service {
    device client_end:Pin;
};

open protocol Debug {
    /// Returns the static properties of a pin.
    strict GetProperties() -> (table {
        /// The platform-specific number of this pin, set as a bind property on the driver node.
        1: pin uint32;
        /// The platform-specific name of this pin.
        2: name string:MAX_PIN_NAME_LEN;
    });

    strict ConnectPin(resource struct {
        server server_end:Pin;
    }) -> () error zx.Status;

    /// Returns ZX_ERR_NOT_SUPPORTED if the pin does not support GPIO.
    strict ConnectGpio(resource struct {
        server server_end:fuchsia.hardware.gpio.Gpio;
    }) -> () error zx.Status;
};

service DebugService {
    device client_end:Debug;
};
