xref: /openbmc/u-boot/cmd/pmic.c (revision d02be99e6774b99c27b7d4304865c7f45e1ac4b4)
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_DEV	32
14  #define LIMIT_PARENT	20
15  
16  static struct udevice *currdev;
17  
18  static int failure(int ret)
19  {
20  	printf("Error: %d (%s)\n", ret, errno_str(ret));
21  
22  	return CMD_RET_FAILURE;
23  }
24  
25  static int do_dev(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
26  {
27  	char *name;
28  	int ret = -ENODEV;
29  
30  	switch (argc) {
31  	case 2:
32  		name = argv[1];
33  		ret = pmic_get(name, &currdev);
34  		if (ret) {
35  			printf("Can't get PMIC: %s!\n", name);
36  			return failure(ret);
37  		}
38  	case 1:
39  		if (!currdev) {
40  			printf("PMIC device is not set!\n\n");
41  			return CMD_RET_USAGE;
42  		}
43  
44  		printf("dev: %d @ %s\n", currdev->seq, currdev->name);
45  	}
46  
47  	return CMD_RET_SUCCESS;
48  }
49  
50  static int do_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
51  {
52  	struct udevice *dev;
53  	int ret;
54  
55  	printf("| %-*.*s| %-*.*s| %s @ %s\n",
56  	       LIMIT_DEV, LIMIT_DEV, "Name",
57  	       LIMIT_PARENT, LIMIT_PARENT, "Parent name",
58  	       "Parent uclass", "seq");
59  
60  	for (ret = uclass_first_device(UCLASS_PMIC, &dev); dev;
61  	     ret = uclass_next_device(&dev)) {
62  		if (ret)
63  			continue;
64  
65  		printf("| %-*.*s| %-*.*s| %s @ %d\n",
66  		       LIMIT_DEV, LIMIT_DEV, dev->name,
67  		       LIMIT_PARENT, LIMIT_PARENT, dev->parent->name,
68  		       dev_get_uclass_name(dev->parent), dev->parent->seq);
69  	}
70  
71  	if (ret)
72  		return CMD_RET_FAILURE;
73  
74  	return CMD_RET_SUCCESS;
75  }
76  
77  static int do_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
78  {
79  	struct udevice *dev;
80  	uint8_t value;
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  
91  	printf("Dump pmic: %s registers\n", dev->name);
92  
93  	for (reg = 0; reg < pmic_reg_count(dev); reg++) {
94  		ret = pmic_read(dev, reg, &value, 1);
95  		if (ret) {
96  			printf("Can't read register: %d\n", reg);
97  			return failure(ret);
98  		}
99  
100  		if (!(reg % 16))
101  			printf("\n0x%02x: ", reg);
102  
103  		printf("%2.2x ", value);
104  	}
105  	printf("\n");
106  
107  	return CMD_RET_SUCCESS;
108  }
109  
110  static int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
111  {
112  	struct udevice *dev;
113  	int regs, ret;
114  	uint8_t value;
115  	uint reg;
116  
117  	if (!currdev) {
118  		printf("First, set the PMIC device!\n");
119  		return CMD_RET_USAGE;
120  	}
121  
122  	dev = currdev;
123  
124  	if (argc != 2)
125  		return CMD_RET_USAGE;
126  
127  	reg = simple_strtoul(argv[1], NULL, 0);
128  	regs = pmic_reg_count(dev);
129  	if (reg > regs) {
130  		printf("PMIC max reg: %d\n", regs);
131  		return failure(-EFAULT);
132  	}
133  
134  	ret = pmic_read(dev, reg, &value, 1);
135  	if (ret) {
136  		printf("Can't read PMIC register: %d!\n", reg);
137  		return failure(ret);
138  	}
139  
140  	printf("0x%02x: 0x%2.2x\n", reg, value);
141  
142  	return CMD_RET_SUCCESS;
143  }
144  
145  static int do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
146  {
147  	struct udevice *dev;
148  	int regs, ret;
149  	uint8_t value;
150  	uint reg;
151  
152  	if (!currdev) {
153  		printf("First, set the PMIC device!\n");
154  		return CMD_RET_USAGE;
155  	}
156  
157  	dev = currdev;
158  
159  	if (argc != 3)
160  		return CMD_RET_USAGE;
161  
162  	reg = simple_strtoul(argv[1], NULL, 0);
163  	regs = pmic_reg_count(dev);
164  	if (reg > regs) {
165  		printf("PMIC max reg: %d\n", regs);
166  		return failure(-EFAULT);
167  	}
168  
169  	value = simple_strtoul(argv[2], NULL, 0);
170  
171  	ret = pmic_write(dev, reg, &value, 1);
172  	if (ret) {
173  		printf("Can't write PMIC register: %d!\n", reg);
174  		return failure(ret);
175  	}
176  
177  	return CMD_RET_SUCCESS;
178  }
179  
180  static cmd_tbl_t subcmd[] = {
181  	U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""),
182  	U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""),
183  	U_BOOT_CMD_MKENT(dump, 1, 1, do_dump, "", ""),
184  	U_BOOT_CMD_MKENT(read, 2, 1, do_read, "", ""),
185  	U_BOOT_CMD_MKENT(write, 3, 1, do_write, "", ""),
186  };
187  
188  static int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc,
189  			char * const argv[])
190  {
191  	cmd_tbl_t *cmd;
192  
193  	argc--;
194  	argv++;
195  
196  	cmd = find_cmd_tbl(argv[0], subcmd, ARRAY_SIZE(subcmd));
197  	if (cmd == NULL || argc > cmd->maxargs)
198  		return CMD_RET_USAGE;
199  
200  	return cmd->cmd(cmdtp, flag, argc, argv);
201  }
202  
203  U_BOOT_CMD(pmic, CONFIG_SYS_MAXARGS, 1, do_pmic,
204  	" operations",
205  	"list          - list pmic devices\n"
206  	"pmic dev [name]    - show or [set] operating PMIC device\n"
207  	"pmic dump          - dump registers\n"
208  	"pmic read address  - read byte of register at address\n"
209  	"pmic write address - write byte to register at address\n"
210  );
211