xref: /openbsd-src/sys/dev/fdt/axppmic.c (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1 /*	$OpenBSD: axppmic.c,v 1.20 2023/08/02 11:52:18 uaa Exp $	*/
2 /*
3  * Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/device.h>
21 #include <sys/malloc.h>
22 #include <sys/sensors.h>
23 
24 #include <dev/i2c/i2cvar.h>
25 #include <dev/fdt/rsbvar.h>
26 
27 #include <dev/ofw/openfirm.h>
28 #include <dev/ofw/ofw_regulator.h>
29 #include <dev/ofw/fdt.h>
30 
31 extern void (*powerdownfn)(void);
32 
33 #define AXP209_SDR		0x32
34 #define  AXP209_SDR_SHUTDOWN	(1 << 7)
35 #define AXP209_ADC_EN1		0x82
36 #define  AXP209_ADC_EN1_ACIN	(3 << 4)
37 #define  AXP209_ADC_EN1_VBUS	(3 << 2)
38 
39 #define AXP803_IRQ1_EN		0x40
40 #define AXP803_IRQ2_EN		0x41
41 #define AXP803_IRQ3_EN		0x42
42 #define AXP803_IRQ4_EN		0x43
43 #define AXP803_IRQ5_EN		0x44
44 #define  AXP803_IRQ5_EN_PEK_SHORT	(1 << 4)
45 #define AXP803_IRQ6_EN		0x45
46 #define AXP803_IRQ1_STAT	0x48
47 #define AXP803_IRQ2_STAT	0x49
48 #define AXP803_IRQ3_STAT	0x4a
49 #define AXP803_IRQ4_STAT	0x4b
50 #define AXP803_IRQ5_STAT	0x4c
51 #define  AXP803_IRQ5_STAT_PEK_SHORT	(1 << 4)
52 #define AXP803_IRQ6_STAT	0x4d
53 #define AXP803_BAT_CAP_WARN		0xe6
54 #define  AXP803_BAT_CAP_WARN_LV1	0xf0
55 #define  AXP803_BAT_CAP_WARN_LV1BASE	5
56 #define  AXP803_BAT_CAP_WARN_LV2	0x0f
57 
58 #define AXP806_REG_ADDR_EXT			0xff
59 #define  AXP806_REG_ADDR_EXT_MASTER_MODE	(0 << 4)
60 #define  AXP806_REG_ADDR_EXT_SLAVE_MODE		(1 << 4)
61 
62 /* Regulators for AXP209, AXP221, AXP806 and AXP809. */
63 
64 struct axppmic_regdata {
65 	const char *name;
66 	uint8_t ereg, emask, eval, dval;
67 	uint8_t vreg, vmask;
68 	uint32_t base, delta, nsteps;
69 	uint32_t base2, delta2, nsteps2;
70 };
71 
72 const struct axppmic_regdata axp209_regdata[] = {
73 	{ "dcdc2", 0x12, (1 << 4), (1 << 4), (0 << 4),
74 	  0x23, 0x3f, 700000, 25000, 64 },
75 	{ "dcdc3", 0x12, (1 << 1), (1 << 1), (0 << 1),
76 	  0x27, 0x7f, 700000, 25000, 113 },
77 	/* LDO1 can't be controlled */
78 	{ "ldo2", 0x12, (1 << 2), (1 << 2), (0 << 2),
79 	  0x28, 0xf0, 1800000, (100000 >> 4), (16 << 4) },
80 	{ "ldo3", 0x12, (1 << 6), (1 << 6), (0 << 6),
81 	  0x29, 0x7f, 700000, 25000, 113 },
82 	/* LDO4 voltage levels are complicated */
83 	{ "ldo5", 0x90, 0x07, 0x03, 0x07,
84 	  0x91, 0xf0, 1800000, (100000 >> 4), (16 << 4) },
85 	{ NULL }
86 };
87 
88 const struct axppmic_regdata axp221_regdata[] = {
89 	{ "dcdc1", 0x10, (1 << 1), (1 << 1), (0 << 1),
90 	  0x21, 0x1f, 1600000, 100000, 19 },
91 	{ "dcdc2", 0x10, (1 << 2), (1 << 2), (0 << 2),
92 	  0x22, 0x3f, 600000, 20000, 48 },
93 	{ "dcdc3", 0x10, (1 << 3), (1 << 3), (0 << 3),
94 	  0x23, 0x3f, 600000, 20000, 64 },
95 	{ "dcdc4", 0x10, (1 << 4), (1 << 4), (0 << 4),
96 	  0x24, 0x3f, 600000, 20000, 48 },
97 	{ "dcdc5", 0x10, (1 << 5), (1 << 5), (0 << 5),
98 	  0x25, 0x1f, 1000000, 50000, 32 },
99 	{ "dc1sw", 0x12, (1 << 7), (1 << 7), (0 << 7) },
100 	{ "dc5ldo", 0x10, (1 << 0), (1 << 0), (0 << 0),
101 	  0x1c, 0x07, 700000, 100000, 8 },
102 	{ "aldo1", 0x10, (1 << 6), (1 << 6), (0 << 6),
103 	  0x28, 0x1f, 700000, 100000, 27 },
104 	{ "aldo2", 0x10, (1 << 7), (1 << 7), (0 << 7),
105 	  0x29, 0x1f, 700000, 100000, 27 },
106 	{ "aldo3", 0x13, (1 << 7), (1 << 7), (0 << 7),
107 	  0x2a, 0x1f, 700000, 100000, 27 },
108 	{ "dldo1", 0x12, (1 << 3), (1 << 3), (0 << 3),
109 	  0x15, 0x1f, 700000, 100000, 27 },
110 	{ "dldo2", 0x12, (1 << 4), (1 << 4), (0 << 4),
111 	  0x16, 0x1f, 700000, 100000, 27 },
112 	{ "dldo3", 0x12, (1 << 5), (1 << 5), (0 << 5),
113 	  0x17, 0x1f, 700000, 100000, 27 },
114 	{ "dldo4", 0x12, (1 << 6), (1 << 6), (0 << 6),
115 	  0x18, 0x1f, 700000, 100000, 27 },
116 	{ "eldo1", 0x12, (1 << 0), (1 << 0), (0 << 0),
117 	  0x19, 0x1f, 700000, 100000, 27 },
118 	{ "eldo2", 0x12, (1 << 1), (1 << 1), (0 << 1),
119 	  0x1a, 0x1f, 700000, 100000, 27 },
120 	{ "eldo3", 0x12, (1 << 2), (1 << 2), (0 << 2),
121 	  0x1b, 0x1f, 700000, 100000, 27 },
122 	{ "ldo_io0", 0x90, 0x07, 0x03, 0x04,
123 	  0x91, 0x1f, 700000, 100000, 27 },
124 	{ "ldo_io1", 0x92, 0x07, 0x03, 0x04,
125 	  0x93, 0x1f, 700000, 100000, 27 },
126 	{ NULL }
127 };
128 
129 const struct axppmic_regdata axp313a_regdata[] = {
130 	/* dcdc1: 1.6-3.4V (100mV step) not supported */
131 	{ "dcdc1", 0x10, (1 << 0), (1 << 0), (0 << 0),
132 	  0x13, 0x7f, 500000, 10000, 71, 122000, 20000, 17 },
133 	{ "dcdc2", 0x10, (1 << 1), (1 << 1), (0 << 1),
134 	  0x14, 0x7f, 500000, 10000, 71, 122000, 20000, 17 },
135 	{ "dcdc3", 0x10, (1 << 2), (1 << 2), (0 << 2),
136 	  0x15, 0x7f, 500000, 10000, 71, 122000, 20000, 32 },
137 	{ "aldo1", 0x10, (1 << 3), (1 << 3), (0 << 3),
138 	  0x16, 0x1f, 500000, 100000, 31 },
139 	{ "dldo1", 0x10, (1 << 4), (1 << 4), (0 << 4),
140 	  0x17, 0x1f, 500000, 100000, 31 },
141 	{ NULL }
142 };
143 
144 const struct axppmic_regdata axp803_regdata[] = {
145 	{ "dcdc1", 0x10, (1 << 0), (1 << 0), (0 << 0),
146 	  0x20, 0x1f, 1600000, 100000, 19 },
147 	{ "dcdc2", 0x10, (1 << 1), (1 << 1), (0 << 1),
148 	  0x21, 0x7f, 500000, 10000, 71, 1220000, 20000, 5 },
149 	{ "dcdc3", 0x10, (1 << 2), (1 << 2), (0 << 2),
150 	  0x22, 0x7f, 500000, 10000, 71, 1220000, 20000, 5 },
151 	{ "dcdc4", 0x10, (1 << 3), (1 << 3), (0 << 3),
152 	  0x23, 0x7f, 500000, 10000, 71, 1220000, 20000, 5 },
153 	{ "dcdc5", 0x10, (1 << 4), (1 << 4), (0 << 4),
154 	  0x24, 0x7f, 800000, 10000, 33, 1140000, 20000, 36 },
155 	{ "dcdc6", 0x10, (1 << 5), (1 << 5), (0 << 5),
156 	  0x25, 0x7f, 600000, 10000, 51, 1120000, 20000, 21 },
157 	{ "dc1sw", 0x12, (1 << 7), (1 << 7), (0 << 7) },
158 	{ "aldo1", 0x13, (1 << 5), (1 << 5), (0 << 5),
159 	  0x28, 0x1f, 700000, 100000, 27 },
160 	{ "aldo2", 0x13, (1 << 6), (1 << 6), (0 << 6),
161 	  0x29, 0x1f, 700000, 100000, 27 },
162 	{ "aldo3", 0x13, (1 << 7), (1 << 7), (0 << 7),
163 	  0x2a, 0x1f, 700000, 100000, 27 },
164 	{ "dldo1", 0x12, (1 << 3), (1 << 3), (0 << 3),
165 	  0x15, 0x1f, 700000, 100000, 27 },
166 	{ "dldo2", 0x12, (1 << 4), (1 << 4), (0 << 4),
167 	  0x16, 0x1f, 700000, 100000, 27, 3400000, 200000, 5 },
168 	{ "dldo3", 0x12, (1 << 5), (1 << 5), (0 << 5),
169 	  0x17, 0x1f, 700000, 100000, 27 },
170 	{ "dldo4", 0x12, (1 << 6), (1 << 6), (0 << 6),
171 	  0x18, 0x1f, 700000, 100000, 27 },
172 	{ "eldo1", 0x12, (1 << 0), (1 << 0), (0 << 0),
173 	  0x19, 0x1f, 700000, 50000, 25 },
174 	{ "eldo2", 0x12, (1 << 1), (1 << 1), (0 << 1),
175 	  0x1a, 0x1f, 700000, 50000, 25 },
176 	{ "eldo3", 0x12, (1 << 2), (1 << 2), (0 << 2),
177 	  0x1b, 0x1f, 700000, 50000, 25 },
178 	{ "fldo1", 0x13, (1 << 2), (1 << 2), (0 << 2),
179 	  0x1c, 0x0f, 700000, 50000, 16 },
180 	{ "fldo2", 0x13, (1 << 3), (1 << 3), (0 << 3),
181 	  0x1d, 0x0f, 700000, 50000, 16 },
182 	{ "ldo-io0", 0x90, 0x07, 0x03, 0x04,
183 	  0x91, 0x1f, 700000, 100000, 27 },
184 	{ "ldo-io1", 0x92, 0x07, 0x03, 0x04,
185 	  0x93, 0x1f, 700000, 100000, 27 },
186 	{ NULL }
187 };
188 
189 const struct axppmic_regdata axp806_regdata[] = {
190 	{ "dcdca", 0x10, (1 << 0), (1 << 0), (0 << 0),
191 	  0x12, 0x7f, 600000, 10000, 51, 1120000, 20000, 21 },
192 	{ "dcdcb", 0x10, (1 << 1), (1 << 1), (0 << 1),
193 	  0x13, 0x1f, 1000000, 50000, 32 },
194 	{ "dcdcc", 0x10, (1 << 2), (1 << 2), (0 << 2),
195 	  0x14, 0x7f, 600000, 10000, 51, 1120000, 20000, 21 },
196 	{ "dcdcd", 0x10, (1 << 3), (1 << 3), (0 << 3),
197 	  0x15, 0x3f, 600000, 20000, 46, 1600000, 100000, 18 },
198 	{ "dcdce", 0x10, (1 << 4), (1 << 4), (0 << 4),
199 	  0x16, 0x1f, 1100000, 100000, 24 },
200 	{ "aldo1", 0x10, (1 << 5), (1 << 5), (0 << 5),
201 	  0x17, 0x1f, 700000, 100000, 27 },
202 	{ "aldo2", 0x10, (1 << 6), (1 << 6), (0 << 6),
203 	  0x18, 0x1f, 700000, 100000, 27 },
204 	{ "aldo3", 0x10, (1 << 7), (1 << 7), (0 << 7),
205 	  0x19, 0x1f, 700000, 100000, 27 },
206 	{ "bldo1", 0x11, (1 << 0), (1 << 0), (0 << 0),
207 	  0x20, 0x0f, 700000, 100000, 13 },
208 	{ "bldo2", 0x11, (1 << 1), (1 << 1), (0 << 1),
209 	  0x21, 0x0f, 700000, 100000, 13 },
210 	{ "bldo3", 0x11, (1 << 2), (1 << 2), (0 << 2),
211 	  0x22, 0x0f, 700000, 100000, 13 },
212 	{ "bldo4", 0x11, (1 << 3), (1 << 3), (0 << 3),
213 	  0x23, 0x0f, 700000, 100000, 13 },
214 	{ "cldo1", 0x11, (1 << 4), (1 << 4), (0 << 4),
215 	  0x24, 0x1f, 700000, 100000 , 27},
216 	{ "cldo2", 0x11, (1 << 5), (1 << 5), (0 << 5),
217 	  0x25, 0x1f, 700000, 100000, 28, 3600000, 200000, 4 },
218 	{ "cldo3", 0x11, (1 << 6), (1 << 6), (0 << 6),
219 	  0x26, 0x1f, 700000, 100000, 27 },
220 	{ "sw", 0x11, (1 << 7), (1 << 7), (0 << 7) },
221 	{ NULL }
222 };
223 
224 const struct axppmic_regdata axp809_regdata[] = {
225 	{ "dcdc1", 0x10, (1 << 1), (1 << 1), (0 << 1),
226 	  0x21, 0x1f, 1600000, 100000, 19 },
227 	{ "dcdc2", 0x10, (1 << 2), (1 << 2), (0 << 2),
228 	  0x22, 0x3f, 600000, 20000, 48 },
229 	{ "dcdc3", 0x10, (1 << 3), (1 << 3), (0 << 3),
230 	  0x23, 0x3f, 600000, 20000, 64 },
231 	{ "dcdc4", 0x10, (1 << 4), (1 << 4), (0 << 4),
232 	  0x24, 0x3f, 600000, 20000, 48, 1800000, 100000, 9 },
233 	{ "dcdc5", 0x10, (1 << 5), (1 << 5), (0 << 5),
234 	  0x25, 0x1f, 1000000, 50000, 32 },
235 	{ "dc5ldo", 0x10, (1 << 0), (1 << 0), (0 << 0),
236 	  0x1c, 0x07, 700000, 100000, 8 },
237 	{ "aldo1", 0x10, (1 << 6), (1 << 6), (0 << 6),
238 	  0x28, 0x1f, 700000, 100000, 27 },
239 	{ "aldo2", 0x10, (1 << 7), (1 << 7), (0 << 7),
240 	  0x29, 0x1f, 700000, 100000, 27 },
241 	{ "aldo3", 0x12, (1 << 5), (1 << 5), (0 << 5),
242 	  0x2a, 0x1f, 700000, 100000, 27 },
243 	{ "dldo1", 0x12, (1 << 3), (1 << 3), (0 << 3),
244 	  0x15, 0x1f, 700000, 100000, 27, 3400000, 200000, 5 },
245 	{ "dldo2", 0x12, (1 << 4), (1 << 4), (0 << 4),
246 	  0x16, 0x1f, 700000, 100000, 27 },
247 	{ "eldo1", 0x12, (1 << 0), (1 << 0), (0 << 0),
248 	  0x19, 0x1f, 700000, 100000, 27 },
249 	{ "eldo2", 0x12, (1 << 1), (1 << 1), (0 << 1),
250 	  0x1a, 0x1f, 700000, 100000, 27 },
251 	{ "eldo3", 0x12, (1 << 2), (1 << 2), (0 << 2),
252 	  0x1b, 0x1f, 700000, 100000, 27 },
253 	{ "ldo_io0", 0x90, 0x07, 0x03, 0x04,
254 	  0x91, 0x1f, 700000, 100000, 27 },
255 	{ "ldo_io1", 0x92, 0x07, 0x03, 0x04,
256 	  0x93, 0x1f, 700000, 100000, 27 },
257 	{ NULL }
258 };
259 
260 const struct axppmic_regdata axp15060_regdata[] = {
261 	{ "dcdc1", 0x10, (1 << 0), (1 << 0), (0 << 0),
262 	  0x13, 0x1f, 15000000, 100000, 20 },
263 	{ "dcdc2", 0x10, (1 << 1), (1 << 1), (0 << 1),
264 	  0x14, 0x7f, 500000, 10000, 71, 1220000, 20000, 17 },
265 	{ "dcdc3", 0x10, (1 << 2), (1 << 2), (0 << 2),
266 	  0x15, 0x7f, 500000, 10000, 71, 1220000, 20000, 17 },
267 	{ "dcdc4", 0x10, (1 << 3), (1 << 3), (0 << 3),
268 	  0x16, 0x7f, 500000, 10000, 71, 1220000, 20000, 17 },
269 	{ "dcdc5", 0x10, (1 << 4), (1 << 4), (0 << 4),
270 	  0x17, 0x7f, 800000, 10000, 33, 1140000, 20000, 36 },
271 	{ "dcdc6", 0x10, (1 << 5), (1 << 5), (0 << 5),
272 	  0x18, 0x1f, 500000, 100000, 30 },
273 	{ "aldo1", 0x11, (1 << 0), (1 << 0), (0 << 0),
274 	  0x19, 0x1f, 700000, 100000, 27 },
275 	{ "aldo2", 0x11, (1 << 1), (1 << 1), (0 << 1),
276 	  0x20, 0x1f, 700000, 100000, 27 },
277 	{ "aldo3", 0x11, (1 << 2), (1 << 2), (0 << 2),
278 	  0x21, 0x1f, 700000, 100000, 27 },
279 	{ "aldo4", 0x11, (1 << 3), (1 << 3), (0 << 3),
280 	  0x22, 0x1f, 700000, 100000, 27 },
281 	{ "aldo5", 0x11, (1 << 4), (1 << 4), (0 << 4),
282 	  0x23, 0x1f, 700000, 100000, 27 },
283 	{ "bldo1", 0x11, (1 << 5), (1 << 5), (0 << 5),
284 	  0x24, 0x1f, 700000, 100000, 27 },
285 	{ "bldo2", 0x11, (1 << 6), (1 << 6), (0 << 6),
286 	  0x25, 0x1f, 700000, 100000, 27 },
287 	{ "bldo3", 0x11, (1 << 7), (1 << 7), (0 << 7),
288 	  0x26, 0x1f, 700000, 100000, 27 },
289 	{ "bldo4", 0x12, (1 << 0), (1 << 0), (0 << 0),
290 	  0x27, 0x1f, 700000, 100000, 27 },
291 	{ "bldo5", 0x12, (1 << 1), (1 << 1), (0 << 1),
292 	  0x28, 0x1f, 700000, 100000, 27 },
293 	{ "cldo1", 0x12, (1 << 2), (1 << 2), (0 << 2),
294 	  0x29, 0x1f, 700000, 100000, 27 },
295 	{ "cldo2", 0x12, (1 << 3), (1 << 3), (0 << 3),
296 	  0x2a, 0x1f, 700000, 100000, 27 },
297 	{ "cldo3", 0x12, (1 << 4), (1 << 4), (0 << 4),
298 	  0x2b, 0x1f, 700000, 100000, 27 },
299 	{ "cldo4", 0x12, (1 << 5), (1 << 5), (0 << 5),
300 	  0x2d, 0x3f, 700000, 100000, 36 },
301 	{ "cpusldo", 0x12, (1 << 6), (1 << 6), (0 << 6),
302 	  0x2e, 0x0f, 700000, 50000, 15 },
303 	{ "sw", 0x12, (1 << 7), (1 << 7), (0 << 7) },
304 	{ NULL }
305 };
306 
307 /* Sensors for AXP209 and AXP221/AXP809. */
308 
309 #define AXPPMIC_NSENSORS 12
310 
311 struct axppmic_sensdata {
312 	const char *name;
313 	enum sensor_type type;
314 	uint8_t reg;
315 	uint64_t base, delta;
316 };
317 
318 const struct axppmic_sensdata axp209_sensdata[] = {
319 	{ "ACIN", SENSOR_INDICATOR, 0x00, (1 << 7), (1 << 6) },
320 	{ "VBUS", SENSOR_INDICATOR, 0x00, (1 << 5), (1 << 4) },
321 	{ "ACIN", SENSOR_VOLTS_DC, 0x56, 0, 1700 },
322 	{ "ACIN", SENSOR_AMPS, 0x58, 0, 625 },
323 	{ "VBUS", SENSOR_VOLTS_DC, 0x5a, 0, 1700 },
324 	{ "VBUS", SENSOR_AMPS, 0x5c, 0, 375 },
325 	{ "", SENSOR_TEMP, 0x5e, 128450000, 100000 },
326 	{ "APS", SENSOR_VOLTS_DC, 0x7e, 0, 1400 },
327 	{ NULL }
328 };
329 
330 const struct axppmic_sensdata axp221_sensdata[] = {
331 	{ "ACIN", SENSOR_INDICATOR, 0x00, (1 << 7), (1 << 6) },
332 	{ "VBUS", SENSOR_INDICATOR, 0x00, (1 << 5), (1 << 4) },
333 	{ "", SENSOR_TEMP, 0x56, 5450000, 105861 },
334 	{ NULL }
335 };
336 
337 const struct axppmic_sensdata axp803_sensdata[] = {
338 	{ "ACIN", SENSOR_INDICATOR, 0x00, (1 << 7), (1 << 6) },
339 	{ "VBUS", SENSOR_INDICATOR, 0x00, (1 << 5), (1 << 4) },
340 	{ "", SENSOR_TEMP, 0x56, 5450000, 106250 },
341 	{ NULL }
342 };
343 
344 const struct axppmic_sensdata axp803_battery_sensdata[] = {
345 	{ "ACIN", SENSOR_INDICATOR, 0x00, (1 << 7), (1 << 6) },
346 	{ "VBUS", SENSOR_INDICATOR, 0x00, (1 << 5), (1 << 4) },
347 	{ "", SENSOR_TEMP, 0x56, 5450000, 106250 },
348 	{ "battery present", SENSOR_INDICATOR, 0x01, (1 << 5), (1 << 4) },
349 	{ "battery charging", SENSOR_INDICATOR, 0x01, (1 << 6), (1 << 6) },
350 	{ "battery percent", SENSOR_PERCENT, 0xb9, 0x7f, (1 << 7) },
351 	{ "battery voltage", SENSOR_VOLTS_DC, 0x78, 0x00, 1100 },
352 	{ "battery charging current", SENSOR_AMPS, 0x7a, 0x00, 1000 },
353 	{ "battery discharging current", SENSOR_AMPS, 0x7c, 0x00, 1000 },
354 	{ "battery maximum capacity", SENSOR_AMPHOUR, 0xe0, 0x00, 1456 },
355 	{ "battery current capacity", SENSOR_AMPHOUR, 0xe2, 0x00, 1456 },
356 	{ NULL }
357 };
358 
359 struct axppmic_device {
360 	const char *name;
361 	const char *chip;
362 	const struct axppmic_regdata *regdata;
363 	const struct axppmic_sensdata *sensdata;
364 };
365 
366 const struct axppmic_device axppmic_devices[] = {
367 	{ "x-powers,axp152", "AXP152" },
368 	{ "x-powers,axp209", "AXP209", axp209_regdata, axp209_sensdata },
369 	{ "x-powers,axp221", "AXP221", axp221_regdata, axp221_sensdata },
370 	{ "x-powers,axp223", "AXP223", axp221_regdata, axp221_sensdata },
371 	{ "x-powers,axp305", "AXP305", axp806_regdata },
372 	{ "x-powers,axp313a", "AXP313A", axp313a_regdata },
373 	{ "x-powers,axp803", "AXP803", axp803_regdata, axp803_sensdata },
374 	{ "x-powers,axp805", "AXP805", axp806_regdata },
375 	{ "x-powers,axp806", "AXP806", axp806_regdata },
376 	{ "x-powers,axp809", "AXP809", axp809_regdata, axp221_sensdata },
377 	{ "x-powers,axp15060", "AXP15060", axp15060_regdata },
378 };
379 
380 const struct axppmic_device *
381 axppmic_lookup(const char *name)
382 {
383 	int i;
384 
385 	for (i = 0; i < nitems(axppmic_devices); i++) {
386 		if (strcmp(name, axppmic_devices[i].name) == 0)
387 			return &axppmic_devices[i];
388 	}
389 
390 	return NULL;
391 }
392 
393 struct axppmic_softc {
394 	struct device	sc_dev;
395 	void		*sc_cookie;
396 	uint16_t 	sc_addr;
397 	const char	*sc_name;
398 
399 	uint8_t		(*sc_read)(struct axppmic_softc *, uint8_t);
400 	void		(*sc_write)(struct axppmic_softc *, uint8_t, uint8_t);
401 	const struct axppmic_regdata *sc_regdata;
402 	const struct axppmic_sensdata *sc_sensdata;
403 
404 	struct ksensor	sc_sensor[AXPPMIC_NSENSORS];
405 	struct ksensordev sc_sensordev;
406 
407 	uint8_t 	sc_warn;
408 	uint8_t		sc_crit;
409 };
410 
411 static inline uint8_t
412 axppmic_read_reg(struct axppmic_softc *sc, uint8_t reg)
413 {
414 	return sc->sc_read(sc, reg);
415 }
416 
417 static inline void
418 axppmic_write_reg(struct axppmic_softc *sc, uint8_t reg, uint8_t value)
419 {
420 	sc->sc_write(sc, reg, value);
421 }
422 
423 void	axppmic_attach_common(struct axppmic_softc *, const char *, int);
424 int	axppmic_activate(struct device *, int);
425 
426 /* I2C interface */
427 
428 int	axppmic_i2c_match(struct device *, void *, void *);
429 void	axppmic_i2c_attach(struct device *, struct device *, void *);
430 
431 const struct cfattach axppmic_ca = {
432 	sizeof(struct axppmic_softc), axppmic_i2c_match, axppmic_i2c_attach,
433 	NULL, axppmic_activate
434 };
435 
436 struct cfdriver axppmic_cd = {
437 	NULL, "axppmic", DV_DULL
438 };
439 
440 uint8_t	axppmic_i2c_read(struct axppmic_softc *, uint8_t);
441 void	axppmic_i2c_write(struct axppmic_softc *, uint8_t, uint8_t);
442 
443 int
444 axppmic_i2c_match(struct device *parent, void *match, void *aux)
445 {
446 	struct i2c_attach_args *ia = aux;
447 
448 	if (axppmic_lookup(ia->ia_name))
449 		return 1;
450 	return 0;
451 }
452 
453 void
454 axppmic_i2c_attach(struct device *parent, struct device *self, void *aux)
455 {
456 	struct axppmic_softc *sc = (struct axppmic_softc *)self;
457 	struct i2c_attach_args *ia = aux;
458 	int node = *(int *)ia->ia_cookie;
459 
460 	sc->sc_cookie = ia->ia_tag;
461 	sc->sc_addr = ia->ia_addr;
462 	sc->sc_read = axppmic_i2c_read;
463 	sc->sc_write = axppmic_i2c_write;
464 
465 	axppmic_attach_common(sc, ia->ia_name, node);
466 }
467 
468 uint8_t
469 axppmic_i2c_read(struct axppmic_softc *sc, uint8_t reg)
470 {
471 	i2c_tag_t tag = sc->sc_cookie;
472 	int flags = cold ? I2C_F_POLL : 0;
473 	int error;
474 	uint8_t value;
475 
476 	iic_acquire_bus(tag, flags);
477 	error = iic_smbus_read_byte(tag, sc->sc_addr, reg, &value, flags);
478 	iic_release_bus(tag, flags);
479 	if (error) {
480 		printf("%s: SMBus read byte from 0x%02x failed\n",
481 		    sc->sc_dev.dv_xname, reg);
482 		return 0xff;
483 	}
484 
485 	return value;
486 }
487 
488 void
489 axppmic_i2c_write(struct axppmic_softc *sc, uint8_t reg, uint8_t value)
490 {
491 	i2c_tag_t tag = sc->sc_cookie;
492 	int flags = cold ? I2C_F_POLL : 0;
493 	int error;
494 
495 	iic_acquire_bus(tag, flags);
496 	error = iic_smbus_write_byte(tag, sc->sc_addr, reg, value, flags);
497 	iic_release_bus(tag, flags);
498 	if (error)
499 		printf("%s: SMBus write byte to 0x%02x failed\n",
500 		    sc->sc_dev.dv_xname, reg);
501 }
502 
503 /* RSB interface */
504 
505 #include "sxirsb.h"
506 
507 #if NSXIRSB > 0
508 
509 int	axppmic_rsb_match(struct device *, void *, void *);
510 void	axppmic_rsb_attach(struct device *, struct device *, void *);
511 
512 const struct cfattach axppmic_rsb_ca = {
513 	sizeof(struct axppmic_softc), axppmic_rsb_match, axppmic_rsb_attach,
514 	NULL, axppmic_activate
515 };
516 
517 struct cfdriver axppmic_rsb_cd = {
518 	NULL, "axppmic", DV_DULL
519 };
520 
521 uint8_t	axppmic_rsb_read(struct axppmic_softc *, uint8_t);
522 void	axppmic_rsb_write(struct axppmic_softc *, uint8_t, uint8_t);
523 
524 int
525 axppmic_rsb_match(struct device *parent, void *match, void *aux)
526 {
527 	struct rsb_attach_args *ra = aux;
528 
529 	if (axppmic_lookup(ra->ra_name))
530 		return 1;
531 	return 0;
532 }
533 
534 void
535 axppmic_rsb_attach(struct device *parent, struct device *self, void *aux)
536 {
537 	struct axppmic_softc *sc = (struct axppmic_softc *)self;
538 	struct rsb_attach_args *ra = aux;
539 
540 	sc->sc_cookie = ra->ra_cookie;
541 	sc->sc_addr = ra->ra_rta;
542 	sc->sc_read = axppmic_rsb_read;
543 	sc->sc_write = axppmic_rsb_write;
544 
545 	axppmic_attach_common(sc, ra->ra_name, ra->ra_node);
546 }
547 
548 uint8_t
549 axppmic_rsb_read(struct axppmic_softc *sc, uint8_t reg)
550 {
551 	return rsb_read_1(sc->sc_cookie, sc->sc_addr, reg);
552 }
553 
554 void
555 axppmic_rsb_write(struct axppmic_softc *sc, uint8_t reg, uint8_t value)
556 {
557 	rsb_write_1(sc->sc_cookie, sc->sc_addr, reg, value);
558 }
559 
560 #endif
561 
562 /* Common code */
563 
564 void	axppmic_attach_node(struct axppmic_softc *, int);
565 void	axppmic_attach_regulators(struct axppmic_softc *, int);
566 void	axppmic_attach_sensors(struct axppmic_softc *);
567 
568 struct axppmic_softc *axppmic_sc;
569 void	axp209_powerdown(void);
570 
571 void
572 axppmic_attach_common(struct axppmic_softc *sc, const char *name, int node)
573 {
574 	const struct axppmic_device *device;
575 	int child;
576 
577 	device = axppmic_lookup(name);
578 	printf(": %s\n", device->chip);
579 
580 	sc->sc_name = device->name;
581 	sc->sc_regdata = device->regdata;
582 	sc->sc_sensdata = device->sensdata;
583 
584 	/* Switch AXP806 into master or slave mode. */
585 	if (strcmp(name, "x-powers,axp305") == 0 ||
586 	    strcmp(name, "x-powers,axp805") == 0 ||
587 	    strcmp(name, "x-powers,axp806") == 0) {
588 	    if (OF_getproplen(node, "x-powers,master-mode") == 0 ||
589 	        OF_getproplen(node, "x-powers,self-working-mode") == 0) {
590 			axppmic_write_reg(sc, AXP806_REG_ADDR_EXT,
591 			    AXP806_REG_ADDR_EXT_MASTER_MODE);
592 		} else {
593 			axppmic_write_reg(sc, AXP806_REG_ADDR_EXT,
594 			    AXP806_REG_ADDR_EXT_SLAVE_MODE);
595 		}
596 	}
597 
598 	/* Enable data collection on AXP209. */
599 	if (strcmp(name, "x-powers,axp209") == 0) {
600 		uint8_t reg;
601 
602 		/* Turn on sampling of ACIN and VBUS voltage and current. */
603 		reg = axppmic_read_reg(sc, AXP209_ADC_EN1);
604 		reg |= AXP209_ADC_EN1_ACIN;
605 		reg |= AXP209_ADC_EN1_VBUS;
606 		axppmic_write_reg(sc, AXP209_ADC_EN1, reg);
607 	}
608 
609 	/* Read battery warning levels on AXP803. */
610 	if (strcmp(name, "x-powers,axp803") == 0) {
611 		uint8_t value;
612 
613 		value = axppmic_read_reg(sc, AXP803_BAT_CAP_WARN);
614 		sc->sc_warn = ((value & AXP803_BAT_CAP_WARN_LV1) >> 4);
615 		sc->sc_warn += AXP803_BAT_CAP_WARN_LV1BASE;
616 		sc->sc_crit = (value & AXP803_BAT_CAP_WARN_LV2);
617 	}
618 
619 	for (child = OF_child(node); child; child = OF_peer(child))
620 		axppmic_attach_node(sc, child);
621 
622 	if (sc->sc_regdata)
623 		axppmic_attach_regulators(sc, node);
624 
625 	if (sc->sc_sensdata)
626 		axppmic_attach_sensors(sc);
627 
628 	/* Disable all interrupts on AXP803. */
629 	if (strcmp(name, "x-powers,axp803") == 0) {
630 		axppmic_write_reg(sc, AXP803_IRQ1_EN, 0);
631 		axppmic_write_reg(sc, AXP803_IRQ2_EN, 0);
632 		axppmic_write_reg(sc, AXP803_IRQ3_EN, 0);
633 		axppmic_write_reg(sc, AXP803_IRQ4_EN, 0);
634 		axppmic_write_reg(sc, AXP803_IRQ5_EN, 0);
635 		axppmic_write_reg(sc, AXP803_IRQ6_EN, 0);
636 	}
637 
638 #ifdef __armv7__
639 	if (strcmp(name, "x-powers,axp152") == 0 ||
640 	    strcmp(name, "x-powers,axp209") == 0) {
641 		axppmic_sc = sc;
642 		powerdownfn = axp209_powerdown;
643 	}
644 #endif
645 
646 #ifdef SUSPEND
647 	/* AXP803 can wake us up. */
648 	if (strcmp(name, "x-powers,axp803") == 0)
649 		device_register_wakeup(&sc->sc_dev);
650 #endif
651 }
652 
653 void
654 axppmic_attach_node(struct axppmic_softc *sc, int node)
655 {
656 	char status[32];
657 
658 	if (OF_getprop(node, "status", status, sizeof(status)) > 0 &&
659 	    strcmp(status, "disabled") == 0)
660 		return;
661 
662 	if (OF_is_compatible(node, "x-powers,axp803-battery-power-supply"))
663 		sc->sc_sensdata = axp803_battery_sensdata;
664 }
665 
666 int
667 axppmic_activate(struct device *self, int act)
668 {
669 	struct axppmic_softc *sc = (struct axppmic_softc *)self;
670 
671 	switch (act) {
672 	case DVACT_SUSPEND:
673 		if (strcmp(sc->sc_name, "x-powers,axp803") == 0) {
674 			/* Enable interrupt for short power button press. */
675 			axppmic_write_reg(sc, AXP803_IRQ5_STAT,
676 			    AXP803_IRQ5_STAT_PEK_SHORT);
677 			axppmic_write_reg(sc, AXP803_IRQ5_EN,
678 			    AXP803_IRQ5_EN_PEK_SHORT);
679 		}
680 		break;
681 	case DVACT_RESUME:
682 		if (strcmp(sc->sc_name, "x-powers,axp803") == 0) {
683 			/* Disable interrupt for short power button press. */
684 			axppmic_write_reg(sc, AXP803_IRQ5_EN, 0);
685 		}
686 		break;
687 	}
688 
689 	return 0;
690 }
691 
692 /* Regulators */
693 
694 struct axppmic_regulator {
695 	struct axppmic_softc *ar_sc;
696 
697 	uint8_t ar_ereg, ar_emask;
698 	uint8_t ar_eval, ar_dval;
699 
700 	uint8_t ar_vreg, ar_vmask;
701 	uint32_t ar_base, ar_delta, ar_nsteps;
702 	uint32_t ar_base2, ar_delta2, ar_nsteps2;
703 
704 	struct regulator_device ar_rd;
705 };
706 
707 void	axppmic_attach_regulator(struct axppmic_softc *, int);
708 uint32_t axppmic_get_voltage(void *);
709 int	axppmic_set_voltage(void *, uint32_t);
710 int	axppmic_enable(void *, int);
711 
712 void
713 axppmic_attach_regulators(struct axppmic_softc *sc, int node)
714 {
715 	node = OF_getnodebyname(node, "regulators");
716 	if (node == 0)
717 		return;
718 
719 	for (node = OF_child(node); node; node = OF_peer(node))
720 		axppmic_attach_regulator(sc, node);
721 }
722 
723 void
724 axppmic_attach_regulator(struct axppmic_softc *sc, int node)
725 {
726 	struct axppmic_regulator *ar;
727 	char name[32];
728 	int i;
729 
730 	name[0] = 0;
731 	OF_getprop(node, "name", name, sizeof(name));
732 	name[sizeof(name) - 1] = 0;
733 	for (i = 0; sc->sc_regdata[i].name; i++) {
734 		if (strcmp(sc->sc_regdata[i].name, name) == 0)
735 			break;
736 	}
737 	if (sc->sc_regdata[i].name == NULL)
738 		return;
739 
740 	ar = malloc(sizeof(*ar), M_DEVBUF, M_WAITOK | M_ZERO);
741 	ar->ar_sc = sc;
742 
743 	ar->ar_ereg = sc->sc_regdata[i].ereg;
744 	ar->ar_emask = sc->sc_regdata[i].emask;
745 	ar->ar_eval = sc->sc_regdata[i].eval;
746 	ar->ar_dval = sc->sc_regdata[i].dval;
747 	ar->ar_vreg = sc->sc_regdata[i].vreg;
748 	ar->ar_vmask = sc->sc_regdata[i].vmask;
749 	ar->ar_base = sc->sc_regdata[i].base;
750 	ar->ar_delta = sc->sc_regdata[i].delta;
751 	ar->ar_nsteps = sc->sc_regdata[i].nsteps;
752 	ar->ar_base2 = sc->sc_regdata[i].base2;
753 	ar->ar_delta2 = sc->sc_regdata[i].delta2;
754 	ar->ar_nsteps2 = sc->sc_regdata[i].nsteps2;
755 
756 	ar->ar_rd.rd_node = node;
757 	ar->ar_rd.rd_cookie = ar;
758 	ar->ar_rd.rd_get_voltage = axppmic_get_voltage;
759 	ar->ar_rd.rd_set_voltage = axppmic_set_voltage;
760 	ar->ar_rd.rd_enable = axppmic_enable;
761 	regulator_register(&ar->ar_rd);
762 }
763 
764 uint32_t
765 axppmic_get_voltage(void *cookie)
766 {
767 	struct axppmic_regulator *ar = cookie;
768 	uint32_t voltage;
769 	uint8_t value;
770 
771 	value = axppmic_read_reg(ar->ar_sc, ar->ar_vreg);
772 	value &= ar->ar_vmask;
773 	if (ar->ar_base2 > 0 && value >= ar->ar_nsteps) {
774 		voltage =
775 		     ar->ar_base2 + (value - ar->ar_nsteps) * ar->ar_delta2;
776 	} else {
777 		voltage = ar->ar_base + value * ar->ar_delta;
778 	}
779 	return voltage;
780 }
781 
782 int
783 axppmic_set_voltage(void *cookie, uint32_t voltage)
784 {
785 	struct axppmic_regulator *ar = cookie;
786 	uint32_t value, reg;
787 
788 	if (voltage < ar->ar_base)
789 		return EINVAL;
790 	if (ar->ar_base2 > 0 && voltage >= ar->ar_base2) {
791 		value = (voltage - ar->ar_base2) / ar->ar_delta2;
792 		if (value >= ar->ar_nsteps2)
793 			return EINVAL;
794 		value += ar->ar_nsteps;
795 	} else {
796 		value = (voltage - ar->ar_base) / ar->ar_delta;
797 		if (value >= ar->ar_nsteps)
798 			return EINVAL;
799 	}
800 	if (value > ar->ar_vmask)
801 		return EINVAL;
802 
803 	reg = axppmic_read_reg(ar->ar_sc, ar->ar_vreg);
804 	axppmic_write_reg(ar->ar_sc, ar->ar_vreg,
805 	    (reg & ~ar->ar_vmask) | (value & ar->ar_vmask));
806 	return 0;
807 }
808 
809 int
810 axppmic_enable(void *cookie, int on)
811 {
812 	struct axppmic_regulator *ar = cookie;
813 	uint8_t reg;
814 
815 	reg = axppmic_read_reg(ar->ar_sc, ar->ar_ereg);
816 	reg &= ~ar->ar_emask;
817 	if (on)
818 		reg |= ar->ar_eval;
819 	else
820 		reg |= ar->ar_dval;
821 	axppmic_write_reg(ar->ar_sc, ar->ar_ereg, reg);
822 	return 0;
823 }
824 
825 /* Sensors */
826 
827 void	axppmic_update_sensors(void *);
828 void	axppmic_update_indicator(struct axppmic_softc *, int);
829 void	axppmic_update_percent(struct axppmic_softc *, int);
830 void	axppmic_update_amphour(struct axppmic_softc *, int);
831 void	axppmic_update_sensor(struct axppmic_softc *, int);
832 
833 void
834 axppmic_attach_sensors(struct axppmic_softc *sc)
835 {
836 	int i;
837 
838 	for (i = 0; sc->sc_sensdata[i].name; i++) {
839 		KASSERT(i < AXPPMIC_NSENSORS);
840 
841 		sc->sc_sensor[i].type = sc->sc_sensdata[i].type;
842 		strlcpy(sc->sc_sensor[i].desc, sc->sc_sensdata[i].name,
843 		    sizeof(sc->sc_sensor[i].desc));
844 		sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
845 	}
846 
847 	axppmic_update_sensors(sc);
848 	if (sensor_task_register(sc, axppmic_update_sensors, 5) == NULL) {
849 		printf(", unable to register update task\n");
850 		return;
851 	}
852 
853 	strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
854 	    sizeof(sc->sc_sensordev.xname));
855 	sensordev_install(&sc->sc_sensordev);
856 }
857 
858 void
859 axppmic_update_sensors(void *arg)
860 {
861 	struct axppmic_softc *sc = arg;
862 	int i;
863 
864 	for (i = 0; sc->sc_sensdata[i].name; i++) {
865 		switch (sc->sc_sensdata[i].type) {
866 		case SENSOR_INDICATOR:
867 			axppmic_update_indicator(sc, i);
868 			break;
869 		case SENSOR_PERCENT:
870 			axppmic_update_percent(sc, i);
871 			break;
872 		case SENSOR_AMPHOUR:
873 			axppmic_update_amphour(sc, i);
874 			break;
875 		default:
876 			axppmic_update_sensor(sc, i);
877 			break;
878 		}
879 	}
880 }
881 
882 void
883 axppmic_update_indicator(struct axppmic_softc *sc, int i)
884 {
885 	uint8_t reg = sc->sc_sensdata[i].reg;
886 	uint8_t mask = sc->sc_sensdata[i].base;
887 	uint8_t mask_ok = sc->sc_sensdata[i].delta;
888 	uint8_t value;
889 
890 	value = axppmic_read_reg(sc, reg);
891 	sc->sc_sensor[i].value = (value & mask) ? 1 : 0;
892 	if (value & mask) {
893 		sc->sc_sensor[i].status =
894 		    (value & mask_ok) ? SENSOR_S_OK : SENSOR_S_WARN;
895 	} else {
896 		sc->sc_sensor[i].status = SENSOR_S_UNSPEC;
897 	}
898 }
899 
900 void
901 axppmic_update_percent(struct axppmic_softc *sc, int i)
902 {
903 	uint8_t reg = sc->sc_sensdata[i].reg;
904 	uint8_t mask = sc->sc_sensdata[i].base;
905 	uint8_t mask_ok = sc->sc_sensdata[i].delta;
906 	uint8_t value;
907 
908 	value = axppmic_read_reg(sc, reg);
909 	sc->sc_sensor[i].value = (value & mask) * 1000;
910 
911 	if (value & mask_ok) {
912 		if ((value & mask) <= sc->sc_crit)
913 			sc->sc_sensor[i].status = SENSOR_S_CRIT;
914 		else if ((value & mask) <= sc->sc_warn)
915 			sc->sc_sensor[i].status = SENSOR_S_WARN;
916 		else
917 			sc->sc_sensor[i].status = SENSOR_S_OK;
918 	} else {
919 		sc->sc_sensor[i].status = SENSOR_S_UNSPEC;
920 	}
921 }
922 
923 void
924 axppmic_update_amphour(struct axppmic_softc *sc, int i)
925 {
926 	uint8_t reg = sc->sc_sensdata[i].reg;
927 	uint64_t base = sc->sc_sensdata[i].base;
928 	uint64_t delta = sc->sc_sensdata[i].delta;
929 	uint16_t value;
930 
931 	value = axppmic_read_reg(sc, reg);
932 	sc->sc_sensor[i].status = (value & 0x80) ? SENSOR_S_OK : SENSOR_S_WARN;
933 	value = ((value & 0x7f) << 8) | axppmic_read_reg(sc, reg + 1);
934 	sc->sc_sensor[i].value = base + value * delta;
935 }
936 
937 void
938 axppmic_update_sensor(struct axppmic_softc *sc, int i)
939 {
940 	uint8_t reg = sc->sc_sensdata[i].reg;
941 	uint64_t base = sc->sc_sensdata[i].base;
942 	uint64_t delta = sc->sc_sensdata[i].delta;
943 	uint16_t value;
944 
945 	value = axppmic_read_reg(sc, reg);
946 	value = (value << 4) | axppmic_read_reg(sc, reg + 1);
947 	sc->sc_sensor[i].value = base + value * delta;
948 }
949 
950 void
951 axp209_powerdown(void)
952 {
953 	axppmic_write_reg(axppmic_sc, AXP209_SDR, AXP209_SDR_SHUTDOWN);
954 }
955