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