]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - sys/arm/xscale/ixp425/cambria_gpio.c
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / sys / arm / xscale / ixp425 / cambria_gpio.c
1 /*-
2  * Copyright (c) 2010, Andrew Thompson <thompsa@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 unmodified, this list of conditions, and the following
10  *    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  * GPIO driver for Gateworks Cambria
30  *
31  * Note:
32  * The Cambria PLD does not set the i2c ack bit after each write, if we used the
33  * regular iicbus interface it would abort the xfer after the address byte
34  * times out and not write our latch. To get around this we grab the iicbus and
35  * then do our own bit banging. This is a comprimise to changing all the iicbb
36  * device methods to allow a flag to be passed down and is similir to how Linux
37  * does it.
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/bus.h>
47
48 #include <sys/kernel.h>
49 #include <sys/module.h>
50 #include <sys/rman.h>
51 #include <sys/lock.h>
52 #include <sys/mutex.h>
53 #include <sys/gpio.h>
54
55 #include <arm/xscale/ixp425/ixp425reg.h>
56 #include <arm/xscale/ixp425/ixp425var.h>
57 #include <arm/xscale/ixp425/ixdp425reg.h>
58
59 #include <dev/iicbus/iiconf.h>
60 #include <dev/iicbus/iicbus.h>
61
62 #include "iicbb_if.h"
63 #include "gpio_if.h"
64
65 #define IIC_M_WR        0       /* write operation */
66 #define PLD_ADDR        0xac    /* slave address */
67
68 #define I2C_DELAY       10
69
70 #define GPIO_CONF_CLR(sc, reg, mask)    \
71         GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, reg) &~ (mask))
72 #define GPIO_CONF_SET(sc, reg, mask)    \
73         GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, reg) | (mask))
74
75 #define GPIO_LOCK(_sc)          mtx_lock(&(_sc)->sc_mtx)
76 #define GPIO_UNLOCK(_sc)        mtx_unlock(&(_sc)->sc_mtx)
77 #define GPIO_LOCK_ASSERT(_sc)   mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
78
79 #define GPIO_PINS               5
80 struct cambria_gpio_softc {
81         device_t                sc_dev;
82         bus_space_tag_t         sc_iot;
83         bus_space_handle_t      sc_gpio_ioh;
84         struct mtx              sc_mtx;
85         struct gpio_pin         sc_pins[GPIO_PINS];
86         uint8_t                 sc_latch;
87 };
88
89 struct cambria_gpio_pin {
90         const char *name;
91         int pin;
92         int flags;
93 };
94
95 extern struct ixp425_softc *ixp425_softc;
96
97 static struct cambria_gpio_pin cambria_gpio_pins[GPIO_PINS] = {
98         { "GPIO0", 0, GPIO_PIN_OUTPUT },
99         { "GPIO1", 1, GPIO_PIN_OUTPUT },
100         { "GPIO2", 2, GPIO_PIN_OUTPUT },
101         { "GPIO3", 3, GPIO_PIN_OUTPUT },
102         { "GPIO4", 4, GPIO_PIN_OUTPUT },
103 };
104
105 /*
106  * Helpers
107  */
108 static int cambria_gpio_read(struct cambria_gpio_softc *, uint32_t, unsigned int *);
109 static int cambria_gpio_write(struct cambria_gpio_softc *);
110
111 /*
112  * Driver stuff
113  */
114 static int cambria_gpio_probe(device_t dev);
115 static int cambria_gpio_attach(device_t dev);
116 static int cambria_gpio_detach(device_t dev);
117
118 /*
119  * GPIO interface
120  */
121 static int cambria_gpio_pin_max(device_t dev, int *maxpin);
122 static int cambria_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
123 static int cambria_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
124     *flags);
125 static int cambria_gpio_pin_getname(device_t dev, uint32_t pin, char *name);
126 static int cambria_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags);
127 static int cambria_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value);
128 static int cambria_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val);
129 static int cambria_gpio_pin_toggle(device_t dev, uint32_t pin);
130
131 static int
132 i2c_getsda(struct cambria_gpio_softc *sc)
133 {
134         uint32_t reg;
135
136         IXP4XX_GPIO_LOCK();
137         GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
138
139         reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
140         IXP4XX_GPIO_UNLOCK();
141         return (reg & GPIO_I2C_SDA_BIT);
142 }
143
144 static void
145 i2c_setsda(struct cambria_gpio_softc *sc, int val)
146 {
147
148         IXP4XX_GPIO_LOCK();
149         GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT);
150         if (val)
151                 GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
152         else
153                 GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
154         IXP4XX_GPIO_UNLOCK();
155         DELAY(I2C_DELAY);
156 }
157
158 static void
159 i2c_setscl(struct cambria_gpio_softc *sc, int val)
160 {
161
162         IXP4XX_GPIO_LOCK();
163         GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT);
164         if (val)
165                 GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
166         else
167                 GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
168         IXP4XX_GPIO_UNLOCK();
169         DELAY(I2C_DELAY);
170 }
171
172 static void
173 i2c_sendstart(struct cambria_gpio_softc *sc)
174 {
175         i2c_setsda(sc, 1);
176         i2c_setscl(sc, 1);
177         i2c_setsda(sc, 0);
178         i2c_setscl(sc, 0);
179 }
180
181 static void
182 i2c_sendstop(struct cambria_gpio_softc *sc)
183 {
184         i2c_setscl(sc, 1);
185         i2c_setsda(sc, 1);
186         i2c_setscl(sc, 0);
187         i2c_setsda(sc, 0);
188 }
189
190 static void
191 i2c_sendbyte(struct cambria_gpio_softc *sc, u_char data)
192 {
193         int i;
194
195         for (i=7; i>=0; i--) {
196                 i2c_setsda(sc, data & (1<<i));
197                 i2c_setscl(sc, 1);
198                 i2c_setscl(sc, 0);
199         }
200         i2c_setscl(sc, 1);
201         i2c_getsda(sc);
202         i2c_setscl(sc, 0);
203 }
204
205 static u_char
206 i2c_readbyte(struct cambria_gpio_softc *sc)
207 {
208         int i;
209         unsigned char data=0;
210
211         for (i=7; i>=0; i--)
212         {
213                 i2c_setscl(sc, 1);
214                 if (i2c_getsda(sc))
215                         data |= (1<<i);
216                 i2c_setscl(sc, 0);
217         }
218         return data;
219 }
220
221 static int
222 cambria_gpio_read(struct cambria_gpio_softc *sc, uint32_t pin, unsigned int *val)
223 {
224         device_t dev = sc->sc_dev;
225         int error;
226
227         error = iicbus_request_bus(device_get_parent(dev), dev,
228             IIC_DONTWAIT);
229         if (error)
230                 return (error);
231
232         i2c_sendstart(sc);
233         i2c_sendbyte(sc, PLD_ADDR | LSB);
234         *val = (i2c_readbyte(sc) & (1 << pin)) != 0;
235         i2c_sendstop(sc);
236
237         iicbus_release_bus(device_get_parent(dev), dev);
238
239         return (0);
240 }
241
242 static int
243 cambria_gpio_write(struct cambria_gpio_softc *sc)
244 {
245         device_t dev = sc->sc_dev;
246         int error;
247
248         error = iicbus_request_bus(device_get_parent(dev), dev,
249             IIC_DONTWAIT);
250         if (error)
251                 return (error);
252
253         i2c_sendstart(sc);
254         i2c_sendbyte(sc, PLD_ADDR & ~LSB);
255         i2c_sendbyte(sc, sc->sc_latch);
256         i2c_sendstop(sc);
257
258         iicbus_release_bus(device_get_parent(dev), dev);
259
260         return (0);
261 }
262
263 static int
264 cambria_gpio_pin_max(device_t dev, int *maxpin)
265 {
266
267         *maxpin = GPIO_PINS - 1;
268         return (0);
269 }
270
271 static int
272 cambria_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
273 {
274         struct cambria_gpio_softc *sc = device_get_softc(dev);
275
276         if (pin >= GPIO_PINS)
277                 return (EINVAL);
278
279         *caps = sc->sc_pins[pin].gp_caps;
280         return (0);
281 }
282
283 static int
284 cambria_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
285 {
286         struct cambria_gpio_softc *sc = device_get_softc(dev);
287
288         if (pin >= GPIO_PINS)
289                 return (EINVAL);
290
291         *flags = sc->sc_pins[pin].gp_flags;
292         return (0);
293 }
294
295 static int
296 cambria_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
297 {
298         struct cambria_gpio_softc *sc = device_get_softc(dev);
299
300         if (pin >= GPIO_PINS)
301                 return (EINVAL);
302
303         memcpy(name, sc->sc_pins[pin].gp_name, GPIOMAXNAME);
304         return (0);
305 }
306
307 static int
308 cambria_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
309 {
310         struct cambria_gpio_softc *sc = device_get_softc(dev);
311         int error;
312
313         if (pin >= GPIO_PINS)
314                 return (EINVAL);
315
316         /* Filter out unwanted flags */
317         if ((flags &= sc->sc_pins[pin].gp_caps) != flags)
318                 return (EINVAL);
319
320         /* Can't mix input/output together */
321         if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) ==
322             (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT))
323                 return (EINVAL);
324
325         GPIO_LOCK(sc);
326         sc->sc_pins[pin].gp_flags = flags;
327
328         sc->sc_latch |= (1 << pin);
329         error = cambria_gpio_write(sc);
330         GPIO_UNLOCK(sc);
331
332         return (error);
333 }
334
335 static int
336 cambria_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
337 {
338         struct cambria_gpio_softc *sc = device_get_softc(dev);
339         int error;
340
341         if (pin >= GPIO_PINS || sc->sc_pins[pin].gp_flags != GPIO_PIN_OUTPUT)
342                 return (EINVAL);
343
344         GPIO_LOCK(sc);
345         if (value)
346                 sc->sc_latch |= (1 << pin);
347         else
348                 sc->sc_latch &= ~(1 << pin);
349         error = cambria_gpio_write(sc);
350         GPIO_UNLOCK(sc);
351
352         return (error);
353 }
354
355 static int
356 cambria_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
357 {
358         struct cambria_gpio_softc *sc = device_get_softc(dev);
359         int error = 0;
360
361         if (pin >= GPIO_PINS)
362                 return (EINVAL);
363
364         GPIO_LOCK(sc);
365         if (sc->sc_pins[pin].gp_flags == GPIO_PIN_OUTPUT)
366                 *val = (sc->sc_latch & (1 << pin)) ? 1 : 0;
367         else
368                 error = cambria_gpio_read(sc, pin, val);
369         GPIO_UNLOCK(sc);
370
371         return (error);
372 }
373
374 static int
375 cambria_gpio_pin_toggle(device_t dev, uint32_t pin)
376 {
377         struct cambria_gpio_softc *sc = device_get_softc(dev);
378         int error;
379
380         if (pin >= GPIO_PINS || sc->sc_pins[pin].gp_flags != GPIO_PIN_OUTPUT)
381                 return (EINVAL);
382
383         GPIO_LOCK(sc);
384         sc->sc_latch ^= (1 << pin);
385         error = cambria_gpio_write(sc);
386         GPIO_UNLOCK(sc);
387
388         return (error);
389 }
390
391 static int
392 cambria_gpio_probe(device_t dev)
393 {
394
395         device_set_desc(dev, "Gateworks Cambria GPIO driver");
396         return (0);
397 }
398
399 static int
400 cambria_gpio_attach(device_t dev)
401 {
402         struct cambria_gpio_softc *sc = device_get_softc(dev);
403         int pin;
404
405         sc->sc_dev = dev;
406         sc->sc_iot = ixp425_softc->sc_iot;
407         sc->sc_gpio_ioh = ixp425_softc->sc_gpio_ioh;
408
409         mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
410             MTX_DEF);
411
412         for (pin = 0; pin < GPIO_PINS; pin++) {
413                 struct cambria_gpio_pin *p = &cambria_gpio_pins[pin];
414
415                 strncpy(sc->sc_pins[pin].gp_name, p->name, GPIOMAXNAME);
416                 sc->sc_pins[pin].gp_pin = pin;
417                 sc->sc_pins[pin].gp_caps = GPIO_PIN_INPUT|GPIO_PIN_OUTPUT;
418                 sc->sc_pins[pin].gp_flags = 0;
419                 cambria_gpio_pin_setflags(dev, pin, p->flags);
420         }
421
422         device_add_child(dev, "gpioc", device_get_unit(dev));
423         device_add_child(dev, "gpiobus", device_get_unit(dev));
424         return (bus_generic_attach(dev));
425 }
426
427 static int
428 cambria_gpio_detach(device_t dev)
429 {
430         struct cambria_gpio_softc *sc = device_get_softc(dev);
431
432         KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
433
434         bus_generic_detach(dev);
435
436         mtx_destroy(&sc->sc_mtx);
437
438         return(0);
439 }
440
441 static device_method_t cambria_gpio_methods[] = {
442         DEVMETHOD(device_probe, cambria_gpio_probe),
443         DEVMETHOD(device_attach, cambria_gpio_attach),
444         DEVMETHOD(device_detach, cambria_gpio_detach),
445
446         /* GPIO protocol */
447         DEVMETHOD(gpio_pin_max, cambria_gpio_pin_max),
448         DEVMETHOD(gpio_pin_getname, cambria_gpio_pin_getname),
449         DEVMETHOD(gpio_pin_getflags, cambria_gpio_pin_getflags),
450         DEVMETHOD(gpio_pin_getcaps, cambria_gpio_pin_getcaps),
451         DEVMETHOD(gpio_pin_setflags, cambria_gpio_pin_setflags),
452         DEVMETHOD(gpio_pin_get, cambria_gpio_pin_get),
453         DEVMETHOD(gpio_pin_set, cambria_gpio_pin_set),
454         DEVMETHOD(gpio_pin_toggle, cambria_gpio_pin_toggle),
455         {0, 0},
456 };
457
458 static driver_t cambria_gpio_driver = {
459         "gpio_cambria",
460         cambria_gpio_methods,
461         sizeof(struct cambria_gpio_softc),
462 };
463 static devclass_t cambria_gpio_devclass;
464 extern devclass_t gpiobus_devclass, gpioc_devclass;
465 extern driver_t gpiobus_driver, gpioc_driver;
466
467 DRIVER_MODULE(gpio_cambria, iicbus, cambria_gpio_driver, cambria_gpio_devclass, 0, 0);
468 DRIVER_MODULE(gpiobus, gpio_cambria, gpiobus_driver, gpiobus_devclass, 0, 0);
469 DRIVER_MODULE(gpioc, gpio_cambria, gpioc_driver, gpioc_devclass, 0, 0);
470 MODULE_VERSION(gpio_cambria, 1);
471 MODULE_DEPEND(gpio_cambria, iicbus, 1, 1, 1);