]> Git Repo - J-u-boot.git/blob - cmd/regulator.c
bootm: Drop arguments from do_bootm_states()
[J-u-boot.git] / cmd / regulator.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2014-2015 Samsung Electronics
4  * Przemyslaw Marczak <[email protected]>
5  */
6 #include <common.h>
7 #include <command.h>
8 #include <errno.h>
9 #include <dm.h>
10 #include <dm/uclass-internal.h>
11 #include <linux/printk.h>
12 #include <power/regulator.h>
13
14 #define LIMIT_DEVNAME   20
15 #define LIMIT_OFNAME    32
16 #define LIMIT_INFO      18
17
18 static struct udevice *currdev;
19
20 static int failure(int ret)
21 {
22         printf("Error: %d (%s)\n", ret, errno_str(ret));
23
24         return CMD_RET_FAILURE;
25 }
26
27 static int do_dev(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
28 {
29         struct dm_regulator_uclass_plat *uc_pdata;
30         const char *name;
31         int ret = -ENXIO;
32
33         switch (argc) {
34         case 2:
35                 name = argv[1];
36                 ret = regulator_get_by_platname(name, &currdev);
37                 if (ret) {
38                         printf("Can't get the regulator: %s!\n", name);
39                         return failure(ret);
40                 }
41                 fallthrough;
42         case 1:
43                 if (!currdev) {
44                         printf("Regulator device is not set!\n\n");
45                         return CMD_RET_USAGE;
46                 }
47
48                 uc_pdata = dev_get_uclass_plat(currdev);
49                 if (!uc_pdata) {
50                         printf("%s: no regulator platform data!\n", currdev->name);
51                         return failure(ret);
52                 }
53
54                 printf("dev: %s @ %s\n", uc_pdata->name, currdev->name);
55         }
56
57         return CMD_RET_SUCCESS;
58 }
59
60 static int curr_dev_and_plat(struct udevice **devp,
61                              struct dm_regulator_uclass_plat **uc_pdata,
62                              bool allow_type_fixed)
63 {
64         *devp = NULL;
65         *uc_pdata = NULL;
66
67         if (!currdev) {
68                 printf("First, set the regulator device!\n");
69                 return CMD_RET_FAILURE;
70         }
71
72         *devp = currdev;
73
74         *uc_pdata = dev_get_uclass_plat(*devp);
75         if (!*uc_pdata) {
76                 pr_err("Regulator: %s - missing platform data!\n", currdev->name);
77                 return CMD_RET_FAILURE;
78         }
79
80         if (!allow_type_fixed && (*uc_pdata)->type == REGULATOR_TYPE_FIXED) {
81                 printf("Operation not allowed for fixed regulator!\n");
82                 return CMD_RET_FAILURE;
83         }
84
85         return CMD_RET_SUCCESS;
86 }
87
88 static int do_list(struct cmd_tbl *cmdtp, int flag, int argc,
89                    char *const argv[])
90 {
91         struct dm_regulator_uclass_plat *uc_pdata;
92         struct udevice *dev;
93         int ret;
94
95         printf("| %-*.*s| %-*.*s| %s\n",
96                LIMIT_DEVNAME, LIMIT_DEVNAME, "Device",
97                LIMIT_OFNAME, LIMIT_OFNAME, "regulator-name",
98                "Parent");
99
100         for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
101              ret = uclass_find_next_device(&dev)) {
102                 if (ret)
103                         continue;
104
105                 uc_pdata = dev_get_uclass_plat(dev);
106                 printf("| %-*.*s| %-*.*s| %s\n",
107                        LIMIT_DEVNAME, LIMIT_DEVNAME, dev->name,
108                        LIMIT_OFNAME, LIMIT_OFNAME, uc_pdata->name,
109                        dev->parent->name);
110         }
111
112         return ret;
113 }
114
115 static int constraint(const char *name, int val, const char *val_name)
116 {
117         printf("%-*s", LIMIT_INFO, name);
118         if (val < 0) {
119                 printf(" %s (err: %d)\n", errno_str(val), val);
120                 return val;
121         }
122
123         if (val_name)
124                 printf(" %d (%s)\n", val, val_name);
125         else
126                 printf(" %d\n", val);
127
128         return 0;
129 }
130
131 static const char *get_mode_name(struct dm_regulator_mode *mode,
132                                  int mode_count,
133                                  int mode_id)
134 {
135         while (mode_count--) {
136                 if (mode->id == mode_id)
137                         return mode->name;
138                 mode++;
139         }
140
141         return NULL;
142 }
143
144 static int do_info(struct cmd_tbl *cmdtp, int flag, int argc,
145                    char *const argv[])
146 {
147         struct udevice *dev;
148         struct dm_regulator_uclass_plat *uc_pdata;
149         struct dm_regulator_mode *modes;
150         const char *parent_uc;
151         int mode_count;
152         int ret;
153         int i;
154
155         ret = curr_dev_and_plat(&dev, &uc_pdata, true);
156         if (ret)
157                 return ret;
158
159         parent_uc = dev_get_uclass_name(dev->parent);
160
161         printf("%s\n%-*s %s\n%-*s %s\n%-*s %s\n%-*s %s\n%-*s\n",
162                "Regulator info:",
163                LIMIT_INFO, "* regulator-name:", uc_pdata->name,
164                LIMIT_INFO, "* device name:", dev->name,
165                LIMIT_INFO, "* parent name:", dev->parent->name,
166                LIMIT_INFO, "* parent uclass:", parent_uc,
167                LIMIT_INFO, "* constraints:");
168
169         constraint("  - min uV:", uc_pdata->min_uV, NULL);
170         constraint("  - max uV:", uc_pdata->max_uV, NULL);
171         constraint("  - min uA:", uc_pdata->min_uA, NULL);
172         constraint("  - max uA:", uc_pdata->max_uA, NULL);
173         constraint("  - always on:", uc_pdata->always_on,
174                    uc_pdata->always_on ? "true" : "false");
175         constraint("  - boot on:", uc_pdata->boot_on,
176                    uc_pdata->boot_on ? "true" : "false");
177
178         mode_count = regulator_mode(dev, &modes);
179         constraint("* op modes:", mode_count, NULL);
180
181         for (i = 0; i < mode_count; i++, modes++)
182                 constraint("  - mode id:", modes->id, modes->name);
183
184         return CMD_RET_SUCCESS;
185 }
186
187 static void do_status_detail(struct udevice *dev,
188                              struct dm_regulator_uclass_plat *uc_pdata)
189 {
190         int current, value, mode;
191         const char *mode_name;
192         bool enabled;
193
194         printf("Regulator %s status:\n", uc_pdata->name);
195
196         enabled = regulator_get_enable(dev);
197         constraint(" * enable:", enabled, enabled ? "true" : "false");
198
199         value = regulator_get_value(dev);
200         constraint(" * value uV:", value, NULL);
201
202         current = regulator_get_current(dev);
203         constraint(" * current uA:", current, NULL);
204
205         mode = regulator_get_mode(dev);
206         mode_name = get_mode_name(uc_pdata->mode, uc_pdata->mode_count, mode);
207         constraint(" * mode id:", mode, mode_name);
208 }
209
210 static void do_status_line(struct udevice *dev, int status)
211 {
212         struct dm_regulator_uclass_plat *pdata;
213         int current, value, mode;
214         const char *mode_name;
215         bool enabled;
216
217         pdata = dev_get_uclass_plat(dev);
218         enabled = regulator_get_enable(dev);
219         value = regulator_get_value(dev);
220         current = regulator_get_current(dev);
221         mode = regulator_get_mode(dev);
222         mode_name = get_mode_name(pdata->mode, pdata->mode_count, mode);
223         printf("%-20s %-10s ", pdata->name, enabled ? "enabled" : "disabled");
224         if (value >= 0)
225                 printf("%10d ", value);
226         else
227                 printf("%10s ", "-");
228         if (current >= 0)
229                 printf("%10d ", current);
230         else
231                 printf("%10s ", "-");
232         if (mode >= 0)
233                 printf("%-10s", mode_name);
234         else
235                 printf("%-10s", "-");
236         printf(" %i", status);
237         printf("\n");
238 }
239
240 static int do_status(struct cmd_tbl *cmdtp, int flag, int argc,
241                      char *const argv[])
242 {
243         struct dm_regulator_uclass_plat *uc_pdata;
244         struct udevice *dev;
245         int ret;
246
247         if (currdev && (argc < 2 || strcmp(argv[1], "-a"))) {
248                 ret = curr_dev_and_plat(&dev, &uc_pdata, true);
249                 if (ret)
250                         return CMD_RET_FAILURE;
251                 do_status_detail(dev, uc_pdata);
252                 return 0;
253         }
254
255         /* Show all of them in a list, probing them as needed */
256         printf("%-20s %-10s %10s %10s %-10s %s\n", "Name", "Enabled", "uV", "mA",
257                "Mode", "Status");
258         for (ret = uclass_first_device_check(UCLASS_REGULATOR, &dev); dev;
259              ret = uclass_next_device_check(&dev))
260                 do_status_line(dev, ret);
261
262         return CMD_RET_SUCCESS;
263 }
264
265 static int do_value(struct cmd_tbl *cmdtp, int flag, int argc,
266                     char *const argv[])
267 {
268         struct udevice *dev;
269         struct dm_regulator_uclass_plat *uc_pdata;
270         int value;
271         int force;
272         int ret;
273
274         ret = curr_dev_and_plat(&dev, &uc_pdata, argc == 1);
275         if (ret)
276                 return ret;
277
278         if (argc == 1) {
279                 ret = regulator_get_value(dev);
280                 if (ret < 0) {
281                         printf("Regulator: %s - can't get the Voltage!\n",
282                                uc_pdata->name);
283                         return failure(ret);
284                 }
285
286                 printf("%d uV\n", ret);
287                 return CMD_RET_SUCCESS;
288         }
289
290         if (argc == 3)
291                 force = !strcmp("-f", argv[2]);
292         else
293                 force = 0;
294
295         value = simple_strtoul(argv[1], NULL, 0);
296         if ((value < uc_pdata->min_uV || value > uc_pdata->max_uV) && !force) {
297                 printf("Value exceeds regulator constraint limits %d..%d uV\n",
298                        uc_pdata->min_uV, uc_pdata->max_uV);
299                 return CMD_RET_FAILURE;
300         }
301
302         if (!force)
303                 ret = regulator_set_value(dev, value);
304         else
305                 ret = regulator_set_value_force(dev, value);
306         if (ret) {
307                 printf("Regulator: %s - can't set the Voltage!\n",
308                        uc_pdata->name);
309                 return failure(ret);
310         }
311
312         return CMD_RET_SUCCESS;
313 }
314
315 static int do_current(struct cmd_tbl *cmdtp, int flag, int argc,
316                       char *const argv[])
317 {
318         struct udevice *dev;
319         struct dm_regulator_uclass_plat *uc_pdata;
320         int current;
321         int ret;
322
323         ret = curr_dev_and_plat(&dev, &uc_pdata, argc == 1);
324         if (ret)
325                 return ret;
326
327         if (argc == 1) {
328                 ret = regulator_get_current(dev);
329                 if (ret < 0) {
330                         printf("Regulator: %s - can't get the Current!\n",
331                                uc_pdata->name);
332                         return failure(ret);
333                 }
334
335                 printf("%d uA\n", ret);
336                 return CMD_RET_SUCCESS;
337         }
338
339         current = simple_strtoul(argv[1], NULL, 0);
340         if (current < uc_pdata->min_uA || current > uc_pdata->max_uA) {
341                 printf("Current exceeds regulator constraint limits\n");
342                 return CMD_RET_FAILURE;
343         }
344
345         ret = regulator_set_current(dev, current);
346         if (ret) {
347                 printf("Regulator: %s - can't set the Current!\n",
348                        uc_pdata->name);
349                 return failure(ret);
350         }
351
352         return CMD_RET_SUCCESS;
353 }
354
355 static int do_mode(struct cmd_tbl *cmdtp, int flag, int argc,
356                    char *const argv[])
357 {
358         struct udevice *dev;
359         struct dm_regulator_uclass_plat *uc_pdata;
360         int mode;
361         int ret;
362
363         ret = curr_dev_and_plat(&dev, &uc_pdata, false);
364         if (ret)
365                 return ret;
366
367         if (argc == 1) {
368                 ret = regulator_get_mode(dev);
369                 if (ret < 0) {
370                         printf("Regulator: %s - can't get the operation mode!\n",
371                                uc_pdata->name);
372                         return failure(ret);
373                 }
374
375                 printf("mode id: %d\n", ret);
376                 return CMD_RET_SUCCESS;
377         }
378
379         mode = simple_strtoul(argv[1], NULL, 0);
380
381         ret = regulator_set_mode(dev, mode);
382         if (ret) {
383                 printf("Regulator: %s - can't set the operation mode!\n",
384                        uc_pdata->name);
385                 return failure(ret);
386         }
387
388         return CMD_RET_SUCCESS;
389 }
390
391 static int do_enable(struct cmd_tbl *cmdtp, int flag, int argc,
392                      char *const argv[])
393 {
394         struct udevice *dev;
395         struct dm_regulator_uclass_plat *uc_pdata;
396         int ret;
397
398         ret = curr_dev_and_plat(&dev, &uc_pdata, true);
399         if (ret)
400                 return ret;
401
402         ret = regulator_set_enable(dev, true);
403         if (ret) {
404                 printf("Regulator: %s - can't enable!\n", uc_pdata->name);
405                 return failure(ret);
406         }
407
408         return CMD_RET_SUCCESS;
409 }
410
411 static int do_disable(struct cmd_tbl *cmdtp, int flag, int argc,
412                       char *const argv[])
413 {
414         struct udevice *dev;
415         struct dm_regulator_uclass_plat *uc_pdata;
416         int ret;
417
418         ret = curr_dev_and_plat(&dev, &uc_pdata, true);
419         if (ret)
420                 return ret;
421
422         ret = regulator_set_enable(dev, false);
423         if (ret) {
424                 printf("Regulator: %s - can't disable!\n", uc_pdata->name);
425                 return failure(ret);
426         }
427
428         return CMD_RET_SUCCESS;
429 }
430
431 static struct cmd_tbl subcmd[] = {
432         U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""),
433         U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""),
434         U_BOOT_CMD_MKENT(info, 2, 1, do_info, "", ""),
435         U_BOOT_CMD_MKENT(status, 2, 1, do_status, "", ""),
436         U_BOOT_CMD_MKENT(value, 3, 1, do_value, "", ""),
437         U_BOOT_CMD_MKENT(current, 3, 1, do_current, "", ""),
438         U_BOOT_CMD_MKENT(mode, 2, 1, do_mode, "", ""),
439         U_BOOT_CMD_MKENT(enable, 1, 1, do_enable, "", ""),
440         U_BOOT_CMD_MKENT(disable, 1, 1, do_disable, "", ""),
441 };
442
443 static int do_regulator(struct cmd_tbl *cmdtp, int flag, int argc,
444                         char *const argv[])
445 {
446         struct cmd_tbl *cmd;
447
448         argc--;
449         argv++;
450
451         cmd = find_cmd_tbl(argv[0], subcmd, ARRAY_SIZE(subcmd));
452         if (cmd == NULL || argc > cmd->maxargs)
453                 return CMD_RET_USAGE;
454
455         return cmd->cmd(cmdtp, flag, argc, argv);
456 }
457
458 U_BOOT_CMD(regulator, CONFIG_SYS_MAXARGS, 1, do_regulator,
459         "uclass operations",
460         "list             - list UCLASS regulator devices\n"
461         "regulator dev [regulator-name] - show/[set] operating regulator device\n"
462         "regulator info                 - print constraints info\n"
463         "regulator status [-a]          - print operating status [for all]\n"
464         "regulator value [val] [-f]     - print/[set] voltage value [uV] (force)\n"
465         "regulator current [val]        - print/[set] current value [uA]\n"
466         "regulator mode [id]            - print/[set] operating mode id\n"
467         "regulator enable               - enable the regulator output\n"
468         "regulator disable              - disable the regulator output\n"
469 );
This page took 0.053094 seconds and 4 git commands to generate.