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