tps65217pmic.c revision 1.21 1 1.21 thorpej /* $NetBSD: tps65217pmic.c,v 1.21 2025/09/17 13:49:13 thorpej Exp $ */
2 1.1 rkujawa
3 1.1 rkujawa /*-
4 1.1 rkujawa * Copyright (c) 2013 The NetBSD Foundation, Inc.
5 1.1 rkujawa * All rights reserved.
6 1.1 rkujawa *
7 1.1 rkujawa * This code is derived from software contributed to The NetBSD Foundation
8 1.1 rkujawa * by Radoslaw Kujawa.
9 1.1 rkujawa *
10 1.1 rkujawa * Redistribution and use in source and binary forms, with or without
11 1.1 rkujawa * modification, are permitted provided that the following conditions
12 1.1 rkujawa * are met:
13 1.1 rkujawa * 1. Redistributions of source code must retain the above copyright
14 1.1 rkujawa * notice, this list of conditions and the following disclaimer.
15 1.1 rkujawa * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 rkujawa * notice, this list of conditions and the following disclaimer in the
17 1.1 rkujawa * documentation and/or other materials provided with the distribution.
18 1.1 rkujawa *
19 1.1 rkujawa * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 rkujawa * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 rkujawa * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 rkujawa * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 rkujawa * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 rkujawa * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 rkujawa * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 rkujawa * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 rkujawa * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 rkujawa * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 rkujawa * POSSIBILITY OF SUCH DAMAGE.
30 1.1 rkujawa */
31 1.1 rkujawa
32 1.4 jakllsch /*
33 1.4 jakllsch * Texas Instruments TPS65217 Power Management IC driver.
34 1.3 rkujawa * TODO: battery, sequencer, pgood
35 1.2 rkujawa */
36 1.2 rkujawa
37 1.13 jmcneill #include "opt_fdt.h"
38 1.13 jmcneill
39 1.1 rkujawa #include <sys/cdefs.h>
40 1.21 thorpej __KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.21 2025/09/17 13:49:13 thorpej Exp $");
41 1.1 rkujawa
42 1.1 rkujawa #include <sys/param.h>
43 1.1 rkujawa #include <sys/systm.h>
44 1.1 rkujawa #include <sys/device.h>
45 1.1 rkujawa #include <sys/kernel.h>
46 1.3 rkujawa #include <sys/mutex.h>
47 1.1 rkujawa
48 1.1 rkujawa #include <sys/bus.h>
49 1.1 rkujawa #include <dev/i2c/i2cvar.h>
50 1.1 rkujawa
51 1.3 rkujawa #include <dev/sysmon/sysmonvar.h>
52 1.14 jmcneill #include <dev/sysmon/sysmon_taskq.h>
53 1.3 rkujawa
54 1.1 rkujawa #include <dev/i2c/tps65217pmicreg.h>
55 1.10 bouyer #include <dev/i2c/tps65217pmicvar.h>
56 1.1 rkujawa
57 1.13 jmcneill #ifdef FDT
58 1.13 jmcneill #include <dev/fdt/fdtvar.h>
59 1.13 jmcneill #endif
60 1.13 jmcneill
61 1.3 rkujawa #define NTPS_REG 7
62 1.9 jakllsch #define SNUM_REGS NTPS_REG-1
63 1.6 rkujawa #define SNUM_USBSTATUS NTPS_REG
64 1.6 rkujawa #define SNUM_ACSTATUS NTPS_REG+1
65 1.3 rkujawa
66 1.13 jmcneill struct tps_reg_param;
67 1.13 jmcneill
68 1.1 rkujawa struct tps65217pmic_softc {
69 1.3 rkujawa device_t sc_dev;
70 1.3 rkujawa
71 1.3 rkujawa i2c_tag_t sc_tag;
72 1.3 rkujawa i2c_addr_t sc_addr;
73 1.13 jmcneill int sc_phandle;
74 1.1 rkujawa
75 1.3 rkujawa uint8_t sc_version;
76 1.3 rkujawa uint8_t sc_revision;
77 1.1 rkujawa
78 1.6 rkujawa kmutex_t sc_lock;
79 1.6 rkujawa
80 1.6 rkujawa bool sc_acstatus;
81 1.6 rkujawa bool sc_usbstatus;
82 1.6 rkujawa bool sc_acenabled;
83 1.6 rkujawa bool sc_usbenabled;
84 1.6 rkujawa
85 1.6 rkujawa callout_t sc_powerpollco;
86 1.6 rkujawa
87 1.6 rkujawa /* sysmon(4) stuff */
88 1.3 rkujawa struct sysmon_envsys *sc_sme;
89 1.6 rkujawa envsys_data_t sc_regsensor[NTPS_REG];
90 1.6 rkujawa envsys_data_t sc_acsensor;
91 1.6 rkujawa envsys_data_t sc_usbsensor;
92 1.6 rkujawa
93 1.6 rkujawa struct sysmon_pswitch sc_smpsw;
94 1.1 rkujawa };
95 1.1 rkujawa
96 1.13 jmcneill struct tps65217reg_softc {
97 1.13 jmcneill device_t sc_dev;
98 1.13 jmcneill int sc_phandle;
99 1.13 jmcneill struct tps_reg_param *sc_param;
100 1.13 jmcneill };
101 1.13 jmcneill
102 1.13 jmcneill struct tps65217reg_attach_args {
103 1.13 jmcneill struct tps_reg_param *reg_param;
104 1.13 jmcneill int reg_phandle;
105 1.13 jmcneill };
106 1.13 jmcneill
107 1.2 rkujawa /* Voltage regulators */
108 1.2 rkujawa enum tps_reg_num {
109 1.2 rkujawa TPS65217PMIC_LDO1,
110 1.2 rkujawa TPS65217PMIC_LDO2,
111 1.2 rkujawa TPS65217PMIC_LDO3LS,
112 1.2 rkujawa TPS65217PMIC_LDO4LS,
113 1.2 rkujawa TPS65217PMIC_DCDC1,
114 1.2 rkujawa TPS65217PMIC_DCDC2,
115 1.2 rkujawa TPS65217PMIC_DCDC3
116 1.4 jakllsch };
117 1.2 rkujawa
118 1.2 rkujawa struct tps_reg_param {
119 1.2 rkujawa /* parameters configured statically */
120 1.2 rkujawa
121 1.2 rkujawa const char* name;
122 1.2 rkujawa uint16_t voltage_min; /* in mV */
123 1.2 rkujawa uint16_t voltage_max; /* in mV */
124 1.2 rkujawa const uint16_t *voltages; /* all possible voltage settings */
125 1.2 rkujawa uint8_t nvoltages; /* number of voltage settings */
126 1.2 rkujawa
127 1.2 rkujawa bool can_track; /* regulator can track U of other r. */
128 1.2 rkujawa struct tps_reg_param *tracked_reg; /* ptr to tracked regulator */
129 1.2 rkujawa bool can_xadj; /* voltage can be adjusted externally */
130 1.2 rkujawa bool can_ls; /* can be a load switch instead of r. */
131 1.2 rkujawa
132 1.2 rkujawa uint8_t defreg_num; /* DEF register */
133 1.2 rkujawa uint8_t enable_bit; /* position in ENABLE register */
134 1.4 jakllsch
135 1.2 rkujawa /*
136 1.2 rkujawa * Run-time parameters configured during attachment and later, these
137 1.2 rkujawa * probably should be split into separate struct that would be a part
138 1.2 rkujawa * of softc. But since we can have only one TPS chip, that should be
139 1.2 rkujawa * okay for now.
140 1.2 rkujawa */
141 1.2 rkujawa
142 1.2 rkujawa bool is_enabled; /* regulator is enabled */
143 1.2 rkujawa bool is_pg; /* regulator is "power good" */
144 1.2 rkujawa bool is_tracking; /* voltage is tracking other reg. */
145 1.2 rkujawa bool is_ls; /* is a load switch */
146 1.2 rkujawa bool is_xadj; /* voltage is adjusted externally */
147 1.2 rkujawa
148 1.2 rkujawa uint16_t current_voltage; /* in mV */
149 1.2 rkujawa };
150 1.2 rkujawa
151 1.1 rkujawa static int tps65217pmic_match(device_t, cfdata_t, void *);
152 1.1 rkujawa static void tps65217pmic_attach(device_t, device_t, void *);
153 1.1 rkujawa
154 1.15 thorpej static int tps65217pmic_i2c_lock(struct tps65217pmic_softc *);
155 1.15 thorpej static void tps65217pmic_i2c_unlock(struct tps65217pmic_softc *);
156 1.15 thorpej
157 1.3 rkujawa static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *, uint8_t);
158 1.8 jakllsch static void tps65217pmic_reg_write(struct tps65217pmic_softc *, uint8_t,
159 1.8 jakllsch uint8_t);
160 1.3 rkujawa
161 1.6 rkujawa static void tps65217pmic_reg_refresh(struct tps65217pmic_softc *);
162 1.2 rkujawa
163 1.3 rkujawa static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t);
164 1.3 rkujawa static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t);
165 1.1 rkujawa
166 1.3 rkujawa static void tps65217pmic_regulator_read_config(struct tps65217pmic_softc *,
167 1.3 rkujawa struct tps_reg_param *);
168 1.1 rkujawa
169 1.3 rkujawa static void tps65217pmic_print_ppath(struct tps65217pmic_softc *);
170 1.3 rkujawa static void tps65217pmic_print_ldos(struct tps65217pmic_softc *);
171 1.2 rkujawa
172 1.3 rkujawa static void tps65217pmic_version(struct tps65217pmic_softc *);
173 1.2 rkujawa
174 1.3 rkujawa static void tps65217pmic_envsys_register(struct tps65217pmic_softc *);
175 1.3 rkujawa static void tps65217pmic_envsys_refresh(struct sysmon_envsys *, envsys_data_t *);
176 1.1 rkujawa
177 1.6 rkujawa static void tps65217pmic_power_monitor_init(struct tps65217pmic_softc *);
178 1.6 rkujawa static void tps65217pmic_power_monitor(void *);
179 1.6 rkujawa
180 1.11 kiyohara static void tps65217pmic_wled_init(struct tps65217pmic_softc *, int, int, int);
181 1.11 kiyohara
182 1.1 rkujawa CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
183 1.1 rkujawa tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
184 1.1 rkujawa
185 1.13 jmcneill #ifdef FDT
186 1.13 jmcneill static void tps65217pmic_regulator_attach(struct tps65217pmic_softc *);
187 1.13 jmcneill #endif
188 1.13 jmcneill
189 1.1 rkujawa /* Possible settings of LDO1 in mV. */
190 1.4 jakllsch static const uint16_t ldo1voltages[] = { 1000, 1100, 1200, 1250, 1300, 1350,
191 1.1 rkujawa 1400, 1500, 1600, 1800, 2500, 2750, 2800, 3000, 3100, 3300 };
192 1.1 rkujawa /* Possible settings of LDO2, DCDC1, DCDC2, DCDC3 in mV. */
193 1.4 jakllsch static const uint16_t ldo2voltages[] = { 900, 925, 950, 975, 1000, 1025, 1050,
194 1.4 jakllsch 1075, 1100, 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, 1325, 1350,
195 1.4 jakllsch 1375, 1400, 1425, 1450, 1475, 1500, 1550, 1600, 1650, 1700, 1750, 1800,
196 1.4 jakllsch 1850, 1900, 1950, 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400,
197 1.4 jakllsch 2450, 2500, 2550, 2600, 2650, 2700, 2750, 2800, 2850, 2900, 3000, 3100,
198 1.1 rkujawa 3200, 3300, 3300, 3300, 3300, 3300, 3300, 3300, 3300 };
199 1.1 rkujawa /* Possible settings of LDO3, LDO4 in mV. */
200 1.4 jakllsch static const uint16_t ldo3voltages[] = { 1500, 1550, 1600, 1650, 1700, 1750,
201 1.4 jakllsch 1800, 1850, 1900, 2000, 2100, 2200, 2300, 2400, 2450, 2500, 2550, 2600,
202 1.4 jakllsch 2650, 2700, 2750, 2800, 2850, 2900,2950, 3000, 3050, 3100, 3150, 3200,
203 1.1 rkujawa 3250, 3300 };
204 1.1 rkujawa
205 1.2 rkujawa static struct tps_reg_param tps_regulators[] = {
206 1.4 jakllsch {
207 1.13 jmcneill .name = "ldo1",
208 1.4 jakllsch .voltage_min = 1000,
209 1.4 jakllsch .voltage_max = 3300,
210 1.2 rkujawa .voltages = ldo1voltages,
211 1.2 rkujawa .nvoltages = 16,
212 1.2 rkujawa .can_track = false,
213 1.2 rkujawa .tracked_reg = NULL,
214 1.2 rkujawa .can_xadj = false,
215 1.2 rkujawa .can_ls = false,
216 1.2 rkujawa .defreg_num = TPS65217PMIC_DEFLDO1,
217 1.2 rkujawa .enable_bit = TPS65217PMIC_ENABLE_LDO1
218 1.2 rkujawa },
219 1.4 jakllsch {
220 1.13 jmcneill .name = "ldo2",
221 1.4 jakllsch .voltage_min = 900,
222 1.2 rkujawa .voltage_max = 3300,
223 1.2 rkujawa .voltages = ldo2voltages,
224 1.2 rkujawa .nvoltages = 64,
225 1.2 rkujawa .can_track = true,
226 1.4 jakllsch .tracked_reg = &(tps_regulators[TPS65217PMIC_DCDC3]),
227 1.2 rkujawa .can_xadj = false,
228 1.2 rkujawa .can_ls = false,
229 1.2 rkujawa .defreg_num = TPS65217PMIC_DEFLDO2,
230 1.2 rkujawa .enable_bit = TPS65217PMIC_ENABLE_LDO2
231 1.2 rkujawa },
232 1.4 jakllsch {
233 1.13 jmcneill .name = "ldo3",
234 1.4 jakllsch .voltage_min = 1500,
235 1.2 rkujawa .voltage_max = 3300,
236 1.2 rkujawa .voltages = ldo3voltages,
237 1.2 rkujawa .nvoltages = 32,
238 1.2 rkujawa .can_track = false,
239 1.4 jakllsch .tracked_reg = NULL,
240 1.2 rkujawa .can_xadj = false,
241 1.2 rkujawa .can_ls = true,
242 1.2 rkujawa .defreg_num = TPS65217PMIC_DEFLDO3,
243 1.2 rkujawa .enable_bit = TPS65217PMIC_ENABLE_LDO3
244 1.2 rkujawa },
245 1.4 jakllsch {
246 1.13 jmcneill .name = "ldo4",
247 1.4 jakllsch .voltage_min = 1500,
248 1.2 rkujawa .voltage_max = 3300,
249 1.2 rkujawa .voltages = ldo3voltages,
250 1.2 rkujawa .nvoltages = 32,
251 1.2 rkujawa .can_track = false,
252 1.4 jakllsch .tracked_reg = NULL,
253 1.2 rkujawa .can_xadj = false,
254 1.2 rkujawa .can_ls = true,
255 1.2 rkujawa .defreg_num = TPS65217PMIC_DEFLDO4,
256 1.2 rkujawa .enable_bit = TPS65217PMIC_ENABLE_LDO4
257 1.2 rkujawa },
258 1.4 jakllsch {
259 1.13 jmcneill .name = "dcdc1",
260 1.4 jakllsch .voltage_min = 900,
261 1.2 rkujawa .voltage_max = 3300,
262 1.2 rkujawa .voltages = ldo2voltages,
263 1.2 rkujawa .nvoltages = 64,
264 1.2 rkujawa .can_track = false,
265 1.4 jakllsch .tracked_reg = NULL,
266 1.2 rkujawa .can_xadj = true,
267 1.2 rkujawa .can_ls = false,
268 1.2 rkujawa .defreg_num = TPS65217PMIC_DEFDCDC1,
269 1.2 rkujawa .enable_bit = TPS65217PMIC_ENABLE_DCDC1
270 1.2 rkujawa },
271 1.4 jakllsch {
272 1.13 jmcneill .name = "dcdc2",
273 1.4 jakllsch .voltage_min = 900,
274 1.2 rkujawa .voltage_max = 3300,
275 1.2 rkujawa .voltages = ldo2voltages,
276 1.2 rkujawa .nvoltages = 64,
277 1.2 rkujawa .can_track = false,
278 1.4 jakllsch .tracked_reg = NULL,
279 1.2 rkujawa .can_xadj = true,
280 1.2 rkujawa .can_ls = false,
281 1.2 rkujawa .defreg_num = TPS65217PMIC_DEFDCDC2,
282 1.4 jakllsch .enable_bit = TPS65217PMIC_ENABLE_DCDC2
283 1.2 rkujawa },
284 1.4 jakllsch {
285 1.13 jmcneill .name = "dcdc3",
286 1.4 jakllsch .voltage_min = 900,
287 1.2 rkujawa .voltage_max = 3300,
288 1.2 rkujawa .voltages = ldo2voltages,
289 1.2 rkujawa .nvoltages = 64,
290 1.2 rkujawa .can_track = false,
291 1.4 jakllsch .tracked_reg = NULL,
292 1.2 rkujawa .can_xadj = true,
293 1.2 rkujawa .can_ls = false,
294 1.2 rkujawa .defreg_num = TPS65217PMIC_DEFDCDC3,
295 1.2 rkujawa .enable_bit = TPS65217PMIC_ENABLE_DCDC3
296 1.2 rkujawa }
297 1.2 rkujawa };
298 1.2 rkujawa
299 1.2 rkujawa static bool matched = false;
300 1.2 rkujawa
301 1.13 jmcneill static const struct device_compatible_entry compat_data[] = {
302 1.16 thorpej { .compat = "ti,tps65217" },
303 1.18 thorpej DEVICE_COMPAT_EOL
304 1.13 jmcneill };
305 1.13 jmcneill
306 1.1 rkujawa static int
307 1.1 rkujawa tps65217pmic_match(device_t parent, cfdata_t cf, void *aux)
308 1.1 rkujawa {
309 1.1 rkujawa struct i2c_attach_args *ia = aux;
310 1.13 jmcneill int match_result;
311 1.13 jmcneill
312 1.13 jmcneill if (iic_use_direct_match(ia, cf, compat_data, &match_result))
313 1.13 jmcneill return match_result;
314 1.1 rkujawa
315 1.2 rkujawa if (ia->ia_addr == TPS65217PMIC_ADDR) {
316 1.2 rkujawa /* we can only have one */
317 1.2 rkujawa if (matched)
318 1.2 rkujawa return 0;
319 1.2 rkujawa
320 1.12 thorpej return I2C_MATCH_ADDRESS_ONLY;
321 1.2 rkujawa }
322 1.1 rkujawa return 0;
323 1.1 rkujawa }
324 1.1 rkujawa
325 1.1 rkujawa static void
326 1.1 rkujawa tps65217pmic_attach(device_t parent, device_t self, void *aux)
327 1.1 rkujawa {
328 1.1 rkujawa struct tps65217pmic_softc *sc = device_private(self);
329 1.1 rkujawa struct i2c_attach_args *ia = aux;
330 1.11 kiyohara prop_dictionary_t dict;
331 1.11 kiyohara int isel, fdim, brightness;
332 1.1 rkujawa
333 1.12 thorpej /* XXXJRT But what if you have multiple i2c busses? */
334 1.12 thorpej matched = true;
335 1.12 thorpej
336 1.1 rkujawa sc->sc_dev = self;
337 1.1 rkujawa sc->sc_addr = ia->ia_addr;
338 1.1 rkujawa sc->sc_tag = ia->ia_tag;
339 1.1 rkujawa
340 1.21 thorpej #ifdef FDT
341 1.21 thorpej if (devhandle_type(device_handle(self)) == DEVHANDLE_TYPE_OF) {
342 1.21 thorpej sc->sc_phandle = devhandle_to_of(device_handle(self));
343 1.21 thorpej }
344 1.21 thorpej #endif
345 1.21 thorpej
346 1.11 kiyohara dict = device_properties(self);
347 1.11 kiyohara if (prop_dictionary_get_int32(dict, "isel", &isel)) {
348 1.11 kiyohara prop_dictionary_get_int32(dict, "fdim", &fdim);
349 1.11 kiyohara prop_dictionary_get_int32(dict, "brightness", &brightness);
350 1.11 kiyohara } else
351 1.11 kiyohara isel = -1;
352 1.11 kiyohara
353 1.1 rkujawa tps65217pmic_version(sc);
354 1.1 rkujawa
355 1.1 rkujawa aprint_normal(": TPS65217");
356 1.1 rkujawa switch (sc->sc_version) {
357 1.1 rkujawa case TPS65217PMIC_CHIPID_VER_A:
358 1.1 rkujawa aprint_normal("A");
359 1.1 rkujawa break;
360 1.1 rkujawa case TPS65217PMIC_CHIPID_VER_B:
361 1.1 rkujawa aprint_normal("B");
362 1.1 rkujawa break;
363 1.1 rkujawa case TPS65217PMIC_CHIPID_VER_C:
364 1.1 rkujawa aprint_normal("C");
365 1.1 rkujawa break;
366 1.1 rkujawa case TPS65217PMIC_CHIPID_VER_D:
367 1.1 rkujawa aprint_normal("D");
368 1.1 rkujawa break;
369 1.1 rkujawa default:
370 1.1 rkujawa /* unknown version */
371 1.1 rkujawa break;
372 1.1 rkujawa }
373 1.1 rkujawa
374 1.4 jakllsch aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n",
375 1.1 rkujawa sc->sc_revision);
376 1.1 rkujawa
377 1.3 rkujawa mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
378 1.3 rkujawa
379 1.6 rkujawa sc->sc_smpsw.smpsw_name = device_xname(self);
380 1.6 rkujawa sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER;
381 1.6 rkujawa sysmon_pswitch_register(&sc->sc_smpsw);
382 1.6 rkujawa
383 1.6 rkujawa tps65217pmic_reg_refresh(sc);
384 1.2 rkujawa
385 1.2 rkujawa tps65217pmic_print_ppath(sc);
386 1.2 rkujawa tps65217pmic_print_ldos(sc);
387 1.3 rkujawa
388 1.6 rkujawa tps65217pmic_power_monitor_init(sc);
389 1.6 rkujawa
390 1.11 kiyohara if (isel != -1)
391 1.11 kiyohara tps65217pmic_wled_init(sc, isel, fdim, brightness);
392 1.11 kiyohara
393 1.3 rkujawa tps65217pmic_envsys_register(sc);
394 1.13 jmcneill
395 1.13 jmcneill #ifdef FDT
396 1.13 jmcneill tps65217pmic_regulator_attach(sc);
397 1.13 jmcneill #endif
398 1.2 rkujawa }
399 1.2 rkujawa
400 1.2 rkujawa static void
401 1.6 rkujawa tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc)
402 1.6 rkujawa {
403 1.6 rkujawa uint8_t intr, intrmask, status, ppath;
404 1.6 rkujawa
405 1.9 jakllsch intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM |
406 1.6 rkujawa TPS65217PMIC_INT_PBM;
407 1.6 rkujawa
408 1.15 thorpej if (tps65217pmic_i2c_lock(sc) != 0) {
409 1.15 thorpej aprint_error_dev(sc->sc_dev,
410 1.15 thorpej "failed to initialize power monitor\n");
411 1.15 thorpej return;
412 1.15 thorpej }
413 1.15 thorpej
414 1.6 rkujawa status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
415 1.6 rkujawa ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
416 1.6 rkujawa /* acknowledge and disregard whatever interrupt was generated earlier */
417 1.6 rkujawa intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT);
418 1.6 rkujawa
419 1.15 thorpej tps65217pmic_i2c_unlock(sc);
420 1.15 thorpej
421 1.6 rkujawa sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
422 1.6 rkujawa sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR;
423 1.6 rkujawa sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN;
424 1.6 rkujawa sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN;
425 1.6 rkujawa
426 1.6 rkujawa if (intr & intrmask)
427 1.9 jakllsch aprint_normal_dev(sc->sc_dev,
428 1.6 rkujawa "WARNING: hardware interrupt enabled but not supported");
429 1.6 rkujawa
430 1.6 rkujawa /* set up callout to poll for power source changes */
431 1.6 rkujawa callout_init(&sc->sc_powerpollco, 0);
432 1.6 rkujawa callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc);
433 1.6 rkujawa
434 1.6 rkujawa callout_schedule(&sc->sc_powerpollco, hz);
435 1.6 rkujawa }
436 1.6 rkujawa
437 1.6 rkujawa static void
438 1.14 jmcneill tps65217pmic_power_monitor_task(void *aux)
439 1.6 rkujawa {
440 1.6 rkujawa struct tps65217pmic_softc *sc;
441 1.6 rkujawa uint8_t status;
442 1.6 rkujawa bool usbstatus, acstatus;
443 1.6 rkujawa
444 1.6 rkujawa sc = aux;
445 1.6 rkujawa
446 1.6 rkujawa mutex_enter(&sc->sc_lock);
447 1.6 rkujawa
448 1.15 thorpej if (tps65217pmic_i2c_lock(sc) != 0) {
449 1.15 thorpej device_printf(sc->sc_dev,
450 1.15 thorpej "WARNING: unable to perform power monitor task.\n");
451 1.15 thorpej return;
452 1.15 thorpej }
453 1.6 rkujawa status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
454 1.15 thorpej tps65217pmic_i2c_unlock(sc);
455 1.15 thorpej
456 1.6 rkujawa usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
457 1.6 rkujawa acstatus = status & TPS65217PMIC_STATUS_ACPWR;
458 1.6 rkujawa
459 1.6 rkujawa if (usbstatus != sc->sc_usbstatus) {
460 1.6 rkujawa sc->sc_usbstatus = usbstatus;
461 1.6 rkujawa pmf_event_inject(NULL, PMFE_POWER_CHANGED);
462 1.6 rkujawa if (usbstatus)
463 1.9 jakllsch aprint_normal_dev(sc->sc_dev,
464 1.6 rkujawa "USB power source connected\n");
465 1.6 rkujawa else
466 1.9 jakllsch aprint_normal_dev(sc->sc_dev,
467 1.6 rkujawa "USB power source disconnected\n");
468 1.6 rkujawa }
469 1.6 rkujawa
470 1.6 rkujawa if (acstatus != sc->sc_acstatus) {
471 1.6 rkujawa sc->sc_acstatus = acstatus;
472 1.6 rkujawa pmf_event_inject(NULL, PMFE_POWER_CHANGED);
473 1.6 rkujawa if (acstatus) {
474 1.9 jakllsch sysmon_pswitch_event(&sc->sc_smpsw,
475 1.6 rkujawa PSWITCH_EVENT_PRESSED);
476 1.6 rkujawa } else {
477 1.9 jakllsch sysmon_pswitch_event(&sc->sc_smpsw,
478 1.6 rkujawa PSWITCH_EVENT_RELEASED);
479 1.6 rkujawa }
480 1.6 rkujawa }
481 1.6 rkujawa
482 1.6 rkujawa mutex_exit(&sc->sc_lock);
483 1.6 rkujawa
484 1.6 rkujawa callout_schedule(&sc->sc_powerpollco, hz);
485 1.6 rkujawa }
486 1.6 rkujawa
487 1.6 rkujawa static void
488 1.14 jmcneill tps65217pmic_power_monitor(void *aux)
489 1.14 jmcneill {
490 1.14 jmcneill sysmon_task_queue_sched(0, tps65217pmic_power_monitor_task, aux);
491 1.14 jmcneill }
492 1.14 jmcneill
493 1.14 jmcneill static void
494 1.11 kiyohara tps65217pmic_wled_init(struct tps65217pmic_softc *sc, int isel, int fdim,
495 1.11 kiyohara int brightness)
496 1.11 kiyohara {
497 1.11 kiyohara uint8_t val = 0;
498 1.11 kiyohara
499 1.11 kiyohara switch (isel) {
500 1.11 kiyohara case 1:
501 1.11 kiyohara case 2:
502 1.11 kiyohara val |= ((isel - 1) << TPS65217PMIC_WLEDCTRL1_ISEL);
503 1.11 kiyohara break;
504 1.11 kiyohara default:
505 1.11 kiyohara aprint_error_dev(sc->sc_dev,
506 1.11 kiyohara "WLED ISET selection is 1 or 2: isel %d\n", isel);
507 1.11 kiyohara return;
508 1.11 kiyohara }
509 1.11 kiyohara switch (fdim) {
510 1.11 kiyohara case 100:
511 1.11 kiyohara val |= TPS65217PMIC_WLEDCTRL1_FDIM_100Hz;
512 1.11 kiyohara break;
513 1.11 kiyohara case 200:
514 1.11 kiyohara val |= TPS65217PMIC_WLEDCTRL1_FDIM_200Hz;
515 1.11 kiyohara break;
516 1.11 kiyohara case 500:
517 1.11 kiyohara val |= TPS65217PMIC_WLEDCTRL1_FDIM_500Hz;
518 1.11 kiyohara break;
519 1.11 kiyohara case 1000:
520 1.11 kiyohara val |= TPS65217PMIC_WLEDCTRL1_FDIM_1000Hz;
521 1.11 kiyohara break;
522 1.11 kiyohara default:
523 1.11 kiyohara aprint_error_dev(sc->sc_dev,
524 1.11 kiyohara "WLED PWM dimming frequency is 100, 200, 500 or 1000:"
525 1.11 kiyohara " fdim %d\n", fdim);
526 1.11 kiyohara return;
527 1.11 kiyohara }
528 1.11 kiyohara if (brightness > 100 ||
529 1.11 kiyohara brightness < 0) {
530 1.11 kiyohara aprint_error_dev(sc->sc_dev,
531 1.11 kiyohara "invalid brightness: between 0 and 100: %d\n", brightness);
532 1.11 kiyohara return;
533 1.11 kiyohara }
534 1.11 kiyohara
535 1.15 thorpej if (tps65217pmic_i2c_lock(sc) != 0) {
536 1.15 thorpej device_printf(sc->sc_dev,
537 1.15 thorpej "WARNING: unable to configure LED\n");
538 1.15 thorpej return;
539 1.15 thorpej }
540 1.15 thorpej
541 1.11 kiyohara tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val);
542 1.11 kiyohara tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL2,
543 1.11 kiyohara (brightness - 1) & TPS65217PMIC_WLEDCTRL2_DUTY);
544 1.11 kiyohara val |= TPS65217PMIC_WLEDCTRL1_ISINK_EN;
545 1.11 kiyohara tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val);
546 1.15 thorpej
547 1.15 thorpej tps65217pmic_i2c_unlock(sc);
548 1.11 kiyohara }
549 1.11 kiyohara
550 1.11 kiyohara static void
551 1.6 rkujawa tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc)
552 1.2 rkujawa {
553 1.2 rkujawa int i;
554 1.2 rkujawa struct tps_reg_param *c_reg;
555 1.2 rkujawa
556 1.15 thorpej if (tps65217pmic_i2c_lock(sc) != 0) {
557 1.15 thorpej device_printf(sc->sc_dev,
558 1.15 thorpej "WARNING: unable to refresh regulators\n");
559 1.15 thorpej return;
560 1.15 thorpej }
561 1.15 thorpej
562 1.2 rkujawa for (i = 0; i < NTPS_REG; i++) {
563 1.2 rkujawa c_reg = &tps_regulators[i];
564 1.4 jakllsch tps65217pmic_regulator_read_config(sc, c_reg);
565 1.2 rkujawa }
566 1.15 thorpej
567 1.15 thorpej tps65217pmic_i2c_unlock(sc);
568 1.1 rkujawa }
569 1.1 rkujawa
570 1.1 rkujawa /* Get version and revision of the chip. */
571 1.4 jakllsch static void
572 1.1 rkujawa tps65217pmic_version(struct tps65217pmic_softc *sc)
573 1.1 rkujawa {
574 1.1 rkujawa uint8_t chipid;
575 1.1 rkujawa
576 1.15 thorpej if (tps65217pmic_i2c_lock(sc) != 0) {
577 1.15 thorpej device_printf(sc->sc_dev,
578 1.15 thorpej "WARNING: unable to get chip ID\n");
579 1.15 thorpej return;
580 1.15 thorpej }
581 1.15 thorpej
582 1.1 rkujawa chipid = tps65217pmic_reg_read(sc, TPS65217PMIC_CHIPID);
583 1.1 rkujawa
584 1.15 thorpej tps65217pmic_i2c_unlock(sc);
585 1.15 thorpej
586 1.1 rkujawa sc->sc_version = chipid & TPS65217PMIC_CHIPID_VER_MASK;
587 1.1 rkujawa sc->sc_revision = chipid & TPS65217PMIC_CHIPID_REV_MASK;
588 1.1 rkujawa }
589 1.1 rkujawa
590 1.4 jakllsch static uint16_t
591 1.4 jakllsch tps65217pmic_ppath_max_ac_current(uint8_t ppath)
592 1.1 rkujawa {
593 1.4 jakllsch switch ((ppath & TPS65217PMIC_PPATH_IAC) >>
594 1.1 rkujawa TPS65217PMIC_PPATH_IAC_RSHFIT) {
595 1.1 rkujawa case TPS65217PMIC_PPATH_IAC_100MA:
596 1.1 rkujawa return 100;
597 1.1 rkujawa case TPS65217PMIC_PPATH_IAC_500MA:
598 1.5 rkujawa return 500;
599 1.1 rkujawa case TPS65217PMIC_PPATH_IAC_1300MA:
600 1.1 rkujawa return 1300;
601 1.1 rkujawa case TPS65217PMIC_PPATH_IAC_2500MA:
602 1.1 rkujawa return 2500;
603 1.1 rkujawa }
604 1.1 rkujawa return 0;
605 1.1 rkujawa }
606 1.1 rkujawa
607 1.4 jakllsch static uint16_t
608 1.1 rkujawa tps65217pmic_ppath_max_usb_current(uint8_t ppath)
609 1.1 rkujawa {
610 1.1 rkujawa switch (ppath & TPS65217PMIC_PPATH_IUSB) {
611 1.1 rkujawa case TPS65217PMIC_PPATH_IUSB_100MA:
612 1.1 rkujawa return 100;
613 1.1 rkujawa case TPS65217PMIC_PPATH_IUSB_500MA:
614 1.5 rkujawa return 500;
615 1.1 rkujawa case TPS65217PMIC_PPATH_IUSB_1300MA:
616 1.1 rkujawa return 1300;
617 1.1 rkujawa case TPS65217PMIC_PPATH_IUSB_1800MA:
618 1.1 rkujawa return 1800;
619 1.1 rkujawa }
620 1.1 rkujawa return 0;
621 1.1 rkujawa }
622 1.1 rkujawa
623 1.2 rkujawa /* Read regulator state and save it to tps_reg_param. */
624 1.4 jakllsch static void
625 1.4 jakllsch tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct
626 1.2 rkujawa tps_reg_param *regulator)
627 1.1 rkujawa {
628 1.2 rkujawa uint8_t defreg, regenable;
629 1.2 rkujawa uint16_t voltage;
630 1.1 rkujawa
631 1.2 rkujawa regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE);
632 1.2 rkujawa
633 1.2 rkujawa if (regenable & (regulator->enable_bit))
634 1.2 rkujawa regulator->is_enabled = true;
635 1.2 rkujawa else {
636 1.2 rkujawa regulator->is_enabled = false;
637 1.2 rkujawa return;
638 1.2 rkujawa }
639 1.2 rkujawa
640 1.4 jakllsch defreg = tps65217pmic_reg_read(sc,
641 1.2 rkujawa regulator->defreg_num);
642 1.2 rkujawa
643 1.2 rkujawa switch (regulator->nvoltages) {
644 1.2 rkujawa case 16:
645 1.4 jakllsch voltage = regulator->voltages[defreg &
646 1.2 rkujawa TPS65217PMIC_DEFX_VOLTAGE_16];
647 1.2 rkujawa break;
648 1.2 rkujawa case 32:
649 1.4 jakllsch voltage = regulator->voltages[defreg &
650 1.2 rkujawa TPS65217PMIC_DEFX_VOLTAGE_32];
651 1.2 rkujawa break;
652 1.2 rkujawa case 64:
653 1.4 jakllsch voltage = regulator->voltages[defreg &
654 1.2 rkujawa TPS65217PMIC_DEFX_VOLTAGE_64];
655 1.2 rkujawa break;
656 1.1 rkujawa default:
657 1.2 rkujawa /* unsupported number of voltage settings? */
658 1.2 rkujawa voltage = 0;
659 1.1 rkujawa break;
660 1.1 rkujawa }
661 1.1 rkujawa
662 1.2 rkujawa /* Handle regulator tracking other regulator voltage. */
663 1.2 rkujawa if (regulator->can_track)
664 1.2 rkujawa if (defreg & TPS65217PMIC_DEFX_TRACKING) {
665 1.2 rkujawa regulator->is_tracking = true;
666 1.2 rkujawa voltage = 0; /* see regulator->tracked_reg */
667 1.2 rkujawa }
668 1.2 rkujawa
669 1.2 rkujawa /* Handle regulator configured into load switch mode. */
670 1.2 rkujawa if (regulator->can_ls)
671 1.2 rkujawa if (!(defreg & TPS65217PMIC_DEFX_LS)) {
672 1.2 rkujawa regulator->is_ls = true;
673 1.4 jakllsch voltage = 0;
674 1.2 rkujawa }
675 1.2 rkujawa
676 1.2 rkujawa if (regulator->can_xadj)
677 1.2 rkujawa if (defreg & TPS65217PMIC_DEFX_XADJ) {
678 1.2 rkujawa regulator->is_xadj = true;
679 1.2 rkujawa voltage = 0;
680 1.2 rkujawa
681 1.2 rkujawa }
682 1.2 rkujawa
683 1.2 rkujawa /* TODO: add PGOOD checking */
684 1.2 rkujawa
685 1.2 rkujawa regulator->current_voltage = voltage;
686 1.2 rkujawa }
687 1.2 rkujawa
688 1.2 rkujawa static void
689 1.2 rkujawa tps65217pmic_print_ldos(struct tps65217pmic_softc *sc)
690 1.2 rkujawa {
691 1.2 rkujawa int i;
692 1.2 rkujawa struct tps_reg_param *c_reg;
693 1.2 rkujawa
694 1.2 rkujawa aprint_normal_dev(sc->sc_dev, "");
695 1.2 rkujawa
696 1.2 rkujawa for (i = 0; i < NTPS_REG; i++) {
697 1.2 rkujawa c_reg = &tps_regulators[i];
698 1.2 rkujawa
699 1.3 rkujawa if (c_reg->is_enabled) {
700 1.3 rkujawa if (c_reg->is_ls)
701 1.2 rkujawa aprint_normal("[%s: LS] ", c_reg->name);
702 1.3 rkujawa else if (c_reg->is_xadj)
703 1.2 rkujawa aprint_normal("[%s: XADJ] ", c_reg->name);
704 1.3 rkujawa else
705 1.2 rkujawa aprint_normal("[%s: %d mV] ", c_reg->name,
706 1.2 rkujawa c_reg->current_voltage);
707 1.2 rkujawa }
708 1.2 rkujawa }
709 1.2 rkujawa aprint_normal("\n");
710 1.1 rkujawa }
711 1.1 rkujawa
712 1.4 jakllsch static void
713 1.2 rkujawa tps65217pmic_print_ppath(struct tps65217pmic_softc *sc)
714 1.1 rkujawa {
715 1.7 skrll uint8_t status, ppath;
716 1.1 rkujawa
717 1.1 rkujawa ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
718 1.1 rkujawa status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
719 1.1 rkujawa
720 1.1 rkujawa aprint_normal_dev(sc->sc_dev, "power sources ");
721 1.1 rkujawa
722 1.1 rkujawa if (ppath & TPS65217PMIC_PPATH_USB_EN) {
723 1.1 rkujawa if (status & TPS65217PMIC_STATUS_USBPWR)
724 1.1 rkujawa aprint_normal("[USB] ");
725 1.1 rkujawa else
726 1.1 rkujawa aprint_normal("USB ");
727 1.4 jakllsch aprint_normal("max %d mA, ",
728 1.1 rkujawa tps65217pmic_ppath_max_usb_current(ppath));
729 1.1 rkujawa }
730 1.1 rkujawa
731 1.1 rkujawa if (ppath & TPS65217PMIC_PPATH_AC_EN) {
732 1.1 rkujawa if (status & TPS65217PMIC_STATUS_ACPWR)
733 1.1 rkujawa aprint_normal("[AC] ");
734 1.1 rkujawa else
735 1.1 rkujawa aprint_normal("AC ");
736 1.4 jakllsch aprint_normal("max %d mA",
737 1.1 rkujawa tps65217pmic_ppath_max_ac_current(ppath));
738 1.1 rkujawa }
739 1.1 rkujawa
740 1.1 rkujawa aprint_normal("\n");
741 1.1 rkujawa }
742 1.1 rkujawa
743 1.15 thorpej static int
744 1.15 thorpej tps65217pmic_i2c_lock(struct tps65217pmic_softc *sc)
745 1.15 thorpej {
746 1.15 thorpej int error;
747 1.15 thorpej
748 1.15 thorpej error = iic_acquire_bus(sc->sc_tag, 0);
749 1.15 thorpej if (error) {
750 1.15 thorpej device_printf(sc->sc_dev,
751 1.15 thorpej "unable to acquire i2c bus, error %d\n", error);
752 1.15 thorpej }
753 1.15 thorpej return error;
754 1.15 thorpej }
755 1.15 thorpej
756 1.15 thorpej static void
757 1.15 thorpej tps65217pmic_i2c_unlock(struct tps65217pmic_softc *sc)
758 1.15 thorpej {
759 1.15 thorpej iic_release_bus(sc->sc_tag, 0);
760 1.15 thorpej }
761 1.15 thorpej
762 1.1 rkujawa static uint8_t
763 1.1 rkujawa tps65217pmic_reg_read(struct tps65217pmic_softc *sc, uint8_t reg)
764 1.1 rkujawa {
765 1.1 rkujawa uint8_t wbuf[2];
766 1.1 rkujawa uint8_t rv;
767 1.1 rkujawa
768 1.1 rkujawa wbuf[0] = reg;
769 1.1 rkujawa
770 1.4 jakllsch if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, wbuf,
771 1.15 thorpej 1, &rv, 1, 0)) {
772 1.1 rkujawa aprint_error_dev(sc->sc_dev, "cannot execute operation\n");
773 1.15 thorpej iic_release_bus(sc->sc_tag, 0);
774 1.1 rkujawa return 0;
775 1.1 rkujawa }
776 1.1 rkujawa
777 1.1 rkujawa return rv;
778 1.1 rkujawa }
779 1.1 rkujawa
780 1.10 bouyer static void
781 1.15 thorpej tps65217pmic_reg_write(struct tps65217pmic_softc *sc,
782 1.10 bouyer uint8_t reg, uint8_t data)
783 1.10 bouyer {
784 1.10 bouyer uint8_t wbuf[2];
785 1.10 bouyer
786 1.10 bouyer wbuf[0] = reg;
787 1.10 bouyer wbuf[1] = data;
788 1.10 bouyer
789 1.10 bouyer if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, NULL, 0,
790 1.15 thorpej wbuf, 2, 0)) {
791 1.10 bouyer aprint_error_dev(sc->sc_dev, "cannot execute I2C write\n");
792 1.10 bouyer }
793 1.10 bouyer }
794 1.10 bouyer
795 1.10 bouyer static void
796 1.10 bouyer tps65217pmic_reg_write_l2(struct tps65217pmic_softc *sc,
797 1.10 bouyer uint8_t reg, uint8_t data)
798 1.10 bouyer {
799 1.10 bouyer uint8_t regpw = reg ^ TPS65217PMIC_PASSWORD_XOR;
800 1.15 thorpej
801 1.15 thorpej if (tps65217pmic_i2c_lock(sc))
802 1.8 jakllsch return;
803 1.8 jakllsch
804 1.15 thorpej tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw);
805 1.15 thorpej tps65217pmic_reg_write(sc, reg, data);
806 1.15 thorpej tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw);
807 1.15 thorpej tps65217pmic_reg_write(sc, reg, data);
808 1.15 thorpej
809 1.15 thorpej tps65217pmic_i2c_unlock(sc);
810 1.8 jakllsch }
811 1.8 jakllsch
812 1.3 rkujawa static void
813 1.3 rkujawa tps65217pmic_envsys_register(struct tps65217pmic_softc *sc)
814 1.3 rkujawa {
815 1.3 rkujawa int i;
816 1.3 rkujawa
817 1.3 rkujawa sc->sc_sme = sysmon_envsys_create();
818 1.3 rkujawa
819 1.6 rkujawa /* iterate over all regulators and attach them as sensors */
820 1.6 rkujawa for(i = 0; i <= SNUM_REGS; i++) {
821 1.3 rkujawa /* set name */
822 1.6 rkujawa strlcpy(sc->sc_regsensor[i].desc, tps_regulators[i].name,
823 1.6 rkujawa sizeof(sc->sc_regsensor[i].desc));
824 1.6 rkujawa sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC;
825 1.6 rkujawa sc->sc_regsensor[i].state = ENVSYS_SINVALID;
826 1.3 rkujawa
827 1.6 rkujawa if (sysmon_envsys_sensor_attach(sc->sc_sme,
828 1.6 rkujawa &sc->sc_regsensor[i]))
829 1.4 jakllsch aprint_error_dev(sc->sc_dev,
830 1.6 rkujawa "error attaching regulator sensor %d\n", i);
831 1.3 rkujawa }
832 1.3 rkujawa
833 1.6 rkujawa /* attach power source indicators */
834 1.6 rkujawa strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */
835 1.6 rkujawa sc->sc_usbsensor.units = ENVSYS_INDICATOR;
836 1.9 jakllsch sc->sc_usbsensor.state = ENVSYS_SINVALID;
837 1.6 rkujawa if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor))
838 1.9 jakllsch aprint_error_dev(sc->sc_dev,
839 1.6 rkujawa "error attaching USB power source sensor\n");
840 1.6 rkujawa strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */
841 1.6 rkujawa sc->sc_acsensor.units = ENVSYS_INDICATOR;
842 1.9 jakllsch sc->sc_acsensor.state = ENVSYS_SINVALID;
843 1.6 rkujawa if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor))
844 1.9 jakllsch aprint_error_dev(sc->sc_dev,
845 1.9 jakllsch "error attaching AC power source sensor\n");
846 1.6 rkujawa
847 1.6 rkujawa /* register everything in sysmon */
848 1.3 rkujawa sc->sc_sme->sme_name = device_xname(sc->sc_dev);
849 1.3 rkujawa sc->sc_sme->sme_cookie = sc;
850 1.3 rkujawa sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh;
851 1.3 rkujawa
852 1.3 rkujawa if (sysmon_envsys_register(sc->sc_sme)) {
853 1.3 rkujawa aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n");
854 1.3 rkujawa sysmon_envsys_destroy(sc->sc_sme);
855 1.3 rkujawa }
856 1.3 rkujawa }
857 1.3 rkujawa
858 1.3 rkujawa static void
859 1.3 rkujawa tps65217pmic_envsys_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
860 1.3 rkujawa {
861 1.4 jakllsch struct tps65217pmic_softc *sc = sme->sme_cookie;
862 1.3 rkujawa
863 1.3 rkujawa mutex_enter(&sc->sc_lock);
864 1.3 rkujawa
865 1.6 rkujawa tps65217pmic_reg_refresh(sc);
866 1.3 rkujawa
867 1.6 rkujawa if (edata->sensor <= SNUM_REGS) {
868 1.6 rkujawa /* TODO: handle special cases like LS, XADJ... */
869 1.6 rkujawa edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000;
870 1.6 rkujawa edata->state = ENVSYS_SVALID;
871 1.6 rkujawa } else if (edata->sensor == SNUM_USBSTATUS) {
872 1.6 rkujawa edata->value_cur = sc->sc_usbstatus && sc->sc_usbenabled;
873 1.6 rkujawa edata->state = ENVSYS_SVALID;
874 1.6 rkujawa } else if (edata->sensor == SNUM_ACSTATUS) {
875 1.6 rkujawa edata->value_cur = sc->sc_acstatus && sc->sc_acenabled;
876 1.6 rkujawa edata->state = ENVSYS_SVALID;
877 1.6 rkujawa } else
878 1.6 rkujawa aprint_error_dev(sc->sc_dev, "unknown sensor number\n");
879 1.4 jakllsch
880 1.3 rkujawa mutex_exit(&sc->sc_lock);
881 1.3 rkujawa }
882 1.3 rkujawa
883 1.10 bouyer int
884 1.10 bouyer tps65217pmic_set_volt(device_t self, const char *name, int mvolt)
885 1.10 bouyer {
886 1.10 bouyer int i;
887 1.10 bouyer struct tps65217pmic_softc *sc = device_private(self);
888 1.10 bouyer struct tps_reg_param *regulator = NULL;
889 1.10 bouyer uint8_t val;
890 1.10 bouyer
891 1.10 bouyer for (i = 0; i < __arraycount(tps_regulators); i++) {
892 1.10 bouyer if (strcmp(name, tps_regulators[i].name) == 0) {
893 1.10 bouyer regulator = &tps_regulators[i];
894 1.10 bouyer break;
895 1.10 bouyer }
896 1.10 bouyer }
897 1.10 bouyer if (regulator == NULL)
898 1.10 bouyer return EINVAL;
899 1.10 bouyer
900 1.10 bouyer if (regulator->voltage_min > mvolt || regulator->voltage_max < mvolt)
901 1.10 bouyer return EINVAL;
902 1.10 bouyer
903 1.10 bouyer if (!regulator->is_enabled)
904 1.10 bouyer return EINVAL;
905 1.10 bouyer
906 1.10 bouyer if (regulator->is_tracking)
907 1.10 bouyer return EINVAL;
908 1.10 bouyer
909 1.10 bouyer if (regulator->is_xadj)
910 1.10 bouyer return EINVAL;
911 1.10 bouyer
912 1.10 bouyer /* find closest voltage entry */
913 1.10 bouyer for (i = 0; i < regulator->nvoltages; i++) {
914 1.10 bouyer if (mvolt <= regulator->voltages[i]) {
915 1.10 bouyer break;
916 1.10 bouyer }
917 1.10 bouyer }
918 1.10 bouyer KASSERT(i < regulator->nvoltages);
919 1.10 bouyer tps65217pmic_reg_write_l2(sc, regulator->defreg_num, i);
920 1.10 bouyer
921 1.10 bouyer val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
922 1.10 bouyer val |= TPS65217PMIC_DEFSLEW_GO;
923 1.10 bouyer tps65217pmic_reg_write_l2(sc, TPS65217PMIC_DEFSLEW, val);
924 1.10 bouyer
925 1.10 bouyer while (val & TPS65217PMIC_DEFSLEW_GO) {
926 1.10 bouyer val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
927 1.10 bouyer }
928 1.13 jmcneill
929 1.13 jmcneill regulator->current_voltage = regulator->voltages[i];
930 1.13 jmcneill
931 1.10 bouyer return 0;
932 1.10 bouyer }
933 1.13 jmcneill
934 1.13 jmcneill #ifdef FDT
935 1.13 jmcneill static struct tps_reg_param *
936 1.13 jmcneill tps65217pmic_get_params(const char *name)
937 1.13 jmcneill {
938 1.13 jmcneill int i;
939 1.13 jmcneill
940 1.13 jmcneill for (i = 0; i < __arraycount(tps_regulators); i++) {
941 1.13 jmcneill if (strcmp(name, tps_regulators[i].name) == 0)
942 1.13 jmcneill return &tps_regulators[i];
943 1.13 jmcneill }
944 1.13 jmcneill
945 1.13 jmcneill return NULL;
946 1.13 jmcneill }
947 1.13 jmcneill
948 1.13 jmcneill static void
949 1.13 jmcneill tps65217pmic_regulator_attach(struct tps65217pmic_softc *sc)
950 1.13 jmcneill {
951 1.13 jmcneill struct tps65217reg_attach_args raa;
952 1.13 jmcneill struct tps_reg_param *param;
953 1.13 jmcneill const char *compat_name;
954 1.13 jmcneill int phandle, child;
955 1.13 jmcneill
956 1.13 jmcneill phandle = of_find_firstchild_byname(sc->sc_phandle, "regulators");
957 1.13 jmcneill if (phandle <= 0)
958 1.13 jmcneill return;
959 1.13 jmcneill
960 1.13 jmcneill for (child = OF_child(phandle); child; child = OF_peer(child)) {
961 1.13 jmcneill compat_name = fdtbus_get_string(child, "regulator-compatible");
962 1.13 jmcneill if (compat_name == NULL)
963 1.13 jmcneill continue;
964 1.13 jmcneill param = tps65217pmic_get_params(compat_name);
965 1.13 jmcneill if (param == NULL)
966 1.13 jmcneill continue;
967 1.13 jmcneill
968 1.13 jmcneill raa.reg_param = param;
969 1.13 jmcneill raa.reg_phandle = child;
970 1.20 thorpej config_found(sc->sc_dev, &raa, NULL, CFARGS_NONE);
971 1.13 jmcneill }
972 1.13 jmcneill }
973 1.13 jmcneill
974 1.13 jmcneill static int
975 1.13 jmcneill tps65217reg_acquire(device_t dev)
976 1.13 jmcneill {
977 1.13 jmcneill return 0;
978 1.13 jmcneill }
979 1.13 jmcneill
980 1.13 jmcneill static void
981 1.13 jmcneill tps65217reg_release(device_t dev)
982 1.13 jmcneill {
983 1.13 jmcneill }
984 1.13 jmcneill
985 1.13 jmcneill static int
986 1.13 jmcneill tps65217reg_enable(device_t dev, bool enable)
987 1.13 jmcneill {
988 1.13 jmcneill struct tps65217reg_softc *sc = device_private(dev);
989 1.13 jmcneill struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
990 1.13 jmcneill struct tps_reg_param *regulator = sc->sc_param;
991 1.13 jmcneill uint8_t val;
992 1.13 jmcneill int error;
993 1.13 jmcneill
994 1.15 thorpej error = tps65217pmic_i2c_lock(pmic_sc);
995 1.13 jmcneill if (error != 0)
996 1.13 jmcneill return error;
997 1.13 jmcneill
998 1.13 jmcneill val = tps65217pmic_reg_read(pmic_sc, TPS65217PMIC_ENABLE);
999 1.13 jmcneill if (enable)
1000 1.13 jmcneill val |= regulator->enable_bit;
1001 1.13 jmcneill else
1002 1.13 jmcneill val &= ~regulator->enable_bit;
1003 1.13 jmcneill tps65217pmic_reg_write(pmic_sc, TPS65217PMIC_ENABLE, val);
1004 1.13 jmcneill
1005 1.13 jmcneill regulator->is_enabled = enable;
1006 1.13 jmcneill
1007 1.15 thorpej tps65217pmic_i2c_unlock(pmic_sc);
1008 1.13 jmcneill
1009 1.13 jmcneill return 0;
1010 1.13 jmcneill }
1011 1.13 jmcneill
1012 1.13 jmcneill static int
1013 1.13 jmcneill tps65217reg_set_voltage(device_t dev, u_int min_uvol, u_int max_uvol)
1014 1.13 jmcneill {
1015 1.13 jmcneill struct tps65217reg_softc *sc = device_private(dev);
1016 1.13 jmcneill struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
1017 1.13 jmcneill struct tps_reg_param *regulator = sc->sc_param;
1018 1.13 jmcneill int error;
1019 1.13 jmcneill
1020 1.15 thorpej error = tps65217pmic_i2c_lock(pmic_sc);
1021 1.13 jmcneill if (error != 0)
1022 1.13 jmcneill return error;
1023 1.13 jmcneill
1024 1.13 jmcneill error = tps65217pmic_set_volt(pmic_sc->sc_dev, regulator->name, min_uvol / 1000);
1025 1.13 jmcneill
1026 1.15 thorpej tps65217pmic_i2c_unlock(pmic_sc);
1027 1.13 jmcneill
1028 1.13 jmcneill return error;
1029 1.13 jmcneill }
1030 1.13 jmcneill
1031 1.13 jmcneill static int
1032 1.13 jmcneill tps65217reg_get_voltage(device_t dev, u_int *puvol)
1033 1.13 jmcneill {
1034 1.13 jmcneill struct tps65217reg_softc *sc = device_private(dev);
1035 1.13 jmcneill struct tps_reg_param *regulator = sc->sc_param;
1036 1.13 jmcneill
1037 1.13 jmcneill *puvol = (u_int)regulator->current_voltage * 1000;
1038 1.13 jmcneill
1039 1.13 jmcneill return 0;
1040 1.13 jmcneill }
1041 1.13 jmcneill
1042 1.13 jmcneill static struct fdtbus_regulator_controller_func tps65217reg_funcs = {
1043 1.13 jmcneill .acquire = tps65217reg_acquire,
1044 1.13 jmcneill .release = tps65217reg_release,
1045 1.13 jmcneill .enable = tps65217reg_enable,
1046 1.13 jmcneill .set_voltage = tps65217reg_set_voltage,
1047 1.13 jmcneill .get_voltage = tps65217reg_get_voltage,
1048 1.13 jmcneill };
1049 1.13 jmcneill
1050 1.13 jmcneill static int
1051 1.13 jmcneill tps65217reg_match(device_t parent, cfdata_t match, void *aux)
1052 1.13 jmcneill {
1053 1.13 jmcneill return 1;
1054 1.13 jmcneill }
1055 1.13 jmcneill
1056 1.13 jmcneill static void
1057 1.13 jmcneill tps65217reg_attach(device_t parent, device_t self, void *aux)
1058 1.13 jmcneill {
1059 1.13 jmcneill struct tps65217reg_softc *sc = device_private(self);
1060 1.13 jmcneill struct tps65217reg_attach_args *raa = aux;
1061 1.13 jmcneill const char *regname;
1062 1.13 jmcneill
1063 1.13 jmcneill sc->sc_dev = self;
1064 1.13 jmcneill sc->sc_phandle = raa->reg_phandle;
1065 1.13 jmcneill sc->sc_param = raa->reg_param;
1066 1.13 jmcneill
1067 1.13 jmcneill fdtbus_register_regulator_controller(self, sc->sc_phandle,
1068 1.13 jmcneill &tps65217reg_funcs);
1069 1.13 jmcneill
1070 1.13 jmcneill regname = fdtbus_get_string(sc->sc_phandle, "regulator-name");
1071 1.13 jmcneill if (regname == NULL)
1072 1.13 jmcneill regname = fdtbus_get_string(sc->sc_phandle, "regulator-compatible");
1073 1.13 jmcneill
1074 1.13 jmcneill aprint_naive("\n");
1075 1.13 jmcneill if (regname != NULL)
1076 1.13 jmcneill aprint_normal(": %s\n", regname);
1077 1.13 jmcneill else
1078 1.13 jmcneill aprint_normal("\n");
1079 1.13 jmcneill }
1080 1.13 jmcneill
1081 1.13 jmcneill CFATTACH_DECL_NEW(tps65217reg, sizeof (struct tps65217reg_softc),
1082 1.13 jmcneill tps65217reg_match, tps65217reg_attach, NULL, NULL);
1083 1.13 jmcneill
1084 1.13 jmcneill #endif
1085