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