1 /* $NetBSD: tps65217pmic.c,v 1.21 2025/09/17 13:49: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 "opt_fdt.h" 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.21 2025/09/17 13:49:13 thorpej Exp $"); 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/device.h> 45 #include <sys/kernel.h> 46 #include <sys/mutex.h> 47 48 #include <sys/bus.h> 49 #include <dev/i2c/i2cvar.h> 50 51 #include <dev/sysmon/sysmonvar.h> 52 #include <dev/sysmon/sysmon_taskq.h> 53 54 #include <dev/i2c/tps65217pmicreg.h> 55 #include <dev/i2c/tps65217pmicvar.h> 56 57 #ifdef FDT 58 #include <dev/fdt/fdtvar.h> 59 #endif 60 61 #define NTPS_REG 7 62 #define SNUM_REGS NTPS_REG-1 63 #define SNUM_USBSTATUS NTPS_REG 64 #define SNUM_ACSTATUS NTPS_REG+1 65 66 struct tps_reg_param; 67 68 struct tps65217pmic_softc { 69 device_t sc_dev; 70 71 i2c_tag_t sc_tag; 72 i2c_addr_t sc_addr; 73 int sc_phandle; 74 75 uint8_t sc_version; 76 uint8_t sc_revision; 77 78 kmutex_t sc_lock; 79 80 bool sc_acstatus; 81 bool sc_usbstatus; 82 bool sc_acenabled; 83 bool sc_usbenabled; 84 85 callout_t sc_powerpollco; 86 87 /* sysmon(4) stuff */ 88 struct sysmon_envsys *sc_sme; 89 envsys_data_t sc_regsensor[NTPS_REG]; 90 envsys_data_t sc_acsensor; 91 envsys_data_t sc_usbsensor; 92 93 struct sysmon_pswitch sc_smpsw; 94 }; 95 96 struct tps65217reg_softc { 97 device_t sc_dev; 98 int sc_phandle; 99 struct tps_reg_param *sc_param; 100 }; 101 102 struct tps65217reg_attach_args { 103 struct tps_reg_param *reg_param; 104 int reg_phandle; 105 }; 106 107 /* Voltage regulators */ 108 enum tps_reg_num { 109 TPS65217PMIC_LDO1, 110 TPS65217PMIC_LDO2, 111 TPS65217PMIC_LDO3LS, 112 TPS65217PMIC_LDO4LS, 113 TPS65217PMIC_DCDC1, 114 TPS65217PMIC_DCDC2, 115 TPS65217PMIC_DCDC3 116 }; 117 118 struct tps_reg_param { 119 /* parameters configured statically */ 120 121 const char* name; 122 uint16_t voltage_min; /* in mV */ 123 uint16_t voltage_max; /* in mV */ 124 const uint16_t *voltages; /* all possible voltage settings */ 125 uint8_t nvoltages; /* number of voltage settings */ 126 127 bool can_track; /* regulator can track U of other r. */ 128 struct tps_reg_param *tracked_reg; /* ptr to tracked regulator */ 129 bool can_xadj; /* voltage can be adjusted externally */ 130 bool can_ls; /* can be a load switch instead of r. */ 131 132 uint8_t defreg_num; /* DEF register */ 133 uint8_t enable_bit; /* position in ENABLE register */ 134 135 /* 136 * Run-time parameters configured during attachment and later, these 137 * probably should be split into separate struct that would be a part 138 * of softc. But since we can have only one TPS chip, that should be 139 * okay for now. 140 */ 141 142 bool is_enabled; /* regulator is enabled */ 143 bool is_pg; /* regulator is "power good" */ 144 bool is_tracking; /* voltage is tracking other reg. */ 145 bool is_ls; /* is a load switch */ 146 bool is_xadj; /* voltage is adjusted externally */ 147 148 uint16_t current_voltage; /* in mV */ 149 }; 150 151 static int tps65217pmic_match(device_t, cfdata_t, void *); 152 static void tps65217pmic_attach(device_t, device_t, void *); 153 154 static int tps65217pmic_i2c_lock(struct tps65217pmic_softc *); 155 static void tps65217pmic_i2c_unlock(struct tps65217pmic_softc *); 156 157 static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *, uint8_t); 158 static void tps65217pmic_reg_write(struct tps65217pmic_softc *, uint8_t, 159 uint8_t); 160 161 static void tps65217pmic_reg_refresh(struct tps65217pmic_softc *); 162 163 static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t); 164 static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t); 165 166 static void tps65217pmic_regulator_read_config(struct tps65217pmic_softc *, 167 struct tps_reg_param *); 168 169 static void tps65217pmic_print_ppath(struct tps65217pmic_softc *); 170 static void tps65217pmic_print_ldos(struct tps65217pmic_softc *); 171 172 static void tps65217pmic_version(struct tps65217pmic_softc *); 173 174 static void tps65217pmic_envsys_register(struct tps65217pmic_softc *); 175 static void tps65217pmic_envsys_refresh(struct sysmon_envsys *, envsys_data_t *); 176 177 static void tps65217pmic_power_monitor_init(struct tps65217pmic_softc *); 178 static void tps65217pmic_power_monitor(void *); 179 180 static void tps65217pmic_wled_init(struct tps65217pmic_softc *, int, int, int); 181 182 CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc), 183 tps65217pmic_match, tps65217pmic_attach, NULL, NULL); 184 185 #ifdef FDT 186 static void tps65217pmic_regulator_attach(struct tps65217pmic_softc *); 187 #endif 188 189 /* Possible settings of LDO1 in mV. */ 190 static const uint16_t ldo1voltages[] = { 1000, 1100, 1200, 1250, 1300, 1350, 191 1400, 1500, 1600, 1800, 2500, 2750, 2800, 3000, 3100, 3300 }; 192 /* Possible settings of LDO2, DCDC1, DCDC2, DCDC3 in mV. */ 193 static const uint16_t ldo2voltages[] = { 900, 925, 950, 975, 1000, 1025, 1050, 194 1075, 1100, 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, 1325, 1350, 195 1375, 1400, 1425, 1450, 1475, 1500, 1550, 1600, 1650, 1700, 1750, 1800, 196 1850, 1900, 1950, 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400, 197 2450, 2500, 2550, 2600, 2650, 2700, 2750, 2800, 2850, 2900, 3000, 3100, 198 3200, 3300, 3300, 3300, 3300, 3300, 3300, 3300, 3300 }; 199 /* Possible settings of LDO3, LDO4 in mV. */ 200 static const uint16_t ldo3voltages[] = { 1500, 1550, 1600, 1650, 1700, 1750, 201 1800, 1850, 1900, 2000, 2100, 2200, 2300, 2400, 2450, 2500, 2550, 2600, 202 2650, 2700, 2750, 2800, 2850, 2900,2950, 3000, 3050, 3100, 3150, 3200, 203 3250, 3300 }; 204 205 static struct tps_reg_param tps_regulators[] = { 206 { 207 .name = "ldo1", 208 .voltage_min = 1000, 209 .voltage_max = 3300, 210 .voltages = ldo1voltages, 211 .nvoltages = 16, 212 .can_track = false, 213 .tracked_reg = NULL, 214 .can_xadj = false, 215 .can_ls = false, 216 .defreg_num = TPS65217PMIC_DEFLDO1, 217 .enable_bit = TPS65217PMIC_ENABLE_LDO1 218 }, 219 { 220 .name = "ldo2", 221 .voltage_min = 900, 222 .voltage_max = 3300, 223 .voltages = ldo2voltages, 224 .nvoltages = 64, 225 .can_track = true, 226 .tracked_reg = &(tps_regulators[TPS65217PMIC_DCDC3]), 227 .can_xadj = false, 228 .can_ls = false, 229 .defreg_num = TPS65217PMIC_DEFLDO2, 230 .enable_bit = TPS65217PMIC_ENABLE_LDO2 231 }, 232 { 233 .name = "ldo3", 234 .voltage_min = 1500, 235 .voltage_max = 3300, 236 .voltages = ldo3voltages, 237 .nvoltages = 32, 238 .can_track = false, 239 .tracked_reg = NULL, 240 .can_xadj = false, 241 .can_ls = true, 242 .defreg_num = TPS65217PMIC_DEFLDO3, 243 .enable_bit = TPS65217PMIC_ENABLE_LDO3 244 }, 245 { 246 .name = "ldo4", 247 .voltage_min = 1500, 248 .voltage_max = 3300, 249 .voltages = ldo3voltages, 250 .nvoltages = 32, 251 .can_track = false, 252 .tracked_reg = NULL, 253 .can_xadj = false, 254 .can_ls = true, 255 .defreg_num = TPS65217PMIC_DEFLDO4, 256 .enable_bit = TPS65217PMIC_ENABLE_LDO4 257 }, 258 { 259 .name = "dcdc1", 260 .voltage_min = 900, 261 .voltage_max = 3300, 262 .voltages = ldo2voltages, 263 .nvoltages = 64, 264 .can_track = false, 265 .tracked_reg = NULL, 266 .can_xadj = true, 267 .can_ls = false, 268 .defreg_num = TPS65217PMIC_DEFDCDC1, 269 .enable_bit = TPS65217PMIC_ENABLE_DCDC1 270 }, 271 { 272 .name = "dcdc2", 273 .voltage_min = 900, 274 .voltage_max = 3300, 275 .voltages = ldo2voltages, 276 .nvoltages = 64, 277 .can_track = false, 278 .tracked_reg = NULL, 279 .can_xadj = true, 280 .can_ls = false, 281 .defreg_num = TPS65217PMIC_DEFDCDC2, 282 .enable_bit = TPS65217PMIC_ENABLE_DCDC2 283 }, 284 { 285 .name = "dcdc3", 286 .voltage_min = 900, 287 .voltage_max = 3300, 288 .voltages = ldo2voltages, 289 .nvoltages = 64, 290 .can_track = false, 291 .tracked_reg = NULL, 292 .can_xadj = true, 293 .can_ls = false, 294 .defreg_num = TPS65217PMIC_DEFDCDC3, 295 .enable_bit = TPS65217PMIC_ENABLE_DCDC3 296 } 297 }; 298 299 static bool matched = false; 300 301 static const struct device_compatible_entry compat_data[] = { 302 { .compat = "ti,tps65217" }, 303 DEVICE_COMPAT_EOL 304 }; 305 306 static int 307 tps65217pmic_match(device_t parent, cfdata_t cf, void *aux) 308 { 309 struct i2c_attach_args *ia = aux; 310 int match_result; 311 312 if (iic_use_direct_match(ia, cf, compat_data, &match_result)) 313 return match_result; 314 315 if (ia->ia_addr == TPS65217PMIC_ADDR) { 316 /* we can only have one */ 317 if (matched) 318 return 0; 319 320 return I2C_MATCH_ADDRESS_ONLY; 321 } 322 return 0; 323 } 324 325 static void 326 tps65217pmic_attach(device_t parent, device_t self, void *aux) 327 { 328 struct tps65217pmic_softc *sc = device_private(self); 329 struct i2c_attach_args *ia = aux; 330 prop_dictionary_t dict; 331 int isel, fdim, brightness; 332 333 /* XXXJRT But what if you have multiple i2c busses? */ 334 matched = true; 335 336 sc->sc_dev = self; 337 sc->sc_addr = ia->ia_addr; 338 sc->sc_tag = ia->ia_tag; 339 340 #ifdef FDT 341 if (devhandle_type(device_handle(self)) == DEVHANDLE_TYPE_OF) { 342 sc->sc_phandle = devhandle_to_of(device_handle(self)); 343 } 344 #endif 345 346 dict = device_properties(self); 347 if (prop_dictionary_get_int32(dict, "isel", &isel)) { 348 prop_dictionary_get_int32(dict, "fdim", &fdim); 349 prop_dictionary_get_int32(dict, "brightness", &brightness); 350 } else 351 isel = -1; 352 353 tps65217pmic_version(sc); 354 355 aprint_normal(": TPS65217"); 356 switch (sc->sc_version) { 357 case TPS65217PMIC_CHIPID_VER_A: 358 aprint_normal("A"); 359 break; 360 case TPS65217PMIC_CHIPID_VER_B: 361 aprint_normal("B"); 362 break; 363 case TPS65217PMIC_CHIPID_VER_C: 364 aprint_normal("C"); 365 break; 366 case TPS65217PMIC_CHIPID_VER_D: 367 aprint_normal("D"); 368 break; 369 default: 370 /* unknown version */ 371 break; 372 } 373 374 aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n", 375 sc->sc_revision); 376 377 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 378 379 sc->sc_smpsw.smpsw_name = device_xname(self); 380 sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER; 381 sysmon_pswitch_register(&sc->sc_smpsw); 382 383 tps65217pmic_reg_refresh(sc); 384 385 tps65217pmic_print_ppath(sc); 386 tps65217pmic_print_ldos(sc); 387 388 tps65217pmic_power_monitor_init(sc); 389 390 if (isel != -1) 391 tps65217pmic_wled_init(sc, isel, fdim, brightness); 392 393 tps65217pmic_envsys_register(sc); 394 395 #ifdef FDT 396 tps65217pmic_regulator_attach(sc); 397 #endif 398 } 399 400 static void 401 tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc) 402 { 403 uint8_t intr, intrmask, status, ppath; 404 405 intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM | 406 TPS65217PMIC_INT_PBM; 407 408 if (tps65217pmic_i2c_lock(sc) != 0) { 409 aprint_error_dev(sc->sc_dev, 410 "failed to initialize power monitor\n"); 411 return; 412 } 413 414 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS); 415 ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH); 416 /* acknowledge and disregard whatever interrupt was generated earlier */ 417 intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT); 418 419 tps65217pmic_i2c_unlock(sc); 420 421 sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR; 422 sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR; 423 sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN; 424 sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN; 425 426 if (intr & intrmask) 427 aprint_normal_dev(sc->sc_dev, 428 "WARNING: hardware interrupt enabled but not supported"); 429 430 /* set up callout to poll for power source changes */ 431 callout_init(&sc->sc_powerpollco, 0); 432 callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc); 433 434 callout_schedule(&sc->sc_powerpollco, hz); 435 } 436 437 static void 438 tps65217pmic_power_monitor_task(void *aux) 439 { 440 struct tps65217pmic_softc *sc; 441 uint8_t status; 442 bool usbstatus, acstatus; 443 444 sc = aux; 445 446 mutex_enter(&sc->sc_lock); 447 448 if (tps65217pmic_i2c_lock(sc) != 0) { 449 device_printf(sc->sc_dev, 450 "WARNING: unable to perform power monitor task.\n"); 451 return; 452 } 453 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS); 454 tps65217pmic_i2c_unlock(sc); 455 456 usbstatus = status & TPS65217PMIC_STATUS_USBPWR; 457 acstatus = status & TPS65217PMIC_STATUS_ACPWR; 458 459 if (usbstatus != sc->sc_usbstatus) { 460 sc->sc_usbstatus = usbstatus; 461 pmf_event_inject(NULL, PMFE_POWER_CHANGED); 462 if (usbstatus) 463 aprint_normal_dev(sc->sc_dev, 464 "USB power source connected\n"); 465 else 466 aprint_normal_dev(sc->sc_dev, 467 "USB power source disconnected\n"); 468 } 469 470 if (acstatus != sc->sc_acstatus) { 471 sc->sc_acstatus = acstatus; 472 pmf_event_inject(NULL, PMFE_POWER_CHANGED); 473 if (acstatus) { 474 sysmon_pswitch_event(&sc->sc_smpsw, 475 PSWITCH_EVENT_PRESSED); 476 } else { 477 sysmon_pswitch_event(&sc->sc_smpsw, 478 PSWITCH_EVENT_RELEASED); 479 } 480 } 481 482 mutex_exit(&sc->sc_lock); 483 484 callout_schedule(&sc->sc_powerpollco, hz); 485 } 486 487 static void 488 tps65217pmic_power_monitor(void *aux) 489 { 490 sysmon_task_queue_sched(0, tps65217pmic_power_monitor_task, aux); 491 } 492 493 static void 494 tps65217pmic_wled_init(struct tps65217pmic_softc *sc, int isel, int fdim, 495 int brightness) 496 { 497 uint8_t val = 0; 498 499 switch (isel) { 500 case 1: 501 case 2: 502 val |= ((isel - 1) << TPS65217PMIC_WLEDCTRL1_ISEL); 503 break; 504 default: 505 aprint_error_dev(sc->sc_dev, 506 "WLED ISET selection is 1 or 2: isel %d\n", isel); 507 return; 508 } 509 switch (fdim) { 510 case 100: 511 val |= TPS65217PMIC_WLEDCTRL1_FDIM_100Hz; 512 break; 513 case 200: 514 val |= TPS65217PMIC_WLEDCTRL1_FDIM_200Hz; 515 break; 516 case 500: 517 val |= TPS65217PMIC_WLEDCTRL1_FDIM_500Hz; 518 break; 519 case 1000: 520 val |= TPS65217PMIC_WLEDCTRL1_FDIM_1000Hz; 521 break; 522 default: 523 aprint_error_dev(sc->sc_dev, 524 "WLED PWM dimming frequency is 100, 200, 500 or 1000:" 525 " fdim %d\n", fdim); 526 return; 527 } 528 if (brightness > 100 || 529 brightness < 0) { 530 aprint_error_dev(sc->sc_dev, 531 "invalid brightness: between 0 and 100: %d\n", brightness); 532 return; 533 } 534 535 if (tps65217pmic_i2c_lock(sc) != 0) { 536 device_printf(sc->sc_dev, 537 "WARNING: unable to configure LED\n"); 538 return; 539 } 540 541 tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val); 542 tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL2, 543 (brightness - 1) & TPS65217PMIC_WLEDCTRL2_DUTY); 544 val |= TPS65217PMIC_WLEDCTRL1_ISINK_EN; 545 tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val); 546 547 tps65217pmic_i2c_unlock(sc); 548 } 549 550 static void 551 tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc) 552 { 553 int i; 554 struct tps_reg_param *c_reg; 555 556 if (tps65217pmic_i2c_lock(sc) != 0) { 557 device_printf(sc->sc_dev, 558 "WARNING: unable to refresh regulators\n"); 559 return; 560 } 561 562 for (i = 0; i < NTPS_REG; i++) { 563 c_reg = &tps_regulators[i]; 564 tps65217pmic_regulator_read_config(sc, c_reg); 565 } 566 567 tps65217pmic_i2c_unlock(sc); 568 } 569 570 /* Get version and revision of the chip. */ 571 static void 572 tps65217pmic_version(struct tps65217pmic_softc *sc) 573 { 574 uint8_t chipid; 575 576 if (tps65217pmic_i2c_lock(sc) != 0) { 577 device_printf(sc->sc_dev, 578 "WARNING: unable to get chip ID\n"); 579 return; 580 } 581 582 chipid = tps65217pmic_reg_read(sc, TPS65217PMIC_CHIPID); 583 584 tps65217pmic_i2c_unlock(sc); 585 586 sc->sc_version = chipid & TPS65217PMIC_CHIPID_VER_MASK; 587 sc->sc_revision = chipid & TPS65217PMIC_CHIPID_REV_MASK; 588 } 589 590 static uint16_t 591 tps65217pmic_ppath_max_ac_current(uint8_t ppath) 592 { 593 switch ((ppath & TPS65217PMIC_PPATH_IAC) >> 594 TPS65217PMIC_PPATH_IAC_RSHFIT) { 595 case TPS65217PMIC_PPATH_IAC_100MA: 596 return 100; 597 case TPS65217PMIC_PPATH_IAC_500MA: 598 return 500; 599 case TPS65217PMIC_PPATH_IAC_1300MA: 600 return 1300; 601 case TPS65217PMIC_PPATH_IAC_2500MA: 602 return 2500; 603 } 604 return 0; 605 } 606 607 static uint16_t 608 tps65217pmic_ppath_max_usb_current(uint8_t ppath) 609 { 610 switch (ppath & TPS65217PMIC_PPATH_IUSB) { 611 case TPS65217PMIC_PPATH_IUSB_100MA: 612 return 100; 613 case TPS65217PMIC_PPATH_IUSB_500MA: 614 return 500; 615 case TPS65217PMIC_PPATH_IUSB_1300MA: 616 return 1300; 617 case TPS65217PMIC_PPATH_IUSB_1800MA: 618 return 1800; 619 } 620 return 0; 621 } 622 623 /* Read regulator state and save it to tps_reg_param. */ 624 static void 625 tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct 626 tps_reg_param *regulator) 627 { 628 uint8_t defreg, regenable; 629 uint16_t voltage; 630 631 regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE); 632 633 if (regenable & (regulator->enable_bit)) 634 regulator->is_enabled = true; 635 else { 636 regulator->is_enabled = false; 637 return; 638 } 639 640 defreg = tps65217pmic_reg_read(sc, 641 regulator->defreg_num); 642 643 switch (regulator->nvoltages) { 644 case 16: 645 voltage = regulator->voltages[defreg & 646 TPS65217PMIC_DEFX_VOLTAGE_16]; 647 break; 648 case 32: 649 voltage = regulator->voltages[defreg & 650 TPS65217PMIC_DEFX_VOLTAGE_32]; 651 break; 652 case 64: 653 voltage = regulator->voltages[defreg & 654 TPS65217PMIC_DEFX_VOLTAGE_64]; 655 break; 656 default: 657 /* unsupported number of voltage settings? */ 658 voltage = 0; 659 break; 660 } 661 662 /* Handle regulator tracking other regulator voltage. */ 663 if (regulator->can_track) 664 if (defreg & TPS65217PMIC_DEFX_TRACKING) { 665 regulator->is_tracking = true; 666 voltage = 0; /* see regulator->tracked_reg */ 667 } 668 669 /* Handle regulator configured into load switch mode. */ 670 if (regulator->can_ls) 671 if (!(defreg & TPS65217PMIC_DEFX_LS)) { 672 regulator->is_ls = true; 673 voltage = 0; 674 } 675 676 if (regulator->can_xadj) 677 if (defreg & TPS65217PMIC_DEFX_XADJ) { 678 regulator->is_xadj = true; 679 voltage = 0; 680 681 } 682 683 /* TODO: add PGOOD checking */ 684 685 regulator->current_voltage = voltage; 686 } 687 688 static void 689 tps65217pmic_print_ldos(struct tps65217pmic_softc *sc) 690 { 691 int i; 692 struct tps_reg_param *c_reg; 693 694 aprint_normal_dev(sc->sc_dev, ""); 695 696 for (i = 0; i < NTPS_REG; i++) { 697 c_reg = &tps_regulators[i]; 698 699 if (c_reg->is_enabled) { 700 if (c_reg->is_ls) 701 aprint_normal("[%s: LS] ", c_reg->name); 702 else if (c_reg->is_xadj) 703 aprint_normal("[%s: XADJ] ", c_reg->name); 704 else 705 aprint_normal("[%s: %d mV] ", c_reg->name, 706 c_reg->current_voltage); 707 } 708 } 709 aprint_normal("\n"); 710 } 711 712 static void 713 tps65217pmic_print_ppath(struct tps65217pmic_softc *sc) 714 { 715 uint8_t status, ppath; 716 717 ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH); 718 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS); 719 720 aprint_normal_dev(sc->sc_dev, "power sources "); 721 722 if (ppath & TPS65217PMIC_PPATH_USB_EN) { 723 if (status & TPS65217PMIC_STATUS_USBPWR) 724 aprint_normal("[USB] "); 725 else 726 aprint_normal("USB "); 727 aprint_normal("max %d mA, ", 728 tps65217pmic_ppath_max_usb_current(ppath)); 729 } 730 731 if (ppath & TPS65217PMIC_PPATH_AC_EN) { 732 if (status & TPS65217PMIC_STATUS_ACPWR) 733 aprint_normal("[AC] "); 734 else 735 aprint_normal("AC "); 736 aprint_normal("max %d mA", 737 tps65217pmic_ppath_max_ac_current(ppath)); 738 } 739 740 aprint_normal("\n"); 741 } 742 743 static int 744 tps65217pmic_i2c_lock(struct tps65217pmic_softc *sc) 745 { 746 int error; 747 748 error = iic_acquire_bus(sc->sc_tag, 0); 749 if (error) { 750 device_printf(sc->sc_dev, 751 "unable to acquire i2c bus, error %d\n", error); 752 } 753 return error; 754 } 755 756 static void 757 tps65217pmic_i2c_unlock(struct tps65217pmic_softc *sc) 758 { 759 iic_release_bus(sc->sc_tag, 0); 760 } 761 762 static uint8_t 763 tps65217pmic_reg_read(struct tps65217pmic_softc *sc, uint8_t reg) 764 { 765 uint8_t wbuf[2]; 766 uint8_t rv; 767 768 wbuf[0] = reg; 769 770 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, wbuf, 771 1, &rv, 1, 0)) { 772 aprint_error_dev(sc->sc_dev, "cannot execute operation\n"); 773 iic_release_bus(sc->sc_tag, 0); 774 return 0; 775 } 776 777 return rv; 778 } 779 780 static void 781 tps65217pmic_reg_write(struct tps65217pmic_softc *sc, 782 uint8_t reg, uint8_t data) 783 { 784 uint8_t wbuf[2]; 785 786 wbuf[0] = reg; 787 wbuf[1] = data; 788 789 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, NULL, 0, 790 wbuf, 2, 0)) { 791 aprint_error_dev(sc->sc_dev, "cannot execute I2C write\n"); 792 } 793 } 794 795 static void 796 tps65217pmic_reg_write_l2(struct tps65217pmic_softc *sc, 797 uint8_t reg, uint8_t data) 798 { 799 uint8_t regpw = reg ^ TPS65217PMIC_PASSWORD_XOR; 800 801 if (tps65217pmic_i2c_lock(sc)) 802 return; 803 804 tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw); 805 tps65217pmic_reg_write(sc, reg, data); 806 tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw); 807 tps65217pmic_reg_write(sc, reg, data); 808 809 tps65217pmic_i2c_unlock(sc); 810 } 811 812 static void 813 tps65217pmic_envsys_register(struct tps65217pmic_softc *sc) 814 { 815 int i; 816 817 sc->sc_sme = sysmon_envsys_create(); 818 819 /* iterate over all regulators and attach them as sensors */ 820 for(i = 0; i <= SNUM_REGS; i++) { 821 /* set name */ 822 strlcpy(sc->sc_regsensor[i].desc, tps_regulators[i].name, 823 sizeof(sc->sc_regsensor[i].desc)); 824 sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC; 825 sc->sc_regsensor[i].state = ENVSYS_SINVALID; 826 827 if (sysmon_envsys_sensor_attach(sc->sc_sme, 828 &sc->sc_regsensor[i])) 829 aprint_error_dev(sc->sc_dev, 830 "error attaching regulator sensor %d\n", i); 831 } 832 833 /* attach power source indicators */ 834 strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */ 835 sc->sc_usbsensor.units = ENVSYS_INDICATOR; 836 sc->sc_usbsensor.state = ENVSYS_SINVALID; 837 if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor)) 838 aprint_error_dev(sc->sc_dev, 839 "error attaching USB power source sensor\n"); 840 strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */ 841 sc->sc_acsensor.units = ENVSYS_INDICATOR; 842 sc->sc_acsensor.state = ENVSYS_SINVALID; 843 if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor)) 844 aprint_error_dev(sc->sc_dev, 845 "error attaching AC power source sensor\n"); 846 847 /* register everything in sysmon */ 848 sc->sc_sme->sme_name = device_xname(sc->sc_dev); 849 sc->sc_sme->sme_cookie = sc; 850 sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh; 851 852 if (sysmon_envsys_register(sc->sc_sme)) { 853 aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n"); 854 sysmon_envsys_destroy(sc->sc_sme); 855 } 856 } 857 858 static void 859 tps65217pmic_envsys_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 860 { 861 struct tps65217pmic_softc *sc = sme->sme_cookie; 862 863 mutex_enter(&sc->sc_lock); 864 865 tps65217pmic_reg_refresh(sc); 866 867 if (edata->sensor <= SNUM_REGS) { 868 /* TODO: handle special cases like LS, XADJ... */ 869 edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000; 870 edata->state = ENVSYS_SVALID; 871 } else if (edata->sensor == SNUM_USBSTATUS) { 872 edata->value_cur = sc->sc_usbstatus && sc->sc_usbenabled; 873 edata->state = ENVSYS_SVALID; 874 } else if (edata->sensor == SNUM_ACSTATUS) { 875 edata->value_cur = sc->sc_acstatus && sc->sc_acenabled; 876 edata->state = ENVSYS_SVALID; 877 } else 878 aprint_error_dev(sc->sc_dev, "unknown sensor number\n"); 879 880 mutex_exit(&sc->sc_lock); 881 } 882 883 int 884 tps65217pmic_set_volt(device_t self, const char *name, int mvolt) 885 { 886 int i; 887 struct tps65217pmic_softc *sc = device_private(self); 888 struct tps_reg_param *regulator = NULL; 889 uint8_t val; 890 891 for (i = 0; i < __arraycount(tps_regulators); i++) { 892 if (strcmp(name, tps_regulators[i].name) == 0) { 893 regulator = &tps_regulators[i]; 894 break; 895 } 896 } 897 if (regulator == NULL) 898 return EINVAL; 899 900 if (regulator->voltage_min > mvolt || regulator->voltage_max < mvolt) 901 return EINVAL; 902 903 if (!regulator->is_enabled) 904 return EINVAL; 905 906 if (regulator->is_tracking) 907 return EINVAL; 908 909 if (regulator->is_xadj) 910 return EINVAL; 911 912 /* find closest voltage entry */ 913 for (i = 0; i < regulator->nvoltages; i++) { 914 if (mvolt <= regulator->voltages[i]) { 915 break; 916 } 917 } 918 KASSERT(i < regulator->nvoltages); 919 tps65217pmic_reg_write_l2(sc, regulator->defreg_num, i); 920 921 val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW); 922 val |= TPS65217PMIC_DEFSLEW_GO; 923 tps65217pmic_reg_write_l2(sc, TPS65217PMIC_DEFSLEW, val); 924 925 while (val & TPS65217PMIC_DEFSLEW_GO) { 926 val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW); 927 } 928 929 regulator->current_voltage = regulator->voltages[i]; 930 931 return 0; 932 } 933 934 #ifdef FDT 935 static struct tps_reg_param * 936 tps65217pmic_get_params(const char *name) 937 { 938 int i; 939 940 for (i = 0; i < __arraycount(tps_regulators); i++) { 941 if (strcmp(name, tps_regulators[i].name) == 0) 942 return &tps_regulators[i]; 943 } 944 945 return NULL; 946 } 947 948 static void 949 tps65217pmic_regulator_attach(struct tps65217pmic_softc *sc) 950 { 951 struct tps65217reg_attach_args raa; 952 struct tps_reg_param *param; 953 const char *compat_name; 954 int phandle, child; 955 956 phandle = of_find_firstchild_byname(sc->sc_phandle, "regulators"); 957 if (phandle <= 0) 958 return; 959 960 for (child = OF_child(phandle); child; child = OF_peer(child)) { 961 compat_name = fdtbus_get_string(child, "regulator-compatible"); 962 if (compat_name == NULL) 963 continue; 964 param = tps65217pmic_get_params(compat_name); 965 if (param == NULL) 966 continue; 967 968 raa.reg_param = param; 969 raa.reg_phandle = child; 970 config_found(sc->sc_dev, &raa, NULL, CFARGS_NONE); 971 } 972 } 973 974 static int 975 tps65217reg_acquire(device_t dev) 976 { 977 return 0; 978 } 979 980 static void 981 tps65217reg_release(device_t dev) 982 { 983 } 984 985 static int 986 tps65217reg_enable(device_t dev, bool enable) 987 { 988 struct tps65217reg_softc *sc = device_private(dev); 989 struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev)); 990 struct tps_reg_param *regulator = sc->sc_param; 991 uint8_t val; 992 int error; 993 994 error = tps65217pmic_i2c_lock(pmic_sc); 995 if (error != 0) 996 return error; 997 998 val = tps65217pmic_reg_read(pmic_sc, TPS65217PMIC_ENABLE); 999 if (enable) 1000 val |= regulator->enable_bit; 1001 else 1002 val &= ~regulator->enable_bit; 1003 tps65217pmic_reg_write(pmic_sc, TPS65217PMIC_ENABLE, val); 1004 1005 regulator->is_enabled = enable; 1006 1007 tps65217pmic_i2c_unlock(pmic_sc); 1008 1009 return 0; 1010 } 1011 1012 static int 1013 tps65217reg_set_voltage(device_t dev, u_int min_uvol, u_int max_uvol) 1014 { 1015 struct tps65217reg_softc *sc = device_private(dev); 1016 struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev)); 1017 struct tps_reg_param *regulator = sc->sc_param; 1018 int error; 1019 1020 error = tps65217pmic_i2c_lock(pmic_sc); 1021 if (error != 0) 1022 return error; 1023 1024 error = tps65217pmic_set_volt(pmic_sc->sc_dev, regulator->name, min_uvol / 1000); 1025 1026 tps65217pmic_i2c_unlock(pmic_sc); 1027 1028 return error; 1029 } 1030 1031 static int 1032 tps65217reg_get_voltage(device_t dev, u_int *puvol) 1033 { 1034 struct tps65217reg_softc *sc = device_private(dev); 1035 struct tps_reg_param *regulator = sc->sc_param; 1036 1037 *puvol = (u_int)regulator->current_voltage * 1000; 1038 1039 return 0; 1040 } 1041 1042 static struct fdtbus_regulator_controller_func tps65217reg_funcs = { 1043 .acquire = tps65217reg_acquire, 1044 .release = tps65217reg_release, 1045 .enable = tps65217reg_enable, 1046 .set_voltage = tps65217reg_set_voltage, 1047 .get_voltage = tps65217reg_get_voltage, 1048 }; 1049 1050 static int 1051 tps65217reg_match(device_t parent, cfdata_t match, void *aux) 1052 { 1053 return 1; 1054 } 1055 1056 static void 1057 tps65217reg_attach(device_t parent, device_t self, void *aux) 1058 { 1059 struct tps65217reg_softc *sc = device_private(self); 1060 struct tps65217reg_attach_args *raa = aux; 1061 const char *regname; 1062 1063 sc->sc_dev = self; 1064 sc->sc_phandle = raa->reg_phandle; 1065 sc->sc_param = raa->reg_param; 1066 1067 fdtbus_register_regulator_controller(self, sc->sc_phandle, 1068 &tps65217reg_funcs); 1069 1070 regname = fdtbus_get_string(sc->sc_phandle, "regulator-name"); 1071 if (regname == NULL) 1072 regname = fdtbus_get_string(sc->sc_phandle, "regulator-compatible"); 1073 1074 aprint_naive("\n"); 1075 if (regname != NULL) 1076 aprint_normal(": %s\n", regname); 1077 else 1078 aprint_normal("\n"); 1079 } 1080 1081 CFATTACH_DECL_NEW(tps65217reg, sizeof (struct tps65217reg_softc), 1082 tps65217reg_match, tps65217reg_attach, NULL, NULL); 1083 1084 #endif 1085