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 <power/regulator.h>
12 #define LIMIT_DEVNAME 20
13 #define LIMIT_OFNAME 32
16 static struct udevice
*currdev
;
18 static int failure(int ret
)
20 printf("Error: %d (%s)\n", ret
, errno_str(ret
));
22 return CMD_RET_FAILURE
;
25 static int do_dev(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
27 struct dm_regulator_uclass_platdata
*uc_pdata
;
34 ret
= regulator_get_by_platname(name
, &currdev
);
36 printf("Can't get the regulator: %s!\n", name
);
41 printf("Regulator device is not set!\n\n");
45 uc_pdata
= dev_get_uclass_platdata(currdev
);
47 printf("%s: no regulator platform data!\n", currdev
->name
);
51 printf("dev: %s @ %s\n", uc_pdata
->name
, currdev
->name
);
54 return CMD_RET_SUCCESS
;
57 static int curr_dev_and_platdata(struct udevice
**devp
,
58 struct dm_regulator_uclass_platdata
**uc_pdata
,
59 bool allow_type_fixed
)
65 printf("First, set the regulator device!\n");
66 return CMD_RET_FAILURE
;
71 *uc_pdata
= dev_get_uclass_platdata(*devp
);
73 pr_err("Regulator: %s - missing platform data!\n", currdev
->name
);
74 return CMD_RET_FAILURE
;
77 if (!allow_type_fixed
&& (*uc_pdata
)->type
== REGULATOR_TYPE_FIXED
) {
78 printf("Operation not allowed for fixed regulator!\n");
79 return CMD_RET_FAILURE
;
82 return CMD_RET_SUCCESS
;
85 static int do_list(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
87 struct dm_regulator_uclass_platdata
*uc_pdata
;
91 printf("| %-*.*s| %-*.*s| %s\n",
92 LIMIT_DEVNAME
, LIMIT_DEVNAME
, "Device",
93 LIMIT_OFNAME
, LIMIT_OFNAME
, "regulator-name",
96 for (ret
= uclass_find_first_device(UCLASS_REGULATOR
, &dev
); dev
;
97 ret
= uclass_find_next_device(&dev
)) {
101 uc_pdata
= dev_get_uclass_platdata(dev
);
102 printf("| %-*.*s| %-*.*s| %s\n",
103 LIMIT_DEVNAME
, LIMIT_DEVNAME
, dev
->name
,
104 LIMIT_OFNAME
, LIMIT_OFNAME
, uc_pdata
->name
,
111 static int constraint(const char *name
, int val
, const char *val_name
)
113 printf("%-*s", LIMIT_INFO
, name
);
115 printf(" %s (err: %d)\n", errno_str(val
), val
);
120 printf(" %d (%s)\n", val
, val_name
);
122 printf(" %d\n", val
);
127 static const char *get_mode_name(struct dm_regulator_mode
*mode
,
131 while (mode_count
--) {
132 if (mode
->id
== mode_id
)
140 static int do_info(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
143 struct dm_regulator_uclass_platdata
*uc_pdata
;
144 struct dm_regulator_mode
*modes
;
145 const char *parent_uc
;
150 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, true);
154 parent_uc
= dev_get_uclass_name(dev
->parent
);
156 printf("%s\n%-*s %s\n%-*s %s\n%-*s %s\n%-*s %s\n%-*s\n",
158 LIMIT_INFO
, "* regulator-name:", uc_pdata
->name
,
159 LIMIT_INFO
, "* device name:", dev
->name
,
160 LIMIT_INFO
, "* parent name:", dev
->parent
->name
,
161 LIMIT_INFO
, "* parent uclass:", parent_uc
,
162 LIMIT_INFO
, "* constraints:");
164 constraint(" - min uV:", uc_pdata
->min_uV
, NULL
);
165 constraint(" - max uV:", uc_pdata
->max_uV
, NULL
);
166 constraint(" - min uA:", uc_pdata
->min_uA
, NULL
);
167 constraint(" - max uA:", uc_pdata
->max_uA
, NULL
);
168 constraint(" - always on:", uc_pdata
->always_on
,
169 uc_pdata
->always_on
? "true" : "false");
170 constraint(" - boot on:", uc_pdata
->boot_on
,
171 uc_pdata
->boot_on
? "true" : "false");
173 mode_count
= regulator_mode(dev
, &modes
);
174 constraint("* op modes:", mode_count
, NULL
);
176 for (i
= 0; i
< mode_count
; i
++, modes
++)
177 constraint(" - mode id:", modes
->id
, modes
->name
);
179 return CMD_RET_SUCCESS
;
182 static void do_status_detail(struct udevice
*dev
,
183 struct dm_regulator_uclass_platdata
*uc_pdata
)
185 int current
, value
, mode
;
186 const char *mode_name
;
189 printf("Regulator %s status:\n", uc_pdata
->name
);
191 enabled
= regulator_get_enable(dev
);
192 constraint(" * enable:", enabled
, enabled
? "true" : "false");
194 value
= regulator_get_value(dev
);
195 constraint(" * value uV:", value
, NULL
);
197 current
= regulator_get_current(dev
);
198 constraint(" * current uA:", current
, NULL
);
200 mode
= regulator_get_mode(dev
);
201 mode_name
= get_mode_name(uc_pdata
->mode
, uc_pdata
->mode_count
, mode
);
202 constraint(" * mode id:", mode
, mode_name
);
205 static void do_status_line(struct udevice
*dev
)
207 struct dm_regulator_uclass_platdata
*pdata
;
208 int current
, value
, mode
;
209 const char *mode_name
;
212 pdata
= dev_get_uclass_platdata(dev
);
213 enabled
= regulator_get_enable(dev
);
214 value
= regulator_get_value(dev
);
215 current
= regulator_get_current(dev
);
216 mode
= regulator_get_mode(dev
);
217 mode_name
= get_mode_name(pdata
->mode
, pdata
->mode_count
, mode
);
218 printf("%-20s %-10s ", pdata
->name
, enabled
? "enabled" : "disabled");
220 printf("%10d ", value
);
222 printf("%10s ", "-");
224 printf("%10d ", current
);
226 printf("%10s ", "-");
228 printf("%-10s", mode_name
);
230 printf("%-10s", "-");
234 static int do_status(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
236 struct dm_regulator_uclass_platdata
*uc_pdata
;
240 if (currdev
&& (argc
< 2 || strcmp(argv
[1], "-a"))) {
241 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, true);
243 return CMD_RET_FAILURE
;
244 do_status_detail(dev
, uc_pdata
);
248 /* Show all of them in a list, probing them as needed */
249 printf("%-20s %-10s %10s %10s %-10s\n", "Name", "Enabled", "uV", "mA",
251 for (ret
= uclass_first_device(UCLASS_REGULATOR
, &dev
); dev
;
252 ret
= uclass_next_device(&dev
))
255 return CMD_RET_SUCCESS
;
258 static int do_value(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
261 struct dm_regulator_uclass_platdata
*uc_pdata
;
266 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, argc
== 1);
271 ret
= regulator_get_value(dev
);
273 printf("Regulator: %s - can't get the Voltage!\n",
278 printf("%d uV\n", ret
);
279 return CMD_RET_SUCCESS
;
283 force
= !strcmp("-f", argv
[2]);
287 value
= simple_strtoul(argv
[1], NULL
, 0);
288 if ((value
< uc_pdata
->min_uV
|| value
> uc_pdata
->max_uV
) && !force
) {
289 printf("Value exceeds regulator constraint limits %d..%d uV\n",
290 uc_pdata
->min_uV
, uc_pdata
->max_uV
);
291 return CMD_RET_FAILURE
;
295 ret
= regulator_set_value(dev
, value
);
297 ret
= regulator_set_value_force(dev
, value
);
299 printf("Regulator: %s - can't set the Voltage!\n",
304 return CMD_RET_SUCCESS
;
307 static int do_current(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
310 struct dm_regulator_uclass_platdata
*uc_pdata
;
314 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, argc
== 1);
319 ret
= regulator_get_current(dev
);
321 printf("Regulator: %s - can't get the Current!\n",
326 printf("%d uA\n", ret
);
327 return CMD_RET_SUCCESS
;
330 current
= simple_strtoul(argv
[1], NULL
, 0);
331 if (current
< uc_pdata
->min_uA
|| current
> uc_pdata
->max_uA
) {
332 printf("Current exceeds regulator constraint limits\n");
333 return CMD_RET_FAILURE
;
336 ret
= regulator_set_current(dev
, current
);
338 printf("Regulator: %s - can't set the Current!\n",
343 return CMD_RET_SUCCESS
;
346 static int do_mode(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
349 struct dm_regulator_uclass_platdata
*uc_pdata
;
353 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, false);
358 ret
= regulator_get_mode(dev
);
360 printf("Regulator: %s - can't get the operation mode!\n",
365 printf("mode id: %d\n", ret
);
366 return CMD_RET_SUCCESS
;
369 mode
= simple_strtoul(argv
[1], NULL
, 0);
371 ret
= regulator_set_mode(dev
, mode
);
373 printf("Regulator: %s - can't set the operation mode!\n",
378 return CMD_RET_SUCCESS
;
381 static int do_enable(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
384 struct dm_regulator_uclass_platdata
*uc_pdata
;
387 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, true);
391 ret
= regulator_set_enable(dev
, true);
393 printf("Regulator: %s - can't enable!\n", uc_pdata
->name
);
397 return CMD_RET_SUCCESS
;
400 static int do_disable(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
403 struct dm_regulator_uclass_platdata
*uc_pdata
;
406 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, true);
410 ret
= regulator_set_enable(dev
, false);
412 printf("Regulator: %s - can't disable!\n", uc_pdata
->name
);
416 return CMD_RET_SUCCESS
;
419 static cmd_tbl_t subcmd
[] = {
420 U_BOOT_CMD_MKENT(dev
, 2, 1, do_dev
, "", ""),
421 U_BOOT_CMD_MKENT(list
, 1, 1, do_list
, "", ""),
422 U_BOOT_CMD_MKENT(info
, 2, 1, do_info
, "", ""),
423 U_BOOT_CMD_MKENT(status
, 2, 1, do_status
, "", ""),
424 U_BOOT_CMD_MKENT(value
, 3, 1, do_value
, "", ""),
425 U_BOOT_CMD_MKENT(current
, 3, 1, do_current
, "", ""),
426 U_BOOT_CMD_MKENT(mode
, 2, 1, do_mode
, "", ""),
427 U_BOOT_CMD_MKENT(enable
, 1, 1, do_enable
, "", ""),
428 U_BOOT_CMD_MKENT(disable
, 1, 1, do_disable
, "", ""),
431 static int do_regulator(cmd_tbl_t
*cmdtp
, int flag
, int argc
,
439 cmd
= find_cmd_tbl(argv
[0], subcmd
, ARRAY_SIZE(subcmd
));
440 if (cmd
== NULL
|| argc
> cmd
->maxargs
)
441 return CMD_RET_USAGE
;
443 return cmd
->cmd(cmdtp
, flag
, argc
, argv
);
446 U_BOOT_CMD(regulator
, CONFIG_SYS_MAXARGS
, 1, do_regulator
,
448 "list - list UCLASS regulator devices\n"
449 "regulator dev [regulator-name] - show/[set] operating regulator device\n"
450 "regulator info - print constraints info\n"
451 "regulator status [-a] - print operating status [for all]\n"
452 "regulator value [val] [-f] - print/[set] voltage value [uV] (force)\n"
453 "regulator current [val] - print/[set] current value [uA]\n"
454 "regulator mode [id] - print/[set] operating mode id\n"
455 "regulator enable - enable the regulator output\n"
456 "regulator disable - disable the regulator output\n"