]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
d89fdcf9 PM |
2 | /* |
3 | * Copyright (C) 2014-2015 Samsung Electronics | |
4 | * Przemyslaw Marczak <[email protected]> | |
d89fdcf9 PM |
5 | */ |
6 | #include <common.h> | |
7 | #include <errno.h> | |
8 | #include <dm.h> | |
9 | #include <dm/uclass-internal.h> | |
10 | #include <power/pmic.h> | |
11 | ||
493cdec7 PM |
12 | #define LIMIT_DEV 32 |
13 | #define LIMIT_PARENT 20 | |
d89fdcf9 PM |
14 | |
15 | static struct udevice *currdev; | |
16 | ||
493cdec7 | 17 | static int failure(int ret) |
d89fdcf9 | 18 | { |
493cdec7 | 19 | printf("Error: %d (%s)\n", ret, errno_str(ret)); |
d89fdcf9 | 20 | |
493cdec7 | 21 | return CMD_RET_FAILURE; |
d89fdcf9 PM |
22 | } |
23 | ||
24 | static int do_dev(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
25 | { | |
493cdec7 PM |
26 | char *name; |
27 | int ret = -ENODEV; | |
d89fdcf9 PM |
28 | |
29 | switch (argc) { | |
30 | case 2: | |
493cdec7 PM |
31 | name = argv[1]; |
32 | ret = pmic_get(name, &currdev); | |
33 | if (ret) { | |
34 | printf("Can't get PMIC: %s!\n", name); | |
35 | return failure(ret); | |
36 | } | |
d89fdcf9 | 37 | case 1: |
493cdec7 PM |
38 | if (!currdev) { |
39 | printf("PMIC device is not set!\n\n"); | |
40 | return CMD_RET_USAGE; | |
41 | } | |
d89fdcf9 PM |
42 | |
43 | printf("dev: %d @ %s\n", currdev->seq, currdev->name); | |
44 | } | |
45 | ||
46 | return CMD_RET_SUCCESS; | |
d89fdcf9 PM |
47 | } |
48 | ||
49 | static int do_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
50 | { | |
51 | struct udevice *dev; | |
52 | int ret; | |
53 | ||
493cdec7 PM |
54 | printf("| %-*.*s| %-*.*s| %s @ %s\n", |
55 | LIMIT_DEV, LIMIT_DEV, "Name", | |
56 | LIMIT_PARENT, LIMIT_PARENT, "Parent name", | |
d89fdcf9 PM |
57 | "Parent uclass", "seq"); |
58 | ||
59 | for (ret = uclass_first_device(UCLASS_PMIC, &dev); dev; | |
60 | ret = uclass_next_device(&dev)) { | |
493cdec7 PM |
61 | if (ret) |
62 | continue; | |
63 | ||
64 | printf("| %-*.*s| %-*.*s| %s @ %d\n", | |
65 | LIMIT_DEV, LIMIT_DEV, dev->name, | |
66 | LIMIT_PARENT, LIMIT_PARENT, dev->parent->name, | |
d89fdcf9 PM |
67 | dev_get_uclass_name(dev->parent), dev->parent->seq); |
68 | } | |
69 | ||
70 | if (ret) | |
71 | return CMD_RET_FAILURE; | |
72 | ||
73 | return CMD_RET_SUCCESS; | |
74 | } | |
75 | ||
76 | static int do_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
77 | { | |
d4505c8e | 78 | struct uc_pmic_priv *priv; |
d89fdcf9 | 79 | struct udevice *dev; |
d4505c8e | 80 | char fmt[16]; |
d89fdcf9 PM |
81 | uint reg; |
82 | int ret; | |
83 | ||
493cdec7 PM |
84 | if (!currdev) { |
85 | printf("First, set the PMIC device!\n"); | |
86 | return CMD_RET_USAGE; | |
87 | } | |
d89fdcf9 PM |
88 | |
89 | dev = currdev; | |
d4505c8e | 90 | priv = dev_get_uclass_priv(dev); |
d89fdcf9 PM |
91 | printf("Dump pmic: %s registers\n", dev->name); |
92 | ||
d4505c8e LM |
93 | sprintf(fmt, "%%%d.%dx ", priv->trans_len * 2, |
94 | priv->trans_len * 2); | |
95 | ||
d89fdcf9 | 96 | for (reg = 0; reg < pmic_reg_count(dev); reg++) { |
d4505c8e LM |
97 | ret = pmic_reg_read(dev, reg); |
98 | if (ret < 0) { | |
493cdec7 PM |
99 | printf("Can't read register: %d\n", reg); |
100 | return failure(ret); | |
101 | } | |
d89fdcf9 PM |
102 | |
103 | if (!(reg % 16)) | |
104 | printf("\n0x%02x: ", reg); | |
105 | ||
d4505c8e | 106 | printf(fmt, ret); |
d89fdcf9 PM |
107 | } |
108 | printf("\n"); | |
109 | ||
110 | return CMD_RET_SUCCESS; | |
111 | } | |
112 | ||
113 | static int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
114 | { | |
d4505c8e | 115 | struct uc_pmic_priv *priv; |
d89fdcf9 PM |
116 | struct udevice *dev; |
117 | int regs, ret; | |
d4505c8e | 118 | char fmt[24]; |
d89fdcf9 PM |
119 | uint reg; |
120 | ||
493cdec7 PM |
121 | if (!currdev) { |
122 | printf("First, set the PMIC device!\n"); | |
123 | return CMD_RET_USAGE; | |
124 | } | |
d89fdcf9 PM |
125 | |
126 | dev = currdev; | |
d4505c8e | 127 | priv = dev_get_uclass_priv(dev); |
d89fdcf9 PM |
128 | |
129 | if (argc != 2) | |
130 | return CMD_RET_USAGE; | |
131 | ||
132 | reg = simple_strtoul(argv[1], NULL, 0); | |
133 | regs = pmic_reg_count(dev); | |
134 | if (reg > regs) { | |
493cdec7 PM |
135 | printf("PMIC max reg: %d\n", regs); |
136 | return failure(-EFAULT); | |
d89fdcf9 PM |
137 | } |
138 | ||
d4505c8e LM |
139 | ret = pmic_reg_read(dev, reg); |
140 | if (ret < 0) { | |
493cdec7 PM |
141 | printf("Can't read PMIC register: %d!\n", reg); |
142 | return failure(ret); | |
143 | } | |
d89fdcf9 | 144 | |
d4505c8e LM |
145 | sprintf(fmt, "0x%%02x: 0x%%%d.%dx\n", priv->trans_len * 2, |
146 | priv->trans_len * 2); | |
147 | printf(fmt, reg, ret); | |
d89fdcf9 PM |
148 | |
149 | return CMD_RET_SUCCESS; | |
150 | } | |
151 | ||
152 | static int do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
153 | { | |
154 | struct udevice *dev; | |
d4505c8e | 155 | uint reg, value; |
d89fdcf9 | 156 | int regs, ret; |
d89fdcf9 | 157 | |
493cdec7 PM |
158 | if (!currdev) { |
159 | printf("First, set the PMIC device!\n"); | |
160 | return CMD_RET_USAGE; | |
161 | } | |
d89fdcf9 PM |
162 | |
163 | dev = currdev; | |
164 | ||
165 | if (argc != 3) | |
166 | return CMD_RET_USAGE; | |
167 | ||
168 | reg = simple_strtoul(argv[1], NULL, 0); | |
169 | regs = pmic_reg_count(dev); | |
170 | if (reg > regs) { | |
493cdec7 PM |
171 | printf("PMIC max reg: %d\n", regs); |
172 | return failure(-EFAULT); | |
d89fdcf9 PM |
173 | } |
174 | ||
175 | value = simple_strtoul(argv[2], NULL, 0); | |
176 | ||
d4505c8e | 177 | ret = pmic_reg_write(dev, reg, value); |
493cdec7 PM |
178 | if (ret) { |
179 | printf("Can't write PMIC register: %d!\n", reg); | |
180 | return failure(ret); | |
181 | } | |
d89fdcf9 PM |
182 | |
183 | return CMD_RET_SUCCESS; | |
184 | } | |
185 | ||
186 | static cmd_tbl_t subcmd[] = { | |
187 | U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""), | |
188 | U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""), | |
189 | U_BOOT_CMD_MKENT(dump, 1, 1, do_dump, "", ""), | |
190 | U_BOOT_CMD_MKENT(read, 2, 1, do_read, "", ""), | |
191 | U_BOOT_CMD_MKENT(write, 3, 1, do_write, "", ""), | |
192 | }; | |
193 | ||
194 | static int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, | |
195 | char * const argv[]) | |
196 | { | |
197 | cmd_tbl_t *cmd; | |
198 | ||
199 | argc--; | |
200 | argv++; | |
201 | ||
202 | cmd = find_cmd_tbl(argv[0], subcmd, ARRAY_SIZE(subcmd)); | |
203 | if (cmd == NULL || argc > cmd->maxargs) | |
204 | return CMD_RET_USAGE; | |
205 | ||
206 | return cmd->cmd(cmdtp, flag, argc, argv); | |
207 | } | |
208 | ||
209 | U_BOOT_CMD(pmic, CONFIG_SYS_MAXARGS, 1, do_pmic, | |
7e37a884 | 210 | "PMIC sub-system", |
d89fdcf9 | 211 | "list - list pmic devices\n" |
493cdec7 | 212 | "pmic dev [name] - show or [set] operating PMIC device\n" |
d89fdcf9 PM |
213 | "pmic dump - dump registers\n" |
214 | "pmic read address - read byte of register at address\n" | |
215 | "pmic write address - write byte to register at address\n" | |
216 | ); |