1 /*
2  * Copyright (c) 2024 Meta Platforms
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/i3c.h>
8 #include <zephyr/shell/shell.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <zephyr/sys/byteorder.h>
12 #include <zephyr/sys/util.h>
13 
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(i3c_shell, CONFIG_LOG_DEFAULT_LEVEL);
16 
17 #define MAX_BYTES_FOR_REGISTER_INDEX 4
18 #define ARGV_DEV                     1
19 #define ARGV_TDEV                    2
20 #define ARGV_REG                     3
21 
22 /* Maximum bytes we can write or read at once */
23 #define MAX_I3C_BYTES 16
24 
25 struct i3c_ctrl {
26 	const struct device *dev;
27 	const union shell_cmd_entry *i3c_attached_dev_subcmd;
28 	const union shell_cmd_entry *i3c_list_dev_subcmd;
29 };
30 
31 #define I3C_ATTACHED_DEV_GET_FN(node_id)                                                           \
32 	static void node_id##cmd_i3c_attached_get(size_t idx, struct shell_static_entry *entry);   \
33                                                                                                    \
34 	SHELL_DYNAMIC_CMD_CREATE(node_id##sub_i3c_attached, node_id##cmd_i3c_attached_get);        \
35                                                                                                    \
36 	static void node_id##cmd_i3c_attached_get(size_t idx, struct shell_static_entry *entry)    \
37 	{                                                                                          \
38 		const struct device *dev = DEVICE_DT_GET(node_id);                                 \
39 		struct i3c_device_desc *i3c_desc;                                                  \
40 		size_t cnt = 0;                                                                    \
41                                                                                                    \
42 		entry->syntax = NULL;                                                              \
43 		entry->handler = NULL;                                                             \
44 		entry->subcmd = NULL;                                                              \
45 		entry->help = NULL;                                                                \
46                                                                                                    \
47 		I3C_BUS_FOR_EACH_I3CDEV(dev, i3c_desc) {                                           \
48 			if (cnt == idx) {                                                          \
49 				entry->syntax = i3c_desc->dev->name;                               \
50 				return;                                                            \
51 			}                                                                          \
52 			cnt++;                                                                     \
53 		}                                                                                  \
54 	}
55 
56 #define I3C_LIST_DEV_GET_FN(node_id)                                                               \
57 	static void node_id##cmd_i3c_list_get(size_t idx, struct shell_static_entry *entry);       \
58                                                                                                    \
59 	SHELL_DYNAMIC_CMD_CREATE(node_id##sub_i3c_list, node_id##cmd_i3c_list_get);                \
60                                                                                                    \
61 	static void node_id##cmd_i3c_list_get(size_t idx, struct shell_static_entry *entry)        \
62 	{                                                                                          \
63 		const struct device *dev = DEVICE_DT_GET(node_id);                                 \
64 		struct i3c_driver_config *config;                                                  \
65                                                                                                    \
66 		entry->syntax = NULL;                                                              \
67 		entry->handler = NULL;                                                             \
68 		entry->subcmd = NULL;                                                              \
69 		entry->help = NULL;                                                                \
70                                                                                                    \
71 		config = (struct i3c_driver_config *)dev->config;                                  \
72 		if (idx < config->dev_list.num_i3c) {                                              \
73 			entry->syntax = config->dev_list.i3c[idx].dev->name;                       \
74 		}                                                                                  \
75 	}
76 
77 #define I3C_CTRL_FN(node_id)                                                                       \
78 	I3C_ATTACHED_DEV_GET_FN(node_id)                                                           \
79 	I3C_LIST_DEV_GET_FN(node_id)
80 
81 /* zephyr-keep-sorted-start */
82 DT_FOREACH_STATUS_OKAY(cdns_i3c, I3C_CTRL_FN)
83 DT_FOREACH_STATUS_OKAY(nuvoton_npcx_i3c, I3C_CTRL_FN)
84 DT_FOREACH_STATUS_OKAY(nxp_mcux_i3c, I3C_CTRL_FN)
85 DT_FOREACH_STATUS_OKAY(snps_designware_i3c, I3C_CTRL_FN)
86 DT_FOREACH_STATUS_OKAY(st_stm32_i3c, I3C_CTRL_FN)
87 /* zephyr-keep-sorted-stop */
88 
89 #define I3C_CTRL_LIST_ENTRY(node_id)                                                               \
90 	{                                                                                          \
91 		.dev = DEVICE_DT_GET(node_id),                                                     \
92 		.i3c_attached_dev_subcmd = &node_id##sub_i3c_attached,                             \
93 		.i3c_list_dev_subcmd = &node_id##sub_i3c_list,                                     \
94 	},
95 
96 const struct i3c_ctrl i3c_list[] = {
97 	/* zephyr-keep-sorted-start */
98 	DT_FOREACH_STATUS_OKAY(cdns_i3c, I3C_CTRL_LIST_ENTRY)
99 	DT_FOREACH_STATUS_OKAY(nuvoton_npcx_i3c, I3C_CTRL_LIST_ENTRY)
100 	DT_FOREACH_STATUS_OKAY(nxp_mcux_i3c, I3C_CTRL_LIST_ENTRY)
101 	DT_FOREACH_STATUS_OKAY(snps_designware_i3c, I3C_CTRL_LIST_ENTRY)
102 	DT_FOREACH_STATUS_OKAY(st_stm32_i3c, I3C_CTRL_LIST_ENTRY)
103 	/* zephyr-keep-sorted-stop */
104 };
105 
get_bytes_count_for_hex(char * arg)106 static int get_bytes_count_for_hex(char *arg)
107 {
108 	int length = (strlen(arg) + 1) / 2;
109 
110 	if (length > 1 && arg[0] == '0' && (arg[1] == 'x' || arg[1] == 'X')) {
111 		length -= 1;
112 	}
113 
114 	return MIN(MAX_BYTES_FOR_REGISTER_INDEX, length);
115 }
116 
get_i3c_list_desc_from_dev_name(const struct device * dev,const char * tdev_name)117 static struct i3c_device_desc *get_i3c_list_desc_from_dev_name(const struct device *dev,
118 							       const char *tdev_name)
119 {
120 	struct i3c_driver_config *config;
121 	uint8_t i;
122 
123 	config = (struct i3c_driver_config *)dev->config;
124 	for (i = 0; i < config->dev_list.num_i3c; i++) {
125 		if (strcmp(config->dev_list.i3c[i].dev->name, tdev_name) == 0) {
126 			/* only look for a device with the same name */
127 			return &config->dev_list.i3c[i];
128 		}
129 	}
130 
131 	return NULL;
132 }
133 
get_i3c_attached_desc_from_dev_name(const struct device * dev,const char * tdev_name)134 static struct i3c_device_desc *get_i3c_attached_desc_from_dev_name(const struct device *dev,
135 								   const char *tdev_name)
136 {
137 	struct i3c_device_desc *i3c_desc;
138 
139 	I3C_BUS_FOR_EACH_I3CDEV(dev, i3c_desc) {
140 		/* only look for a device with the same name */
141 		if (strcmp(i3c_desc->dev->name, tdev_name) == 0) {
142 			return i3c_desc;
143 		}
144 	}
145 
146 	return NULL;
147 }
148 
i3c_parse_args(const struct shell * sh,char ** argv,const struct device ** dev,const struct device ** tdev,struct i3c_device_desc ** desc)149 static int i3c_parse_args(const struct shell *sh, char **argv, const struct device **dev,
150 			  const struct device **tdev, struct i3c_device_desc **desc)
151 {
152 	*dev = shell_device_get_binding(argv[ARGV_DEV]);
153 	if (!*dev) {
154 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
155 		return -ENODEV;
156 	}
157 	*tdev = shell_device_get_binding(argv[ARGV_TDEV]);
158 	if (!*tdev) {
159 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_TDEV]);
160 		return -ENODEV;
161 	}
162 	*desc = get_i3c_attached_desc_from_dev_name(*dev, (*tdev)->name);
163 	if (!*desc) {
164 		shell_error(sh, "I3C: Device %s not attached to bus.", (*tdev)->name);
165 		return -ENODEV;
166 	}
167 
168 	return 0;
169 }
170 
171 /* i3c info <device> [<target>] */
cmd_i3c_info(const struct shell * sh,size_t argc,char ** argv)172 static int cmd_i3c_info(const struct shell *sh, size_t argc, char **argv)
173 {
174 	const struct device *dev, *tdev;
175 	struct i3c_driver_data *data;
176 	struct i3c_device_desc *desc;
177 	struct i3c_i2c_device_desc *i2c_desc;
178 	bool found = false;
179 
180 	dev = shell_device_get_binding(argv[ARGV_DEV]);
181 
182 	if (!dev) {
183 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
184 		return -ENODEV;
185 	}
186 	data = (struct i3c_driver_data *)dev->data;
187 
188 	if (argc == 3) {
189 		tdev = shell_device_get_binding(argv[ARGV_TDEV]);
190 		if (!tdev) {
191 			shell_error(sh, "I3C: Target Device driver %s not found.", argv[ARGV_TDEV]);
192 			return -ENODEV;
193 		}
194 		if (!sys_slist_is_empty(&data->attached_dev.devices.i3c)) {
195 			I3C_BUS_FOR_EACH_I3CDEV(dev, desc) {
196 				/* only look for a device with the same name */
197 				if (strcmp(desc->dev->name, tdev->name) == 0) {
198 					shell_print(sh,
199 						    "name: %s\n"
200 						    "\tpid: 0x%012llx\n"
201 						    "\tstatic_addr: 0x%02x\n"
202 						    "\tdynamic_addr: 0x%02x\n"
203 #if defined(CONFIG_I3C_USE_GROUP_ADDR)
204 						    "\tgroup_addr: 0x%02x\n"
205 #endif
206 						    "\tbcr: 0x%02x\n"
207 						    "\tdcr: 0x%02x\n"
208 						    "\tmaxrd: 0x%02x\n"
209 						    "\tmaxwr: 0x%02x\n"
210 						    "\tmax_read_turnaround: 0x%06x\n"
211 						    "\tmrl: 0x%04x\n"
212 						    "\tmwl: 0x%04x\n"
213 						    "\tmax_ibi: 0x%02x\n"
214 						    "\tcrhdly1: 0x%02x\n"
215 						    "\tgetcaps: 0x%02x; 0x%02x; 0x%02x; 0x%02x\n"
216 						    "\tcrcaps: 0x%02x; 0x%02x",
217 						    desc->dev->name, (uint64_t)desc->pid,
218 						    desc->static_addr, desc->dynamic_addr,
219 #if defined(CONFIG_I3C_USE_GROUP_ADDR)
220 						    desc->group_addr,
221 #endif
222 						    desc->bcr, desc->dcr, desc->data_speed.maxrd,
223 						    desc->data_speed.maxwr,
224 						    desc->data_speed.max_read_turnaround,
225 						    desc->data_length.mrl, desc->data_length.mwl,
226 						    desc->data_length.max_ibi, desc->crhdly1,
227 						    desc->getcaps.getcap1, desc->getcaps.getcap2,
228 						    desc->getcaps.getcap3, desc->getcaps.getcap4,
229 						    desc->crcaps.crcaps1, desc->crcaps.crcaps2);
230 					found = true;
231 					break;
232 				}
233 			}
234 		} else {
235 			shell_print(sh, "I3C: No devices found.");
236 			return -ENODEV;
237 		}
238 		if (found == false) {
239 			shell_error(sh, "I3C: Target device not found.");
240 			return -ENODEV;
241 		}
242 	} else if (argc == 2) {
243 		/* This gets all "currently attached" I3C and I2C devices */
244 		if (!sys_slist_is_empty(&data->attached_dev.devices.i3c)) {
245 			shell_print(sh, "I3C: Devices found:");
246 			I3C_BUS_FOR_EACH_I3CDEV(dev, desc) {
247 				shell_print(sh,
248 					    "name: %s\n"
249 					    "\tpid: 0x%012llx\n"
250 					    "\tstatic_addr: 0x%02x\n"
251 					    "\tdynamic_addr: 0x%02x\n"
252 #if defined(CONFIG_I3C_USE_GROUP_ADDR)
253 					    "\tgroup_addr: 0x%02x\n"
254 #endif
255 					    "\tbcr: 0x%02x\n"
256 					    "\tdcr: 0x%02x\n"
257 					    "\tmaxrd: 0x%02x\n"
258 					    "\tmaxwr: 0x%02x\n"
259 					    "\tmax_read_turnaround: 0x%06x\n"
260 					    "\tmrl: 0x%04x\n"
261 					    "\tmwl: 0x%04x\n"
262 					    "\tmax_ibi: 0x%02x\n"
263 					    "\tcrhdly1: 0x%02x\n"
264 					    "\tgetcaps: 0x%02x; 0x%02x; 0x%02x; 0x%02x\n"
265 					    "\tcrcaps: 0x%02x; 0x%02x",
266 					    desc->dev->name, (uint64_t)desc->pid, desc->static_addr,
267 					    desc->dynamic_addr,
268 #if defined(CONFIG_I3C_USE_GROUP_ADDR)
269 					    desc->group_addr,
270 #endif
271 					    desc->bcr, desc->dcr, desc->data_speed.maxrd,
272 					    desc->data_speed.maxwr,
273 					    desc->data_speed.max_read_turnaround,
274 					    desc->data_length.mrl, desc->data_length.mwl,
275 					    desc->data_length.max_ibi, desc->crhdly1,
276 					    desc->getcaps.getcap1, desc->getcaps.getcap2,
277 					    desc->getcaps.getcap3, desc->getcaps.getcap4,
278 					    desc->crcaps.crcaps1, desc->crcaps.crcaps2);
279 			}
280 		} else {
281 			shell_print(sh, "I3C: No devices found.");
282 		}
283 		if (!sys_slist_is_empty(&data->attached_dev.devices.i2c)) {
284 			shell_print(sh, "I2C: Devices found:");
285 			I3C_BUS_FOR_EACH_I2CDEV(dev, i2c_desc) {
286 				shell_print(sh,
287 					    "addr: 0x%02x\n"
288 					    "\tlvr: 0x%02x",
289 					    i2c_desc->addr, i2c_desc->lvr);
290 			}
291 		} else {
292 			shell_print(sh, "I2C: No devices found.");
293 		}
294 	} else {
295 		shell_error(sh, "Invalid number of arguments.");
296 	}
297 
298 	return 0;
299 }
300 
301 /* i3c speed <device> <speed> */
cmd_i3c_speed(const struct shell * sh,size_t argc,char ** argv)302 static int cmd_i3c_speed(const struct shell *sh, size_t argc, char **argv)
303 {
304 	const struct device *dev;
305 	struct i3c_config_controller config;
306 	uint32_t speed;
307 	int ret;
308 
309 	dev = shell_device_get_binding(argv[ARGV_DEV]);
310 	if (!dev) {
311 		shell_error(sh, "I3C: Device driver %s not found.", argv[1]);
312 		return -ENODEV;
313 	}
314 
315 	speed = strtol(argv[ARGV_DEV + 1], NULL, 10);
316 
317 	ret = i3c_config_get(dev, I3C_CONFIG_CONTROLLER, &config);
318 	if (ret != 0) {
319 		shell_error(sh, "I3C: Failed to retrieve configuration");
320 		return ret;
321 	}
322 
323 	config.scl.i3c = speed;
324 
325 	ret = i3c_configure(dev, I3C_CONFIG_CONTROLLER, &config);
326 	if (ret != 0) {
327 		shell_error(sh, "I3C: Failed to configure device");
328 		return ret;
329 	}
330 
331 	return ret;
332 }
333 
334 /* i3c recover <device> */
cmd_i3c_recover(const struct shell * sh,size_t argc,char ** argv)335 static int cmd_i3c_recover(const struct shell *sh, size_t argc, char **argv)
336 {
337 	const struct device *dev;
338 	int err;
339 
340 	dev = shell_device_get_binding(argv[ARGV_DEV]);
341 	if (!dev) {
342 		shell_error(sh, "I3C: Device driver %s not found.", argv[1]);
343 		return -ENODEV;
344 	}
345 
346 	err = i3c_recover_bus(dev);
347 	if (err) {
348 		shell_error(sh, "I3C: Bus recovery failed (err %d)", err);
349 		return err;
350 	}
351 
352 	return 0;
353 }
354 
i3c_write_from_buffer(const struct shell * sh,char * s_dev_name,char * s_tdev_name,char * s_reg_addr,char ** data,uint8_t data_length)355 static int i3c_write_from_buffer(const struct shell *sh, char *s_dev_name, char *s_tdev_name,
356 				 char *s_reg_addr, char **data, uint8_t data_length)
357 {
358 	/* This buffer must preserve 4 bytes for register address, as it is
359 	 * filled using put_be32 function and we don't want to lower available
360 	 * space when using 1 byte address.
361 	 */
362 	uint8_t buf[MAX_I3C_BYTES + MAX_BYTES_FOR_REGISTER_INDEX - 1];
363 	const struct device *dev, *tdev;
364 	struct i3c_device_desc *desc;
365 	int reg_addr_bytes;
366 	int reg_addr;
367 	int ret;
368 	int i;
369 
370 	dev = shell_device_get_binding(s_dev_name);
371 	if (!dev) {
372 		shell_error(sh, "I3C: Device driver %s not found.", s_dev_name);
373 		return -ENODEV;
374 	}
375 	tdev = shell_device_get_binding(s_tdev_name);
376 	if (!tdev) {
377 		shell_error(sh, "I3C: Device driver %s not found.", s_tdev_name);
378 		return -ENODEV;
379 	}
380 	desc = get_i3c_attached_desc_from_dev_name(dev, tdev->name);
381 	if (!desc) {
382 		shell_error(sh, "I3C: Device %s not attached to bus.", tdev->name);
383 		return -ENODEV;
384 	}
385 
386 	reg_addr = strtol(s_reg_addr, NULL, 16);
387 
388 	reg_addr_bytes = get_bytes_count_for_hex(s_reg_addr);
389 	sys_put_be32(reg_addr, buf);
390 
391 	if (data_length + reg_addr_bytes > MAX_I3C_BYTES) {
392 		data_length = MAX_I3C_BYTES - reg_addr_bytes;
393 		shell_info(sh, "Too many bytes provided, limit is %d",
394 			   MAX_I3C_BYTES - reg_addr_bytes);
395 	}
396 
397 	for (i = 0; i < data_length; i++) {
398 		buf[MAX_BYTES_FOR_REGISTER_INDEX + i] = (uint8_t)strtol(data[i], NULL, 16);
399 	}
400 
401 	ret = i3c_write(desc, buf + MAX_BYTES_FOR_REGISTER_INDEX - reg_addr_bytes,
402 			reg_addr_bytes + data_length);
403 	if (ret < 0) {
404 		shell_error(sh, "Failed to write to device: %s", tdev->name);
405 		return -EIO;
406 	}
407 
408 	return 0;
409 }
410 
411 /* i3c write <device> <dev_addr> <reg_addr> [<byte1>, ...] */
cmd_i3c_write(const struct shell * sh,size_t argc,char ** argv)412 static int cmd_i3c_write(const struct shell *sh, size_t argc, char **argv)
413 {
414 	return i3c_write_from_buffer(sh, argv[ARGV_DEV], argv[ARGV_TDEV], argv[ARGV_REG], &argv[4],
415 				     argc - 4);
416 }
417 
418 /* i3c write_byte <device> <dev_addr> <reg_addr> <value> */
cmd_i3c_write_byte(const struct shell * sh,size_t argc,char ** argv)419 static int cmd_i3c_write_byte(const struct shell *sh, size_t argc, char **argv)
420 {
421 	return i3c_write_from_buffer(sh, argv[ARGV_DEV], argv[ARGV_TDEV], argv[ARGV_REG], &argv[4],
422 				     1);
423 }
424 
i3c_read_to_buffer(const struct shell * sh,char * s_dev_name,char * s_tdev_name,char * s_reg_addr,uint8_t * buf,uint8_t buf_length)425 static int i3c_read_to_buffer(const struct shell *sh, char *s_dev_name, char *s_tdev_name,
426 			      char *s_reg_addr, uint8_t *buf, uint8_t buf_length)
427 {
428 	const struct device *dev, *tdev;
429 	struct i3c_device_desc *desc;
430 	uint8_t reg_addr_buf[MAX_BYTES_FOR_REGISTER_INDEX];
431 	int reg_addr_bytes;
432 	int reg_addr;
433 	int ret;
434 
435 	dev = shell_device_get_binding(s_dev_name);
436 	if (!dev) {
437 		shell_error(sh, "I3C: Device driver %s not found.", s_dev_name);
438 		return -ENODEV;
439 	}
440 	tdev = shell_device_get_binding(s_tdev_name);
441 	if (!tdev) {
442 		shell_error(sh, "I3C: Device driver %s not found.", s_dev_name);
443 		return -ENODEV;
444 	}
445 	desc = get_i3c_attached_desc_from_dev_name(dev, tdev->name);
446 	if (!desc) {
447 		shell_error(sh, "I3C: Device %s not attached to bus.", tdev->name);
448 		return -ENODEV;
449 	}
450 
451 	reg_addr = strtol(s_reg_addr, NULL, 16);
452 
453 	reg_addr_bytes = get_bytes_count_for_hex(s_reg_addr);
454 	sys_put_be32(reg_addr, reg_addr_buf);
455 
456 	ret = i3c_write_read(desc, reg_addr_buf + MAX_BYTES_FOR_REGISTER_INDEX - reg_addr_bytes,
457 			     reg_addr_bytes, buf, buf_length);
458 	if (ret < 0) {
459 		shell_error(sh, "Failed to read from device: %s", tdev->name);
460 		return -EIO;
461 	}
462 
463 	return 0;
464 }
465 
466 /* i3c read_byte <device> <target> <reg_addr> */
cmd_i3c_read_byte(const struct shell * sh,size_t argc,char ** argv)467 static int cmd_i3c_read_byte(const struct shell *sh, size_t argc, char **argv)
468 {
469 	uint8_t out;
470 	int ret;
471 
472 	ret = i3c_read_to_buffer(sh, argv[ARGV_DEV], argv[ARGV_TDEV], argv[ARGV_REG], &out, 1);
473 	if (ret == 0) {
474 		shell_print(sh, "Output: 0x%x", out);
475 	}
476 
477 	return ret;
478 }
479 
480 /* i3c read <device> <target> <reg_addr> [<numbytes>] */
cmd_i3c_read(const struct shell * sh,size_t argc,char ** argv)481 static int cmd_i3c_read(const struct shell *sh, size_t argc, char **argv)
482 {
483 	uint8_t buf[MAX_I3C_BYTES];
484 	int num_bytes;
485 	int ret;
486 
487 	if (argc > 4) {
488 		num_bytes = strtol(argv[4], NULL, 16);
489 		if (num_bytes > MAX_I3C_BYTES) {
490 			num_bytes = MAX_I3C_BYTES;
491 		}
492 	} else {
493 		num_bytes = MAX_I3C_BYTES;
494 	}
495 
496 	ret = i3c_read_to_buffer(sh, argv[ARGV_DEV], argv[ARGV_TDEV], argv[ARGV_REG], buf,
497 				 num_bytes);
498 	if (ret == 0) {
499 		shell_hexdump(sh, buf, num_bytes);
500 	}
501 
502 	return ret;
503 }
504 
505 /* i3c hdr ddr read <device> <target> <7b cmd> [<byte1>, ...] */
cmd_i3c_hdr_ddr_write(const struct shell * sh,size_t argc,char ** argv)506 static int cmd_i3c_hdr_ddr_write(const struct shell *sh, size_t argc, char **argv)
507 {
508 	const struct device *dev, *tdev;
509 	struct i3c_device_desc *desc;
510 	uint8_t buf[MAX_I3C_BYTES];
511 	uint8_t cmd;
512 	uint8_t data_length;
513 	uint8_t i;
514 	int ret;
515 
516 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
517 	if (ret != 0) {
518 		return ret;
519 	}
520 
521 	cmd = strtol(argv[3], NULL, 16);
522 
523 	data_length = argc - 4;
524 	if (data_length > MAX_I3C_BYTES) {
525 		shell_info(sh, "Too many bytes provided, limit is %d", MAX_I3C_BYTES);
526 	}
527 
528 	for (i = 0; i < data_length; i++) {
529 		buf[i] = (uint8_t)strtol(argv[4 + i], NULL, 16);
530 	}
531 
532 	ret = i3c_hdr_ddr_write(desc, cmd, buf, data_length);
533 	if (ret != 0) {
534 		shell_error(sh, "I3C: unable to perform HDR DDR write.");
535 		return ret;
536 	}
537 
538 	return ret;
539 }
540 
541 /* i3c hdr ddr read <device> <target> <7b cmd> [<numbytes>] */
cmd_i3c_hdr_ddr_read(const struct shell * sh,size_t argc,char ** argv)542 static int cmd_i3c_hdr_ddr_read(const struct shell *sh, size_t argc, char **argv)
543 {
544 	const struct device *dev, *tdev;
545 	struct i3c_device_desc *desc;
546 	uint8_t buf[MAX_I3C_BYTES];
547 	int num_bytes;
548 	uint8_t cmd;
549 	int ret;
550 
551 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
552 	if (ret != 0) {
553 		return ret;
554 	}
555 
556 	cmd = strtol(argv[3], NULL, 16);
557 
558 	if (argc > 4) {
559 		num_bytes = strtol(argv[4], NULL, 16);
560 		if (num_bytes > MAX_I3C_BYTES) {
561 			num_bytes = MAX_I3C_BYTES;
562 		}
563 	} else {
564 		num_bytes = MAX_I3C_BYTES;
565 	}
566 
567 	ret = i3c_hdr_ddr_read(desc, cmd, buf, num_bytes);
568 	if (ret != 0) {
569 		shell_error(sh, "I3C: unable to perform HDR DDR read.");
570 		return ret;
571 	}
572 
573 	shell_hexdump(sh, buf, num_bytes);
574 
575 	return ret;
576 }
577 
578 /* i3c ccc rstdaa <device> */
cmd_i3c_ccc_rstdaa(const struct shell * sh,size_t argc,char ** argv)579 static int cmd_i3c_ccc_rstdaa(const struct shell *sh, size_t argc, char **argv)
580 {
581 	const struct device *dev;
582 	struct i3c_device_desc *desc;
583 	int ret;
584 
585 	dev = shell_device_get_binding(argv[ARGV_DEV]);
586 	if (!dev) {
587 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
588 		return -ENODEV;
589 	}
590 
591 	ret = i3c_ccc_do_rstdaa_all(dev);
592 	if (ret < 0) {
593 		shell_error(sh, "I3C: unable to send CCC RSTDAA.");
594 		return ret;
595 	}
596 
597 	/* reset all devices DA */
598 	I3C_BUS_FOR_EACH_I3CDEV(dev, desc) {
599 		desc->dynamic_addr = 0;
600 		shell_print(sh, "Reset dynamic address for device %s", desc->dev->name);
601 	}
602 
603 	return ret;
604 }
605 
606 /* i3c ccc entdaa <device> */
cmd_i3c_ccc_entdaa(const struct shell * sh,size_t argc,char ** argv)607 static int cmd_i3c_ccc_entdaa(const struct shell *sh, size_t argc, char **argv)
608 {
609 	const struct device *dev;
610 
611 	dev = shell_device_get_binding(argv[ARGV_DEV]);
612 	if (!dev) {
613 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
614 		return -ENODEV;
615 	}
616 
617 	return i3c_do_daa(dev);
618 }
619 
620 /* i3c ccc setaasa <device> */
cmd_i3c_ccc_setaasa(const struct shell * sh,size_t argc,char ** argv)621 static int cmd_i3c_ccc_setaasa(const struct shell *sh, size_t argc, char **argv)
622 {
623 	const struct device *dev;
624 	struct i3c_device_desc *desc;
625 	int ret;
626 
627 	dev = shell_device_get_binding(argv[ARGV_DEV]);
628 	if (!dev) {
629 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
630 		return -ENODEV;
631 	}
632 
633 	ret = i3c_ccc_do_setaasa_all(dev);
634 	if (ret < 0) {
635 		shell_error(sh, "I3C: unable to send CCC SETAASA.");
636 		return ret;
637 	}
638 
639 	/* set all devices DA to SA */
640 	I3C_BUS_FOR_EACH_I3CDEV(dev, desc) {
641 		if ((desc->supports_setaasa) && (desc->dynamic_addr == 0) &&
642 		    (desc->static_addr != 0)) {
643 			desc->dynamic_addr = desc->static_addr;
644 		}
645 	}
646 
647 	return ret;
648 }
649 
650 /* i3c ccc setdasa <device> <target> <dynamic address> */
cmd_i3c_ccc_setdasa(const struct shell * sh,size_t argc,char ** argv)651 static int cmd_i3c_ccc_setdasa(const struct shell *sh, size_t argc, char **argv)
652 {
653 	const struct device *dev, *tdev;
654 	struct i3c_device_desc *desc;
655 	struct i3c_driver_data *data;
656 	struct i3c_ccc_address da;
657 	uint8_t dynamic_addr;
658 	int ret;
659 
660 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
661 	if (ret != 0) {
662 		return ret;
663 	}
664 
665 	data = (struct i3c_driver_data *)dev->data;
666 	dynamic_addr = strtol(argv[3], NULL, 16);
667 	da.addr = dynamic_addr << 1;
668 	/* check if the addressed is free */
669 	if (!i3c_addr_slots_is_free(&data->attached_dev.addr_slots, dynamic_addr)) {
670 		shell_error(sh, "I3C: Address 0x%02x is already in use.", dynamic_addr);
671 		return -EINVAL;
672 	}
673 	ret = i3c_ccc_do_setdasa(desc, da);
674 	if (ret < 0) {
675 		shell_error(sh, "I3C: unable to send CCC SETDASA.");
676 		return ret;
677 	}
678 
679 	/* update the target's dynamic address */
680 	desc->dynamic_addr = dynamic_addr;
681 	if (desc->dynamic_addr != desc->static_addr) {
682 		ret = i3c_reattach_i3c_device(desc, desc->static_addr);
683 		if (ret < 0) {
684 			shell_error(sh, "I3C: unable to reattach device");
685 			return ret;
686 		}
687 	}
688 
689 	return ret;
690 }
691 
692 /* i3c ccc setnewda <device> <target> <dynamic address> */
cmd_i3c_ccc_setnewda(const struct shell * sh,size_t argc,char ** argv)693 static int cmd_i3c_ccc_setnewda(const struct shell *sh, size_t argc, char **argv)
694 {
695 	const struct device *dev, *tdev;
696 	struct i3c_device_desc *desc;
697 	struct i3c_driver_data *data;
698 	struct i3c_ccc_address new_da;
699 	uint8_t dynamic_addr;
700 	uint8_t old_da;
701 	int ret;
702 
703 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
704 	if (ret != 0) {
705 		return ret;
706 	}
707 
708 	data = (struct i3c_driver_data *)dev->data;
709 	dynamic_addr = strtol(argv[3], NULL, 16);
710 	new_da.addr = dynamic_addr << 1;
711 	/* check if the addressed is free */
712 	if (!i3c_addr_slots_is_free(&data->attached_dev.addr_slots, dynamic_addr)) {
713 		shell_error(sh, "I3C: Address 0x%02x is already in use.", dynamic_addr);
714 		return -EINVAL;
715 	}
716 
717 	ret = i3c_ccc_do_setnewda(desc, new_da);
718 	if (ret < 0) {
719 		shell_error(sh, "I3C: unable to send CCC SETDASA.");
720 		return ret;
721 	}
722 
723 	/* reattach device address */
724 	old_da = desc->dynamic_addr;
725 	desc->dynamic_addr = dynamic_addr;
726 	ret = i3c_reattach_i3c_device(desc, old_da);
727 	if (ret < 0) {
728 		shell_error(sh, "I3C: unable to reattach device");
729 		return ret;
730 	}
731 
732 	return ret;
733 }
734 
735 /* i3c ccc getbcr <device> <target> */
cmd_i3c_ccc_getbcr(const struct shell * sh,size_t argc,char ** argv)736 static int cmd_i3c_ccc_getbcr(const struct shell *sh, size_t argc, char **argv)
737 {
738 	const struct device *dev, *tdev;
739 	struct i3c_device_desc *desc;
740 	struct i3c_ccc_getbcr bcr;
741 	int ret;
742 
743 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
744 	if (ret != 0) {
745 		return ret;
746 	}
747 
748 	ret = i3c_ccc_do_getbcr(desc, &bcr);
749 	if (ret < 0) {
750 		shell_error(sh, "I3C: unable to send CCC GETBCR.");
751 		return ret;
752 	}
753 
754 	shell_print(sh, "BCR: 0x%02x", bcr.bcr);
755 	desc->bcr = bcr.bcr;
756 
757 	return ret;
758 }
759 
760 /* i3c ccc getdcr <device> <target> */
cmd_i3c_ccc_getdcr(const struct shell * sh,size_t argc,char ** argv)761 static int cmd_i3c_ccc_getdcr(const struct shell *sh, size_t argc, char **argv)
762 {
763 	const struct device *dev, *tdev;
764 	struct i3c_device_desc *desc;
765 	struct i3c_ccc_getdcr dcr;
766 	int ret;
767 
768 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
769 	if (ret != 0) {
770 		return ret;
771 	}
772 
773 	ret = i3c_ccc_do_getdcr(desc, &dcr);
774 	if (ret < 0) {
775 		shell_error(sh, "I3C: unable to send CCC GETDCR.");
776 		return ret;
777 	}
778 
779 	shell_print(sh, "DCR: 0x%02x", dcr.dcr);
780 	desc->dcr = dcr.dcr;
781 
782 	return ret;
783 }
784 
785 /* i3c ccc getpid <device> <target> */
cmd_i3c_ccc_getpid(const struct shell * sh,size_t argc,char ** argv)786 static int cmd_i3c_ccc_getpid(const struct shell *sh, size_t argc, char **argv)
787 {
788 	const struct device *dev, *tdev;
789 	struct i3c_device_desc *desc;
790 	struct i3c_ccc_getpid pid;
791 	int ret;
792 
793 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
794 	if (ret != 0) {
795 		return ret;
796 	}
797 
798 	ret = i3c_ccc_do_getpid(desc, &pid);
799 	if (ret < 0) {
800 		shell_error(sh, "I3C: unable to send CCC GETPID.");
801 		return ret;
802 	}
803 
804 	shell_print(sh, "PID: 0x%012llx", sys_get_be48(pid.pid));
805 
806 	return ret;
807 }
808 
809 /* i3c ccc getmrl <device> <target> */
cmd_i3c_ccc_getmrl(const struct shell * sh,size_t argc,char ** argv)810 static int cmd_i3c_ccc_getmrl(const struct shell *sh, size_t argc, char **argv)
811 {
812 	const struct device *dev, *tdev;
813 	struct i3c_device_desc *desc;
814 	struct i3c_ccc_mrl mrl;
815 	int ret;
816 
817 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
818 	if (ret != 0) {
819 		return ret;
820 	}
821 
822 	ret = i3c_ccc_do_getmrl(desc, &mrl);
823 	if (ret < 0) {
824 		shell_error(sh, "I3C: unable to send CCC GETMRL.");
825 		return ret;
826 	}
827 
828 	desc->data_length.mrl = mrl.len;
829 	if (desc->bcr & I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE) {
830 		shell_print(sh, "MRL: 0x%04x; IBI Length:0x%02x", mrl.len, mrl.ibi_len);
831 		desc->data_length.max_ibi = mrl.ibi_len;
832 	} else {
833 		shell_print(sh, "MRL: 0x%04x", mrl.len);
834 		desc->data_length.max_ibi = 0;
835 	}
836 
837 	return ret;
838 }
839 
840 /* i3c ccc getmwl <device> <target> */
cmd_i3c_ccc_getmwl(const struct shell * sh,size_t argc,char ** argv)841 static int cmd_i3c_ccc_getmwl(const struct shell *sh, size_t argc, char **argv)
842 {
843 	const struct device *dev, *tdev;
844 	struct i3c_device_desc *desc;
845 	struct i3c_ccc_mwl mwl;
846 	int ret;
847 
848 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
849 	if (ret != 0) {
850 		return ret;
851 	}
852 
853 	ret = i3c_ccc_do_getmwl(desc, &mwl);
854 	if (ret < 0) {
855 		shell_error(sh, "I3C: unable to send CCC GETMWL.");
856 		return ret;
857 	}
858 
859 	shell_print(sh, "MWL: 0x%04x", mwl.len);
860 	desc->data_length.mwl = mwl.len;
861 
862 	return ret;
863 }
864 
865 /* i3c ccc setmrl <device> <target> <max read length> [<max ibi length>] */
cmd_i3c_ccc_setmrl(const struct shell * sh,size_t argc,char ** argv)866 static int cmd_i3c_ccc_setmrl(const struct shell *sh, size_t argc, char **argv)
867 {
868 	const struct device *dev, *tdev;
869 	struct i3c_device_desc *desc;
870 	struct i3c_ccc_mrl mrl;
871 	int ret;
872 
873 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
874 	if (ret != 0) {
875 		return ret;
876 	}
877 
878 	/* IBI length is required if the ibi payload bit is set */
879 	if ((desc->bcr & I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE) && (argc < 5)) {
880 		shell_error(sh, "I3C: Missing IBI length.");
881 		return -EINVAL;
882 	}
883 
884 	mrl.len = strtol(argv[3], NULL, 16);
885 	if (argc > 4) {
886 		mrl.ibi_len = strtol(argv[4], NULL, 16);
887 	}
888 
889 	ret = i3c_ccc_do_setmrl(desc, &mrl);
890 	if (ret < 0) {
891 		shell_error(sh, "I3C: unable to send CCC SETMRL.");
892 		return ret;
893 	}
894 
895 	desc->data_length.mrl = mrl.len;
896 	if (argc > 4) {
897 		desc->data_length.max_ibi = mrl.ibi_len;
898 	}
899 
900 	return ret;
901 }
902 
903 /* i3c ccc setmwl <device> <target> <max write length> */
cmd_i3c_ccc_setmwl(const struct shell * sh,size_t argc,char ** argv)904 static int cmd_i3c_ccc_setmwl(const struct shell *sh, size_t argc, char **argv)
905 {
906 	const struct device *dev, *tdev;
907 	struct i3c_device_desc *desc;
908 	struct i3c_ccc_mwl mwl;
909 	int ret;
910 
911 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
912 	if (ret != 0) {
913 		return ret;
914 	}
915 
916 	mwl.len = strtol(argv[3], NULL, 16);
917 
918 	ret = i3c_ccc_do_setmwl(desc, &mwl);
919 	if (ret < 0) {
920 		shell_error(sh, "I3C: unable to send CCC SETMWL.");
921 		return ret;
922 	}
923 
924 	desc->data_length.mwl = mwl.len;
925 
926 	return ret;
927 }
928 
929 /* i3c ccc setmrl_bc <device> <max read length> [<max ibi length>] */
cmd_i3c_ccc_setmrl_bc(const struct shell * sh,size_t argc,char ** argv)930 static int cmd_i3c_ccc_setmrl_bc(const struct shell *sh, size_t argc, char **argv)
931 {
932 	const struct device *dev;
933 	struct i3c_device_desc *desc;
934 	struct i3c_ccc_mrl mrl;
935 	int ret;
936 
937 	dev = shell_device_get_binding(argv[ARGV_DEV]);
938 	if (!dev) {
939 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
940 		return -ENODEV;
941 	}
942 
943 	mrl.len = strtol(argv[2], NULL, 16);
944 	if (argc > 3) {
945 		mrl.ibi_len = strtol(argv[3], NULL, 16);
946 	}
947 
948 	ret = i3c_ccc_do_setmrl_all(dev, &mrl, argc > 3);
949 	if (ret < 0) {
950 		shell_error(sh, "I3C: unable to send CCC SETMRL BC.");
951 		return ret;
952 	}
953 
954 	I3C_BUS_FOR_EACH_I3CDEV(dev, desc) {
955 		desc->data_length.mrl = mrl.len;
956 		if ((argc > 3) && (desc->bcr & I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE)) {
957 			desc->data_length.max_ibi = mrl.ibi_len;
958 		}
959 	}
960 
961 	return ret;
962 }
963 
964 /* i3c ccc setmwl_bc <device> <max write length> */
cmd_i3c_ccc_setmwl_bc(const struct shell * sh,size_t argc,char ** argv)965 static int cmd_i3c_ccc_setmwl_bc(const struct shell *sh, size_t argc, char **argv)
966 {
967 	const struct device *dev;
968 	struct i3c_device_desc *desc;
969 	struct i3c_ccc_mwl mwl;
970 	int ret;
971 
972 	dev = shell_device_get_binding(argv[ARGV_DEV]);
973 	if (!dev) {
974 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
975 		return -ENODEV;
976 	}
977 
978 	mwl.len = strtol(argv[3], NULL, 16);
979 
980 	ret = i3c_ccc_do_setmwl_all(dev, &mwl);
981 	if (ret < 0) {
982 		shell_error(sh, "I3C: unable to send CCC SETMWL BC.");
983 		return ret;
984 	}
985 
986 	I3C_BUS_FOR_EACH_I3CDEV(dev, desc) {
987 		desc->data_length.mwl = mwl.len;
988 	}
989 
990 	return ret;
991 }
992 
993 /* i3c ccc deftgts <device> */
cmd_i3c_ccc_deftgts(const struct shell * sh,size_t argc,char ** argv)994 static int cmd_i3c_ccc_deftgts(const struct shell *sh, size_t argc, char **argv)
995 {
996 	const struct device *dev;
997 	int ret;
998 
999 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1000 	if (!dev) {
1001 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1002 		return -ENODEV;
1003 	}
1004 
1005 	if (!i3c_bus_has_sec_controller(dev)) {
1006 		shell_error(sh, "I3C: No secondary controller on the bus");
1007 		return -ENXIO;
1008 	}
1009 
1010 	ret = i3c_bus_deftgts(dev);
1011 	if (ret < 0) {
1012 		shell_error(sh, "I3C: unable to send CCC DEFTGTS.");
1013 		return ret;
1014 	}
1015 
1016 	return ret;
1017 }
1018 
1019 /* i3c ccc enttm <device> <defining byte> */
cmd_i3c_ccc_enttm(const struct shell * sh,size_t argc,char ** argv)1020 static int cmd_i3c_ccc_enttm(const struct shell *sh, size_t argc, char **argv)
1021 {
1022 	const struct device *dev;
1023 	enum i3c_ccc_enttm_defbyte defbyte;
1024 	int ret;
1025 
1026 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1027 	if (!dev) {
1028 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1029 		return -ENODEV;
1030 	}
1031 
1032 	defbyte = strtol(argv[2], NULL, 16);
1033 
1034 	ret = i3c_ccc_do_enttm(dev, defbyte);
1035 	if (ret < 0) {
1036 		shell_error(sh, "I3C: unable to send CCC ENTTM.");
1037 		return ret;
1038 	}
1039 
1040 	return ret;
1041 }
1042 
1043 /* i3c ccc getacccr <device> <target> */
cmd_i3c_ccc_getacccr(const struct shell * sh,size_t argc,char ** argv)1044 static int cmd_i3c_ccc_getacccr(const struct shell *sh, size_t argc, char **argv)
1045 {
1046 	const struct device *dev, *tdev;
1047 	struct i3c_device_desc *desc;
1048 	struct i3c_ccc_address handoff_address;
1049 	int ret;
1050 
1051 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
1052 	if (ret != 0) {
1053 		return ret;
1054 	}
1055 
1056 	if (!i3c_device_is_controller_capable(desc)) {
1057 		shell_error(sh, "I3C: Not a Controller Capable Device");
1058 		return -EINVAL;
1059 	}
1060 
1061 	ret = i3c_ccc_do_getacccr(desc, &handoff_address);
1062 	if (ret < 0) {
1063 		shell_error(sh, "I3C: unable to send CCC GETACCCR.");
1064 		return ret;
1065 	}
1066 
1067 	/* Verify Odd Parity and Correct Dynamic Address Reply */
1068 	if ((i3c_odd_parity(handoff_address.addr >> 1) != (handoff_address.addr & BIT(0))) ||
1069 	    (handoff_address.addr >> 1 != desc->dynamic_addr)) {
1070 		shell_error(sh, "I3C: invalid returned address 0x%02x; expected 0x%02x",
1071 			    handoff_address.addr, desc->dynamic_addr);
1072 		return -EIO;
1073 	}
1074 
1075 	shell_print(sh, "I3C: Controller Handoff successful");
1076 
1077 	return ret;
1078 }
1079 
1080 /* i3c ccc rstact_bc <device> <defining byte> */
cmd_i3c_ccc_rstact_bc(const struct shell * sh,size_t argc,char ** argv)1081 static int cmd_i3c_ccc_rstact_bc(const struct shell *sh, size_t argc, char **argv)
1082 {
1083 	const struct device *dev;
1084 	enum i3c_ccc_rstact_defining_byte action;
1085 	int ret;
1086 
1087 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1088 	if (!dev) {
1089 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1090 		return -ENODEV;
1091 	}
1092 
1093 	action = strtol(argv[2], NULL, 16);
1094 
1095 	ret = i3c_ccc_do_rstact_all(dev, action);
1096 	if (ret < 0) {
1097 		shell_error(sh, "I3C: unable to send CCC RSTACT BC.");
1098 		return ret;
1099 	}
1100 
1101 	return ret;
1102 }
1103 
1104 /* i3c ccc rstact <device> <target> <"set"/"get"> <defining byte> */
cmd_i3c_ccc_rstact(const struct shell * sh,size_t argc,char ** argv)1105 static int cmd_i3c_ccc_rstact(const struct shell *sh, size_t argc, char **argv)
1106 {
1107 	const struct device *dev, *tdev;
1108 	struct i3c_device_desc *desc;
1109 	enum i3c_ccc_rstact_defining_byte action;
1110 	int ret;
1111 	uint8_t data;
1112 
1113 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
1114 	if (ret != 0) {
1115 		return ret;
1116 	}
1117 
1118 	action = strtol(argv[4], NULL, 16);
1119 
1120 	if (strcmp(argv[3], "get") == 0) {
1121 		ret = i3c_ccc_do_rstact_fmt3(desc, action, &data);
1122 	} else if (strcmp(argv[3], "set") == 0) {
1123 		ret = i3c_ccc_do_rstact_fmt2(desc, action);
1124 	} else {
1125 		shell_error(sh, "I3C: invalid parameter");
1126 		return -EINVAL;
1127 	}
1128 
1129 	if (ret < 0) {
1130 		shell_error(sh, "I3C: unable to send CCC RSTACT.");
1131 		return ret;
1132 	}
1133 
1134 	if (action >= 0x80) {
1135 		shell_print(sh, "RSTACT Returned Data: 0x%02x", data);
1136 	}
1137 
1138 	return ret;
1139 }
1140 
1141 
1142 /* i3c ccc enec_bc <device> <defining byte> */
cmd_i3c_ccc_enec_bc(const struct shell * sh,size_t argc,char ** argv)1143 static int cmd_i3c_ccc_enec_bc(const struct shell *sh, size_t argc, char **argv)
1144 {
1145 	const struct device *dev;
1146 	struct i3c_ccc_events events;
1147 	int ret;
1148 
1149 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1150 	if (!dev) {
1151 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1152 		return -ENODEV;
1153 	}
1154 
1155 	events.events = strtol(argv[2], NULL, 16);
1156 
1157 	ret = i3c_ccc_do_events_all_set(dev, true, &events);
1158 	if (ret < 0) {
1159 		shell_error(sh, "I3C: unable to send CCC ENEC BC.");
1160 		return ret;
1161 	}
1162 
1163 	return ret;
1164 }
1165 
1166 /* i3c ccc disec_bc <device> <defining byte> */
cmd_i3c_ccc_disec_bc(const struct shell * sh,size_t argc,char ** argv)1167 static int cmd_i3c_ccc_disec_bc(const struct shell *sh, size_t argc, char **argv)
1168 {
1169 	const struct device *dev;
1170 	struct i3c_ccc_events events;
1171 	int ret;
1172 
1173 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1174 	if (!dev) {
1175 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1176 		return -ENODEV;
1177 	}
1178 
1179 	events.events = strtol(argv[2], NULL, 16);
1180 
1181 	ret = i3c_ccc_do_events_all_set(dev, false, &events);
1182 	if (ret < 0) {
1183 		shell_error(sh, "I3C: unable to send CCC DISEC BC.");
1184 		return ret;
1185 	}
1186 
1187 	return ret;
1188 }
1189 
1190 /* i3c ccc enec <device> <target> <defining byte> */
cmd_i3c_ccc_enec(const struct shell * sh,size_t argc,char ** argv)1191 static int cmd_i3c_ccc_enec(const struct shell *sh, size_t argc, char **argv)
1192 {
1193 	const struct device *dev, *tdev;
1194 	struct i3c_device_desc *desc;
1195 	struct i3c_ccc_events events;
1196 	int ret;
1197 
1198 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
1199 	if (ret != 0) {
1200 		return ret;
1201 	}
1202 
1203 	events.events = strtol(argv[3], NULL, 16);
1204 
1205 	ret = i3c_ccc_do_events_set(desc, true, &events);
1206 	if (ret < 0) {
1207 		shell_error(sh, "I3C: unable to send CCC ENEC.");
1208 		return ret;
1209 	}
1210 
1211 	return ret;
1212 }
1213 
1214 /* i3c ccc disec <device> <target> <defining byte> */
cmd_i3c_ccc_disec(const struct shell * sh,size_t argc,char ** argv)1215 static int cmd_i3c_ccc_disec(const struct shell *sh, size_t argc, char **argv)
1216 {
1217 	const struct device *dev, *tdev;
1218 	struct i3c_device_desc *desc;
1219 	struct i3c_ccc_events events;
1220 	int ret;
1221 
1222 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
1223 	if (ret != 0) {
1224 		return ret;
1225 	}
1226 
1227 	events.events = strtol(argv[3], NULL, 16);
1228 
1229 	ret = i3c_ccc_do_events_set(desc, false, &events);
1230 	if (ret < 0) {
1231 		shell_error(sh, "I3C: unable to send CCC DISEC.");
1232 		return ret;
1233 	}
1234 
1235 	return ret;
1236 }
1237 
1238 /* i3c ccc entas0_bc <device> */
cmd_i3c_ccc_entas0_bc(const struct shell * sh,size_t argc,char ** argv)1239 static int cmd_i3c_ccc_entas0_bc(const struct shell *sh, size_t argc, char **argv)
1240 {
1241 	const struct device *dev;
1242 	struct i3c_driver_data *data;
1243 	int ret;
1244 
1245 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1246 	if (!dev) {
1247 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1248 		return -ENODEV;
1249 	}
1250 	data = (struct i3c_driver_data *)dev->data;
1251 
1252 	ret = i3c_ccc_do_entas0_all(dev);
1253 	if (ret < 0) {
1254 		shell_error(sh, "I3C: unable to send CCC ENTAS0 BC.");
1255 		return ret;
1256 	}
1257 
1258 	return ret;
1259 }
1260 
1261 /* i3c ccc entas1_bc <device> */
cmd_i3c_ccc_entas1_bc(const struct shell * sh,size_t argc,char ** argv)1262 static int cmd_i3c_ccc_entas1_bc(const struct shell *sh, size_t argc, char **argv)
1263 {
1264 	const struct device *dev;
1265 	struct i3c_driver_data *data;
1266 	int ret;
1267 
1268 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1269 	if (!dev) {
1270 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1271 		return -ENODEV;
1272 	}
1273 	data = (struct i3c_driver_data *)dev->data;
1274 
1275 	ret = i3c_ccc_do_entas1_all(dev);
1276 	if (ret < 0) {
1277 		shell_error(sh, "I3C: unable to send CCC ENTAS1 BC.");
1278 		return ret;
1279 	}
1280 
1281 	return ret;
1282 }
1283 
1284 /* i3c ccc entas2_bc <device> */
cmd_i3c_ccc_entas2_bc(const struct shell * sh,size_t argc,char ** argv)1285 static int cmd_i3c_ccc_entas2_bc(const struct shell *sh, size_t argc, char **argv)
1286 {
1287 	const struct device *dev;
1288 	struct i3c_driver_data *data;
1289 	int ret;
1290 
1291 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1292 	if (!dev) {
1293 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1294 		return -ENODEV;
1295 	}
1296 	data = (struct i3c_driver_data *)dev->data;
1297 
1298 	ret = i3c_ccc_do_entas2_all(dev);
1299 	if (ret < 0) {
1300 		shell_error(sh, "I3C: unable to send CCC ENTAS2 BC.");
1301 		return ret;
1302 	}
1303 
1304 	return ret;
1305 }
1306 
1307 /* i3c ccc entas3_bc <device> */
cmd_i3c_ccc_entas3_bc(const struct shell * sh,size_t argc,char ** argv)1308 static int cmd_i3c_ccc_entas3_bc(const struct shell *sh, size_t argc, char **argv)
1309 {
1310 	const struct device *dev;
1311 	struct i3c_driver_data *data;
1312 	int ret;
1313 
1314 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1315 	if (!dev) {
1316 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1317 		return -ENODEV;
1318 	}
1319 	data = (struct i3c_driver_data *)dev->data;
1320 
1321 	ret = i3c_ccc_do_entas3_all(dev);
1322 	if (ret < 0) {
1323 		shell_error(sh, "I3C: unable to send CCC ENTAS3 BC.");
1324 		return ret;
1325 	}
1326 
1327 	return ret;
1328 }
1329 
1330 /* i3c ccc entas0 <device> <target> */
cmd_i3c_ccc_entas0(const struct shell * sh,size_t argc,char ** argv)1331 static int cmd_i3c_ccc_entas0(const struct shell *sh, size_t argc, char **argv)
1332 {
1333 	const struct device *dev, *tdev;
1334 	struct i3c_device_desc *desc;
1335 	int ret;
1336 
1337 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
1338 	if (ret != 0) {
1339 		return ret;
1340 	}
1341 
1342 	ret = i3c_ccc_do_entas0(desc);
1343 	if (ret < 0) {
1344 		shell_error(sh, "I3C: unable to send CCC ENTAS0.");
1345 		return ret;
1346 	}
1347 
1348 	return ret;
1349 }
1350 
1351 /* i3c ccc entas1 <device> <target> */
cmd_i3c_ccc_entas1(const struct shell * sh,size_t argc,char ** argv)1352 static int cmd_i3c_ccc_entas1(const struct shell *sh, size_t argc, char **argv)
1353 {
1354 	const struct device *dev, *tdev;
1355 	struct i3c_device_desc *desc;
1356 	int ret;
1357 
1358 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
1359 	if (ret != 0) {
1360 		return ret;
1361 	}
1362 
1363 	ret = i3c_ccc_do_entas1(desc);
1364 	if (ret < 0) {
1365 		shell_error(sh, "I3C: unable to send CCC ENTAS1.");
1366 		return ret;
1367 	}
1368 
1369 	return ret;
1370 }
1371 
1372 /* i3c ccc entas2 <device> <target> */
cmd_i3c_ccc_entas2(const struct shell * sh,size_t argc,char ** argv)1373 static int cmd_i3c_ccc_entas2(const struct shell *sh, size_t argc, char **argv)
1374 {
1375 	const struct device *dev, *tdev;
1376 	struct i3c_device_desc *desc;
1377 	int ret;
1378 
1379 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
1380 	if (ret != 0) {
1381 		return ret;
1382 	}
1383 
1384 	ret = i3c_ccc_do_entas2(desc);
1385 	if (ret < 0) {
1386 		shell_error(sh, "I3C: unable to send CCC ENTAS2.");
1387 		return ret;
1388 	}
1389 
1390 	return ret;
1391 }
1392 
1393 /* i3c ccc entas3 <device> <target> */
cmd_i3c_ccc_entas3(const struct shell * sh,size_t argc,char ** argv)1394 static int cmd_i3c_ccc_entas3(const struct shell *sh, size_t argc, char **argv)
1395 {
1396 	const struct device *dev, *tdev;
1397 	struct i3c_device_desc *desc;
1398 	int ret;
1399 
1400 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
1401 	if (ret != 0) {
1402 		return ret;
1403 	}
1404 
1405 	ret = i3c_ccc_do_entas3(desc);
1406 	if (ret < 0) {
1407 		shell_error(sh, "I3C: unable to send CCC ENTAS3.");
1408 		return ret;
1409 	}
1410 
1411 	return ret;
1412 }
1413 
1414 /* i3c ccc getstatus <device> <target> [<defining byte>] */
cmd_i3c_ccc_getstatus(const struct shell * sh,size_t argc,char ** argv)1415 static int cmd_i3c_ccc_getstatus(const struct shell *sh, size_t argc, char **argv)
1416 {
1417 	const struct device *dev, *tdev;
1418 	struct i3c_device_desc *desc;
1419 	union i3c_ccc_getstatus status;
1420 	enum i3c_ccc_getstatus_fmt fmt;
1421 	enum i3c_ccc_getstatus_defbyte defbyte = GETSTATUS_FORMAT_2_INVALID;
1422 	int ret;
1423 
1424 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
1425 	if (ret != 0) {
1426 		return ret;
1427 	}
1428 
1429 	/* If there is a defining byte, then it is assumed to be Format 2*/
1430 	if (argc > 3) {
1431 		fmt = GETSTATUS_FORMAT_2;
1432 		defbyte = strtol(argv[3], NULL, 16);
1433 		if (defbyte != GETSTATUS_FORMAT_2_TGTSTAT && defbyte != GETSTATUS_FORMAT_2_PRECR) {
1434 			shell_error(sh, "Invalid defining byte.");
1435 			return -EINVAL;
1436 		}
1437 	} else {
1438 		fmt = GETSTATUS_FORMAT_1;
1439 	}
1440 
1441 	ret = i3c_ccc_do_getstatus(desc, &status, fmt, defbyte);
1442 	if (ret < 0) {
1443 		shell_error(sh, "I3C: unable to send CCC GETSTATUS.");
1444 		return ret;
1445 	}
1446 
1447 	if (fmt == GETSTATUS_FORMAT_2) {
1448 		if (defbyte == GETSTATUS_FORMAT_2_TGTSTAT) {
1449 			shell_print(sh, "TGTSTAT: 0x%04x", status.fmt2.tgtstat);
1450 		} else if (defbyte == GETSTATUS_FORMAT_2_PRECR) {
1451 			shell_print(sh, "PRECR: 0x%04x", status.fmt2.precr);
1452 		}
1453 	} else {
1454 		shell_print(sh, "Status: 0x%04x", status.fmt1.status);
1455 	}
1456 
1457 	return ret;
1458 }
1459 
1460 /* i3c ccc getcaps <device> <target> [<defining byte>] */
cmd_i3c_ccc_getcaps(const struct shell * sh,size_t argc,char ** argv)1461 static int cmd_i3c_ccc_getcaps(const struct shell *sh, size_t argc, char **argv)
1462 {
1463 	const struct device *dev, *tdev;
1464 	struct i3c_device_desc *desc;
1465 	union i3c_ccc_getcaps caps;
1466 	enum i3c_ccc_getcaps_fmt fmt;
1467 	enum i3c_ccc_getcaps_defbyte defbyte = GETCAPS_FORMAT_2_INVALID;
1468 	int ret;
1469 
1470 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
1471 	if (ret != 0) {
1472 		return ret;
1473 	}
1474 
1475 	/* If there is a defining byte, then it is assumed to be Format 2 */
1476 	if (argc > 3) {
1477 		fmt = GETCAPS_FORMAT_2;
1478 		defbyte = strtol(argv[3], NULL, 16);
1479 		if (defbyte != GETCAPS_FORMAT_2_TGTCAPS || defbyte != GETCAPS_FORMAT_2_TESTPAT ||
1480 		    defbyte != GETCAPS_FORMAT_2_CRCAPS || defbyte != GETCAPS_FORMAT_2_VTCAPS ||
1481 		    defbyte != GETCAPS_FORMAT_2_DBGCAPS) {
1482 			shell_error(sh, "Invalid defining byte.");
1483 			return -EINVAL;
1484 		}
1485 	} else {
1486 		fmt = GETCAPS_FORMAT_1;
1487 	}
1488 
1489 	ret = i3c_ccc_do_getcaps(desc, &caps, fmt, defbyte);
1490 	if (ret < 0) {
1491 		shell_error(sh, "I3C: unable to send CCC GETCAPS.");
1492 		return ret;
1493 	}
1494 
1495 	if (fmt == GETCAPS_FORMAT_2) {
1496 		if (defbyte == GETCAPS_FORMAT_2_TGTCAPS) {
1497 			shell_print(sh, "TGTCAPS: 0x%02x; 0x%02x; 0x%02x; 0x%02x",
1498 				    caps.fmt2.tgtcaps[0], caps.fmt2.tgtcaps[1],
1499 				    caps.fmt2.tgtcaps[2], caps.fmt2.tgtcaps[3]);
1500 		} else if (defbyte == GETCAPS_FORMAT_2_TESTPAT) {
1501 			shell_print(sh, "TESTPAT: 0x%08x", caps.fmt2.testpat);
1502 		} else if (defbyte == GETCAPS_FORMAT_2_CRCAPS) {
1503 			shell_print(sh, "CRCAPS: 0x%02x; 0x%02x", caps.fmt2.crcaps[0],
1504 				    caps.fmt2.crcaps[1]);
1505 			memcpy(&desc->crcaps, &caps, sizeof(desc->crcaps));
1506 		} else if (defbyte == GETCAPS_FORMAT_2_VTCAPS) {
1507 			shell_print(sh, "VTCAPS: 0x%02x; 0x%02x", caps.fmt2.vtcaps[0],
1508 				    caps.fmt2.vtcaps[1]);
1509 		}
1510 	} else {
1511 		shell_print(sh, "GETCAPS: 0x%02x; 0x%02x; 0x%02x; 0x%02x", caps.fmt1.getcaps[0],
1512 			    caps.fmt1.getcaps[1], caps.fmt1.getcaps[2], caps.fmt1.getcaps[3]);
1513 		memcpy(&desc->getcaps, &caps, sizeof(desc->getcaps));
1514 	}
1515 
1516 	return ret;
1517 }
1518 
1519 /* i3c ccc getvendor <device> <target> <id> [<defining byte>] */
cmd_i3c_ccc_getvendor(const struct shell * sh,size_t argc,char ** argv)1520 static int cmd_i3c_ccc_getvendor(const struct shell *sh, size_t argc, char **argv)
1521 {
1522 	const struct device *dev, *tdev;
1523 	struct i3c_device_desc *desc;
1524 	uint8_t buf[MAX_I3C_BYTES] = {0};
1525 	uint8_t defbyte;
1526 	size_t num_xfer;
1527 	uint8_t id;
1528 	int err = 0;
1529 	int ret;
1530 
1531 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1532 	if (!dev) {
1533 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1534 		return -ENODEV;
1535 	}
1536 
1537 	tdev = shell_device_get_binding(argv[ARGV_TDEV]);
1538 	if (!tdev) {
1539 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_TDEV]);
1540 		return -ENODEV;
1541 	}
1542 	desc = get_i3c_attached_desc_from_dev_name(dev, tdev->name);
1543 	if (!desc) {
1544 		shell_error(sh, "I3C: Device %s not attached to bus.", tdev->name);
1545 		return -ENODEV;
1546 	}
1547 
1548 	id = (uint8_t)shell_strtoul(argv[3], 0, &err);
1549 	if (err != 0) {
1550 		shell_error(sh, "I3C: Invalid ID.");
1551 		return -EINVAL;
1552 	}
1553 
1554 	if (argc > 4) {
1555 		defbyte = strtol(argv[4], NULL, 16);
1556 		ret = i3c_ccc_do_getvendor_defbyte(desc, id, defbyte, buf, MAX_I3C_BYTES,
1557 						   &num_xfer);
1558 	} else {
1559 		ret = i3c_ccc_do_getvendor(desc, id, buf, MAX_I3C_BYTES, &num_xfer);
1560 	}
1561 
1562 	if (ret < 0) {
1563 		shell_error(sh, "I3C: unable to send CCC VENDOR.");
1564 		return ret;
1565 	}
1566 
1567 	shell_hexdump(sh, buf, num_xfer);
1568 
1569 	return ret;
1570 }
1571 
1572 /* i3c ccc setvendor <device> <target> <id> [<bytes>] */
cmd_i3c_ccc_setvendor(const struct shell * sh,size_t argc,char ** argv)1573 static int cmd_i3c_ccc_setvendor(const struct shell *sh, size_t argc, char **argv)
1574 {
1575 	const struct device *dev, *tdev;
1576 	struct i3c_device_desc *desc;
1577 	struct i3c_driver_data *data;
1578 	uint8_t buf[MAX_I3C_BYTES] = {0};
1579 	uint8_t data_length;
1580 	uint8_t id;
1581 	int err = 0;
1582 	int ret;
1583 	int i;
1584 
1585 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1586 	if (!dev) {
1587 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1588 		return -ENODEV;
1589 	}
1590 
1591 	tdev = shell_device_get_binding(argv[ARGV_TDEV]);
1592 	if (!tdev) {
1593 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_TDEV]);
1594 		return -ENODEV;
1595 	}
1596 	desc = get_i3c_attached_desc_from_dev_name(dev, tdev->name);
1597 	if (!desc) {
1598 		shell_error(sh, "I3C: Device %s not attached to bus.", tdev->name);
1599 		return -ENODEV;
1600 	}
1601 	data = (struct i3c_driver_data *)dev->data;
1602 
1603 	id = (uint8_t)shell_strtoul(argv[3], 0, &err);
1604 	if (err != 0) {
1605 		shell_error(sh, "I3C: Invalid ID.");
1606 		return -EINVAL;
1607 	}
1608 
1609 	data_length = argc - 4;
1610 	for (i = 0; i < data_length; i++) {
1611 		buf[i] = (uint8_t)strtol(argv[4 + i], NULL, 16);
1612 	}
1613 
1614 	ret = i3c_ccc_do_setvendor(desc, id, buf, data_length);
1615 	if (ret < 0) {
1616 		shell_error(sh, "I3C: unable to send CCC VENDOR.");
1617 		return ret;
1618 	}
1619 
1620 	return ret;
1621 }
1622 
1623 /* i3c ccc setvendor_bc <device> <id> [<bytes>] */
cmd_i3c_ccc_setvendor_bc(const struct shell * sh,size_t argc,char ** argv)1624 static int cmd_i3c_ccc_setvendor_bc(const struct shell *sh, size_t argc, char **argv)
1625 {
1626 	const struct device *dev;
1627 	uint8_t buf[MAX_I3C_BYTES] = {0};
1628 	uint8_t data_length;
1629 	uint8_t id;
1630 	int err = 0;
1631 	int ret;
1632 	int i;
1633 
1634 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1635 	if (!dev) {
1636 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1637 		return -ENODEV;
1638 	}
1639 
1640 	id = (uint8_t)shell_strtoul(argv[2], 0, &err);
1641 	if (err != 0) {
1642 		shell_error(sh, "I3C: Invalid ID.");
1643 		return -EINVAL;
1644 	}
1645 
1646 	data_length = argc - 3;
1647 	for (i = 0; i < data_length; i++) {
1648 		buf[i] = (uint8_t)strtol(argv[3 + i], NULL, 16);
1649 	}
1650 
1651 	ret = i3c_ccc_do_setvendor_all(dev, id, buf, data_length);
1652 	if (ret < 0) {
1653 		shell_error(sh, "I3C: unable to send CCC VENDOR.");
1654 		return ret;
1655 	}
1656 
1657 	return ret;
1658 }
1659 
1660 /* i3c ccc setbuscon <device> <context> [<optional bytes>] */
cmd_i3c_ccc_setbuscon(const struct shell * sh,size_t argc,char ** argv)1661 static int cmd_i3c_ccc_setbuscon(const struct shell *sh, size_t argc, char **argv)
1662 {
1663 	const struct device *dev;
1664 	uint8_t buf[MAX_I3C_BYTES] = {0};
1665 	uint8_t data_length;
1666 	int ret;
1667 	int i;
1668 
1669 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1670 	if (!dev) {
1671 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1672 		return -ENODEV;
1673 	}
1674 
1675 	data_length = argc - 2;
1676 	for (i = 0; i < data_length; i++) {
1677 		buf[i] = (uint8_t)strtol(argv[2 + i], NULL, 16);
1678 	}
1679 
1680 	ret = i3c_ccc_do_setbuscon(dev, buf, data_length);
1681 	if (ret < 0) {
1682 		shell_error(sh, "I3C: unable to send CCC SETBUSCON.");
1683 		return ret;
1684 	}
1685 
1686 	return ret;
1687 }
1688 
1689 /* i3c ccc getmxds <device> <target> [<defining byte>] */
cmd_i3c_ccc_getmxds(const struct shell * sh,size_t argc,char ** argv)1690 static int cmd_i3c_ccc_getmxds(const struct shell *sh, size_t argc, char **argv)
1691 {
1692 	const struct device *dev, *tdev;
1693 	struct i3c_device_desc *desc;
1694 	union i3c_ccc_getmxds mxds;
1695 	enum i3c_ccc_getmxds_fmt fmt;
1696 	enum i3c_ccc_getmxds_defbyte defbyte = GETMXDS_FORMAT_3_INVALID;
1697 	int ret;
1698 
1699 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
1700 	if (ret != 0) {
1701 		return ret;
1702 	}
1703 
1704 	if (!(desc->bcr & I3C_BCR_MAX_DATA_SPEED_LIMIT)) {
1705 		shell_error(sh, "I3C: Device %s does not support max data speed limit",
1706 			    desc->dev->name);
1707 		return -ENOTSUP;
1708 	}
1709 
1710 	/* If there is a defining byte, then it is assumed to be Format 3 */
1711 	if (argc > 3) {
1712 		fmt = GETMXDS_FORMAT_3;
1713 		defbyte = strtol(argv[3], NULL, 16);
1714 		if (defbyte != GETMXDS_FORMAT_3_CRHDLY || defbyte != GETMXDS_FORMAT_3_WRRDTURN) {
1715 			shell_error(sh, "Invalid defining byte.");
1716 			return -EINVAL;
1717 		}
1718 	} else {
1719 		fmt = GETMXDS_FORMAT_2;
1720 	}
1721 
1722 	ret = i3c_ccc_do_getmxds(desc, &mxds, fmt, defbyte);
1723 	if (ret < 0) {
1724 		shell_error(sh, "I3C: unable to send CCC GETMXDS.");
1725 		return ret;
1726 	}
1727 
1728 	if (fmt == GETMXDS_FORMAT_3) {
1729 		if (defbyte == GETMXDS_FORMAT_3_WRRDTURN) {
1730 			shell_print(sh, "WRRDTURN: maxwr 0x%02x; maxrd 0x%02x; maxrdturn 0x%06x",
1731 				    mxds.fmt3.wrrdturn[0], mxds.fmt3.wrrdturn[1],
1732 				    sys_get_le24(&mxds.fmt3.wrrdturn[2]));
1733 			/* Update values in descriptor */
1734 			desc->data_speed.maxwr = mxds.fmt3.wrrdturn[0];
1735 			desc->data_speed.maxrd = mxds.fmt3.wrrdturn[1];
1736 			desc->data_speed.max_read_turnaround = sys_get_le24(&mxds.fmt3.wrrdturn[2]);
1737 		} else if (defbyte == GETMXDS_FORMAT_3_CRHDLY) {
1738 			shell_print(sh, "CRHDLY1: 0x%02x", mxds.fmt3.crhdly1);
1739 			desc->crhdly1 = mxds.fmt3.crhdly1;
1740 		}
1741 	} else {
1742 		shell_print(sh, "GETMXDS: maxwr 0x%02x; maxrd 0x%02x; maxrdturn 0x%06x",
1743 			    mxds.fmt2.maxwr, mxds.fmt2.maxrd, sys_get_le24(mxds.fmt2.maxrdturn));
1744 		/* Update values in descriptor */
1745 		desc->data_speed.maxwr = mxds.fmt2.maxwr;
1746 		desc->data_speed.maxrd = mxds.fmt2.maxrd;
1747 		desc->data_speed.max_read_turnaround = sys_get_le24(mxds.fmt2.maxrdturn);
1748 	}
1749 
1750 	return ret;
1751 }
1752 
cmd_i3c_attach(const struct shell * sh,size_t argc,char ** argv)1753 static int cmd_i3c_attach(const struct shell *sh, size_t argc, char **argv)
1754 {
1755 	const struct device *dev, *tdev;
1756 	struct i3c_device_desc *desc;
1757 	int ret;
1758 
1759 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1760 	if (!dev) {
1761 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1762 		return -ENODEV;
1763 	}
1764 	tdev = shell_device_get_binding(argv[ARGV_TDEV]);
1765 	if (!tdev) {
1766 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_TDEV]);
1767 		return -ENODEV;
1768 	}
1769 	desc = get_i3c_list_desc_from_dev_name(dev, tdev->name);
1770 	if (!desc) {
1771 		shell_error(sh, "I3C: Device %s not attached to bus.", tdev->name);
1772 		return -ENODEV;
1773 	}
1774 
1775 	ret = i3c_attach_i3c_device(desc);
1776 	if (ret < 0) {
1777 		shell_error(sh, "I3C: unable to attach device %s.", tdev->name);
1778 	}
1779 
1780 	return ret;
1781 }
1782 
cmd_i3c_reattach(const struct shell * sh,size_t argc,char ** argv)1783 static int cmd_i3c_reattach(const struct shell *sh, size_t argc, char **argv)
1784 {
1785 	const struct device *dev, *tdev;
1786 	struct i3c_device_desc *desc;
1787 	uint8_t old_dyn_addr = 0;
1788 	int ret;
1789 
1790 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
1791 	if (ret != 0) {
1792 		return ret;
1793 	}
1794 
1795 	if (argc > 2) {
1796 		old_dyn_addr = strtol(argv[2], NULL, 16);
1797 	}
1798 
1799 	ret = i3c_reattach_i3c_device(desc, old_dyn_addr);
1800 	if (ret < 0) {
1801 		shell_error(sh, "I3C: unable to reattach device %s.", tdev->name);
1802 	}
1803 
1804 	return ret;
1805 }
1806 
cmd_i3c_detach(const struct shell * sh,size_t argc,char ** argv)1807 static int cmd_i3c_detach(const struct shell *sh, size_t argc, char **argv)
1808 {
1809 	const struct device *dev, *tdev;
1810 	struct i3c_device_desc *desc;
1811 	int ret;
1812 
1813 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
1814 	if (ret != 0) {
1815 		return ret;
1816 	}
1817 
1818 	ret = i3c_detach_i3c_device(desc);
1819 	if (ret < 0) {
1820 		shell_error(sh, "I3C: unable to detach device %s.", tdev->name);
1821 	}
1822 
1823 	return ret;
1824 }
1825 
cmd_i3c_i2c_attach(const struct shell * sh,size_t argc,char ** argv)1826 static int cmd_i3c_i2c_attach(const struct shell *sh, size_t argc, char **argv)
1827 {
1828 	const struct device *dev;
1829 	struct i3c_i2c_device_desc *desc;
1830 	uint16_t addr = 0;
1831 	int ret;
1832 
1833 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1834 	if (!dev) {
1835 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1836 		return -ENODEV;
1837 	}
1838 	addr = strtol(argv[2], NULL, 16);
1839 	desc = i3c_dev_list_i2c_addr_find(dev, addr);
1840 	if (!desc) {
1841 		shell_error(sh, "I3C: I2C addr 0x%02x not listed with the bus.", addr);
1842 		return -ENODEV;
1843 	}
1844 
1845 	ret = i3c_attach_i2c_device(desc);
1846 	if (ret < 0) {
1847 		shell_error(sh, "I3C: unable to attach I2C addr 0x%02x.", addr);
1848 	}
1849 
1850 	return ret;
1851 }
1852 
cmd_i3c_i2c_detach(const struct shell * sh,size_t argc,char ** argv)1853 static int cmd_i3c_i2c_detach(const struct shell *sh, size_t argc, char **argv)
1854 {
1855 	const struct device *dev;
1856 	struct i3c_i2c_device_desc *desc;
1857 	uint16_t addr = 0;
1858 	int ret;
1859 
1860 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1861 	if (!dev) {
1862 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1863 		return -ENODEV;
1864 	}
1865 	addr = strtol(argv[2], NULL, 16);
1866 	desc = i3c_dev_list_i2c_addr_find(dev, addr);
1867 	if (!desc) {
1868 		shell_error(sh, "I3C: I2C addr 0x%02x not listed with the bus.", addr);
1869 		return -ENODEV;
1870 	}
1871 
1872 	ret = i3c_detach_i2c_device(desc);
1873 	if (ret < 0) {
1874 		shell_error(sh, "I3C: unable to detach I2C addr 0x%02x.", addr);
1875 	}
1876 
1877 	return ret;
1878 }
1879 
1880 /*
1881  * This is a workaround command to perform an I2C Scan which is not as
1882  * simple on an I3C bus as it is with the I2C Shell.
1883  *
1884  * This will print "I3" if an address is already assigned for an I3C
1885  * device and it will print "I2" if an address is already assigned for
1886  * an I2C device. It will print RS, if the address is reserved according
1887  * to section 5.1.2.2.5 I3C Target Address Restrictions in I3C v1.1.1.
1888  *
1889  * This sends I2C messages without any data (i.e. stop condition after
1890  * sending just the address). If there is an ACK for the address, it
1891  * is assumed there is a device present.
1892  *
1893  * WARNING: As there is no standard I2C detection command, this code
1894  * uses arbitrary SMBus commands (namely SMBus quick write and SMBus
1895  * receive byte) to probe for devices.  This operation can confuse
1896  * your I2C bus, cause data loss, and is known to corrupt the Atmel
1897  * AT24RF08 EEPROM found on many IBM Thinkpad laptops.
1898  *
1899  * https://manpages.debian.org/buster/i2c-tools/i2cdetect.8.en.html
1900  */
1901 /* i3c i2c_scan <device> */
cmd_i3c_i2c_scan(const struct shell * sh,size_t argc,char ** argv)1902 static int cmd_i3c_i2c_scan(const struct shell *sh, size_t argc, char **argv)
1903 {
1904 	const struct device *dev;
1905 	struct i3c_driver_data *data;
1906 	enum i3c_addr_slot_status slot;
1907 	uint8_t cnt = 0, first = 0x04, last = 0x77;
1908 
1909 	dev = shell_device_get_binding(argv[ARGV_DEV]);
1910 
1911 	if (!dev) {
1912 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1913 		return -ENODEV;
1914 	}
1915 
1916 	data = (struct i3c_driver_data *)dev->data;
1917 
1918 	shell_print(sh, "     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f");
1919 	for (uint8_t i = 0; i <= last; i += 16) {
1920 		shell_fprintf_normal(sh, "%02x: ", i);
1921 		for (uint8_t j = 0; j < 16; j++) {
1922 			if (i + j < first || i + j > last) {
1923 				shell_fprintf_normal(sh, "   ");
1924 				continue;
1925 			}
1926 
1927 			slot = i3c_addr_slots_status(&data->attached_dev.addr_slots, i + j);
1928 			if (slot == I3C_ADDR_SLOT_STATUS_FREE) {
1929 				struct i2c_msg msgs[1];
1930 				uint8_t dst;
1931 				int ret;
1932 				struct i3c_i2c_device_desc desc = {
1933 					.bus = dev,
1934 					.addr = i + j,
1935 					.lvr = 0x00,
1936 				};
1937 
1938 				ret = i3c_attach_i2c_device(&desc);
1939 				if (ret < 0) {
1940 					shell_error(sh, "I3C: unable to attach I2C addr 0x%02x.",
1941 						    desc.addr);
1942 				}
1943 
1944 				/* Send the address to read from */
1945 				msgs[0].buf = &dst;
1946 				msgs[0].len = 0U;
1947 				msgs[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
1948 				if (i2c_transfer(dev, &msgs[0], 1, i + j) == 0) {
1949 					shell_fprintf_normal(sh, "%02x ", i + j);
1950 					++cnt;
1951 				} else {
1952 					shell_fprintf_normal(sh, "-- ");
1953 				}
1954 
1955 				ret = i3c_detach_i2c_device(&desc);
1956 				if (ret < 0) {
1957 					shell_error(sh, "I3C: unable to detach I2C addr 0x%02x.",
1958 						    desc.addr);
1959 				}
1960 			} else if (slot == I3C_ADDR_SLOT_STATUS_I3C_DEV) {
1961 				shell_fprintf_normal(sh, "I3 ");
1962 			} else if (slot == I3C_ADDR_SLOT_STATUS_I2C_DEV) {
1963 				shell_fprintf_normal(sh, "I2 ");
1964 			} else if (slot == I3C_ADDR_SLOT_STATUS_RSVD) {
1965 				shell_fprintf_normal(sh, "RS ");
1966 			} else {
1967 				shell_fprintf_normal(sh, "-- ");
1968 			}
1969 		}
1970 		shell_print(sh, "");
1971 	}
1972 
1973 	shell_print(sh, "%u additional devices found on %s", cnt, argv[ARGV_DEV]);
1974 
1975 	return 0;
1976 }
1977 
1978 #ifdef CONFIG_I3C_USE_IBI
1979 /* i3c ibi hj_response <device> <"ack"/"nack"> */
cmd_i3c_ibi_hj_response(const struct shell * sh,size_t argc,char ** argv)1980 static int cmd_i3c_ibi_hj_response(const struct shell *sh, size_t argc, char **argv)
1981 {
1982 	const struct device *dev;
1983 	bool ack;
1984 	int ret;
1985 
1986 	dev = device_get_binding(argv[ARGV_DEV]);
1987 	if (!dev) {
1988 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
1989 		return -ENODEV;
1990 	}
1991 
1992 	if (strcmp(argv[2], "ack") == 0) {
1993 		ack = true;
1994 	} else if (strcmp(argv[2], "nack") == 0) {
1995 		ack = false;
1996 	} else {
1997 		shell_error(sh, "I3C: invalid parameter");
1998 		return -EINVAL;
1999 	}
2000 
2001 	ret = i3c_ibi_hj_response(dev, ack);
2002 	if (ret != 0) {
2003 		shell_error(sh, "I3C: Unable to set IBI HJ Response");
2004 		return ret;
2005 	}
2006 
2007 	shell_print(sh, "I3C: Set IBI HJ Response");
2008 
2009 	return 0;
2010 }
2011 
2012 /* i3c ibi hj <device> */
cmd_i3c_ibi_hj(const struct shell * sh,size_t argc,char ** argv)2013 static int cmd_i3c_ibi_hj(const struct shell *sh, size_t argc, char **argv)
2014 {
2015 	const struct device *dev;
2016 	struct i3c_ibi request;
2017 	int ret;
2018 
2019 	dev = shell_device_get_binding(argv[ARGV_DEV]);
2020 	if (!dev) {
2021 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
2022 		return -ENODEV;
2023 	}
2024 
2025 	request.ibi_type = I3C_IBI_HOTJOIN;
2026 	ret = i3c_ibi_raise(dev, &request);
2027 	if (ret != 0) {
2028 		shell_error(sh, "I3C: Unable to issue IBI HJ");
2029 		return ret;
2030 	}
2031 
2032 	shell_print(sh, "I3C: Issued IBI HJ");
2033 
2034 	return 0;
2035 }
2036 
2037 /* i3c ibi cr <device> */
cmd_i3c_ibi_cr(const struct shell * sh,size_t argc,char ** argv)2038 static int cmd_i3c_ibi_cr(const struct shell *sh, size_t argc, char **argv)
2039 {
2040 	const struct device *dev;
2041 	struct i3c_ibi request;
2042 	int ret;
2043 
2044 	dev = shell_device_get_binding(argv[ARGV_DEV]);
2045 	if (!dev) {
2046 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
2047 		return -ENODEV;
2048 	}
2049 
2050 	request.ibi_type = I3C_IBI_CONTROLLER_ROLE_REQUEST;
2051 	ret = i3c_ibi_raise(dev, &request);
2052 	if (ret != 0) {
2053 		shell_error(sh, "I3C: Unable to issue IBI CR");
2054 		return ret;
2055 	}
2056 
2057 	shell_print(sh, "I3C: Issued IBI CR");
2058 
2059 	return 0;
2060 }
2061 
2062 /* i3c ibi tir <device> [<bytes>]*/
cmd_i3c_ibi_tir(const struct shell * sh,size_t argc,char ** argv)2063 static int cmd_i3c_ibi_tir(const struct shell *sh, size_t argc, char **argv)
2064 {
2065 	const struct device *dev;
2066 	struct i3c_ibi request;
2067 	uint16_t data_length;
2068 	uint8_t buf[MAX_I3C_BYTES];
2069 	int ret;
2070 	uint8_t i;
2071 
2072 	dev = shell_device_get_binding(argv[ARGV_DEV]);
2073 	if (!dev) {
2074 		shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
2075 		return -ENODEV;
2076 	}
2077 
2078 	data_length = argc - 2;
2079 	for (i = 0; i < data_length; i++) {
2080 		buf[i] = (uint8_t)strtol(argv[2 + i], NULL, 16);
2081 	}
2082 
2083 	request.ibi_type = I3C_IBI_TARGET_INTR;
2084 	request.payload = buf;
2085 	request.payload_len = data_length;
2086 
2087 	ret = i3c_ibi_raise(dev, &request);
2088 	if (ret != 0) {
2089 		shell_error(sh, "I3C: Unable to issue IBI TIR");
2090 		return ret;
2091 	}
2092 
2093 	shell_print(sh, "I3C: Issued IBI TIR");
2094 
2095 	return 0;
2096 }
2097 
2098 /* i3c ibi enable <device> <target> */
cmd_i3c_ibi_enable(const struct shell * sh,size_t argc,char ** argv)2099 static int cmd_i3c_ibi_enable(const struct shell *sh, size_t argc, char **argv)
2100 {
2101 	const struct device *dev, *tdev;
2102 	struct i3c_device_desc *desc;
2103 	int ret;
2104 
2105 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
2106 	if (ret != 0) {
2107 		return ret;
2108 	}
2109 
2110 	ret = i3c_ibi_enable(desc);
2111 	if (ret != 0) {
2112 		shell_error(sh, "I3C: Unable to enable IBI");
2113 		return ret;
2114 	}
2115 
2116 	shell_print(sh, "I3C: Enabled IBI");
2117 
2118 	return 0;
2119 }
2120 
2121 /* i3c ibi disable <device> <target> */
cmd_i3c_ibi_disable(const struct shell * sh,size_t argc,char ** argv)2122 static int cmd_i3c_ibi_disable(const struct shell *sh, size_t argc, char **argv)
2123 {
2124 	const struct device *dev, *tdev;
2125 	struct i3c_device_desc *desc;
2126 	int ret;
2127 
2128 	ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc);
2129 	if (ret != 0) {
2130 		return ret;
2131 	}
2132 
2133 	ret = i3c_ibi_disable(desc);
2134 	if (ret != 0) {
2135 		shell_error(sh, "I3C: Unable to disable IBI");
2136 		return ret;
2137 	}
2138 
2139 	shell_print(sh, "I3C: Disabled IBI");
2140 
2141 	return 0;
2142 }
2143 #endif
2144 
i3c_device_list_target_name_get(size_t idx,struct shell_static_entry * entry)2145 static void i3c_device_list_target_name_get(size_t idx, struct shell_static_entry *entry)
2146 {
2147 	if (idx < ARRAY_SIZE(i3c_list)) {
2148 		entry->syntax = i3c_list[idx].dev->name;
2149 		entry->handler = NULL;
2150 		entry->help = NULL;
2151 		entry->subcmd = i3c_list[idx].i3c_list_dev_subcmd;
2152 	} else {
2153 		entry->syntax = NULL;
2154 	}
2155 }
2156 
2157 SHELL_DYNAMIC_CMD_CREATE(dsub_i3c_device_list_name, i3c_device_list_target_name_get);
2158 
i3c_device_attached_target_name_get(size_t idx,struct shell_static_entry * entry)2159 static void i3c_device_attached_target_name_get(size_t idx, struct shell_static_entry *entry)
2160 {
2161 	if (idx < ARRAY_SIZE(i3c_list)) {
2162 		entry->syntax = i3c_list[idx].dev->name;
2163 		entry->handler = NULL;
2164 		entry->help = NULL;
2165 		entry->subcmd = i3c_list[idx].i3c_attached_dev_subcmd;
2166 	} else {
2167 		entry->syntax = NULL;
2168 	}
2169 }
2170 
2171 SHELL_DYNAMIC_CMD_CREATE(dsub_i3c_device_attached_name, i3c_device_attached_target_name_get);
2172 
i3c_device_name_get(size_t idx,struct shell_static_entry * entry)2173 static void i3c_device_name_get(size_t idx, struct shell_static_entry *entry)
2174 {
2175 	if (idx < ARRAY_SIZE(i3c_list)) {
2176 		entry->syntax = i3c_list[idx].dev->name;
2177 		entry->handler = NULL;
2178 		entry->help = NULL;
2179 		entry->subcmd = NULL;
2180 	} else {
2181 		entry->syntax = NULL;
2182 	}
2183 }
2184 
2185 SHELL_DYNAMIC_CMD_CREATE(dsub_i3c_device_name, i3c_device_name_get);
2186 
2187 #ifdef CONFIG_I3C_USE_IBI
2188 /* L2 I3C IBI Shell Commands*/
2189 SHELL_STATIC_SUBCMD_SET_CREATE(
2190 	sub_i3c_ibi_cmds,
2191 	SHELL_CMD_ARG(hj_response, &dsub_i3c_device_name,
2192 		      "Set IBI HJ Response\n"
2193 		      "Usage: ibi hj_response <device> <\"ack\"/\"nack\">",
2194 		      cmd_i3c_ibi_hj_response, 3, 0),
2195 	SHELL_CMD_ARG(hj, &dsub_i3c_device_name,
2196 		      "Send IBI HJ\n"
2197 		      "Usage: ibi hj <device>",
2198 		      cmd_i3c_ibi_hj, 2, 0),
2199 	SHELL_CMD_ARG(tir, &dsub_i3c_device_name,
2200 		      "Send IBI TIR\n"
2201 		      "Usage: ibi tir <device> [<byte1>, ...]",
2202 		      cmd_i3c_ibi_tir, 2, MAX_I3C_BYTES),
2203 	SHELL_CMD_ARG(cr, &dsub_i3c_device_name,
2204 		      "Send IBI CR\n"
2205 		      "Usage: ibi cr <device>",
2206 		      cmd_i3c_ibi_cr, 2, 0),
2207 	SHELL_CMD_ARG(enable, &dsub_i3c_device_attached_name,
2208 		      "Enable receiving IBI from target\n"
2209 		      "Usage: ibi enable <device> <target>",
2210 		      cmd_i3c_ibi_enable, 3, 0),
2211 	SHELL_CMD_ARG(disable, &dsub_i3c_device_attached_name,
2212 		      "Disable receiving IBI from target\n"
2213 		      "Usage: ibi disable <device> <target>",
2214 		      cmd_i3c_ibi_disable, 3, 0),
2215 	SHELL_SUBCMD_SET_END /* Array terminated. */
2216 );
2217 #endif
2218 
2219 /* L3 I3C HDR DDR Shell Commands*/
2220 SHELL_STATIC_SUBCMD_SET_CREATE(
2221 	sub_i3c_hdr_ddr_cmds,
2222 	SHELL_CMD_ARG(write, &dsub_i3c_device_attached_name,
2223 		      "Send HDR DDR Write\n"
2224 		      "Usage: hdr ddr write <device> <target> <7b cmd> [<byte1>, ...]",
2225 		      cmd_i3c_hdr_ddr_write, 4, MAX_I3C_BYTES),
2226 	SHELL_CMD_ARG(read, &dsub_i3c_device_attached_name,
2227 		      "Send HDR DDR Read\n"
2228 		      "Usage: hdr ddr read <device> <target> <7b cmd> <bytes>",
2229 		      cmd_i3c_hdr_ddr_read, 5, 0),
2230 	SHELL_SUBCMD_SET_END /* Array terminated. */
2231 );
2232 
2233 /* L2 I3C HDR Shell Commands*/
2234 SHELL_STATIC_SUBCMD_SET_CREATE(
2235 	sub_i3c_hdr_cmds,
2236 	SHELL_CMD_ARG(ddr, &sub_i3c_hdr_ddr_cmds,
2237 		      "Send HDR DDR\n"
2238 		      "Usage: hdr ddr <sub cmd>",
2239 		      NULL, 2, 0),
2240 	SHELL_SUBCMD_SET_END /* Array terminated. */
2241 );
2242 
2243 /* L2 I3C CCC Shell Commands*/
2244 SHELL_STATIC_SUBCMD_SET_CREATE(
2245 	sub_i3c_ccc_cmds,
2246 	SHELL_CMD_ARG(rstdaa, &dsub_i3c_device_name,
2247 		      "Send CCC RSTDAA\n"
2248 		      "Usage: ccc rstdaa <device>",
2249 		      cmd_i3c_ccc_rstdaa, 2, 0),
2250 	SHELL_CMD_ARG(entdaa, &dsub_i3c_device_name,
2251 		      "Send CCC ENTDAA\n"
2252 		      "Usage: ccc entdaa <device>",
2253 		      cmd_i3c_ccc_entdaa, 2, 0),
2254 	SHELL_CMD_ARG(setaasa, &dsub_i3c_device_name,
2255 		      "Send CCC SETAASA\n"
2256 		      "Usage: ccc setaasa <device>",
2257 		      cmd_i3c_ccc_setaasa, 2, 0),
2258 	SHELL_CMD_ARG(setdasa, &dsub_i3c_device_attached_name,
2259 		      "Send CCC SETDASA\n"
2260 		      "Usage: ccc setdasa <device> <target> <dynamic address>",
2261 		      cmd_i3c_ccc_setdasa, 4, 0),
2262 	SHELL_CMD_ARG(setnewda, &dsub_i3c_device_attached_name,
2263 		      "Send CCC SETNEWDA\n"
2264 		      "Usage: ccc setnewda <device> <target> <dynamic address>",
2265 		      cmd_i3c_ccc_setnewda, 4, 0),
2266 	SHELL_CMD_ARG(getbcr, &dsub_i3c_device_attached_name,
2267 		      "Send CCC GETBCR\n"
2268 		      "Usage: ccc getbcr <device> <target>",
2269 		      cmd_i3c_ccc_getbcr, 3, 0),
2270 	SHELL_CMD_ARG(getdcr, &dsub_i3c_device_attached_name,
2271 		      "Send CCC GETDCR\n"
2272 		      "Usage: ccc getdcr <device> <target>",
2273 		      cmd_i3c_ccc_getdcr, 3, 0),
2274 	SHELL_CMD_ARG(getpid, &dsub_i3c_device_attached_name,
2275 		      "Send CCC GETPID\n"
2276 		      "Usage: ccc getpid <device> <target>",
2277 		      cmd_i3c_ccc_getpid, 3, 0),
2278 	SHELL_CMD_ARG(getmrl, &dsub_i3c_device_attached_name,
2279 		      "Send CCC GETMRL\n"
2280 		      "Usage: ccc getmrl <device> <target>",
2281 		      cmd_i3c_ccc_getmrl, 3, 0),
2282 	SHELL_CMD_ARG(getmwl, &dsub_i3c_device_attached_name,
2283 		      "Send CCC GETMWL\n"
2284 		      "Usage: ccc getmwl <device> <target>",
2285 		      cmd_i3c_ccc_getmwl, 3, 0),
2286 	SHELL_CMD_ARG(setmrl, &dsub_i3c_device_attached_name,
2287 		      "Send CCC SETMRL\n"
2288 		      "Usage: ccc setmrl <device> <target> <max read length> [<max ibi length>]",
2289 		      cmd_i3c_ccc_setmrl, 4, 1),
2290 	SHELL_CMD_ARG(setmwl, &dsub_i3c_device_attached_name,
2291 		      "Send CCC SETMWL\n"
2292 		      "Usage: ccc setmwl <device> <target> <max write length>",
2293 		      cmd_i3c_ccc_setmwl, 4, 0),
2294 	SHELL_CMD_ARG(setmrl_bc, &dsub_i3c_device_name,
2295 		      "Send CCC SETMRL BC\n"
2296 		      "Usage: ccc setmrl_bc <device> <max read length> [<max ibi length>]",
2297 		      cmd_i3c_ccc_setmrl_bc, 3, 1),
2298 	SHELL_CMD_ARG(setmwl_bc, &dsub_i3c_device_name,
2299 		      "Send CCC SETMWL BC\n"
2300 		      "Usage: ccc setmwl_bc <device> <max write length>",
2301 		      cmd_i3c_ccc_setmwl_bc, 3, 0),
2302 	SHELL_CMD_ARG(deftgts, &dsub_i3c_device_name,
2303 		      "Send CCC DEFTGTS\n"
2304 		      "Usage: ccc deftgts <device>",
2305 		      cmd_i3c_ccc_deftgts, 2, 0),
2306 	SHELL_CMD_ARG(enttm, &dsub_i3c_device_name,
2307 		      "Send CCC ENTTM\n"
2308 		      "Usage: ccc enttm <device> <defining byte>",
2309 		      cmd_i3c_ccc_enttm, 3, 0),
2310 	SHELL_CMD_ARG(rstact, &dsub_i3c_device_attached_name,
2311 		      "Send CCC RSTACT\n"
2312 		      "Usage: ccc rstact <device> <target> <\"set\"/\"get\"> <defining byte>",
2313 		      cmd_i3c_ccc_rstact, 5, 0),
2314 	SHELL_CMD_ARG(getacccr, &dsub_i3c_device_attached_name,
2315 		      "Send CCC GETACCCR\n"
2316 		      "Usage: ccc getacccr <device> <target>",
2317 		      cmd_i3c_ccc_getacccr, 3, 0),
2318 	SHELL_CMD_ARG(rstact_bc, &dsub_i3c_device_name,
2319 		      "Send CCC RSTACT BC\n"
2320 		      "Usage: ccc rstact_bc <device> <defining byte>",
2321 		      cmd_i3c_ccc_rstact_bc, 3, 0),
2322 	SHELL_CMD_ARG(enec_bc, &dsub_i3c_device_name,
2323 		      "Send CCC ENEC BC\n"
2324 		      "Usage: ccc enec_bc <device> <defining byte>",
2325 		      cmd_i3c_ccc_enec_bc, 3, 0),
2326 	SHELL_CMD_ARG(disec_bc, &dsub_i3c_device_name,
2327 		      "Send CCC DISEC BC\n"
2328 		      "Usage: ccc disec_bc <device> <defining byte>",
2329 		      cmd_i3c_ccc_disec_bc, 3, 0),
2330 	SHELL_CMD_ARG(enec, &dsub_i3c_device_attached_name,
2331 		      "Send CCC ENEC\n"
2332 		      "Usage: ccc enec <device> <target> <defining byte>",
2333 		      cmd_i3c_ccc_enec, 4, 0),
2334 	SHELL_CMD_ARG(disec, &dsub_i3c_device_attached_name,
2335 		      "Send CCC DISEC\n"
2336 		      "Usage: ccc disec <device> <target> <defining byte>",
2337 		      cmd_i3c_ccc_disec, 4, 0),
2338 	SHELL_CMD_ARG(entas0_bc, &dsub_i3c_device_name,
2339 		      "Send CCC ENTAS0 BC\n"
2340 		      "Usage: ccc entas0 <device>",
2341 		      cmd_i3c_ccc_entas0_bc, 2, 0),
2342 	SHELL_CMD_ARG(entas1_bc, &dsub_i3c_device_name,
2343 		      "Send CCC ENTAS1 BC\n"
2344 		      "Usage: ccc entas1 <device>",
2345 		      cmd_i3c_ccc_entas1_bc, 2, 0),
2346 	SHELL_CMD_ARG(entas2_bc, &dsub_i3c_device_name,
2347 		      "Send CCC ENTAS2 BC\n"
2348 		      "Usage: ccc entas2 <device>",
2349 		      cmd_i3c_ccc_entas2_bc, 2, 0),
2350 	SHELL_CMD_ARG(entas3_bc, &dsub_i3c_device_name,
2351 		      "Send CCC ENTAS3 BC\n"
2352 		      "Usage: ccc entas3 <device>",
2353 		      cmd_i3c_ccc_entas3_bc, 2, 0),
2354 	SHELL_CMD_ARG(entas0, &dsub_i3c_device_attached_name,
2355 		      "Send CCC ENTAS0\n"
2356 		      "Usage: ccc entas0 <device> <target>",
2357 		      cmd_i3c_ccc_entas0, 3, 0),
2358 	SHELL_CMD_ARG(entas1, &dsub_i3c_device_attached_name,
2359 		      "Send CCC ENTAS1\n"
2360 		      "Usage: ccc entas1 <device> <target>",
2361 		      cmd_i3c_ccc_entas1, 3, 0),
2362 	SHELL_CMD_ARG(entas2, &dsub_i3c_device_attached_name,
2363 		      "Send CCC ENTAS2\n"
2364 		      "Usage: ccc entas2 <device> <target>",
2365 		      cmd_i3c_ccc_entas2, 3, 0),
2366 	SHELL_CMD_ARG(entas3, &dsub_i3c_device_attached_name,
2367 		      "Send CCC ENTAS3\n"
2368 		      "Usage: ccc entas3 <device> <target>",
2369 		      cmd_i3c_ccc_entas3, 3, 0),
2370 	SHELL_CMD_ARG(getstatus, &dsub_i3c_device_attached_name,
2371 		      "Send CCC GETSTATUS\n"
2372 		      "Usage: ccc getstatus <device> <target> [<defining byte>]",
2373 		      cmd_i3c_ccc_getstatus, 3, 1),
2374 	SHELL_CMD_ARG(getcaps, &dsub_i3c_device_attached_name,
2375 		      "Send CCC GETCAPS\n"
2376 		      "Usage: ccc getcaps <device> <target> [<defining byte>]",
2377 		      cmd_i3c_ccc_getcaps, 3, 1),
2378 	SHELL_CMD_ARG(getmxds, &dsub_i3c_device_attached_name,
2379 		      "Send CCC GETMXDS\n"
2380 		      "Usage: ccc getmxds <device> <target> [<defining byte>]",
2381 		      cmd_i3c_ccc_getmxds, 3, 1),
2382 	SHELL_CMD_ARG(setbuscon, &dsub_i3c_device_name,
2383 		      "Send CCC SETBUSCON\n"
2384 		      "Usage: ccc setbuscon <device> <context> [<optional bytes>]",
2385 		      cmd_i3c_ccc_setbuscon, 3, MAX_I3C_BYTES - 1),
2386 	SHELL_CMD_ARG(getvendor, &dsub_i3c_device_attached_name,
2387 		      "Send CCC GETVENDOR\n"
2388 		      "Usage: ccc getvendor <device> <target> <id> [<defining byte>]",
2389 		      cmd_i3c_ccc_getvendor, 4, 1),
2390 	SHELL_CMD_ARG(setvendor, &dsub_i3c_device_attached_name,
2391 		      "Send CCC SETVENDOR\n"
2392 		      "Usage: ccc setvendor <device> <target> <id> [<bytes>]",
2393 		      cmd_i3c_ccc_setvendor, 4, MAX_I3C_BYTES),
2394 	SHELL_CMD_ARG(setvendor_bc, &dsub_i3c_device_name,
2395 		      "Send CCC SETVENDOR BC\n"
2396 		      "Usage: ccc setvendor_bc <device> <id> [<bytes>]",
2397 		      cmd_i3c_ccc_setvendor_bc, 3, MAX_I3C_BYTES),
2398 	SHELL_SUBCMD_SET_END /* Array terminated. */
2399 );
2400 
2401 /* L1 I3C Shell Commands*/
2402 SHELL_STATIC_SUBCMD_SET_CREATE(
2403 	sub_i3c_cmds,
2404 	SHELL_CMD_ARG(info, &dsub_i3c_device_attached_name,
2405 		      "Get I3C device info\n"
2406 		      "Usage: info <device> [<target>]",
2407 		      cmd_i3c_info, 2, 1),
2408 	SHELL_CMD_ARG(speed, &dsub_i3c_device_name,
2409 		      "Set I3C device speed\n"
2410 		      "Usage: speed <device> <speed>",
2411 		      cmd_i3c_speed, 3, 0),
2412 	SHELL_CMD_ARG(recover, &dsub_i3c_device_name,
2413 		      "Recover I3C bus\n"
2414 		      "Usage: recover <device>",
2415 		      cmd_i3c_recover, 2, 0),
2416 	SHELL_CMD_ARG(read, &dsub_i3c_device_attached_name,
2417 		      "Read bytes from an I3C device\n"
2418 		      "Usage: read <device> <target> <reg> [<bytes>]",
2419 		      cmd_i3c_read, 4, 1),
2420 	SHELL_CMD_ARG(read_byte, &dsub_i3c_device_attached_name,
2421 		      "Read a byte from an I3C device\n"
2422 		      "Usage: read_byte <device> <target> <reg>",
2423 		      cmd_i3c_read_byte, 4, 0),
2424 	SHELL_CMD_ARG(write, &dsub_i3c_device_attached_name,
2425 		      "Write bytes to an I3C device\n"
2426 		      "Usage: write <device> <target> <reg> [<byte1>, ...]",
2427 		      cmd_i3c_write, 4, MAX_I3C_BYTES),
2428 	SHELL_CMD_ARG(write_byte, &dsub_i3c_device_attached_name,
2429 		      "Write a byte to an I3C device\n"
2430 		      "Usage: write_byte <device> <target> <reg> <value>",
2431 		      cmd_i3c_write_byte, 5, 0),
2432 	SHELL_CMD_ARG(i3c_attach, &dsub_i3c_device_list_name,
2433 		      "Attach I3C device from the bus\n"
2434 		      "Usage: i3c_attach <device> <target>",
2435 		      cmd_i3c_attach, 3, 0),
2436 	SHELL_CMD_ARG(i3c_reattach, &dsub_i3c_device_attached_name,
2437 		      "Reattach I3C device from the bus\n"
2438 		      "Usage: i3c_reattach <device> <target> [<old dynamic address>]",
2439 		      cmd_i3c_reattach, 3, 1),
2440 	SHELL_CMD_ARG(i3c_detach, &dsub_i3c_device_attached_name,
2441 		      "Detach I3C device from the bus\n"
2442 		      "Usage: i3c_detach <device> <target>",
2443 		      cmd_i3c_detach, 3, 0),
2444 	SHELL_CMD_ARG(i2c_attach, &dsub_i3c_device_name,
2445 		      "Attach I2C device from the bus\n"
2446 		      "Usage: i2c_attach <device> <addr>",
2447 		      cmd_i3c_i2c_attach, 3, 0),
2448 	SHELL_CMD_ARG(i2c_detach, &dsub_i3c_device_name,
2449 		      "Detach I2C device from the bus\n"
2450 		      "Usage: i2c_detach <device> <addr>",
2451 		      cmd_i3c_i2c_detach, 3, 0),
2452 	SHELL_CMD_ARG(i2c_scan, &dsub_i3c_device_name,
2453 		      "Scan I2C devices\n"
2454 		      "Usage: i2c_scan <device>",
2455 		      cmd_i3c_i2c_scan, 2, 0),
2456 	SHELL_CMD_ARG(ccc, &sub_i3c_ccc_cmds,
2457 		      "Send I3C CCC\n"
2458 		      "Usage: ccc <sub cmd>",
2459 		      NULL, 3, 0),
2460 	SHELL_CMD_ARG(hdr, &sub_i3c_hdr_cmds,
2461 		      "Send I3C HDR\n"
2462 		      "Usage: hdr <sub cmd>",
2463 		      NULL, 3, 0),
2464 #ifdef CONFIG_I3C_USE_IBI
2465 	SHELL_CMD_ARG(ibi, &sub_i3c_ibi_cmds,
2466 		      "Send I3C IBI\n"
2467 		      "Usage: ibi <sub cmd>",
2468 		      NULL, 3, 0),
2469 #endif
2470 	SHELL_SUBCMD_SET_END /* Array terminated. */
2471 );
2472 
2473 SHELL_CMD_REGISTER(i3c, &sub_i3c_cmds, "I3C commands", NULL);
2474