]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/extres/regulator/regulator.c
Merge bmake-20170510
[FreeBSD/FreeBSD.git] / sys / dev / extres / regulator / regulator.c
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$");
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
54 MALLOC_DEFINE(M_REGULATOR, "regulator", "Regulator framework");
55
56 #define DIV_ROUND_UP(n,d) howmany(n, d)
57
58 /* Forward declarations. */
59 struct regulator;
60 struct regnode;
61
62 typedef TAILQ_HEAD(regnode_list, regnode) regnode_list_t;
63 typedef TAILQ_HEAD(regulator_list, regulator) regulator_list_t;
64
65 /* Default regulator methods. */
66 static int regnode_method_enable(struct regnode *regnode, bool enable,
67     int *udelay);
68 static int regnode_method_status(struct regnode *regnode, int *status);
69 static int regnode_method_set_voltage(struct regnode *regnode, int min_uvolt,
70     int max_uvolt, int *udelay);
71 static int regnode_method_get_voltage(struct regnode *regnode, int *uvolt);
72
73 /*
74  * Regulator controller methods.
75  */
76 static 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 };
84 DEFINE_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  */
90 struct 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  */
122 struct 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  */
135 static regnode_list_t regnode_list = TAILQ_HEAD_INITIALIZER(regnode_list);
136
137 static struct sx                regnode_topo_lock;
138 SX_SYSINIT(regulator_topology, &regnode_topo_lock, "Regulator topology lock");
139
140 #define REG_TOPO_SLOCK()        sx_slock(&regnode_topo_lock)
141 #define REG_TOPO_XLOCK()        sx_xlock(&regnode_topo_lock)
142 #define REG_TOPO_UNLOCK()       sx_unlock(&regnode_topo_lock)
143 #define REG_TOPO_ASSERT()       sx_assert(&regnode_topo_lock, SA_LOCKED)
144 #define REG_TOPO_XASSERT()      sx_assert(&regnode_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  */
155 static int
156 regnode_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
166 static int
167 regnode_method_status(struct regnode *regnode, int *status)
168 {
169         *status = REGULATOR_STATUS_ENABLED;
170         return (0);
171 }
172
173 static int
174 regnode_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
185 static int
186 regnode_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
199 static struct regnode *
200 regnode_find_by_name(const char *name)
201 {
202         struct regnode *entry;
203
204         REG_TOPO_ASSERT();
205
206         TAILQ_FOREACH(entry, &regnode_list, reglist_link) {
207                 if (strcmp(entry->name, name) == 0)
208                         return (entry);
209         }
210         return (NULL);
211 }
212
213 static struct regnode *
214 regnode_find_by_id(device_t dev, intptr_t id)
215 {
216         struct regnode *entry;
217
218         REG_TOPO_ASSERT();
219
220         TAILQ_FOREACH(entry, &regnode_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  */
231 struct regnode *
232 regnode_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(&regnode->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(&regnode->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. */
284 struct regnode *
285 regnode_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(&regnode_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
312 static int
313 regnode_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
327 static void
328 regnode_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
348 const char *
349 regnode_get_name(struct regnode *regnode)
350 {
351
352         return (regnode->name);
353 }
354
355 const char *
356 regnode_get_parent_name(struct regnode *regnode)
357 {
358
359         return (regnode->parent_name);
360 }
361
362 int
363 regnode_get_flags(struct regnode *regnode)
364 {
365
366         return (regnode->flags);
367 }
368
369 void *
370 regnode_get_softc(struct regnode *regnode)
371 {
372
373         return (regnode->softc);
374 }
375
376 device_t
377 regnode_get_device(struct regnode *regnode)
378 {
379
380         return (regnode->pdev);
381 }
382
383 struct regnode_std_param *regnode_get_stdparam(struct regnode *regnode)
384 {
385
386         return (&regnode->std_param);
387 }
388
389 void regnode_topo_unlock(void)
390 {
391
392         REG_TOPO_UNLOCK();
393 }
394
395 void regnode_topo_xlock(void)
396 {
397
398         REG_TOPO_XLOCK();
399 }
400
401 void regnode_topo_slock(void)
402 {
403
404         REG_TOPO_SLOCK();
405 }
406
407
408 /* --------------------------------------------------------------------------
409  *
410  * Real consumers executive
411  *
412  */
413 struct regnode *
414 regnode_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  */
430 int
431 regnode_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  */
466 int
467 regnode_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  */
500 int
501 regnode_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_ENABLE(regnode, false, &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)
531                 rv = regnode_stop(regnode->parent, depth + 1);
532         return (rv);
533 }
534
535 /*
536  * Get regulator status. (REGULATOR_STATUS_*)
537  */
538 int
539 regnode_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  */
554 int
555 regnode_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  */
580 int
581 regnode_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  */
600 static int
601 regnode_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, &regnode->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
653 phandle_t
654 regnode_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*() */
667 static regulator_t
668 regulator_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(&regnode->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
690 int
691 regulator_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
707 int
708 regulator_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
727 int
728 regulator_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
745 int
746 regulator_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
761 int
762 regulator_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
777 int
778 regulator_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
798 const char *
799 regulator_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
809 int
810 regulator_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
825 int
826 regulator_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
843 int
844 regulator_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(&regnode->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. */
868 int
869 regdev_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
882 int
883 regulator_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
949 int
950 regulator_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 */
997 int
998 regulator_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
1023 int
1024 regulator_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 }