]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/ralink/rt1310_gpio.c
Fix a locking issue in sctp_accept.
[FreeBSD/FreeBSD.git] / sys / arm / ralink / rt1310_gpio.c
1 /*-
2  * Copyright (c) 2011 Jakub Wojciech Klama <jceel@FreeBSD.org>
3  * Copyright (c) 2015 Hiroki Mori
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  */
28
29 /*
30  * GPIO on RT1310A consist of 2 ports:
31  * - PortA with 8 input/output pins
32  * - PortB with 4 input/output pins
33  *
34  * Pins are mapped to logical pin number as follows:
35  * [0..7] -> GPI_00..GPI_07             (port A)
36  * [8..11] -> GPI_08..GPI_11            (port B)
37  *
38  */
39
40
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/bio.h>
47 #include <sys/bus.h>
48 #include <sys/conf.h>
49 #include <sys/endian.h>
50 #include <sys/kernel.h>
51 #include <sys/kthread.h>
52 #include <sys/lock.h>
53 #include <sys/malloc.h>
54 #include <sys/module.h>
55 #include <sys/mutex.h>
56 #include <sys/queue.h>
57 #include <sys/resource.h>
58 #include <sys/rman.h>
59 #include <sys/time.h>
60 #include <sys/timetc.h>
61 #include <sys/watchdog.h>
62 #include <sys/gpio.h>
63
64 #include <machine/bus.h>
65 #include <machine/cpu.h>
66 #include <machine/cpufunc.h>
67 #include <machine/resource.h>
68 #include <machine/intr.h>
69 #include <machine/fdt.h>
70
71 #include <dev/gpio/gpiobusvar.h>
72 #include <dev/ofw/ofw_bus.h>
73 #include <dev/ofw/ofw_bus_subr.h>
74
75 #include <arm/ralink/rt1310reg.h>
76 #include <arm/ralink/rt1310var.h>
77
78 #include "gpio_if.h"
79
80 struct rt1310_gpio_softc
81 {
82         device_t                lg_dev;
83         device_t                lg_busdev;
84         struct resource *       lg_res;
85         bus_space_tag_t         lg_bst;
86         bus_space_handle_t      lg_bsh;
87 };
88
89 struct rt1310_gpio_pinmap
90 {
91         int                     lp_start_idx;
92         int                     lp_pin_count;
93         int                     lp_port;
94         int                     lp_start_bit;
95         int                     lp_flags;
96 };
97
98 static const struct rt1310_gpio_pinmap rt1310_gpio_pins[] = {
99         { 0,    8,      RT_GPIO_PORTA,  0,      GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
100         { 8,    4,      RT_GPIO_PORTB,  0,      GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
101         { -1,   -1,     -1,     -1,     -1 },
102 };
103
104 #define RT_GPIO_NPINS                           12
105
106 #define RT_GPIO_PIN_IDX(_map, _idx)     \
107     (_idx - _map->lp_start_idx)
108
109 #define RT_GPIO_PIN_BIT(_map, _idx)     \
110     (_map->lp_start_bit + RT_GPIO_PIN_IDX(_map, _idx))
111
112 static int rt1310_gpio_probe(device_t);
113 static int rt1310_gpio_attach(device_t);
114 static int rt1310_gpio_detach(device_t);
115
116 static device_t rt1310_gpio_get_bus(device_t);
117 static int rt1310_gpio_pin_max(device_t, int *);
118 static int rt1310_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
119 static int rt1310_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
120 static int rt1310_gpio_pin_setflags(device_t, uint32_t, uint32_t);
121 static int rt1310_gpio_pin_getname(device_t, uint32_t, char *);
122 static int rt1310_gpio_pin_get(device_t, uint32_t, uint32_t *);
123 static int rt1310_gpio_pin_set(device_t, uint32_t, uint32_t);
124 static int rt1310_gpio_pin_toggle(device_t, uint32_t);
125
126 static const struct rt1310_gpio_pinmap *rt1310_gpio_get_pinmap(int);
127
128 static struct rt1310_gpio_softc *rt1310_gpio_sc = NULL;
129
130 #define rt1310_gpio_read_4(_sc, _reg) \
131     bus_space_read_4(_sc->lg_bst, _sc->lg_bsh, _reg)
132 #define rt1310_gpio_write_4(_sc, _reg, _val) \
133     bus_space_write_4(_sc->lg_bst, _sc->lg_bsh, _reg, _val)
134
135 static int
136 rt1310_gpio_probe(device_t dev)
137 {
138         phandle_t node;
139
140         if (!ofw_bus_status_okay(dev))
141                 return (ENXIO);
142
143         if (!ofw_bus_is_compatible(dev, "ralink,rt1310-gpio"))
144                 return (ENXIO);
145                 
146         node = ofw_bus_get_node(dev);
147         if (!OF_hasprop(node, "gpio-controller"))
148                 return (ENXIO);
149
150         device_set_desc(dev, "RT1310 GPIO");
151         return (BUS_PROBE_DEFAULT);
152 }
153
154 static int
155 rt1310_gpio_attach(device_t dev)
156 {
157         struct rt1310_gpio_softc *sc = device_get_softc(dev);
158         int rid;
159
160         sc->lg_dev = dev;
161
162         rid = 0;
163         sc->lg_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
164             RF_ACTIVE);
165         if (!sc->lg_res) {
166                 device_printf(dev, "cannot allocate memory window\n");
167                 return (ENXIO);
168         }
169
170         sc->lg_bst = rman_get_bustag(sc->lg_res);
171         sc->lg_bsh = rman_get_bushandle(sc->lg_res);
172
173         rt1310_gpio_sc = sc;
174
175         sc->lg_busdev = gpiobus_attach_bus(dev);
176         if (sc->lg_busdev == NULL) {
177                 bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->lg_res);
178                 return (ENXIO);
179         }
180
181         return (0);
182 }
183
184 static int
185 rt1310_gpio_detach(device_t dev)
186 {
187         return (EBUSY);
188 }
189
190 static device_t
191 rt1310_gpio_get_bus(device_t dev)
192 {
193         struct rt1310_gpio_softc *sc;
194
195         sc = device_get_softc(dev);
196
197         return (sc->lg_busdev);
198 }
199
200 static int
201 rt1310_gpio_pin_max(device_t dev, int *npins)
202 {
203         *npins = RT_GPIO_NPINS - 1;
204         return (0);
205 }
206
207 static int
208 rt1310_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
209 {
210         const struct rt1310_gpio_pinmap *map;
211
212         if (pin > RT_GPIO_NPINS)
213                 return (ENODEV);
214
215         map = rt1310_gpio_get_pinmap(pin);
216
217         *caps = map->lp_flags;
218         return (0);
219 }
220
221 static int
222 rt1310_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
223 {
224         struct rt1310_gpio_softc *sc = device_get_softc(dev);
225         const struct rt1310_gpio_pinmap *map;
226         uint32_t state;
227         int dir;
228
229         if (pin > RT_GPIO_NPINS)
230                 return (ENODEV);
231
232         map = rt1310_gpio_get_pinmap(pin);
233
234         /* Check whether it's bidirectional pin */
235         if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) != 
236             (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
237                 *flags = map->lp_flags;
238                 return (0);
239         }
240
241         switch (map->lp_port) {
242         case RT_GPIO_PORTA:
243                 state = rt1310_gpio_read_4(sc, RT_GPIO_OFF_PADIR);
244                 dir = (state & (1 << RT_GPIO_PIN_BIT(map, pin)));
245                 break;
246         case RT_GPIO_PORTB:
247                 state = rt1310_gpio_read_4(sc, RT_GPIO_OFF_PBDIR);
248                 dir = (state & (1 << RT_GPIO_PIN_BIT(map, pin)));
249                 break;
250         default:
251                 panic("unknown GPIO port");
252         }
253
254         *flags = dir ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT;
255
256         return (0);
257 }
258
259 static int
260 rt1310_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
261 {
262         struct rt1310_gpio_softc *sc = device_get_softc(dev);
263         const struct rt1310_gpio_pinmap *map;
264         uint32_t dir, state;
265         uint32_t port;
266
267         if (pin > RT_GPIO_NPINS)
268                 return (ENODEV);
269
270         map = rt1310_gpio_get_pinmap(pin);
271
272         /* Check whether it's bidirectional pin */
273         if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) != 
274             (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
275                 return (ENOTSUP);
276         
277         if (flags & GPIO_PIN_INPUT)
278                 dir = 0;
279
280         if (flags & GPIO_PIN_OUTPUT)
281                 dir = 1;
282
283         switch (map->lp_port) {
284         case RT_GPIO_PORTA:
285                 port = RT_GPIO_OFF_PADIR;
286                 break;
287         case RT_GPIO_PORTB:
288                 port = RT_GPIO_OFF_PBDIR;
289                 break;
290         }
291
292         state = rt1310_gpio_read_4(sc, port);
293         if (flags & GPIO_PIN_INPUT) {
294                 state &= ~(1 << RT_GPIO_PIN_IDX(map, pin));
295         } else {
296                 state |= (1 << RT_GPIO_PIN_IDX(map, pin));
297         }
298         rt1310_gpio_write_4(sc, port, state);
299
300         return (0);
301 }
302
303 static int
304 rt1310_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
305 {
306         snprintf(name, GPIOMAXNAME - 1, "GPIO_%02d", pin);
307
308         return (0);
309 }
310
311 static int
312 rt1310_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value)
313 {
314         struct rt1310_gpio_softc *sc = device_get_softc(dev);
315         const struct rt1310_gpio_pinmap *map;
316         uint32_t state, flags;
317         int dir;
318
319         map = rt1310_gpio_get_pinmap(pin);
320
321         if (rt1310_gpio_pin_getflags(dev, pin, &flags))
322                 return (ENXIO);
323
324         if (flags & GPIO_PIN_OUTPUT)
325                 dir = 1;
326
327         if (flags & GPIO_PIN_INPUT)
328                 dir = 0;
329
330         switch (map->lp_port) {
331         case RT_GPIO_PORTA:
332                 state = rt1310_gpio_read_4(sc, RT_GPIO_OFF_PADR);
333                 *value = !!(state & (1 << RT_GPIO_PIN_BIT(map, pin)));
334                 break;
335         case RT_GPIO_PORTB:
336                 state = rt1310_gpio_read_4(sc, RT_GPIO_OFF_PBDR);
337                 *value = !!(state & (1 << RT_GPIO_PIN_BIT(map, pin)));
338                 break;
339         }
340
341         return (0);
342 }
343
344 static int
345 rt1310_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value)
346 {
347         struct rt1310_gpio_softc *sc = device_get_softc(dev);
348         const struct rt1310_gpio_pinmap *map;
349         uint32_t state, flags;
350         uint32_t port;
351
352         map = rt1310_gpio_get_pinmap(pin);
353
354         if (rt1310_gpio_pin_getflags(dev, pin, &flags))
355                 return (ENXIO);
356
357         if ((flags & GPIO_PIN_OUTPUT) == 0)
358                 return (EINVAL);
359
360         switch (map->lp_port) {
361         case RT_GPIO_PORTA:
362                 port = RT_GPIO_OFF_PADR;
363                 break;
364         case RT_GPIO_PORTB:
365                 port = RT_GPIO_OFF_PBDR;
366                 break;
367         }
368
369         state = rt1310_gpio_read_4(sc, port);
370         if (value == 1) {
371                 state |= (1 << RT_GPIO_PIN_BIT(map, pin));
372         } else {
373                 state &= ~(1 << RT_GPIO_PIN_BIT(map, pin));
374         }
375         rt1310_gpio_write_4(sc, port, state);
376
377         return (0);
378 }
379
380 static int
381 rt1310_gpio_pin_toggle(device_t dev, uint32_t pin)
382 {
383         const struct rt1310_gpio_pinmap *map;
384         uint32_t flags;
385
386         map = rt1310_gpio_get_pinmap(pin);
387
388         if (rt1310_gpio_pin_getflags(dev, pin, &flags))
389                 return (ENXIO);
390
391         if ((flags & GPIO_PIN_OUTPUT) == 0)
392                 return (EINVAL);
393         
394         panic("not implemented yet");
395
396         return (0);
397
398 }
399
400 static const struct rt1310_gpio_pinmap *
401 rt1310_gpio_get_pinmap(int pin)
402 {
403         const struct rt1310_gpio_pinmap *map;
404
405         for (map = &rt1310_gpio_pins[0]; map->lp_start_idx != -1; map++) {
406                 if (pin >= map->lp_start_idx &&
407                     pin < map->lp_start_idx + map->lp_pin_count)
408                         return map;
409         }
410
411         panic("pin number %d out of range", pin);
412 }
413
414 int
415 rt1310_gpio_set_flags(device_t dev, int pin, int flags)
416 {
417         if (rt1310_gpio_sc == NULL)
418                 return (ENXIO);
419
420         return rt1310_gpio_pin_setflags(rt1310_gpio_sc->lg_dev, pin, flags);
421 }
422
423 int
424 rt1310_gpio_set_state(device_t dev, int pin, int state)
425 {
426         if (rt1310_gpio_sc == NULL)
427                 return (ENXIO);
428
429         return rt1310_gpio_pin_set(rt1310_gpio_sc->lg_dev, pin, state); 
430 }
431
432 int
433 rt1310_gpio_get_state(device_t dev, int pin, int *state)
434 {
435         if (rt1310_gpio_sc == NULL)
436                 return (ENXIO);
437
438         return rt1310_gpio_pin_get(rt1310_gpio_sc->lg_dev, pin, state);
439 }
440
441 static phandle_t
442 rt1310_gpio_get_node(device_t bus, device_t dev)
443 {
444         /* We only have one child, the GPIO bus, which needs our own node. */
445         return (ofw_bus_get_node(bus));
446 }
447
448 static device_method_t rt1310_gpio_methods[] = {
449         /* Device interface */
450         DEVMETHOD(device_probe,         rt1310_gpio_probe),
451         DEVMETHOD(device_attach,        rt1310_gpio_attach),
452         DEVMETHOD(device_detach,        rt1310_gpio_detach),
453
454         /* GPIO interface */
455         DEVMETHOD(gpio_get_bus,         rt1310_gpio_get_bus),
456         DEVMETHOD(gpio_pin_max,         rt1310_gpio_pin_max),
457         DEVMETHOD(gpio_pin_getcaps,     rt1310_gpio_pin_getcaps),
458         DEVMETHOD(gpio_pin_getflags,    rt1310_gpio_pin_getflags),
459         DEVMETHOD(gpio_pin_setflags,    rt1310_gpio_pin_setflags),
460         DEVMETHOD(gpio_pin_getname,     rt1310_gpio_pin_getname),
461         DEVMETHOD(gpio_pin_set,         rt1310_gpio_pin_set),
462         DEVMETHOD(gpio_pin_get,         rt1310_gpio_pin_get),
463         DEVMETHOD(gpio_pin_toggle,      rt1310_gpio_pin_toggle),
464
465         /* ofw_bus interface */
466         DEVMETHOD(ofw_bus_get_node,     rt1310_gpio_get_node),
467
468         { 0, 0 }
469 };
470
471 static devclass_t rt1310_gpio_devclass;
472
473 static driver_t rt1310_gpio_driver = {
474         "gpio",
475         rt1310_gpio_methods,
476         sizeof(struct rt1310_gpio_softc),
477 };
478
479 DRIVER_MODULE(rt1310gpio, simplebus, rt1310_gpio_driver, rt1310_gpio_devclass, 0, 0);
480 MODULE_VERSION(rt1310gpio, 1);