1 /*
2 * Copyright (c) 2022 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8 #include <stdlib.h>
9
10 #include <zephyr/toolchain.h>
11 #include <zephyr/sys/__assert.h>
12 #include <zephyr/sys/slist.h>
13 #include <zephyr/sys/byteorder.h>
14
15 #include <zephyr/drivers/i3c.h>
16
17 #include <zephyr/logging/log.h>
18 LOG_MODULE_REGISTER(i3c, CONFIG_I3C_LOG_LEVEL);
19
i3c_dump_msgs(const char * name,const struct i3c_msg * msgs,uint8_t num_msgs,struct i3c_device_desc * target)20 void i3c_dump_msgs(const char *name, const struct i3c_msg *msgs, uint8_t num_msgs,
21 struct i3c_device_desc *target)
22 {
23 LOG_DBG("I3C msg: %s, addr=%x", name, target->dynamic_addr);
24 for (unsigned int i = 0; i < num_msgs; i++) {
25 const struct i3c_msg *msg = &msgs[i];
26
27 LOG_DBG(" %c len=%02x: ", msg->flags & I3C_MSG_READ ? 'R' : 'W', msg->len);
28 if (!(msg->flags & I3C_MSG_READ)) {
29 LOG_HEXDUMP_DBG(msg->buf, msg->len, "contents:");
30 }
31 }
32 }
33
i3c_addr_slots_set(struct i3c_addr_slots * slots,uint8_t dev_addr,enum i3c_addr_slot_status status)34 void i3c_addr_slots_set(struct i3c_addr_slots *slots, uint8_t dev_addr,
35 enum i3c_addr_slot_status status)
36 {
37 int bitpos;
38 int idx;
39
40 __ASSERT_NO_MSG(slots != NULL);
41
42 if (dev_addr > I3C_MAX_ADDR) {
43 /* Invalid address. Do nothing. */
44 return;
45 }
46
47 bitpos = dev_addr * 2;
48 idx = bitpos / BITS_PER_LONG;
49 bitpos %= BITS_PER_LONG;
50
51 slots->slots[idx] &= ~((unsigned long)I3C_ADDR_SLOT_STATUS_MASK << bitpos);
52 slots->slots[idx] |= status << bitpos;
53 }
54
i3c_addr_slots_status(struct i3c_addr_slots * slots,uint8_t dev_addr)55 enum i3c_addr_slot_status i3c_addr_slots_status(struct i3c_addr_slots *slots, uint8_t dev_addr)
56 {
57 unsigned long status;
58 int bitpos;
59 int idx;
60
61 __ASSERT_NO_MSG(slots != NULL);
62
63 if (dev_addr > I3C_MAX_ADDR) {
64 /* Invalid address.
65 * Simply says it's reserved so it will not be
66 * used for anything.
67 */
68 return I3C_ADDR_SLOT_STATUS_RSVD;
69 }
70
71 bitpos = dev_addr * 2;
72 idx = bitpos / BITS_PER_LONG;
73 bitpos %= BITS_PER_LONG;
74
75 status = slots->slots[idx] >> bitpos;
76 status &= I3C_ADDR_SLOT_STATUS_MASK;
77
78 return status;
79 }
80
i3c_addr_slots_init(const struct device * dev)81 int i3c_addr_slots_init(const struct device *dev)
82 {
83 struct i3c_driver_data *data = (struct i3c_driver_data *)dev->data;
84 const struct i3c_driver_config *config = (const struct i3c_driver_config *)dev->config;
85 int i, ret = 0;
86 struct i3c_device_desc *i3c_dev;
87 struct i3c_i2c_device_desc *i2c_dev;
88
89 __ASSERT_NO_MSG(dev != NULL);
90
91 (void)memset(&data->attached_dev.addr_slots, 0, sizeof(data->attached_dev.addr_slots));
92 sys_slist_init(&data->attached_dev.devices.i3c);
93 sys_slist_init(&data->attached_dev.devices.i2c);
94
95 /* Address restrictions (ref 5.1.2.2.5, Specification for I3C v1.1.1) */
96 for (i = 0; i <= 7; i++) {
97 /* Addresses 0 to 7 are reserved */
98 i3c_addr_slots_set(&data->attached_dev.addr_slots, i, I3C_ADDR_SLOT_STATUS_RSVD);
99
100 /*
101 * Addresses within a single bit error of broadcast address
102 * are also reserved.
103 */
104 i3c_addr_slots_set(&data->attached_dev.addr_slots, I3C_BROADCAST_ADDR ^ BIT(i),
105 I3C_ADDR_SLOT_STATUS_RSVD);
106 }
107
108 /* The broadcast address is reserved */
109 i3c_addr_slots_set(&data->attached_dev.addr_slots, I3C_BROADCAST_ADDR,
110 I3C_ADDR_SLOT_STATUS_RSVD);
111
112 /*
113 * Mark all I2C addresses first.
114 */
115 for (i = 0; i < config->dev_list.num_i2c; i++) {
116 i2c_dev = &config->dev_list.i2c[i];
117 ret = i3c_attach_i2c_device(i2c_dev);
118 if (ret != 0) {
119 /* Address slot is not free */
120 ret = -EINVAL;
121 goto out;
122 }
123 }
124
125 /*
126 * If there is a static address for the I3C devices, check
127 * if this address is free, and there is no other devices of
128 * the same (pre-assigned) address on the bus.
129 */
130 for (i = 0; i < config->dev_list.num_i3c; i++) {
131 i3c_dev = &config->dev_list.i3c[i];
132 ret = i3c_attach_i3c_device(i3c_dev);
133 if (ret != 0) {
134 /* Address slot is not free */
135 ret = -EINVAL;
136 goto out;
137 }
138 }
139
140 out:
141 return ret;
142 }
143
i3c_addr_slots_is_free(struct i3c_addr_slots * slots,uint8_t dev_addr)144 bool i3c_addr_slots_is_free(struct i3c_addr_slots *slots, uint8_t dev_addr)
145 {
146 enum i3c_addr_slot_status status;
147
148 __ASSERT_NO_MSG(slots != NULL);
149
150 status = i3c_addr_slots_status(slots, dev_addr);
151
152 return (status == I3C_ADDR_SLOT_STATUS_FREE);
153 }
154
i3c_addr_slots_next_free_find(struct i3c_addr_slots * slots,uint8_t start_addr)155 uint8_t i3c_addr_slots_next_free_find(struct i3c_addr_slots *slots, uint8_t start_addr)
156 {
157 uint8_t addr;
158 enum i3c_addr_slot_status status;
159
160 /* Addresses 0 to 7 are reserved. So start at 8. */
161 for (addr = MAX(start_addr, 8); addr < I3C_MAX_ADDR; addr++) {
162 status = i3c_addr_slots_status(slots, addr);
163 if (status == I3C_ADDR_SLOT_STATUS_FREE) {
164 return addr;
165 }
166 }
167
168 return 0;
169 }
170
i3c_dev_list_find(const struct i3c_dev_list * dev_list,const struct i3c_device_id * id)171 struct i3c_device_desc *i3c_dev_list_find(const struct i3c_dev_list *dev_list,
172 const struct i3c_device_id *id)
173 {
174 int i;
175 struct i3c_device_desc *ret = NULL;
176
177 __ASSERT_NO_MSG(dev_list != NULL);
178
179 /* this only searches known I3C PIDs */
180 for (i = 0; i < dev_list->num_i3c; i++) {
181 struct i3c_device_desc *desc = &dev_list->i3c[i];
182
183 if (desc->pid == id->pid) {
184 ret = desc;
185 break;
186 }
187 }
188
189 return ret;
190 }
191
i3c_dev_list_i3c_addr_find(const struct device * dev,uint8_t addr)192 struct i3c_device_desc *i3c_dev_list_i3c_addr_find(const struct device *dev, uint8_t addr)
193 {
194 struct i3c_device_desc *ret = NULL;
195 struct i3c_device_desc *desc;
196
197 __ASSERT_NO_MSG(dev != NULL);
198
199 I3C_BUS_FOR_EACH_I3CDEV(dev, desc) {
200 if (desc->dynamic_addr == addr) {
201 ret = desc;
202 break;
203 }
204 }
205
206 return ret;
207 }
208
i3c_dev_list_i3c_static_addr_find(const struct device * dev,uint8_t addr)209 struct i3c_device_desc *i3c_dev_list_i3c_static_addr_find(const struct device *dev, uint8_t addr)
210 {
211 struct i3c_device_desc *ret = NULL;
212 struct i3c_device_desc *desc;
213
214 __ASSERT_NO_MSG(dev != NULL);
215
216 I3C_BUS_FOR_EACH_I3CDEV(dev, desc) {
217 if (desc->static_addr == addr) {
218 ret = desc;
219 break;
220 }
221 }
222
223 return ret;
224 }
225
i3c_dev_list_i2c_addr_find(const struct device * dev,uint16_t addr)226 struct i3c_i2c_device_desc *i3c_dev_list_i2c_addr_find(const struct device *dev, uint16_t addr)
227 {
228 struct i3c_i2c_device_desc *ret = NULL;
229 struct i3c_i2c_device_desc *desc;
230
231 __ASSERT_NO_MSG(dev != NULL);
232
233 I3C_BUS_FOR_EACH_I2CDEV(dev, desc) {
234 if (desc->addr == addr) {
235 ret = desc;
236 break;
237 }
238 }
239
240 return ret;
241 }
242
i3c_attach_i3c_device(struct i3c_device_desc * target)243 int i3c_attach_i3c_device(struct i3c_device_desc *target)
244 {
245 struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
246 const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
247 uint8_t addr = 0;
248 int status = 0;
249 struct i3c_device_desc *i3c_desc;
250
251 /* check to see if the device has already been attached */
252 I3C_BUS_FOR_EACH_I3CDEV(target->bus, i3c_desc) {
253 if (i3c_desc == target) {
254 return -EINVAL;
255 }
256 }
257
258 addr = target->dynamic_addr ? target->dynamic_addr : target->static_addr;
259
260 /*
261 * If it has a dynamic addr already assigned or a static address, check that it is free
262 */
263 if (addr) {
264 if (!i3c_addr_slots_is_free(&data->attached_dev.addr_slots, addr)) {
265 return -EINVAL;
266 }
267 }
268
269 sys_slist_append(&data->attached_dev.devices.i3c, &target->node);
270
271 if (api->attach_i3c_device != NULL) {
272 status = api->attach_i3c_device(target->bus, target);
273 }
274
275 if (addr) {
276 i3c_addr_slots_mark_i3c(&data->attached_dev.addr_slots, addr);
277 }
278
279 return status;
280 }
281
i3c_reattach_i3c_device(struct i3c_device_desc * target,uint8_t old_dyn_addr)282 int i3c_reattach_i3c_device(struct i3c_device_desc *target, uint8_t old_dyn_addr)
283 {
284 struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
285 const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
286 int status = 0;
287
288 if (!i3c_addr_slots_is_free(&data->attached_dev.addr_slots, target->dynamic_addr)) {
289 return -EINVAL;
290 }
291
292 if (api->reattach_i3c_device != NULL) {
293 status = api->reattach_i3c_device(target->bus, target, old_dyn_addr);
294 }
295
296 if (old_dyn_addr) {
297 /* mark the old address as free */
298 i3c_addr_slots_mark_free(&data->attached_dev.addr_slots, old_dyn_addr);
299 }
300
301 i3c_addr_slots_mark_i3c(&data->attached_dev.addr_slots, target->dynamic_addr);
302
303 return status;
304 }
305
i3c_detach_i3c_device(struct i3c_device_desc * target)306 int i3c_detach_i3c_device(struct i3c_device_desc *target)
307 {
308 struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
309 const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
310 int status = 0;
311
312 if (!sys_slist_is_empty(&data->attached_dev.devices.i3c)) {
313 if (!sys_slist_find_and_remove(&data->attached_dev.devices.i3c, &target->node)) {
314 return -EINVAL;
315 }
316 } else {
317 return -EINVAL;
318 }
319
320 if (api->detach_i3c_device != NULL) {
321 status = api->detach_i3c_device(target->bus, target);
322 }
323
324 i3c_addr_slots_mark_free(&data->attached_dev.addr_slots,
325 target->dynamic_addr ? target->dynamic_addr : target->static_addr);
326
327 /* if it was from allocated memory, free it */
328 if (i3c_device_desc_in_pool(target)) {
329 i3c_device_desc_free(target);
330 }
331
332 return status;
333 }
334
i3c_attach_i2c_device(struct i3c_i2c_device_desc * target)335 int i3c_attach_i2c_device(struct i3c_i2c_device_desc *target)
336 {
337 struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
338 const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
339 int status = 0;
340 struct i3c_i2c_device_desc *i3c_i2c_desc;
341
342 /* check to see if the device has already been attached */
343 I3C_BUS_FOR_EACH_I2CDEV(target->bus, i3c_i2c_desc) {
344 if (i3c_i2c_desc == target) {
345 return -EINVAL;
346 }
347 }
348
349 if (!i3c_addr_slots_is_free(&data->attached_dev.addr_slots, target->addr)) {
350 return -EINVAL;
351 }
352
353 sys_slist_append(&data->attached_dev.devices.i2c, &target->node);
354
355 if (api->attach_i2c_device != NULL) {
356 status = api->attach_i2c_device(target->bus, target);
357 }
358
359 i3c_addr_slots_mark_i2c(&data->attached_dev.addr_slots, target->addr);
360
361 return status;
362 }
363
i3c_detach_i2c_device(struct i3c_i2c_device_desc * target)364 int i3c_detach_i2c_device(struct i3c_i2c_device_desc *target)
365 {
366 struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
367 const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
368 int status = 0;
369
370 if (!sys_slist_is_empty(&data->attached_dev.devices.i2c)) {
371 if (!sys_slist_find_and_remove(&data->attached_dev.devices.i2c, &target->node)) {
372 return -EINVAL;
373 }
374 } else {
375 return -EINVAL;
376 }
377
378 if (api->detach_i2c_device != NULL) {
379 status = api->detach_i2c_device(target->bus, target);
380 }
381
382 i3c_addr_slots_mark_free(&data->attached_dev.addr_slots, target->addr);
383
384 /* if it was from allocated memory, free it */
385 if (i3c_i2c_device_desc_in_pool(target)) {
386 i3c_i2c_device_desc_free(target);
387 }
388
389 return status;
390 }
391
i3c_sec_get_basic_info(const struct device * dev,uint8_t dynamic_addr,uint8_t static_addr,uint8_t bcr,uint8_t dcr)392 int i3c_sec_get_basic_info(const struct device *dev, uint8_t dynamic_addr, uint8_t static_addr,
393 uint8_t bcr, uint8_t dcr)
394 {
395 struct i3c_ccc_getpid getpid;
396 struct i3c_device_desc temp_desc;
397 struct i3c_device_desc *desc;
398 struct i3c_device_id id;
399 const struct i3c_driver_config *config = dev->config;
400 int ret;
401
402 *(const struct device **)&temp_desc.bus = dev;
403 temp_desc.dynamic_addr = dynamic_addr;
404 temp_desc.bcr = bcr;
405 temp_desc.dcr = dcr;
406 /* attach it first with a temperary value so we can at least get the pid */
407 ret = i3c_attach_i3c_device(&temp_desc);
408 if (ret != 0) {
409 return ret;
410 }
411
412 /* First try to look up if this is a known device in the list by PID */
413 ret = i3c_ccc_do_getpid(&temp_desc, &getpid);
414 if (ret != 0) {
415 return ret;
416 }
417
418 *(uint64_t *)&id = sys_get_be48(getpid.pid);
419
420 /* try to see if we already have a device statically allocated */
421 desc = i3c_dev_list_find(&config->dev_list, &id);
422 if (!desc) {
423 /* device was not found so allocate a descriptor */
424 desc = i3c_device_desc_alloc();
425 if (!desc) {
426 return -ENOMEM;
427 }
428 *(uint64_t *)&desc->pid = id.pid;
429 *(uint16_t *)&temp_desc.static_addr = (uint16_t)static_addr;
430 }
431 desc->dynamic_addr = dynamic_addr;
432 desc->bcr = bcr;
433 desc->dcr = dcr;
434
435 /* Detach that temporary device */
436 ret = i3c_detach_i3c_device(&temp_desc);
437 if (ret != 0) {
438 return ret;
439 }
440 ret = i3c_attach_i3c_device(desc);
441 if (ret != 0) {
442 return ret;
443 }
444
445 /* Skip reading BCR and DCR as they came from DEFTGTS */
446 ret = i3c_device_adv_info_get(desc);
447
448 return ret;
449 }
450
i3c_sec_i2c_attach(const struct device * dev,uint8_t static_addr,uint8_t lvr)451 int i3c_sec_i2c_attach(const struct device *dev, uint8_t static_addr, uint8_t lvr)
452 {
453 struct i3c_i2c_device_desc *i2c_desc;
454 int ret;
455
456 /* try to see if we already have a device statically allocated */
457 i2c_desc = i3c_dev_list_i2c_addr_find(dev, (uint16_t)static_addr);
458 if (!i2c_desc) {
459 /* device was not found so allocate a descriptor */
460 i2c_desc = i3c_i2c_device_desc_alloc();
461 if (!i2c_desc) {
462 return -ENOMEM;
463 }
464 *(const struct device **)&i2c_desc->bus = dev;
465 *(uint16_t *)&i2c_desc->addr = (uint16_t)static_addr;
466 *(uint8_t *)&i2c_desc->lvr = lvr;
467 }
468
469 ret = i3c_attach_i2c_device(i2c_desc);
470 return ret;
471 }
472
i3c_sec_bus_reset(const struct device * dev)473 static void i3c_sec_bus_reset(const struct device *dev)
474 {
475 struct i3c_device_desc *i3c_desc;
476 struct i3c_i2c_device_desc *i3c_i2c_desc;
477
478 I3C_BUS_FOR_EACH_I3CDEV(dev, i3c_desc) {
479 i3c_detach_i3c_device(i3c_desc);
480 }
481
482 I3C_BUS_FOR_EACH_I2CDEV(dev, i3c_i2c_desc) {
483 i3c_detach_i2c_device(i3c_i2c_desc);
484 }
485 }
486 #ifdef CONFIG_I3C_USE_IBI
487 /* call this from a workq after the interrupt from a controller */
i3c_sec_handoffed(struct k_work * work)488 void i3c_sec_handoffed(struct k_work *work)
489 {
490 struct i3c_ibi_work *ibi_node = CONTAINER_OF(work, struct i3c_ibi_work, work);
491 const struct device *dev = ibi_node->controller;
492 struct i3c_driver_data *data = (struct i3c_driver_data *)dev->data;
493 struct i3c_ccc_deftgts *deftgts = data->deftgts;
494 struct i3c_config_target config_target;
495 uint8_t n, cur_dyn_addr;
496 int ret;
497
498 if (!deftgts) {
499 LOG_ERR("Did not receive DEFTGTS before Handoff");
500 return;
501 }
502
503 if (!data->deftgts_refreshed) {
504 LOG_DBG("Already processed DEFTGTS from previous handoff");
505 return;
506 }
507
508 /* Forget all devices as another controller made changes */
509 i3c_sec_bus_reset(dev);
510
511 /*
512 * Retrieve the active controller information
513 */
514 ret = i3c_config_get_target(dev, &config_target);
515 if (ret != 0) {
516 LOG_ERR("Failed to retrieve active controller info");
517 return;
518 }
519
520 cur_dyn_addr = config_target.dynamic_addr;
521
522 /* Attach the previous AC */
523 ret = i3c_sec_get_basic_info(
524 dev, deftgts->active_controller.addr, deftgts->active_controller.static_addr,
525 deftgts->active_controller.bcr, deftgts->active_controller.dcr);
526
527 /* Attach all Targets */
528 for (n = 0; n < deftgts->count; n++) {
529 if (deftgts->targets[n].addr != 0) {
530 /* Must be an I3C device and skip itself */
531 if (deftgts->targets[n].addr != cur_dyn_addr) {
532 ret = i3c_sec_get_basic_info(dev, deftgts->targets[n].addr,
533 deftgts->targets[n].static_addr,
534 deftgts->targets[n].bcr,
535 deftgts->targets[n].dcr);
536 }
537 } else {
538 /* Must be an I2C device */
539 ret = i3c_sec_i2c_attach(dev, deftgts->targets[n].static_addr,
540 deftgts->targets[n].lvr);
541 }
542 }
543
544 /* Set false, so the next handoff doesn't retrigger regathering info */
545 data->deftgts_refreshed = false;
546 }
547 #endif
548
i3c_dev_list_daa_addr_helper(struct i3c_addr_slots * addr_slots,const struct i3c_dev_list * dev_list,uint64_t pid,bool must_match,bool assigned_okay,struct i3c_device_desc ** target,uint8_t * addr)549 int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots,
550 const struct i3c_dev_list *dev_list, uint64_t pid, bool must_match,
551 bool assigned_okay, struct i3c_device_desc **target, uint8_t *addr)
552 {
553 struct i3c_device_desc *desc;
554 const uint16_t vendor_id = (uint16_t)(pid >> 32);
555 const uint32_t part_no = (uint32_t)(pid & 0xFFFFFFFFU);
556 uint8_t dyn_addr = 0;
557 int ret = 0;
558 const struct i3c_device_id i3c_id = I3C_DEVICE_ID(pid);
559
560 desc = i3c_dev_list_find(dev_list, &i3c_id);
561 /* If a device was not found, try to allocate a descriptor */
562 if (desc == NULL) {
563 desc = i3c_device_desc_alloc();
564 }
565 if (must_match && (desc == NULL)) {
566 /*
567 * No device descriptor matching incoming PID and
568 * that we want an exact match.
569 */
570 ret = -ENODEV;
571
572 LOG_DBG("PID 0x%04x%08x is not in registered device list", vendor_id, part_no);
573
574 goto out;
575 }
576
577 if (desc != NULL && desc->dynamic_addr != 0U) {
578 if (assigned_okay) {
579 /* Return the already assigned address if desired so. */
580 dyn_addr = desc->dynamic_addr;
581 goto out;
582 } else {
583 /*
584 * Bail If target already has an assigned address.
585 * This is probably due to having the same PIDs for multiple targets
586 * in the device tree.
587 */
588 LOG_ERR("PID 0x%04x%08x already has "
589 "dynamic address (0x%02x) assigned",
590 vendor_id, part_no, desc->dynamic_addr);
591 ret = -EINVAL;
592 goto err;
593 }
594 }
595
596 /*
597 * Use the desired dynamic address as the new dynamic address
598 * if the slot is free.
599 */
600 if (desc != NULL && desc->init_dynamic_addr != 0U) {
601 if (i3c_addr_slots_is_free(addr_slots, desc->init_dynamic_addr)) {
602 dyn_addr = desc->init_dynamic_addr;
603 goto out;
604 }
605 }
606
607 /*
608 * Find the next available address.
609 */
610 dyn_addr = i3c_addr_slots_next_free_find(addr_slots, 0);
611
612 if (dyn_addr == 0U) {
613 /* No free addresses available */
614 LOG_DBG("No more free addresses available.");
615 ret = -ENOSPC;
616 }
617
618 out:
619 *addr = dyn_addr;
620 *target = desc;
621
622 err:
623 return ret;
624 }
625
i3c_odd_parity(uint8_t p)626 uint8_t i3c_odd_parity(uint8_t p)
627 {
628 p ^= p >> 4;
629 p &= 0xf;
630 return (0x9669 >> p) & 1;
631 }
632
i3c_device_controller_handoff(const struct i3c_device_desc * target,bool requested)633 int i3c_device_controller_handoff(const struct i3c_device_desc *target, bool requested)
634 {
635 int ret;
636 union i3c_ccc_getstatus status = {0};
637 struct i3c_ccc_events i3c_events;
638 struct i3c_ccc_address handoff_address;
639
640 /*
641 * If the Active Controller intends to pass the Controller Role to a selected Secondary
642 * Controller that did not send a Controller Role Request, then the Active Controller should
643 * verify that the selected Secondary Controller is active and ready to respond to
644 * additional commands
645 */
646 if (!requested) {
647 ret = i3c_ccc_do_getstatus_fmt1(target, &status);
648 if (ret != 0) {
649 return ret;
650 }
651
652 if (I3C_CCC_GETSTATUS_ACTIVITY_MODE(status.fmt1.status) ==
653 I3C_CCC_GETSTATUS_ACTIVITY_MODE_NCH) {
654 return -EBUSY;
655 }
656 }
657
658 /*
659 * The Active Controller needs to disable Hot-Joins, Target Interrupt Requests, and other
660 * Bus events that could interfere with the Handoff, then it sends the appropriate
661 * Broadcast to disable those events before the Handoff. Once the Handoff is complete, the
662 * new Active Controller should re-enable events that are disabled in this step.
663 */
664 i3c_events.events = I3C_CCC_EVT_ALL;
665 ret = i3c_ccc_do_events_all_set(target->bus, false, &i3c_events);
666 if (ret != 0) {
667 return ret;
668 }
669
670 /** TODO: reconfigure MLANE if needed */
671
672 /*
673 * If the Active Controller knows that the selected Secondary Controller must be put into a
674 * different Activity State before Handoff, then the Active Controller shall send the
675 * appropriate Broadcast or Direct CCCs to put the Bus (or selected Devices) into a
676 * different Activity State
677 */
678 if (target->crhdly1 & I3C_CCC_GETMXDS_CRDHLY1_SET_BUS_ACT_STATE) {
679 ret = i3c_ccc_do_entas(
680 target, I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE(target->crhdly1));
681 if (ret != 0) {
682 return ret;
683 }
684 }
685
686 if ((target->getcaps.getcap3 & I3C_CCC_GETCAPS3_GETSTATUS_DEFINING_BYTE_SUPPORT) &&
687 (target->crcaps.crcaps2 & I3C_CCC_GETCAPS_CRCAPS2_DEEP_SLEEP_CAPABLE)) {
688 ret = i3c_ccc_do_getstatus_fmt2(target, &status, GETSTATUS_FORMAT_2_PRECR);
689 if (ret != 0) {
690 return ret;
691 }
692
693 /*
694 * If the Active Controller determines that the indicated Secondary Controller has
695 * been in a “deep sleep” state and may need to be re-synchronized with the most
696 * current list of I3C Targets and Group Addresses, then the Active Controller
697 * should send CCC DEFTGTS and DEFGRPA
698 */
699 if (status.fmt2.precr & I3C_CCC_GETSTATUS_PRECR_DEEP_SLEEP_DETECTED) {
700 ret = i3c_bus_deftgts(target->bus);
701 if (ret != 0) {
702 return ret;
703 }
704 /* TODO: broadcast DEFGRPA when group address support comes */
705
706 /* Check CRCAPS if the device needs additional time to process */
707 if (target->crcaps.crcaps2 &
708 I3C_CCC_GETCAPS_CRCAPS2_DELAYED_CONTROLLER_HANDOFF) {
709 /*
710 * Afterwards, the Active Controller should poll the Secondary
711 * Controller to ensure that it has successfully processed this data
712 * and indicates that it is ready to accept the Controller Role
713 */
714 do {
715 ret = i3c_ccc_do_getstatus_fmt2(target, &status,
716 GETSTATUS_FORMAT_2_PRECR);
717 if (ret != 0) {
718 return ret;
719 }
720 } while (!(status.fmt2.precr &
721 I3C_CCC_GETSTATUS_PRECR_HANDOFF_DELAY_NACK));
722 }
723 }
724 }
725
726 /*
727 * After the Active Controller has prepared for Handoff, the Active Controller shall
728 * then issue a GETACCCR CCC
729 */
730 ret = i3c_ccc_do_getacccr(target, &handoff_address);
731 if (ret != 0) {
732 return ret;
733 }
734
735 /* Verify Odd Parity and Correct Dynamic Address Reply */
736 if ((i3c_odd_parity(handoff_address.addr >> 1) != (handoff_address.addr & BIT(0))) ||
737 (handoff_address.addr >> 1 != target->dynamic_addr)) {
738 return -EIO;
739 }
740
741 return ret;
742 }
743
i3c_device_basic_info_get(struct i3c_device_desc * target)744 int i3c_device_basic_info_get(struct i3c_device_desc *target)
745 {
746 int ret;
747 struct i3c_ccc_getbcr bcr = {0};
748 struct i3c_ccc_getdcr dcr = {0};
749
750 /* GETBCR */
751 ret = i3c_ccc_do_getbcr(target, &bcr);
752 if (ret != 0) {
753 return ret;
754 }
755
756 /* GETDCR */
757 ret = i3c_ccc_do_getdcr(target, &dcr);
758 if (ret != 0) {
759 return ret;
760 }
761
762 target->bcr = bcr.bcr;
763 target->dcr = dcr.dcr;
764
765 return 0;
766 }
767
i3c_device_adv_info_get(struct i3c_device_desc * target)768 int i3c_device_adv_info_get(struct i3c_device_desc *target)
769 {
770 struct i3c_ccc_mrl mrl = {0};
771 struct i3c_ccc_mwl mwl = {0};
772 union i3c_ccc_getcaps caps = {0};
773 union i3c_ccc_getmxds mxds = {0};
774 int ret;
775
776 /* GETMRL */
777 if (i3c_ccc_do_getmrl(target, &mrl) != 0) {
778 /* GETMRL may be optionally supported if no settable limit */
779 LOG_DBG("No settable limit for GETMRL");
780 }
781
782 /* GETMWL */
783 if (i3c_ccc_do_getmwl(target, &mwl) != 0) {
784 /* GETMWL may be optionally supported if no settable limit */
785 LOG_DBG("No settable limit for GETMWL");
786 }
787
788 /* GETCAPS */
789 ret = i3c_ccc_do_getcaps_fmt1(target, &caps);
790 /*
791 * GETCAPS (GETHDRCAP) is required to be supported for I3C v1.0 targets that support HDR
792 * modes and required if the Target's I3C version is v1.1 or later, but which the version it
793 * supports it can't be known ahead of time. So if the BCR bit for Advanced capabilities is
794 * set, then it is expected for GETCAPS to always be supported. Otherwise, then it's a I3C
795 * v1.0 device without any HDR modes so do not treat as an error if no valid response.
796 */
797 if ((ret != 0) && (target->bcr & I3C_BCR_ADV_CAPABILITIES)) {
798 return ret;
799 } else {
800 ret = 0;
801 }
802
803 /* CRCAPS */
804 if ((target->getcaps.getcap3 & I3C_CCC_GETCAPS3_GETCAPS_DEFINING_BYTE_SUPPORT) &&
805 (i3c_device_is_controller_capable(target))) {
806 ret = i3c_ccc_do_getcaps_fmt2(target, &caps, GETCAPS_FORMAT_2_CRCAPS);
807 if (ret != 0) {
808 return ret;
809 }
810 }
811
812 /* GETMXDS */
813 if (target->bcr & I3C_BCR_MAX_DATA_SPEED_LIMIT) {
814 ret = i3c_ccc_do_getmxds_fmt2(target, &mxds);
815 if (ret != 0) {
816 return ret;
817 }
818
819 /* Get CRHDLY if supported */
820 if ((target->data_speed.maxwr & I3C_CCC_GETMXDS_MAXWR_DEFINING_BYTE_SUPPORT) &&
821 (i3c_device_is_controller_capable(target))) {
822 ret = i3c_ccc_do_getmxds_fmt3(target, &mxds, GETMXDS_FORMAT_3_CRHDLY);
823 if (ret != 0) {
824 return ret;
825 }
826
827 target->crhdly1 = mxds.fmt3.crhdly1;
828 }
829 }
830
831 target->data_length.mrl = mrl.len;
832 target->data_length.mwl = mwl.len;
833 target->data_length.max_ibi = mrl.ibi_len;
834
835 return ret;
836 }
837
838 /**
839 * @brief Do SETDASA to set static address as dynamic address.
840 *
841 * @param dev Pointer to the device driver instance.
842 * @param[out] True if DAA is still needed. False if all registered
843 * devices have static addresses.
844 *
845 * @retval 0 if successful.
846 */
i3c_bus_setdasa(const struct device * dev,const struct i3c_dev_list * dev_list,bool * need_daa,bool * need_aasa)847 static int i3c_bus_setdasa(const struct device *dev, const struct i3c_dev_list *dev_list,
848 bool *need_daa, bool *need_aasa)
849 {
850 int i, ret;
851
852 *need_daa = false;
853 *need_aasa = false;
854
855 /* Loop through the registered I3C devices */
856 for (i = 0; i < dev_list->num_i3c; i++) {
857 struct i3c_device_desc *desc = &dev_list->i3c[i];
858 struct i3c_driver_data *bus_data = (struct i3c_driver_data *)dev->data;
859 struct i3c_ccc_address dyn_addr;
860
861 /*
862 * A device without static address => need to do
863 * dynamic address assignment.
864 */
865 if (desc->static_addr == 0U) {
866 *need_daa = true;
867 continue;
868 }
869
870 /*
871 * A device that supports SETAASA and will use the same dynamic
872 * address as its static address if a different dynamic address
873 * is not requested
874 */
875 if ((desc->supports_setaasa) && ((desc->init_dynamic_addr == 0) ||
876 desc->init_dynamic_addr == desc->static_addr)) {
877 *need_aasa = true;
878 continue;
879 }
880
881 LOG_DBG("SETDASA for 0x%x", desc->static_addr);
882
883 /*
884 * check that initial dynamic address is free before setting it
885 * if configured
886 */
887 if ((desc->init_dynamic_addr != 0) &&
888 (desc->init_dynamic_addr != desc->static_addr)) {
889 if (!i3c_addr_slots_is_free(&bus_data->attached_dev.addr_slots,
890 desc->init_dynamic_addr)) {
891 if (i3c_detach_i3c_device(desc) != 0) {
892 LOG_ERR("Failed to detach %s", desc->dev->name);
893 }
894 continue;
895 }
896 }
897
898 /*
899 * Note that the 7-bit address needs to start at bit 1
900 * (aka left-justified). So shift left by 1;
901 */
902 dyn_addr.addr =
903 (desc->init_dynamic_addr ? desc->init_dynamic_addr : desc->static_addr)
904 << 1;
905
906 ret = i3c_ccc_do_setdasa(desc, dyn_addr);
907 if (ret == 0) {
908 desc->dynamic_addr = dyn_addr.addr >> 1;
909 if (desc->dynamic_addr != desc->static_addr) {
910 if (i3c_reattach_i3c_device(desc, desc->static_addr) != 0) {
911 LOG_ERR("Failed to reattach %s (%d)", desc->dev->name, ret);
912 }
913 }
914 } else {
915 /* SETDASA failed, detach it from the controller */
916 if (i3c_detach_i3c_device(desc) != 0) {
917 LOG_ERR("Failed to detach %s (%d)", desc->dev->name, ret);
918 }
919 LOG_ERR("SETDASA error on address 0x%x (%d)", desc->static_addr, ret);
920 }
921 }
922
923 return 0;
924 }
925
i3c_bus_has_sec_controller(const struct device * dev)926 bool i3c_bus_has_sec_controller(const struct device *dev)
927 {
928 struct i3c_device_desc *i3c_desc;
929
930 I3C_BUS_FOR_EACH_I3CDEV(dev, i3c_desc) {
931 if (i3c_device_is_controller_capable(i3c_desc)) {
932 return true;
933 }
934 }
935
936 return false;
937 }
938
i3c_bus_deftgts(const struct device * dev)939 int i3c_bus_deftgts(const struct device *dev)
940 {
941 struct i3c_driver_data *data = (struct i3c_driver_data *)dev->data;
942 struct i3c_config_target config_target;
943 struct i3c_ccc_deftgts *deftgts;
944 struct i3c_device_desc *i3c_desc;
945 struct i3c_i2c_device_desc *i3c_i2c_desc;
946 int ret;
947 uint8_t n = 0;
948 size_t num_of_targets = sys_slist_len(&data->attached_dev.devices.i3c) +
949 sys_slist_len(&data->attached_dev.devices.i2c);
950 size_t data_len = sizeof(uint8_t) + sizeof(struct i3c_ccc_deftgts_active_controller) +
951 (num_of_targets * sizeof(struct i3c_ccc_deftgts_target));
952
953 /*
954 * Retrieve the active controller information
955 */
956 ret = i3c_config_get(dev, I3C_CONFIG_TARGET, &config_target);
957 if (ret != 0) {
958 LOG_ERR("Failed to retrieve active controller info");
959 return ret;
960 }
961
962 /* Allocate memory for the struct with enough space for the targets */
963 deftgts = malloc(data_len);
964 if (!deftgts) {
965 return -ENOMEM;
966 }
967
968 /*
969 * Write the total number of I3C and I2C targets to the payload
970 */
971 deftgts->count = num_of_targets;
972
973 /*
974 * Add the active controller information to the payload
975 */
976 deftgts->active_controller.addr = config_target.dynamic_addr << 1;
977 deftgts->active_controller.dcr = config_target.dcr;
978 deftgts->active_controller.bcr = config_target.bcr;
979 deftgts->active_controller.static_addr = I3C_BROADCAST_ADDR << 1;
980
981 /*
982 * Loop through each attached I3C device and add it to the payload
983 */
984 I3C_BUS_FOR_EACH_I3CDEV(dev, i3c_desc) {
985 deftgts->targets[n].addr = i3c_desc->dynamic_addr << 1;
986 deftgts->targets[n].dcr = i3c_desc->dcr;
987 deftgts->targets[n].bcr = i3c_desc->bcr;
988 deftgts->targets[n].static_addr = i3c_desc->static_addr << 1;
989 n++;
990 }
991
992 /*
993 * Loop through each attached I2C device and add it to the payload
994 */
995 I3C_BUS_FOR_EACH_I2CDEV(dev, i3c_i2c_desc) {
996 deftgts->targets[n].addr = 0;
997 deftgts->targets[n].lvr = i3c_i2c_desc->lvr;
998 deftgts->targets[n].bcr = 0;
999 deftgts->targets[n].static_addr = (uint8_t)(i3c_i2c_desc->addr << 1);
1000 n++;
1001 }
1002
1003 /* TODO: add support for Group Addr in DEFTGTS when that comes */
1004
1005 ret = i3c_ccc_do_deftgts_all(dev, deftgts);
1006
1007 free(deftgts);
1008
1009 return ret;
1010 }
1011
i3c_bus_init(const struct device * dev,const struct i3c_dev_list * dev_list)1012 int i3c_bus_init(const struct device *dev, const struct i3c_dev_list *dev_list)
1013 {
1014 int i, ret = 0;
1015 bool need_daa = true;
1016 bool need_aasa = true;
1017 struct i3c_ccc_events i3c_events;
1018
1019 #ifdef CONFIG_I3C_INIT_RSTACT
1020 /*
1021 * Reset all connected targets. Also reset dynamic
1022 * addresses for all devices as we have no idea what
1023 * dynamic addresses the connected devices have
1024 * (e.g. assigned during previous power cycle).
1025 *
1026 * Note that we ignore error for both RSTACT and RSTDAA
1027 * as there may not be any connected devices responding
1028 * to these CCCs.
1029 */
1030 if (i3c_ccc_do_rstact_all(dev, I3C_CCC_RSTACT_RESET_WHOLE_TARGET) != 0) {
1031 /*
1032 * Reset Whole Target support is not required so
1033 * if there is any NACK, we want to at least reset
1034 * the I3C peripheral of targets.
1035 */
1036 LOG_DBG("Broadcast RSTACT (whole target) was NACK.");
1037
1038 if (i3c_ccc_do_rstact_all(dev, I3C_CCC_RSTACT_PERIPHERAL_ONLY) != 0) {
1039 LOG_DBG("Broadcast RSTACT (peripehral) was NACK.");
1040 }
1041 }
1042 #endif
1043
1044 if (i3c_ccc_do_rstdaa_all(dev) != 0) {
1045 LOG_DBG("Broadcast RSTDAA was NACK.");
1046 }
1047
1048 /*
1049 * Disable all events from targets to avoid them
1050 * interfering with bus initialization,
1051 * especially during DAA.
1052 */
1053 i3c_events.events = I3C_CCC_EVT_ALL;
1054 ret = i3c_ccc_do_events_all_set(dev, false, &i3c_events);
1055 if (ret != 0) {
1056 LOG_DBG("Broadcast DISEC was NACK.");
1057 }
1058
1059 /*
1060 * Set static addresses as dynamic addresses.
1061 */
1062 ret = i3c_bus_setdasa(dev, dev_list, &need_daa, &need_aasa);
1063 if (ret != 0) {
1064 goto err_out;
1065 }
1066
1067 /*
1068 * Perform Set All Addresses to Static Address if possible.
1069 */
1070 if (need_aasa) {
1071 ret = i3c_ccc_do_setaasa_all(dev);
1072 if (ret != 0) {
1073 LOG_ERR("failed to perform setaasa");
1074 } else {
1075 for (i = 0; i < dev_list->num_i3c; i++) {
1076 struct i3c_device_desc *desc = &dev_list->i3c[i];
1077 /*
1078 * Only set for devices that support SETAASA and do not
1079 * request a different dynamic address than its SA
1080 */
1081 if ((desc->supports_setaasa) && (desc->static_addr != 0) &&
1082 ((desc->init_dynamic_addr == 0) ||
1083 desc->init_dynamic_addr == desc->static_addr)) {
1084 desc->dynamic_addr = desc->static_addr;
1085 }
1086 }
1087 }
1088 }
1089
1090 /*
1091 * Perform Dynamic Address Assignment if needed.
1092 */
1093 if (need_daa) {
1094 ret = i3c_do_daa(dev);
1095 if (ret != 0) {
1096 /*
1097 * Spec says to try once more
1098 * if DAA fails the first time.
1099 */
1100 ret = i3c_do_daa(dev);
1101 if (ret != 0) {
1102 /*
1103 * Failure to finish dynamic address assignment
1104 * is not the end of world... hopefully.
1105 * Continue on so the devices already have
1106 * addresses can still function.
1107 */
1108 LOG_ERR("DAA was not successful.");
1109 }
1110 }
1111 }
1112
1113 /*
1114 * Loop through the registered I3C devices to retrieve
1115 * basic target information.
1116 */
1117 for (i = 0; i < dev_list->num_i3c; i++) {
1118 struct i3c_device_desc *desc = &dev_list->i3c[i];
1119
1120 if (desc->dynamic_addr == 0U) {
1121 continue;
1122 }
1123
1124 /*
1125 * If static address is 0, then it is assumed that BCR
1126 * and DCR were already read through ENTDAA
1127 */
1128 ret = (desc->static_addr == 0) ? i3c_device_adv_info_get(desc)
1129 : i3c_device_info_get(desc);
1130 if (ret != 0) {
1131 LOG_ERR("Error getting device info for 0x%02x", desc->static_addr);
1132 } else {
1133 LOG_DBG("Target 0x%02x, BCR 0x%02x, DCR 0x%02x, MRL %d, MWL %d, IBI %d",
1134 desc->dynamic_addr, desc->bcr, desc->dcr, desc->data_length.mrl,
1135 desc->data_length.mwl, desc->data_length.max_ibi);
1136 }
1137 }
1138
1139 if (i3c_bus_has_sec_controller(dev)) {
1140 ret = i3c_bus_deftgts(dev);
1141 if (ret != 0) {
1142 LOG_ERR("Error sending DEFTGTS");
1143 }
1144 }
1145
1146 /*
1147 * Only re-enable Hot-Join from targets.
1148 * Target interrupts will be enabled when IBI is enabled.
1149 */
1150 i3c_events.events = I3C_CCC_EVT_HJ;
1151 ret = i3c_ccc_do_events_all_set(dev, true, &i3c_events);
1152 if (ret != 0) {
1153 LOG_DBG("Broadcast ENEC was NACK.");
1154 }
1155
1156 err_out:
1157 return ret;
1158 }
1159