tps65217pmic.c revision 1.9.4.2 1 1.9.4.2 yamt /* $NetBSD: tps65217pmic.c,v 1.9.4.2 2014/05/22 11:40:21 yamt Exp $ */
2 1.9.4.2 yamt
3 1.9.4.2 yamt /*-
4 1.9.4.2 yamt * Copyright (c) 2013 The NetBSD Foundation, Inc.
5 1.9.4.2 yamt * All rights reserved.
6 1.9.4.2 yamt *
7 1.9.4.2 yamt * This code is derived from software contributed to The NetBSD Foundation
8 1.9.4.2 yamt * by Radoslaw Kujawa.
9 1.9.4.2 yamt *
10 1.9.4.2 yamt * Redistribution and use in source and binary forms, with or without
11 1.9.4.2 yamt * modification, are permitted provided that the following conditions
12 1.9.4.2 yamt * are met:
13 1.9.4.2 yamt * 1. Redistributions of source code must retain the above copyright
14 1.9.4.2 yamt * notice, this list of conditions and the following disclaimer.
15 1.9.4.2 yamt * 2. Redistributions in binary form must reproduce the above copyright
16 1.9.4.2 yamt * notice, this list of conditions and the following disclaimer in the
17 1.9.4.2 yamt * documentation and/or other materials provided with the distribution.
18 1.9.4.2 yamt *
19 1.9.4.2 yamt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.9.4.2 yamt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.9.4.2 yamt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.9.4.2 yamt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.9.4.2 yamt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.9.4.2 yamt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.9.4.2 yamt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.9.4.2 yamt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.9.4.2 yamt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.9.4.2 yamt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.9.4.2 yamt * POSSIBILITY OF SUCH DAMAGE.
30 1.9.4.2 yamt */
31 1.9.4.2 yamt
32 1.9.4.2 yamt /*
33 1.9.4.2 yamt * Texas Instruments TPS65217 Power Management IC driver.
34 1.9.4.2 yamt * TODO: battery, sequencer, pgood
35 1.9.4.2 yamt */
36 1.9.4.2 yamt
37 1.9.4.2 yamt #include <sys/cdefs.h>
38 1.9.4.2 yamt __KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.9.4.2 2014/05/22 11:40:21 yamt Exp $");
39 1.9.4.2 yamt
40 1.9.4.2 yamt #include <sys/param.h>
41 1.9.4.2 yamt #include <sys/systm.h>
42 1.9.4.2 yamt #include <sys/device.h>
43 1.9.4.2 yamt #include <sys/kernel.h>
44 1.9.4.2 yamt #include <sys/mutex.h>
45 1.9.4.2 yamt
46 1.9.4.2 yamt #include <sys/bus.h>
47 1.9.4.2 yamt #include <dev/i2c/i2cvar.h>
48 1.9.4.2 yamt
49 1.9.4.2 yamt #include <dev/sysmon/sysmonvar.h>
50 1.9.4.2 yamt
51 1.9.4.2 yamt #include <dev/i2c/tps65217pmicreg.h>
52 1.9.4.2 yamt
53 1.9.4.2 yamt #define NTPS_REG 7
54 1.9.4.2 yamt #define SNUM_REGS NTPS_REG-1
55 1.9.4.2 yamt #define SNUM_USBSTATUS NTPS_REG
56 1.9.4.2 yamt #define SNUM_ACSTATUS NTPS_REG+1
57 1.9.4.2 yamt
58 1.9.4.2 yamt struct tps65217pmic_softc {
59 1.9.4.2 yamt device_t sc_dev;
60 1.9.4.2 yamt
61 1.9.4.2 yamt i2c_tag_t sc_tag;
62 1.9.4.2 yamt i2c_addr_t sc_addr;
63 1.9.4.2 yamt
64 1.9.4.2 yamt uint8_t sc_version;
65 1.9.4.2 yamt uint8_t sc_revision;
66 1.9.4.2 yamt
67 1.9.4.2 yamt kmutex_t sc_lock;
68 1.9.4.2 yamt
69 1.9.4.2 yamt bool sc_acstatus;
70 1.9.4.2 yamt bool sc_usbstatus;
71 1.9.4.2 yamt bool sc_acenabled;
72 1.9.4.2 yamt bool sc_usbenabled;
73 1.9.4.2 yamt
74 1.9.4.2 yamt callout_t sc_powerpollco;
75 1.9.4.2 yamt
76 1.9.4.2 yamt /* sysmon(4) stuff */
77 1.9.4.2 yamt struct sysmon_envsys *sc_sme;
78 1.9.4.2 yamt envsys_data_t sc_regsensor[NTPS_REG];
79 1.9.4.2 yamt envsys_data_t sc_acsensor;
80 1.9.4.2 yamt envsys_data_t sc_usbsensor;
81 1.9.4.2 yamt
82 1.9.4.2 yamt struct sysmon_pswitch sc_smpsw;
83 1.9.4.2 yamt };
84 1.9.4.2 yamt
85 1.9.4.2 yamt /* Voltage regulators */
86 1.9.4.2 yamt enum tps_reg_num {
87 1.9.4.2 yamt TPS65217PMIC_LDO1,
88 1.9.4.2 yamt TPS65217PMIC_LDO2,
89 1.9.4.2 yamt TPS65217PMIC_LDO3LS,
90 1.9.4.2 yamt TPS65217PMIC_LDO4LS,
91 1.9.4.2 yamt TPS65217PMIC_DCDC1,
92 1.9.4.2 yamt TPS65217PMIC_DCDC2,
93 1.9.4.2 yamt TPS65217PMIC_DCDC3
94 1.9.4.2 yamt };
95 1.9.4.2 yamt
96 1.9.4.2 yamt struct tps_reg_param {
97 1.9.4.2 yamt /* parameters configured statically */
98 1.9.4.2 yamt
99 1.9.4.2 yamt const char* name;
100 1.9.4.2 yamt uint16_t voltage_min; /* in mV */
101 1.9.4.2 yamt uint16_t voltage_max; /* in mV */
102 1.9.4.2 yamt const uint16_t *voltages; /* all possible voltage settings */
103 1.9.4.2 yamt uint8_t nvoltages; /* number of voltage settings */
104 1.9.4.2 yamt
105 1.9.4.2 yamt bool can_track; /* regulator can track U of other r. */
106 1.9.4.2 yamt struct tps_reg_param *tracked_reg; /* ptr to tracked regulator */
107 1.9.4.2 yamt bool can_xadj; /* voltage can be adjusted externally */
108 1.9.4.2 yamt bool can_ls; /* can be a load switch instead of r. */
109 1.9.4.2 yamt
110 1.9.4.2 yamt uint8_t defreg_num; /* DEF register */
111 1.9.4.2 yamt uint8_t enable_bit; /* position in ENABLE register */
112 1.9.4.2 yamt
113 1.9.4.2 yamt /*
114 1.9.4.2 yamt * Run-time parameters configured during attachment and later, these
115 1.9.4.2 yamt * probably should be split into separate struct that would be a part
116 1.9.4.2 yamt * of softc. But since we can have only one TPS chip, that should be
117 1.9.4.2 yamt * okay for now.
118 1.9.4.2 yamt */
119 1.9.4.2 yamt
120 1.9.4.2 yamt bool is_enabled; /* regulator is enabled */
121 1.9.4.2 yamt bool is_pg; /* regulator is "power good" */
122 1.9.4.2 yamt bool is_tracking; /* voltage is tracking other reg. */
123 1.9.4.2 yamt bool is_ls; /* is a load switch */
124 1.9.4.2 yamt bool is_xadj; /* voltage is adjusted externally */
125 1.9.4.2 yamt
126 1.9.4.2 yamt uint16_t current_voltage; /* in mV */
127 1.9.4.2 yamt
128 1.9.4.2 yamt };
129 1.9.4.2 yamt
130 1.9.4.2 yamt static int tps65217pmic_match(device_t, cfdata_t, void *);
131 1.9.4.2 yamt static void tps65217pmic_attach(device_t, device_t, void *);
132 1.9.4.2 yamt
133 1.9.4.2 yamt static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *, uint8_t);
134 1.9.4.2 yamt static void tps65217pmic_reg_write(struct tps65217pmic_softc *, uint8_t,
135 1.9.4.2 yamt uint8_t);
136 1.9.4.2 yamt
137 1.9.4.2 yamt static void tps65217pmic_reg_refresh(struct tps65217pmic_softc *);
138 1.9.4.2 yamt
139 1.9.4.2 yamt static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t);
140 1.9.4.2 yamt static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t);
141 1.9.4.2 yamt
142 1.9.4.2 yamt static void tps65217pmic_regulator_read_config(struct tps65217pmic_softc *,
143 1.9.4.2 yamt struct tps_reg_param *);
144 1.9.4.2 yamt
145 1.9.4.2 yamt static void tps65217pmic_print_ppath(struct tps65217pmic_softc *);
146 1.9.4.2 yamt static void tps65217pmic_print_ldos(struct tps65217pmic_softc *);
147 1.9.4.2 yamt
148 1.9.4.2 yamt static void tps65217pmic_version(struct tps65217pmic_softc *);
149 1.9.4.2 yamt
150 1.9.4.2 yamt static void tps65217pmic_envsys_register(struct tps65217pmic_softc *);
151 1.9.4.2 yamt static void tps65217pmic_envsys_refresh(struct sysmon_envsys *, envsys_data_t *);
152 1.9.4.2 yamt
153 1.9.4.2 yamt static void tps65217pmic_power_monitor_init(struct tps65217pmic_softc *);
154 1.9.4.2 yamt static void tps65217pmic_power_monitor(void *);
155 1.9.4.2 yamt
156 1.9.4.2 yamt CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
157 1.9.4.2 yamt tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
158 1.9.4.2 yamt
159 1.9.4.2 yamt /* Possible settings of LDO1 in mV. */
160 1.9.4.2 yamt static const uint16_t ldo1voltages[] = { 1000, 1100, 1200, 1250, 1300, 1350,
161 1.9.4.2 yamt 1400, 1500, 1600, 1800, 2500, 2750, 2800, 3000, 3100, 3300 };
162 1.9.4.2 yamt /* Possible settings of LDO2, DCDC1, DCDC2, DCDC3 in mV. */
163 1.9.4.2 yamt static const uint16_t ldo2voltages[] = { 900, 925, 950, 975, 1000, 1025, 1050,
164 1.9.4.2 yamt 1075, 1100, 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, 1325, 1350,
165 1.9.4.2 yamt 1375, 1400, 1425, 1450, 1475, 1500, 1550, 1600, 1650, 1700, 1750, 1800,
166 1.9.4.2 yamt 1850, 1900, 1950, 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400,
167 1.9.4.2 yamt 2450, 2500, 2550, 2600, 2650, 2700, 2750, 2800, 2850, 2900, 3000, 3100,
168 1.9.4.2 yamt 3200, 3300, 3300, 3300, 3300, 3300, 3300, 3300, 3300 };
169 1.9.4.2 yamt /* Possible settings of LDO3, LDO4 in mV. */
170 1.9.4.2 yamt static const uint16_t ldo3voltages[] = { 1500, 1550, 1600, 1650, 1700, 1750,
171 1.9.4.2 yamt 1800, 1850, 1900, 2000, 2100, 2200, 2300, 2400, 2450, 2500, 2550, 2600,
172 1.9.4.2 yamt 2650, 2700, 2750, 2800, 2850, 2900,2950, 3000, 3050, 3100, 3150, 3200,
173 1.9.4.2 yamt 3250, 3300 };
174 1.9.4.2 yamt
175 1.9.4.2 yamt static struct tps_reg_param tps_regulators[] = {
176 1.9.4.2 yamt {
177 1.9.4.2 yamt .name = "LDO1",
178 1.9.4.2 yamt .voltage_min = 1000,
179 1.9.4.2 yamt .voltage_max = 3300,
180 1.9.4.2 yamt .voltages = ldo1voltages,
181 1.9.4.2 yamt .nvoltages = 16,
182 1.9.4.2 yamt .can_track = false,
183 1.9.4.2 yamt .tracked_reg = NULL,
184 1.9.4.2 yamt .can_xadj = false,
185 1.9.4.2 yamt .can_ls = false,
186 1.9.4.2 yamt .defreg_num = TPS65217PMIC_DEFLDO1,
187 1.9.4.2 yamt .enable_bit = TPS65217PMIC_ENABLE_LDO1
188 1.9.4.2 yamt },
189 1.9.4.2 yamt {
190 1.9.4.2 yamt .name = "LDO2",
191 1.9.4.2 yamt .voltage_min = 900,
192 1.9.4.2 yamt .voltage_max = 3300,
193 1.9.4.2 yamt .voltages = ldo2voltages,
194 1.9.4.2 yamt .nvoltages = 64,
195 1.9.4.2 yamt .can_track = true,
196 1.9.4.2 yamt .tracked_reg = &(tps_regulators[TPS65217PMIC_DCDC3]),
197 1.9.4.2 yamt .can_xadj = false,
198 1.9.4.2 yamt .can_ls = false,
199 1.9.4.2 yamt .defreg_num = TPS65217PMIC_DEFLDO2,
200 1.9.4.2 yamt .enable_bit = TPS65217PMIC_ENABLE_LDO2
201 1.9.4.2 yamt },
202 1.9.4.2 yamt {
203 1.9.4.2 yamt .name = "LDO3",
204 1.9.4.2 yamt .voltage_min = 1500,
205 1.9.4.2 yamt .voltage_max = 3300,
206 1.9.4.2 yamt .voltages = ldo3voltages,
207 1.9.4.2 yamt .nvoltages = 32,
208 1.9.4.2 yamt .can_track = false,
209 1.9.4.2 yamt .tracked_reg = NULL,
210 1.9.4.2 yamt .can_xadj = false,
211 1.9.4.2 yamt .can_ls = true,
212 1.9.4.2 yamt .defreg_num = TPS65217PMIC_DEFLDO3,
213 1.9.4.2 yamt .enable_bit = TPS65217PMIC_ENABLE_LDO3
214 1.9.4.2 yamt },
215 1.9.4.2 yamt {
216 1.9.4.2 yamt .name = "LDO4",
217 1.9.4.2 yamt .voltage_min = 1500,
218 1.9.4.2 yamt .voltage_max = 3300,
219 1.9.4.2 yamt .voltages = ldo3voltages,
220 1.9.4.2 yamt .nvoltages = 32,
221 1.9.4.2 yamt .can_track = false,
222 1.9.4.2 yamt .tracked_reg = NULL,
223 1.9.4.2 yamt .can_xadj = false,
224 1.9.4.2 yamt .can_ls = true,
225 1.9.4.2 yamt .defreg_num = TPS65217PMIC_DEFLDO4,
226 1.9.4.2 yamt .enable_bit = TPS65217PMIC_ENABLE_LDO4
227 1.9.4.2 yamt },
228 1.9.4.2 yamt {
229 1.9.4.2 yamt .name = "DCDC1",
230 1.9.4.2 yamt .voltage_min = 900,
231 1.9.4.2 yamt .voltage_max = 3300,
232 1.9.4.2 yamt .voltages = ldo2voltages,
233 1.9.4.2 yamt .nvoltages = 64,
234 1.9.4.2 yamt .can_track = false,
235 1.9.4.2 yamt .tracked_reg = NULL,
236 1.9.4.2 yamt .can_xadj = true,
237 1.9.4.2 yamt .can_ls = false,
238 1.9.4.2 yamt .defreg_num = TPS65217PMIC_DEFDCDC1,
239 1.9.4.2 yamt .enable_bit = TPS65217PMIC_ENABLE_DCDC1
240 1.9.4.2 yamt },
241 1.9.4.2 yamt {
242 1.9.4.2 yamt .name = "DCDC2",
243 1.9.4.2 yamt .voltage_min = 900,
244 1.9.4.2 yamt .voltage_max = 3300,
245 1.9.4.2 yamt .voltages = ldo2voltages,
246 1.9.4.2 yamt .nvoltages = 64,
247 1.9.4.2 yamt .can_track = false,
248 1.9.4.2 yamt .tracked_reg = NULL,
249 1.9.4.2 yamt .can_xadj = true,
250 1.9.4.2 yamt .can_ls = false,
251 1.9.4.2 yamt .defreg_num = TPS65217PMIC_DEFDCDC2,
252 1.9.4.2 yamt .enable_bit = TPS65217PMIC_ENABLE_DCDC2
253 1.9.4.2 yamt },
254 1.9.4.2 yamt {
255 1.9.4.2 yamt .name = "DCDC3",
256 1.9.4.2 yamt .voltage_min = 900,
257 1.9.4.2 yamt .voltage_max = 3300,
258 1.9.4.2 yamt .voltages = ldo2voltages,
259 1.9.4.2 yamt .nvoltages = 64,
260 1.9.4.2 yamt .can_track = false,
261 1.9.4.2 yamt .tracked_reg = NULL,
262 1.9.4.2 yamt .can_xadj = true,
263 1.9.4.2 yamt .can_ls = false,
264 1.9.4.2 yamt .defreg_num = TPS65217PMIC_DEFDCDC3,
265 1.9.4.2 yamt .enable_bit = TPS65217PMIC_ENABLE_DCDC3
266 1.9.4.2 yamt }
267 1.9.4.2 yamt };
268 1.9.4.2 yamt
269 1.9.4.2 yamt static bool matched = false;
270 1.9.4.2 yamt
271 1.9.4.2 yamt static int
272 1.9.4.2 yamt tps65217pmic_match(device_t parent, cfdata_t cf, void *aux)
273 1.9.4.2 yamt {
274 1.9.4.2 yamt struct i2c_attach_args *ia = aux;
275 1.9.4.2 yamt
276 1.9.4.2 yamt if (ia->ia_addr == TPS65217PMIC_ADDR) {
277 1.9.4.2 yamt /* we can only have one */
278 1.9.4.2 yamt if (matched)
279 1.9.4.2 yamt return 0;
280 1.9.4.2 yamt else
281 1.9.4.2 yamt matched = true;
282 1.9.4.2 yamt
283 1.9.4.2 yamt return 1;
284 1.9.4.2 yamt }
285 1.9.4.2 yamt return 0;
286 1.9.4.2 yamt }
287 1.9.4.2 yamt
288 1.9.4.2 yamt static void
289 1.9.4.2 yamt tps65217pmic_attach(device_t parent, device_t self, void *aux)
290 1.9.4.2 yamt {
291 1.9.4.2 yamt struct tps65217pmic_softc *sc = device_private(self);
292 1.9.4.2 yamt struct i2c_attach_args *ia = aux;
293 1.9.4.2 yamt
294 1.9.4.2 yamt sc->sc_dev = self;
295 1.9.4.2 yamt sc->sc_addr = ia->ia_addr;
296 1.9.4.2 yamt sc->sc_tag = ia->ia_tag;
297 1.9.4.2 yamt
298 1.9.4.2 yamt tps65217pmic_version(sc);
299 1.9.4.2 yamt
300 1.9.4.2 yamt aprint_normal(": TPS65217");
301 1.9.4.2 yamt switch (sc->sc_version) {
302 1.9.4.2 yamt case TPS65217PMIC_CHIPID_VER_A:
303 1.9.4.2 yamt aprint_normal("A");
304 1.9.4.2 yamt break;
305 1.9.4.2 yamt case TPS65217PMIC_CHIPID_VER_B:
306 1.9.4.2 yamt aprint_normal("B");
307 1.9.4.2 yamt break;
308 1.9.4.2 yamt case TPS65217PMIC_CHIPID_VER_C:
309 1.9.4.2 yamt aprint_normal("C");
310 1.9.4.2 yamt break;
311 1.9.4.2 yamt case TPS65217PMIC_CHIPID_VER_D:
312 1.9.4.2 yamt aprint_normal("D");
313 1.9.4.2 yamt break;
314 1.9.4.2 yamt default:
315 1.9.4.2 yamt /* unknown version */
316 1.9.4.2 yamt break;
317 1.9.4.2 yamt }
318 1.9.4.2 yamt
319 1.9.4.2 yamt aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n",
320 1.9.4.2 yamt sc->sc_revision);
321 1.9.4.2 yamt
322 1.9.4.2 yamt mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
323 1.9.4.2 yamt
324 1.9.4.2 yamt sc->sc_smpsw.smpsw_name = device_xname(self);
325 1.9.4.2 yamt sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER;
326 1.9.4.2 yamt sysmon_pswitch_register(&sc->sc_smpsw);
327 1.9.4.2 yamt
328 1.9.4.2 yamt tps65217pmic_reg_refresh(sc);
329 1.9.4.2 yamt
330 1.9.4.2 yamt tps65217pmic_print_ppath(sc);
331 1.9.4.2 yamt tps65217pmic_print_ldos(sc);
332 1.9.4.2 yamt
333 1.9.4.2 yamt tps65217pmic_power_monitor_init(sc);
334 1.9.4.2 yamt
335 1.9.4.2 yamt tps65217pmic_envsys_register(sc);
336 1.9.4.2 yamt }
337 1.9.4.2 yamt
338 1.9.4.2 yamt static void
339 1.9.4.2 yamt tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc)
340 1.9.4.2 yamt {
341 1.9.4.2 yamt uint8_t intr, intrmask, status, ppath;
342 1.9.4.2 yamt
343 1.9.4.2 yamt intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM |
344 1.9.4.2 yamt TPS65217PMIC_INT_PBM;
345 1.9.4.2 yamt
346 1.9.4.2 yamt status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
347 1.9.4.2 yamt ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
348 1.9.4.2 yamt /* acknowledge and disregard whatever interrupt was generated earlier */
349 1.9.4.2 yamt intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT);
350 1.9.4.2 yamt
351 1.9.4.2 yamt sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
352 1.9.4.2 yamt sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR;
353 1.9.4.2 yamt sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN;
354 1.9.4.2 yamt sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN;
355 1.9.4.2 yamt
356 1.9.4.2 yamt if (intr & intrmask)
357 1.9.4.2 yamt aprint_normal_dev(sc->sc_dev,
358 1.9.4.2 yamt "WARNING: hardware interrupt enabled but not supported");
359 1.9.4.2 yamt
360 1.9.4.2 yamt /* set up callout to poll for power source changes */
361 1.9.4.2 yamt callout_init(&sc->sc_powerpollco, 0);
362 1.9.4.2 yamt callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc);
363 1.9.4.2 yamt
364 1.9.4.2 yamt callout_schedule(&sc->sc_powerpollco, hz);
365 1.9.4.2 yamt }
366 1.9.4.2 yamt
367 1.9.4.2 yamt static void
368 1.9.4.2 yamt tps65217pmic_power_monitor(void *aux)
369 1.9.4.2 yamt {
370 1.9.4.2 yamt struct tps65217pmic_softc *sc;
371 1.9.4.2 yamt uint8_t status;
372 1.9.4.2 yamt bool usbstatus, acstatus;
373 1.9.4.2 yamt
374 1.9.4.2 yamt sc = aux;
375 1.9.4.2 yamt
376 1.9.4.2 yamt mutex_enter(&sc->sc_lock);
377 1.9.4.2 yamt
378 1.9.4.2 yamt status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
379 1.9.4.2 yamt usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
380 1.9.4.2 yamt acstatus = status & TPS65217PMIC_STATUS_ACPWR;
381 1.9.4.2 yamt
382 1.9.4.2 yamt if (usbstatus != sc->sc_usbstatus) {
383 1.9.4.2 yamt sc->sc_usbstatus = usbstatus;
384 1.9.4.2 yamt pmf_event_inject(NULL, PMFE_POWER_CHANGED);
385 1.9.4.2 yamt if (usbstatus)
386 1.9.4.2 yamt aprint_normal_dev(sc->sc_dev,
387 1.9.4.2 yamt "USB power source connected\n");
388 1.9.4.2 yamt else
389 1.9.4.2 yamt aprint_normal_dev(sc->sc_dev,
390 1.9.4.2 yamt "USB power source disconnected\n");
391 1.9.4.2 yamt }
392 1.9.4.2 yamt
393 1.9.4.2 yamt if (acstatus != sc->sc_acstatus) {
394 1.9.4.2 yamt sc->sc_acstatus = acstatus;
395 1.9.4.2 yamt pmf_event_inject(NULL, PMFE_POWER_CHANGED);
396 1.9.4.2 yamt if (acstatus) {
397 1.9.4.2 yamt sysmon_pswitch_event(&sc->sc_smpsw,
398 1.9.4.2 yamt PSWITCH_EVENT_PRESSED);
399 1.9.4.2 yamt } else {
400 1.9.4.2 yamt sysmon_pswitch_event(&sc->sc_smpsw,
401 1.9.4.2 yamt PSWITCH_EVENT_RELEASED);
402 1.9.4.2 yamt }
403 1.9.4.2 yamt }
404 1.9.4.2 yamt
405 1.9.4.2 yamt mutex_exit(&sc->sc_lock);
406 1.9.4.2 yamt
407 1.9.4.2 yamt callout_schedule(&sc->sc_powerpollco, hz);
408 1.9.4.2 yamt }
409 1.9.4.2 yamt
410 1.9.4.2 yamt static void
411 1.9.4.2 yamt tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc)
412 1.9.4.2 yamt {
413 1.9.4.2 yamt int i;
414 1.9.4.2 yamt struct tps_reg_param *c_reg;
415 1.9.4.2 yamt
416 1.9.4.2 yamt for (i = 0; i < NTPS_REG; i++) {
417 1.9.4.2 yamt c_reg = &tps_regulators[i];
418 1.9.4.2 yamt tps65217pmic_regulator_read_config(sc, c_reg);
419 1.9.4.2 yamt }
420 1.9.4.2 yamt }
421 1.9.4.2 yamt
422 1.9.4.2 yamt /* Get version and revision of the chip. */
423 1.9.4.2 yamt static void
424 1.9.4.2 yamt tps65217pmic_version(struct tps65217pmic_softc *sc)
425 1.9.4.2 yamt {
426 1.9.4.2 yamt uint8_t chipid;
427 1.9.4.2 yamt
428 1.9.4.2 yamt chipid = tps65217pmic_reg_read(sc, TPS65217PMIC_CHIPID);
429 1.9.4.2 yamt
430 1.9.4.2 yamt sc->sc_version = chipid & TPS65217PMIC_CHIPID_VER_MASK;
431 1.9.4.2 yamt sc->sc_revision = chipid & TPS65217PMIC_CHIPID_REV_MASK;
432 1.9.4.2 yamt }
433 1.9.4.2 yamt
434 1.9.4.2 yamt static uint16_t
435 1.9.4.2 yamt tps65217pmic_ppath_max_ac_current(uint8_t ppath)
436 1.9.4.2 yamt {
437 1.9.4.2 yamt switch ((ppath & TPS65217PMIC_PPATH_IAC) >>
438 1.9.4.2 yamt TPS65217PMIC_PPATH_IAC_RSHFIT) {
439 1.9.4.2 yamt case TPS65217PMIC_PPATH_IAC_100MA:
440 1.9.4.2 yamt return 100;
441 1.9.4.2 yamt case TPS65217PMIC_PPATH_IAC_500MA:
442 1.9.4.2 yamt return 500;
443 1.9.4.2 yamt case TPS65217PMIC_PPATH_IAC_1300MA:
444 1.9.4.2 yamt return 1300;
445 1.9.4.2 yamt case TPS65217PMIC_PPATH_IAC_2500MA:
446 1.9.4.2 yamt return 2500;
447 1.9.4.2 yamt }
448 1.9.4.2 yamt return 0;
449 1.9.4.2 yamt }
450 1.9.4.2 yamt
451 1.9.4.2 yamt static uint16_t
452 1.9.4.2 yamt tps65217pmic_ppath_max_usb_current(uint8_t ppath)
453 1.9.4.2 yamt {
454 1.9.4.2 yamt switch (ppath & TPS65217PMIC_PPATH_IUSB) {
455 1.9.4.2 yamt case TPS65217PMIC_PPATH_IUSB_100MA:
456 1.9.4.2 yamt return 100;
457 1.9.4.2 yamt case TPS65217PMIC_PPATH_IUSB_500MA:
458 1.9.4.2 yamt return 500;
459 1.9.4.2 yamt case TPS65217PMIC_PPATH_IUSB_1300MA:
460 1.9.4.2 yamt return 1300;
461 1.9.4.2 yamt case TPS65217PMIC_PPATH_IUSB_1800MA:
462 1.9.4.2 yamt return 1800;
463 1.9.4.2 yamt }
464 1.9.4.2 yamt return 0;
465 1.9.4.2 yamt }
466 1.9.4.2 yamt
467 1.9.4.2 yamt /* Read regulator state and save it to tps_reg_param. */
468 1.9.4.2 yamt static void
469 1.9.4.2 yamt tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct
470 1.9.4.2 yamt tps_reg_param *regulator)
471 1.9.4.2 yamt {
472 1.9.4.2 yamt uint8_t defreg, regenable;
473 1.9.4.2 yamt uint16_t voltage;
474 1.9.4.2 yamt
475 1.9.4.2 yamt regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE);
476 1.9.4.2 yamt
477 1.9.4.2 yamt if (regenable & (regulator->enable_bit))
478 1.9.4.2 yamt regulator->is_enabled = true;
479 1.9.4.2 yamt else {
480 1.9.4.2 yamt regulator->is_enabled = false;
481 1.9.4.2 yamt return;
482 1.9.4.2 yamt }
483 1.9.4.2 yamt
484 1.9.4.2 yamt defreg = tps65217pmic_reg_read(sc,
485 1.9.4.2 yamt regulator->defreg_num);
486 1.9.4.2 yamt
487 1.9.4.2 yamt switch (regulator->nvoltages) {
488 1.9.4.2 yamt case 16:
489 1.9.4.2 yamt voltage = regulator->voltages[defreg &
490 1.9.4.2 yamt TPS65217PMIC_DEFX_VOLTAGE_16];
491 1.9.4.2 yamt break;
492 1.9.4.2 yamt case 32:
493 1.9.4.2 yamt voltage = regulator->voltages[defreg &
494 1.9.4.2 yamt TPS65217PMIC_DEFX_VOLTAGE_32];
495 1.9.4.2 yamt break;
496 1.9.4.2 yamt case 64:
497 1.9.4.2 yamt voltage = regulator->voltages[defreg &
498 1.9.4.2 yamt TPS65217PMIC_DEFX_VOLTAGE_64];
499 1.9.4.2 yamt break;
500 1.9.4.2 yamt default:
501 1.9.4.2 yamt /* unsupported number of voltage settings? */
502 1.9.4.2 yamt voltage = 0;
503 1.9.4.2 yamt break;
504 1.9.4.2 yamt }
505 1.9.4.2 yamt
506 1.9.4.2 yamt /* Handle regulator tracking other regulator voltage. */
507 1.9.4.2 yamt if (regulator->can_track)
508 1.9.4.2 yamt if (defreg & TPS65217PMIC_DEFX_TRACKING) {
509 1.9.4.2 yamt regulator->is_tracking = true;
510 1.9.4.2 yamt voltage = 0; /* see regulator->tracked_reg */
511 1.9.4.2 yamt }
512 1.9.4.2 yamt
513 1.9.4.2 yamt /* Handle regulator configured into load switch mode. */
514 1.9.4.2 yamt if (regulator->can_ls)
515 1.9.4.2 yamt if (!(defreg & TPS65217PMIC_DEFX_LS)) {
516 1.9.4.2 yamt regulator->is_ls = true;
517 1.9.4.2 yamt voltage = 0;
518 1.9.4.2 yamt }
519 1.9.4.2 yamt
520 1.9.4.2 yamt if (regulator->can_xadj)
521 1.9.4.2 yamt if (defreg & TPS65217PMIC_DEFX_XADJ) {
522 1.9.4.2 yamt regulator->is_xadj = true;
523 1.9.4.2 yamt voltage = 0;
524 1.9.4.2 yamt
525 1.9.4.2 yamt }
526 1.9.4.2 yamt
527 1.9.4.2 yamt /* TODO: add PGOOD checking */
528 1.9.4.2 yamt
529 1.9.4.2 yamt regulator->current_voltage = voltage;
530 1.9.4.2 yamt }
531 1.9.4.2 yamt
532 1.9.4.2 yamt static void
533 1.9.4.2 yamt tps65217pmic_print_ldos(struct tps65217pmic_softc *sc)
534 1.9.4.2 yamt {
535 1.9.4.2 yamt int i;
536 1.9.4.2 yamt struct tps_reg_param *c_reg;
537 1.9.4.2 yamt
538 1.9.4.2 yamt aprint_normal_dev(sc->sc_dev, "");
539 1.9.4.2 yamt
540 1.9.4.2 yamt for (i = 0; i < NTPS_REG; i++) {
541 1.9.4.2 yamt c_reg = &tps_regulators[i];
542 1.9.4.2 yamt
543 1.9.4.2 yamt if (c_reg->is_enabled) {
544 1.9.4.2 yamt if (c_reg->is_ls)
545 1.9.4.2 yamt aprint_normal("[%s: LS] ", c_reg->name);
546 1.9.4.2 yamt else if (c_reg->is_xadj)
547 1.9.4.2 yamt aprint_normal("[%s: XADJ] ", c_reg->name);
548 1.9.4.2 yamt else
549 1.9.4.2 yamt aprint_normal("[%s: %d mV] ", c_reg->name,
550 1.9.4.2 yamt c_reg->current_voltage);
551 1.9.4.2 yamt }
552 1.9.4.2 yamt }
553 1.9.4.2 yamt aprint_normal("\n");
554 1.9.4.2 yamt }
555 1.9.4.2 yamt
556 1.9.4.2 yamt static void
557 1.9.4.2 yamt tps65217pmic_print_ppath(struct tps65217pmic_softc *sc)
558 1.9.4.2 yamt {
559 1.9.4.2 yamt uint8_t status, ppath;
560 1.9.4.2 yamt
561 1.9.4.2 yamt ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
562 1.9.4.2 yamt status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
563 1.9.4.2 yamt
564 1.9.4.2 yamt aprint_normal_dev(sc->sc_dev, "power sources ");
565 1.9.4.2 yamt
566 1.9.4.2 yamt if (ppath & TPS65217PMIC_PPATH_USB_EN) {
567 1.9.4.2 yamt if (status & TPS65217PMIC_STATUS_USBPWR)
568 1.9.4.2 yamt aprint_normal("[USB] ");
569 1.9.4.2 yamt else
570 1.9.4.2 yamt aprint_normal("USB ");
571 1.9.4.2 yamt aprint_normal("max %d mA, ",
572 1.9.4.2 yamt tps65217pmic_ppath_max_usb_current(ppath));
573 1.9.4.2 yamt }
574 1.9.4.2 yamt
575 1.9.4.2 yamt if (ppath & TPS65217PMIC_PPATH_AC_EN) {
576 1.9.4.2 yamt if (status & TPS65217PMIC_STATUS_ACPWR)
577 1.9.4.2 yamt aprint_normal("[AC] ");
578 1.9.4.2 yamt else
579 1.9.4.2 yamt aprint_normal("AC ");
580 1.9.4.2 yamt aprint_normal("max %d mA",
581 1.9.4.2 yamt tps65217pmic_ppath_max_ac_current(ppath));
582 1.9.4.2 yamt }
583 1.9.4.2 yamt
584 1.9.4.2 yamt aprint_normal("\n");
585 1.9.4.2 yamt }
586 1.9.4.2 yamt
587 1.9.4.2 yamt static uint8_t
588 1.9.4.2 yamt tps65217pmic_reg_read(struct tps65217pmic_softc *sc, uint8_t reg)
589 1.9.4.2 yamt {
590 1.9.4.2 yamt uint8_t wbuf[2];
591 1.9.4.2 yamt uint8_t rv;
592 1.9.4.2 yamt
593 1.9.4.2 yamt if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL) != 0) {
594 1.9.4.2 yamt aprint_error_dev(sc->sc_dev, "cannot acquire bus for read\n");
595 1.9.4.2 yamt return 0;
596 1.9.4.2 yamt }
597 1.9.4.2 yamt
598 1.9.4.2 yamt wbuf[0] = reg;
599 1.9.4.2 yamt
600 1.9.4.2 yamt if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, wbuf,
601 1.9.4.2 yamt 1, &rv, 1, I2C_F_POLL)) {
602 1.9.4.2 yamt aprint_error_dev(sc->sc_dev, "cannot execute operation\n");
603 1.9.4.2 yamt iic_release_bus(sc->sc_tag, I2C_F_POLL);
604 1.9.4.2 yamt return 0;
605 1.9.4.2 yamt }
606 1.9.4.2 yamt iic_release_bus(sc->sc_tag, I2C_F_POLL);
607 1.9.4.2 yamt
608 1.9.4.2 yamt return rv;
609 1.9.4.2 yamt }
610 1.9.4.2 yamt
611 1.9.4.2 yamt static void __unused
612 1.9.4.2 yamt tps65217pmic_reg_write(struct tps65217pmic_softc *sc, uint8_t reg, uint8_t data)
613 1.9.4.2 yamt {
614 1.9.4.2 yamt uint8_t wbuf[2];
615 1.9.4.2 yamt
616 1.9.4.2 yamt if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL) != 0) {
617 1.9.4.2 yamt aprint_error_dev(sc->sc_dev, "cannot acquire bus for write\n");
618 1.9.4.2 yamt return;
619 1.9.4.2 yamt }
620 1.9.4.2 yamt
621 1.9.4.2 yamt wbuf[0] = reg;
622 1.9.4.2 yamt wbuf[1] = data;
623 1.9.4.2 yamt
624 1.9.4.2 yamt if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, wbuf,
625 1.9.4.2 yamt 2, NULL, 0, I2C_F_POLL)) {
626 1.9.4.2 yamt aprint_error_dev(sc->sc_dev, "cannot execute I2C write\n");
627 1.9.4.2 yamt iic_release_bus(sc->sc_tag, I2C_F_POLL);
628 1.9.4.2 yamt return;
629 1.9.4.2 yamt }
630 1.9.4.2 yamt
631 1.9.4.2 yamt iic_release_bus(sc->sc_tag, I2C_F_POLL);
632 1.9.4.2 yamt }
633 1.9.4.2 yamt
634 1.9.4.2 yamt static void
635 1.9.4.2 yamt tps65217pmic_envsys_register(struct tps65217pmic_softc *sc)
636 1.9.4.2 yamt {
637 1.9.4.2 yamt int i;
638 1.9.4.2 yamt
639 1.9.4.2 yamt sc->sc_sme = sysmon_envsys_create();
640 1.9.4.2 yamt
641 1.9.4.2 yamt /* iterate over all regulators and attach them as sensors */
642 1.9.4.2 yamt for(i = 0; i <= SNUM_REGS; i++) {
643 1.9.4.2 yamt /* set name */
644 1.9.4.2 yamt strlcpy(sc->sc_regsensor[i].desc, tps_regulators[i].name,
645 1.9.4.2 yamt sizeof(sc->sc_regsensor[i].desc));
646 1.9.4.2 yamt sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC;
647 1.9.4.2 yamt sc->sc_regsensor[i].state = ENVSYS_SINVALID;
648 1.9.4.2 yamt
649 1.9.4.2 yamt if (sysmon_envsys_sensor_attach(sc->sc_sme,
650 1.9.4.2 yamt &sc->sc_regsensor[i]))
651 1.9.4.2 yamt aprint_error_dev(sc->sc_dev,
652 1.9.4.2 yamt "error attaching regulator sensor %d\n", i);
653 1.9.4.2 yamt }
654 1.9.4.2 yamt
655 1.9.4.2 yamt /* attach power source indicators */
656 1.9.4.2 yamt strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */
657 1.9.4.2 yamt sc->sc_usbsensor.units = ENVSYS_INDICATOR;
658 1.9.4.2 yamt sc->sc_usbsensor.state = ENVSYS_SINVALID;
659 1.9.4.2 yamt if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor))
660 1.9.4.2 yamt aprint_error_dev(sc->sc_dev,
661 1.9.4.2 yamt "error attaching USB power source sensor\n");
662 1.9.4.2 yamt strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */
663 1.9.4.2 yamt sc->sc_acsensor.units = ENVSYS_INDICATOR;
664 1.9.4.2 yamt sc->sc_acsensor.state = ENVSYS_SINVALID;
665 1.9.4.2 yamt if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor))
666 1.9.4.2 yamt aprint_error_dev(sc->sc_dev,
667 1.9.4.2 yamt "error attaching AC power source sensor\n");
668 1.9.4.2 yamt
669 1.9.4.2 yamt /* register everything in sysmon */
670 1.9.4.2 yamt sc->sc_sme->sme_name = device_xname(sc->sc_dev);
671 1.9.4.2 yamt sc->sc_sme->sme_cookie = sc;
672 1.9.4.2 yamt sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh;
673 1.9.4.2 yamt
674 1.9.4.2 yamt if (sysmon_envsys_register(sc->sc_sme)) {
675 1.9.4.2 yamt aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n");
676 1.9.4.2 yamt sysmon_envsys_destroy(sc->sc_sme);
677 1.9.4.2 yamt }
678 1.9.4.2 yamt }
679 1.9.4.2 yamt
680 1.9.4.2 yamt static void
681 1.9.4.2 yamt tps65217pmic_envsys_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
682 1.9.4.2 yamt {
683 1.9.4.2 yamt struct tps65217pmic_softc *sc = sme->sme_cookie;
684 1.9.4.2 yamt
685 1.9.4.2 yamt mutex_enter(&sc->sc_lock);
686 1.9.4.2 yamt
687 1.9.4.2 yamt tps65217pmic_reg_refresh(sc);
688 1.9.4.2 yamt
689 1.9.4.2 yamt if (edata->sensor <= SNUM_REGS) {
690 1.9.4.2 yamt /* TODO: handle special cases like LS, XADJ... */
691 1.9.4.2 yamt edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000;
692 1.9.4.2 yamt edata->state = ENVSYS_SVALID;
693 1.9.4.2 yamt } else if (edata->sensor == SNUM_USBSTATUS) {
694 1.9.4.2 yamt edata->value_cur = sc->sc_usbstatus && sc->sc_usbenabled;
695 1.9.4.2 yamt edata->state = ENVSYS_SVALID;
696 1.9.4.2 yamt } else if (edata->sensor == SNUM_ACSTATUS) {
697 1.9.4.2 yamt edata->value_cur = sc->sc_acstatus && sc->sc_acenabled;
698 1.9.4.2 yamt edata->state = ENVSYS_SVALID;
699 1.9.4.2 yamt } else
700 1.9.4.2 yamt aprint_error_dev(sc->sc_dev, "unknown sensor number\n");
701 1.9.4.2 yamt
702 1.9.4.2 yamt mutex_exit(&sc->sc_lock);
703 1.9.4.2 yamt }
704 1.9.4.2 yamt
705