xref: /openbmc/u-boot/cmd/pmic.c (revision a65e6440)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2014-2015 Samsung Electronics
4  * Przemyslaw Marczak <p.marczak@samsung.com>
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 
12 #define LIMIT_DEV	32
13 #define LIMIT_PARENT	20
14 
15 static struct udevice *currdev;
16 
17 static int failure(int ret)
18 {
19 	printf("Error: %d (%s)\n", ret, errno_str(ret));
20 
21 	return CMD_RET_FAILURE;
22 }
23 
24 static int do_dev(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
25 {
26 	char *name;
27 	int ret = -ENODEV;
28 
29 	switch (argc) {
30 	case 2:
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 		}
37 	case 1:
38 		if (!currdev) {
39 			printf("PMIC device is not set!\n\n");
40 			return CMD_RET_USAGE;
41 		}
42 
43 		printf("dev: %d @ %s\n", currdev->seq, currdev->name);
44 	}
45 
46 	return CMD_RET_SUCCESS;
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 
54 	printf("| %-*.*s| %-*.*s| %s @ %s\n",
55 	       LIMIT_DEV, LIMIT_DEV, "Name",
56 	       LIMIT_PARENT, LIMIT_PARENT, "Parent name",
57 	       "Parent uclass", "seq");
58 
59 	for (ret = uclass_first_device(UCLASS_PMIC, &dev); dev;
60 	     ret = uclass_next_device(&dev)) {
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,
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 {
78 	struct uc_pmic_priv *priv;
79 	struct udevice *dev;
80 	char fmt[16];
81 	uint reg;
82 	int ret;
83 
84 	if (!currdev) {
85 		printf("First, set the PMIC device!\n");
86 		return CMD_RET_USAGE;
87 	}
88 
89 	dev = currdev;
90 	priv = dev_get_uclass_priv(dev);
91 	printf("Dump pmic: %s registers\n", dev->name);
92 
93 	sprintf(fmt, "%%%d.%dx ", priv->trans_len * 2,
94 		priv->trans_len * 2);
95 
96 	for (reg = 0; reg < pmic_reg_count(dev); reg++) {
97 		ret = pmic_reg_read(dev, reg);
98 		if (ret < 0) {
99 			printf("Can't read register: %d\n", reg);
100 			return failure(ret);
101 		}
102 
103 		if (!(reg % 16))
104 			printf("\n0x%02x: ", reg);
105 
106 		printf(fmt, ret);
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 {
115 	struct uc_pmic_priv *priv;
116 	struct udevice *dev;
117 	int regs, ret;
118 	char fmt[24];
119 	uint reg;
120 
121 	if (!currdev) {
122 		printf("First, set the PMIC device!\n");
123 		return CMD_RET_USAGE;
124 	}
125 
126 	dev = currdev;
127 	priv = dev_get_uclass_priv(dev);
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) {
135 		printf("PMIC max reg: %d\n", regs);
136 		return failure(-EFAULT);
137 	}
138 
139 	ret = pmic_reg_read(dev, reg);
140 	if (ret < 0) {
141 		printf("Can't read PMIC register: %d!\n", reg);
142 		return failure(ret);
143 	}
144 
145 	sprintf(fmt, "0x%%02x: 0x%%%d.%dx\n", priv->trans_len * 2,
146 		priv->trans_len * 2);
147 	printf(fmt, reg, ret);
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;
155 	uint reg, value;
156 	int regs, ret;
157 
158 	if (!currdev) {
159 		printf("First, set the PMIC device!\n");
160 		return CMD_RET_USAGE;
161 	}
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) {
171 		printf("PMIC max reg: %d\n", regs);
172 		return failure(-EFAULT);
173 	}
174 
175 	value = simple_strtoul(argv[2], NULL, 0);
176 
177 	ret = pmic_reg_write(dev, reg, value);
178 	if (ret) {
179 		printf("Can't write PMIC register: %d!\n", reg);
180 		return failure(ret);
181 	}
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,
210 	"PMIC sub-system",
211 	"list          - list pmic devices\n"
212 	"pmic dev [name]    - show or [set] operating PMIC device\n"
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 );
217