]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm64/rockchip/rk_gpio.c
MFV 354917, 354918, 354919
[FreeBSD/FreeBSD.git] / sys / arm64 / rockchip / rk_gpio.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2018 Emmanuel Vadot <manu@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/bus.h>
36
37 #include <sys/kernel.h>
38 #include <sys/module.h>
39 #include <sys/rman.h>
40 #include <sys/lock.h>
41 #include <sys/mutex.h>
42 #include <sys/gpio.h>
43
44 #include <machine/bus.h>
45 #include <machine/resource.h>
46 #include <machine/intr.h>
47
48 #include <dev/gpio/gpiobusvar.h>
49 #include <dev/ofw/ofw_bus.h>
50 #include <dev/ofw/ofw_bus_subr.h>
51 #include <dev/extres/clk/clk.h>
52
53 #include "gpio_if.h"
54
55 #define RK_GPIO_SWPORTA_DR      0x00    /* Data register */
56 #define RK_GPIO_SWPORTA_DDR     0x04    /* Data direction register */
57
58 #define RK_GPIO_INTEN           0x30    /* Interrupt enable register */
59 #define RK_GPIO_INTMASK         0x34    /* Interrupt mask register */
60 #define RK_GPIO_INTTYPE_LEVEL   0x38    /* Interrupt level register */
61 #define RK_GPIO_INT_POLARITY    0x3C    /* Interrupt polarity register */
62 #define RK_GPIO_INT_STATUS      0x40    /* Interrupt status register */
63 #define RK_GPIO_INT_RAWSTATUS   0x44    /* Raw Interrupt status register */
64
65 #define RK_GPIO_DEBOUNCE        0x48    /* Debounce enable register */
66
67 #define RK_GPIO_PORTA_EOI       0x4C    /* Clear interrupt register */
68 #define RK_GPIO_EXT_PORTA       0x50    /* External port register */
69
70 #define RK_GPIO_LS_SYNC         0x60    /* Level sensitive syncronization enable register */
71
72 struct rk_gpio_softc {
73         device_t                sc_dev;
74         device_t                sc_busdev;
75         struct mtx              sc_mtx;
76         struct resource         *sc_res[2];
77         bus_space_tag_t         sc_bst;
78         bus_space_handle_t      sc_bsh;
79         clk_t                   clk;
80 };
81
82 static struct ofw_compat_data compat_data[] = {
83         {"rockchip,gpio-bank", 1},
84         {NULL,             0}
85 };
86
87 static struct resource_spec rk_gpio_spec[] = {
88         { SYS_RES_MEMORY,       0,      RF_ACTIVE },
89         { SYS_RES_IRQ,          0,      RF_ACTIVE },
90         { -1, 0 }
91 };
92
93 static int rk_gpio_detach(device_t dev);
94
95 #define RK_GPIO_LOCK(_sc)               mtx_lock_spin(&(_sc)->sc_mtx)
96 #define RK_GPIO_UNLOCK(_sc)             mtx_unlock_spin(&(_sc)->sc_mtx)
97 #define RK_GPIO_LOCK_ASSERT(_sc)        mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
98
99 #define RK_GPIO_WRITE(_sc, _off, _val)          \
100     bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val)
101 #define RK_GPIO_READ(_sc, _off)         \
102     bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off)
103
104 static int
105 rk_gpio_probe(device_t dev)
106 {
107
108         if (!ofw_bus_status_okay(dev))
109                 return (ENXIO);
110
111         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
112                 return (ENXIO);
113
114         device_set_desc(dev, "RockChip GPIO Bank controller");
115         return (BUS_PROBE_DEFAULT);
116 }
117
118 static int
119 rk_gpio_attach(device_t dev)
120 {
121         struct rk_gpio_softc *sc;
122         phandle_t node;
123         int err;
124
125         sc = device_get_softc(dev);
126         sc->sc_dev = dev;
127
128         node = ofw_bus_get_node(sc->sc_dev);
129         if (!OF_hasprop(node, "gpio-controller"))
130                 return (ENXIO);
131
132         mtx_init(&sc->sc_mtx, "rk gpio", "gpio", MTX_SPIN);
133
134         if (bus_alloc_resources(dev, rk_gpio_spec, sc->sc_res)) {
135                 device_printf(dev, "could not allocate resources\n");
136                 bus_release_resources(dev, rk_gpio_spec, sc->sc_res);
137                 mtx_destroy(&sc->sc_mtx);
138                 return (ENXIO);
139         }
140
141         sc->sc_bst = rman_get_bustag(sc->sc_res[0]);
142         sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]);
143
144         if (clk_get_by_ofw_index(dev, 0, 0, &sc->clk) != 0) {
145                 device_printf(dev, "Cannot get clock\n");
146                 rk_gpio_detach(dev);
147                 return (ENXIO);
148         }
149         err = clk_enable(sc->clk);
150         if (err != 0) {
151                 device_printf(dev, "Could not enable clock %s\n",
152                     clk_get_name(sc->clk));
153                 rk_gpio_detach(dev);
154                 return (ENXIO);
155         }
156
157         sc->sc_busdev = gpiobus_attach_bus(dev);
158         if (sc->sc_busdev == NULL) {
159                 rk_gpio_detach(dev);
160                 return (ENXIO);
161         }
162
163         return (0);
164 }
165
166 static int
167 rk_gpio_detach(device_t dev)
168 {
169         struct rk_gpio_softc *sc;
170
171         sc = device_get_softc(dev);
172
173         if (sc->sc_busdev)
174                 gpiobus_detach_bus(dev);
175         bus_release_resources(dev, rk_gpio_spec, sc->sc_res);
176         mtx_destroy(&sc->sc_mtx);
177         clk_disable(sc->clk);
178
179         return(0);
180 }
181
182 static device_t
183 rk_gpio_get_bus(device_t dev)
184 {
185         struct rk_gpio_softc *sc;
186
187         sc = device_get_softc(dev);
188
189         return (sc->sc_busdev);
190 }
191
192 static int
193 rk_gpio_pin_max(device_t dev, int *maxpin)
194 {
195
196         /* Each bank have always 32 pins */
197         /* XXX not true*/
198         *maxpin = 32;
199         return (0);
200 }
201
202 static int
203 rk_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
204 {
205         struct rk_gpio_softc *sc;
206
207         sc = device_get_softc(dev);
208
209         if (pin >= 32)
210                 return (EINVAL);
211
212         RK_GPIO_LOCK(sc);
213         snprintf(name, GPIOMAXNAME, "gpio%d", pin);
214         RK_GPIO_UNLOCK(sc);
215
216         return (0);
217 }
218
219 static int
220 rk_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
221 {
222         struct rk_gpio_softc *sc;
223         uint32_t reg;
224
225         sc = device_get_softc(dev);
226
227         /* XXX Combine this with parent (pinctrl) */
228         RK_GPIO_LOCK(sc);
229         reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DDR);
230         RK_GPIO_UNLOCK(sc);
231
232         if (reg & (1 << pin))
233                 *flags = GPIO_PIN_OUTPUT;
234         else
235                 *flags = GPIO_PIN_INPUT;
236
237         return (0);
238 }
239
240 static int
241 rk_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
242 {
243
244         /* Caps are managed by the pinctrl device */
245         /* XXX Pass this to parent (pinctrl) */
246         *caps = 0;
247         return (0);
248 }
249
250 static int
251 rk_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
252 {
253         struct rk_gpio_softc *sc;
254         uint32_t reg;
255
256         sc = device_get_softc(dev);
257
258         /* XXX Combine this with parent (pinctrl) */
259         RK_GPIO_LOCK(sc);
260
261         reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DDR);
262         if (flags & GPIO_PIN_INPUT)
263                 reg &= ~(1 << pin);
264         else if (flags & GPIO_PIN_OUTPUT)
265                 reg |= (1 << pin);
266
267         RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DDR, reg);
268         RK_GPIO_UNLOCK(sc);
269
270         return (0);
271 }
272
273 static int
274 rk_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
275 {
276         struct rk_gpio_softc *sc;
277         uint32_t reg;
278
279         sc = device_get_softc(dev);
280
281         RK_GPIO_LOCK(sc);
282         reg = RK_GPIO_READ(sc, RK_GPIO_EXT_PORTA);
283         RK_GPIO_UNLOCK(sc);
284
285         *val = reg & (1 << pin) ? 1 : 0;
286
287         return (0);
288 }
289
290 static int
291 rk_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
292 {
293         struct rk_gpio_softc *sc;
294         uint32_t reg;
295
296         sc = device_get_softc(dev);
297
298         RK_GPIO_LOCK(sc);
299         reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DR);
300         if (value)
301                 reg |= (1 << pin);
302         else
303                 reg &= ~(1 << pin);
304         RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DR, reg);
305         RK_GPIO_UNLOCK(sc);
306
307         return (0);
308 }
309
310 static int
311 rk_gpio_pin_toggle(device_t dev, uint32_t pin)
312 {
313         struct rk_gpio_softc *sc;
314         uint32_t reg;
315
316         sc = device_get_softc(dev);
317
318         RK_GPIO_LOCK(sc);
319         reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DR);
320         if (reg & (1 << pin))
321                 reg &= ~(1 << pin);
322         else
323                 reg |= (1 << pin);
324         RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DR, reg);
325         RK_GPIO_UNLOCK(sc);
326
327         return (0);
328 }
329
330 static int
331 rk_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins,
332     uint32_t change_pins, uint32_t *orig_pins)
333 {
334         struct rk_gpio_softc *sc;
335         uint32_t reg;
336
337         sc = device_get_softc(dev);
338
339         RK_GPIO_LOCK(sc);
340         reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DR);
341         if (orig_pins)
342                 *orig_pins = reg;
343
344         if ((clear_pins | change_pins) != 0) {
345                 reg = (reg & ~clear_pins) ^ change_pins;
346                 RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DR, reg);
347         }
348         RK_GPIO_UNLOCK(sc);
349
350         return (0);
351 }
352
353 static int
354 rk_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins,
355     uint32_t *pin_flags)
356 {
357         struct rk_gpio_softc *sc;
358         uint32_t reg, set, mask, flags;
359         int i;
360
361         sc = device_get_softc(dev);
362
363         if (first_pin != 0 || num_pins > 32)
364                 return (EINVAL);
365
366         set = 0;
367         mask = 0;
368         for (i = 0; i < num_pins; i++) {
369                 mask = (mask << 1) | 1;
370                 flags = pin_flags[i];
371                 if (flags & GPIO_PIN_INPUT) {
372                         set &= ~(1 << i);
373                 } else if (flags & GPIO_PIN_OUTPUT) {
374                         set |= (1 << i);
375                 }
376         }
377
378         RK_GPIO_LOCK(sc);
379         reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DDR);
380         reg &= ~mask;
381         reg |= set;
382         RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DDR, reg);
383         RK_GPIO_UNLOCK(sc);
384
385         return (0);
386 }
387
388 static int
389 rk_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
390     pcell_t *gpios, uint32_t *pin, uint32_t *flags)
391 {
392
393         /* The gpios are mapped as <pin flags> */
394         *pin = gpios[0];
395         *flags = gpios[1];
396         return (0);
397 }
398
399 static phandle_t
400 rk_gpio_get_node(device_t bus, device_t dev)
401 {
402
403         /* We only have one child, the GPIO bus, which needs our own node. */
404         return (ofw_bus_get_node(bus));
405 }
406
407 static device_method_t rk_gpio_methods[] = {
408         /* Device interface */
409         DEVMETHOD(device_probe,         rk_gpio_probe),
410         DEVMETHOD(device_attach,        rk_gpio_attach),
411         DEVMETHOD(device_detach,        rk_gpio_detach),
412
413         /* GPIO protocol */
414         DEVMETHOD(gpio_get_bus,         rk_gpio_get_bus),
415         DEVMETHOD(gpio_pin_max,         rk_gpio_pin_max),
416         DEVMETHOD(gpio_pin_getname,     rk_gpio_pin_getname),
417         DEVMETHOD(gpio_pin_getflags,    rk_gpio_pin_getflags),
418         DEVMETHOD(gpio_pin_getcaps,     rk_gpio_pin_getcaps),
419         DEVMETHOD(gpio_pin_setflags,    rk_gpio_pin_setflags),
420         DEVMETHOD(gpio_pin_get,         rk_gpio_pin_get),
421         DEVMETHOD(gpio_pin_set,         rk_gpio_pin_set),
422         DEVMETHOD(gpio_pin_toggle,      rk_gpio_pin_toggle),
423         DEVMETHOD(gpio_pin_access_32,   rk_gpio_pin_access_32),
424         DEVMETHOD(gpio_pin_config_32,   rk_gpio_pin_config_32),
425         DEVMETHOD(gpio_map_gpios,       rk_gpio_map_gpios),
426
427         /* ofw_bus interface */
428         DEVMETHOD(ofw_bus_get_node,     rk_gpio_get_node),
429
430         DEVMETHOD_END
431 };
432
433 static driver_t rk_gpio_driver = {
434         "gpio",
435         rk_gpio_methods,
436         sizeof(struct rk_gpio_softc),
437 };
438
439 static devclass_t rk_gpio_devclass;
440
441 /*
442  * GPIO driver is always a child of rk_pinctrl driver and should be probed
443  * and attached within rk_pinctrl_attach function. Due to this, bus pass order
444  * must be same as bus pass order of rk_pinctrl driver.
445  */
446 EARLY_DRIVER_MODULE(rk_gpio, simplebus, rk_gpio_driver,
447     rk_gpio_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);