]> git.ipfire.org Git - people/ms/u-boot.git/blame - common/cmd_pmic.c
dm: pmic: add pmic command
[people/ms/u-boot.git] / common / cmd_pmic.c
CommitLineData
d89fdcf9
PM
1/*
2 * Copyright (C) 2014-2015 Samsung Electronics
3 * Przemyslaw Marczak <p.marczak@samsung.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7#include <common.h>
8#include <errno.h>
9#include <dm.h>
10#include <dm/uclass-internal.h>
11#include <power/pmic.h>
12
13#define LIMIT_SEQ 3
14#define LIMIT_DEVNAME 20
15
16static struct udevice *currdev;
17
18static int failed(const char *getset, const char *thing,
19 const char *for_dev, int ret)
20{
21 printf("Can't %s %s %s.\nError: %d (%s)\n", getset, thing, for_dev,
22 ret, errno_str(ret));
23 return CMD_RET_FAILURE;
24}
25
26static int pmic_dev_get(bool list_only, int get_seq, struct udevice **devp)
27{
28 struct udevice *dev;
29 int ret;
30
31 if (devp)
32 *devp = NULL;
33
34 for (ret = uclass_first_device(UCLASS_PMIC, &dev); dev;
35 ret = uclass_next_device(&dev)) {
36 if (list_only) {
37 printf("|%*d | %-*.*s| %-*.*s| %s @ %d\n",
38 LIMIT_SEQ, dev->seq,
39 LIMIT_DEVNAME, LIMIT_DEVNAME, dev->name,
40 LIMIT_DEVNAME, LIMIT_DEVNAME, dev->parent->name,
41 dev_get_uclass_name(dev->parent),
42 dev->parent->seq);
43 continue;
44 }
45
46 if (dev->seq == get_seq) {
47 if (devp)
48 *devp = dev;
49 else
50 return -EINVAL;
51
52 return 0;
53 }
54 }
55
56 if (list_only)
57 return ret;
58
59 return -ENODEV;
60}
61
62static int do_dev(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
63{
64 int seq, ret = -ENODEV;
65
66 switch (argc) {
67 case 2:
68 seq = simple_strtoul(argv[1], NULL, 0);
69 ret = uclass_get_device_by_seq(UCLASS_PMIC, seq, &currdev);
70 if (ret && (ret = pmic_dev_get(false, seq, &currdev)))
71 goto failed;
72 case 1:
73 if (!currdev)
74 goto failed;
75
76 printf("dev: %d @ %s\n", currdev->seq, currdev->name);
77 }
78
79 return CMD_RET_SUCCESS;
80failed:
81 return failed("get", "the", "device", ret);
82}
83
84static int do_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
85{
86 struct udevice *dev;
87 int ret;
88
89 printf("|%*s | %-*.*s| %-*.*s| %s @ %s\n",
90 LIMIT_SEQ, "Seq",
91 LIMIT_DEVNAME, LIMIT_DEVNAME, "Name",
92 LIMIT_DEVNAME, LIMIT_DEVNAME, "Parent name",
93 "Parent uclass", "seq");
94
95 for (ret = uclass_first_device(UCLASS_PMIC, &dev); dev;
96 ret = uclass_next_device(&dev)) {
97 printf("|%*d | %-*.*s| %-*.*s| %s @ %d\n",
98 LIMIT_SEQ, dev->seq,
99 LIMIT_DEVNAME, LIMIT_DEVNAME, dev->name,
100 LIMIT_DEVNAME, LIMIT_DEVNAME, dev->parent->name,
101 dev_get_uclass_name(dev->parent), dev->parent->seq);
102 }
103
104 if (ret)
105 return CMD_RET_FAILURE;
106
107 return CMD_RET_SUCCESS;
108}
109
110static int do_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
111{
112 struct udevice *dev;
113 uint8_t value;
114 uint reg;
115 int ret;
116
117 if (!currdev)
118 return failed("get", "current", "device", -ENODEV);
119
120 dev = currdev;
121
122 printf("Dump pmic: %s registers\n", dev->name);
123
124 for (reg = 0; reg < pmic_reg_count(dev); reg++) {
125 ret = pmic_read(dev, reg, &value, 1);
126 if (ret)
127 return failed("read", dev->name, "register", ret);
128
129 if (!(reg % 16))
130 printf("\n0x%02x: ", reg);
131
132 printf("%2.2x ", value);
133 }
134 printf("\n");
135
136 return CMD_RET_SUCCESS;
137}
138
139static int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
140{
141 struct udevice *dev;
142 int regs, ret;
143 uint8_t value;
144 uint reg;
145
146 if (!currdev)
147 return failed("get", "current", "device", -ENODEV);
148
149 dev = currdev;
150
151 if (argc != 2)
152 return CMD_RET_USAGE;
153
154 reg = simple_strtoul(argv[1], NULL, 0);
155 regs = pmic_reg_count(dev);
156 if (reg > regs) {
157 printf("Pmic max reg: %d\n", regs);
158 return failed("read", "given", "address", -EFAULT);
159 }
160
161 ret = pmic_read(dev, reg, &value, 1);
162 if (ret)
163 return failed("read", dev->name, "register", ret);
164
165 printf("0x%02x: 0x%2.2x\n", reg, value);
166
167 return CMD_RET_SUCCESS;
168}
169
170static int do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
171{
172 struct udevice *dev;
173 int regs, ret;
174 uint8_t value;
175 uint reg;
176
177 if (!currdev)
178 return failed("get", "current", "device", -ENODEV);
179
180 dev = currdev;
181
182 if (argc != 3)
183 return CMD_RET_USAGE;
184
185 reg = simple_strtoul(argv[1], NULL, 0);
186 regs = pmic_reg_count(dev);
187 if (reg > regs) {
188 printf("Pmic max reg: %d\n", regs);
189 return failed("write", "given", "address", -EFAULT);
190 }
191
192 value = simple_strtoul(argv[2], NULL, 0);
193
194 ret = pmic_write(dev, reg, &value, 1);
195 if (ret)
196 return failed("write", dev->name, "register", ret);
197
198 return CMD_RET_SUCCESS;
199}
200
201static cmd_tbl_t subcmd[] = {
202 U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""),
203 U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""),
204 U_BOOT_CMD_MKENT(dump, 1, 1, do_dump, "", ""),
205 U_BOOT_CMD_MKENT(read, 2, 1, do_read, "", ""),
206 U_BOOT_CMD_MKENT(write, 3, 1, do_write, "", ""),
207};
208
209static int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc,
210 char * const argv[])
211{
212 cmd_tbl_t *cmd;
213
214 argc--;
215 argv++;
216
217 cmd = find_cmd_tbl(argv[0], subcmd, ARRAY_SIZE(subcmd));
218 if (cmd == NULL || argc > cmd->maxargs)
219 return CMD_RET_USAGE;
220
221 return cmd->cmd(cmdtp, flag, argc, argv);
222}
223
224U_BOOT_CMD(pmic, CONFIG_SYS_MAXARGS, 1, do_pmic,
225 " operations",
226 "list - list pmic devices\n"
227 "pmic dev [id] - show or [set] operating pmic device\n"
228 "pmic dump - dump registers\n"
229 "pmic read address - read byte of register at address\n"
230 "pmic write address - write byte to register at address\n"
231);