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