1 /* $NetBSD: tps65217pmic.c,v 1.11 2016/10/15 14:40:41 kiyohara 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.11 2016/10/15 14:40:41 kiyohara 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 else 284 matched = true; 285 286 return 1; 287 } 288 return 0; 289 } 290 291 static void 292 tps65217pmic_attach(device_t parent, device_t self, void *aux) 293 { 294 struct tps65217pmic_softc *sc = device_private(self); 295 struct i2c_attach_args *ia = aux; 296 prop_dictionary_t dict; 297 int isel, fdim, brightness; 298 299 sc->sc_dev = self; 300 sc->sc_addr = ia->ia_addr; 301 sc->sc_tag = ia->ia_tag; 302 303 dict = device_properties(self); 304 if (prop_dictionary_get_int32(dict, "isel", &isel)) { 305 prop_dictionary_get_int32(dict, "fdim", &fdim); 306 prop_dictionary_get_int32(dict, "brightness", &brightness); 307 } else 308 isel = -1; 309 310 tps65217pmic_version(sc); 311 312 aprint_normal(": TPS65217"); 313 switch (sc->sc_version) { 314 case TPS65217PMIC_CHIPID_VER_A: 315 aprint_normal("A"); 316 break; 317 case TPS65217PMIC_CHIPID_VER_B: 318 aprint_normal("B"); 319 break; 320 case TPS65217PMIC_CHIPID_VER_C: 321 aprint_normal("C"); 322 break; 323 case TPS65217PMIC_CHIPID_VER_D: 324 aprint_normal("D"); 325 break; 326 default: 327 /* unknown version */ 328 break; 329 } 330 331 aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n", 332 sc->sc_revision); 333 334 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 335 336 sc->sc_smpsw.smpsw_name = device_xname(self); 337 sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER; 338 sysmon_pswitch_register(&sc->sc_smpsw); 339 340 tps65217pmic_reg_refresh(sc); 341 342 tps65217pmic_print_ppath(sc); 343 tps65217pmic_print_ldos(sc); 344 345 tps65217pmic_power_monitor_init(sc); 346 347 if (isel != -1) 348 tps65217pmic_wled_init(sc, isel, fdim, brightness); 349 350 tps65217pmic_envsys_register(sc); 351 } 352 353 static void 354 tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc) 355 { 356 uint8_t intr, intrmask, status, ppath; 357 358 intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM | 359 TPS65217PMIC_INT_PBM; 360 361 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS); 362 ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH); 363 /* acknowledge and disregard whatever interrupt was generated earlier */ 364 intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT); 365 366 sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR; 367 sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR; 368 sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN; 369 sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN; 370 371 if (intr & intrmask) 372 aprint_normal_dev(sc->sc_dev, 373 "WARNING: hardware interrupt enabled but not supported"); 374 375 /* set up callout to poll for power source changes */ 376 callout_init(&sc->sc_powerpollco, 0); 377 callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc); 378 379 callout_schedule(&sc->sc_powerpollco, hz); 380 } 381 382 static void 383 tps65217pmic_power_monitor(void *aux) 384 { 385 struct tps65217pmic_softc *sc; 386 uint8_t status; 387 bool usbstatus, acstatus; 388 389 sc = aux; 390 391 mutex_enter(&sc->sc_lock); 392 393 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS); 394 usbstatus = status & TPS65217PMIC_STATUS_USBPWR; 395 acstatus = status & TPS65217PMIC_STATUS_ACPWR; 396 397 if (usbstatus != sc->sc_usbstatus) { 398 sc->sc_usbstatus = usbstatus; 399 pmf_event_inject(NULL, PMFE_POWER_CHANGED); 400 if (usbstatus) 401 aprint_normal_dev(sc->sc_dev, 402 "USB power source connected\n"); 403 else 404 aprint_normal_dev(sc->sc_dev, 405 "USB power source disconnected\n"); 406 } 407 408 if (acstatus != sc->sc_acstatus) { 409 sc->sc_acstatus = acstatus; 410 pmf_event_inject(NULL, PMFE_POWER_CHANGED); 411 if (acstatus) { 412 sysmon_pswitch_event(&sc->sc_smpsw, 413 PSWITCH_EVENT_PRESSED); 414 } else { 415 sysmon_pswitch_event(&sc->sc_smpsw, 416 PSWITCH_EVENT_RELEASED); 417 } 418 } 419 420 mutex_exit(&sc->sc_lock); 421 422 callout_schedule(&sc->sc_powerpollco, hz); 423 } 424 425 static void 426 tps65217pmic_wled_init(struct tps65217pmic_softc *sc, int isel, int fdim, 427 int brightness) 428 { 429 uint8_t val = 0; 430 431 switch (isel) { 432 case 1: 433 case 2: 434 val |= ((isel - 1) << TPS65217PMIC_WLEDCTRL1_ISEL); 435 break; 436 default: 437 aprint_error_dev(sc->sc_dev, 438 "WLED ISET selection is 1 or 2: isel %d\n", isel); 439 return; 440 } 441 switch (fdim) { 442 case 100: 443 val |= TPS65217PMIC_WLEDCTRL1_FDIM_100Hz; 444 break; 445 case 200: 446 val |= TPS65217PMIC_WLEDCTRL1_FDIM_200Hz; 447 break; 448 case 500: 449 val |= TPS65217PMIC_WLEDCTRL1_FDIM_500Hz; 450 break; 451 case 1000: 452 val |= TPS65217PMIC_WLEDCTRL1_FDIM_1000Hz; 453 break; 454 default: 455 aprint_error_dev(sc->sc_dev, 456 "WLED PWM dimming frequency is 100, 200, 500 or 1000:" 457 " fdim %d\n", fdim); 458 return; 459 } 460 if (brightness > 100 || 461 brightness < 0) { 462 aprint_error_dev(sc->sc_dev, 463 "invalid brightness: between 0 and 100: %d\n", brightness); 464 return; 465 } 466 467 tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val); 468 tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL2, 469 (brightness - 1) & TPS65217PMIC_WLEDCTRL2_DUTY); 470 val |= TPS65217PMIC_WLEDCTRL1_ISINK_EN; 471 tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val); 472 } 473 474 static void 475 tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc) 476 { 477 int i; 478 struct tps_reg_param *c_reg; 479 480 for (i = 0; i < NTPS_REG; i++) { 481 c_reg = &tps_regulators[i]; 482 tps65217pmic_regulator_read_config(sc, c_reg); 483 } 484 } 485 486 /* Get version and revision of the chip. */ 487 static void 488 tps65217pmic_version(struct tps65217pmic_softc *sc) 489 { 490 uint8_t chipid; 491 492 chipid = tps65217pmic_reg_read(sc, TPS65217PMIC_CHIPID); 493 494 sc->sc_version = chipid & TPS65217PMIC_CHIPID_VER_MASK; 495 sc->sc_revision = chipid & TPS65217PMIC_CHIPID_REV_MASK; 496 } 497 498 static uint16_t 499 tps65217pmic_ppath_max_ac_current(uint8_t ppath) 500 { 501 switch ((ppath & TPS65217PMIC_PPATH_IAC) >> 502 TPS65217PMIC_PPATH_IAC_RSHFIT) { 503 case TPS65217PMIC_PPATH_IAC_100MA: 504 return 100; 505 case TPS65217PMIC_PPATH_IAC_500MA: 506 return 500; 507 case TPS65217PMIC_PPATH_IAC_1300MA: 508 return 1300; 509 case TPS65217PMIC_PPATH_IAC_2500MA: 510 return 2500; 511 } 512 return 0; 513 } 514 515 static uint16_t 516 tps65217pmic_ppath_max_usb_current(uint8_t ppath) 517 { 518 switch (ppath & TPS65217PMIC_PPATH_IUSB) { 519 case TPS65217PMIC_PPATH_IUSB_100MA: 520 return 100; 521 case TPS65217PMIC_PPATH_IUSB_500MA: 522 return 500; 523 case TPS65217PMIC_PPATH_IUSB_1300MA: 524 return 1300; 525 case TPS65217PMIC_PPATH_IUSB_1800MA: 526 return 1800; 527 } 528 return 0; 529 } 530 531 /* Read regulator state and save it to tps_reg_param. */ 532 static void 533 tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct 534 tps_reg_param *regulator) 535 { 536 uint8_t defreg, regenable; 537 uint16_t voltage; 538 539 regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE); 540 541 if (regenable & (regulator->enable_bit)) 542 regulator->is_enabled = true; 543 else { 544 regulator->is_enabled = false; 545 return; 546 } 547 548 defreg = tps65217pmic_reg_read(sc, 549 regulator->defreg_num); 550 551 switch (regulator->nvoltages) { 552 case 16: 553 voltage = regulator->voltages[defreg & 554 TPS65217PMIC_DEFX_VOLTAGE_16]; 555 break; 556 case 32: 557 voltage = regulator->voltages[defreg & 558 TPS65217PMIC_DEFX_VOLTAGE_32]; 559 break; 560 case 64: 561 voltage = regulator->voltages[defreg & 562 TPS65217PMIC_DEFX_VOLTAGE_64]; 563 break; 564 default: 565 /* unsupported number of voltage settings? */ 566 voltage = 0; 567 break; 568 } 569 570 /* Handle regulator tracking other regulator voltage. */ 571 if (regulator->can_track) 572 if (defreg & TPS65217PMIC_DEFX_TRACKING) { 573 regulator->is_tracking = true; 574 voltage = 0; /* see regulator->tracked_reg */ 575 } 576 577 /* Handle regulator configured into load switch mode. */ 578 if (regulator->can_ls) 579 if (!(defreg & TPS65217PMIC_DEFX_LS)) { 580 regulator->is_ls = true; 581 voltage = 0; 582 } 583 584 if (regulator->can_xadj) 585 if (defreg & TPS65217PMIC_DEFX_XADJ) { 586 regulator->is_xadj = true; 587 voltage = 0; 588 589 } 590 591 /* TODO: add PGOOD checking */ 592 593 regulator->current_voltage = voltage; 594 } 595 596 static void 597 tps65217pmic_print_ldos(struct tps65217pmic_softc *sc) 598 { 599 int i; 600 struct tps_reg_param *c_reg; 601 602 aprint_normal_dev(sc->sc_dev, ""); 603 604 for (i = 0; i < NTPS_REG; i++) { 605 c_reg = &tps_regulators[i]; 606 607 if (c_reg->is_enabled) { 608 if (c_reg->is_ls) 609 aprint_normal("[%s: LS] ", c_reg->name); 610 else if (c_reg->is_xadj) 611 aprint_normal("[%s: XADJ] ", c_reg->name); 612 else 613 aprint_normal("[%s: %d mV] ", c_reg->name, 614 c_reg->current_voltage); 615 } 616 } 617 aprint_normal("\n"); 618 } 619 620 static void 621 tps65217pmic_print_ppath(struct tps65217pmic_softc *sc) 622 { 623 uint8_t status, ppath; 624 625 ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH); 626 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS); 627 628 aprint_normal_dev(sc->sc_dev, "power sources "); 629 630 if (ppath & TPS65217PMIC_PPATH_USB_EN) { 631 if (status & TPS65217PMIC_STATUS_USBPWR) 632 aprint_normal("[USB] "); 633 else 634 aprint_normal("USB "); 635 aprint_normal("max %d mA, ", 636 tps65217pmic_ppath_max_usb_current(ppath)); 637 } 638 639 if (ppath & TPS65217PMIC_PPATH_AC_EN) { 640 if (status & TPS65217PMIC_STATUS_ACPWR) 641 aprint_normal("[AC] "); 642 else 643 aprint_normal("AC "); 644 aprint_normal("max %d mA", 645 tps65217pmic_ppath_max_ac_current(ppath)); 646 } 647 648 aprint_normal("\n"); 649 } 650 651 static uint8_t 652 tps65217pmic_reg_read(struct tps65217pmic_softc *sc, uint8_t reg) 653 { 654 uint8_t wbuf[2]; 655 uint8_t rv; 656 657 if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL) != 0) { 658 aprint_error_dev(sc->sc_dev, "cannot acquire bus for read\n"); 659 return 0; 660 } 661 662 wbuf[0] = reg; 663 664 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, wbuf, 665 1, &rv, 1, I2C_F_POLL)) { 666 aprint_error_dev(sc->sc_dev, "cannot execute operation\n"); 667 iic_release_bus(sc->sc_tag, I2C_F_POLL); 668 return 0; 669 } 670 iic_release_bus(sc->sc_tag, I2C_F_POLL); 671 672 return rv; 673 } 674 675 static void 676 tps65217pmic_reg_write_unlocked(struct tps65217pmic_softc *sc, 677 uint8_t reg, uint8_t data) 678 { 679 uint8_t wbuf[2]; 680 681 wbuf[0] = reg; 682 wbuf[1] = data; 683 684 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, NULL, 0, 685 wbuf, 2, I2C_F_POLL)) { 686 aprint_error_dev(sc->sc_dev, "cannot execute I2C write\n"); 687 } 688 } 689 690 static void __unused 691 tps65217pmic_reg_write(struct tps65217pmic_softc *sc, uint8_t reg, uint8_t data) 692 { 693 694 if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL) != 0) { 695 aprint_error_dev(sc->sc_dev, "cannot acquire bus for write\n"); 696 return; 697 } 698 699 tps65217pmic_reg_write_unlocked(sc, reg, data); 700 701 iic_release_bus(sc->sc_tag, I2C_F_POLL); 702 } 703 704 static void 705 tps65217pmic_reg_write_l2(struct tps65217pmic_softc *sc, 706 uint8_t reg, uint8_t data) 707 { 708 uint8_t regpw = reg ^ TPS65217PMIC_PASSWORD_XOR; 709 if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL) != 0) { 710 aprint_error_dev(sc->sc_dev, "cannot acquire bus for write\n"); 711 return; 712 } 713 714 tps65217pmic_reg_write_unlocked(sc, TPS65217PMIC_PASSWORD, regpw); 715 tps65217pmic_reg_write_unlocked(sc, reg, data); 716 tps65217pmic_reg_write_unlocked(sc, TPS65217PMIC_PASSWORD, regpw); 717 tps65217pmic_reg_write_unlocked(sc, reg, data); 718 iic_release_bus(sc->sc_tag, I2C_F_POLL); 719 } 720 721 static void 722 tps65217pmic_envsys_register(struct tps65217pmic_softc *sc) 723 { 724 int i; 725 726 sc->sc_sme = sysmon_envsys_create(); 727 728 /* iterate over all regulators and attach them as sensors */ 729 for(i = 0; i <= SNUM_REGS; i++) { 730 /* set name */ 731 strlcpy(sc->sc_regsensor[i].desc, tps_regulators[i].name, 732 sizeof(sc->sc_regsensor[i].desc)); 733 sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC; 734 sc->sc_regsensor[i].state = ENVSYS_SINVALID; 735 736 if (sysmon_envsys_sensor_attach(sc->sc_sme, 737 &sc->sc_regsensor[i])) 738 aprint_error_dev(sc->sc_dev, 739 "error attaching regulator sensor %d\n", i); 740 } 741 742 /* attach power source indicators */ 743 strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */ 744 sc->sc_usbsensor.units = ENVSYS_INDICATOR; 745 sc->sc_usbsensor.state = ENVSYS_SINVALID; 746 if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor)) 747 aprint_error_dev(sc->sc_dev, 748 "error attaching USB power source sensor\n"); 749 strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */ 750 sc->sc_acsensor.units = ENVSYS_INDICATOR; 751 sc->sc_acsensor.state = ENVSYS_SINVALID; 752 if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor)) 753 aprint_error_dev(sc->sc_dev, 754 "error attaching AC power source sensor\n"); 755 756 /* register everything in sysmon */ 757 sc->sc_sme->sme_name = device_xname(sc->sc_dev); 758 sc->sc_sme->sme_cookie = sc; 759 sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh; 760 761 if (sysmon_envsys_register(sc->sc_sme)) { 762 aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n"); 763 sysmon_envsys_destroy(sc->sc_sme); 764 } 765 } 766 767 static void 768 tps65217pmic_envsys_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 769 { 770 struct tps65217pmic_softc *sc = sme->sme_cookie; 771 772 mutex_enter(&sc->sc_lock); 773 774 tps65217pmic_reg_refresh(sc); 775 776 if (edata->sensor <= SNUM_REGS) { 777 /* TODO: handle special cases like LS, XADJ... */ 778 edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000; 779 edata->state = ENVSYS_SVALID; 780 } else if (edata->sensor == SNUM_USBSTATUS) { 781 edata->value_cur = sc->sc_usbstatus && sc->sc_usbenabled; 782 edata->state = ENVSYS_SVALID; 783 } else if (edata->sensor == SNUM_ACSTATUS) { 784 edata->value_cur = sc->sc_acstatus && sc->sc_acenabled; 785 edata->state = ENVSYS_SVALID; 786 } else 787 aprint_error_dev(sc->sc_dev, "unknown sensor number\n"); 788 789 mutex_exit(&sc->sc_lock); 790 } 791 792 int 793 tps65217pmic_set_volt(device_t self, const char *name, int mvolt) 794 { 795 int i; 796 struct tps65217pmic_softc *sc = device_private(self); 797 struct tps_reg_param *regulator = NULL; 798 uint8_t val; 799 800 for (i = 0; i < __arraycount(tps_regulators); i++) { 801 if (strcmp(name, tps_regulators[i].name) == 0) { 802 regulator = &tps_regulators[i]; 803 break; 804 } 805 } 806 if (regulator == NULL) 807 return EINVAL; 808 809 if (regulator->voltage_min > mvolt || regulator->voltage_max < mvolt) 810 return EINVAL; 811 812 if (!regulator->is_enabled) 813 return EINVAL; 814 815 if (regulator->is_tracking) 816 return EINVAL; 817 818 if (regulator->is_xadj) 819 return EINVAL; 820 821 /* find closest voltage entry */ 822 for (i = 0; i < regulator->nvoltages; i++) { 823 if (mvolt <= regulator->voltages[i]) { 824 break; 825 } 826 } 827 KASSERT(i < regulator->nvoltages); 828 tps65217pmic_reg_write_l2(sc, regulator->defreg_num, i); 829 830 val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW); 831 val |= TPS65217PMIC_DEFSLEW_GO; 832 tps65217pmic_reg_write_l2(sc, TPS65217PMIC_DEFSLEW, val); 833 834 while (val & TPS65217PMIC_DEFSLEW_GO) { 835 val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW); 836 } 837 return 0; 838 } 839