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_ */
|