Deleted Added
full compact
cambria_gpio.c (273799) cambria_gpio.c (274670)
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>
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: head/sys/arm/xscale/ixp425/cambria_gpio.c 273799 2014-10-28 18:33:59Z loos $");
42__FBSDID("$FreeBSD: head/sys/arm/xscale/ixp425/cambria_gpio.c 274670 2014-11-18 17:22:08Z loos $");
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
80struct 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 uint8_t sc_val;
88};
89
90struct cambria_gpio_pin {
91 const char *name;
92 int pin;
93 int flags;
94};
95
96extern struct ixp425_softc *ixp425_softc;
97
98static struct cambria_gpio_pin cambria_gpio_pins[GPIO_PINS] = {
99 { "PLD0", 0, GPIO_PIN_OUTPUT },
100 { "PLD1", 1, GPIO_PIN_OUTPUT },
101 { "PLD2", 2, GPIO_PIN_OUTPUT },
102 { "PLD3", 3, GPIO_PIN_OUTPUT },
103 { "PLD4", 4, GPIO_PIN_OUTPUT },
104};
105
106/*
107 * Helpers
108 */
109static int cambria_gpio_read(struct cambria_gpio_softc *, uint32_t, unsigned int *);
110static int cambria_gpio_write(struct cambria_gpio_softc *);
111
112/*
113 * Driver stuff
114 */
115static int cambria_gpio_probe(device_t dev);
116static int cambria_gpio_attach(device_t dev);
117static int cambria_gpio_detach(device_t dev);
118
119/*
120 * GPIO interface
121 */
122static int cambria_gpio_pin_max(device_t dev, int *maxpin);
123static int cambria_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
124static int cambria_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
125 *flags);
126static int cambria_gpio_pin_getname(device_t dev, uint32_t pin, char *name);
127static int cambria_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags);
128static int cambria_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value);
129static int cambria_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val);
130static int cambria_gpio_pin_toggle(device_t dev, uint32_t pin);
131
132static int
133i2c_getsda(struct cambria_gpio_softc *sc)
134{
135 uint32_t reg;
136
137 IXP4XX_GPIO_LOCK();
138 GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
139
140 reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
141 IXP4XX_GPIO_UNLOCK();
142 return (reg & GPIO_I2C_SDA_BIT);
143}
144
145static void
146i2c_setsda(struct cambria_gpio_softc *sc, int val)
147{
148
149 IXP4XX_GPIO_LOCK();
150 GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT);
151 if (val)
152 GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
153 else
154 GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
155 IXP4XX_GPIO_UNLOCK();
156 DELAY(I2C_DELAY);
157}
158
159static void
160i2c_setscl(struct cambria_gpio_softc *sc, int val)
161{
162
163 IXP4XX_GPIO_LOCK();
164 GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT);
165 if (val)
166 GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
167 else
168 GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
169 IXP4XX_GPIO_UNLOCK();
170 DELAY(I2C_DELAY);
171}
172
173static void
174i2c_sendstart(struct cambria_gpio_softc *sc)
175{
176 i2c_setsda(sc, 1);
177 i2c_setscl(sc, 1);
178 i2c_setsda(sc, 0);
179 i2c_setscl(sc, 0);
180}
181
182static void
183i2c_sendstop(struct cambria_gpio_softc *sc)
184{
185 i2c_setscl(sc, 1);
186 i2c_setsda(sc, 1);
187 i2c_setscl(sc, 0);
188 i2c_setsda(sc, 0);
189}
190
191static void
192i2c_sendbyte(struct cambria_gpio_softc *sc, u_char data)
193{
194 int i;
195
196 for (i=7; i>=0; i--) {
197 i2c_setsda(sc, data & (1<<i));
198 i2c_setscl(sc, 1);
199 i2c_setscl(sc, 0);
200 }
201 i2c_setscl(sc, 1);
202 i2c_getsda(sc);
203 i2c_setscl(sc, 0);
204}
205
206static u_char
207i2c_readbyte(struct cambria_gpio_softc *sc)
208{
209 int i;
210 unsigned char data=0;
211
212 for (i=7; i>=0; i--)
213 {
214 i2c_setscl(sc, 1);
215 if (i2c_getsda(sc))
216 data |= (1<<i);
217 i2c_setscl(sc, 0);
218 }
219 return data;
220}
221
222static int
223cambria_gpio_read(struct cambria_gpio_softc *sc, uint32_t pin, unsigned int *val)
224{
225 device_t dev = sc->sc_dev;
226 int error;
227
228 error = iicbus_request_bus(device_get_parent(dev), dev,
229 IIC_DONTWAIT);
230 if (error)
231 return (error);
232
233 i2c_sendstart(sc);
234 i2c_sendbyte(sc, PLD_ADDR | LSB);
235 *val = (i2c_readbyte(sc) & (1 << pin)) != 0;
236 i2c_sendstop(sc);
237
238 iicbus_release_bus(device_get_parent(dev), dev);
239
240 return (0);
241}
242
243static int
244cambria_gpio_write(struct cambria_gpio_softc *sc)
245{
246 device_t dev = sc->sc_dev;
247 int error;
248
249 error = iicbus_request_bus(device_get_parent(dev), dev,
250 IIC_DONTWAIT);
251 if (error)
252 return (error);
253
254 i2c_sendstart(sc);
255 i2c_sendbyte(sc, PLD_ADDR & ~LSB);
256 i2c_sendbyte(sc, sc->sc_latch);
257 i2c_sendstop(sc);
258
259 iicbus_release_bus(device_get_parent(dev), dev);
260
261 return (0);
262}
263
264static int
265cambria_gpio_pin_max(device_t dev, int *maxpin)
266{
267
268 *maxpin = GPIO_PINS - 1;
269 return (0);
270}
271
272static int
273cambria_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
274{
275 struct cambria_gpio_softc *sc = device_get_softc(dev);
276
277 if (pin >= GPIO_PINS)
278 return (EINVAL);
279
280 *caps = sc->sc_pins[pin].gp_caps;
281 return (0);
282}
283
284static int
285cambria_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
286{
287 struct cambria_gpio_softc *sc = device_get_softc(dev);
288
289 if (pin >= GPIO_PINS)
290 return (EINVAL);
291
292 *flags = sc->sc_pins[pin].gp_flags;
293 return (0);
294}
295
296static int
297cambria_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
298{
299 struct cambria_gpio_softc *sc = device_get_softc(dev);
300
301 if (pin >= GPIO_PINS)
302 return (EINVAL);
303
304 memcpy(name, sc->sc_pins[pin].gp_name, GPIOMAXNAME);
305 return (0);
306}
307
308static int
309cambria_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
310{
311 struct cambria_gpio_softc *sc = device_get_softc(dev);
312 int error;
313 uint8_t mask;
314
315 mask = 1 << pin;
316
317 if (pin >= GPIO_PINS)
318 return (EINVAL);
319
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
80struct 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 uint8_t sc_val;
88};
89
90struct cambria_gpio_pin {
91 const char *name;
92 int pin;
93 int flags;
94};
95
96extern struct ixp425_softc *ixp425_softc;
97
98static struct cambria_gpio_pin cambria_gpio_pins[GPIO_PINS] = {
99 { "PLD0", 0, GPIO_PIN_OUTPUT },
100 { "PLD1", 1, GPIO_PIN_OUTPUT },
101 { "PLD2", 2, GPIO_PIN_OUTPUT },
102 { "PLD3", 3, GPIO_PIN_OUTPUT },
103 { "PLD4", 4, GPIO_PIN_OUTPUT },
104};
105
106/*
107 * Helpers
108 */
109static int cambria_gpio_read(struct cambria_gpio_softc *, uint32_t, unsigned int *);
110static int cambria_gpio_write(struct cambria_gpio_softc *);
111
112/*
113 * Driver stuff
114 */
115static int cambria_gpio_probe(device_t dev);
116static int cambria_gpio_attach(device_t dev);
117static int cambria_gpio_detach(device_t dev);
118
119/*
120 * GPIO interface
121 */
122static int cambria_gpio_pin_max(device_t dev, int *maxpin);
123static int cambria_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
124static int cambria_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
125 *flags);
126static int cambria_gpio_pin_getname(device_t dev, uint32_t pin, char *name);
127static int cambria_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags);
128static int cambria_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value);
129static int cambria_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val);
130static int cambria_gpio_pin_toggle(device_t dev, uint32_t pin);
131
132static int
133i2c_getsda(struct cambria_gpio_softc *sc)
134{
135 uint32_t reg;
136
137 IXP4XX_GPIO_LOCK();
138 GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
139
140 reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
141 IXP4XX_GPIO_UNLOCK();
142 return (reg & GPIO_I2C_SDA_BIT);
143}
144
145static void
146i2c_setsda(struct cambria_gpio_softc *sc, int val)
147{
148
149 IXP4XX_GPIO_LOCK();
150 GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT);
151 if (val)
152 GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
153 else
154 GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
155 IXP4XX_GPIO_UNLOCK();
156 DELAY(I2C_DELAY);
157}
158
159static void
160i2c_setscl(struct cambria_gpio_softc *sc, int val)
161{
162
163 IXP4XX_GPIO_LOCK();
164 GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT);
165 if (val)
166 GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
167 else
168 GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
169 IXP4XX_GPIO_UNLOCK();
170 DELAY(I2C_DELAY);
171}
172
173static void
174i2c_sendstart(struct cambria_gpio_softc *sc)
175{
176 i2c_setsda(sc, 1);
177 i2c_setscl(sc, 1);
178 i2c_setsda(sc, 0);
179 i2c_setscl(sc, 0);
180}
181
182static void
183i2c_sendstop(struct cambria_gpio_softc *sc)
184{
185 i2c_setscl(sc, 1);
186 i2c_setsda(sc, 1);
187 i2c_setscl(sc, 0);
188 i2c_setsda(sc, 0);
189}
190
191static void
192i2c_sendbyte(struct cambria_gpio_softc *sc, u_char data)
193{
194 int i;
195
196 for (i=7; i>=0; i--) {
197 i2c_setsda(sc, data & (1<<i));
198 i2c_setscl(sc, 1);
199 i2c_setscl(sc, 0);
200 }
201 i2c_setscl(sc, 1);
202 i2c_getsda(sc);
203 i2c_setscl(sc, 0);
204}
205
206static u_char
207i2c_readbyte(struct cambria_gpio_softc *sc)
208{
209 int i;
210 unsigned char data=0;
211
212 for (i=7; i>=0; i--)
213 {
214 i2c_setscl(sc, 1);
215 if (i2c_getsda(sc))
216 data |= (1<<i);
217 i2c_setscl(sc, 0);
218 }
219 return data;
220}
221
222static int
223cambria_gpio_read(struct cambria_gpio_softc *sc, uint32_t pin, unsigned int *val)
224{
225 device_t dev = sc->sc_dev;
226 int error;
227
228 error = iicbus_request_bus(device_get_parent(dev), dev,
229 IIC_DONTWAIT);
230 if (error)
231 return (error);
232
233 i2c_sendstart(sc);
234 i2c_sendbyte(sc, PLD_ADDR | LSB);
235 *val = (i2c_readbyte(sc) & (1 << pin)) != 0;
236 i2c_sendstop(sc);
237
238 iicbus_release_bus(device_get_parent(dev), dev);
239
240 return (0);
241}
242
243static int
244cambria_gpio_write(struct cambria_gpio_softc *sc)
245{
246 device_t dev = sc->sc_dev;
247 int error;
248
249 error = iicbus_request_bus(device_get_parent(dev), dev,
250 IIC_DONTWAIT);
251 if (error)
252 return (error);
253
254 i2c_sendstart(sc);
255 i2c_sendbyte(sc, PLD_ADDR & ~LSB);
256 i2c_sendbyte(sc, sc->sc_latch);
257 i2c_sendstop(sc);
258
259 iicbus_release_bus(device_get_parent(dev), dev);
260
261 return (0);
262}
263
264static int
265cambria_gpio_pin_max(device_t dev, int *maxpin)
266{
267
268 *maxpin = GPIO_PINS - 1;
269 return (0);
270}
271
272static int
273cambria_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
274{
275 struct cambria_gpio_softc *sc = device_get_softc(dev);
276
277 if (pin >= GPIO_PINS)
278 return (EINVAL);
279
280 *caps = sc->sc_pins[pin].gp_caps;
281 return (0);
282}
283
284static int
285cambria_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
286{
287 struct cambria_gpio_softc *sc = device_get_softc(dev);
288
289 if (pin >= GPIO_PINS)
290 return (EINVAL);
291
292 *flags = sc->sc_pins[pin].gp_flags;
293 return (0);
294}
295
296static int
297cambria_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
298{
299 struct cambria_gpio_softc *sc = device_get_softc(dev);
300
301 if (pin >= GPIO_PINS)
302 return (EINVAL);
303
304 memcpy(name, sc->sc_pins[pin].gp_name, GPIOMAXNAME);
305 return (0);
306}
307
308static int
309cambria_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
310{
311 struct cambria_gpio_softc *sc = device_get_softc(dev);
312 int error;
313 uint8_t mask;
314
315 mask = 1 << pin;
316
317 if (pin >= GPIO_PINS)
318 return (EINVAL);
319
320 /* Check for unwanted flags. */
321 if ((flags & sc->sc_pins[pin].gp_caps) != flags)
322 return (EINVAL);
323
324 /* Can't mix input/output together */
325 if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) ==
326 (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT))
327 return (EINVAL);
328
329 GPIO_LOCK(sc);
330 sc->sc_pins[pin].gp_flags = flags;
331
332 /*
333 * Writing a logical one sets the signal high and writing a logical
334 * zero sets the signal low. To configure a digital I/O signal as an
335 * input, a logical one must first be written to the data bit to
336 * three-state the associated output.
337 */
338 if (flags & GPIO_PIN_INPUT || sc->sc_val & mask)
339 sc->sc_latch |= mask; /* input or output & high */
340 else
341 sc->sc_latch &= ~mask;
342 error = cambria_gpio_write(sc);
343 GPIO_UNLOCK(sc);
344
345 return (error);
346}
347
348static int
349cambria_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
350{
351 struct cambria_gpio_softc *sc = device_get_softc(dev);
352 int error;
353 uint8_t mask;
354
355 mask = 1 << pin;
356
357 if (pin >= GPIO_PINS)
358 return (EINVAL);
359 GPIO_LOCK(sc);
360 if (value)
361 sc->sc_val |= mask;
362 else
363 sc->sc_val &= ~mask;
364
365 if (sc->sc_pins[pin].gp_flags != GPIO_PIN_OUTPUT) {
366 /* just save, altering the latch will disable input */
367 GPIO_UNLOCK(sc);
368 return (0);
369 }
370
371 if (value)
372 sc->sc_latch |= mask;
373 else
374 sc->sc_latch &= ~mask;
375 error = cambria_gpio_write(sc);
376 GPIO_UNLOCK(sc);
377
378 return (error);
379}
380
381static int
382cambria_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
383{
384 struct cambria_gpio_softc *sc = device_get_softc(dev);
385 int error = 0;
386
387 if (pin >= GPIO_PINS)
388 return (EINVAL);
389
390 GPIO_LOCK(sc);
391 if (sc->sc_pins[pin].gp_flags == GPIO_PIN_OUTPUT)
392 *val = (sc->sc_latch & (1 << pin)) ? 1 : 0;
393 else
394 error = cambria_gpio_read(sc, pin, val);
395 GPIO_UNLOCK(sc);
396
397 return (error);
398}
399
400static int
401cambria_gpio_pin_toggle(device_t dev, uint32_t pin)
402{
403 struct cambria_gpio_softc *sc = device_get_softc(dev);
404 int error = 0;
405
406 if (pin >= GPIO_PINS)
407 return (EINVAL);
408
409 GPIO_LOCK(sc);
410 sc->sc_val ^= (1 << pin);
411 if (sc->sc_pins[pin].gp_flags == GPIO_PIN_OUTPUT) {
412 sc->sc_latch ^= (1 << pin);
413 error = cambria_gpio_write(sc);
414 }
415 GPIO_UNLOCK(sc);
416
417 return (error);
418}
419
420static int
421cambria_gpio_probe(device_t dev)
422{
423
424 device_set_desc(dev, "Gateworks Cambria GPIO driver");
425 return (0);
426}
427
428static int
429cambria_gpio_attach(device_t dev)
430{
431 struct cambria_gpio_softc *sc = device_get_softc(dev);
432 int pin;
433
434 sc->sc_dev = dev;
435 sc->sc_iot = ixp425_softc->sc_iot;
436 sc->sc_gpio_ioh = ixp425_softc->sc_gpio_ioh;
437
438 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
439
440 for (pin = 0; pin < GPIO_PINS; pin++) {
441 struct cambria_gpio_pin *p = &cambria_gpio_pins[pin];
442
443 strncpy(sc->sc_pins[pin].gp_name, p->name, GPIOMAXNAME);
444 sc->sc_pins[pin].gp_pin = pin;
445 sc->sc_pins[pin].gp_caps = GPIO_PIN_INPUT|GPIO_PIN_OUTPUT;
446 sc->sc_pins[pin].gp_flags = 0;
447 cambria_gpio_pin_setflags(dev, pin, p->flags);
448 }
449
450 device_add_child(dev, "gpioc", -1);
451 device_add_child(dev, "gpiobus", -1);
452
453 return (bus_generic_attach(dev));
454}
455
456static int
457cambria_gpio_detach(device_t dev)
458{
459 struct cambria_gpio_softc *sc = device_get_softc(dev);
460
461 KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
462
463 bus_generic_detach(dev);
464
465 mtx_destroy(&sc->sc_mtx);
466
467 return(0);
468}
469
470static device_method_t cambria_gpio_methods[] = {
471 DEVMETHOD(device_probe, cambria_gpio_probe),
472 DEVMETHOD(device_attach, cambria_gpio_attach),
473 DEVMETHOD(device_detach, cambria_gpio_detach),
474
475 /* GPIO protocol */
476 DEVMETHOD(gpio_pin_max, cambria_gpio_pin_max),
477 DEVMETHOD(gpio_pin_getname, cambria_gpio_pin_getname),
478 DEVMETHOD(gpio_pin_getflags, cambria_gpio_pin_getflags),
479 DEVMETHOD(gpio_pin_getcaps, cambria_gpio_pin_getcaps),
480 DEVMETHOD(gpio_pin_setflags, cambria_gpio_pin_setflags),
481 DEVMETHOD(gpio_pin_get, cambria_gpio_pin_get),
482 DEVMETHOD(gpio_pin_set, cambria_gpio_pin_set),
483 DEVMETHOD(gpio_pin_toggle, cambria_gpio_pin_toggle),
484 {0, 0},
485};
486
487static driver_t cambria_gpio_driver = {
488 "gpio_cambria",
489 cambria_gpio_methods,
490 sizeof(struct cambria_gpio_softc),
491};
492static devclass_t cambria_gpio_devclass;
493extern devclass_t gpiobus_devclass, gpioc_devclass;
494extern driver_t gpiobus_driver, gpioc_driver;
495
496DRIVER_MODULE(gpio_cambria, iicbus, cambria_gpio_driver, cambria_gpio_devclass, 0, 0);
497DRIVER_MODULE(gpiobus, gpio_cambria, gpiobus_driver, gpiobus_devclass, 0, 0);
498DRIVER_MODULE(gpioc, gpio_cambria, gpioc_driver, gpioc_devclass, 0, 0);
499MODULE_VERSION(gpio_cambria, 1);
500MODULE_DEPEND(gpio_cambria, iicbus, 1, 1, 1);
320 GPIO_LOCK(sc);
321 sc->sc_pins[pin].gp_flags = flags;
322
323 /*
324 * Writing a logical one sets the signal high and writing a logical
325 * zero sets the signal low. To configure a digital I/O signal as an
326 * input, a logical one must first be written to the data bit to
327 * three-state the associated output.
328 */
329 if (flags & GPIO_PIN_INPUT || sc->sc_val & mask)
330 sc->sc_latch |= mask; /* input or output & high */
331 else
332 sc->sc_latch &= ~mask;
333 error = cambria_gpio_write(sc);
334 GPIO_UNLOCK(sc);
335
336 return (error);
337}
338
339static int
340cambria_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
341{
342 struct cambria_gpio_softc *sc = device_get_softc(dev);
343 int error;
344 uint8_t mask;
345
346 mask = 1 << pin;
347
348 if (pin >= GPIO_PINS)
349 return (EINVAL);
350 GPIO_LOCK(sc);
351 if (value)
352 sc->sc_val |= mask;
353 else
354 sc->sc_val &= ~mask;
355
356 if (sc->sc_pins[pin].gp_flags != GPIO_PIN_OUTPUT) {
357 /* just save, altering the latch will disable input */
358 GPIO_UNLOCK(sc);
359 return (0);
360 }
361
362 if (value)
363 sc->sc_latch |= mask;
364 else
365 sc->sc_latch &= ~mask;
366 error = cambria_gpio_write(sc);
367 GPIO_UNLOCK(sc);
368
369 return (error);
370}
371
372static int
373cambria_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
374{
375 struct cambria_gpio_softc *sc = device_get_softc(dev);
376 int error = 0;
377
378 if (pin >= GPIO_PINS)
379 return (EINVAL);
380
381 GPIO_LOCK(sc);
382 if (sc->sc_pins[pin].gp_flags == GPIO_PIN_OUTPUT)
383 *val = (sc->sc_latch & (1 << pin)) ? 1 : 0;
384 else
385 error = cambria_gpio_read(sc, pin, val);
386 GPIO_UNLOCK(sc);
387
388 return (error);
389}
390
391static int
392cambria_gpio_pin_toggle(device_t dev, uint32_t pin)
393{
394 struct cambria_gpio_softc *sc = device_get_softc(dev);
395 int error = 0;
396
397 if (pin >= GPIO_PINS)
398 return (EINVAL);
399
400 GPIO_LOCK(sc);
401 sc->sc_val ^= (1 << pin);
402 if (sc->sc_pins[pin].gp_flags == GPIO_PIN_OUTPUT) {
403 sc->sc_latch ^= (1 << pin);
404 error = cambria_gpio_write(sc);
405 }
406 GPIO_UNLOCK(sc);
407
408 return (error);
409}
410
411static int
412cambria_gpio_probe(device_t dev)
413{
414
415 device_set_desc(dev, "Gateworks Cambria GPIO driver");
416 return (0);
417}
418
419static int
420cambria_gpio_attach(device_t dev)
421{
422 struct cambria_gpio_softc *sc = device_get_softc(dev);
423 int pin;
424
425 sc->sc_dev = dev;
426 sc->sc_iot = ixp425_softc->sc_iot;
427 sc->sc_gpio_ioh = ixp425_softc->sc_gpio_ioh;
428
429 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
430
431 for (pin = 0; pin < GPIO_PINS; pin++) {
432 struct cambria_gpio_pin *p = &cambria_gpio_pins[pin];
433
434 strncpy(sc->sc_pins[pin].gp_name, p->name, GPIOMAXNAME);
435 sc->sc_pins[pin].gp_pin = pin;
436 sc->sc_pins[pin].gp_caps = GPIO_PIN_INPUT|GPIO_PIN_OUTPUT;
437 sc->sc_pins[pin].gp_flags = 0;
438 cambria_gpio_pin_setflags(dev, pin, p->flags);
439 }
440
441 device_add_child(dev, "gpioc", -1);
442 device_add_child(dev, "gpiobus", -1);
443
444 return (bus_generic_attach(dev));
445}
446
447static int
448cambria_gpio_detach(device_t dev)
449{
450 struct cambria_gpio_softc *sc = device_get_softc(dev);
451
452 KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
453
454 bus_generic_detach(dev);
455
456 mtx_destroy(&sc->sc_mtx);
457
458 return(0);
459}
460
461static device_method_t cambria_gpio_methods[] = {
462 DEVMETHOD(device_probe, cambria_gpio_probe),
463 DEVMETHOD(device_attach, cambria_gpio_attach),
464 DEVMETHOD(device_detach, cambria_gpio_detach),
465
466 /* GPIO protocol */
467 DEVMETHOD(gpio_pin_max, cambria_gpio_pin_max),
468 DEVMETHOD(gpio_pin_getname, cambria_gpio_pin_getname),
469 DEVMETHOD(gpio_pin_getflags, cambria_gpio_pin_getflags),
470 DEVMETHOD(gpio_pin_getcaps, cambria_gpio_pin_getcaps),
471 DEVMETHOD(gpio_pin_setflags, cambria_gpio_pin_setflags),
472 DEVMETHOD(gpio_pin_get, cambria_gpio_pin_get),
473 DEVMETHOD(gpio_pin_set, cambria_gpio_pin_set),
474 DEVMETHOD(gpio_pin_toggle, cambria_gpio_pin_toggle),
475 {0, 0},
476};
477
478static driver_t cambria_gpio_driver = {
479 "gpio_cambria",
480 cambria_gpio_methods,
481 sizeof(struct cambria_gpio_softc),
482};
483static devclass_t cambria_gpio_devclass;
484extern devclass_t gpiobus_devclass, gpioc_devclass;
485extern driver_t gpiobus_driver, gpioc_driver;
486
487DRIVER_MODULE(gpio_cambria, iicbus, cambria_gpio_driver, cambria_gpio_devclass, 0, 0);
488DRIVER_MODULE(gpiobus, gpio_cambria, gpiobus_driver, gpiobus_devclass, 0, 0);
489DRIVER_MODULE(gpioc, gpio_cambria, gpioc_driver, gpioc_devclass, 0, 0);
490MODULE_VERSION(gpio_cambria, 1);
491MODULE_DEPEND(gpio_cambria, iicbus, 1, 1, 1);