2 * (C) Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
4 * SPDX-License-Identifier: GPL-2.0+
14 #include <power/pmic-qcom-smd-rpm.h>
16 DECLARE_GLOBAL_DATA_PTR;
18 static bool smd_inited;
20 static uint32_t smd_rpm_msg[] = {
21 LDOA_RES_TYPE, 0, KEY_SOFTWARE_ENABLE, 4, 0,
26 #define smd_param_ldo smd_rpm_msg[1]
27 #define smd_param_enable smd_rpm_msg[4]
28 #define smd_param_uV smd_rpm_msg[7]
29 #define smd_param_uA smd_rpm_msg[10]
31 static int do_smd_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
37 return CMD_RET_SUCCESS;
40 static int do_smd_uninit(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
46 return CMD_RET_SUCCESS;
50 static void dump_rpm_msg(void *_msg, size_t msglen)
56 for (m = 0; m < msglen / 4; m++) {
57 printf(" %08x", msg[m]);
62 static inline void dump_rpm_msg(void *_msg, size_t msglen)
67 static int do_raw_write(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
70 size_t msglen = argc * sizeof(uint32_t);
72 static size_t msgsize;
78 if (msg == NULL || msgsize < msglen) {
83 return CMD_RET_FAILURE;
88 for (i = 0; i < argc; i++)
89 msg[i] = strtoul(argv[i], NULL, 16);
91 dump_rpm_msg(msg, msglen);
96 ret = rpm_send_data(msg, msglen, RPM_REQUEST_TYPE);
98 printf("Failed to configure regulator LDO%u\n", smd_param_ldo);
103 return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
106 static int do_smd_write(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
112 if (argv[0][0] == 'w')
113 return do_raw_write(cmdtp, flag, argc - 1, &argv[1]);
115 if (argc < 2 || argc > 4)
116 return cmd_usage(cmdtp);
118 msglen = 5 * sizeof(uint32_t);
119 smd_param_enable = argv[0][0] == 'e';
121 ldo = simple_strtoul(argv[1], NULL, 10);
123 return CMD_RET_USAGE;
129 uV = simple_strtoul(argv[2], NULL, 10);
131 msglen += 3 * sizeof(uint32_t);
133 printf("LDO%u has no voltage control\n", ldo);
137 uA = simple_strtoul(argv[3], NULL, 10);
139 msglen += 3 * sizeof(uint32_t);
141 printf("%sabling LDO%u", smd_param_enable == GENERIC_ENABLE ? "En" : "Dis",
144 printf(": %u.%03uV", smd_param_uV / 1000000,
145 smd_param_uV / 1000 % 1000);
147 printf(", %u.%03umA", smd_param_uA / 1000,
148 smd_param_uA % 1000);
154 dump_rpm_msg(smd_rpm_msg, msglen);
155 ret = rpm_send_data(smd_rpm_msg, msglen, RPM_REQUEST_TYPE);
157 printf("Failed to configure regulator LDO%u\n", smd_param_ldo);
162 return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
165 static cmd_tbl_t cmd_smd_sub[] = {
166 U_BOOT_CMD_MKENT(init, 0, 1, do_smd_init, "", ""),
167 U_BOOT_CMD_MKENT(uninit, 0, 1, do_smd_uninit, "", ""),
168 U_BOOT_CMD_MKENT(enable, 4, 1, do_smd_write, "", ""),
169 U_BOOT_CMD_MKENT(disable, 5, 0, do_smd_write, "", ""),
170 U_BOOT_CMD_MKENT(write, 4, 1, do_smd_write, "", ""),
173 static inline void smd_reloc(void)
175 static int relocated;
178 fixup_cmdtable(cmd_smd_sub, ARRAY_SIZE(cmd_smd_sub));
184 * do_smd() - Handle the "smd" command-line command
185 * @cmdtp: Command data struct pointer
186 * @flag: Command flag
187 * @argc: Command-line argument count
188 * @argv: Array of command-line arguments
190 * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
193 static int do_smd(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
197 #ifdef CONFIG_NEEDS_MANUAL_RELOC
202 return CMD_RET_USAGE;
204 /* Strip off leading 'smd' command argument */
208 c = find_cmd_tbl(argv[0], cmd_smd_sub, ARRAY_SIZE(cmd_smd_sub));
211 return c->cmd(cmdtp, flag, argc, argv);
213 printf("subcommand '%s' not found\n", argv[0]);
214 return CMD_RET_USAGE;
217 #ifdef CONFIG_SYS_LONGHELP
218 static char smd_help_text[] =
221 "\tsmd enable <ldo#> [<uV>] [<uA>] - Enable LDO<ldo#> optionally setting voltage and current\n"
222 "\tsmd disable <ldo#> [<uV>] [<uA>] - Disable LDO<ldö#>\n"
223 "\tsmd write <keycode> <key> [<param> <value>] [...]\n"
230 "Qualcomm SMD sub-system",