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 #include "i3c_core.h"
10 #include "hdf_device_desc.h"
11 #include "hdf_log.h"
12 #include "osal_mem.h"
13 #include "osal_mutex.h"
14
15 #define I3C_SERVICE_NAME "HDF_PLATFORM_I3C_MANAGER"
16
17 struct I3cManager {
18 struct IDeviceIoService service;
19 struct HdfDeviceObject *device;
20 struct I3cCntlr *cntlrs[I3C_CNTLR_MAX];
21 struct OsalMutex lock;
22 };
23
24 static struct I3cManager *g_i3cManager = NULL;
25 static struct DListHead g_i3cDeviceList;
26 static OsalSpinlock g_listLock;
27
I3cCheckReservedAddr(uint16_t addr)28 int I3cCheckReservedAddr(uint16_t addr)
29 {
30 if ((addr == I3C_RESERVED_ADDR_7H00) || (addr == I3C_RESERVED_ADDR_7H01) ||
31 (addr == I3C_RESERVED_ADDR_7H02) || (addr == I3C_RESERVED_ADDR_7H3E) ||
32 (addr == I3C_RESERVED_ADDR_7H5E) || (addr == I3C_RESERVED_ADDR_7H6E) ||
33 (addr == I3C_RESERVED_ADDR_7H76) || (addr == I3C_RESERVED_ADDR_7H78) ||
34 (addr == I3C_RESERVED_ADDR_7H79) || (addr == I3C_RESERVED_ADDR_7H7A) ||
35 (addr == I3C_RESERVED_ADDR_7H7B) || (addr == I3C_RESERVED_ADDR_7H7C) ||
36 (addr == I3C_RESERVED_ADDR_7H7D) || (addr == I3C_RESERVED_ADDR_7H7E) ||
37 (addr == I3C_RESERVED_ADDR_7H7F)) {
38 return I3C_ADDR_RESERVED;
39 }
40 return I3C_ADDR_FREE;
41 }
42
I3cCntlrLockDefault(struct I3cCntlr * cntlr)43 static inline int32_t I3cCntlrLockDefault(struct I3cCntlr *cntlr)
44 {
45 if (cntlr == NULL) {
46 return HDF_ERR_DEVICE_BUSY;
47 }
48 return OsalSpinLock(&cntlr->lock);
49 }
50
I3cCntlrUnlockDefault(struct I3cCntlr * cntlr)51 static inline void I3cCntlrUnlockDefault(struct I3cCntlr *cntlr)
52 {
53 if (cntlr == NULL) {
54 return;
55 }
56 (void)OsalSpinUnlock(&cntlr->lock);
57 }
58
59 static const struct I3cLockMethod g_i3cLockOpsDefault = {
60 .lock = I3cCntlrLockDefault,
61 .unlock = I3cCntlrUnlockDefault,
62 };
63
I3cCntlrLock(struct I3cCntlr * cntlr)64 static inline int32_t I3cCntlrLock(struct I3cCntlr *cntlr)
65 {
66 if (cntlr->lockOps == NULL || cntlr->lockOps->lock == NULL) {
67 return HDF_ERR_NOT_SUPPORT;
68 }
69 return cntlr->lockOps->lock(cntlr);
70 }
71
I3cCntlrUnlock(struct I3cCntlr * cntlr)72 static inline void I3cCntlrUnlock(struct I3cCntlr *cntlr)
73 {
74 if (cntlr->lockOps != NULL && cntlr->lockOps->unlock != NULL) {
75 cntlr->lockOps->unlock(cntlr);
76 }
77 }
78
I3cDeviceListGet(void)79 static struct DListHead *I3cDeviceListGet(void)
80 {
81 static struct DListHead *head = NULL;
82
83 head = &g_i3cDeviceList;
84 while (OsalSpinLock(&g_listLock));
85
86 return head;
87 }
88
I3cDeviceListPut(void)89 static void I3cDeviceListPut(void)
90 {
91 (void)OsalSpinUnlock(&g_listLock);
92 }
93
GetAddrStatus(struct I3cCntlr * cntlr,uint16_t addr)94 static int32_t GetAddrStatus(struct I3cCntlr *cntlr, uint16_t addr)
95 {
96 int32_t status;
97
98 if (addr > I3C_ADDR_MAX) {
99 HDF_LOGE("%s: The address 0x%x exceeds the maximum address", __func__, addr);
100 return HDF_ERR_INVALID_PARAM;
101 }
102
103 status = ADDR_STATUS_MASK & ((cntlr->addrSlot[addr / ADDRS_PER_UINT16]) \
104 >> ((addr % ADDRS_PER_UINT16) * ADDRS_STATUS_BITS));
105
106 return status;
107 }
108
SetAddrStatus(struct I3cCntlr * cntlr,uint16_t addr,enum I3cAddrStatus status)109 static int32_t SetAddrStatus(struct I3cCntlr *cntlr, uint16_t addr, enum I3cAddrStatus status)
110 {
111 uint16_t temp;
112 int32_t ret;
113 uint16_t statusMask;
114
115 if (addr > I3C_ADDR_MAX) {
116 HDF_LOGE("%s: The address 0x%x exceeds the maximum address", __func__, addr);
117 return HDF_ERR_INVALID_PARAM;
118 }
119
120 if (cntlr == NULL) {
121 HDF_LOGE("%s: cntlr is NULL!", __func__);
122 return HDF_ERR_INVALID_PARAM;
123 }
124
125 ret = I3cCntlrLock(cntlr);
126 if (ret != HDF_SUCCESS) {
127 HDF_LOGE("%s: Lock cntlr failed!", __func__);
128 return ret;
129 }
130
131 statusMask = ADDR_STATUS_MASK << ((addr % ADDRS_PER_UINT16) * ADDRS_STATUS_BITS);
132 temp = (cntlr->addrSlot[addr / (uint16_t)ADDRS_PER_UINT16]) & (uint16_t)~statusMask;
133 temp |= (uint16_t)(((uint16_t)status) << ((addr % ADDRS_PER_UINT16) * ADDRS_STATUS_BITS));
134 cntlr->addrSlot[addr / ADDRS_PER_UINT16] = temp;
135
136 I3cCntlrUnlock(cntlr);
137
138 return HDF_SUCCESS;
139 }
140
I3cInitAddrStatus(struct I3cCntlr * cntlr)141 static void inline I3cInitAddrStatus(struct I3cCntlr *cntlr)
142 {
143 uint16_t addr;
144
145 for (addr = 0; addr <= I3C_ADDR_MAX; addr++) {
146 if (I3cCheckReservedAddr(addr) == I3C_ADDR_RESERVED) {
147 (void)SetAddrStatus(cntlr, addr, I3C_ADDR_RESERVED);
148 }
149 }
150 }
151
GetFreeAddr(struct I3cCntlr * cntlr)152 static int32_t GetFreeAddr(struct I3cCntlr *cntlr)
153 {
154 enum I3cAddrStatus status;
155 int16_t count;
156 int32_t ret;
157
158 if (cntlr == NULL) {
159 HDF_LOGE("%s: cntlr is NULL!", __func__);
160 return HDF_ERR_INVALID_PARAM;
161 }
162
163 ret = I3cCntlrLock(cntlr);
164 if (ret != HDF_SUCCESS) {
165 HDF_LOGE("%s: Lock cntlr failed!", __func__);
166 return ret;
167 }
168
169 for (count = 0; count <= I3C_ADDR_MAX; count++) {
170 status = (enum I3cAddrStatus)GetAddrStatus(cntlr, count);
171 if (status == I3C_ADDR_FREE) {
172 return (int32_t)count;
173 }
174 }
175 I3cCntlrUnlock(cntlr);
176 HDF_LOGE("%s: No free addresses left!", __func__);
177
178 return HDF_FAILURE;
179 }
180
I3cCntlrSendCccCmd(struct I3cCntlr * cntlr,struct I3cCccCmd * ccc)181 int32_t I3cCntlrSendCccCmd(struct I3cCntlr *cntlr, struct I3cCccCmd *ccc)
182 {
183 int32_t ret;
184
185 if (ccc == NULL) {
186 HDF_LOGE("%s: ccc is NULL!", __func__);
187 return HDF_ERR_INVALID_PARAM;
188 }
189
190 if (cntlr->ops == NULL || cntlr->ops->sendCccCmd == NULL) {
191 HDF_LOGE("%s: ops or sendCccCmd is null", __func__);
192 return HDF_ERR_NOT_SUPPORT;
193 }
194
195 if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
196 HDF_LOGE("%s: lock controller fail!", __func__);
197 return HDF_ERR_DEVICE_BUSY;
198 }
199
200 ret = cntlr->ops->sendCccCmd(cntlr, ccc);
201 I3cCntlrUnlock(cntlr);
202
203 return ret;
204 }
205
GetDeviceByAddr(struct I3cCntlr * cntlr,uint16_t addr)206 struct I3cDevice *GetDeviceByAddr(struct I3cCntlr *cntlr, uint16_t addr)
207 {
208 struct DListHead *head = NULL;
209 struct I3cDevice *pos = NULL;
210 struct I3cDevice *tmp = NULL;
211 enum I3cAddrStatus addrStatus;
212
213 if (addr > I3C_ADDR_MAX) {
214 HDF_LOGE("%s: The address 0x%x exceeds the maximum address", __func__, addr);
215 return NULL;
216 }
217 addrStatus = GetAddrStatus(cntlr, addr);
218 if (addrStatus == I3C_ADDR_FREE) {
219 HDF_LOGE("%s: The addr 0x%x is unavailable", __func__, addr);
220 return NULL;
221 }
222 if (addrStatus == I3C_ADDR_RESERVED) {
223 HDF_LOGE("%s: The addr 0x%x is reserved", __func__, addr);
224 return NULL;
225 }
226
227 if (addrStatus == I3C_ADDR_I2C_DEVICE || addrStatus == I3C_ADDR_I3C_DEVICE) {
228 head = I3cDeviceListGet();
229 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, head, struct I3cDevice, list) {
230 if ((pos->dynaAddr == addr) && (pos->cntlr == cntlr)) {
231 I3cDeviceListPut();
232 HDF_LOGI("%s: found by dynaAddr,done!", __func__);
233 return pos;
234 } else if ((!pos->dynaAddr) && (pos->addr == addr) && (pos->cntlr == cntlr)) {
235 HDF_LOGI("%s: found by Addr,done!", __func__);
236 I3cDeviceListPut();
237 return pos;
238 }
239 }
240 }
241 HDF_LOGE("%s: No such device found! addr: 0x%x", __func__, addr);
242
243 return NULL;
244 }
245
I3cDeviceDefineI3cDevices(struct I3cDevice * device)246 static int32_t I3cDeviceDefineI3cDevices(struct I3cDevice *device)
247 {
248 int32_t ret, addr;
249
250 ret = SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_I3C_DEVICE);
251 if (ret != HDF_SUCCESS) {
252 addr = GetFreeAddr(device->cntlr);
253 if (addr <= 0) {
254 HDF_LOGE("%s: No free addresses left!", __func__);
255 return HDF_ERR_DEVICE_BUSY;
256 }
257 ret = SetAddrStatus(device->cntlr, (uint16_t)addr, I3C_ADDR_I3C_DEVICE);
258 if (ret != HDF_SUCCESS) {
259 HDF_LOGE("%s: Add I3C device failed!", __func__);
260 return ret;
261 }
262 }
263
264 return HDF_SUCCESS;
265 }
266
I3cDeviceAdd(struct I3cDevice * device)267 int32_t I3cDeviceAdd(struct I3cDevice *device)
268 {
269 struct DListHead *head = NULL;
270 struct I3cDevice *pos = NULL;
271 struct I3cDevice *tmp = NULL;
272 int32_t ret;
273
274 if ((device == NULL) || (GetAddrStatus(device->cntlr, device->addr) != I3C_ADDR_FREE)) {
275 HDF_LOGE("%s: device or addr is unavailable", __func__);
276 return HDF_ERR_INVALID_OBJECT;
277 }
278 if (device->type == I3C_CNTLR_I2C_DEVICE || device->type == I3C_CNTLR_I2C_LEGACY_DEVICE) {
279 ret = SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_I2C_DEVICE);
280 if (ret != HDF_SUCCESS) {
281 HDF_LOGE("%s: Add I2C device failed!", __func__);
282 return ret;
283 }
284 } else {
285 ret = I3cDeviceDefineI3cDevices(device);
286 if (ret != HDF_SUCCESS) {
287 HDF_LOGE("%s: I3c DEFSLVS error!", __func__);
288 return ret;
289 }
290 }
291 head = I3cDeviceListGet();
292 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, head, struct I3cDevice, list) {
293 if (pos == NULL) { // empty list
294 break;
295 }
296 if ((pos->pid == device->pid) && (pos->cntlr == device->cntlr)) {
297 I3cDeviceListPut();
298 HDF_LOGE("%s: device already existed!: 0x%llx", __func__, device->pid);
299 (void)SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_RESERVED);
300 return HDF_ERR_IO;
301 }
302 }
303 DListHeadInit(&device->list);
304 DListInsertTail(&device->list, head);
305 I3cDeviceListPut();
306 HDF_LOGI("%s: done!", __func__);
307
308 return HDF_SUCCESS;
309 }
310
I3cDeviceRemove(struct I3cDevice * device)311 void I3cDeviceRemove(struct I3cDevice *device)
312 {
313 int32_t ret;
314 if (device == NULL) {
315 return;
316 }
317
318 ret = SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_RESERVED);
319 if (ret != HDF_SUCCESS) {
320 return;
321 }
322 (void)I3cDeviceListGet();
323 DListRemove(&device->list);
324 I3cDeviceListPut();
325 }
326
I3cManagerAddCntlr(struct I3cCntlr * cntlr)327 static int32_t I3cManagerAddCntlr(struct I3cCntlr *cntlr)
328 {
329 int32_t ret;
330 struct I3cManager *manager = g_i3cManager;
331
332 if (cntlr->busId >= I3C_CNTLR_MAX) {
333 HDF_LOGE("%s: busId:%d exceed!", __func__, cntlr->busId);
334 return HDF_ERR_INVALID_PARAM;
335 }
336
337 if (manager == NULL) {
338 HDF_LOGE("%s: get i3c manager fail!", __func__);
339 return HDF_ERR_NOT_SUPPORT;
340 }
341
342 if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
343 HDF_LOGE("%s: lock i3c manager fail!", __func__);
344 return HDF_ERR_DEVICE_BUSY;
345 }
346
347 if (manager->cntlrs[cntlr->busId] != NULL) {
348 HDF_LOGE("%s: cntlr of bus:%d already exits!", __func__, cntlr->busId);
349 ret = HDF_FAILURE;
350 } else {
351 manager->cntlrs[cntlr->busId] = cntlr;
352 ret = HDF_SUCCESS;
353 }
354 (void)OsalMutexUnlock(&manager->lock);
355
356 return ret;
357 }
358
I3cManagerRemoveCntlr(struct I3cCntlr * cntlr)359 static void I3cManagerRemoveCntlr(struct I3cCntlr *cntlr)
360 {
361 struct I3cManager *manager = g_i3cManager;
362
363 if (cntlr->busId < 0 || cntlr->busId >= I3C_CNTLR_MAX) {
364 HDF_LOGE("%s: invalid busId:%d!", __func__, cntlr->busId);
365 return;
366 }
367
368 if (manager == NULL) {
369 HDF_LOGE("%s: get i3c manager fail!", __func__);
370 return;
371 }
372 if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
373 HDF_LOGE("%s: lock i3c manager fail!", __func__);
374 return;
375 }
376
377 if (manager->cntlrs[cntlr->busId] != cntlr) {
378 HDF_LOGE("%s: cntlr(%d) not in manager!", __func__, cntlr->busId);
379 } else {
380 manager->cntlrs[cntlr->busId] = NULL;
381 }
382
383 (void)OsalMutexUnlock(&manager->lock);
384 }
385
I3cCntlrGet(int16_t number)386 struct I3cCntlr *I3cCntlrGet(int16_t number)
387 {
388 struct I3cCntlr *cntlr = NULL;
389 struct I3cManager *manager = g_i3cManager;
390
391 if (number < 0 || number >= I3C_CNTLR_MAX) {
392 HDF_LOGE("%s: invalid busId:%d!", __func__, number);
393 return NULL;
394 }
395
396 if (manager == NULL) {
397 HDF_LOGE("%s: get i3c manager fail!", __func__);
398 return NULL;
399 }
400
401 if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
402 HDF_LOGE("%s: lock i3c manager fail!", __func__);
403 return NULL;
404 }
405 cntlr = manager->cntlrs[number];
406 (void)OsalMutexUnlock(&manager->lock);
407
408 return cntlr;
409 }
410
I3cCntlrPut(struct I3cCntlr * cntlr)411 void I3cCntlrPut(struct I3cCntlr *cntlr)
412 {
413 (void)cntlr;
414 }
415
I3cCntlrAdd(struct I3cCntlr * cntlr)416 int32_t I3cCntlrAdd(struct I3cCntlr *cntlr)
417 {
418 int32_t ret;
419
420 if (cntlr == NULL) {
421 return HDF_ERR_INVALID_OBJECT;
422 }
423
424 if (cntlr->ops == NULL) {
425 HDF_LOGE("%s: no ops supplied!", __func__);
426 return HDF_ERR_INVALID_OBJECT;
427 }
428
429 if (cntlr->lockOps == NULL) {
430 HDF_LOGI("%s: use default lock methods!", __func__);
431 cntlr->lockOps = &g_i3cLockOpsDefault;
432 }
433
434 if (OsalSpinInit(&cntlr->lock) != HDF_SUCCESS) {
435 HDF_LOGE("%s: init lock fail!", __func__);
436 return HDF_FAILURE;
437 }
438
439 I3cInitAddrStatus(cntlr);
440 ret = I3cManagerAddCntlr(cntlr);
441 if (ret != HDF_SUCCESS) {
442 (void)OsalSpinDestroy(&cntlr->lock);
443 return ret;
444 }
445
446 return HDF_SUCCESS;
447 }
448
I3cCntlrRemove(struct I3cCntlr * cntlr)449 void I3cCntlrRemove(struct I3cCntlr *cntlr)
450 {
451 if (cntlr == NULL) {
452 return;
453 }
454 I3cManagerRemoveCntlr(cntlr);
455 (void)OsalSpinDestroy(&cntlr->lock);
456 }
457
I3cCntlrTransfer(struct I3cCntlr * cntlr,struct I3cMsg * msgs,int16_t count)458 int32_t I3cCntlrTransfer(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count)
459 {
460 int32_t ret;
461
462 if (cntlr == NULL) {
463 HDF_LOGE("%s: cntlr is NULL!", __func__);
464 return HDF_ERR_INVALID_OBJECT;
465 }
466
467 if (cntlr->ops == NULL || cntlr->ops->Transfer == NULL) {
468 HDF_LOGE("%s: ops or i3transfer is null", __func__);
469 return HDF_ERR_NOT_SUPPORT;
470 }
471
472 if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
473 HDF_LOGE("%s: lock controller fail!", __func__);
474 return HDF_ERR_DEVICE_BUSY;
475 }
476
477 ret = cntlr->ops->Transfer(cntlr, msgs, count);
478 I3cCntlrUnlock(cntlr);
479
480 return ret;
481 }
482
I3cCntlrI2cTransfer(struct I3cCntlr * cntlr,struct I3cMsg * msgs,int16_t count)483 int32_t I3cCntlrI2cTransfer(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count)
484 {
485 int32_t ret;
486
487 if (cntlr == NULL) {
488 HDF_LOGE("%s: cntlr is NULL!", __func__);
489 return HDF_ERR_INVALID_OBJECT;
490 }
491
492 if (cntlr->ops == NULL || cntlr->ops->i2cTransfer == NULL) {
493 HDF_LOGE("%s: ops or i2ctransfer is null", __func__);
494 return HDF_ERR_NOT_SUPPORT;
495 }
496
497 if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
498 HDF_LOGE("%s: lock controller fail!", __func__);
499 return HDF_ERR_DEVICE_BUSY;
500 }
501 ret = cntlr->ops->i2cTransfer(cntlr, msgs, count);
502 I3cCntlrUnlock(cntlr);
503
504 return ret;
505 }
506
I3cCntlrSetConfig(struct I3cCntlr * cntlr,struct I3cConfig * config)507 int32_t I3cCntlrSetConfig(struct I3cCntlr *cntlr, struct I3cConfig *config)
508 {
509 int32_t ret;
510
511 if (cntlr == NULL) {
512 HDF_LOGE("%s: cntlr is NULL!", __func__);
513 return HDF_ERR_INVALID_OBJECT;
514 }
515
516 if (config == NULL) {
517 HDF_LOGE("%s: config is NULL!", __func__);
518 return HDF_ERR_INVALID_PARAM;
519 }
520
521 if (cntlr->ops == NULL || cntlr->ops->setConfig == NULL) {
522 HDF_LOGE("%s: ops or setConfig is NULL!", __func__);
523 return HDF_ERR_NOT_SUPPORT;
524 }
525
526 if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
527 HDF_LOGE("%s: lock controller fail!", __func__);
528 return HDF_ERR_DEVICE_BUSY;
529 }
530
531 ret = cntlr->ops->setConfig(cntlr, config);
532 cntlr->config = *config;
533 I3cCntlrUnlock(cntlr);
534
535 return ret;
536 }
537
I3cCntlrGetConfig(struct I3cCntlr * cntlr,struct I3cConfig * config)538 int32_t I3cCntlrGetConfig(struct I3cCntlr *cntlr, struct I3cConfig *config)
539 {
540 int32_t ret;
541
542 if (cntlr == NULL) {
543 HDF_LOGE("%s: cntlr is NULL!", __func__);
544 return HDF_ERR_INVALID_OBJECT;
545 }
546
547 if (config == NULL) {
548 HDF_LOGE("%s: config is NULL!", __func__);
549 return HDF_ERR_INVALID_PARAM;
550 }
551
552 if (cntlr->ops == NULL || cntlr->ops->getConfig == NULL) {
553 HDF_LOGE("%s: ops or getConfig is NULL!", __func__);
554 return HDF_ERR_NOT_SUPPORT;
555 }
556
557 if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
558 HDF_LOGE("%s: lock controller fail!", __func__);
559 return HDF_ERR_DEVICE_BUSY;
560 }
561
562 ret = cntlr->ops->getConfig(cntlr, config);
563 cntlr->config = *config;
564 I3cCntlrUnlock(cntlr);
565
566 return ret;
567 }
568
I3cCntlrRequestIbi(struct I3cCntlr * cntlr,uint16_t addr,I3cIbiFunc func,uint32_t payload)569 int32_t I3cCntlrRequestIbi(struct I3cCntlr *cntlr, uint16_t addr, I3cIbiFunc func, uint32_t payload)
570 {
571 struct I3cDevice *device = NULL;
572 struct I3cIbiInfo *ibi = NULL;
573 uint16_t ptr;
574 int32_t ret;
575
576 if (cntlr == NULL) {
577 return HDF_ERR_INVALID_OBJECT;
578 }
579 if (cntlr->ops == NULL || cntlr->ops->requestIbi == NULL) {
580 HDF_LOGE("%s: Not support!", __func__);
581 return HDF_ERR_NOT_SUPPORT;
582 }
583 if ((func == NULL) || (addr >= I3C_ADDR_MAX)) {
584 HDF_LOGE("%s: invalid func or addr!", __func__);
585 return HDF_ERR_INVALID_PARAM;
586 }
587 device = GetDeviceByAddr(cntlr, addr);
588 if (device == NULL) {
589 HDF_LOGE("%s: Get device failed!", __func__);
590 return HDF_ERR_INVALID_OBJECT;
591 }
592 if (device->supportIbi != I3C_DEVICE_SUPPORT_IBI) {
593 HDF_LOGE("%s: not support!", __func__);
594 return HDF_ERR_NOT_SUPPORT;
595 }
596 if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
597 HDF_LOGE("%s: lock controller fail!", __func__);
598 return HDF_ERR_DEVICE_BUSY;
599 }
600
601 for (ptr = 0; ptr < I3C_IBI_MAX; ptr++) {
602 if (cntlr->ibiSlot[ptr] != NULL) {
603 continue;
604 }
605 ibi = (struct I3cIbiInfo *)OsalMemCalloc(sizeof(*ibi));
606 if (ibi == NULL) {
607 HDF_LOGE("func:%s ibi is NULL!", __func__);
608 return HDF_ERR_MALLOC_FAIL;
609 }
610 ibi->ibiFunc = func;
611 ibi->payload = payload;
612 ibi->data = (uint8_t *)OsalMemCalloc(sizeof(uint8_t) * payload);
613 device->ibi = ibi;
614 cntlr->ibiSlot[ptr] = device->ibi;
615 ret = cntlr->ops->requestIbi(device);
616 I3cCntlrUnlock(cntlr);
617 return ret;
618 }
619 I3cCntlrUnlock(cntlr);
620
621 return HDF_ERR_DEVICE_BUSY;
622 }
623
I3cCntlrFreeIbi(struct I3cCntlr * cntlr,uint16_t addr)624 int32_t I3cCntlrFreeIbi(struct I3cCntlr *cntlr, uint16_t addr)
625 {
626 struct I3cDevice *device = NULL;
627 uint16_t ptr;
628
629 if (cntlr == NULL) {
630 return HDF_ERR_INVALID_OBJECT;
631 }
632
633 if (addr >= I3C_ADDR_MAX) {
634 HDF_LOGE("%s: Invalid addr: %x", __func__, addr);
635 return HDF_ERR_INVALID_PARAM;
636 }
637
638 device = GetDeviceByAddr(cntlr, addr);
639 if (device == NULL) {
640 HDF_LOGE("%s: Get device failed!", __func__);
641 return HDF_ERR_INVALID_OBJECT;
642 }
643
644 for (ptr = 0; ptr < I3C_IBI_MAX; ptr++) {
645 if (cntlr->ibiSlot[ptr] == NULL || device->ibi == NULL) {
646 break;
647 }
648 if (cntlr->ibiSlot[ptr] != device->ibi) {
649 break;
650 }
651 cntlr->ibiSlot[ptr] = NULL;
652 if (device->ibi->data != NULL) {
653 OsalMemFree(device->ibi->data);
654 }
655 OsalMemFree(device->ibi);
656 device->ibi = NULL;
657 break;
658 }
659
660 return HDF_SUCCESS;
661 }
662
I3cCntlrIbiCallback(struct I3cDevice * device)663 int32_t I3cCntlrIbiCallback(struct I3cDevice *device)
664 {
665 struct I3cIbiData *ibiData = NULL;
666
667 if (device == NULL) {
668 HDF_LOGW("%s: invalid device!", __func__);
669 return HDF_ERR_INVALID_PARAM;
670 }
671
672 ibiData = (struct I3cIbiData *)OsalMemCalloc(sizeof(*ibiData));
673 if (ibiData == NULL) {
674 HDF_LOGE("%s: Memcalloc failed", __func__);
675 return HDF_ERR_MALLOC_FAIL;
676 }
677
678 ibiData->buf = device->ibi->data;
679 ibiData->payload = device->ibi->payload;
680
681 if (device->ibi->ibiFunc == NULL) {
682 HDF_LOGW("%s: device->ibi or ibiFunc is NULL!", __func__);
683 return HDF_ERR_NOT_SUPPORT;
684 }
685
686 if (device->dynaAddr != 0) {
687 (void)device->ibi->ibiFunc(device->cntlr, device->dynaAddr, *ibiData);
688 OsalMemFree(ibiData);
689 } else {
690 (void)device->ibi->ibiFunc(device->cntlr, device->addr, *ibiData);
691 OsalMemFree(ibiData);
692 }
693
694 return HDF_SUCCESS;
695 }
696
I3cManagerBind(struct HdfDeviceObject * device)697 static int32_t I3cManagerBind(struct HdfDeviceObject *device)
698 {
699 (void)device;
700 HDF_LOGI("%s:Enter!", __func__);
701 return HDF_SUCCESS;
702 }
703
I3cManagerInit(struct HdfDeviceObject * device)704 static int32_t I3cManagerInit(struct HdfDeviceObject *device)
705 {
706 int32_t ret;
707 struct I3cManager *manager = NULL;
708
709 HDF_LOGI("%s: Enter!", __func__);
710 if (device == NULL) {
711 HDF_LOGE("%s: device is NULL", __func__);
712 return HDF_ERR_INVALID_OBJECT;
713 }
714
715 manager = (struct I3cManager *)OsalMemCalloc(sizeof(*manager));
716 if (manager == NULL) {
717 HDF_LOGE("%s: malloc manager fail!", __func__);
718 return HDF_ERR_MALLOC_FAIL;
719 }
720
721 ret = OsalMutexInit(&manager->lock);
722 if (ret != HDF_SUCCESS) {
723 HDF_LOGE("%s: mutex init fail:%d", __func__, ret);
724 OsalMemFree(manager);
725 return HDF_FAILURE;
726 }
727 manager->device = device;
728 g_i3cManager = manager;
729 DListHeadInit(&g_i3cDeviceList);
730 OsalSpinInit(&g_listLock);
731
732 return HDF_SUCCESS;
733 }
734
I3cManagerRelease(struct HdfDeviceObject * device)735 static void I3cManagerRelease(struct HdfDeviceObject *device)
736 {
737 struct I3cManager *manager = NULL;
738
739 HDF_LOGI("%s: enter", __func__);
740 if (device == NULL) {
741 HDF_LOGI("%s: device is null", __func__);
742 return;
743 }
744 manager = (struct I3cManager *)device->service;
745 if (manager == NULL) {
746 HDF_LOGI("%s: no service binded!", __func__);
747 return;
748 }
749 g_i3cManager = NULL;
750 OsalMemFree(manager);
751 }
752
753 struct HdfDriverEntry g_i3cManagerEntry = {
754 .moduleVersion = 1,
755 .Bind = I3cManagerBind,
756 .Init = I3cManagerInit,
757 .Release = I3cManagerRelease,
758 .moduleName = "HDF_PLATFORM_I3C_MANAGER",
759 };
760 HDF_INIT(g_i3cManagerEntry);
761