Newer
Older
/*
* Copyright (C) 2014-2015 Samsung Electronics
* Przemyslaw Marczak <p.marczak@samsung.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <errno.h>
#include <dm.h>
#include <dm/uclass-internal.h>
#include <power/regulator.h>
#define LIMIT_DEVNAME 20
#define LIMIT_OFNAME 32
#define LIMIT_INFO 18
static struct udevice *currdev;
printf("Error: %d (%s)\n", ret, errno_str(ret));
}
static int do_dev(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct dm_regulator_uclass_platdata *uc_pdata;
const char *name;
int ret = -ENXIO;
name = argv[1];
ret = regulator_get_by_platname(name, &currdev);
if (ret) {
printf("Can't get the regulator: %s!\n", name);
return failure(ret);
}
if (!currdev) {
printf("Regulator device is not set!\n\n");
return CMD_RET_USAGE;
}
uc_pdata = dev_get_uclass_platdata(currdev);
if (!uc_pdata) {
printf("%s: no regulator platform data!\n", currdev->name);
return failure(ret);
}
printf("dev: %s @ %s\n", uc_pdata->name, currdev->name);
}
return CMD_RET_SUCCESS;
}
static int curr_dev_and_platdata(struct udevice **devp,
struct dm_regulator_uclass_platdata **uc_pdata,
bool allow_type_fixed)
{
*devp = NULL;
*uc_pdata = NULL;
if (!currdev) {
printf("First, set the regulator device!\n");
return CMD_RET_FAILURE;
}
*devp = currdev;
*uc_pdata = dev_get_uclass_platdata(*devp);
if (!*uc_pdata) {
error("Regulator: %s - missing platform data!", currdev->name);
return CMD_RET_FAILURE;
}
if (!allow_type_fixed && (*uc_pdata)->type == REGULATOR_TYPE_FIXED) {
printf("Operation not allowed for fixed regulator!\n");
return CMD_RET_FAILURE;
}
return CMD_RET_SUCCESS;
}
static int do_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct dm_regulator_uclass_platdata *uc_pdata;
struct udevice *dev;
printf("| %-*.*s| %-*.*s| %s\n",
LIMIT_DEVNAME, LIMIT_DEVNAME, "Device",
LIMIT_OFNAME, LIMIT_OFNAME, "regulator-name",
"Parent");
for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
ret = uclass_find_next_device(&dev)) {
if (ret)
continue;
uc_pdata = dev_get_uclass_platdata(dev);
printf("| %-*.*s| %-*.*s| %s\n",
LIMIT_DEVNAME, LIMIT_DEVNAME, dev->name,
LIMIT_OFNAME, LIMIT_OFNAME, uc_pdata->name,
dev->parent->name);
}
return ret;
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
}
static int constraint(const char *name, int val, const char *val_name)
{
printf("%-*s", LIMIT_INFO, name);
if (val < 0) {
printf(" %s (err: %d)\n", errno_str(val), val);
return val;
}
if (val_name)
printf(" %d (%s)\n", val, val_name);
else
printf(" %d\n", val);
return 0;
}
static const char *get_mode_name(struct dm_regulator_mode *mode,
int mode_count,
int mode_id)
{
while (mode_count--) {
if (mode->id == mode_id)
return mode->name;
mode++;
}
return NULL;
}
static int do_info(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct udevice *dev;
struct dm_regulator_uclass_platdata *uc_pdata;
struct dm_regulator_mode *modes;
const char *parent_uc;
int mode_count;
int ret;
int i;
ret = curr_dev_and_platdata(&dev, &uc_pdata, true);
if (ret)
return ret;
parent_uc = dev_get_uclass_name(dev->parent);
printf("%s\n%-*s %s\n%-*s %s\n%-*s %s\n%-*s %s\n%-*s\n",
"Regulator info:",
LIMIT_INFO, "* regulator-name:", uc_pdata->name,
LIMIT_INFO, "* device name:", dev->name,
LIMIT_INFO, "* parent name:", dev->parent->name,
LIMIT_INFO, "* parent uclass:", parent_uc,
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
LIMIT_INFO, "* constraints:");
constraint(" - min uV:", uc_pdata->min_uV, NULL);
constraint(" - max uV:", uc_pdata->max_uV, NULL);
constraint(" - min uA:", uc_pdata->min_uA, NULL);
constraint(" - max uA:", uc_pdata->max_uA, NULL);
constraint(" - always on:", uc_pdata->always_on,
uc_pdata->always_on ? "true" : "false");
constraint(" - boot on:", uc_pdata->boot_on,
uc_pdata->boot_on ? "true" : "false");
mode_count = regulator_mode(dev, &modes);
constraint("* op modes:", mode_count, NULL);
for (i = 0; i < mode_count; i++, modes++)
constraint(" - mode id:", modes->id, modes->name);
return CMD_RET_SUCCESS;
}
static int do_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct dm_regulator_uclass_platdata *uc_pdata;
int current, value, mode, ret;
const char *mode_name = NULL;
struct udevice *dev;
bool enabled;
ret = curr_dev_and_platdata(&dev, &uc_pdata, true);
printf("Regulator %s status:\n", uc_pdata->name);
enabled = regulator_get_enable(dev);
constraint(" * enable:", enabled, enabled ? "true" : "false");
value = regulator_get_value(dev);
constraint(" * value uV:", value, NULL);
current = regulator_get_current(dev);
constraint(" * current uA:", current, NULL);
mode = regulator_get_mode(dev);
mode_name = get_mode_name(uc_pdata->mode, uc_pdata->mode_count, mode);
constraint(" * mode id:", mode, mode_name);
return CMD_RET_SUCCESS;
}
static int do_value(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct udevice *dev;
struct dm_regulator_uclass_platdata *uc_pdata;
int value;
int force;
int ret;
ret = curr_dev_and_platdata(&dev, &uc_pdata, argc == 1);
if (ret)
return ret;
if (argc == 1) {
ret = regulator_get_value(dev);
if (ret < 0) {
printf("Regulator: %s - can't get the Voltage!\n",
uc_pdata->name);
return failure(ret);
}
return CMD_RET_SUCCESS;
}
if (argc == 3)
force = !strcmp("-f", argv[2]);
else
force = 0;
value = simple_strtoul(argv[1], NULL, 0);
if ((value < uc_pdata->min_uV || value > uc_pdata->max_uV) && !force) {
printf("Value exceeds regulator constraint limits\n");
return CMD_RET_FAILURE;
}
ret = regulator_set_value(dev, value);
if (ret) {
printf("Regulator: %s - can't set the Voltage!\n",
uc_pdata->name);
return failure(ret);
}
return CMD_RET_SUCCESS;
}
static int do_current(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct udevice *dev;
struct dm_regulator_uclass_platdata *uc_pdata;
int current;
int ret;
ret = curr_dev_and_platdata(&dev, &uc_pdata, argc == 1);
if (ret)
return ret;
if (argc == 1) {
ret = regulator_get_current(dev);
if (ret < 0) {
printf("Regulator: %s - can't get the Current!\n",
uc_pdata->name);
return failure(ret);
}
return CMD_RET_SUCCESS;
}
current = simple_strtoul(argv[1], NULL, 0);
if (current < uc_pdata->min_uA || current > uc_pdata->max_uA) {
printf("Current exceeds regulator constraint limits\n");
return CMD_RET_FAILURE;
}
ret = regulator_set_current(dev, current);
if (ret) {
printf("Regulator: %s - can't set the Current!\n",
uc_pdata->name);
return failure(ret);
}
return CMD_RET_SUCCESS;
}
static int do_mode(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct udevice *dev;
struct dm_regulator_uclass_platdata *uc_pdata;
int mode;
int ret;
ret = curr_dev_and_platdata(&dev, &uc_pdata, false);
if (ret)
return ret;
if (argc == 1) {
ret = regulator_get_mode(dev);
if (ret < 0) {
printf("Regulator: %s - can't get the operation mode!\n",
uc_pdata->name);
return failure(ret);
}
printf("mode id: %d\n", ret);
return CMD_RET_SUCCESS;
}
mode = simple_strtoul(argv[1], NULL, 0);
ret = regulator_set_mode(dev, mode);
if (ret) {
printf("Regulator: %s - can't set the operation mode!\n",
uc_pdata->name);
return failure(ret);
}
return CMD_RET_SUCCESS;
}
static int do_enable(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct udevice *dev;
struct dm_regulator_uclass_platdata *uc_pdata;
int ret;
ret = curr_dev_and_platdata(&dev, &uc_pdata, true);
if (ret)
return ret;
ret = regulator_set_enable(dev, true);
if (ret) {
printf("Regulator: %s - can't enable!\n", uc_pdata->name);
return failure(ret);
}
return CMD_RET_SUCCESS;
}
static int do_disable(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct udevice *dev;
struct dm_regulator_uclass_platdata *uc_pdata;
int ret;
ret = curr_dev_and_platdata(&dev, &uc_pdata, true);
if (ret)
return ret;
ret = regulator_set_enable(dev, false);
if (ret) {
printf("Regulator: %s - can't disable!\n", uc_pdata->name);
return failure(ret);
}
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
return CMD_RET_SUCCESS;
}
static cmd_tbl_t subcmd[] = {
U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""),
U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""),
U_BOOT_CMD_MKENT(info, 2, 1, do_info, "", ""),
U_BOOT_CMD_MKENT(status, 2, 1, do_status, "", ""),
U_BOOT_CMD_MKENT(value, 3, 1, do_value, "", ""),
U_BOOT_CMD_MKENT(current, 3, 1, do_current, "", ""),
U_BOOT_CMD_MKENT(mode, 2, 1, do_mode, "", ""),
U_BOOT_CMD_MKENT(enable, 1, 1, do_enable, "", ""),
U_BOOT_CMD_MKENT(disable, 1, 1, do_disable, "", ""),
};
static int do_regulator(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
cmd_tbl_t *cmd;
argc--;
argv++;
cmd = find_cmd_tbl(argv[0], subcmd, ARRAY_SIZE(subcmd));
if (cmd == NULL || argc > cmd->maxargs)
return CMD_RET_USAGE;
return cmd->cmd(cmdtp, flag, argc, argv);
}
U_BOOT_CMD(regulator, CONFIG_SYS_MAXARGS, 1, do_regulator,
"uclass operations",
"list - list UCLASS regulator devices\n"
"regulator dev [regulator-name] - show/[set] operating regulator device\n"
"regulator info - print constraints info\n"
"regulator status - print operating status\n"
"regulator value [val] [-f] - print/[set] voltage value [uV] (force)\n"
"regulator current [val] - print/[set] current value [uA]\n"
"regulator mode [id] - print/[set] operating mode id\n"
"regulator enable - enable the regulator output\n"
"regulator disable - disable the regulator output\n"