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,
21 		   uint8_t num_msgs, 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: ",
28 			msg->flags & I3C_MSG_READ ? 'R' : 'W', msg->len);
29 		if (!(msg->flags & I3C_MSG_READ)) {
30 			LOG_HEXDUMP_DBG(msg->buf, msg->len, "contents:");
31 		}
32 	}
33 }
34 
i3c_addr_slots_set(struct i3c_addr_slots * slots,uint8_t dev_addr,enum i3c_addr_slot_status status)35 void i3c_addr_slots_set(struct i3c_addr_slots *slots,
36 			uint8_t dev_addr,
37 			enum i3c_addr_slot_status status)
38 {
39 	int bitpos;
40 	int idx;
41 
42 	__ASSERT_NO_MSG(slots != NULL);
43 
44 	if (dev_addr > I3C_MAX_ADDR) {
45 		/* Invalid address. Do nothing. */
46 		return;
47 	}
48 
49 	bitpos = dev_addr * 2;
50 	idx = bitpos / BITS_PER_LONG;
51 	bitpos %= BITS_PER_LONG;
52 
53 	slots->slots[idx] &= ~((unsigned long)I3C_ADDR_SLOT_STATUS_MASK << bitpos);
54 	slots->slots[idx] |= status << bitpos;
55 }
56 
57 enum i3c_addr_slot_status
i3c_addr_slots_status(struct i3c_addr_slots * slots,uint8_t dev_addr)58 i3c_addr_slots_status(struct i3c_addr_slots *slots,
59 		      uint8_t dev_addr)
60 {
61 	unsigned long status;
62 	int bitpos;
63 	int idx;
64 
65 	__ASSERT_NO_MSG(slots != NULL);
66 
67 	if (dev_addr > I3C_MAX_ADDR) {
68 		/* Invalid address.
69 		 * Simply says it's reserved so it will not be
70 		 * used for anything.
71 		 */
72 		return I3C_ADDR_SLOT_STATUS_RSVD;
73 	}
74 
75 	bitpos = dev_addr * 2;
76 	idx = bitpos / BITS_PER_LONG;
77 	bitpos %= BITS_PER_LONG;
78 
79 	status = slots->slots[idx] >> bitpos;
80 	status &= I3C_ADDR_SLOT_STATUS_MASK;
81 
82 	return status;
83 }
84 
85 
i3c_addr_slots_init(const struct device * dev)86 int i3c_addr_slots_init(const struct device *dev)
87 {
88 	struct i3c_driver_data *data =
89 		(struct i3c_driver_data *)dev->data;
90 	const struct i3c_driver_config *config =
91 		(const struct i3c_driver_config *)dev->config;
92 	int i, ret = 0;
93 	struct i3c_device_desc *i3c_dev;
94 	struct i3c_i2c_device_desc *i2c_dev;
95 
96 	__ASSERT_NO_MSG(dev != NULL);
97 
98 	(void)memset(&data->attached_dev.addr_slots, 0, sizeof(data->attached_dev.addr_slots));
99 	sys_slist_init(&data->attached_dev.devices.i3c);
100 	sys_slist_init(&data->attached_dev.devices.i2c);
101 
102 	/* Address restrictions (ref 5.1.2.2.5, Specification for I3C v1.1.1) */
103 	for (i = 0; i <= 7; i++) {
104 		/* Addresses 0 to 7 are reserved */
105 		i3c_addr_slots_set(&data->attached_dev.addr_slots, i, I3C_ADDR_SLOT_STATUS_RSVD);
106 
107 		/*
108 		 * Addresses within a single bit error of broadcast address
109 		 * are also reserved.
110 		 */
111 		i3c_addr_slots_set(&data->attached_dev.addr_slots, I3C_BROADCAST_ADDR ^ BIT(i),
112 				   I3C_ADDR_SLOT_STATUS_RSVD);
113 
114 	}
115 
116 	/* The broadcast address is reserved */
117 	i3c_addr_slots_set(&data->attached_dev.addr_slots, I3C_BROADCAST_ADDR,
118 			   I3C_ADDR_SLOT_STATUS_RSVD);
119 
120 	/*
121 	 * Mark all I2C addresses first.
122 	 */
123 	for (i = 0; i < config->dev_list.num_i2c; i++) {
124 		i2c_dev = &config->dev_list.i2c[i];
125 		ret = i3c_attach_i2c_device(i2c_dev);
126 		if (ret != 0) {
127 			/* Address slot is not free */
128 			ret = -EINVAL;
129 			goto out;
130 		}
131 	}
132 
133 	/*
134 	 * If there is a static address for the I3C devices, check
135 	 * if this address is free, and there is no other devices of
136 	 * the same (pre-assigned) address on the bus.
137 	 */
138 	for (i = 0; i < config->dev_list.num_i3c; i++) {
139 		i3c_dev = &config->dev_list.i3c[i];
140 		ret = i3c_attach_i3c_device(i3c_dev);
141 		if (ret != 0) {
142 			/* Address slot is not free */
143 			ret = -EINVAL;
144 			goto out;
145 		}
146 	}
147 
148 out:
149 	return ret;
150 }
151 
i3c_addr_slots_is_free(struct i3c_addr_slots * slots,uint8_t dev_addr)152 bool i3c_addr_slots_is_free(struct i3c_addr_slots *slots,
153 			    uint8_t dev_addr)
154 {
155 	enum i3c_addr_slot_status status;
156 
157 	__ASSERT_NO_MSG(slots != NULL);
158 
159 	status = i3c_addr_slots_status(slots, dev_addr);
160 
161 	return (status == I3C_ADDR_SLOT_STATUS_FREE);
162 }
163 
i3c_addr_slots_next_free_find(struct i3c_addr_slots * slots,uint8_t start_addr)164 uint8_t i3c_addr_slots_next_free_find(struct i3c_addr_slots *slots, uint8_t start_addr)
165 {
166 	uint8_t addr;
167 	enum i3c_addr_slot_status status;
168 
169 	/* Addresses 0 to 7 are reserved. So start at 8. */
170 	for (addr = MAX(start_addr, 8); addr < I3C_MAX_ADDR; addr++) {
171 		status = i3c_addr_slots_status(slots, addr);
172 		if (status == I3C_ADDR_SLOT_STATUS_FREE) {
173 			return addr;
174 		}
175 	}
176 
177 	return 0;
178 }
179 
i3c_dev_list_find(const struct i3c_dev_list * dev_list,const struct i3c_device_id * id)180 struct i3c_device_desc *i3c_dev_list_find(const struct i3c_dev_list *dev_list,
181 					  const struct i3c_device_id *id)
182 {
183 	int i;
184 	struct i3c_device_desc *ret = NULL;
185 
186 	__ASSERT_NO_MSG(dev_list != NULL);
187 
188 	/* this only searches known I3C PIDs */
189 	for (i = 0; i < dev_list->num_i3c; i++) {
190 		struct i3c_device_desc *desc = &dev_list->i3c[i];
191 
192 		if (desc->pid == id->pid) {
193 			ret = desc;
194 			break;
195 		}
196 	}
197 
198 	return ret;
199 }
200 
i3c_dev_list_i3c_addr_find(const struct device * dev,uint8_t addr)201 struct i3c_device_desc *i3c_dev_list_i3c_addr_find(const struct device *dev,
202 						   uint8_t addr)
203 {
204 	struct i3c_device_desc *ret = NULL;
205 	struct i3c_device_desc *desc;
206 
207 	__ASSERT_NO_MSG(dev != NULL);
208 
209 	I3C_BUS_FOR_EACH_I3CDEV(dev, desc) {
210 		if (desc->dynamic_addr == addr) {
211 			ret = desc;
212 			break;
213 		}
214 	}
215 
216 	return ret;
217 }
218 
i3c_dev_list_i2c_addr_find(const struct device * dev,uint16_t addr)219 struct i3c_i2c_device_desc *i3c_dev_list_i2c_addr_find(const struct device *dev,
220 							   uint16_t addr)
221 {
222 	struct i3c_i2c_device_desc *ret = NULL;
223 	struct i3c_i2c_device_desc *desc;
224 
225 	__ASSERT_NO_MSG(dev != NULL);
226 
227 	I3C_BUS_FOR_EACH_I2CDEV(dev, desc) {
228 		if (desc->addr == addr) {
229 			ret = desc;
230 			break;
231 		}
232 	}
233 
234 	return ret;
235 }
236 
i3c_attach_i3c_device(struct i3c_device_desc * target)237 int i3c_attach_i3c_device(struct i3c_device_desc *target)
238 {
239 	struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
240 	const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
241 	uint8_t addr = 0;
242 	int status = 0;
243 	struct i3c_device_desc *i3c_desc;
244 
245 	/* check to see if the device has already been attached */
246 	I3C_BUS_FOR_EACH_I3CDEV(target->bus, i3c_desc) {
247 		if (i3c_desc == target) {
248 			return -EINVAL;
249 		}
250 	}
251 
252 	addr = target->dynamic_addr ? target->dynamic_addr : target->static_addr;
253 
254 	/*
255 	 * If it has a dynamic addr already assigned or a static address, check that it is free
256 	 */
257 	if (addr) {
258 		if (!i3c_addr_slots_is_free(&data->attached_dev.addr_slots, addr)) {
259 			return -EINVAL;
260 		}
261 	}
262 
263 	sys_slist_append(&data->attached_dev.devices.i3c, &target->node);
264 
265 	if (api->attach_i3c_device != NULL) {
266 		status = api->attach_i3c_device(target->bus, target);
267 	}
268 
269 	if (addr) {
270 		i3c_addr_slots_mark_i3c(&data->attached_dev.addr_slots, addr);
271 	}
272 
273 	return status;
274 }
275 
i3c_reattach_i3c_device(struct i3c_device_desc * target,uint8_t old_dyn_addr)276 int i3c_reattach_i3c_device(struct i3c_device_desc *target, uint8_t old_dyn_addr)
277 {
278 	struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
279 	const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
280 	int status = 0;
281 
282 	if (!i3c_addr_slots_is_free(&data->attached_dev.addr_slots, target->dynamic_addr)) {
283 		return -EINVAL;
284 	}
285 
286 	if (api->reattach_i3c_device != NULL) {
287 		status = api->reattach_i3c_device(target->bus, target, old_dyn_addr);
288 	}
289 
290 	if (old_dyn_addr) {
291 		/* mark the old address as free */
292 		i3c_addr_slots_mark_free(&data->attached_dev.addr_slots, old_dyn_addr);
293 	}
294 
295 	i3c_addr_slots_mark_i3c(&data->attached_dev.addr_slots, target->dynamic_addr);
296 
297 	return status;
298 }
299 
i3c_detach_i3c_device(struct i3c_device_desc * target)300 int i3c_detach_i3c_device(struct i3c_device_desc *target)
301 {
302 	struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
303 	const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
304 	int status = 0;
305 
306 	if (!sys_slist_is_empty(&data->attached_dev.devices.i3c)) {
307 		if (!sys_slist_find_and_remove(&data->attached_dev.devices.i3c, &target->node)) {
308 			return -EINVAL;
309 		}
310 	} else {
311 		return -EINVAL;
312 	}
313 
314 	if (api->detach_i3c_device != NULL) {
315 		status = api->detach_i3c_device(target->bus, target);
316 	}
317 
318 	i3c_addr_slots_mark_free(&data->attached_dev.addr_slots,
319 				 target->dynamic_addr ? target->dynamic_addr : target->static_addr);
320 
321 	return status;
322 }
323 
i3c_attach_i2c_device(struct i3c_i2c_device_desc * target)324 int i3c_attach_i2c_device(struct i3c_i2c_device_desc *target)
325 {
326 	struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
327 	const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
328 	int status = 0;
329 	struct i3c_i2c_device_desc *i3c_i2c_desc;
330 
331 	/* check to see if the device has already been attached */
332 	I3C_BUS_FOR_EACH_I2CDEV(target->bus, i3c_i2c_desc) {
333 		if (i3c_i2c_desc == target) {
334 			return -EINVAL;
335 		}
336 	}
337 
338 	if (!i3c_addr_slots_is_free(&data->attached_dev.addr_slots, target->addr)) {
339 		return -EINVAL;
340 	}
341 
342 	sys_slist_append(&data->attached_dev.devices.i2c, &target->node);
343 
344 	if (api->attach_i2c_device != NULL) {
345 		status = api->attach_i2c_device(target->bus, target);
346 	}
347 
348 	i3c_addr_slots_mark_i2c(&data->attached_dev.addr_slots, target->addr);
349 
350 	return status;
351 }
352 
i3c_detach_i2c_device(struct i3c_i2c_device_desc * target)353 int i3c_detach_i2c_device(struct i3c_i2c_device_desc *target)
354 {
355 	struct i3c_driver_data *data = (struct i3c_driver_data *)target->bus->data;
356 	const struct i3c_driver_api *api = (const struct i3c_driver_api *)target->bus->api;
357 	int status = 0;
358 
359 	if (!sys_slist_is_empty(&data->attached_dev.devices.i2c)) {
360 		if (!sys_slist_find_and_remove(&data->attached_dev.devices.i2c, &target->node)) {
361 			return -EINVAL;
362 		}
363 	} else {
364 		return -EINVAL;
365 	}
366 
367 	if (api->detach_i2c_device != NULL) {
368 		status = api->detach_i2c_device(target->bus, target);
369 	}
370 
371 	i3c_addr_slots_mark_free(&data->attached_dev.addr_slots, target->addr);
372 
373 	return status;
374 }
375 
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)376 int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots,
377 				 const struct i3c_dev_list *dev_list,
378 				 uint64_t pid, bool must_match,
379 				 bool assigned_okay,
380 				 struct i3c_device_desc **target,
381 				 uint8_t *addr)
382 {
383 	struct i3c_device_desc *desc;
384 	const uint16_t vendor_id = (uint16_t)(pid >> 32);
385 	const uint32_t part_no = (uint32_t)(pid & 0xFFFFFFFFU);
386 	uint8_t dyn_addr = 0;
387 	int ret = 0;
388 	const struct i3c_device_id i3c_id = I3C_DEVICE_ID(pid);
389 
390 	desc = i3c_dev_list_find(dev_list, &i3c_id);
391 	if (must_match && (desc == NULL)) {
392 		/*
393 		 * No device descriptor matching incoming PID and
394 		 * that we want an exact match.
395 		 */
396 		ret = -ENODEV;
397 
398 		LOG_DBG("PID 0x%04x%08x is not in registered device list",
399 			vendor_id, part_no);
400 
401 		goto out;
402 	}
403 
404 	if (desc != NULL && desc->dynamic_addr != 0U) {
405 		if (assigned_okay) {
406 			/* Return the already assigned address if desired so. */
407 			dyn_addr = desc->dynamic_addr;
408 			goto out;
409 		} else {
410 			/*
411 			 * Bail If target already has an assigned address.
412 			 * This is probably due to having the same PIDs for multiple targets
413 			 * in the device tree.
414 			 */
415 			LOG_ERR("PID 0x%04x%08x already has "
416 				"dynamic address (0x%02x) assigned",
417 				vendor_id, part_no, desc->dynamic_addr);
418 			ret = -EINVAL;
419 			goto err;
420 		}
421 	}
422 
423 	/*
424 	 * Use the desired dynamic address as the new dynamic address
425 	 * if the slot is free.
426 	 */
427 	if (desc != NULL && desc->init_dynamic_addr != 0U) {
428 		if (i3c_addr_slots_is_free(addr_slots, desc->init_dynamic_addr)) {
429 			dyn_addr = desc->init_dynamic_addr;
430 			goto out;
431 		}
432 	}
433 
434 	/*
435 	 * Find the next available address.
436 	 */
437 	dyn_addr = i3c_addr_slots_next_free_find(addr_slots, 0);
438 
439 	if (dyn_addr == 0U) {
440 		/* No free addresses available */
441 		LOG_DBG("No more free addresses available.");
442 		ret = -ENOSPC;
443 	}
444 
445 out:
446 	*addr = dyn_addr;
447 	*target = desc;
448 
449 err:
450 	return ret;
451 }
452 
i3c_device_basic_info_get(struct i3c_device_desc * target)453 int i3c_device_basic_info_get(struct i3c_device_desc *target)
454 {
455 	int ret;
456 	uint8_t tmp_bcr;
457 
458 	struct i3c_ccc_getbcr bcr = {0};
459 	struct i3c_ccc_getdcr dcr = {0};
460 	struct i3c_ccc_mrl mrl = {0};
461 	struct i3c_ccc_mwl mwl = {0};
462 	union i3c_ccc_getcaps caps = {0};
463 	union i3c_ccc_getmxds mxds = {0};
464 
465 	/*
466 	 * Since some CCC functions requires BCR to function
467 	 * correctly, we save the BCR here and update the BCR
468 	 * in the descriptor. If any following operations fails,
469 	 * we can restore the BCR.
470 	 */
471 	tmp_bcr = target->bcr;
472 
473 	/* GETBCR */
474 	ret = i3c_ccc_do_getbcr(target, &bcr);
475 	if (ret != 0) {
476 		goto out;
477 	}
478 
479 	target->bcr = bcr.bcr;
480 
481 	/* GETDCR */
482 	ret = i3c_ccc_do_getdcr(target, &dcr);
483 	if (ret != 0) {
484 		goto out;
485 	}
486 
487 	/* GETMRL */
488 	if (i3c_ccc_do_getmrl(target, &mrl) != 0) {
489 		/* GETMRL may be optionally supported if no settable limit */
490 		LOG_DBG("No settable limit for GETMRL");
491 	}
492 
493 	/* GETMWL */
494 	if (i3c_ccc_do_getmwl(target, &mwl) != 0) {
495 		/* GETMWL may be optionally supported if no settable limit */
496 		LOG_DBG("No settable limit for GETMWL");
497 	}
498 
499 	/* GETCAPS */
500 	ret = i3c_ccc_do_getcaps_fmt1(target, &caps);
501 	/*
502 	 * GETCAPS (GETHDRCAP) is required to be supported for I3C v1.0 targets that support HDR
503 	 * modes and required if the Target's I3C version is v1.1 or later, but which the version it
504 	 * supports it can't be known ahead of time. So if the BCR bit for Advanced capabilities is
505 	 * set, then it is expected for GETCAPS to always be supported. Otherwise, then it's a I3C
506 	 * v1.0 device without any HDR modes so do not treat as an error if no valid response.
507 	 */
508 	if (ret == 0) {
509 		memcpy(&target->getcaps, &caps, sizeof(target->getcaps));
510 	} else if ((ret != 0) && (target->bcr & I3C_BCR_ADV_CAPABILITIES)) {
511 		goto out;
512 	} else {
513 		ret = 0;
514 	}
515 
516 	/* GETMXDS */
517 	if (target->bcr & I3C_BCR_MAX_DATA_SPEED_LIMIT) {
518 		ret = i3c_ccc_do_getmxds_fmt2(target, &mxds);
519 		if (ret != 0) {
520 			goto out;
521 		}
522 
523 		target->data_speed.maxrd = mxds.fmt2.maxrd;
524 		target->data_speed.maxwr = mxds.fmt2.maxwr;
525 		target->data_speed.max_read_turnaround = sys_get_le24(mxds.fmt2.maxrdturn);
526 	}
527 
528 	target->dcr = dcr.dcr;
529 	target->data_length.mrl = mrl.len;
530 	target->data_length.mwl = mwl.len;
531 	target->data_length.max_ibi = mrl.ibi_len;
532 
533 out:
534 	if (ret != 0) {
535 		/* Restore BCR is any CCC fails. */
536 		target->bcr = tmp_bcr;
537 	}
538 	return ret;
539 }
540 
541 /**
542  * @brief Do SETDASA to set static address as dynamic address.
543  *
544  * @param dev Pointer to the device driver instance.
545  * @param[out] True if DAA is still needed. False if all registered
546  *             devices have static addresses.
547  *
548  * @retval 0 if successful.
549  */
i3c_bus_setdasa(const struct device * dev,const struct i3c_dev_list * dev_list,bool * need_daa,bool * need_aasa)550 static int i3c_bus_setdasa(const struct device *dev,
551 			   const struct i3c_dev_list *dev_list,
552 			   bool *need_daa, bool *need_aasa)
553 {
554 	int i, ret;
555 
556 	*need_daa = false;
557 	*need_aasa = false;
558 
559 	/* Loop through the registered I3C devices */
560 	for (i = 0; i < dev_list->num_i3c; i++) {
561 		struct i3c_device_desc *desc = &dev_list->i3c[i];
562 		struct i3c_driver_data *bus_data = (struct i3c_driver_data *)dev->data;
563 		struct i3c_ccc_address dyn_addr;
564 
565 		/*
566 		 * A device without static address => need to do
567 		 * dynamic address assignment.
568 		 */
569 		if (desc->static_addr == 0U) {
570 			*need_daa = true;
571 			continue;
572 		}
573 
574 		/*
575 		 * A device that supports SETAASA and will use the same dynamic
576 		 * address as its static address if a different dynamic address
577 		 * is not requested
578 		 */
579 		if ((desc->supports_setaasa) && ((desc->init_dynamic_addr == 0) ||
580 					       desc->init_dynamic_addr == desc->static_addr)) {
581 			*need_aasa = true;
582 			continue;
583 		}
584 
585 		LOG_DBG("SETDASA for 0x%x", desc->static_addr);
586 
587 		/*
588 		 * check that initial dynamic address is free before setting it
589 		 * if configured
590 		 */
591 		if ((desc->init_dynamic_addr != 0) &&
592 			(desc->init_dynamic_addr != desc->static_addr)) {
593 			if (!i3c_addr_slots_is_free(&bus_data->attached_dev.addr_slots,
594 				desc->init_dynamic_addr)) {
595 				if (i3c_detach_i3c_device(desc) != 0) {
596 					LOG_ERR("Failed to detach %s", desc->dev->name);
597 				}
598 				continue;
599 			}
600 		}
601 
602 		/*
603 		 * Note that the 7-bit address needs to start at bit 1
604 		 * (aka left-justified). So shift left by 1;
605 		 */
606 		dyn_addr.addr = (desc->init_dynamic_addr ?
607 					desc->init_dynamic_addr : desc->static_addr) << 1;
608 
609 		ret = i3c_ccc_do_setdasa(desc, dyn_addr);
610 		if (ret == 0) {
611 			desc->dynamic_addr = dyn_addr.addr >> 1;
612 			if (desc->dynamic_addr != desc->static_addr) {
613 				if (i3c_reattach_i3c_device(desc, desc->static_addr) != 0) {
614 					LOG_ERR("Failed to reattach %s (%d)", desc->dev->name, ret);
615 				}
616 			}
617 		} else {
618 			/* SETDASA failed, detach it from the controller */
619 			if (i3c_detach_i3c_device(desc) != 0) {
620 				LOG_ERR("Failed to detach %s (%d)", desc->dev->name, ret);
621 			}
622 			LOG_ERR("SETDASA error on address 0x%x (%d)",
623 				desc->static_addr, ret);
624 		}
625 	}
626 
627 	return 0;
628 }
629 
i3c_bus_has_sec_controller(const struct device * dev)630 bool i3c_bus_has_sec_controller(const struct device *dev)
631 {
632 	struct i3c_device_desc *i3c_desc;
633 
634 	I3C_BUS_FOR_EACH_I3CDEV(dev, i3c_desc) {
635 		if (i3c_device_is_controller_capable(i3c_desc)) {
636 			return true;
637 		}
638 	}
639 
640 	return false;
641 }
642 
i3c_bus_deftgts(const struct device * dev)643 int i3c_bus_deftgts(const struct device *dev)
644 {
645 	struct i3c_driver_data *data = (struct i3c_driver_data *)dev->data;
646 	struct i3c_config_target config_target;
647 	struct i3c_ccc_deftgts *deftgts;
648 	struct i3c_device_desc *i3c_desc;
649 	struct i3c_i2c_device_desc *i3c_i2c_desc;
650 	int ret;
651 	uint8_t n = 0;
652 	size_t num_of_targets = sys_slist_len(&data->attached_dev.devices.i3c) +
653 				sys_slist_len(&data->attached_dev.devices.i2c);
654 	size_t data_len = sizeof(uint8_t) +
655 				   sizeof(struct i3c_ccc_deftgts_active_controller) +
656 				   (num_of_targets * sizeof(struct i3c_ccc_deftgts_target));
657 
658 	/*
659 	 * Retrieve the active controller information
660 	 */
661 	ret = i3c_config_get(dev, I3C_CONFIG_TARGET, &config_target);
662 	if (ret != 0) {
663 		LOG_ERR("Failed to retrieve active controller info");
664 		return ret;
665 	}
666 
667 	/* Allocate memory for the struct with enough space for the targets */
668 	deftgts = malloc(data_len);
669 	if (!deftgts) {
670 		return -ENOMEM;
671 	}
672 
673 	/*
674 	 * Write the total number of I3C and I2C targets to the payload
675 	 */
676 	deftgts->count = num_of_targets;
677 
678 	/*
679 	 * Add the active controller information to the payload
680 	 */
681 	deftgts->active_controller.addr = config_target.dynamic_addr << 1;
682 	deftgts->active_controller.dcr = config_target.dcr;
683 	deftgts->active_controller.bcr = config_target.bcr;
684 	deftgts->active_controller.static_addr = I3C_BROADCAST_ADDR << 1;
685 
686 	/*
687 	 * Loop through each attached I3C device and add it to the payload
688 	 */
689 	I3C_BUS_FOR_EACH_I3CDEV(dev, i3c_desc) {
690 		deftgts->targets[n].addr = i3c_desc->dynamic_addr << 1;
691 		deftgts->targets[n].dcr = i3c_desc->dcr;
692 		deftgts->targets[n].bcr = i3c_desc->bcr;
693 		deftgts->targets[n].static_addr = i3c_desc->static_addr << 1;
694 		n++;
695 	}
696 
697 	/*
698 	 * Loop through each attached I2C device and add it to the payload
699 	 */
700 	I3C_BUS_FOR_EACH_I2CDEV(dev, i3c_i2c_desc) {
701 		deftgts->targets[n].addr = 0;
702 		deftgts->targets[n].lvr = i3c_i2c_desc->lvr;
703 		deftgts->targets[n].bcr = 0;
704 		deftgts->targets[n].static_addr = (uint8_t)(i3c_i2c_desc->addr << 1);
705 		n++;
706 	}
707 
708 	/* TODO: add support for Group Addr in DEFTGTS when that comes */
709 
710 	ret = i3c_ccc_do_deftgts_all(dev, deftgts);
711 
712 	free(deftgts);
713 
714 	return ret;
715 }
716 
i3c_bus_init(const struct device * dev,const struct i3c_dev_list * dev_list)717 int i3c_bus_init(const struct device *dev, const struct i3c_dev_list *dev_list)
718 {
719 	int i, ret = 0;
720 	bool need_daa = true;
721 	bool need_aasa = true;
722 	struct i3c_ccc_events i3c_events;
723 
724 #ifdef CONFIG_I3C_INIT_RSTACT
725 	/*
726 	 * Reset all connected targets. Also reset dynamic
727 	 * addresses for all devices as we have no idea what
728 	 * dynamic addresses the connected devices have
729 	 * (e.g. assigned during previous power cycle).
730 	 *
731 	 * Note that we ignore error for both RSTACT and RSTDAA
732 	 * as there may not be any connected devices responding
733 	 * to these CCCs.
734 	 */
735 	if (i3c_ccc_do_rstact_all(dev, I3C_CCC_RSTACT_RESET_WHOLE_TARGET) != 0) {
736 		/*
737 		 * Reset Whole Target support is not required so
738 		 * if there is any NACK, we want to at least reset
739 		 * the I3C peripheral of targets.
740 		 */
741 		LOG_DBG("Broadcast RSTACT (whole target) was NACK.");
742 
743 		if (i3c_ccc_do_rstact_all(dev, I3C_CCC_RSTACT_PERIPHERAL_ONLY) != 0) {
744 			LOG_DBG("Broadcast RSTACT (peripehral) was NACK.");
745 		}
746 	}
747 #endif
748 
749 	if (i3c_ccc_do_rstdaa_all(dev) != 0) {
750 		LOG_DBG("Broadcast RSTDAA was NACK.");
751 	}
752 
753 	/*
754 	 * Disable all events from targets to avoid them
755 	 * interfering with bus initialization,
756 	 * especially during DAA.
757 	 */
758 	i3c_events.events = I3C_CCC_EVT_ALL;
759 	ret = i3c_ccc_do_events_all_set(dev, false, &i3c_events);
760 	if (ret != 0) {
761 		LOG_DBG("Broadcast DISEC was NACK.");
762 	}
763 
764 	/*
765 	 * Set static addresses as dynamic addresses.
766 	 */
767 	ret = i3c_bus_setdasa(dev, dev_list, &need_daa, &need_aasa);
768 	if (ret != 0) {
769 		goto err_out;
770 	}
771 
772 	/*
773 	 * Perform Set All Addresses to Static Address if possible.
774 	 */
775 	if (need_aasa) {
776 		ret = i3c_ccc_do_setaasa_all(dev);
777 		if (ret != 0) {
778 			for (i = 0; i < dev_list->num_i3c; i++) {
779 				struct i3c_device_desc *desc = &dev_list->i3c[i];
780 				/*
781 				 * Only set for devices that support SETAASA and do not
782 				 * request a different dynamic address than its SA
783 				 */
784 				if ((desc->supports_setaasa) && (desc->static_addr != 0) &&
785 				    ((desc->init_dynamic_addr == 0) ||
786 				     desc->init_dynamic_addr == desc->static_addr)) {
787 					desc->dynamic_addr = desc->static_addr;
788 				}
789 			}
790 		}
791 	}
792 
793 	/*
794 	 * Perform Dynamic Address Assignment if needed.
795 	 */
796 	if (need_daa) {
797 		ret = i3c_do_daa(dev);
798 		if (ret != 0) {
799 			/*
800 			 * Spec says to try once more
801 			 * if DAA fails the first time.
802 			 */
803 			ret = i3c_do_daa(dev);
804 			if (ret != 0) {
805 				/*
806 				 * Failure to finish dynamic address assignment
807 				 * is not the end of world... hopefully.
808 				 * Continue on so the devices already have
809 				 * addresses can still function.
810 				 */
811 				LOG_ERR("DAA was not successful.");
812 			}
813 		}
814 	}
815 
816 	/*
817 	 * Loop through the registered I3C devices to retrieve
818 	 * basic target information.
819 	 */
820 	for (i = 0; i < dev_list->num_i3c; i++) {
821 		struct i3c_device_desc *desc = &dev_list->i3c[i];
822 
823 		if (desc->dynamic_addr == 0U) {
824 			continue;
825 		}
826 
827 		ret = i3c_device_basic_info_get(desc);
828 		if (ret != 0) {
829 			LOG_ERR("Error getting basic device info for 0x%02x",
830 				desc->static_addr);
831 		} else {
832 			LOG_DBG("Target 0x%02x, BCR 0x%02x, DCR 0x%02x, MRL %d, MWL %d, IBI %d",
833 				desc->dynamic_addr, desc->bcr, desc->dcr,
834 				desc->data_length.mrl, desc->data_length.mwl,
835 				desc->data_length.max_ibi);
836 		}
837 	}
838 
839 	if (i3c_bus_has_sec_controller(dev)) {
840 		ret = i3c_bus_deftgts(dev);
841 		if (ret != 0) {
842 			LOG_ERR("Error sending DEFTGTS");
843 		}
844 	}
845 
846 	/*
847 	 * Only re-enable Hot-Join from targets.
848 	 * Target interrupts will be enabled when IBI is enabled.
849 	 * And transferring controller role is not supported so not need to
850 	 * enable the event.
851 	 */
852 	i3c_events.events = I3C_CCC_EVT_HJ;
853 	ret = i3c_ccc_do_events_all_set(dev, true, &i3c_events);
854 	if (ret != 0) {
855 		LOG_DBG("Broadcast ENEC was NACK.");
856 	}
857 
858 err_out:
859 	return ret;
860 }
861