]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/gpio/bytgpio.c
MFV r368607:
[FreeBSD/FreeBSD.git] / sys / dev / gpio / bytgpio.c
1 /*-
2  * Copyright (c) 2016 Oleksandr Tymoshenko <gonzo@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_acpi.h"
31
32 #include <sys/param.h>
33 #include <sys/bus.h>
34 #include <sys/gpio.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/proc.h>
38 #include <sys/rman.h>
39
40 #include <machine/bus.h>
41 #include <machine/resource.h>
42
43 #include <contrib/dev/acpica/include/acpi.h>
44 #include <contrib/dev/acpica/include/accommon.h>
45
46 #include <dev/acpica/acpivar.h>
47 #include <dev/gpio/gpiobusvar.h>
48
49 #include "gpio_if.h"
50
51 /**
52  *      Macros for driver mutex locking
53  */
54 #define BYTGPIO_LOCK(_sc)               mtx_lock_spin(&(_sc)->sc_mtx)
55 #define BYTGPIO_UNLOCK(_sc)             mtx_unlock_spin(&(_sc)->sc_mtx)
56 #define BYTGPIO_LOCK_INIT(_sc)          \
57         mtx_init(&_sc->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
58             "bytgpio", MTX_SPIN)
59 #define BYTGPIO_LOCK_DESTROY(_sc)       mtx_destroy(&(_sc)->sc_mtx)
60 #define BYTGPIO_ASSERT_LOCKED(_sc)      mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
61 #define BYTGPIO_ASSERT_UNLOCKED(_sc)    mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED)
62
63 struct pinmap_info {
64     int reg;
65     int pad_func;
66 };
67
68 /* Ignore function check, no info is available at the moment */
69 #define PADCONF_FUNC_ANY        -1
70
71 #define GPIO_PIN_MAP(r, f) { .reg = (r), .pad_func = (f) }
72
73 struct bytgpio_softc {
74         ACPI_HANDLE             sc_handle;
75         device_t                sc_dev;
76         device_t                sc_busdev;
77         struct mtx              sc_mtx;
78         int                     sc_mem_rid;
79         struct resource         *sc_mem_res;
80         int                     sc_npins;
81         const char*             sc_bank_prefix;
82         const struct pinmap_info        *sc_pinpad_map;
83         /* List of current functions for pads shared by GPIO */
84         int                     *sc_pad_funcs;
85 };
86
87 static int      bytgpio_probe(device_t dev);
88 static int      bytgpio_attach(device_t dev);
89 static int      bytgpio_detach(device_t dev);
90
91 #define SCORE_UID               1
92 #define SCORE_BANK_PREFIX       "GPIO_S0_SC"
93 const struct pinmap_info bytgpio_score_pins[] = {
94         GPIO_PIN_MAP(85, 0),
95         GPIO_PIN_MAP(89, 0),
96         GPIO_PIN_MAP(93, 0),
97         GPIO_PIN_MAP(96, 0),
98         GPIO_PIN_MAP(99, 0),
99         GPIO_PIN_MAP(102, 0),
100         GPIO_PIN_MAP(98, 0),
101         GPIO_PIN_MAP(101, 0),
102         GPIO_PIN_MAP(34, 0),
103         GPIO_PIN_MAP(37, 0),
104         GPIO_PIN_MAP(36, 0),
105         GPIO_PIN_MAP(38, 0),
106         GPIO_PIN_MAP(39, 0),
107         GPIO_PIN_MAP(35, 0),
108         GPIO_PIN_MAP(40, 0),
109         GPIO_PIN_MAP(84, 0),
110         GPIO_PIN_MAP(62, 0),
111         GPIO_PIN_MAP(61, 0),
112         GPIO_PIN_MAP(64, 0),
113         GPIO_PIN_MAP(59, 0),
114         GPIO_PIN_MAP(54, 0),
115         GPIO_PIN_MAP(56, 0),
116         GPIO_PIN_MAP(60, 0),
117         GPIO_PIN_MAP(55, 0),
118         GPIO_PIN_MAP(63, 0),
119         GPIO_PIN_MAP(57, 0),
120         GPIO_PIN_MAP(51, 0),
121         GPIO_PIN_MAP(50, 0),
122         GPIO_PIN_MAP(53, 0),
123         GPIO_PIN_MAP(47, 0),
124         GPIO_PIN_MAP(52, 0),
125         GPIO_PIN_MAP(49, 0),
126         GPIO_PIN_MAP(48, 0),
127         GPIO_PIN_MAP(43, 0),
128         GPIO_PIN_MAP(46, 0),
129         GPIO_PIN_MAP(41, 0),
130         GPIO_PIN_MAP(45, 0),
131         GPIO_PIN_MAP(42, 0),
132         GPIO_PIN_MAP(58, 0),
133         GPIO_PIN_MAP(44, 0),
134         GPIO_PIN_MAP(95, 0),
135         GPIO_PIN_MAP(105, 0),
136         GPIO_PIN_MAP(70, 0),
137         GPIO_PIN_MAP(68, 0),
138         GPIO_PIN_MAP(67, 0),
139         GPIO_PIN_MAP(66, 0),
140         GPIO_PIN_MAP(69, 0),
141         GPIO_PIN_MAP(71, 0),
142         GPIO_PIN_MAP(65, 0),
143         GPIO_PIN_MAP(72, 0),
144         GPIO_PIN_MAP(86, 0),
145         GPIO_PIN_MAP(90, 0),
146         GPIO_PIN_MAP(88, 0),
147         GPIO_PIN_MAP(92, 0),
148         GPIO_PIN_MAP(103, 0),
149         GPIO_PIN_MAP(77, 0),
150         GPIO_PIN_MAP(79, 0),
151         GPIO_PIN_MAP(83, 0),
152         GPIO_PIN_MAP(78, 0),
153         GPIO_PIN_MAP(81, 0),
154         GPIO_PIN_MAP(80, 0),
155         GPIO_PIN_MAP(82, 0),
156         GPIO_PIN_MAP(13, 0),
157         GPIO_PIN_MAP(12, 0),
158         GPIO_PIN_MAP(15, 0),
159         GPIO_PIN_MAP(14, 0),
160         GPIO_PIN_MAP(17, 0),
161         GPIO_PIN_MAP(18, 0),
162         GPIO_PIN_MAP(19, 0),
163         GPIO_PIN_MAP(16, 0),
164         GPIO_PIN_MAP(2, 0),
165         GPIO_PIN_MAP(1, 0),
166         GPIO_PIN_MAP(0, 0),
167         GPIO_PIN_MAP(4, 0),
168         GPIO_PIN_MAP(6, 0),
169         GPIO_PIN_MAP(7, 0),
170         GPIO_PIN_MAP(9, 0),
171         GPIO_PIN_MAP(8, 0),
172         GPIO_PIN_MAP(33, 0),
173         GPIO_PIN_MAP(32, 0),
174         GPIO_PIN_MAP(31, 0),
175         GPIO_PIN_MAP(30, 0),
176         GPIO_PIN_MAP(29, 0),
177         GPIO_PIN_MAP(27, 0),
178         GPIO_PIN_MAP(25, 0),
179         GPIO_PIN_MAP(28, 0),
180         GPIO_PIN_MAP(26, 0),
181         GPIO_PIN_MAP(23, 0),
182         GPIO_PIN_MAP(21, 0),
183         GPIO_PIN_MAP(20, 0),
184         GPIO_PIN_MAP(24, 0),
185         GPIO_PIN_MAP(22, 0),
186         GPIO_PIN_MAP(5, 1),
187         GPIO_PIN_MAP(3, 1),
188         GPIO_PIN_MAP(10, 0),
189         GPIO_PIN_MAP(11, 0),
190         GPIO_PIN_MAP(106, 0),
191         GPIO_PIN_MAP(87, 0),
192         GPIO_PIN_MAP(91, 0),
193         GPIO_PIN_MAP(104, 0),
194         GPIO_PIN_MAP(97, 0),
195         GPIO_PIN_MAP(100, 0)
196 };
197
198 #define SCORE_PINS      nitems(bytgpio_score_pins)
199
200 #define NCORE_UID               2
201 #define NCORE_BANK_PREFIX       "GPIO_S0_NC"
202 const struct pinmap_info bytgpio_ncore_pins[] = {
203         GPIO_PIN_MAP(19, PADCONF_FUNC_ANY),
204         GPIO_PIN_MAP(18, PADCONF_FUNC_ANY),
205         GPIO_PIN_MAP(17, PADCONF_FUNC_ANY),
206         GPIO_PIN_MAP(20, PADCONF_FUNC_ANY),
207         GPIO_PIN_MAP(21, PADCONF_FUNC_ANY),
208         GPIO_PIN_MAP(22, PADCONF_FUNC_ANY),
209         GPIO_PIN_MAP(24, PADCONF_FUNC_ANY),
210         GPIO_PIN_MAP(25, PADCONF_FUNC_ANY),
211         GPIO_PIN_MAP(23, PADCONF_FUNC_ANY),
212         GPIO_PIN_MAP(16, PADCONF_FUNC_ANY),
213         GPIO_PIN_MAP(14, PADCONF_FUNC_ANY),
214         GPIO_PIN_MAP(15, PADCONF_FUNC_ANY),
215         GPIO_PIN_MAP(12, PADCONF_FUNC_ANY),
216         GPIO_PIN_MAP(26, PADCONF_FUNC_ANY),
217         GPIO_PIN_MAP(27, PADCONF_FUNC_ANY),
218         GPIO_PIN_MAP(1, PADCONF_FUNC_ANY),
219         GPIO_PIN_MAP(4, PADCONF_FUNC_ANY),
220         GPIO_PIN_MAP(8, PADCONF_FUNC_ANY),
221         GPIO_PIN_MAP(11, PADCONF_FUNC_ANY),
222         GPIO_PIN_MAP(0, PADCONF_FUNC_ANY),
223         GPIO_PIN_MAP(3, PADCONF_FUNC_ANY),
224         GPIO_PIN_MAP(6, PADCONF_FUNC_ANY),
225         GPIO_PIN_MAP(10, PADCONF_FUNC_ANY),
226         GPIO_PIN_MAP(13, PADCONF_FUNC_ANY),
227         GPIO_PIN_MAP(2, PADCONF_FUNC_ANY),
228         GPIO_PIN_MAP(5, PADCONF_FUNC_ANY),
229         GPIO_PIN_MAP(9, PADCONF_FUNC_ANY),
230         GPIO_PIN_MAP(7, PADCONF_FUNC_ANY)
231 };
232 #define NCORE_PINS      nitems(bytgpio_ncore_pins)
233
234 #define SUS_UID         3
235 #define SUS_BANK_PREFIX "GPIO_S5_"
236 const struct pinmap_info bytgpio_sus_pins[] = {
237         GPIO_PIN_MAP(29, 0),
238         GPIO_PIN_MAP(33, 0),
239         GPIO_PIN_MAP(30, 0),
240         GPIO_PIN_MAP(31, 0),
241         GPIO_PIN_MAP(32, 0),
242         GPIO_PIN_MAP(34, 0),
243         GPIO_PIN_MAP(36, 0),
244         GPIO_PIN_MAP(35, 0),
245         GPIO_PIN_MAP(38, 0),
246         GPIO_PIN_MAP(37, 0),
247         GPIO_PIN_MAP(18, 0),
248         GPIO_PIN_MAP(7, 1),
249         GPIO_PIN_MAP(11, 1),
250         GPIO_PIN_MAP(20, 1),
251         GPIO_PIN_MAP(17, 1),
252         GPIO_PIN_MAP(1, 1),
253         GPIO_PIN_MAP(8, 1),
254         GPIO_PIN_MAP(10, 1),
255         GPIO_PIN_MAP(19, 1),
256         GPIO_PIN_MAP(12, 1),
257         GPIO_PIN_MAP(0, 1),
258         GPIO_PIN_MAP(2, 1),
259         GPIO_PIN_MAP(23, 0),
260         GPIO_PIN_MAP(39, 0),
261         GPIO_PIN_MAP(28, 0),
262         GPIO_PIN_MAP(27, 0),
263         GPIO_PIN_MAP(22, 0),
264         GPIO_PIN_MAP(21, 0),
265         GPIO_PIN_MAP(24, 0),
266         GPIO_PIN_MAP(25, 0),
267         GPIO_PIN_MAP(26, 0),
268         GPIO_PIN_MAP(51, 0),
269         GPIO_PIN_MAP(56, 0),
270         GPIO_PIN_MAP(54, 0),
271         GPIO_PIN_MAP(49, 0),
272         GPIO_PIN_MAP(55, 0),
273         GPIO_PIN_MAP(48, 0),
274         GPIO_PIN_MAP(57, 0),
275         GPIO_PIN_MAP(50, 0),
276         GPIO_PIN_MAP(58, 0),
277         GPIO_PIN_MAP(52, 0),
278         GPIO_PIN_MAP(53, 0),
279         GPIO_PIN_MAP(59, 0),
280         GPIO_PIN_MAP(40, 0)
281 };
282
283 #define SUS_PINS        nitems(bytgpio_sus_pins)
284
285 #define BYGPIO_PIN_REGISTER(sc, pin, r) ((sc)->sc_pinpad_map[(pin)].reg * 16 + (r))
286 #define BYTGPIO_PCONF0          0x0000
287 #define         BYTGPIO_PCONF0_FUNC_MASK        7
288 #define BYTGPIO_PAD_VAL         0x0008
289 #define         BYTGPIO_PAD_VAL_LEVEL           (1 << 0)        
290 #define         BYTGPIO_PAD_VAL_I_OUTPUT_ENABLED        (1 << 1)
291 #define         BYTGPIO_PAD_VAL_I_INPUT_ENABLED (1 << 2)
292 #define         BYTGPIO_PAD_VAL_DIR_MASK                (3 << 1)
293
294 static inline uint32_t
295 bytgpio_read_4(struct bytgpio_softc *sc, bus_size_t off)
296 {
297         return (bus_read_4(sc->sc_mem_res, off));
298 }
299
300 static inline void
301 bytgpio_write_4(struct bytgpio_softc *sc, bus_size_t off,
302     uint32_t val)
303 {
304         bus_write_4(sc->sc_mem_res, off, val);
305 }
306
307 static device_t
308 bytgpio_get_bus(device_t dev)
309 {
310         struct bytgpio_softc *sc;
311
312         sc = device_get_softc(dev);
313
314         return (sc->sc_busdev);
315 }
316
317 static int
318 bytgpio_pin_max(device_t dev, int *maxpin)
319 {
320         struct bytgpio_softc *sc;
321
322         sc = device_get_softc(dev);
323
324         *maxpin = sc->sc_npins - 1;
325
326         return (0);
327 }
328
329 static int
330 bytgpio_valid_pin(struct bytgpio_softc *sc, int pin)
331 {
332
333         if (pin >= sc->sc_npins || sc->sc_mem_res == NULL)
334                 return (EINVAL);
335
336         return (0);
337 }
338
339 /*
340  * Returns true if pad configured to be used as GPIO
341  */
342 static bool
343 bytgpio_pad_is_gpio(struct bytgpio_softc *sc, int pin)
344 {
345         if ((sc->sc_pinpad_map[pin].pad_func == PADCONF_FUNC_ANY) ||
346             (sc->sc_pad_funcs[pin] == sc->sc_pinpad_map[pin].pad_func))
347                 return (true);
348         else
349                 return (false);
350 }
351
352 static int
353 bytgpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
354 {
355         struct bytgpio_softc *sc;
356
357         sc = device_get_softc(dev);
358         if (bytgpio_valid_pin(sc, pin) != 0)
359                 return (EINVAL);
360
361         *caps = 0;
362         if (bytgpio_pad_is_gpio(sc, pin))
363                 *caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
364
365         return (0);
366 }
367
368 static int
369 bytgpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
370 {
371         struct bytgpio_softc *sc;
372         uint32_t reg, val;
373
374         sc = device_get_softc(dev);
375         if (bytgpio_valid_pin(sc, pin) != 0)
376                 return (EINVAL);
377
378         *flags = 0;
379         if (!bytgpio_pad_is_gpio(sc, pin))
380                 return (0);
381
382         /* Get the current pin state */
383         BYTGPIO_LOCK(sc);
384         reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL);
385         val = bytgpio_read_4(sc, reg);
386         if ((val & BYTGPIO_PAD_VAL_I_OUTPUT_ENABLED) == 0)
387                 *flags |= GPIO_PIN_OUTPUT;
388         /*
389          * this bit can be cleared to read current output value
390          * sou output bit takes precedense
391          */
392         else if ((val & BYTGPIO_PAD_VAL_I_INPUT_ENABLED) == 0)
393                 *flags |= GPIO_PIN_INPUT;
394         BYTGPIO_UNLOCK(sc);
395
396         return (0);
397 }
398
399 static int
400 bytgpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
401 {
402         struct bytgpio_softc *sc;
403         uint32_t reg, val;
404         uint32_t allowed;
405
406         sc = device_get_softc(dev);
407         if (bytgpio_valid_pin(sc, pin) != 0)
408                 return (EINVAL);
409
410         if (bytgpio_pad_is_gpio(sc, pin))
411                 allowed = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
412         else
413                 allowed = 0;
414
415         /* 
416          * Only directtion flag allowed
417          */
418         if (flags & ~allowed)
419                 return (EINVAL);
420
421         /* 
422          * Not both directions simultaneously
423          */
424         if ((flags & allowed) == allowed)
425                 return (EINVAL);
426
427         /* Set the GPIO mode and state */
428         BYTGPIO_LOCK(sc);
429         reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL);
430         val = bytgpio_read_4(sc, reg);
431         val = val | BYTGPIO_PAD_VAL_DIR_MASK;
432         if (flags & GPIO_PIN_INPUT)
433                 val = val & ~BYTGPIO_PAD_VAL_I_INPUT_ENABLED;
434         if (flags & GPIO_PIN_OUTPUT)
435                 val = val & ~BYTGPIO_PAD_VAL_I_OUTPUT_ENABLED;
436         bytgpio_write_4(sc, reg, val);
437         BYTGPIO_UNLOCK(sc);
438
439         return (0);
440 }
441
442 static int
443 bytgpio_pin_getname(device_t dev, uint32_t pin, char *name)
444 {
445         struct bytgpio_softc *sc;
446
447         sc = device_get_softc(dev);
448         if (bytgpio_valid_pin(sc, pin) != 0)
449                 return (EINVAL);
450
451         /* Set a very simple name */
452         snprintf(name, GPIOMAXNAME, "%s%u", sc->sc_bank_prefix, pin);
453         name[GPIOMAXNAME - 1] = '\0';
454
455         return (0);
456 }
457
458 static int
459 bytgpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
460 {
461         struct bytgpio_softc *sc;
462         uint32_t reg, val;
463
464         sc = device_get_softc(dev);
465         if (bytgpio_valid_pin(sc, pin) != 0)
466                 return (EINVAL);
467
468         if (!bytgpio_pad_is_gpio(sc, pin))
469                 return (EINVAL);
470
471         BYTGPIO_LOCK(sc);
472         reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL);
473         val = bytgpio_read_4(sc, reg);
474         if (value == GPIO_PIN_LOW)
475                 val = val & ~BYTGPIO_PAD_VAL_LEVEL;
476         else
477                 val = val | BYTGPIO_PAD_VAL_LEVEL;
478         bytgpio_write_4(sc, reg, val);
479         BYTGPIO_UNLOCK(sc);
480
481         return (0);
482 }
483
484 static int
485 bytgpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
486 {
487         struct bytgpio_softc *sc;
488         uint32_t reg, val;
489
490         sc = device_get_softc(dev);
491         if (bytgpio_valid_pin(sc, pin) != 0)
492                 return (EINVAL);
493         /*
494          * Report non-GPIO pads as pin LOW
495          */
496         if (!bytgpio_pad_is_gpio(sc, pin)) {
497                 *value = GPIO_PIN_LOW;
498                 return (0);
499         }
500
501         BYTGPIO_LOCK(sc);
502         reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL);
503         /*
504          * And read actual value
505          */
506         val = bytgpio_read_4(sc, reg);
507         if (val & BYTGPIO_PAD_VAL_LEVEL)
508                 *value = GPIO_PIN_HIGH;
509         else
510                 *value = GPIO_PIN_LOW;
511         BYTGPIO_UNLOCK(sc);
512
513         return (0);
514 }
515
516 static int
517 bytgpio_pin_toggle(device_t dev, uint32_t pin)
518 {
519         struct bytgpio_softc *sc;
520         uint32_t reg, val;
521
522         sc = device_get_softc(dev);
523         if (bytgpio_valid_pin(sc, pin) != 0)
524                 return (EINVAL);
525
526         if (!bytgpio_pad_is_gpio(sc, pin))
527                 return (EINVAL);
528
529         /* Toggle the pin */
530         BYTGPIO_LOCK(sc);
531         reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL);
532         val = bytgpio_read_4(sc, reg);
533         val = val ^ BYTGPIO_PAD_VAL_LEVEL;
534         bytgpio_write_4(sc, reg, val);
535         BYTGPIO_UNLOCK(sc);
536
537         return (0);
538 }
539
540 static int
541 bytgpio_probe(device_t dev)
542 {
543         static char *gpio_ids[] = { "INT33FC", NULL };
544         int rv;
545
546         if (acpi_disabled("gpio"))
547                 return (ENXIO);
548         rv = ACPI_ID_PROBE(device_get_parent(dev), dev, gpio_ids, NULL);
549         if (rv <= 0)
550                 device_set_desc(dev, "Intel Baytrail GPIO Controller");
551         return (rv);
552 }
553
554 static int
555 bytgpio_attach(device_t dev)
556 {
557         struct bytgpio_softc    *sc;
558         ACPI_STATUS status;
559         int uid;
560         int pin;
561         uint32_t reg, val;
562
563         sc = device_get_softc(dev);
564         sc->sc_dev = dev;
565         sc->sc_handle = acpi_get_handle(dev);
566         status = acpi_GetInteger(sc->sc_handle, "_UID", &uid);
567         if (ACPI_FAILURE(status)) {
568                 device_printf(dev, "failed to read _UID\n");
569                 return (ENXIO);
570         }
571
572         BYTGPIO_LOCK_INIT(sc);
573
574         switch (uid) {
575         case SCORE_UID:
576                 sc->sc_npins = SCORE_PINS;
577                 sc->sc_bank_prefix = SCORE_BANK_PREFIX;
578                 sc->sc_pinpad_map = bytgpio_score_pins;
579                 break;
580         case NCORE_UID:
581                 sc->sc_npins = NCORE_PINS;
582                 sc->sc_bank_prefix = NCORE_BANK_PREFIX;
583                 sc->sc_pinpad_map = bytgpio_ncore_pins;
584                 break;
585         case SUS_UID:
586                 sc->sc_npins = SUS_PINS;
587                 sc->sc_bank_prefix = SUS_BANK_PREFIX;
588                 sc->sc_pinpad_map = bytgpio_sus_pins;
589                 break;
590         default:
591                 device_printf(dev, "invalid _UID value: %d\n", uid);
592                 goto error;
593         }
594
595         sc->sc_pad_funcs = malloc(sizeof(int)*sc->sc_npins, M_DEVBUF,
596             M_WAITOK | M_ZERO);
597
598         sc->sc_mem_rid = 0;
599         sc->sc_mem_res = bus_alloc_resource_any(sc->sc_dev,
600             SYS_RES_MEMORY, &sc->sc_mem_rid, RF_ACTIVE);
601         if (sc->sc_mem_res == NULL) {
602                 device_printf(dev, "can't allocate resource\n");
603                 goto error;
604         }
605
606         for (pin = 0; pin < sc->sc_npins; pin++) {
607             reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PCONF0);
608             val = bytgpio_read_4(sc, reg);
609             sc->sc_pad_funcs[pin] = val & BYTGPIO_PCONF0_FUNC_MASK;
610         }
611
612         sc->sc_busdev = gpiobus_attach_bus(dev);
613         if (sc->sc_busdev == NULL) {
614                 BYTGPIO_LOCK_DESTROY(sc);
615                 bus_release_resource(dev, SYS_RES_MEMORY,
616                     sc->sc_mem_rid, sc->sc_mem_res);
617                 return (ENXIO);
618         }
619
620         return (0);
621
622 error:
623         BYTGPIO_LOCK_DESTROY(sc);
624
625         return (ENXIO);
626 }
627
628
629 static int
630 bytgpio_detach(device_t dev)
631 {
632         struct bytgpio_softc    *sc;
633
634         sc = device_get_softc(dev);
635
636         if (sc->sc_busdev)
637                 gpiobus_detach_bus(dev);
638
639         BYTGPIO_LOCK_DESTROY(sc);
640
641         if (sc->sc_pad_funcs)
642                 free(sc->sc_pad_funcs, M_DEVBUF);
643
644         if (sc->sc_mem_res != NULL)
645                 bus_release_resource(dev, SYS_RES_MEMORY,
646                     sc->sc_mem_rid, sc->sc_mem_res);
647
648         return (0);
649 }
650
651 static device_method_t bytgpio_methods[] = {
652         /* Device interface */
653         DEVMETHOD(device_probe, bytgpio_probe),
654         DEVMETHOD(device_attach, bytgpio_attach),
655         DEVMETHOD(device_detach, bytgpio_detach),
656
657         /* GPIO protocol */
658         DEVMETHOD(gpio_get_bus, bytgpio_get_bus),
659         DEVMETHOD(gpio_pin_max, bytgpio_pin_max),
660         DEVMETHOD(gpio_pin_getname, bytgpio_pin_getname),
661         DEVMETHOD(gpio_pin_getflags, bytgpio_pin_getflags),
662         DEVMETHOD(gpio_pin_getcaps, bytgpio_pin_getcaps),
663         DEVMETHOD(gpio_pin_setflags, bytgpio_pin_setflags),
664         DEVMETHOD(gpio_pin_get, bytgpio_pin_get),
665         DEVMETHOD(gpio_pin_set, bytgpio_pin_set),
666         DEVMETHOD(gpio_pin_toggle, bytgpio_pin_toggle),
667
668         DEVMETHOD_END
669 };
670
671 static driver_t bytgpio_driver = {
672         "gpio",
673         bytgpio_methods,
674         sizeof(struct bytgpio_softc),
675 };
676
677 static devclass_t bytgpio_devclass;
678 DRIVER_MODULE(bytgpio, acpi, bytgpio_driver, bytgpio_devclass, 0, 0);
679 MODULE_DEPEND(bytgpio, acpi, 1, 1, 1);
680 MODULE_DEPEND(bytgpio, gpiobus, 1, 1, 1);