1/*- 2 * Copyright 2016 Michal Meloun <mmel@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: stable/11/sys/dev/extres/regulator/regulator.c 337705 2018-08-13 08:47:54Z mmel $"); 29 30#include "opt_platform.h" 31#include <sys/param.h> 32#include <sys/conf.h> 33#include <sys/bus.h> 34#include <sys/kernel.h> 35#include <sys/queue.h> 36#include <sys/kobj.h> 37#include <sys/malloc.h> 38#include <sys/mutex.h> 39#include <sys/limits.h> 40#include <sys/lock.h> 41#include <sys/sysctl.h> 42#include <sys/systm.h> 43#include <sys/sx.h> 44 45#ifdef FDT 46#include <dev/fdt/fdt_common.h> 47#include <dev/ofw/ofw_bus.h> 48#include <dev/ofw/ofw_bus_subr.h> 49#endif 50#include <dev/extres/regulator/regulator.h> 51 52#include "regdev_if.h" 53 54MALLOC_DEFINE(M_REGULATOR, "regulator", "Regulator framework"); 55 56#define DIV_ROUND_UP(n,d) howmany(n, d) 57 58/* Forward declarations. */ 59struct regulator; 60struct regnode; 61 62typedef TAILQ_HEAD(regnode_list, regnode) regnode_list_t; 63typedef TAILQ_HEAD(regulator_list, regulator) regulator_list_t; 64 65/* Default regulator methods. */ 66static int regnode_method_enable(struct regnode *regnode, bool enable, 67 int *udelay); 68static int regnode_method_status(struct regnode *regnode, int *status); 69static int regnode_method_set_voltage(struct regnode *regnode, int min_uvolt, 70 int max_uvolt, int *udelay); 71static int regnode_method_get_voltage(struct regnode *regnode, int *uvolt); 72 73/* 74 * Regulator controller methods. 75 */ 76static regnode_method_t regnode_methods[] = { 77 REGNODEMETHOD(regnode_enable, regnode_method_enable), 78 REGNODEMETHOD(regnode_status, regnode_method_status), 79 REGNODEMETHOD(regnode_set_voltage, regnode_method_set_voltage), 80 REGNODEMETHOD(regnode_get_voltage, regnode_method_get_voltage), 81 82 REGNODEMETHOD_END 83}; 84DEFINE_CLASS_0(regnode, regnode_class, regnode_methods, 0); 85 86/* 87 * Regulator node - basic element for modelling SOC and bard power supply 88 * chains. Its contains producer data. 89 */ 90struct regnode { 91 KOBJ_FIELDS; 92 93 TAILQ_ENTRY(regnode) reglist_link; /* Global list entry */ 94 regulator_list_t consumers_list; /* Consumers list */ 95 96 /* Cache for already resolved names */ 97 struct regnode *parent; /* Resolved parent */ 98 99 /* Details of this device. */ 100 const char *name; /* Globally unique name */ 101 const char *parent_name; /* Parent name */ 102 103 device_t pdev; /* Producer device_t */ 104 void *softc; /* Producer softc */ 105 intptr_t id; /* Per producer unique id */ 106#ifdef FDT 107 phandle_t ofw_node; /* OFW node of regulator */ 108#endif 109 int flags; /* REGULATOR_FLAGS_ */ 110 struct sx lock; /* Lock for this regulator */ 111 int ref_cnt; /* Reference counter */ 112 int enable_cnt; /* Enabled counter */ 113 114 struct regnode_std_param std_param; /* Standard parameters */ 115}; 116 117/* 118 * Per consumer data, information about how a consumer is using a regulator 119 * node. 120 * A pointer to this structure is used as a handle in the consumer interface. 121 */ 122struct regulator { 123 device_t cdev; /* Consumer device */ 124 struct regnode *regnode; 125 TAILQ_ENTRY(regulator) link; /* Consumers list entry */ 126 127 int enable_cnt; 128 int min_uvolt; /* Requested uvolt range */ 129 int max_uvolt; 130}; 131 132/* 133 * Regulator names must be system wide unique. 134 */ 135static regnode_list_t regnode_list = TAILQ_HEAD_INITIALIZER(regnode_list); 136 137static struct sx regnode_topo_lock; 138SX_SYSINIT(regulator_topology, ®node_topo_lock, "Regulator topology lock"); 139 140#define REG_TOPO_SLOCK() sx_slock(®node_topo_lock) 141#define REG_TOPO_XLOCK() sx_xlock(®node_topo_lock) 142#define REG_TOPO_UNLOCK() sx_unlock(®node_topo_lock) 143#define REG_TOPO_ASSERT() sx_assert(®node_topo_lock, SA_LOCKED) 144#define REG_TOPO_XASSERT() sx_assert(®node_topo_lock, SA_XLOCKED) 145 146#define REGNODE_SLOCK(_sc) sx_slock(&((_sc)->lock)) 147#define REGNODE_XLOCK(_sc) sx_xlock(&((_sc)->lock)) 148#define REGNODE_UNLOCK(_sc) sx_unlock(&((_sc)->lock)) 149 150/* ---------------------------------------------------------------------------- 151 * 152 * Default regulator methods for base class. 153 * 154 */ 155static int 156regnode_method_enable(struct regnode *regnode, bool enable, int *udelay) 157{ 158 159 if (!enable) 160 return (ENXIO); 161 162 *udelay = 0; 163 return (0); 164} 165 166static int 167regnode_method_status(struct regnode *regnode, int *status) 168{ 169 *status = REGULATOR_STATUS_ENABLED; 170 return (0); 171} 172 173static int 174regnode_method_set_voltage(struct regnode *regnode, int min_uvolt, int max_uvolt, 175 int *udelay) 176{ 177 178 if ((min_uvolt > regnode->std_param.max_uvolt) || 179 (max_uvolt < regnode->std_param.min_uvolt)) 180 return (ERANGE); 181 *udelay = 0; 182 return (0); 183} 184 185static int 186regnode_method_get_voltage(struct regnode *regnode, int *uvolt) 187{ 188 189 return (regnode->std_param.min_uvolt + 190 (regnode->std_param.max_uvolt - regnode->std_param.min_uvolt) / 2); 191} 192 193/* ---------------------------------------------------------------------------- 194 * 195 * Internal functions. 196 * 197 */ 198 199static struct regnode * 200regnode_find_by_name(const char *name) 201{ 202 struct regnode *entry; 203 204 REG_TOPO_ASSERT(); 205 206 TAILQ_FOREACH(entry, ®node_list, reglist_link) { 207 if (strcmp(entry->name, name) == 0) 208 return (entry); 209 } 210 return (NULL); 211} 212 213static struct regnode * 214regnode_find_by_id(device_t dev, intptr_t id) 215{ 216 struct regnode *entry; 217 218 REG_TOPO_ASSERT(); 219 220 TAILQ_FOREACH(entry, ®node_list, reglist_link) { 221 if ((entry->pdev == dev) && (entry->id == id)) 222 return (entry); 223 } 224 225 return (NULL); 226} 227 228/* 229 * Create and initialize regulator object, but do not register it. 230 */ 231struct regnode * 232regnode_create(device_t pdev, regnode_class_t regnode_class, 233 struct regnode_init_def *def) 234{ 235 struct regnode *regnode; 236 237 KASSERT(def->name != NULL, ("regulator name is NULL")); 238 KASSERT(def->name[0] != '\0', ("regulator name is empty")); 239 240 REG_TOPO_SLOCK(); 241 if (regnode_find_by_name(def->name) != NULL) 242 panic("Duplicated regulator registration: %s\n", def->name); 243 REG_TOPO_UNLOCK(); 244 245 /* Create object and initialize it. */ 246 regnode = malloc(sizeof(struct regnode), M_REGULATOR, 247 M_WAITOK | M_ZERO); 248 kobj_init((kobj_t)regnode, (kobj_class_t)regnode_class); 249 sx_init(®node->lock, "Regulator node lock"); 250 251 /* Allocate softc if required. */ 252 if (regnode_class->size > 0) { 253 regnode->softc = malloc(regnode_class->size, M_REGULATOR, 254 M_WAITOK | M_ZERO); 255 } 256 257 258 /* Copy all strings unless they're flagged as static. */ 259 if (def->flags & REGULATOR_FLAGS_STATIC) { 260 regnode->name = def->name; 261 regnode->parent_name = def->parent_name; 262 } else { 263 regnode->name = strdup(def->name, M_REGULATOR); 264 if (def->parent_name != NULL) 265 regnode->parent_name = strdup(def->parent_name, 266 M_REGULATOR); 267 } 268 269 /* Rest of init. */ 270 TAILQ_INIT(®node->consumers_list); 271 regnode->id = def->id; 272 regnode->pdev = pdev; 273 regnode->flags = def->flags; 274 regnode->parent = NULL; 275 regnode->std_param = def->std_param; 276#ifdef FDT 277 regnode->ofw_node = def->ofw_node; 278#endif 279 280 return (regnode); 281} 282 283/* Register regulator object. */ 284struct regnode * 285regnode_register(struct regnode *regnode) 286{ 287 int rv; 288 289#ifdef FDT 290 if (regnode->ofw_node <= 0) 291 regnode->ofw_node = ofw_bus_get_node(regnode->pdev); 292 if (regnode->ofw_node <= 0) 293 return (NULL); 294#endif 295 296 rv = REGNODE_INIT(regnode); 297 if (rv != 0) { 298 printf("REGNODE_INIT failed: %d\n", rv); 299 return (NULL); 300 } 301 302 REG_TOPO_XLOCK(); 303 TAILQ_INSERT_TAIL(®node_list, regnode, reglist_link); 304 REG_TOPO_UNLOCK(); 305#ifdef FDT 306 OF_device_register_xref(OF_xref_from_node(regnode->ofw_node), 307 regnode->pdev); 308#endif 309 return (regnode); 310} 311 312static int 313regnode_resolve_parent(struct regnode *regnode) 314{ 315 316 /* All ready resolved or no parent? */ 317 if ((regnode->parent != NULL) || 318 (regnode->parent_name == NULL)) 319 return (0); 320 321 regnode->parent = regnode_find_by_name(regnode->parent_name); 322 if (regnode->parent == NULL) 323 return (ENODEV); 324 return (0); 325} 326 327static void 328regnode_delay(int usec) 329{ 330 int ticks; 331 332 if (usec == 0) 333 return; 334 ticks = (usec * hz + 999999) / 1000000; 335 336 if (cold || ticks < 2) 337 DELAY(usec); 338 else 339 pause("REGULATOR", ticks); 340} 341 342/* -------------------------------------------------------------------------- 343 * 344 * Regulator providers interface 345 * 346 */ 347 348const char * 349regnode_get_name(struct regnode *regnode) 350{ 351 352 return (regnode->name); 353} 354 355const char * 356regnode_get_parent_name(struct regnode *regnode) 357{ 358 359 return (regnode->parent_name); 360} 361 362int 363regnode_get_flags(struct regnode *regnode) 364{ 365 366 return (regnode->flags); 367} 368 369void * 370regnode_get_softc(struct regnode *regnode) 371{ 372 373 return (regnode->softc); 374} 375 376device_t 377regnode_get_device(struct regnode *regnode) 378{ 379 380 return (regnode->pdev); 381} 382 383struct regnode_std_param *regnode_get_stdparam(struct regnode *regnode) 384{ 385 386 return (®node->std_param); 387} 388 389void regnode_topo_unlock(void) 390{ 391 392 REG_TOPO_UNLOCK(); 393} 394 395void regnode_topo_xlock(void) 396{ 397 398 REG_TOPO_XLOCK(); 399} 400 401void regnode_topo_slock(void) 402{ 403 404 REG_TOPO_SLOCK(); 405} 406 407 408/* -------------------------------------------------------------------------- 409 * 410 * Real consumers executive 411 * 412 */ 413struct regnode * 414regnode_get_parent(struct regnode *regnode) 415{ 416 int rv; 417 418 REG_TOPO_ASSERT(); 419 420 rv = regnode_resolve_parent(regnode); 421 if (rv != 0) 422 return (NULL); 423 424 return (regnode->parent); 425} 426 427/* 428 * Enable regulator. 429 */ 430int 431regnode_enable(struct regnode *regnode) 432{ 433 int udelay; 434 int rv; 435 436 REG_TOPO_ASSERT(); 437 438 /* Enable regulator for each node in chain, starting from source. */ 439 rv = regnode_resolve_parent(regnode); 440 if (rv != 0) 441 return (rv); 442 if (regnode->parent != NULL) { 443 rv = regnode_enable(regnode->parent); 444 if (rv != 0) 445 return (rv); 446 } 447 448 /* Handle this node. */ 449 REGNODE_XLOCK(regnode); 450 if (regnode->enable_cnt == 0) { 451 rv = REGNODE_ENABLE(regnode, true, &udelay); 452 if (rv != 0) { 453 REGNODE_UNLOCK(regnode); 454 return (rv); 455 } 456 regnode_delay(udelay); 457 } 458 regnode->enable_cnt++; 459 REGNODE_UNLOCK(regnode); 460 return (0); 461} 462 463/* 464 * Disable regulator. 465 */ 466int 467regnode_disable(struct regnode *regnode) 468{ 469 int udelay; 470 int rv; 471 472 REG_TOPO_ASSERT(); 473 rv = 0; 474 475 REGNODE_XLOCK(regnode); 476 /* Disable regulator for each node in chain, starting from consumer. */ 477 if ((regnode->enable_cnt == 1) && 478 ((regnode->flags & REGULATOR_FLAGS_NOT_DISABLE) == 0)) { 479 rv = REGNODE_ENABLE(regnode, false, &udelay); 480 if (rv != 0) { 481 REGNODE_UNLOCK(regnode); 482 return (rv); 483 } 484 regnode_delay(udelay); 485 } 486 regnode->enable_cnt--; 487 REGNODE_UNLOCK(regnode); 488 489 rv = regnode_resolve_parent(regnode); 490 if (rv != 0) 491 return (rv); 492 if (regnode->parent != NULL) 493 rv = regnode_disable(regnode->parent); 494 return (rv); 495} 496 497/* 498 * Stop regulator. 499 */ 500int 501regnode_stop(struct regnode *regnode, int depth) 502{ 503 int udelay; 504 int rv; 505 506 REG_TOPO_ASSERT(); 507 rv = 0; 508 509 REGNODE_XLOCK(regnode); 510 /* The first node must not be enabled. */ 511 if ((regnode->enable_cnt != 0) && (depth == 0)) { 512 REGNODE_UNLOCK(regnode); 513 return (EBUSY); 514 } 515 /* Disable regulator for each node in chain, starting from consumer */ 516 if ((regnode->enable_cnt == 0) && 517 ((regnode->flags & REGULATOR_FLAGS_NOT_DISABLE) == 0)) { 518 rv = REGNODE_STOP(regnode, &udelay); 519 if (rv != 0) { 520 REGNODE_UNLOCK(regnode); 521 return (rv); 522 } 523 regnode_delay(udelay); 524 } 525 REGNODE_UNLOCK(regnode); 526 527 rv = regnode_resolve_parent(regnode); 528 if (rv != 0) 529 return (rv); 530 if (regnode->parent != NULL && regnode->parent->enable_cnt == 0) 531 rv = regnode_stop(regnode->parent, depth + 1); 532 return (rv); 533} 534 535/* 536 * Get regulator status. (REGULATOR_STATUS_*) 537 */ 538int 539regnode_status(struct regnode *regnode, int *status) 540{ 541 int rv; 542 543 REG_TOPO_ASSERT(); 544 545 REGNODE_XLOCK(regnode); 546 rv = REGNODE_STATUS(regnode, status); 547 REGNODE_UNLOCK(regnode); 548 return (rv); 549} 550 551/* 552 * Get actual regulator voltage. 553 */ 554int 555regnode_get_voltage(struct regnode *regnode, int *uvolt) 556{ 557 int rv; 558 559 REG_TOPO_ASSERT(); 560 561 REGNODE_XLOCK(regnode); 562 rv = REGNODE_GET_VOLTAGE(regnode, uvolt); 563 REGNODE_UNLOCK(regnode); 564 565 /* Pass call into parent, if regulator is in bypass mode. */ 566 if (rv == ENOENT) { 567 rv = regnode_resolve_parent(regnode); 568 if (rv != 0) 569 return (rv); 570 if (regnode->parent != NULL) 571 rv = regnode_get_voltage(regnode->parent, uvolt); 572 573 } 574 return (rv); 575} 576 577/* 578 * Set regulator voltage. 579 */ 580int 581regnode_set_voltage(struct regnode *regnode, int min_uvolt, int max_uvolt) 582{ 583 int udelay; 584 int rv; 585 586 REG_TOPO_ASSERT(); 587 588 REGNODE_XLOCK(regnode); 589 590 rv = REGNODE_SET_VOLTAGE(regnode, min_uvolt, max_uvolt, &udelay); 591 if (rv == 0) 592 regnode_delay(udelay); 593 REGNODE_UNLOCK(regnode); 594 return (rv); 595} 596 597/* 598 * Consumer variant of regnode_set_voltage(). 599 */ 600static int 601regnode_set_voltage_checked(struct regnode *regnode, struct regulator *reg, 602 int min_uvolt, int max_uvolt) 603{ 604 int udelay; 605 int all_max_uvolt; 606 int all_min_uvolt; 607 struct regulator *tmp; 608 int rv; 609 610 REG_TOPO_ASSERT(); 611 612 REGNODE_XLOCK(regnode); 613 /* Return error if requested range is outside of regulator range. */ 614 if ((min_uvolt > regnode->std_param.max_uvolt) || 615 (max_uvolt < regnode->std_param.min_uvolt)) { 616 REGNODE_UNLOCK(regnode); 617 return (ERANGE); 618 } 619 620 /* Get actual voltage range for all consumers. */ 621 all_min_uvolt = regnode->std_param.min_uvolt; 622 all_max_uvolt = regnode->std_param.max_uvolt; 623 TAILQ_FOREACH(tmp, ®node->consumers_list, link) { 624 /* Don't take requestor in account. */ 625 if (tmp == reg) 626 continue; 627 if (all_min_uvolt < tmp->min_uvolt) 628 all_min_uvolt = tmp->min_uvolt; 629 if (all_max_uvolt > tmp->max_uvolt) 630 all_max_uvolt = tmp->max_uvolt; 631 } 632 633 /* Test if request fits to actual contract. */ 634 if ((min_uvolt > all_max_uvolt) || 635 (max_uvolt < all_min_uvolt)) { 636 REGNODE_UNLOCK(regnode); 637 return (ERANGE); 638 } 639 640 /* Adjust new range.*/ 641 if (min_uvolt < all_min_uvolt) 642 min_uvolt = all_min_uvolt; 643 if (max_uvolt > all_max_uvolt) 644 max_uvolt = all_max_uvolt; 645 646 rv = REGNODE_SET_VOLTAGE(regnode, min_uvolt, max_uvolt, &udelay); 647 regnode_delay(udelay); 648 REGNODE_UNLOCK(regnode); 649 return (rv); 650} 651 652#ifdef FDT 653phandle_t 654regnode_get_ofw_node(struct regnode *regnode) 655{ 656 657 return (regnode->ofw_node); 658} 659#endif 660 661/* -------------------------------------------------------------------------- 662 * 663 * Regulator consumers interface. 664 * 665 */ 666/* Helper function for regulator_get*() */ 667static regulator_t 668regulator_create(struct regnode *regnode, device_t cdev) 669{ 670 struct regulator *reg; 671 672 REG_TOPO_ASSERT(); 673 674 reg = malloc(sizeof(struct regulator), M_REGULATOR, 675 M_WAITOK | M_ZERO); 676 reg->cdev = cdev; 677 reg->regnode = regnode; 678 reg->enable_cnt = 0; 679 680 REGNODE_XLOCK(regnode); 681 regnode->ref_cnt++; 682 TAILQ_INSERT_TAIL(®node->consumers_list, reg, link); 683 reg ->min_uvolt = regnode->std_param.min_uvolt; 684 reg ->max_uvolt = regnode->std_param.max_uvolt; 685 REGNODE_UNLOCK(regnode); 686 687 return (reg); 688} 689 690int 691regulator_enable(regulator_t reg) 692{ 693 int rv; 694 struct regnode *regnode; 695 696 regnode = reg->regnode; 697 KASSERT(regnode->ref_cnt > 0, 698 ("Attempt to access unreferenced regulator: %s\n", regnode->name)); 699 REG_TOPO_SLOCK(); 700 rv = regnode_enable(regnode); 701 if (rv == 0) 702 reg->enable_cnt++; 703 REG_TOPO_UNLOCK(); 704 return (rv); 705} 706 707int 708regulator_disable(regulator_t reg) 709{ 710 int rv; 711 struct regnode *regnode; 712 713 regnode = reg->regnode; 714 KASSERT(regnode->ref_cnt > 0, 715 ("Attempt to access unreferenced regulator: %s\n", regnode->name)); 716 KASSERT(reg->enable_cnt > 0, 717 ("Attempt to disable already disabled regulator: %s\n", 718 regnode->name)); 719 REG_TOPO_SLOCK(); 720 rv = regnode_disable(regnode); 721 if (rv == 0) 722 reg->enable_cnt--; 723 REG_TOPO_UNLOCK(); 724 return (rv); 725} 726 727int 728regulator_stop(regulator_t reg) 729{ 730 int rv; 731 struct regnode *regnode; 732 733 regnode = reg->regnode; 734 KASSERT(regnode->ref_cnt > 0, 735 ("Attempt to access unreferenced regulator: %s\n", regnode->name)); 736 KASSERT(reg->enable_cnt == 0, 737 ("Attempt to stop already enabled regulator: %s\n", regnode->name)); 738 739 REG_TOPO_SLOCK(); 740 rv = regnode_stop(regnode, 0); 741 REG_TOPO_UNLOCK(); 742 return (rv); 743} 744 745int 746regulator_status(regulator_t reg, int *status) 747{ 748 int rv; 749 struct regnode *regnode; 750 751 regnode = reg->regnode; 752 KASSERT(regnode->ref_cnt > 0, 753 ("Attempt to access unreferenced regulator: %s\n", regnode->name)); 754 755 REG_TOPO_SLOCK(); 756 rv = regnode_status(regnode, status); 757 REG_TOPO_UNLOCK(); 758 return (rv); 759} 760 761int 762regulator_get_voltage(regulator_t reg, int *uvolt) 763{ 764 int rv; 765 struct regnode *regnode; 766 767 regnode = reg->regnode; 768 KASSERT(regnode->ref_cnt > 0, 769 ("Attempt to access unreferenced regulator: %s\n", regnode->name)); 770 771 REG_TOPO_SLOCK(); 772 rv = regnode_get_voltage(regnode, uvolt); 773 REG_TOPO_UNLOCK(); 774 return (rv); 775} 776 777int 778regulator_set_voltage(regulator_t reg, int min_uvolt, int max_uvolt) 779{ 780 struct regnode *regnode; 781 int rv; 782 783 regnode = reg->regnode; 784 KASSERT(regnode->ref_cnt > 0, 785 ("Attempt to access unreferenced regulator: %s\n", regnode->name)); 786 787 REG_TOPO_SLOCK(); 788 789 rv = regnode_set_voltage_checked(regnode, reg, min_uvolt, max_uvolt); 790 if (rv == 0) { 791 reg->min_uvolt = min_uvolt; 792 reg->max_uvolt = max_uvolt; 793 } 794 REG_TOPO_UNLOCK(); 795 return (rv); 796} 797 798const char * 799regulator_get_name(regulator_t reg) 800{ 801 struct regnode *regnode; 802 803 regnode = reg->regnode; 804 KASSERT(regnode->ref_cnt > 0, 805 ("Attempt to access unreferenced regulator: %s\n", regnode->name)); 806 return (regnode->name); 807} 808 809int 810regulator_get_by_name(device_t cdev, const char *name, regulator_t *reg) 811{ 812 struct regnode *regnode; 813 814 REG_TOPO_SLOCK(); 815 regnode = regnode_find_by_name(name); 816 if (regnode == NULL) { 817 REG_TOPO_UNLOCK(); 818 return (ENODEV); 819 } 820 *reg = regulator_create(regnode, cdev); 821 REG_TOPO_UNLOCK(); 822 return (0); 823} 824 825int 826regulator_get_by_id(device_t cdev, device_t pdev, intptr_t id, regulator_t *reg) 827{ 828 struct regnode *regnode; 829 830 REG_TOPO_SLOCK(); 831 832 regnode = regnode_find_by_id(pdev, id); 833 if (regnode == NULL) { 834 REG_TOPO_UNLOCK(); 835 return (ENODEV); 836 } 837 *reg = regulator_create(regnode, cdev); 838 REG_TOPO_UNLOCK(); 839 840 return (0); 841} 842 843int 844regulator_release(regulator_t reg) 845{ 846 struct regnode *regnode; 847 848 regnode = reg->regnode; 849 KASSERT(regnode->ref_cnt > 0, 850 ("Attempt to access unreferenced regulator: %s\n", regnode->name)); 851 REG_TOPO_SLOCK(); 852 while (reg->enable_cnt > 0) { 853 regnode_disable(regnode); 854 reg->enable_cnt--; 855 } 856 REGNODE_XLOCK(regnode); 857 TAILQ_REMOVE(®node->consumers_list, reg, link); 858 regnode->ref_cnt--; 859 REGNODE_UNLOCK(regnode); 860 REG_TOPO_UNLOCK(); 861 862 free(reg, M_REGULATOR); 863 return (0); 864} 865 866#ifdef FDT 867/* Default DT mapper. */ 868int 869regdev_default_ofw_map(device_t dev, phandle_t xref, int ncells, 870 pcell_t *cells, intptr_t *id) 871{ 872 if (ncells == 0) 873 *id = 1; 874 else if (ncells == 1) 875 *id = cells[0]; 876 else 877 return (ERANGE); 878 879 return (0); 880} 881 882int 883regulator_parse_ofw_stdparam(device_t pdev, phandle_t node, 884 struct regnode_init_def *def) 885{ 886 phandle_t supply_xref; 887 struct regnode_std_param *par; 888 int rv; 889 890 par = &def->std_param; 891 rv = OF_getprop_alloc(node, "regulator-name", 1, 892 (void **)&def->name); 893 if (rv <= 0) { 894 device_printf(pdev, "%s: Missing regulator name\n", 895 __func__); 896 return (ENXIO); 897 } 898 899 rv = OF_getencprop(node, "regulator-min-microvolt", &par->min_uvolt, 900 sizeof(par->min_uvolt)); 901 if (rv <= 0) 902 par->min_uvolt = 0; 903 904 rv = OF_getencprop(node, "regulator-max-microvolt", &par->max_uvolt, 905 sizeof(par->max_uvolt)); 906 if (rv <= 0) 907 par->max_uvolt = 0; 908 909 rv = OF_getencprop(node, "regulator-min-microamp", &par->min_uamp, 910 sizeof(par->min_uamp)); 911 if (rv <= 0) 912 par->min_uamp = 0; 913 914 rv = OF_getencprop(node, "regulator-max-microamp", &par->max_uamp, 915 sizeof(par->max_uamp)); 916 if (rv <= 0) 917 par->max_uamp = 0; 918 919 rv = OF_getencprop(node, "regulator-ramp-delay", &par->ramp_delay, 920 sizeof(par->ramp_delay)); 921 if (rv <= 0) 922 par->ramp_delay = 0; 923 924 rv = OF_getencprop(node, "regulator-enable-ramp-delay", 925 &par->enable_delay, sizeof(par->enable_delay)); 926 if (rv <= 0) 927 par->enable_delay = 0; 928 929 if (OF_hasprop(node, "regulator-boot-on")) 930 par->boot_on = 1; 931 932 if (OF_hasprop(node, "regulator-always-on")) 933 par->always_on = 1; 934 935 if (OF_hasprop(node, "enable-active-high")) 936 par->enable_active_high = 1; 937 938 rv = OF_getencprop(node, "vin-supply", &supply_xref, 939 sizeof(supply_xref)); 940 if (rv >= 0) { 941 rv = OF_getprop_alloc(supply_xref, "regulator-name", 1, 942 (void **)&def->parent_name); 943 if (rv <= 0) 944 def->parent_name = NULL; 945 } 946 return (0); 947} 948 949int 950regulator_get_by_ofw_property(device_t cdev, phandle_t cnode, char *name, 951 regulator_t *reg) 952{ 953 phandle_t *cells; 954 device_t regdev; 955 int ncells, rv; 956 intptr_t id; 957 958 *reg = NULL; 959 960 if (cnode <= 0) 961 cnode = ofw_bus_get_node(cdev); 962 if (cnode <= 0) { 963 device_printf(cdev, "%s called on not ofw based device\n", 964 __func__); 965 return (ENXIO); 966 } 967 968 cells = NULL; 969 ncells = OF_getencprop_alloc(cnode, name, sizeof(*cells), 970 (void **)&cells); 971 if (ncells <= 0) 972 return (ENXIO); 973 974 /* Translate xref to device */ 975 regdev = OF_device_from_xref(cells[0]); 976 if (regdev == NULL) { 977 OF_prop_free(cells); 978 return (ENODEV); 979 } 980 981 /* Map regulator to number */ 982 rv = REGDEV_MAP(regdev, cells[0], ncells - 1, cells + 1, &id); 983 OF_prop_free(cells); 984 if (rv != 0) 985 return (rv); 986 return (regulator_get_by_id(cdev, regdev, id, reg)); 987} 988#endif 989 990/* -------------------------------------------------------------------------- 991 * 992 * Regulator utility functions. 993 * 994 */ 995 996/* Convert raw selector value to real voltage */ 997int 998regulator_range_sel8_to_volt(struct regulator_range *ranges, int nranges, 999 uint8_t sel, int *volt) 1000{ 1001 struct regulator_range *range; 1002 int i; 1003 1004 if (nranges == 0) 1005 panic("Voltage regulator have zero ranges\n"); 1006 1007 for (i = 0; i < nranges ; i++) { 1008 range = ranges + i; 1009 1010 if (!(sel >= range->min_sel && 1011 sel <= range->max_sel)) 1012 continue; 1013 1014 sel -= range->min_sel; 1015 1016 *volt = range->min_uvolt + sel * range->step_uvolt; 1017 return (0); 1018 } 1019 1020 return (ERANGE); 1021} 1022 1023int 1024regulator_range_volt_to_sel8(struct regulator_range *ranges, int nranges, 1025 int min_uvolt, int max_uvolt, uint8_t *out_sel) 1026{ 1027 struct regulator_range *range; 1028 uint8_t sel; 1029 int uvolt; 1030 int rv, i; 1031 1032 if (nranges == 0) 1033 panic("Voltage regulator have zero ranges\n"); 1034 1035 for (i = 0; i < nranges; i++) { 1036 range = ranges + i; 1037 uvolt = range->min_uvolt + 1038 (range->max_sel - range->min_sel) * range->step_uvolt; 1039 1040 if ((min_uvolt > uvolt) || 1041 (max_uvolt < range->min_uvolt)) 1042 continue; 1043 1044 if (min_uvolt <= range->min_uvolt) 1045 min_uvolt = range->min_uvolt; 1046 1047 /* if step == 0 -> fixed voltage range. */ 1048 if (range->step_uvolt == 0) 1049 sel = 0; 1050 else 1051 sel = DIV_ROUND_UP(min_uvolt - range->min_uvolt, 1052 range->step_uvolt); 1053 1054 1055 sel += range->min_sel; 1056 1057 break; 1058 } 1059 1060 if (i >= nranges) 1061 return (ERANGE); 1062 1063 /* Verify new settings. */ 1064 rv = regulator_range_sel8_to_volt(ranges, nranges, sel, &uvolt); 1065 if (rv != 0) 1066 return (rv); 1067 if ((uvolt < min_uvolt) || (uvolt > max_uvolt)) 1068 return (ERANGE); 1069 1070 *out_sel = sel; 1071 return (0); 1072} 1073