| // Copyright 2018 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=7) |
| library fuchsia.hardware.i2c; |
| |
| using zx; |
| |
| const MAX_TRANSFER_SIZE uint32 = 8196; // More than enough for I2C |
| const MAX_COUNT_SEGMENTS uint32 = 8; // Enough for all known transfer configurations. |
| const MAX_I2C_CHANNEL uint32 = 128; // Enough for every address to be used in 7-bit mode. |
| type SegmentType = strict enum { |
| /// Flags the end of a serialized list of segments. |
| END = 1; |
| /// Segment to be read from the I2C device. |
| READ = 2; |
| /// Segment to be written to the I2C device. |
| WRITE = 3; |
| }; |
| |
| /// Used to inform the i2c driver about an attached i2c device. |
| type I2CChannel = table { |
| /// ID of the bus that this device is on. |
| 1: bus_id uint32; |
| /// Adress of the device. |
| 2: address uint16; |
| /// Class of the device. |
| /// TODO(fxbug.dev/78198): remove this once x86 uses ACPI properly. |
| 3: i2c_class uint32; |
| |
| /// Vendor ID. Used when binding via platform bus device IDs. |
| 4: vid uint32; |
| /// Product ID. Used when binding via platform bus device IDs. |
| 5: pid uint32; |
| /// Device ID. Used when binding via platform bus device IDs. |
| 6: did uint32; |
| |
| // Bus configuration. |
| /// Are we in charge of the bus? |
| 7: is_bus_controller bool; |
| /// Is this device using 10-bit addressing mode (if false, use 7-bit). |
| 8: is_ten_bit bool; |
| /// Speed of the bus. |
| 9: bus_speed uint32; |
| }; |
| |
| /// Passed to the i2c driver in metadata as DEVICE_METADATA_I2C_CHANNELS. |
| type I2CBusMetadata = table { |
| 1: channels vector<I2CChannel>:MAX_I2C_CHANNEL; |
| }; |
| |
| // A previous `Device` is now removed. |
| @discoverable |
| protocol Device2 { |
| /// Write and read segments of data for a particular I2C device. |
| /// |
| /// The `segments_is_write` vector specifies the type (write or read) of each segment. |
| /// The `write_segments_data` vector of segments specifies the data to write for each write |
| /// segment. Each segment itself is a vector of uint8s, so `write_segments_data` is a vector of |
| /// vectors of uint8s. |
| /// The `read_segments_length` vector specifies the length of the read segments. No entry may be |
| /// larger than MAX_TRANSFER_SIZE. |
| /// If there is no error, `read_segments_data` returns a vector of segments, with each segment |
| /// data itself returned in vectors. |
| /// |
| /// For a simple I2C read, for instance 2 bytes write followed by one byte read, |
| /// `segments_is_write` would be a vector with 2 elements: true, false and |
| /// `write_segments_data` would be a vector with 1 element including the 2 bytes address of the |
| /// read. Upon success `read_segments_data` would return a vector with one element, the byte |
| /// read. |
| Transfer(struct { |
| segments_is_write vector<bool>:MAX_COUNT_SEGMENTS; |
| write_segments_data vector<vector<uint8>:MAX_TRANSFER_SIZE>:MAX_COUNT_SEGMENTS; |
| read_segments_length vector<uint32>:MAX_COUNT_SEGMENTS; |
| }) -> (struct { |
| read_segments_data vector<vector<uint8>:MAX_TRANSFER_SIZE>:MAX_COUNT_SEGMENTS; |
| }) error zx.status; |
| }; |