2 * Copyright (C) 2014-2015 Samsung Electronics
3 * Przemyslaw Marczak <p.marczak@samsung.com>
5 * SPDX-License-Identifier: GPL-2.0+
10 #include <dm/uclass-internal.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(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
28 struct dm_regulator_uclass_platdata
*uc_pdata
;
35 ret
= regulator_get_by_platname(name
, &currdev
);
37 printf("Can't get the regulator: %s!\n", name
);
42 printf("Regulator device is not set!\n\n");
46 uc_pdata
= dev_get_uclass_platdata(currdev
);
48 printf("%s: no regulator platform data!\n", currdev
->name
);
52 printf("dev: %s @ %s\n", uc_pdata
->name
, currdev
->name
);
55 return CMD_RET_SUCCESS
;
58 static int curr_dev_and_platdata(struct udevice
**devp
,
59 struct dm_regulator_uclass_platdata
**uc_pdata
,
60 bool allow_type_fixed
)
66 printf("First, set the regulator device!\n");
67 return CMD_RET_FAILURE
;
72 *uc_pdata
= dev_get_uclass_platdata(*devp
);
74 error("Regulator: %s - missing platform data!", currdev
->name
);
75 return CMD_RET_FAILURE
;
78 if (!allow_type_fixed
&& (*uc_pdata
)->type
== REGULATOR_TYPE_FIXED
) {
79 printf("Operation not allowed for fixed regulator!\n");
80 return CMD_RET_FAILURE
;
83 return CMD_RET_SUCCESS
;
86 static int do_list(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
88 struct dm_regulator_uclass_platdata
*uc_pdata
;
92 printf("| %-*.*s| %-*.*s| %s\n",
93 LIMIT_DEVNAME
, LIMIT_DEVNAME
, "Device",
94 LIMIT_OFNAME
, LIMIT_OFNAME
, "regulator-name",
97 for (ret
= uclass_find_first_device(UCLASS_REGULATOR
, &dev
); dev
;
98 ret
= uclass_find_next_device(&dev
)) {
102 uc_pdata
= dev_get_uclass_platdata(dev
);
103 printf("| %-*.*s| %-*.*s| %s\n",
104 LIMIT_DEVNAME
, LIMIT_DEVNAME
, dev
->name
,
105 LIMIT_OFNAME
, LIMIT_OFNAME
, uc_pdata
->name
,
112 static int constraint(const char *name
, int val
, const char *val_name
)
114 printf("%-*s", LIMIT_INFO
, name
);
116 printf(" %s (err: %d)\n", errno_str(val
), val
);
121 printf(" %d (%s)\n", val
, val_name
);
123 printf(" %d\n", val
);
128 static const char *get_mode_name(struct dm_regulator_mode
*mode
,
132 while (mode_count
--) {
133 if (mode
->id
== mode_id
)
141 static int do_info(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
144 struct dm_regulator_uclass_platdata
*uc_pdata
;
145 struct dm_regulator_mode
*modes
;
146 const char *parent_uc
;
151 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, true);
155 parent_uc
= dev_get_uclass_name(dev
->parent
);
157 printf("%s\n%-*s %s\n%-*s %s\n%-*s %s\n%-*s %s\n%-*s\n",
159 LIMIT_INFO
, "* regulator-name:", uc_pdata
->name
,
160 LIMIT_INFO
, "* device name:", dev
->name
,
161 LIMIT_INFO
, "* parent name:", dev
->parent
->name
,
162 LIMIT_INFO
, "* parent uclass:", parent_uc
,
163 LIMIT_INFO
, "* constraints:");
165 constraint(" - min uV:", uc_pdata
->min_uV
, NULL
);
166 constraint(" - max uV:", uc_pdata
->max_uV
, NULL
);
167 constraint(" - min uA:", uc_pdata
->min_uA
, NULL
);
168 constraint(" - max uA:", uc_pdata
->max_uA
, NULL
);
169 constraint(" - always on:", uc_pdata
->always_on
,
170 uc_pdata
->always_on
? "true" : "false");
171 constraint(" - boot on:", uc_pdata
->boot_on
,
172 uc_pdata
->boot_on
? "true" : "false");
174 mode_count
= regulator_mode(dev
, &modes
);
175 constraint("* op modes:", mode_count
, NULL
);
177 for (i
= 0; i
< mode_count
; i
++, modes
++)
178 constraint(" - mode id:", modes
->id
, modes
->name
);
180 return CMD_RET_SUCCESS
;
183 static void do_status_detail(struct udevice
*dev
,
184 struct dm_regulator_uclass_platdata
*uc_pdata
)
186 int current
, value
, mode
;
187 const char *mode_name
;
190 printf("Regulator %s status:\n", uc_pdata
->name
);
192 enabled
= regulator_get_enable(dev
);
193 constraint(" * enable:", enabled
, enabled
? "true" : "false");
195 value
= regulator_get_value(dev
);
196 constraint(" * value uV:", value
, NULL
);
198 current
= regulator_get_current(dev
);
199 constraint(" * current uA:", current
, NULL
);
201 mode
= regulator_get_mode(dev
);
202 mode_name
= get_mode_name(uc_pdata
->mode
, uc_pdata
->mode_count
, mode
);
203 constraint(" * mode id:", mode
, mode_name
);
206 static void do_status_line(struct udevice
*dev
)
208 struct dm_regulator_uclass_platdata
*pdata
;
209 int current
, value
, mode
;
210 const char *mode_name
;
213 pdata
= dev_get_uclass_platdata(dev
);
214 enabled
= regulator_get_enable(dev
);
215 value
= regulator_get_value(dev
);
216 current
= regulator_get_current(dev
);
217 mode
= regulator_get_mode(dev
);
218 mode_name
= get_mode_name(pdata
->mode
, pdata
->mode_count
, mode
);
219 printf("%-20s %-10s ", pdata
->name
, enabled
? "enabled" : "disabled");
221 printf("%10d ", value
);
223 printf("%10s ", "-");
225 printf("%10d ", current
);
227 printf("%10s ", "-");
229 printf("%-10s", mode_name
);
231 printf("%-10s", "-");
235 static int do_status(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
237 struct dm_regulator_uclass_platdata
*uc_pdata
;
241 if (currdev
&& (argc
< 2 || strcmp(argv
[1], "-a"))) {
242 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, true);
244 return CMD_RET_FAILURE
;
245 do_status_detail(dev
, uc_pdata
);
249 /* Show all of them in a list, probing them as needed */
250 printf("%-20s %-10s %10s %10s %-10s\n", "Name", "Enabled", "uV", "mA",
252 for (ret
= uclass_first_device(UCLASS_REGULATOR
, &dev
); dev
;
253 ret
= uclass_next_device(&dev
))
256 return CMD_RET_SUCCESS
;
259 static int do_value(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
262 struct dm_regulator_uclass_platdata
*uc_pdata
;
267 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, argc
== 1);
272 ret
= regulator_get_value(dev
);
274 printf("Regulator: %s - can't get the Voltage!\n",
279 printf("%d uV\n", ret
);
280 return CMD_RET_SUCCESS
;
284 force
= !strcmp("-f", argv
[2]);
288 value
= simple_strtoul(argv
[1], NULL
, 0);
289 if ((value
< uc_pdata
->min_uV
|| value
> uc_pdata
->max_uV
) && !force
) {
290 printf("Value exceeds regulator constraint limits %d..%d uV\n",
291 uc_pdata
->min_uV
, uc_pdata
->max_uV
);
292 return CMD_RET_FAILURE
;
295 ret
= regulator_set_value(dev
, value
);
297 printf("Regulator: %s - can't set the Voltage!\n",
302 return CMD_RET_SUCCESS
;
305 static int do_current(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
308 struct dm_regulator_uclass_platdata
*uc_pdata
;
312 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, argc
== 1);
317 ret
= regulator_get_current(dev
);
319 printf("Regulator: %s - can't get the Current!\n",
324 printf("%d uA\n", ret
);
325 return CMD_RET_SUCCESS
;
328 current
= simple_strtoul(argv
[1], NULL
, 0);
329 if (current
< uc_pdata
->min_uA
|| current
> uc_pdata
->max_uA
) {
330 printf("Current exceeds regulator constraint limits\n");
331 return CMD_RET_FAILURE
;
334 ret
= regulator_set_current(dev
, current
);
336 printf("Regulator: %s - can't set the Current!\n",
341 return CMD_RET_SUCCESS
;
344 static int do_mode(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
347 struct dm_regulator_uclass_platdata
*uc_pdata
;
351 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, false);
356 ret
= regulator_get_mode(dev
);
358 printf("Regulator: %s - can't get the operation mode!\n",
363 printf("mode id: %d\n", ret
);
364 return CMD_RET_SUCCESS
;
367 mode
= simple_strtoul(argv
[1], NULL
, 0);
369 ret
= regulator_set_mode(dev
, mode
);
371 printf("Regulator: %s - can't set the operation mode!\n",
376 return CMD_RET_SUCCESS
;
379 static int do_enable(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
382 struct dm_regulator_uclass_platdata
*uc_pdata
;
385 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, true);
389 ret
= regulator_set_enable(dev
, true);
391 printf("Regulator: %s - can't enable!\n", uc_pdata
->name
);
395 return CMD_RET_SUCCESS
;
398 static int do_disable(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
401 struct dm_regulator_uclass_platdata
*uc_pdata
;
404 ret
= curr_dev_and_platdata(&dev
, &uc_pdata
, true);
408 ret
= regulator_set_enable(dev
, false);
410 printf("Regulator: %s - can't disable!\n", uc_pdata
->name
);
414 return CMD_RET_SUCCESS
;
417 static cmd_tbl_t subcmd
[] = {
418 U_BOOT_CMD_MKENT(dev
, 2, 1, do_dev
, "", ""),
419 U_BOOT_CMD_MKENT(list
, 1, 1, do_list
, "", ""),
420 U_BOOT_CMD_MKENT(info
, 2, 1, do_info
, "", ""),
421 U_BOOT_CMD_MKENT(status
, 2, 1, do_status
, "", ""),
422 U_BOOT_CMD_MKENT(value
, 3, 1, do_value
, "", ""),
423 U_BOOT_CMD_MKENT(current
, 3, 1, do_current
, "", ""),
424 U_BOOT_CMD_MKENT(mode
, 2, 1, do_mode
, "", ""),
425 U_BOOT_CMD_MKENT(enable
, 1, 1, do_enable
, "", ""),
426 U_BOOT_CMD_MKENT(disable
, 1, 1, do_disable
, "", ""),
429 static int do_regulator(cmd_tbl_t
*cmdtp
, int flag
, int argc
,
437 cmd
= find_cmd_tbl(argv
[0], subcmd
, ARRAY_SIZE(subcmd
));
438 if (cmd
== NULL
|| argc
> cmd
->maxargs
)
439 return CMD_RET_USAGE
;
441 return cmd
->cmd(cmdtp
, flag
, argc
, argv
);
444 U_BOOT_CMD(regulator
, CONFIG_SYS_MAXARGS
, 1, do_regulator
,
446 "list - list UCLASS regulator devices\n"
447 "regulator dev [regulator-name] - show/[set] operating regulator device\n"
448 "regulator info - print constraints info\n"
449 "regulator status [-a] - print operating status [for all]\n"
450 "regulator value [val] [-f] - print/[set] voltage value [uV] (force)\n"
451 "regulator current [val] - print/[set] current value [uA]\n"
452 "regulator mode [id] - print/[set] operating mode id\n"
453 "regulator enable - enable the regulator output\n"
454 "regulator disable - disable the regulator output\n"