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