1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * 4 * HDF is dual licensed: you can use it either under the terms of 5 * the GPL, or the BSD license, at your option. 6 * See the LICENSE file in the root of this repository for complete details. 7 */ 8 9 #ifndef I3C_CORE_H 10 #define I3C_CORE_H 11 12 #include "i3c_if.h" 13 #include "hdf_base.h" 14 #include "hdf_dlist.h" 15 #include "osal_spinlock.h" 16 #include "platform_core.h" 17 18 #ifdef __cplusplus 19 #if __cplusplus 20 extern "C" { 21 #endif 22 #endif /* __cplusplus */ 23 24 #define I3C_CNTLR_MAX 20 25 #define I3C_ADDR_MAX 127 26 #define I3C_IBI_MAX 10 27 #define ADDRS_STATUS_BITS 2 28 #define BITS_PER_UINT16 16 29 #define ADDRS_PER_UINT16 8 30 31 #define ADDR_STATUS_BIT0_MASK 0x1 32 #define ADDR_STATUS_BIT1_MASK 0x2 33 #define ADDR_STATUS_MASK 0x3 34 35 36 #define I3C_RESERVED_ADDR_7H00 0x00 37 #define I3C_RESERVED_ADDR_7H01 0x01 38 #define I3C_RESERVED_ADDR_7H02 0x02 39 #define I3C_RESERVED_ADDR_7H3E 0x3e 40 #define I3C_RESERVED_ADDR_7H5E 0x5e 41 #define I3C_RESERVED_ADDR_7H6E 0x6e 42 #define I3C_RESERVED_ADDR_7H76 0x76 43 #define I3C_RESERVED_ADDR_7H78 0x78 44 #define I3C_RESERVED_ADDR_7H79 0x79 45 #define I3C_RESERVED_ADDR_7H7A 0x7a 46 #define I3C_RESERVED_ADDR_7H7B 0x7b 47 #define I3C_RESERVED_ADDR_7H7C 0x7c 48 #define I3C_RESERVED_ADDR_7H7D 0x7d 49 #define I3C_RESERVED_ADDR_7H7E 0x7e 50 #define I3C_RESERVED_ADDR_7H7F 0x7f 51 52 #define I3C_HOT_JOIN_ADDR I3C_RESERVED_ADDR_7H02 53 #define I3C_BROADCAST_ADDR I3C_RESERVED_ADDR_7H7E 54 55 struct I3cCntlr; 56 struct I3cMethod; 57 struct I3cLockMethod; 58 struct I3cDevice; 59 struct I3cVendor; 60 61 enum I3cDeviceType { 62 /** I2C device */ 63 I3C_CNTLR_I2C_DEVICE = 0, 64 /** legacy I2C device */ 65 I3C_CNTLR_I2C_LEGACY_DEVICE, 66 /** I3C device */ 67 I3C_CNTLR_I3C_DEVICE, 68 }; 69 70 struct I3cCntlr { 71 OsalSpinlock lock; 72 void *owner; 73 int16_t busId; 74 struct I3cConfig config; 75 uint16_t addrSlot[(I3C_ADDR_MAX + 1) / ADDRS_PER_UINT16]; 76 struct I3cIbiInfo *ibiSlot[I3C_IBI_MAX]; 77 const struct I3cMethod *ops; 78 const struct I3cLockMethod *lockOps; 79 void *priv; 80 }; 81 82 /* vendor information of I3C device */ 83 struct I3cVendor { 84 uint32_t vendorMipiId; 85 uint32_t vendorVersionId; 86 uint32_t vendorProductId; 87 }; 88 89 /* In-bind Interrupt information */ 90 struct I3cIbiInfo { 91 I3cIbiFunc ibiFunc; 92 uint32_t payload; 93 uint8_t *data; 94 }; 95 96 struct I3cDevice { 97 struct DListHead list; 98 struct I3cCntlr *cntlr; 99 uint16_t bcr; 100 uint16_t dcr; 101 uint64_t pid; 102 uint16_t addr; 103 enum I3cDeviceType type; 104 uint16_t dynaAddr; 105 uint16_t supportIbi; 106 struct I3cIbiInfo *ibi; 107 struct I3cVendor vendor; 108 void *devPriv; 109 }; 110 111 struct I3cMethod { 112 /** 113 * @brief Send a CCC(Common Command Code), which is implemented by a specific vendor driver. 114 * 115 * @param cntlr Indicates the I3C controller device. 116 * @param ccc Indicates the {@link I3cCccCmd}(Common Command Code) structure. 117 * 118 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 119 * @since 1.0 120 */ 121 int32_t (*sendCccCmd)(struct I3cCntlr *cntlr, struct I3cCccCmd *ccc); 122 123 /** 124 * @brief Execute one or more I3C messages in I3C mode, which is implemented by a specific vendor driver. 125 * 126 * @param cntlr Indicates the I3C controller device. 127 * @param msgs Indicates the {@link I3cMsg} message array. 128 * @param count Indicates the length of the message array. 129 * 130 * @return Returns the number of transferred message structures on success; Returns a negative value otherwise. 131 * 132 * @see I3cMsg 133 * @since 1.0 134 */ 135 int32_t (*Transfer)(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count); 136 137 /** 138 * @brief Execute one or more I3C messages in I2C mode, which is implemented by a specific vendor driver. 139 * 140 * @param cntlr Indicates the I3C controller device. 141 * @param msgs Indicates the {@link I3cMsg} message array. 142 * @param count Indicates the length of the message array. 143 * 144 * @return Returns the number of transferred message structures on success; Returns a negative value otherwise. 145 * 146 * @see I3cMsg 147 * @since 1.0 148 */ 149 int32_t (*i2cTransfer)(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count); 150 151 /** 152 * @brief Set configurations of an I3C controller. 153 * 154 * @param cntlr Indicates the I3C controller to set. 155 * @param config Indicates the pointer of configuration structure. 156 * 157 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 158 * @since 1.0 159 */ 160 int32_t (*setConfig)(struct I3cCntlr *cntlr, struct I3cConfig *config); 161 162 /** 163 * @brief Get configurations of an I3C controller. 164 * 165 * @param cntlr Indicates the I3C controller to get configurations. 166 * @param config Indicates the pointer of configuration structure. 167 * 168 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 169 * @since 1.0 170 */ 171 int32_t (*getConfig)(struct I3cCntlr *cntlr, struct I3cConfig *config); 172 173 /** 174 * @brief Requeset an IBI(in-bind interrupt) for an I3C device which is supported. 175 * 176 * @param device Indicates the I3C device. 177 * 178 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 179 * @since 1.0 180 */ 181 int32_t (*requestIbi)(struct I3cDevice *dev); 182 183 /** 184 * @brief Free an IBI(in-bind interrupt). 185 * 186 * @param device Indicates the I3C device. 187 * 188 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 189 * @since 1.0 190 */ 191 void (*freeIbi)(struct I3cDevice *dev); 192 }; 193 194 struct I3cLockMethod { 195 /** 196 * @brief Get exclusive access to an I3C controller. 197 * 198 * @param cntlr Indicates the I3C controller to access. 199 * 200 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 201 * @since 1.0 202 */ 203 int32_t (*lock)(struct I3cCntlr *cntlr); 204 /** 205 * @brief Release exclusive access to an I3C controller. 206 * 207 * @param cntlr Indicates the I3C controller to release. 208 * 209 * @since 1.0 210 */ 211 void (*unlock)(struct I3cCntlr *cntlr); 212 }; 213 214 enum I3C_ERROR_CODE { 215 I3C_ERROR_UNKNOWN = 0, 216 I3C_ERROR_M0, 217 I3C_ERROR_M1, 218 I3C_ERROR_M2, 219 I3C_ERROR_S0, 220 I3C_ERROR_S1, 221 I3C_ERROR_S2, 222 I3C_ERROR_S3, 223 I3C_ERROR_S4, 224 I3C_ERROR_S5, 225 I3C_ERROR_S6, 226 }; 227 228 enum I3cAddrStatus { 229 I3C_ADDR_FREE = 0, 230 I3C_ADDR_RESERVED, 231 I3C_ADDR_I2C_DEVICE, 232 I3C_ADDR_I3C_DEVICE, 233 }; 234 235 enum I3cDeviceSupportIbi { 236 I3C_DEVICE_NOT_SUPPORT_IBI = 0, 237 I3C_DEVICE_SUPPORT_IBI, 238 }; 239 240 /** 241 * @brief Set the config of a I3C controller. 242 * 243 * @param cntlr Indicates the I3C controller device. 244 * @param config Indicates the pointer of the configuration structure. 245 * 246 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 247 * @since 1.0 248 */ 249 int32_t I3cCntlrSetConfig(struct I3cCntlr *cntlr, struct I3cConfig *config); 250 251 /** 252 * @brief Get the config of a I3C controller. 253 * 254 * @param cntlr Indicates the I3C controller device. 255 * @param config Indicates the pointer of the configuration structure. 256 * 257 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 258 * @since 1.0 259 */ 260 int32_t I3cCntlrGetConfig(struct I3cCntlr *cntlr, struct I3cConfig *config); 261 262 /** 263 * @brief Requeset an IBI(in-bind interrupt) for an I3C device which is supported. 264 * 265 * @param cntlr Indicates the I3C controller device. 266 * @param addr Indicates the address of device to requeset IBI(In-Band Interrupt). 267 * @param func Indicates the call back function of the IBI. 268 * @param payload Indicates the length of payload data, in bytes. 269 * 270 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 271 * @since 1.0 272 */ 273 int32_t I3cCntlrRequestIbi(struct I3cCntlr *cntlr, uint16_t addr, I3cIbiFunc func, uint32_t payload); 274 275 /** 276 * @brief Free the IBI(in-bind interrupt) which is Requeseted by {@link I3cCntlrRequestIbi}. 277 * 278 * @param cntlr Indicates the I3C controller device. 279 * @param addr Indicates the address of device to requeset IBI(In-Band Interrupt). 280 * 281 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 282 * @since 1.0 283 */ 284 int32_t I3cCntlrFreeIbi(struct I3cCntlr *cntlr, uint16_t addr); 285 286 /** 287 * @brief Send a CCC (Common Command Code) to an I3C device which is supported. 288 * 289 * @param cntlr Indicates the I3C controller device. 290 * @param ccc The pointer of CCC (Common Command Code) structure to send. 291 * 292 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 293 * @since 1.0 294 */ 295 int32_t I3cCntlrSendCccCmd(struct I3cCntlr *cntlr, struct I3cCccCmd *ccc); 296 297 /** 298 * @brief Execute one or more I3C messages in I2C mode. 299 * 300 * @param cntlr Indicates the I3C controller device. 301 * @param msgs Indicates the {@link I3cMsg} message array. 302 * @param count Indicates the length of the message array. 303 * 304 * @return Returns the number of transferred message structures on success; Returns a negative value otherwise. 305 * 306 * @see I3cMsg 307 * @since 1.0 308 */ 309 int32_t I3cCntlrI2cTransfer(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count); 310 311 /** 312 * @brief Execute one or more I3C messages in I3C mode. 313 * 314 * @param cntlr Indicates the I3C controller device. 315 * @param msgs Indicates the {@link I3cMsg} message array. 316 * @param count Indicates the length of the message array. 317 * 318 * @return Returns the number of transferred message structures on success; Returns a negative value otherwise. 319 * 320 * @see I3cMsg 321 * @since 1.0 322 */ 323 int32_t I3cCntlrTransfer(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count); 324 325 /** 326 * @brief Add an I3C device or an I2C device to device list. 327 * 328 * @param device Indicates the I3C device or I2C device. 329 * 330 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 331 * @since 1.0 332 */ 333 int32_t I3cDeviceAdd(struct I3cDevice *device); 334 335 /** 336 * @brief Remove an I3C device or an I2C device from device list. 337 * 338 * @param device Indicates the I3C device or I2C device. 339 * 340 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 341 * @since 1.0 342 */ 343 void I3cDeviceRemove(struct I3cDevice *device); 344 345 /** 346 * @brief Find and return an I3C controller by number, with ref count. 347 * 348 * @param number Indicates the I3C controller to get. 349 * 350 * @return Returns an I3C controller object on success; Returns <b>NULL</b> otherwise. 351 * 352 * @since 1.0 353 */ 354 struct I3cCntlr *I3cCntlrGet(int16_t number); 355 356 /** 357 * @brief Release an I3C controller obtained by {@link I3cCntlrGet}. 358 * 359 * @param number Indicates the I3C controller to get. 360 * 361 * @since 1.0 362 */ 363 void I3cCntlrPut(struct I3cCntlr *cntlr); 364 365 /** 366 * @brief Add an I3C controller to controller list. 367 * 368 * @param cntlr Indicates the I3C controller device. 369 * 370 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 371 * @since 1.0 372 */ 373 int32_t I3cCntlrAdd(struct I3cCntlr *cntlr); 374 375 /** 376 * @brief Remove an I3C controller from controller list. 377 * 378 * @param cntlr Indicates the I3C controller device. 379 * 380 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 381 * @since 1.0 382 */ 383 void I3cCntlrRemove(struct I3cCntlr *cntlr); 384 385 /** 386 * @brief Get an I3C device by addr. 387 * 388 * @param cntlr Indicates the I3C controller device. 389 * @param addr Indicates the address of the device which you would like to get. 390 * 391 * @return Returns <b>0</b> on success; Returns a negative value otherwise. 392 * @since 1.0 393 */ 394 struct I3cDevice *I3cGetDeviceByAddr(const struct I3cCntlr *cntlr, uint16_t addr); 395 396 /** 397 * @brief IBI(In-bind Interrupt) callback function. 398 * 399 * @param device Indicates the device that generated the IBI. 400 * 401 * @return Returns an I3C device object on success; Returns <b>NULL</b> otherwise. 402 * 403 * @since 1.0 404 */ 405 int32_t I3cCntlrIbiCallback(struct I3cDevice *device); 406 407 enum I3cIoCmd { 408 I3C_IO_I2C_TRANSFER = 0, 409 I3C_IO_PRIV_TRANSFER, 410 I3C_IO_OPEN, 411 I3C_IO_CLOSE, 412 I3C_IO_GET_CONFIG, 413 I3C_IO_SET_CONFIG, 414 I3C_IO_REQUEST_IBI, 415 I3C_IO_FREE_IBI, 416 }; 417 418 int I3cCheckReservedAddr(uint16_t addr); 419 420 #ifdef __cplusplus 421 #if __cplusplus 422 } 423 #endif 424 #endif /* __cplusplus */ 425 426 #endif /* I3C_CORE_H */ 427