// 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.i2cimpl;

using fuchsia.hardware.i2c;
using zx;

/// If `read_size` is set: This is a read operation and `read_size` bytes will be read.
/// If `write_data` is set: This is a write operation and `write_data` will be written.
type I2cImplOpType = strict union {
    1: read_size uint32;
    2: write_data vector<uint8>:fuchsia.hardware.i2c.MAX_TRANSFER_SIZE;
};

/// See `Transact` below for usage.
type I2cImplOp = struct {
    address uint16;
    type I2cImplOpType;
    stop bool;
};

/// The result of one read transaction.
type ReadData = struct {
    data vector<uint8>:fuchsia.hardware.i2c.MAX_TRANSFER_SIZE;
};

/// Low-level protocol for i2c drivers.
@discoverable
@transport("Driver")
open protocol Device {
    flexible GetMaxTransferSize() -> (struct {
        size uint64;
    }) error zx.Status;

    /// Sets the bitrate for the i2c bus in KHz units.
    flexible SetBitrate(struct {
        bitrate uint32;
    }) -> () error zx.Status;

    /// |Transact| assumes that write ops write_data length are not zero.
    /// |Transact| assumes that at least the last op has stop set to true.
    ///
    /// For each read-transaction, there will be a corresponding ReadData
    /// returned. Write-transactions produce no data result.
    flexible Transact(struct {
        op vector<I2cImplOp>:fuchsia.hardware.i2c.MAX_COUNT_TRANSACTIONS;
    }) -> (struct {
        read vector<ReadData>:fuchsia.hardware.i2c.MAX_COUNT_TRANSACTIONS;
    }) error zx.Status;
};

service Service {
    device client_end:Device;
};
