colibri_imx6: fix video stdout in default environment
[oweals/u-boot.git] / drivers / power / power_core.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2011 Samsung Electronics
4  * Lukasz Majewski <l.majewski@samsung.com>
5  *
6  * (C) Copyright 2010
7  * Stefano Babic, DENX Software Engineering, sbabic@denx.de
8  *
9  * (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
10  */
11
12 #include <common.h>
13 #include <command.h>
14 #include <log.h>
15 #include <malloc.h>
16 #include <linux/types.h>
17 #include <linux/list.h>
18 #include <power/pmic.h>
19
20 static LIST_HEAD(pmic_list);
21
22 int check_reg(struct pmic *p, u32 reg)
23 {
24         if (reg >= p->number_of_regs) {
25                 printf("<reg num> = %d is invalid. Should be less than %d\n",
26                        reg, p->number_of_regs);
27                 return -EINVAL;
28         }
29
30         return 0;
31 }
32
33 int pmic_set_output(struct pmic *p, u32 reg, int out, int on)
34 {
35         u32 val;
36
37         if (pmic_reg_read(p, reg, &val))
38                 return -ENOTSUPP;
39
40         if (on)
41                 val |= out;
42         else
43                 val &= ~out;
44
45         if (pmic_reg_write(p, reg, val))
46                 return -ENOTSUPP;
47
48         return 0;
49 }
50
51 struct pmic *pmic_alloc(void)
52 {
53         struct pmic *p;
54
55         p = calloc(sizeof(*p), 1);
56         if (!p) {
57                 printf("%s: No available memory for allocation!\n", __func__);
58                 return NULL;
59         }
60
61         list_add_tail(&p->list, &pmic_list);
62
63         debug("%s: new pmic struct: 0x%p\n", __func__, p);
64
65         return p;
66 }
67
68 struct pmic *pmic_get(const char *s)
69 {
70         struct pmic *p;
71
72         list_for_each_entry(p, &pmic_list, list) {
73                 if (strcmp(p->name, s) == 0) {
74                         debug("%s: pmic %s -> 0x%p\n", __func__, p->name, p);
75                         return p;
76                 }
77         }
78
79         return NULL;
80 }
81
82 #ifndef CONFIG_SPL_BUILD
83 static int pmic_dump(struct pmic *p)
84 {
85         int i, ret;
86         u32 val;
87
88         if (!p) {
89                 puts("Wrong PMIC name!\n");
90                 return -ENODEV;
91         }
92
93         printf("PMIC: %s\n", p->name);
94         for (i = 0; i < p->number_of_regs; i++) {
95                 ret = pmic_reg_read(p, i, &val);
96                 if (ret)
97                         puts("PMIC: Registers dump failed\n");
98
99                 if (!(i % 8))
100                         printf("\n0x%02x: ", i);
101
102                 printf("%08x ", val);
103         }
104         puts("\n");
105         return 0;
106 }
107
108 static const char *power_get_interface(int interface)
109 {
110         const char *power_interface[] = {"I2C", "SPI", "|+|-|"};
111         return power_interface[interface];
112 }
113
114 static void pmic_list_names(void)
115 {
116         struct pmic *p;
117
118         puts("PMIC devices:\n");
119         list_for_each_entry(p, &pmic_list, list) {
120                 printf("name: %s bus: %s_%d\n", p->name,
121                        power_get_interface(p->interface), p->bus);
122         }
123 }
124
125 static int do_pmic(struct cmd_tbl *cmdtp, int flag, int argc,
126                    char *const argv[])
127 {
128         u32 ret, reg, val;
129         char *cmd, *name;
130         struct pmic *p;
131
132         /* at least two arguments please */
133         if (argc < 2)
134                 return CMD_RET_USAGE;
135
136         if (strcmp(argv[1], "list") == 0) {
137                 pmic_list_names();
138                 return CMD_RET_SUCCESS;
139         }
140
141         if (argc < 3)
142                 return CMD_RET_USAGE;
143
144         name = argv[1];
145         cmd = argv[2];
146
147         debug("%s: name: %s cmd: %s\n", __func__, name, cmd);
148         p = pmic_get(name);
149         if (!p)
150                 return CMD_RET_FAILURE;
151
152         if (strcmp(cmd, "dump") == 0) {
153                 if (pmic_dump(p))
154                         return CMD_RET_FAILURE;
155                 return CMD_RET_SUCCESS;
156         }
157
158         if (strcmp(cmd, "read") == 0) {
159                 if (argc < 4)
160                         return CMD_RET_USAGE;
161
162                 reg = simple_strtoul(argv[3], NULL, 16);
163                 ret = pmic_reg_read(p, reg, &val);
164
165                 if (ret)
166                         puts("PMIC: Register read failed\n");
167
168                 printf("\n0x%02x: 0x%08x\n", reg, val);
169
170                 return CMD_RET_SUCCESS;
171         }
172
173         if (strcmp(cmd, "write") == 0) {
174                 if (argc < 5)
175                         return CMD_RET_USAGE;
176
177                 reg = simple_strtoul(argv[3], NULL, 16);
178                 val = simple_strtoul(argv[4], NULL, 16);
179                 pmic_reg_write(p, reg, val);
180
181                 return CMD_RET_SUCCESS;
182         }
183
184         if (strcmp(cmd, "bat") == 0) {
185                 if (argc < 4)
186                         return CMD_RET_USAGE;
187
188                 if (!p->pbat) {
189                         printf("%s is not a battery\n", p->name);
190                         return CMD_RET_FAILURE;
191                 }
192
193                 if (strcmp(argv[3], "state") == 0)
194                         p->fg->fg_battery_check(p->pbat->fg, p);
195
196                 if (strcmp(argv[3], "charge") == 0) {
197                         printf("BAT: %s charging (ctrl+c to break)\n",
198                                p->name);
199                         if (p->low_power_mode)
200                                 p->low_power_mode();
201                         if (p->pbat->battery_charge)
202                                 p->pbat->battery_charge(p);
203                 }
204
205                 return CMD_RET_SUCCESS;
206         }
207
208         /* No subcommand found */
209         return CMD_RET_SUCCESS;
210 }
211
212 U_BOOT_CMD(
213         pmic,   CONFIG_SYS_MAXARGS, 1, do_pmic,
214         "PMIC",
215         "list - list available PMICs\n"
216         "pmic name dump - dump named PMIC registers\n"
217         "pmic name read <reg> - read register\n"
218         "pmic name write <reg> <value> - write register\n"
219         "pmic name bat state - write register\n"
220         "pmic name bat charge - write register\n"
221 );
222 #endif