Line data Source code
1 0 : /* 2 : * Copyright 2022 Intel Corporation 3 : * 4 : * SPDX-License-Identifier: Apache-2.0 5 : */ 6 : 7 : #ifndef ZEPHYR_INCLUDE_DRIVERS_I3C_ADDRESSES_H_ 8 : #define ZEPHYR_INCLUDE_DRIVERS_I3C_ADDRESSES_H_ 9 : 10 : /** 11 : * @brief I3C Address-related Helper Code 12 : * @defgroup i3c_addresses I3C Address-related Helper Code 13 : * @ingroup i3c_interface 14 : * @{ 15 : */ 16 : 17 : #include <stdint.h> 18 : 19 : #include <zephyr/device.h> 20 : #include <zephyr/sys/util.h> 21 : 22 : #ifdef __cplusplus 23 : extern "C" { 24 : #endif 25 : 26 : /** Broadcast Address on I3C bus. */ 27 1 : #define I3C_BROADCAST_ADDR 0x7E 28 : 29 : /** Maximum value of device addresses. */ 30 1 : #define I3C_MAX_ADDR 0x7F 31 : 32 : struct i3c_dev_list; 33 : 34 : /** 35 : * Enum to indicate whether an address is reserved, has I2C/I3C device attached, 36 : * or no device attached. 37 : */ 38 1 : enum i3c_addr_slot_status { 39 : /** Address has not device attached. */ 40 : I3C_ADDR_SLOT_STATUS_FREE = 0U, 41 : 42 : /** Address is reserved. */ 43 : I3C_ADDR_SLOT_STATUS_RSVD, 44 : 45 : /** Address is associated with an I3C device. */ 46 : I3C_ADDR_SLOT_STATUS_I3C_DEV, 47 : 48 : /** Address is associated with an I2C device. */ 49 : I3C_ADDR_SLOT_STATUS_I2C_DEV, 50 : 51 : /** Bit masks used to filter status bits. */ 52 : I3C_ADDR_SLOT_STATUS_MASK = 0x03U, 53 : }; 54 : 55 : /** 56 : * @brief Structure to keep track of addresses on I3C bus. 57 : */ 58 1 : struct i3c_addr_slots { 59 : /* 2 bits per slot */ 60 0 : unsigned long slots[((I3C_MAX_ADDR + 1) * 2) / BITS_PER_LONG]; 61 : }; 62 : 63 : /** 64 : * @brief Initialize the I3C address slots struct. 65 : * 66 : * This clears out the assigned address bits, and set the reserved 67 : * address bits according to the I3C specification. 68 : * 69 : * @param dev Pointer to controller device driver instance. 70 : * 71 : * @retval 0 if successful. 72 : * @retval -EINVAL if duplicate addresses. 73 : */ 74 1 : int i3c_addr_slots_init(const struct device *dev); 75 : 76 : /** 77 : * @brief Set the address status of a device. 78 : * 79 : * @param slots Pointer to the address slots structure. 80 : * @param dev_addr Device address. 81 : * @param status New status for the address @p dev_addr. 82 : */ 83 1 : void i3c_addr_slots_set(struct i3c_addr_slots *slots, 84 : uint8_t dev_addr, 85 : enum i3c_addr_slot_status status); 86 : 87 : /** 88 : * @brief Get the address status of a device. 89 : * 90 : * @param slots Pointer to the address slots structure. 91 : * @param dev_addr Device address. 92 : * 93 : * @return Address status for the address @p dev_addr. 94 : */ 95 1 : enum i3c_addr_slot_status i3c_addr_slots_status(struct i3c_addr_slots *slots, 96 : uint8_t dev_addr); 97 : 98 : /** 99 : * @brief Check if the address is free. 100 : * 101 : * @param slots Pointer to the address slots structure. 102 : * @param dev_addr Device address. 103 : * 104 : * @retval true if address is free. 105 : * @retval false if address is not free. 106 : */ 107 1 : bool i3c_addr_slots_is_free(struct i3c_addr_slots *slots, 108 : uint8_t dev_addr); 109 : 110 : /** 111 : * @brief Find the next free address. 112 : * 113 : * This can be used to find the next free address that can be 114 : * assigned to a new device. 115 : * 116 : * @param slots Pointer to the address slots structure. 117 : * @param start_addr Where to start searching 118 : * 119 : * @return The next free address, or 0 if none found. 120 : */ 121 1 : uint8_t i3c_addr_slots_next_free_find(struct i3c_addr_slots *slots, uint8_t start_addr); 122 : 123 : /** 124 : * @brief Mark the address as free (not used) in device list. 125 : * 126 : * @param addr_slots Pointer to the address slots struct. 127 : * @param addr Device address. 128 : */ 129 1 : static inline void i3c_addr_slots_mark_free(struct i3c_addr_slots *addr_slots, 130 : uint8_t addr) 131 : { 132 : i3c_addr_slots_set(addr_slots, addr, 133 : I3C_ADDR_SLOT_STATUS_FREE); 134 : } 135 : 136 : /** 137 : * @brief Mark the address as reserved in device list. 138 : * 139 : * @param addr_slots Pointer to the address slots struct. 140 : * @param addr Device address. 141 : */ 142 1 : static inline void i3c_addr_slots_mark_rsvd(struct i3c_addr_slots *addr_slots, 143 : uint8_t addr) 144 : { 145 : i3c_addr_slots_set(addr_slots, addr, 146 : I3C_ADDR_SLOT_STATUS_RSVD); 147 : } 148 : 149 : /** 150 : * @brief Mark the address as I3C device in device list. 151 : * 152 : * @param addr_slots Pointer to the address slots struct. 153 : * @param addr Device address. 154 : */ 155 1 : static inline void i3c_addr_slots_mark_i3c(struct i3c_addr_slots *addr_slots, 156 : uint8_t addr) 157 : { 158 : i3c_addr_slots_set(addr_slots, addr, 159 : I3C_ADDR_SLOT_STATUS_I3C_DEV); 160 : } 161 : 162 : /** 163 : * @brief Mark the address as I2C device in device list. 164 : * 165 : * @param addr_slots Pointer to the address slots struct. 166 : * @param addr Device address. 167 : */ 168 1 : static inline void i3c_addr_slots_mark_i2c(struct i3c_addr_slots *addr_slots, 169 : uint8_t addr) 170 : { 171 : i3c_addr_slots_set(addr_slots, addr, 172 : I3C_ADDR_SLOT_STATUS_I2C_DEV); 173 : } 174 : 175 : #ifdef __cplusplus 176 : } 177 : #endif 178 : 179 : /** 180 : * @} 181 : */ 182 : 183 : #endif /* ZEPHYR_INCLUDE_DRIVERS_I3C_ADDRESSES_H_ */