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