// Copyright 2023 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=HEAD)
library fuchsia.hardware.gpioimpl;

using fuchsia.hardware.gpio;
using zx;


const MAX_GPIO_NAME_LEN uint32 = 64;

type Pin = struct {
    /// An identifying number for this pin, set by the GPIO core driver as the fuchsia.BIND_GPIO_PIN
    /// bind property. Must be unique for this GPIO controller.
    pin uint32;
    /// A human-readable, informational name for this pin. Optional, but helpful for manual testing
    /// purposes.
    name string:<MAX_GPIO_NAME_LEN, optional>;
};

@transport("Driver")
open protocol GpioImpl {
    /// Configures a GPIO for input.
    strict ConfigIn(struct {
        index uint32;
        flags fuchsia.hardware.gpio.GpioFlags;
    }) -> () error zx.Status;

    /// Configures a GPIO for output.
    strict ConfigOut(struct {
        index uint32;
        initial_value uint8;
    }) -> () error zx.Status;

    /// Configures the GPIO pin for an alternate function (I2C, SPI, etc)
    /// the interpretation of "function" is platform dependent.
    strict SetAltFunction(struct {
        index uint32;
        function uint64;
    }) -> () error zx.Status;

    /// Reads the current value of a GPIO (0 or 1).
    strict Read(struct {
        index uint32;
    }) -> (struct {
        value uint8;
    }) error zx.Status;

    /// Sets the current value of the GPIO (any non-zero value maps to 1).
    strict Write(struct {
        index uint32;
        value uint8;
    }) -> () error zx.Status;

    /// Set GPIO polarity.
    strict SetPolarity(struct {
        index uint32;
        polarity fuchsia.hardware.gpio.GpioPolarity;
    }) -> () error zx.Status;

    /// Sets the drive strength of the GPIO.
    /// actual_ds_ua is always >= ds_ua. If ds_ua is larger than max value, the drive strength will be set to the max value.
    /// Return error if unable to set drive strength. actual_ds_ua is not set in this case.
    strict SetDriveStrength(struct {
        index uint32;
        ds_ua uint64;
    }) -> (struct {
        actual_ds_ua uint64;
    }) error zx.Status;

    /// Gets the configured drive strength of the GPIO in microamps (ua).
    strict GetDriveStrength(struct {
        index uint32;
    }) -> (struct {
        result_ua uint64;
    }) error zx.Status;

    /// Gets an interrupt object pertaining to a particular GPIO pin. `flags`
    /// is passed as the `options` parameter when
    /// [creating the interrupt](https://fuchsia.dev/fuchsia-src/reference/syscalls/interrupt_create).
    strict GetInterrupt(struct {
        index uint32;
        flags uint32;
    }) -> (resource struct {
        irq zx.Handle:INTERRUPT;
    }) error zx.Status;

    /// Release the interrupt.
    strict ReleaseInterrupt(struct {
        index uint32;
    }) -> () error zx.Status;

    /// Returns a vector of pins on this controller to be exposed by the GPIO core driver.
    strict GetPins() -> (struct {
        pins vector<Pin>:MAX;
    });

    /// Returns a vector of initialization steps to be performed by the GPIO core driver in its
    /// start hook. Steps are processed sequentially in the order that they appear in the vector. If
    /// no steps are provided, the core driver does not add an init device.
    strict GetInitSteps() -> (struct {
        steps vector<InitStep>:MAX;
    });

    /// Returns a number that uniquely identifies this GPIO controller device. The GPIO core driver
    /// will use this to create bind properties for pin devices so that controllers can have
    /// overlapping pin numbers. Thus, every (controller, pin) combination will identify at most one
    /// pin device.
    ///
    /// On platforms that will only ever have one GPIO controller device, or that will not have
    /// overlapping pin numbers across devices, this method can just return some hardcoded value.
    /// Otherwise, a value such as the controller's devicetree phandle could be returned.
    strict GetControllerId() -> (struct {
        controller_id uint32;
    });
};

service Service {
    device client_end:GpioImpl;
};
