1/* $NetBSD: tps65217pmic.c,v 1.20 2021/08/07 16:19:11 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.20 2021/08/07 16:19:11 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 66struct tps_reg_param; 67 68struct 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 96struct tps65217reg_softc { 97 device_t sc_dev; 98 int sc_phandle; 99 struct tps_reg_param *sc_param; 100}; 101 102struct tps65217reg_attach_args { 103 struct tps_reg_param *reg_param; 104 int reg_phandle; 105}; 106 107/* Voltage regulators */ 108enum 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 118struct 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 151static int tps65217pmic_match(device_t, cfdata_t, void *); 152static void tps65217pmic_attach(device_t, device_t, void *); 153 154static int tps65217pmic_i2c_lock(struct tps65217pmic_softc *); 155static void tps65217pmic_i2c_unlock(struct tps65217pmic_softc *); 156 157static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *, uint8_t); 158static void tps65217pmic_reg_write(struct tps65217pmic_softc *, uint8_t, 159 uint8_t); 160 161static void tps65217pmic_reg_refresh(struct tps65217pmic_softc *); 162 163static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t); 164static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t); 165 166static void tps65217pmic_regulator_read_config(struct tps65217pmic_softc *, 167 struct tps_reg_param *); 168 169static void tps65217pmic_print_ppath(struct tps65217pmic_softc *); 170static void tps65217pmic_print_ldos(struct tps65217pmic_softc *); 171 172static void tps65217pmic_version(struct tps65217pmic_softc *); 173 174static void tps65217pmic_envsys_register(struct tps65217pmic_softc *); 175static void tps65217pmic_envsys_refresh(struct sysmon_envsys *, envsys_data_t *); 176 177static void tps65217pmic_power_monitor_init(struct tps65217pmic_softc *); 178static void tps65217pmic_power_monitor(void *); 179 180static void tps65217pmic_wled_init(struct tps65217pmic_softc *, int, int, int); 181 182CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc), 183 tps65217pmic_match, tps65217pmic_attach, NULL, NULL); 184 185#ifdef FDT 186static void tps65217pmic_regulator_attach(struct tps65217pmic_softc *); 187#endif 188 189/* Possible settings of LDO1 in mV. */ 190static 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. */ 193static 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. */ 200static 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 205static 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 299static bool matched = false; 300 301static const struct device_compatible_entry compat_data[] = { 302 { .compat = "ti,tps65217" }, 303 DEVICE_COMPAT_EOL 304}; 305 306static int 307tps65217pmic_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 325static void 326tps65217pmic_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_phandle = ia->ia_cookie; 339 sc->sc_tag = ia->ia_tag; 340 341 dict = device_properties(self); 342 if (prop_dictionary_get_int32(dict, "isel", &isel)) { 343 prop_dictionary_get_int32(dict, "fdim", &fdim); 344 prop_dictionary_get_int32(dict, "brightness", &brightness); 345 } else 346 isel = -1; 347 348 tps65217pmic_version(sc); 349 350 aprint_normal(": TPS65217"); 351 switch (sc->sc_version) { 352 case TPS65217PMIC_CHIPID_VER_A: 353 aprint_normal("A"); 354 break; 355 case TPS65217PMIC_CHIPID_VER_B: 356 aprint_normal("B"); 357 break; 358 case TPS65217PMIC_CHIPID_VER_C: 359 aprint_normal("C"); 360 break; 361 case TPS65217PMIC_CHIPID_VER_D: 362 aprint_normal("D"); 363 break; 364 default: 365 /* unknown version */ 366 break; 367 } 368 369 aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n", 370 sc->sc_revision); 371 372 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 373 374 sc->sc_smpsw.smpsw_name = device_xname(self); 375 sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER; 376 sysmon_pswitch_register(&sc->sc_smpsw); 377 378 tps65217pmic_reg_refresh(sc); 379 380 tps65217pmic_print_ppath(sc); 381 tps65217pmic_print_ldos(sc); 382 383 tps65217pmic_power_monitor_init(sc); 384 385 if (isel != -1) 386 tps65217pmic_wled_init(sc, isel, fdim, brightness); 387 388 tps65217pmic_envsys_register(sc); 389 390#ifdef FDT 391 tps65217pmic_regulator_attach(sc); 392#endif 393} 394 395static void 396tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc) 397{ 398 uint8_t intr, intrmask, status, ppath; 399 400 intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM | 401 TPS65217PMIC_INT_PBM; 402 403 if (tps65217pmic_i2c_lock(sc) != 0) { 404 aprint_error_dev(sc->sc_dev, 405 "failed to initialize power monitor\n"); 406 return; 407 } 408 409 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS); 410 ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH); 411 /* acknowledge and disregard whatever interrupt was generated earlier */ 412 intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT); 413 414 tps65217pmic_i2c_unlock(sc); 415 416 sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR; 417 sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR; 418 sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN; 419 sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN; 420 421 if (intr & intrmask) 422 aprint_normal_dev(sc->sc_dev, 423 "WARNING: hardware interrupt enabled but not supported"); 424 425 /* set up callout to poll for power source changes */ 426 callout_init(&sc->sc_powerpollco, 0); 427 callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc); 428 429 callout_schedule(&sc->sc_powerpollco, hz); 430} 431 432static void 433tps65217pmic_power_monitor_task(void *aux) 434{ 435 struct tps65217pmic_softc *sc; 436 uint8_t status; 437 bool usbstatus, acstatus; 438 439 sc = aux; 440 441 mutex_enter(&sc->sc_lock); 442 443 if (tps65217pmic_i2c_lock(sc) != 0) { 444 device_printf(sc->sc_dev, 445 "WARNING: unable to perform power monitor task.\n"); 446 return; 447 } 448 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS); 449 tps65217pmic_i2c_unlock(sc); 450 451 usbstatus = status & TPS65217PMIC_STATUS_USBPWR; 452 acstatus = status & TPS65217PMIC_STATUS_ACPWR; 453 454 if (usbstatus != sc->sc_usbstatus) { 455 sc->sc_usbstatus = usbstatus; 456 pmf_event_inject(NULL, PMFE_POWER_CHANGED); 457 if (usbstatus) 458 aprint_normal_dev(sc->sc_dev, 459 "USB power source connected\n"); 460 else 461 aprint_normal_dev(sc->sc_dev, 462 "USB power source disconnected\n"); 463 } 464 465 if (acstatus != sc->sc_acstatus) { 466 sc->sc_acstatus = acstatus; 467 pmf_event_inject(NULL, PMFE_POWER_CHANGED); 468 if (acstatus) { 469 sysmon_pswitch_event(&sc->sc_smpsw, 470 PSWITCH_EVENT_PRESSED); 471 } else { 472 sysmon_pswitch_event(&sc->sc_smpsw, 473 PSWITCH_EVENT_RELEASED); 474 } 475 } 476 477 mutex_exit(&sc->sc_lock); 478 479 callout_schedule(&sc->sc_powerpollco, hz); 480} 481 482static void 483tps65217pmic_power_monitor(void *aux) 484{ 485 sysmon_task_queue_sched(0, tps65217pmic_power_monitor_task, aux); 486} 487 488static void 489tps65217pmic_wled_init(struct tps65217pmic_softc *sc, int isel, int fdim, 490 int brightness) 491{ 492 uint8_t val = 0; 493 494 switch (isel) { 495 case 1: 496 case 2: 497 val |= ((isel - 1) << TPS65217PMIC_WLEDCTRL1_ISEL); 498 break; 499 default: 500 aprint_error_dev(sc->sc_dev, 501 "WLED ISET selection is 1 or 2: isel %d\n", isel); 502 return; 503 } 504 switch (fdim) { 505 case 100: 506 val |= TPS65217PMIC_WLEDCTRL1_FDIM_100Hz; 507 break; 508 case 200: 509 val |= TPS65217PMIC_WLEDCTRL1_FDIM_200Hz; 510 break; 511 case 500: 512 val |= TPS65217PMIC_WLEDCTRL1_FDIM_500Hz; 513 break; 514 case 1000: 515 val |= TPS65217PMIC_WLEDCTRL1_FDIM_1000Hz; 516 break; 517 default: 518 aprint_error_dev(sc->sc_dev, 519 "WLED PWM dimming frequency is 100, 200, 500 or 1000:" 520 " fdim %d\n", fdim); 521 return; 522 } 523 if (brightness > 100 || 524 brightness < 0) { 525 aprint_error_dev(sc->sc_dev, 526 "invalid brightness: between 0 and 100: %d\n", brightness); 527 return; 528 } 529 530 if (tps65217pmic_i2c_lock(sc) != 0) { 531 device_printf(sc->sc_dev, 532 "WARNING: unable to configure LED\n"); 533 return; 534 } 535 536 tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val); 537 tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL2, 538 (brightness - 1) & TPS65217PMIC_WLEDCTRL2_DUTY); 539 val |= TPS65217PMIC_WLEDCTRL1_ISINK_EN; 540 tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val); 541 542 tps65217pmic_i2c_unlock(sc); 543} 544 545static void 546tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc) 547{ 548 int i; 549 struct tps_reg_param *c_reg; 550 551 if (tps65217pmic_i2c_lock(sc) != 0) { 552 device_printf(sc->sc_dev, 553 "WARNING: unable to refresh regulators\n"); 554 return; 555 } 556 557 for (i = 0; i < NTPS_REG; i++) { 558 c_reg = &tps_regulators[i]; 559 tps65217pmic_regulator_read_config(sc, c_reg); 560 } 561 562 tps65217pmic_i2c_unlock(sc); 563} 564 565/* Get version and revision of the chip. */ 566static void 567tps65217pmic_version(struct tps65217pmic_softc *sc) 568{ 569 uint8_t chipid; 570 571 if (tps65217pmic_i2c_lock(sc) != 0) { 572 device_printf(sc->sc_dev, 573 "WARNING: unable to get chip ID\n"); 574 return; 575 } 576 577 chipid = tps65217pmic_reg_read(sc, TPS65217PMIC_CHIPID); 578 579 tps65217pmic_i2c_unlock(sc); 580 581 sc->sc_version = chipid & TPS65217PMIC_CHIPID_VER_MASK; 582 sc->sc_revision = chipid & TPS65217PMIC_CHIPID_REV_MASK; 583} 584 585static uint16_t 586tps65217pmic_ppath_max_ac_current(uint8_t ppath) 587{ 588 switch ((ppath & TPS65217PMIC_PPATH_IAC) >> 589 TPS65217PMIC_PPATH_IAC_RSHFIT) { 590 case TPS65217PMIC_PPATH_IAC_100MA: 591 return 100; 592 case TPS65217PMIC_PPATH_IAC_500MA: 593 return 500; 594 case TPS65217PMIC_PPATH_IAC_1300MA: 595 return 1300; 596 case TPS65217PMIC_PPATH_IAC_2500MA: 597 return 2500; 598 } 599 return 0; 600} 601 602static uint16_t 603tps65217pmic_ppath_max_usb_current(uint8_t ppath) 604{ 605 switch (ppath & TPS65217PMIC_PPATH_IUSB) { 606 case TPS65217PMIC_PPATH_IUSB_100MA: 607 return 100; 608 case TPS65217PMIC_PPATH_IUSB_500MA: 609 return 500; 610 case TPS65217PMIC_PPATH_IUSB_1300MA: 611 return 1300; 612 case TPS65217PMIC_PPATH_IUSB_1800MA: 613 return 1800; 614 } 615 return 0; 616} 617 618/* Read regulator state and save it to tps_reg_param. */ 619static void 620tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct 621 tps_reg_param *regulator) 622{ 623 uint8_t defreg, regenable; 624 uint16_t voltage; 625 626 regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE); 627 628 if (regenable & (regulator->enable_bit)) 629 regulator->is_enabled = true; 630 else { 631 regulator->is_enabled = false; 632 return; 633 } 634 635 defreg = tps65217pmic_reg_read(sc, 636 regulator->defreg_num); 637 638 switch (regulator->nvoltages) { 639 case 16: 640 voltage = regulator->voltages[defreg & 641 TPS65217PMIC_DEFX_VOLTAGE_16]; 642 break; 643 case 32: 644 voltage = regulator->voltages[defreg & 645 TPS65217PMIC_DEFX_VOLTAGE_32]; 646 break; 647 case 64: 648 voltage = regulator->voltages[defreg & 649 TPS65217PMIC_DEFX_VOLTAGE_64]; 650 break; 651 default: 652 /* unsupported number of voltage settings? */ 653 voltage = 0; 654 break; 655 } 656 657 /* Handle regulator tracking other regulator voltage. */ 658 if (regulator->can_track) 659 if (defreg & TPS65217PMIC_DEFX_TRACKING) { 660 regulator->is_tracking = true; 661 voltage = 0; /* see regulator->tracked_reg */ 662 } 663 664 /* Handle regulator configured into load switch mode. */ 665 if (regulator->can_ls) 666 if (!(defreg & TPS65217PMIC_DEFX_LS)) { 667 regulator->is_ls = true; 668 voltage = 0; 669 } 670 671 if (regulator->can_xadj) 672 if (defreg & TPS65217PMIC_DEFX_XADJ) { 673 regulator->is_xadj = true; 674 voltage = 0; 675 676 } 677 678 /* TODO: add PGOOD checking */ 679 680 regulator->current_voltage = voltage; 681} 682 683static void 684tps65217pmic_print_ldos(struct tps65217pmic_softc *sc) 685{ 686 int i; 687 struct tps_reg_param *c_reg; 688 689 aprint_normal_dev(sc->sc_dev, ""); 690 691 for (i = 0; i < NTPS_REG; i++) { 692 c_reg = &tps_regulators[i]; 693 694 if (c_reg->is_enabled) { 695 if (c_reg->is_ls) 696 aprint_normal("[%s: LS] ", c_reg->name); 697 else if (c_reg->is_xadj) 698 aprint_normal("[%s: XADJ] ", c_reg->name); 699 else 700 aprint_normal("[%s: %d mV] ", c_reg->name, 701 c_reg->current_voltage); 702 } 703 } 704 aprint_normal("\n"); 705} 706 707static void 708tps65217pmic_print_ppath(struct tps65217pmic_softc *sc) 709{ 710 uint8_t status, ppath; 711 712 ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH); 713 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS); 714 715 aprint_normal_dev(sc->sc_dev, "power sources "); 716 717 if (ppath & TPS65217PMIC_PPATH_USB_EN) { 718 if (status & TPS65217PMIC_STATUS_USBPWR) 719 aprint_normal("[USB] "); 720 else 721 aprint_normal("USB "); 722 aprint_normal("max %d mA, ", 723 tps65217pmic_ppath_max_usb_current(ppath)); 724 } 725 726 if (ppath & TPS65217PMIC_PPATH_AC_EN) { 727 if (status & TPS65217PMIC_STATUS_ACPWR) 728 aprint_normal("[AC] "); 729 else 730 aprint_normal("AC "); 731 aprint_normal("max %d mA", 732 tps65217pmic_ppath_max_ac_current(ppath)); 733 } 734 735 aprint_normal("\n"); 736} 737 738static int 739tps65217pmic_i2c_lock(struct tps65217pmic_softc *sc) 740{ 741 int error; 742 743 error = iic_acquire_bus(sc->sc_tag, 0); 744 if (error) { 745 device_printf(sc->sc_dev, 746 "unable to acquire i2c bus, error %d\n", error); 747 } 748 return error; 749} 750 751static void 752tps65217pmic_i2c_unlock(struct tps65217pmic_softc *sc) 753{ 754 iic_release_bus(sc->sc_tag, 0); 755} 756 757static uint8_t 758tps65217pmic_reg_read(struct tps65217pmic_softc *sc, uint8_t reg) 759{ 760 uint8_t wbuf[2]; 761 uint8_t rv; 762 763 wbuf[0] = reg; 764 765 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, wbuf, 766 1, &rv, 1, 0)) { 767 aprint_error_dev(sc->sc_dev, "cannot execute operation\n"); 768 iic_release_bus(sc->sc_tag, 0); 769 return 0; 770 } 771 772 return rv; 773} 774 775static void 776tps65217pmic_reg_write(struct tps65217pmic_softc *sc, 777 uint8_t reg, uint8_t data) 778{ 779 uint8_t wbuf[2]; 780 781 wbuf[0] = reg; 782 wbuf[1] = data; 783 784 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, NULL, 0, 785 wbuf, 2, 0)) { 786 aprint_error_dev(sc->sc_dev, "cannot execute I2C write\n"); 787 } 788} 789 790static void 791tps65217pmic_reg_write_l2(struct tps65217pmic_softc *sc, 792 uint8_t reg, uint8_t data) 793{ 794 uint8_t regpw = reg ^ TPS65217PMIC_PASSWORD_XOR; 795 796 if (tps65217pmic_i2c_lock(sc)) 797 return; 798 799 tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw); 800 tps65217pmic_reg_write(sc, reg, data); 801 tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw); 802 tps65217pmic_reg_write(sc, reg, data); 803 804 tps65217pmic_i2c_unlock(sc); 805} 806 807static void 808tps65217pmic_envsys_register(struct tps65217pmic_softc *sc) 809{ 810 int i; 811 812 sc->sc_sme = sysmon_envsys_create(); 813 814 /* iterate over all regulators and attach them as sensors */ 815 for(i = 0; i <= SNUM_REGS; i++) { 816 /* set name */ 817 strlcpy(sc->sc_regsensor[i].desc, tps_regulators[i].name, 818 sizeof(sc->sc_regsensor[i].desc)); 819 sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC; 820 sc->sc_regsensor[i].state = ENVSYS_SINVALID; 821 822 if (sysmon_envsys_sensor_attach(sc->sc_sme, 823 &sc->sc_regsensor[i])) 824 aprint_error_dev(sc->sc_dev, 825 "error attaching regulator sensor %d\n", i); 826 } 827 828 /* attach power source indicators */ 829 strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */ 830 sc->sc_usbsensor.units = ENVSYS_INDICATOR; 831 sc->sc_usbsensor.state = ENVSYS_SINVALID; 832 if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor)) 833 aprint_error_dev(sc->sc_dev, 834 "error attaching USB power source sensor\n"); 835 strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */ 836 sc->sc_acsensor.units = ENVSYS_INDICATOR; 837 sc->sc_acsensor.state = ENVSYS_SINVALID; 838 if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor)) 839 aprint_error_dev(sc->sc_dev, 840 "error attaching AC power source sensor\n"); 841 842 /* register everything in sysmon */ 843 sc->sc_sme->sme_name = device_xname(sc->sc_dev); 844 sc->sc_sme->sme_cookie = sc; 845 sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh; 846 847 if (sysmon_envsys_register(sc->sc_sme)) { 848 aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n"); 849 sysmon_envsys_destroy(sc->sc_sme); 850 } 851} 852 853static void 854tps65217pmic_envsys_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 855{ 856 struct tps65217pmic_softc *sc = sme->sme_cookie; 857 858 mutex_enter(&sc->sc_lock); 859 860 tps65217pmic_reg_refresh(sc); 861 862 if (edata->sensor <= SNUM_REGS) { 863 /* TODO: handle special cases like LS, XADJ... */ 864 edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000; 865 edata->state = ENVSYS_SVALID; 866 } else if (edata->sensor == SNUM_USBSTATUS) { 867 edata->value_cur = sc->sc_usbstatus && sc->sc_usbenabled; 868 edata->state = ENVSYS_SVALID; 869 } else if (edata->sensor == SNUM_ACSTATUS) { 870 edata->value_cur = sc->sc_acstatus && sc->sc_acenabled; 871 edata->state = ENVSYS_SVALID; 872 } else 873 aprint_error_dev(sc->sc_dev, "unknown sensor number\n"); 874 875 mutex_exit(&sc->sc_lock); 876} 877 878int 879tps65217pmic_set_volt(device_t self, const char *name, int mvolt) 880{ 881 int i; 882 struct tps65217pmic_softc *sc = device_private(self); 883 struct tps_reg_param *regulator = NULL; 884 uint8_t val; 885 886 for (i = 0; i < __arraycount(tps_regulators); i++) { 887 if (strcmp(name, tps_regulators[i].name) == 0) { 888 regulator = &tps_regulators[i]; 889 break; 890 } 891 } 892 if (regulator == NULL) 893 return EINVAL; 894 895 if (regulator->voltage_min > mvolt || regulator->voltage_max < mvolt) 896 return EINVAL; 897 898 if (!regulator->is_enabled) 899 return EINVAL; 900 901 if (regulator->is_tracking) 902 return EINVAL; 903 904 if (regulator->is_xadj) 905 return EINVAL; 906 907 /* find closest voltage entry */ 908 for (i = 0; i < regulator->nvoltages; i++) { 909 if (mvolt <= regulator->voltages[i]) { 910 break; 911 } 912 } 913 KASSERT(i < regulator->nvoltages); 914 tps65217pmic_reg_write_l2(sc, regulator->defreg_num, i); 915 916 val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW); 917 val |= TPS65217PMIC_DEFSLEW_GO; 918 tps65217pmic_reg_write_l2(sc, TPS65217PMIC_DEFSLEW, val); 919 920 while (val & TPS65217PMIC_DEFSLEW_GO) { 921 val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW); 922 } 923 924 regulator->current_voltage = regulator->voltages[i]; 925 926 return 0; 927} 928 929#ifdef FDT 930static struct tps_reg_param * 931tps65217pmic_get_params(const char *name) 932{ 933 int i; 934 935 for (i = 0; i < __arraycount(tps_regulators); i++) { 936 if (strcmp(name, tps_regulators[i].name) == 0) 937 return &tps_regulators[i]; 938 } 939 940 return NULL; 941} 942 943static void 944tps65217pmic_regulator_attach(struct tps65217pmic_softc *sc) 945{ 946 struct tps65217reg_attach_args raa; 947 struct tps_reg_param *param; 948 const char *compat_name; 949 int phandle, child; 950 951 phandle = of_find_firstchild_byname(sc->sc_phandle, "regulators"); 952 if (phandle <= 0) 953 return; 954 955 for (child = OF_child(phandle); child; child = OF_peer(child)) { 956 compat_name = fdtbus_get_string(child, "regulator-compatible"); 957 if (compat_name == NULL) 958 continue; 959 param = tps65217pmic_get_params(compat_name); 960 if (param == NULL) 961 continue; 962 963 raa.reg_param = param; 964 raa.reg_phandle = child; 965 config_found(sc->sc_dev, &raa, NULL, CFARGS_NONE); 966 } 967} 968 969static int 970tps65217reg_acquire(device_t dev) 971{ 972 return 0; 973} 974 975static void 976tps65217reg_release(device_t dev) 977{ 978} 979 980static int 981tps65217reg_enable(device_t dev, bool enable) 982{ 983 struct tps65217reg_softc *sc = device_private(dev); 984 struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev)); 985 struct tps_reg_param *regulator = sc->sc_param; 986 uint8_t val; 987 int error; 988 989 error = tps65217pmic_i2c_lock(pmic_sc); 990 if (error != 0) 991 return error; 992 993 val = tps65217pmic_reg_read(pmic_sc, TPS65217PMIC_ENABLE); 994 if (enable) 995 val |= regulator->enable_bit; 996 else 997 val &= ~regulator->enable_bit; 998 tps65217pmic_reg_write(pmic_sc, TPS65217PMIC_ENABLE, val); 999 1000 regulator->is_enabled = enable; 1001 1002 tps65217pmic_i2c_unlock(pmic_sc); 1003 1004 return 0; 1005} 1006 1007static int 1008tps65217reg_set_voltage(device_t dev, u_int min_uvol, u_int max_uvol) 1009{ 1010 struct tps65217reg_softc *sc = device_private(dev); 1011 struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev)); 1012 struct tps_reg_param *regulator = sc->sc_param; 1013 int error; 1014 1015 error = tps65217pmic_i2c_lock(pmic_sc); 1016 if (error != 0) 1017 return error; 1018 1019 error = tps65217pmic_set_volt(pmic_sc->sc_dev, regulator->name, min_uvol / 1000); 1020 1021 tps65217pmic_i2c_unlock(pmic_sc); 1022 1023 return error; 1024} 1025 1026static int 1027tps65217reg_get_voltage(device_t dev, u_int *puvol) 1028{ 1029 struct tps65217reg_softc *sc = device_private(dev); 1030 struct tps_reg_param *regulator = sc->sc_param; 1031 1032 *puvol = (u_int)regulator->current_voltage * 1000; 1033 1034 return 0; 1035} 1036 1037static struct fdtbus_regulator_controller_func tps65217reg_funcs = { 1038 .acquire = tps65217reg_acquire, 1039 .release = tps65217reg_release, 1040 .enable = tps65217reg_enable, 1041 .set_voltage = tps65217reg_set_voltage, 1042 .get_voltage = tps65217reg_get_voltage, 1043}; 1044 1045static int 1046tps65217reg_match(device_t parent, cfdata_t match, void *aux) 1047{ 1048 return 1; 1049} 1050 1051static void 1052tps65217reg_attach(device_t parent, device_t self, void *aux) 1053{ 1054 struct tps65217reg_softc *sc = device_private(self); 1055 struct tps65217reg_attach_args *raa = aux; 1056 const char *regname; 1057 1058 sc->sc_dev = self; 1059 sc->sc_phandle = raa->reg_phandle; 1060 sc->sc_param = raa->reg_param; 1061 1062 fdtbus_register_regulator_controller(self, sc->sc_phandle, 1063 &tps65217reg_funcs); 1064 1065 regname = fdtbus_get_string(sc->sc_phandle, "regulator-name"); 1066 if (regname == NULL) 1067 regname = fdtbus_get_string(sc->sc_phandle, "regulator-compatible"); 1068 1069 aprint_naive("\n"); 1070 if (regname != NULL) 1071 aprint_normal(": %s\n", regname); 1072 else 1073 aprint_normal("\n"); 1074} 1075 1076CFATTACH_DECL_NEW(tps65217reg, sizeof (struct tps65217reg_softc), 1077 tps65217reg_match, tps65217reg_attach, NULL, NULL); 1078 1079#endif 1080