]> git.sur5r.net Git - u-boot/blob - common/cmd_pmic.c
bd88d687cbed65889d3908e6509904d980e0f5ef
[u-boot] / common / cmd_pmic.c
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
16 static struct udevice *currdev;
17
18 static 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
26 static 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
62 static 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;
80 failed:
81         return failed("get", "the", "device", ret);
82 }
83
84 static 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
110 static 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
139 static 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
170 static 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
201 static 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
209 static 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
224 U_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 );