]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/xscale/ixp425/cambria_gpio.c
arm: make some use of mallocarray(9).
[FreeBSD/FreeBSD.git] / sys / arm / xscale / ixp425 / cambria_gpio.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2010, Andrew Thompson <thompsa@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 unmodified, this list of conditions, and the following
12  *    disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 /*
31  * GPIO driver for Gateworks Cambria
32  *
33  * Note:
34  * The Cambria PLD does not set the i2c ack bit after each write, if we used the
35  * regular iicbus interface it would abort the xfer after the address byte
36  * times out and not write our latch. To get around this we grab the iicbus and
37  * then do our own bit banging. This is a compromise to changing all the iicbb
38  * device methods to allow a flag to be passed down and is similir to how Linux
39  * does it.
40  *
41  */
42
43 #include <sys/cdefs.h>
44 __FBSDID("$FreeBSD$");
45
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/bus.h>
49
50 #include <sys/kernel.h>
51 #include <sys/module.h>
52 #include <sys/rman.h>
53 #include <sys/lock.h>
54 #include <sys/mutex.h>
55 #include <sys/gpio.h>
56
57 #include <arm/xscale/ixp425/ixp425reg.h>
58 #include <arm/xscale/ixp425/ixp425var.h>
59 #include <arm/xscale/ixp425/ixdp425reg.h>
60
61 #include <dev/gpio/gpiobusvar.h>
62 #include <dev/iicbus/iiconf.h>
63 #include <dev/iicbus/iicbus.h>
64
65 #include "iicbb_if.h"
66 #include "gpio_if.h"
67
68 #define IIC_M_WR        0       /* write operation */
69 #define PLD_ADDR        0xac    /* slave address */
70
71 #define I2C_DELAY       10
72
73 #define GPIO_CONF_CLR(sc, reg, mask)    \
74         GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, reg) &~ (mask))
75 #define GPIO_CONF_SET(sc, reg, mask)    \
76         GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, reg) | (mask))
77
78 #define GPIO_LOCK(_sc)          mtx_lock(&(_sc)->sc_mtx)
79 #define GPIO_UNLOCK(_sc)        mtx_unlock(&(_sc)->sc_mtx)
80 #define GPIO_LOCK_ASSERT(_sc)   mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
81
82 #define GPIO_PINS               5
83 struct cambria_gpio_softc {
84         device_t                sc_dev;
85         device_t                sc_busdev;
86         bus_space_tag_t         sc_iot;
87         bus_space_handle_t      sc_gpio_ioh;
88         struct mtx              sc_mtx;
89         struct gpio_pin         sc_pins[GPIO_PINS];
90         uint8_t                 sc_latch;
91         uint8_t                 sc_val;
92 };
93
94 struct cambria_gpio_pin {
95         const char *name;
96         int pin;
97         int flags;
98 };
99
100 extern struct ixp425_softc *ixp425_softc;
101
102 static struct cambria_gpio_pin cambria_gpio_pins[GPIO_PINS] = {
103         { "PLD0", 0, GPIO_PIN_OUTPUT },
104         { "PLD1", 1, GPIO_PIN_OUTPUT },
105         { "PLD2", 2, GPIO_PIN_OUTPUT },
106         { "PLD3", 3, GPIO_PIN_OUTPUT },
107         { "PLD4", 4, GPIO_PIN_OUTPUT },
108 };
109
110 /*
111  * Helpers
112  */
113 static int cambria_gpio_read(struct cambria_gpio_softc *, uint32_t, unsigned int *);
114 static int cambria_gpio_write(struct cambria_gpio_softc *);
115
116 /*
117  * Driver stuff
118  */
119 static int cambria_gpio_probe(device_t dev);
120 static int cambria_gpio_attach(device_t dev);
121 static int cambria_gpio_detach(device_t dev);
122
123 /*
124  * GPIO interface
125  */
126 static device_t cambria_gpio_get_bus(device_t);
127 static int cambria_gpio_pin_max(device_t dev, int *maxpin);
128 static int cambria_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
129 static int cambria_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
130     *flags);
131 static int cambria_gpio_pin_getname(device_t dev, uint32_t pin, char *name);
132 static int cambria_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags);
133 static int cambria_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value);
134 static int cambria_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val);
135 static int cambria_gpio_pin_toggle(device_t dev, uint32_t pin);
136
137 static int
138 i2c_getsda(struct cambria_gpio_softc *sc)
139 {
140         uint32_t reg;
141
142         IXP4XX_GPIO_LOCK();
143         GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
144
145         reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
146         IXP4XX_GPIO_UNLOCK();
147         return (reg & GPIO_I2C_SDA_BIT);
148 }
149
150 static void
151 i2c_setsda(struct cambria_gpio_softc *sc, int val)
152 {
153
154         IXP4XX_GPIO_LOCK();
155         GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT);
156         if (val)
157                 GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
158         else
159                 GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
160         IXP4XX_GPIO_UNLOCK();
161         DELAY(I2C_DELAY);
162 }
163
164 static void
165 i2c_setscl(struct cambria_gpio_softc *sc, int val)
166 {
167
168         IXP4XX_GPIO_LOCK();
169         GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT);
170         if (val)
171                 GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
172         else
173                 GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
174         IXP4XX_GPIO_UNLOCK();
175         DELAY(I2C_DELAY);
176 }
177
178 static void
179 i2c_sendstart(struct cambria_gpio_softc *sc)
180 {
181         i2c_setsda(sc, 1);
182         i2c_setscl(sc, 1);
183         i2c_setsda(sc, 0);
184         i2c_setscl(sc, 0);
185 }
186
187 static void
188 i2c_sendstop(struct cambria_gpio_softc *sc)
189 {
190         i2c_setscl(sc, 1);
191         i2c_setsda(sc, 1);
192         i2c_setscl(sc, 0);
193         i2c_setsda(sc, 0);
194 }
195
196 static void
197 i2c_sendbyte(struct cambria_gpio_softc *sc, u_char data)
198 {
199         int i;
200
201         for (i=7; i>=0; i--) {
202                 i2c_setsda(sc, data & (1<<i));
203                 i2c_setscl(sc, 1);
204                 i2c_setscl(sc, 0);
205         }
206         i2c_setscl(sc, 1);
207         i2c_getsda(sc);
208         i2c_setscl(sc, 0);
209 }
210
211 static u_char
212 i2c_readbyte(struct cambria_gpio_softc *sc)
213 {
214         int i;
215         unsigned char data=0;
216
217         for (i=7; i>=0; i--)
218         {
219                 i2c_setscl(sc, 1);
220                 if (i2c_getsda(sc))
221                         data |= (1<<i);
222                 i2c_setscl(sc, 0);
223         }
224         return data;
225 }
226
227 static int
228 cambria_gpio_read(struct cambria_gpio_softc *sc, uint32_t pin, unsigned int *val)
229 {
230         device_t dev = sc->sc_dev;
231         int error;
232
233         error = iicbus_request_bus(device_get_parent(dev), dev,
234             IIC_DONTWAIT);
235         if (error)
236                 return (error);
237
238         i2c_sendstart(sc);
239         i2c_sendbyte(sc, PLD_ADDR | LSB);
240         *val = (i2c_readbyte(sc) & (1 << pin)) != 0;
241         i2c_sendstop(sc);
242
243         iicbus_release_bus(device_get_parent(dev), dev);
244
245         return (0);
246 }
247
248 static int
249 cambria_gpio_write(struct cambria_gpio_softc *sc)
250 {
251         device_t dev = sc->sc_dev;
252         int error;
253
254         error = iicbus_request_bus(device_get_parent(dev), dev,
255             IIC_DONTWAIT);
256         if (error)
257                 return (error);
258
259         i2c_sendstart(sc);
260         i2c_sendbyte(sc, PLD_ADDR & ~LSB);
261         i2c_sendbyte(sc, sc->sc_latch);
262         i2c_sendstop(sc);
263
264         iicbus_release_bus(device_get_parent(dev), dev);
265
266         return (0);
267 }
268
269 static device_t
270 cambria_gpio_get_bus(device_t dev)
271 {
272         struct cambria_gpio_softc *sc;
273
274         sc = device_get_softc(dev);
275
276         return (sc->sc_busdev);
277 }
278
279 static int
280 cambria_gpio_pin_max(device_t dev, int *maxpin)
281 {
282
283         *maxpin = GPIO_PINS - 1;
284         return (0);
285 }
286
287 static int
288 cambria_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
289 {
290         struct cambria_gpio_softc *sc = device_get_softc(dev);
291
292         if (pin >= GPIO_PINS)
293                 return (EINVAL);
294
295         *caps = sc->sc_pins[pin].gp_caps;
296         return (0);
297 }
298
299 static int
300 cambria_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
301 {
302         struct cambria_gpio_softc *sc = device_get_softc(dev);
303
304         if (pin >= GPIO_PINS)
305                 return (EINVAL);
306
307         *flags = sc->sc_pins[pin].gp_flags;
308         return (0);
309 }
310
311 static int
312 cambria_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
313 {
314         struct cambria_gpio_softc *sc = device_get_softc(dev);
315
316         if (pin >= GPIO_PINS)
317                 return (EINVAL);
318
319         memcpy(name, sc->sc_pins[pin].gp_name, GPIOMAXNAME);
320         return (0);
321 }
322
323 static int
324 cambria_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
325 {
326         struct cambria_gpio_softc *sc = device_get_softc(dev);
327         int error;
328         uint8_t mask;
329
330         mask = 1 << pin;
331
332         if (pin >= GPIO_PINS)
333                 return (EINVAL);
334
335         GPIO_LOCK(sc);
336         sc->sc_pins[pin].gp_flags = flags;
337
338         /*
339          * Writing a logical one sets the signal high and writing a logical
340          * zero sets the signal low. To configure a digital I/O signal as an
341          * input, a logical one must first be written to the data bit to
342          * three-state the associated output.
343          */
344         if (flags & GPIO_PIN_INPUT || sc->sc_val & mask)
345                 sc->sc_latch |= mask; /* input or output & high */
346         else
347                 sc->sc_latch &= ~mask;
348         error = cambria_gpio_write(sc);
349         GPIO_UNLOCK(sc);
350
351         return (error);
352 }
353
354 static int
355 cambria_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
356 {
357         struct cambria_gpio_softc *sc = device_get_softc(dev);
358         int error;
359         uint8_t mask;
360
361         mask = 1 << pin;
362
363         if (pin >= GPIO_PINS)
364                 return (EINVAL);
365         GPIO_LOCK(sc);
366         if (value)
367                 sc->sc_val |= mask;
368         else
369                 sc->sc_val &= ~mask;
370
371         if (sc->sc_pins[pin].gp_flags != GPIO_PIN_OUTPUT) {
372                 /* just save, altering the latch will disable input */
373                 GPIO_UNLOCK(sc);
374                 return (0);
375         }
376
377         if (value)
378                 sc->sc_latch |= mask;
379         else
380                 sc->sc_latch &= ~mask;
381         error = cambria_gpio_write(sc);
382         GPIO_UNLOCK(sc);
383
384         return (error);
385 }
386
387 static int
388 cambria_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
389 {
390         struct cambria_gpio_softc *sc = device_get_softc(dev);
391         int error = 0;
392
393         if (pin >= GPIO_PINS)
394                 return (EINVAL);
395
396         GPIO_LOCK(sc);
397         if (sc->sc_pins[pin].gp_flags == GPIO_PIN_OUTPUT)
398                 *val = (sc->sc_latch & (1 << pin)) ? 1 : 0;
399         else
400                 error = cambria_gpio_read(sc, pin, val);
401         GPIO_UNLOCK(sc);
402
403         return (error);
404 }
405
406 static int
407 cambria_gpio_pin_toggle(device_t dev, uint32_t pin)
408 {
409         struct cambria_gpio_softc *sc = device_get_softc(dev);
410         int error = 0;
411
412         if (pin >= GPIO_PINS)
413                 return (EINVAL);
414
415         GPIO_LOCK(sc);
416         sc->sc_val ^= (1 << pin);
417         if (sc->sc_pins[pin].gp_flags == GPIO_PIN_OUTPUT) {
418                 sc->sc_latch ^= (1 << pin);
419                 error = cambria_gpio_write(sc);
420         }
421         GPIO_UNLOCK(sc);
422
423         return (error);
424 }
425
426 static int
427 cambria_gpio_probe(device_t dev)
428 {
429
430         device_set_desc(dev, "Gateworks Cambria GPIO driver");
431         return (0);
432 }
433
434 static int
435 cambria_gpio_attach(device_t dev)
436 {
437         struct cambria_gpio_softc *sc = device_get_softc(dev);
438         int pin;
439
440         sc->sc_dev = dev;
441         sc->sc_iot = ixp425_softc->sc_iot;
442         sc->sc_gpio_ioh = ixp425_softc->sc_gpio_ioh;
443
444         mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
445
446         for (pin = 0; pin < GPIO_PINS; pin++) {
447                 struct cambria_gpio_pin *p = &cambria_gpio_pins[pin];
448
449                 strncpy(sc->sc_pins[pin].gp_name, p->name, GPIOMAXNAME);
450                 sc->sc_pins[pin].gp_pin = pin;
451                 sc->sc_pins[pin].gp_caps = GPIO_PIN_INPUT|GPIO_PIN_OUTPUT;
452                 sc->sc_pins[pin].gp_flags = 0;
453                 cambria_gpio_pin_setflags(dev, pin, p->flags);
454         }
455
456         sc->sc_busdev = gpiobus_attach_bus(dev);
457         if (sc->sc_busdev == NULL) {
458                 mtx_destroy(&sc->sc_mtx);
459                 return (ENXIO);
460         }
461
462         return (0);
463 }
464
465 static int
466 cambria_gpio_detach(device_t dev)
467 {
468         struct cambria_gpio_softc *sc = device_get_softc(dev);
469
470         KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
471
472         gpiobus_detach_bus(dev);
473         mtx_destroy(&sc->sc_mtx);
474
475         return(0);
476 }
477
478 static device_method_t cambria_gpio_methods[] = {
479         DEVMETHOD(device_probe, cambria_gpio_probe),
480         DEVMETHOD(device_attach, cambria_gpio_attach),
481         DEVMETHOD(device_detach, cambria_gpio_detach),
482
483         /* GPIO protocol */
484         DEVMETHOD(gpio_get_bus, cambria_gpio_get_bus),
485         DEVMETHOD(gpio_pin_max, cambria_gpio_pin_max),
486         DEVMETHOD(gpio_pin_getname, cambria_gpio_pin_getname),
487         DEVMETHOD(gpio_pin_getflags, cambria_gpio_pin_getflags),
488         DEVMETHOD(gpio_pin_getcaps, cambria_gpio_pin_getcaps),
489         DEVMETHOD(gpio_pin_setflags, cambria_gpio_pin_setflags),
490         DEVMETHOD(gpio_pin_get, cambria_gpio_pin_get),
491         DEVMETHOD(gpio_pin_set, cambria_gpio_pin_set),
492         DEVMETHOD(gpio_pin_toggle, cambria_gpio_pin_toggle),
493         {0, 0},
494 };
495
496 static driver_t cambria_gpio_driver = {
497         "gpio",
498         cambria_gpio_methods,
499         sizeof(struct cambria_gpio_softc),
500 };
501 static devclass_t cambria_gpio_devclass;
502
503 DRIVER_MODULE(gpio_cambria, iicbus, cambria_gpio_driver, cambria_gpio_devclass, 0, 0);
504 MODULE_VERSION(gpio_cambria, 1);
505 MODULE_DEPEND(gpio_cambria, iicbus, 1, 1, 1);