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