1 /*
2 * Copyright (c) 2021-2023 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(const struct I3cCntlr * cntlr,uint16_t addr)94 static int32_t GetAddrStatus(const 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
I3cGetDeviceByAddr(const struct I3cCntlr * cntlr,uint16_t addr)206 struct I3cDevice *I3cGetDeviceByAddr(const 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;
249 int32_t addr;
250
251 ret = SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_I3C_DEVICE);
252 if (ret != HDF_SUCCESS) {
253 addr = GetFreeAddr(device->cntlr);
254 if (addr <= 0) {
255 HDF_LOGE("%s: No free addresses left!", __func__);
256 return HDF_ERR_DEVICE_BUSY;
257 }
258 ret = SetAddrStatus(device->cntlr, (uint16_t)addr, I3C_ADDR_I3C_DEVICE);
259 if (ret != HDF_SUCCESS) {
260 HDF_LOGE("%s: Add I3C device failed!", __func__);
261 return ret;
262 }
263 }
264
265 return HDF_SUCCESS;
266 }
267
I3cDeviceAdd(struct I3cDevice * device)268 int32_t I3cDeviceAdd(struct I3cDevice *device)
269 {
270 struct DListHead *head = NULL;
271 struct I3cDevice *pos = NULL;
272 struct I3cDevice *tmp = NULL;
273 int32_t ret;
274
275 if ((device == NULL) || (GetAddrStatus(device->cntlr, device->addr) != I3C_ADDR_FREE)) {
276 HDF_LOGE("%s: device or addr is unavailable", __func__);
277 return HDF_ERR_INVALID_OBJECT;
278 }
279 if (device->type == I3C_CNTLR_I2C_DEVICE || device->type == I3C_CNTLR_I2C_LEGACY_DEVICE) {
280 ret = SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_I2C_DEVICE);
281 if (ret != HDF_SUCCESS) {
282 HDF_LOGE("%s: Add I2C device failed!", __func__);
283 return ret;
284 }
285 } else {
286 ret = I3cDeviceDefineI3cDevices(device);
287 if (ret != HDF_SUCCESS) {
288 HDF_LOGE("%s: I3c DEFSLVS error!", __func__);
289 return ret;
290 }
291 }
292 head = I3cDeviceListGet();
293 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, head, struct I3cDevice, list) {
294 if (pos == NULL) { // empty list
295 break;
296 }
297 if ((pos->pid == device->pid) && (pos->cntlr == device->cntlr)) {
298 I3cDeviceListPut();
299 HDF_LOGE("%s: device already existed!: 0x%llx", __func__, device->pid);
300 (void)SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_RESERVED);
301 return HDF_ERR_IO;
302 }
303 }
304 DListHeadInit(&device->list);
305 DListInsertTail(&device->list, head);
306 I3cDeviceListPut();
307 HDF_LOGI("%s: done!", __func__);
308
309 return HDF_SUCCESS;
310 }
311
I3cDeviceRemove(struct I3cDevice * device)312 void I3cDeviceRemove(struct I3cDevice *device)
313 {
314 int32_t ret;
315 if (device == NULL) {
316 return;
317 }
318
319 ret = SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_RESERVED);
320 if (ret != HDF_SUCCESS) {
321 return;
322 }
323 (void)I3cDeviceListGet();
324 DListRemove(&device->list);
325 I3cDeviceListPut();
326 }
327
I3cManagerAddCntlr(struct I3cCntlr * cntlr)328 static int32_t I3cManagerAddCntlr(struct I3cCntlr *cntlr)
329 {
330 int32_t ret;
331 struct I3cManager *manager = g_i3cManager;
332
333 if (cntlr->busId >= I3C_CNTLR_MAX) {
334 HDF_LOGE("%s: busId:%d exceed!", __func__, cntlr->busId);
335 return HDF_ERR_INVALID_PARAM;
336 }
337
338 if (manager == NULL) {
339 HDF_LOGE("%s: get i3c manager fail!", __func__);
340 return HDF_ERR_NOT_SUPPORT;
341 }
342
343 if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
344 HDF_LOGE("%s: lock i3c manager fail!", __func__);
345 return HDF_ERR_DEVICE_BUSY;
346 }
347
348 if (manager->cntlrs[cntlr->busId] != NULL) {
349 HDF_LOGE("%s: cntlr of bus:%hd already exits!", __func__, cntlr->busId);
350 ret = HDF_FAILURE;
351 } else {
352 manager->cntlrs[cntlr->busId] = cntlr;
353 ret = HDF_SUCCESS;
354 }
355 (void)OsalMutexUnlock(&manager->lock);
356
357 return ret;
358 }
359
I3cManagerRemoveCntlr(struct I3cCntlr * cntlr)360 static void I3cManagerRemoveCntlr(struct I3cCntlr *cntlr)
361 {
362 struct I3cManager *manager = g_i3cManager;
363
364 if (cntlr->busId < 0 || cntlr->busId >= I3C_CNTLR_MAX) {
365 HDF_LOGE("%s: invalid busId:%hd!", __func__, cntlr->busId);
366 return;
367 }
368
369 if (manager == NULL) {
370 HDF_LOGE("%s: get i3c manager fail!", __func__);
371 return;
372 }
373 if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
374 HDF_LOGE("%s: lock i3c manager fail!", __func__);
375 return;
376 }
377
378 if (manager->cntlrs[cntlr->busId] != cntlr) {
379 HDF_LOGE("%s: cntlr(%hd) not in manager!", __func__, cntlr->busId);
380 } else {
381 manager->cntlrs[cntlr->busId] = NULL;
382 }
383
384 (void)OsalMutexUnlock(&manager->lock);
385 }
386
I3cCntlrGet(int16_t number)387 struct I3cCntlr *I3cCntlrGet(int16_t number)
388 {
389 struct I3cCntlr *cntlr = NULL;
390 struct I3cManager *manager = g_i3cManager;
391
392 if (number < 0 || number >= I3C_CNTLR_MAX) {
393 HDF_LOGE("%s: invalid busId:%hd!", __func__, number);
394 return NULL;
395 }
396
397 if (manager == NULL) {
398 HDF_LOGE("%s: get i3c manager fail!", __func__);
399 return NULL;
400 }
401
402 if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
403 HDF_LOGE("%s: lock i3c manager fail!", __func__);
404 return NULL;
405 }
406 cntlr = manager->cntlrs[number];
407 (void)OsalMutexUnlock(&manager->lock);
408
409 return cntlr;
410 }
411
I3cCntlrPut(struct I3cCntlr * cntlr)412 void I3cCntlrPut(struct I3cCntlr *cntlr)
413 {
414 (void)cntlr;
415 }
416
I3cCntlrAdd(struct I3cCntlr * cntlr)417 int32_t I3cCntlrAdd(struct I3cCntlr *cntlr)
418 {
419 int32_t ret;
420
421 if (cntlr == NULL) {
422 HDF_LOGE("%s: cntlr is NULL!", __func__);
423 return HDF_ERR_INVALID_OBJECT;
424 }
425
426 if (cntlr->ops == NULL) {
427 HDF_LOGE("%s: no ops supplied!", __func__);
428 return HDF_ERR_INVALID_OBJECT;
429 }
430
431 if (cntlr->lockOps == NULL) {
432 HDF_LOGI("%s: use default lock methods!", __func__);
433 cntlr->lockOps = &g_i3cLockOpsDefault;
434 }
435
436 if (OsalSpinInit(&cntlr->lock) != HDF_SUCCESS) {
437 HDF_LOGE("%s: init lock fail!", __func__);
438 return HDF_FAILURE;
439 }
440
441 I3cInitAddrStatus(cntlr);
442 ret = I3cManagerAddCntlr(cntlr);
443 if (ret != HDF_SUCCESS) {
444 (void)OsalSpinDestroy(&cntlr->lock);
445 return ret;
446 }
447
448 return HDF_SUCCESS;
449 }
450
I3cCntlrRemove(struct I3cCntlr * cntlr)451 void I3cCntlrRemove(struct I3cCntlr *cntlr)
452 {
453 if (cntlr == NULL) {
454 return;
455 }
456 I3cManagerRemoveCntlr(cntlr);
457 (void)OsalSpinDestroy(&cntlr->lock);
458 }
459
I3cCntlrTransfer(struct I3cCntlr * cntlr,struct I3cMsg * msgs,int16_t count)460 int32_t I3cCntlrTransfer(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count)
461 {
462 int32_t ret;
463
464 if (cntlr == NULL) {
465 HDF_LOGE("%s: cntlr is NULL!", __func__);
466 return HDF_ERR_INVALID_OBJECT;
467 }
468
469 if (cntlr->ops == NULL || cntlr->ops->Transfer == NULL) {
470 HDF_LOGE("%s: ops or i3transfer is null", __func__);
471 return HDF_ERR_NOT_SUPPORT;
472 }
473
474 if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
475 HDF_LOGE("%s: lock controller fail!", __func__);
476 return HDF_ERR_DEVICE_BUSY;
477 }
478
479 ret = cntlr->ops->Transfer(cntlr, msgs, count);
480 I3cCntlrUnlock(cntlr);
481
482 return ret;
483 }
484
I3cCntlrI2cTransfer(struct I3cCntlr * cntlr,struct I3cMsg * msgs,int16_t count)485 int32_t I3cCntlrI2cTransfer(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count)
486 {
487 int32_t ret;
488
489 if (cntlr == NULL) {
490 HDF_LOGE("%s: cntlr is NULL!", __func__);
491 return HDF_ERR_INVALID_OBJECT;
492 }
493
494 if (cntlr->ops == NULL || cntlr->ops->i2cTransfer == NULL) {
495 HDF_LOGE("%s: ops or i2ctransfer is null", __func__);
496 return HDF_ERR_NOT_SUPPORT;
497 }
498
499 if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
500 HDF_LOGE("%s: lock controller fail!", __func__);
501 return HDF_ERR_DEVICE_BUSY;
502 }
503 ret = cntlr->ops->i2cTransfer(cntlr, msgs, count);
504 I3cCntlrUnlock(cntlr);
505
506 return ret;
507 }
508
I3cCntlrSetConfig(struct I3cCntlr * cntlr,struct I3cConfig * config)509 int32_t I3cCntlrSetConfig(struct I3cCntlr *cntlr, struct I3cConfig *config)
510 {
511 int32_t ret;
512
513 if (cntlr == NULL) {
514 HDF_LOGE("%s: cntlr is NULL!", __func__);
515 return HDF_ERR_INVALID_OBJECT;
516 }
517
518 if (config == NULL) {
519 HDF_LOGE("%s: config is NULL!", __func__);
520 return HDF_ERR_INVALID_PARAM;
521 }
522
523 if (cntlr->ops == NULL || cntlr->ops->setConfig == NULL) {
524 HDF_LOGE("%s: ops or setConfig is NULL!", __func__);
525 return HDF_ERR_NOT_SUPPORT;
526 }
527
528 if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
529 HDF_LOGE("%s: lock controller fail!", __func__);
530 return HDF_ERR_DEVICE_BUSY;
531 }
532
533 ret = cntlr->ops->setConfig(cntlr, config);
534 cntlr->config = *config;
535 I3cCntlrUnlock(cntlr);
536
537 return ret;
538 }
539
I3cCntlrGetConfig(struct I3cCntlr * cntlr,struct I3cConfig * config)540 int32_t I3cCntlrGetConfig(struct I3cCntlr *cntlr, struct I3cConfig *config)
541 {
542 int32_t ret;
543
544 if (cntlr == NULL) {
545 HDF_LOGE("%s: cntlr is NULL!", __func__);
546 return HDF_ERR_INVALID_OBJECT;
547 }
548
549 if (config == NULL) {
550 HDF_LOGE("%s: config is NULL!", __func__);
551 return HDF_ERR_INVALID_PARAM;
552 }
553
554 if (cntlr->ops == NULL || cntlr->ops->getConfig == NULL) {
555 HDF_LOGE("%s: ops or getConfig is NULL!", __func__);
556 return HDF_ERR_NOT_SUPPORT;
557 }
558
559 if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
560 HDF_LOGE("%s: lock controller fail!", __func__);
561 return HDF_ERR_DEVICE_BUSY;
562 }
563
564 ret = cntlr->ops->getConfig(cntlr, config);
565 cntlr->config = *config;
566 I3cCntlrUnlock(cntlr);
567
568 return ret;
569 }
570
I3cCntlrRequestIbi(struct I3cCntlr * cntlr,uint16_t addr,I3cIbiFunc func,uint32_t payload)571 int32_t I3cCntlrRequestIbi(struct I3cCntlr *cntlr, uint16_t addr, I3cIbiFunc func, uint32_t payload)
572 {
573 struct I3cDevice *device = NULL;
574 struct I3cIbiInfo *ibi = NULL;
575 uint16_t ptr;
576 int32_t ret;
577
578 if (cntlr == NULL) {
579 HDF_LOGE("%s: cntlr is NULL!", __func__);
580 return HDF_ERR_INVALID_OBJECT;
581 }
582 if (cntlr->ops == NULL || cntlr->ops->requestIbi == NULL) {
583 HDF_LOGE("%s: Not support!", __func__);
584 return HDF_ERR_NOT_SUPPORT;
585 }
586 if ((func == NULL) || (addr >= I3C_ADDR_MAX)) {
587 HDF_LOGE("%s: invalid func or addr!", __func__);
588 return HDF_ERR_INVALID_PARAM;
589 }
590 device = I3cGetDeviceByAddr(cntlr, addr);
591 if (device == NULL) {
592 HDF_LOGE("%s: Get device failed!", __func__);
593 return HDF_ERR_INVALID_OBJECT;
594 }
595 if (device->supportIbi != I3C_DEVICE_SUPPORT_IBI) {
596 HDF_LOGE("%s: not support!", __func__);
597 return HDF_ERR_NOT_SUPPORT;
598 }
599 if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
600 HDF_LOGE("%s: lock controller fail!", __func__);
601 return HDF_ERR_DEVICE_BUSY;
602 }
603
604 for (ptr = 0; ptr < I3C_IBI_MAX; ptr++) {
605 if (cntlr->ibiSlot[ptr] != NULL) {
606 continue;
607 }
608 ibi = (struct I3cIbiInfo *)OsalMemCalloc(sizeof(*ibi));
609 if (ibi == NULL) {
610 HDF_LOGE("func:%s ibi is NULL!", __func__);
611 return HDF_ERR_MALLOC_FAIL;
612 }
613 ibi->ibiFunc = func;
614 ibi->payload = payload;
615 ibi->data = (uint8_t *)OsalMemCalloc(sizeof(uint8_t) * payload);
616 device->ibi = ibi;
617 cntlr->ibiSlot[ptr] = device->ibi;
618 ret = cntlr->ops->requestIbi(device);
619 I3cCntlrUnlock(cntlr);
620 return ret;
621 }
622 I3cCntlrUnlock(cntlr);
623
624 return HDF_ERR_DEVICE_BUSY;
625 }
626
I3cCntlrFreeIbi(struct I3cCntlr * cntlr,uint16_t addr)627 int32_t I3cCntlrFreeIbi(struct I3cCntlr *cntlr, uint16_t addr)
628 {
629 struct I3cDevice *device = NULL;
630 uint16_t ptr;
631
632 if (cntlr == NULL) {
633 HDF_LOGE("%s: cntlr is NULL!", __func__);
634 return HDF_ERR_INVALID_OBJECT;
635 }
636
637 if (addr >= I3C_ADDR_MAX) {
638 HDF_LOGE("%s: Invalid addr: %x", __func__, addr);
639 return HDF_ERR_INVALID_PARAM;
640 }
641
642 device = I3cGetDeviceByAddr(cntlr, addr);
643 if (device == NULL || device->ibi == NULL) {
644 HDF_LOGE("%s: invaild device!", __func__);
645 return HDF_ERR_INVALID_OBJECT;
646 }
647
648 for (ptr = 0; ptr < I3C_IBI_MAX; ptr++) {
649 if (cntlr->ibiSlot[ptr] == NULL || cntlr->ibiSlot[ptr] != device->ibi) {
650 continue;
651 }
652 cntlr->ibiSlot[ptr] = NULL;
653 if (device->ibi->data != NULL) {
654 OsalMemFree(device->ibi->data);
655 }
656 OsalMemFree(device->ibi);
657 device->ibi = NULL;
658 break;
659 }
660
661 return HDF_SUCCESS;
662 }
663
I3cCntlrIbiCallback(struct I3cDevice * device)664 int32_t I3cCntlrIbiCallback(struct I3cDevice *device)
665 {
666 struct I3cIbiData *ibiData = NULL;
667
668 if (device == NULL) {
669 HDF_LOGW("%s: invalid device!", __func__);
670 return HDF_ERR_INVALID_PARAM;
671 }
672
673 ibiData = (struct I3cIbiData *)OsalMemCalloc(sizeof(*ibiData));
674 if (ibiData == NULL) {
675 HDF_LOGE("%s: Memcalloc failed", __func__);
676 return HDF_ERR_MALLOC_FAIL;
677 }
678
679 ibiData->buf = device->ibi->data;
680 ibiData->payload = device->ibi->payload;
681
682 if (device->ibi->ibiFunc == NULL) {
683 HDF_LOGW("%s: device->ibi or ibiFunc is NULL!", __func__);
684 OsalMemFree(ibiData);
685 return HDF_ERR_NOT_SUPPORT;
686 }
687
688 if (device->dynaAddr != 0) {
689 (void)device->ibi->ibiFunc(device->cntlr, device->dynaAddr, *ibiData);
690 OsalMemFree(ibiData);
691 } else {
692 (void)device->ibi->ibiFunc(device->cntlr, device->addr, *ibiData);
693 OsalMemFree(ibiData);
694 }
695
696 return HDF_SUCCESS;
697 }
698
I3cManagerBind(struct HdfDeviceObject * device)699 static int32_t I3cManagerBind(struct HdfDeviceObject *device)
700 {
701 (void)device;
702 HDF_LOGI("%s:Enter!", __func__);
703 return HDF_SUCCESS;
704 }
705
I3cManagerInit(struct HdfDeviceObject * device)706 static int32_t I3cManagerInit(struct HdfDeviceObject *device)
707 {
708 int32_t ret;
709 struct I3cManager *manager = NULL;
710
711 HDF_LOGI("%s: Enter!", __func__);
712 if (device == NULL) {
713 HDF_LOGE("%s: device is NULL", __func__);
714 return HDF_ERR_INVALID_OBJECT;
715 }
716
717 manager = (struct I3cManager *)OsalMemCalloc(sizeof(*manager));
718 if (manager == NULL) {
719 HDF_LOGE("%s: malloc manager fail!", __func__);
720 return HDF_ERR_MALLOC_FAIL;
721 }
722
723 ret = OsalMutexInit(&manager->lock);
724 if (ret != HDF_SUCCESS) {
725 HDF_LOGE("%s: mutex init fail:%d", __func__, ret);
726 OsalMemFree(manager);
727 return HDF_FAILURE;
728 }
729 manager->device = device;
730 g_i3cManager = manager;
731 DListHeadInit(&g_i3cDeviceList);
732 OsalSpinInit(&g_listLock);
733
734 return HDF_SUCCESS;
735 }
736
I3cManagerRelease(struct HdfDeviceObject * device)737 static void I3cManagerRelease(struct HdfDeviceObject *device)
738 {
739 struct I3cManager *manager = NULL;
740
741 HDF_LOGI("%s: enter", __func__);
742 if (device == NULL) {
743 HDF_LOGI("%s: device is null", __func__);
744 return;
745 }
746 manager = (struct I3cManager *)device->service;
747 if (manager == NULL) {
748 HDF_LOGI("%s: no service binded!", __func__);
749 return;
750 }
751 g_i3cManager = NULL;
752 OsalMemFree(manager);
753 }
754
755 struct HdfDriverEntry g_i3cManagerEntry = {
756 .moduleVersion = 1,
757 .Bind = I3cManagerBind,
758 .Init = I3cManagerInit,
759 .Release = I3cManagerRelease,
760 .moduleName = "HDF_PLATFORM_I3C_MANAGER",
761 };
762 HDF_INIT(g_i3cManagerEntry);
763