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