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