1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2014-2015 Samsung Electronics
4 * Przemyslaw Marczak <p.marczak@samsung.com>
9 #include <dm/uclass-internal.h>
10 #include <linux/printk.h>
11 #include <power/regulator.h>
13 #define LIMIT_DEVNAME 20
14 #define LIMIT_OFNAME 32
17 static struct udevice
*currdev
;
19 static int failure(int ret
)
21 printf("Error: %d (%s)\n", ret
, errno_str(ret
));
23 return CMD_RET_FAILURE
;
26 static int do_dev(struct cmd_tbl
*cmdtp
, int flag
, int argc
, char *const argv
[])
28 struct dm_regulator_uclass_plat
*uc_pdata
;
35 ret
= regulator_get_by_platname(name
, &currdev
);
37 printf("Can't get the regulator: %s!\n", name
);
43 printf("Regulator device is not set!\n\n");
47 uc_pdata
= dev_get_uclass_plat(currdev
);
49 printf("%s: no regulator platform data!\n", currdev
->name
);
53 printf("dev: %s @ %s\n", uc_pdata
->name
, currdev
->name
);
56 return CMD_RET_SUCCESS
;
59 static int curr_dev_and_plat(struct udevice
**devp
,
60 struct dm_regulator_uclass_plat
**uc_pdata
,
61 bool allow_type_fixed
)
67 printf("First, set the regulator device!\n");
68 return CMD_RET_FAILURE
;
73 *uc_pdata
= dev_get_uclass_plat(*devp
);
75 pr_err("Regulator: %s - missing platform data!\n", currdev
->name
);
76 return CMD_RET_FAILURE
;
79 if (!allow_type_fixed
&& (*uc_pdata
)->type
== REGULATOR_TYPE_FIXED
) {
80 printf("Operation not allowed for fixed regulator!\n");
81 return CMD_RET_FAILURE
;
84 return CMD_RET_SUCCESS
;
87 static int do_list(struct cmd_tbl
*cmdtp
, int flag
, int argc
,
90 struct dm_regulator_uclass_plat
*uc_pdata
;
94 printf("| %-*.*s| %-*.*s| %s\n",
95 LIMIT_DEVNAME
, LIMIT_DEVNAME
, "Device",
96 LIMIT_OFNAME
, LIMIT_OFNAME
, "regulator-name",
99 for (ret
= uclass_find_first_device(UCLASS_REGULATOR
, &dev
); dev
;
100 ret
= uclass_find_next_device(&dev
)) {
104 uc_pdata
= dev_get_uclass_plat(dev
);
105 printf("| %-*.*s| %-*.*s| %s\n",
106 LIMIT_DEVNAME
, LIMIT_DEVNAME
, dev
->name
,
107 LIMIT_OFNAME
, LIMIT_OFNAME
, uc_pdata
->name
,
114 static int constraint(const char *name
, int val
, const char *val_name
)
116 printf("%-*s", LIMIT_INFO
, name
);
118 printf(" %s (err: %d)\n", errno_str(val
), val
);
123 printf(" %d (%s)\n", val
, val_name
);
125 printf(" %d\n", val
);
130 static const char *get_mode_name(struct dm_regulator_mode
*mode
,
134 while (mode_count
--) {
135 if (mode
->id
== mode_id
)
143 static int do_info(struct cmd_tbl
*cmdtp
, int flag
, int argc
,
147 struct dm_regulator_uclass_plat
*uc_pdata
;
148 struct dm_regulator_mode
*modes
;
149 const char *parent_uc
;
154 ret
= curr_dev_and_plat(&dev
, &uc_pdata
, true);
158 parent_uc
= dev_get_uclass_name(dev
->parent
);
160 printf("%s\n%-*s %s\n%-*s %s\n%-*s %s\n%-*s %s\n%-*s\n",
162 LIMIT_INFO
, "* regulator-name:", uc_pdata
->name
,
163 LIMIT_INFO
, "* device name:", dev
->name
,
164 LIMIT_INFO
, "* parent name:", dev
->parent
->name
,
165 LIMIT_INFO
, "* parent uclass:", parent_uc
,
166 LIMIT_INFO
, "* constraints:");
168 constraint(" - min uV:", uc_pdata
->min_uV
, NULL
);
169 constraint(" - max uV:", uc_pdata
->max_uV
, NULL
);
170 constraint(" - min uA:", uc_pdata
->min_uA
, NULL
);
171 constraint(" - max uA:", uc_pdata
->max_uA
, NULL
);
172 constraint(" - always on:", uc_pdata
->always_on
,
173 uc_pdata
->always_on
? "true" : "false");
174 constraint(" - boot on:", uc_pdata
->boot_on
,
175 uc_pdata
->boot_on
? "true" : "false");
177 mode_count
= regulator_mode(dev
, &modes
);
178 constraint("* op modes:", mode_count
, NULL
);
180 for (i
= 0; i
< mode_count
; i
++, modes
++)
181 constraint(" - mode id:", modes
->id
, modes
->name
);
183 return CMD_RET_SUCCESS
;
186 static void do_status_detail(struct udevice
*dev
,
187 struct dm_regulator_uclass_plat
*uc_pdata
)
189 int current
, value
, mode
;
190 const char *mode_name
;
193 printf("Regulator %s status:\n", uc_pdata
->name
);
195 enabled
= regulator_get_enable(dev
);
196 constraint(" * enable:", enabled
, enabled
? "true" : "false");
198 value
= regulator_get_value(dev
);
199 constraint(" * value uV:", value
, NULL
);
201 current
= regulator_get_current(dev
);
202 constraint(" * current uA:", current
, NULL
);
204 mode
= regulator_get_mode(dev
);
205 mode_name
= get_mode_name(uc_pdata
->mode
, uc_pdata
->mode_count
, mode
);
206 constraint(" * mode id:", mode
, mode_name
);
209 static void do_status_line(struct udevice
*dev
, int status
)
211 struct dm_regulator_uclass_plat
*pdata
;
212 int current
, value
, mode
;
213 const char *mode_name
;
216 pdata
= dev_get_uclass_plat(dev
);
217 enabled
= regulator_get_enable(dev
);
218 value
= regulator_get_value(dev
);
219 current
= regulator_get_current(dev
);
220 mode
= regulator_get_mode(dev
);
221 mode_name
= get_mode_name(pdata
->mode
, pdata
->mode_count
, mode
);
222 printf("%-20s %-10s ", pdata
->name
, enabled
? "enabled" : "disabled");
224 printf("%10d ", value
);
226 printf("%10s ", "-");
228 printf("%10d ", current
);
230 printf("%10s ", "-");
232 printf("%-10s", mode_name
);
234 printf("%-10s", "-");
235 printf(" %i", status
);
239 static int do_status(struct cmd_tbl
*cmdtp
, int flag
, int argc
,
242 struct dm_regulator_uclass_plat
*uc_pdata
;
246 if (currdev
&& (argc
< 2 || strcmp(argv
[1], "-a"))) {
247 ret
= curr_dev_and_plat(&dev
, &uc_pdata
, true);
249 return CMD_RET_FAILURE
;
250 do_status_detail(dev
, uc_pdata
);
254 /* Show all of them in a list, probing them as needed */
255 printf("%-20s %-10s %10s %10s %-10s %s\n", "Name", "Enabled", "uV", "mA",
257 for (ret
= uclass_first_device_check(UCLASS_REGULATOR
, &dev
); dev
;
258 ret
= uclass_next_device_check(&dev
))
259 do_status_line(dev
, ret
);
261 return CMD_RET_SUCCESS
;
264 static int do_value(struct cmd_tbl
*cmdtp
, int flag
, int argc
,
268 struct dm_regulator_uclass_plat
*uc_pdata
;
273 ret
= curr_dev_and_plat(&dev
, &uc_pdata
, argc
== 1);
278 ret
= regulator_get_value(dev
);
280 printf("Regulator: %s - can't get the Voltage!\n",
285 printf("%d uV\n", ret
);
286 return CMD_RET_SUCCESS
;
290 force
= !strcmp("-f", argv
[2]);
294 value
= simple_strtoul(argv
[1], NULL
, 0);
295 if ((value
< uc_pdata
->min_uV
|| value
> uc_pdata
->max_uV
) && !force
) {
296 printf("Value exceeds regulator constraint limits %d..%d uV\n",
297 uc_pdata
->min_uV
, uc_pdata
->max_uV
);
298 return CMD_RET_FAILURE
;
302 ret
= regulator_set_value(dev
, value
);
304 ret
= regulator_set_value_force(dev
, value
);
306 printf("Regulator: %s - can't set the Voltage!\n",
311 return CMD_RET_SUCCESS
;
314 static int do_current(struct cmd_tbl
*cmdtp
, int flag
, int argc
,
318 struct dm_regulator_uclass_plat
*uc_pdata
;
322 ret
= curr_dev_and_plat(&dev
, &uc_pdata
, argc
== 1);
327 ret
= regulator_get_current(dev
);
329 printf("Regulator: %s - can't get the Current!\n",
334 printf("%d uA\n", ret
);
335 return CMD_RET_SUCCESS
;
338 current
= simple_strtoul(argv
[1], NULL
, 0);
339 if (current
< uc_pdata
->min_uA
|| current
> uc_pdata
->max_uA
) {
340 printf("Current exceeds regulator constraint limits\n");
341 return CMD_RET_FAILURE
;
344 ret
= regulator_set_current(dev
, current
);
346 printf("Regulator: %s - can't set the Current!\n",
351 return CMD_RET_SUCCESS
;
354 static int do_mode(struct cmd_tbl
*cmdtp
, int flag
, int argc
,
358 struct dm_regulator_uclass_plat
*uc_pdata
;
362 ret
= curr_dev_and_plat(&dev
, &uc_pdata
, false);
367 ret
= regulator_get_mode(dev
);
369 printf("Regulator: %s - can't get the operation mode!\n",
374 printf("mode id: %d\n", ret
);
375 return CMD_RET_SUCCESS
;
378 mode
= simple_strtoul(argv
[1], NULL
, 0);
380 ret
= regulator_set_mode(dev
, mode
);
382 printf("Regulator: %s - can't set the operation mode!\n",
387 return CMD_RET_SUCCESS
;
390 static int do_enable(struct cmd_tbl
*cmdtp
, int flag
, int argc
,
394 struct dm_regulator_uclass_plat
*uc_pdata
;
397 ret
= curr_dev_and_plat(&dev
, &uc_pdata
, true);
401 ret
= regulator_set_enable(dev
, true);
403 printf("Regulator: %s - can't enable!\n", uc_pdata
->name
);
407 return CMD_RET_SUCCESS
;
410 static int do_disable(struct cmd_tbl
*cmdtp
, int flag
, int argc
,
414 struct dm_regulator_uclass_plat
*uc_pdata
;
417 ret
= curr_dev_and_plat(&dev
, &uc_pdata
, true);
421 ret
= regulator_set_enable(dev
, false);
423 printf("Regulator: %s - can't disable!\n", uc_pdata
->name
);
427 return CMD_RET_SUCCESS
;
430 static struct cmd_tbl subcmd
[] = {
431 U_BOOT_CMD_MKENT(dev
, 2, 1, do_dev
, "", ""),
432 U_BOOT_CMD_MKENT(list
, 1, 1, do_list
, "", ""),
433 U_BOOT_CMD_MKENT(info
, 2, 1, do_info
, "", ""),
434 U_BOOT_CMD_MKENT(status
, 2, 1, do_status
, "", ""),
435 U_BOOT_CMD_MKENT(value
, 3, 1, do_value
, "", ""),
436 U_BOOT_CMD_MKENT(current
, 3, 1, do_current
, "", ""),
437 U_BOOT_CMD_MKENT(mode
, 2, 1, do_mode
, "", ""),
438 U_BOOT_CMD_MKENT(enable
, 1, 1, do_enable
, "", ""),
439 U_BOOT_CMD_MKENT(disable
, 1, 1, do_disable
, "", ""),
442 static int do_regulator(struct cmd_tbl
*cmdtp
, int flag
, int argc
,
450 cmd
= find_cmd_tbl(argv
[0], subcmd
, ARRAY_SIZE(subcmd
));
451 if (cmd
== NULL
|| argc
> cmd
->maxargs
)
452 return CMD_RET_USAGE
;
454 return cmd
->cmd(cmdtp
, flag
, argc
, argv
);
457 U_BOOT_CMD(regulator
, CONFIG_SYS_MAXARGS
, 1, do_regulator
,
459 "list - list UCLASS regulator devices\n"
460 "regulator dev [regulator-name] - show/[set] operating regulator device\n"
461 "regulator info - print constraints info\n"
462 "regulator status [-a] - print operating status [for all]\n"
463 "regulator value [val] [-f] - print/[set] voltage value [uV] (force)\n"
464 "regulator current [val] - print/[set] current value [uA]\n"
465 "regulator mode [id] - print/[set] operating mode id\n"
466 "regulator enable - enable the regulator output\n"
467 "regulator disable - disable the regulator output\n"