2 * (C) Copyright 2017 Lothar Waßmann <LW@KARO-electronics.de>
4 * SPDX-License-Identifier: GPL-2.0+
8 * Sergey Kubushyn, himself, ksi@koi8.net
11 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
19 #include <environment.h>
22 #include <asm/byteorder.h>
23 #include <linux/compiler.h>
24 #include <spmi/spmi.h>
26 DECLARE_GLOBAL_DATA_PTR;
33 static int spmi_report_err(int ret, enum spmi_err_op op)
35 printf("Error %s the chip: %d\n",
36 op == SPMI_ERR_READ ? "reading" : "writing", ret);
38 return CMD_RET_FAILURE;
42 * do_spmi_read() - Handle the "spmi read" command-line command
43 * @cmdtp: Command data struct pointer
45 * @argc: Command-line argument count
46 * @argv: Array of command-line arguments
48 * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
52 * spmi read {spmi_chip} {devaddr}{.0, .1, .2} {len} {memaddr}
54 static int do_spmi_read(cmd_tbl_t *cmdtp, int flag, int argc,
57 uint sid, pid, reg, cnt = 1;
63 if (argc < 4 || argc > 5)
64 return cmd_usage(cmdtp);
66 ret = uclass_get_device_by_name(UCLASS_SPMI, "spmi", &dev);
68 printf("Failed to get SPMI bus: %d\n", ret);
69 return CMD_RET_FAILURE;
73 sid = simple_strtoul(argv[1], NULL, 16);
75 printf("SID %02x out of range 0..5\n", sid);
76 return CMD_RET_FAILURE;
79 /* SPMI peripheral ID */
80 pid = simple_strtoul(argv[2], NULL, 16);
82 printf("PID %02x out of range 0x00..0xff\n", pid);
83 return CMD_RET_FAILURE;
86 /* SPMI register offset */
87 reg = simple_strtoul(argv[3], NULL, 16);
89 printf("REG offset %02x out of range 0x00..0xff\n", reg);
90 return CMD_RET_FAILURE;
95 cnt = simple_strtoul(argv[4], NULL, 16);
96 if (cnt == 0 || cnt > sizeof(buf)) {
97 printf("Byte count %u out of range 1..%lu\n",
99 return CMD_RET_FAILURE;
103 debug("%s@%d: Reading SID %02x PID %02x REG %02x\n", __func__, __LINE__,
105 ret = spmi_read(dev, buf, sid, pid, reg, cnt);
107 return spmi_report_err(ret, SPMI_ERR_READ);
109 for (i = 0; i < cnt; i++)
110 printf("%02x\n", buf[i]);
112 return CMD_RET_SUCCESS;
115 static int do_spmi_write(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
123 return cmd_usage(cmdtp);
125 ret = uclass_get_device_by_name(UCLASS_SPMI, "spmi", &dev);
127 printf("Failed to get SPMI bus: %d\n", ret);
128 return CMD_RET_FAILURE;
134 sid = simple_strtoul(argv[1], NULL, 16);
135 pid = simple_strtoul(argv[2], NULL, 16);
136 reg = simple_strtoul(argv[3], NULL, 16);
137 val = simple_strtoul(argv[4], NULL, 16);
139 printf("Value %08x out of range [0..255]\n", val);
140 return CMD_RET_FAILURE;
143 debug("%s@%d: Writing SID %02x PID %02x REG %02x value %02x\n",
144 __func__, __LINE__, sid, pid, reg, val);
145 ret = spmi_reg_write(dev, sid, pid, reg, val);
147 return spmi_report_err(ret, SPMI_ERR_WRITE);
149 return CMD_RET_SUCCESS;
152 static cmd_tbl_t cmd_spmi_sub[] = {
153 U_BOOT_CMD_MKENT(read, 4, 1, do_spmi_read, "", ""),
154 U_BOOT_CMD_MKENT(write, 5, 0, do_spmi_write, "", ""),
157 static __maybe_unused void spmi_reloc(void)
159 static int relocated;
162 fixup_cmdtable(cmd_spmi_sub, ARRAY_SIZE(cmd_spmi_sub));
168 * do_spmi() - Handle the "spmi" command-line command
169 * @cmdtp: Command data struct pointer
170 * @flag: Command flag
171 * @argc: Command-line argument count
172 * @argv: Array of command-line arguments
174 * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
177 static int do_spmi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
181 #ifdef CONFIG_NEEDS_MANUAL_RELOC
186 return CMD_RET_USAGE;
188 /* Strip off leading 'spmi' command argument */
192 c = find_cmd_tbl(argv[0], cmd_spmi_sub, ARRAY_SIZE(cmd_spmi_sub));
195 return c->cmd(cmdtp, flag, argc, argv);
197 printf("subcommand '%s' not found\n", argv[0]);
198 return CMD_RET_USAGE;
201 #ifdef CONFIG_SYS_LONGHELP
202 static char spmi_help_text[] =
203 "\tspmi read <sid> <pid> <reg> - read register <reg> of peripheral <pid> on slave <sid>\n"
204 "\tspmi write <sid> <pid> <reg> <val> - write <val> to register <reg> of peripheral <pid> on slave <sid>\n"