]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/allwinner/axp81x.c
Expose DC1SW as a regulator switch. On Pine64 this is used to control EMAC
[FreeBSD/FreeBSD.git] / sys / arm / allwinner / axp81x.c
1 /*-
2  * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
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 ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
21  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22  * 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  * $FreeBSD$
27  */
28
29 /*
30  * X-Powers AXP813/818 PMU for Allwinner SoCs
31  */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/eventhandler.h>
39 #include <sys/bus.h>
40 #include <sys/rman.h>
41 #include <sys/kernel.h>
42 #include <sys/reboot.h>
43 #include <sys/gpio.h>
44 #include <sys/module.h>
45 #include <machine/bus.h>
46
47 #include <dev/iicbus/iicbus.h>
48 #include <dev/iicbus/iiconf.h>
49
50 #include <dev/gpio/gpiobusvar.h>
51
52 #include <dev/ofw/ofw_bus.h>
53 #include <dev/ofw/ofw_bus_subr.h>
54
55 #include <dev/extres/regulator/regulator.h>
56
57 #include "gpio_if.h"
58 #include "iicbus_if.h"
59 #include "regdev_if.h"
60
61 MALLOC_DEFINE(M_AXP81X_REG, "AXP81x regulator", "AXP81x power regulator");
62
63 #define AXP_ICTYPE              0x03
64 #define AXP_POWERCTL2           0x12
65 #define  AXP_POWERCTL2_DC1SW    (1 << 7)
66 #define AXP_POWERBAT            0x32
67 #define  AXP_POWERBAT_SHUTDOWN  (1 << 7)
68 #define AXP_IRQEN1              0x40
69 #define AXP_IRQEN2              0x41
70 #define AXP_IRQEN3              0x42
71 #define AXP_IRQEN4              0x43
72 #define AXP_IRQEN5              0x44
73 #define  AXP_IRQEN5_POKSIRQ     (1 << 4)
74 #define AXP_IRQEN6              0x45
75 #define AXP_IRQSTAT5            0x4c
76 #define  AXP_IRQSTAT5_POKSIRQ   (1 << 4)
77 #define AXP_GPIO0_CTRL          0x90
78 #define AXP_GPIO1_CTRL          0x92
79 #define  AXP_GPIO_FUNC          (0x7 << 0)
80 #define  AXP_GPIO_FUNC_SHIFT    0
81 #define  AXP_GPIO_FUNC_DRVLO    0
82 #define  AXP_GPIO_FUNC_DRVHI    1
83 #define  AXP_GPIO_FUNC_INPUT    2
84 #define AXP_GPIO_SIGBIT         0x94
85 #define AXP_GPIO_PD             0x97
86
87 static const struct {
88         const char *name;
89         uint8_t ctrl_reg;
90 } axp81x_pins[] = {
91         { "GPIO0", AXP_GPIO0_CTRL },
92         { "GPIO1", AXP_GPIO1_CTRL },
93 };
94
95 static struct ofw_compat_data compat_data[] = {
96         { "x-powers,axp813",                    1 },
97         { "x-powers,axp818",                    1 },
98         { NULL,                                 0 }
99 };
100
101 static struct resource_spec axp81x_spec[] = {
102         { SYS_RES_IRQ,          0,      RF_ACTIVE },
103         { -1, 0 }
104 };
105
106 struct axp81x_regdef {
107         intptr_t                id;
108         char                    *name;
109         char                    *supply_name;
110         uint8_t                 enable_reg;
111         uint8_t                 enable_mask;
112 };
113
114 enum axp81x_reg_id {
115         AXP81X_REG_ID_DC1SW
116 };
117
118 static struct axp81x_regdef axp81x_regdefs[] = {
119         {
120                 .id = AXP81X_REG_ID_DC1SW,
121                 .name = "dc1sw",
122                 .enable_reg = AXP_POWERCTL2,
123                 .enable_mask = AXP_POWERCTL2_DC1SW,
124         },
125 };
126
127 struct axp81x_softc;
128
129 struct axp81x_reg_sc {
130         struct regnode          *regnode;
131         device_t                base_dev;
132         struct axp81x_regdef    *def;
133         phandle_t               xref;
134         struct regnode_std_param *param;
135 };
136
137 struct axp81x_softc {
138         struct resource         *res;
139         uint16_t                addr;
140         void                    *ih;
141         device_t                gpiodev;
142         struct mtx              mtx;
143         int                     busy;
144
145         /* Regulators */
146         struct axp81x_reg_sc    **regs;
147         int                     nregs;
148 };
149
150 #define AXP_LOCK(sc)    mtx_lock(&(sc)->mtx)
151 #define AXP_UNLOCK(sc)  mtx_unlock(&(sc)->mtx)
152
153 static int
154 axp81x_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
155 {
156         struct axp81x_softc *sc;
157         struct iic_msg msg[2];
158
159         sc = device_get_softc(dev);
160
161         msg[0].slave = sc->addr;
162         msg[0].flags = IIC_M_WR;
163         msg[0].len = 1;
164         msg[0].buf = &reg;
165
166         msg[1].slave = sc->addr;
167         msg[1].flags = IIC_M_RD;
168         msg[1].len = size;
169         msg[1].buf = data;
170
171         return (iicbus_transfer(dev, msg, 2));
172 }
173
174 static int
175 axp81x_write(device_t dev, uint8_t reg, uint8_t val)
176 {
177         struct axp81x_softc *sc;
178         struct iic_msg msg[2];
179
180         sc = device_get_softc(dev);
181
182         msg[0].slave = sc->addr;
183         msg[0].flags = IIC_M_WR;
184         msg[0].len = 1;
185         msg[0].buf = &reg;
186
187         msg[1].slave = sc->addr;
188         msg[1].flags = IIC_M_WR;
189         msg[1].len = 1;
190         msg[1].buf = &val;
191
192         return (iicbus_transfer(dev, msg, 2));
193 }
194
195 static int
196 axp81x_regnode_init(struct regnode *regnode)
197 {
198         return (0);
199 }
200
201 static int
202 axp81x_regnode_enable(struct regnode *regnode, bool enable, int *udelay)
203 {
204         struct axp81x_reg_sc *sc;
205         uint8_t val;
206
207         sc = regnode_get_softc(regnode);
208
209         axp81x_read(sc->base_dev, sc->def->enable_reg, &val, 1);
210         if (enable)
211                 val |= sc->def->enable_mask;
212         else
213                 val &= ~sc->def->enable_mask;
214         axp81x_write(sc->base_dev, sc->def->enable_reg, val);
215
216         *udelay = 0;
217
218         return (0);
219 }
220
221 static int
222 axp81x_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
223     int max_uvolt, int *udelay)
224 {
225         return (ENXIO);
226 }
227
228 static int
229 axp81x_regnode_get_voltage(struct regnode *regnode, int *uvolt)
230 {
231         return (ENXIO);
232 }
233
234 static regnode_method_t axp81x_regnode_methods[] = {
235         /* Regulator interface */
236         REGNODEMETHOD(regnode_init,             axp81x_regnode_init),
237         REGNODEMETHOD(regnode_enable,           axp81x_regnode_enable),
238         REGNODEMETHOD(regnode_set_voltage,      axp81x_regnode_set_voltage),
239         REGNODEMETHOD(regnode_get_voltage,      axp81x_regnode_get_voltage),
240         REGNODEMETHOD_END
241 };
242 DEFINE_CLASS_1(axp81x_regnode, axp81x_regnode_class, axp81x_regnode_methods,
243     sizeof(struct axp81x_reg_sc), regnode_class);
244
245 static void
246 axp81x_shutdown(void *devp, int howto)
247 {
248         device_t dev;
249
250         if ((howto & RB_POWEROFF) == 0)
251                 return;
252
253         dev = devp;
254
255         if (bootverbose)
256                 device_printf(dev, "Shutdown AXP81x\n");
257
258         axp81x_write(dev, AXP_POWERBAT, AXP_POWERBAT_SHUTDOWN);
259 }
260
261 static void
262 axp81x_intr(void *arg)
263 {
264         struct axp81x_softc *sc;
265         device_t dev;
266         uint8_t val;
267         int error;
268
269         dev = arg;
270         sc = device_get_softc(dev);
271
272         error = axp81x_read(dev, AXP_IRQSTAT5, &val, 1);
273         if (error != 0)
274                 return;
275
276         if (val != 0) {
277                 if ((val & AXP_IRQSTAT5_POKSIRQ) != 0) {
278                         if (bootverbose)
279                                 device_printf(dev, "Power button pressed\n");
280                         shutdown_nice(RB_POWEROFF);
281                 }
282                 /* Acknowledge */
283                 axp81x_write(dev, AXP_IRQSTAT5, val);
284         }
285 }
286
287 static device_t
288 axp81x_gpio_get_bus(device_t dev)
289 {
290         struct axp81x_softc *sc;
291
292         sc = device_get_softc(dev);
293
294         return (sc->gpiodev);
295 }
296
297 static int
298 axp81x_gpio_pin_max(device_t dev, int *maxpin)
299 {
300         *maxpin = nitems(axp81x_pins) - 1;
301
302         return (0);
303 }
304
305 static int
306 axp81x_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
307 {
308         if (pin >= nitems(axp81x_pins))
309                 return (EINVAL);
310
311         snprintf(name, GPIOMAXNAME, "%s", axp81x_pins[pin].name);
312
313         return (0);
314 }
315
316 static int
317 axp81x_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
318 {
319         if (pin >= nitems(axp81x_pins))
320                 return (EINVAL);
321
322         *caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
323
324         return (0);
325 }
326
327 static int
328 axp81x_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
329 {
330         struct axp81x_softc *sc;
331         uint8_t data, func;
332         int error;
333
334         if (pin >= nitems(axp81x_pins))
335                 return (EINVAL);
336
337         sc = device_get_softc(dev);
338
339         AXP_LOCK(sc);
340         error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1);
341         if (error == 0) {
342                 func = (data & AXP_GPIO_FUNC) >> AXP_GPIO_FUNC_SHIFT;
343                 if (func == AXP_GPIO_FUNC_INPUT)
344                         *flags = GPIO_PIN_INPUT;
345                 else if (func == AXP_GPIO_FUNC_DRVLO ||
346                     func == AXP_GPIO_FUNC_DRVHI)
347                         *flags = GPIO_PIN_OUTPUT;
348                 else
349                         *flags = 0;
350         }
351         AXP_UNLOCK(sc);
352
353         return (error);
354 }
355
356 static int
357 axp81x_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
358 {
359         struct axp81x_softc *sc;
360         uint8_t data;
361         int error;
362
363         if (pin >= nitems(axp81x_pins))
364                 return (EINVAL);
365
366         sc = device_get_softc(dev);
367
368         AXP_LOCK(sc);
369         error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1);
370         if (error == 0) {
371                 data &= ~AXP_GPIO_FUNC;
372                 if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) != 0) {
373                         if ((flags & GPIO_PIN_OUTPUT) == 0)
374                                 data |= AXP_GPIO_FUNC_INPUT;
375                 }
376                 error = axp81x_write(dev, axp81x_pins[pin].ctrl_reg, data);
377         }
378         AXP_UNLOCK(sc);
379
380         return (error);
381 }
382
383 static int
384 axp81x_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
385 {
386         struct axp81x_softc *sc;
387         uint8_t data, func;
388         int error;
389
390         if (pin >= nitems(axp81x_pins))
391                 return (EINVAL);
392
393         sc = device_get_softc(dev);
394
395         AXP_LOCK(sc);
396         error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1);
397         if (error == 0) {
398                 func = (data & AXP_GPIO_FUNC) >> AXP_GPIO_FUNC_SHIFT;
399                 switch (func) {
400                 case AXP_GPIO_FUNC_DRVLO:
401                         *val = 0;
402                         break;
403                 case AXP_GPIO_FUNC_DRVHI:
404                         *val = 1;
405                         break;
406                 case AXP_GPIO_FUNC_INPUT:
407                         error = axp81x_read(dev, AXP_GPIO_SIGBIT, &data, 1);
408                         if (error == 0)
409                                 *val = (data & (1 << pin)) ? 1 : 0;
410                         break;
411                 default:
412                         error = EIO;
413                         break;
414                 }
415         }
416         AXP_UNLOCK(sc);
417
418         return (error);
419 }
420
421 static int
422 axp81x_gpio_pin_set(device_t dev, uint32_t pin, unsigned int val)
423 {
424         struct axp81x_softc *sc;
425         uint8_t data, func;
426         int error;
427
428         if (pin >= nitems(axp81x_pins))
429                 return (EINVAL);
430
431         sc = device_get_softc(dev);
432
433         AXP_LOCK(sc);
434         error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1);
435         if (error == 0) {
436                 func = (data & AXP_GPIO_FUNC) >> AXP_GPIO_FUNC_SHIFT;
437                 switch (func) {
438                 case AXP_GPIO_FUNC_DRVLO:
439                 case AXP_GPIO_FUNC_DRVHI:
440                         data &= ~AXP_GPIO_FUNC;
441                         data |= (val << AXP_GPIO_FUNC_SHIFT);
442                         break;
443                 default:
444                         error = EIO;
445                         break;
446                 }
447         }
448         if (error == 0)
449                 error = axp81x_write(dev, axp81x_pins[pin].ctrl_reg, data);
450         AXP_UNLOCK(sc);
451
452         return (error);
453 }
454
455
456 static int
457 axp81x_gpio_pin_toggle(device_t dev, uint32_t pin)
458 {
459         struct axp81x_softc *sc;
460         uint8_t data, func;
461         int error;
462
463         if (pin >= nitems(axp81x_pins))
464                 return (EINVAL);
465
466         sc = device_get_softc(dev);
467
468         AXP_LOCK(sc);
469         error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1);
470         if (error == 0) {
471                 func = (data & AXP_GPIO_FUNC) >> AXP_GPIO_FUNC_SHIFT;
472                 switch (func) {
473                 case AXP_GPIO_FUNC_DRVLO:
474                         data &= ~AXP_GPIO_FUNC;
475                         data |= (AXP_GPIO_FUNC_DRVHI << AXP_GPIO_FUNC_SHIFT);
476                         break;
477                 case AXP_GPIO_FUNC_DRVHI:
478                         data &= ~AXP_GPIO_FUNC;
479                         data |= (AXP_GPIO_FUNC_DRVLO << AXP_GPIO_FUNC_SHIFT);
480                         break;
481                 default:
482                         error = EIO;
483                         break;
484                 }
485         }
486         if (error == 0)
487                 error = axp81x_write(dev, axp81x_pins[pin].ctrl_reg, data);
488         AXP_UNLOCK(sc);
489
490         return (error);
491 }
492
493 static int
494 axp81x_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent,
495     int gcells, pcell_t *gpios, uint32_t *pin, uint32_t *flags)
496 {
497         if (gpios[0] >= nitems(axp81x_pins))
498                 return (EINVAL);
499
500         *pin = gpios[0];
501         *flags = gpios[1];
502
503         return (0);
504 }
505
506 static phandle_t
507 axp81x_get_node(device_t dev, device_t bus)
508 {
509         return (ofw_bus_get_node(dev));
510 }
511
512 static struct axp81x_reg_sc *
513 axp81x_reg_attach(device_t dev, phandle_t node,
514     struct axp81x_regdef *def)
515 {
516         struct axp81x_reg_sc *reg_sc;
517         struct regnode_init_def initdef;
518         struct regnode *regnode;
519
520         memset(&initdef, 0, sizeof(initdef));
521         regulator_parse_ofw_stdparam(dev, node, &initdef);
522         initdef.id = def->id;
523         initdef.ofw_node = node;
524         regnode = regnode_create(dev, &axp81x_regnode_class, &initdef);
525         if (regnode == NULL) {
526                 device_printf(dev, "cannot create regulator\n");
527                 return (NULL);
528         }
529
530         reg_sc = regnode_get_softc(regnode);
531         reg_sc->regnode = regnode;
532         reg_sc->base_dev = dev;
533         reg_sc->def = def;
534         reg_sc->xref = OF_xref_from_node(node);
535         reg_sc->param = regnode_get_stdparam(regnode);
536
537         regnode_register(regnode);
538
539         return (reg_sc);
540 }
541
542 static int
543 axp81x_regdev_map(device_t dev, phandle_t xref, int ncells, pcell_t *cells,
544     intptr_t *num)
545 {
546         struct axp81x_softc *sc;
547         int i;
548
549         sc = device_get_softc(dev);
550         for (i = 0; i < sc->nregs; i++) {
551                 if (sc->regs[i] == NULL)
552                         continue;
553                 if (sc->regs[i]->xref == xref) {
554                         *num = sc->regs[i]->def->id;
555                         return (0);
556                 }
557         }
558
559         return (ENXIO);
560 }
561
562 static int
563 axp81x_probe(device_t dev)
564 {
565         if (!ofw_bus_status_okay(dev))
566                 return (ENXIO);
567
568         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
569                 return (ENXIO);
570
571         device_set_desc(dev, "X-Powers AXP81x Power Management Unit");
572
573         return (BUS_PROBE_DEFAULT);
574 }
575
576 static int
577 axp81x_attach(device_t dev)
578 {
579         struct axp81x_softc *sc;
580         struct axp81x_reg_sc *reg;
581         uint8_t chip_id;
582         phandle_t rnode, child;
583         int error, i;
584
585         sc = device_get_softc(dev);
586
587         sc->addr = iicbus_get_addr(dev);
588         mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
589
590         error = bus_alloc_resources(dev, axp81x_spec, &sc->res);
591         if (error != 0) {
592                 device_printf(dev, "cannot allocate resources for device\n");
593                 return (error);
594         }
595
596         if (bootverbose) {
597                 axp81x_read(dev, AXP_ICTYPE, &chip_id, 1);
598                 device_printf(dev, "chip ID 0x%02x\n", chip_id);
599         }
600
601         sc->nregs = nitems(axp81x_regdefs);
602         sc->regs = malloc(sizeof(struct axp81x_reg_sc *) * sc->nregs,
603             M_AXP81X_REG, M_WAITOK | M_ZERO);
604
605         /* Attach known regulators that exist in the DT */
606         rnode = ofw_bus_find_child(ofw_bus_get_node(dev), "regulators");
607         if (rnode > 0) {
608                 for (i = 0; i < sc->nregs; i++) {
609                         child = ofw_bus_find_child(rnode,
610                             axp81x_regdefs[i].name);
611                         if (child == 0)
612                                 continue;
613                         reg = axp81x_reg_attach(dev, child, &axp81x_regdefs[i]);
614                         if (reg == NULL) {
615                                 device_printf(dev,
616                                     "cannot attach regulator %s\n",
617                                     axp81x_regdefs[i].name);
618                                 return (ENXIO);
619                         }
620                         sc->regs[i] = reg;
621                 }
622         }
623
624         /* Enable IRQ on short power key press */
625         axp81x_write(dev, AXP_IRQEN1, 0);
626         axp81x_write(dev, AXP_IRQEN2, 0);
627         axp81x_write(dev, AXP_IRQEN3, 0);
628         axp81x_write(dev, AXP_IRQEN4, 0);
629         axp81x_write(dev, AXP_IRQEN5, AXP_IRQEN5_POKSIRQ);
630         axp81x_write(dev, AXP_IRQEN6, 0);
631
632         /* Install interrupt handler */
633         error = bus_setup_intr(dev, sc->res, INTR_TYPE_MISC | INTR_MPSAFE,
634             NULL, axp81x_intr, dev, &sc->ih);
635         if (error != 0) {
636                 device_printf(dev, "cannot setup interrupt handler\n");
637                 return (error);
638         }
639
640         EVENTHANDLER_REGISTER(shutdown_final, axp81x_shutdown, dev,
641             SHUTDOWN_PRI_LAST);
642
643         sc->gpiodev = gpiobus_attach_bus(dev);
644
645         return (0);
646 }
647
648 static device_method_t axp81x_methods[] = {
649         /* Device interface */
650         DEVMETHOD(device_probe,         axp81x_probe),
651         DEVMETHOD(device_attach,        axp81x_attach),
652
653         /* GPIO interface */
654         DEVMETHOD(gpio_get_bus,         axp81x_gpio_get_bus),
655         DEVMETHOD(gpio_pin_max,         axp81x_gpio_pin_max),
656         DEVMETHOD(gpio_pin_getname,     axp81x_gpio_pin_getname),
657         DEVMETHOD(gpio_pin_getcaps,     axp81x_gpio_pin_getcaps),
658         DEVMETHOD(gpio_pin_getflags,    axp81x_gpio_pin_getflags),
659         DEVMETHOD(gpio_pin_setflags,    axp81x_gpio_pin_setflags),
660         DEVMETHOD(gpio_pin_get,         axp81x_gpio_pin_get),
661         DEVMETHOD(gpio_pin_set,         axp81x_gpio_pin_set),
662         DEVMETHOD(gpio_pin_toggle,      axp81x_gpio_pin_toggle),
663         DEVMETHOD(gpio_map_gpios,       axp81x_gpio_map_gpios),
664
665         /* Regdev interface */
666         DEVMETHOD(regdev_map,           axp81x_regdev_map),
667
668         /* OFW bus interface */
669         DEVMETHOD(ofw_bus_get_node,     axp81x_get_node),
670
671         DEVMETHOD_END
672 };
673
674 static driver_t axp81x_driver = {
675         "axp81x_pmu",
676         axp81x_methods,
677         sizeof(struct axp81x_softc),
678 };
679
680 static devclass_t axp81x_devclass;
681 extern devclass_t ofwgpiobus_devclass, gpioc_devclass;
682 extern driver_t ofw_gpiobus_driver, gpioc_driver;
683
684 EARLY_DRIVER_MODULE(axp81x, iicbus, axp81x_driver, axp81x_devclass, 0, 0,
685     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
686 EARLY_DRIVER_MODULE(ofw_gpiobus, axp81x_pmu, ofw_gpiobus_driver,
687     ofwgpiobus_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
688 DRIVER_MODULE(gpioc, axp81x_pmu, gpioc_driver, gpioc_devclass, 0, 0);
689 MODULE_VERSION(axp81x, 1);
690 MODULE_DEPEND(axp81x, iicbus, 1, 1, 1);