1 /* $Id: at91pio.c,v 1.2 2008/07/03 01:15:38 matt Exp $ */
5 * Copyright (c) 2007 Embedtronics Oy. All rights reserved.
7 * Based on arch/arm/ep93xx/epgpio.c,
8 * Copyright (c) 2005 HAMAJIMA Katsuomi. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD$");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/device.h>
39 #include <machine/bus.h>
40 #include <machine/intr.h>
41 #include <dev/gpio/gpiovar.h>
42 #include <arm/at91/at91var.h>
43 #include <arm/at91/at91reg.h>
44 #include <arm/at91/at91pioreg.h>
45 #include <arm/at91/at91piovar.h>
53 int at91pio_debug
= AT91PIO_DEBUG
;
54 #define DPRINTFN(n,x) if (at91pio_debug>(n)) printf x;
59 #define AT91PIO_NMAXPORTS 4
60 #define AT91PIO_NPINS 32
63 int (*ireq_func
)(void *);
68 #define PIO_READ(_sc, _reg) bus_space_read_4((_sc)->sc_iot, (_sc)->sc_ioh, (_reg))
69 #define PIO_WRITE(_sc, _reg, _val) bus_space_write_4((_sc)->sc_iot, (_sc)->sc_ioh, (_reg), (_val))
71 struct at91pio_softc
{
73 bus_space_tag_t sc_iot
;
74 bus_space_handle_t sc_ioh
;
77 struct gpio_chipset_tag gpio_chipset
;
78 gpio_pin_t pins
[AT91PIO_NPINS
];
82 struct intr_req ireq
[AT91PIO_NPINS
];
85 static int at91pio_match(device_t
, cfdata_t
, void *);
86 static void at91pio_attach(device_t
, device_t
, void *);
89 static int at91piobus_print(void *, const char *);
90 static int at91pio_pin_read(void *, int);
91 static void at91pio_pin_write(void *, int, int);
92 static void at91pio_pin_ctl(void *, int, int);
95 static int at91pio_search(device_t
, cfdata_t
, const int *, void *);
96 static int at91pio_print(void *, const char *);
98 static int at91pio_intr(void* arg
);
100 CFATTACH_DECL(at91pio
, sizeof(struct at91pio_softc
),
101 at91pio_match
, at91pio_attach
, NULL
, NULL
);
103 static struct at91pio_softc
*at91pio_softc
[AT91_PIO_COUNT
];
105 struct at91pio_softc
*at91pio_sc(at91pio_port port
)
107 if (port
< AT91_PIO_COUNT
)
108 return at91pio_softc
[port
];
114 at91pio_match(device_t parent
, cfdata_t match
, void *aux
)
116 if (strcmp(match
->cf_name
, "at91pio") == 0)
122 at91pio_attach(device_t parent
, device_t self
, void *aux
)
124 struct at91pio_softc
*sc
= (struct at91pio_softc
*)self
;
125 struct at91bus_attach_args
*sa
= aux
;
127 struct gpiobus_attach_args gba
;
128 uint32_t psr
, osr
, pin
;
132 sc
->sc_iot
= sa
->sa_iot
;
133 sc
->sc_pid
= sa
->sa_pid
;
135 if (bus_space_map(sa
->sa_iot
, sa
->sa_addr
,
136 sa
->sa_size
, 0, &sc
->sc_ioh
)){
137 printf("%s: Cannot map registers", self
->dv_xname
);
141 /* save descriptor: */
142 at91pio_port p
= at91_pio_port(sa
->sa_pid
);
143 if (p
< AT91_PIO_COUNT
&& !at91pio_softc
[p
])
144 at91pio_softc
[p
] = sc
;
146 /* make sure peripheral is enabled: */
147 at91_peripheral_clock(sc
->sc_pid
, 1);
149 /* initialize ports (disable interrupts) */
150 PIO_WRITE(sc
, PIO_IDR
, -1);
153 /* initialize and attach gpio(4) */
154 psr
= PIO_READ(sc
, PIO_PSR
); // only ports
155 osr
= PIO_READ(sc
, PIO_OSR
);
156 pin
= PIO_READ(sc
, PIO_PDSR
);
157 psr
&= ~at91_gpio_mask(sc
->sc_pid
);
158 for (j
= n
= 0; j
< AT91PIO_NPINS
; j
++) {
159 sc
->pins
[n
].pin_num
= j
;
161 sc
->pins
[n
].pin_caps
= (GPIO_PIN_INPUT
163 | GPIO_PIN_OPENDRAIN
// @@@ not all pins
167 sc
->pins
[n
].pin_caps
= 0;
170 sc
->pins
[n
].pin_flags
= GPIO_PIN_OUTPUT
;
172 sc
->pins
[n
].pin_flags
= GPIO_PIN_INPUT
;
174 sc
->pins
[n
].pin_state
= GPIO_PIN_HIGH
;
176 sc
->pins
[n
].pin_state
= GPIO_PIN_LOW
;
179 sc
->gpio_chipset
.gp_cookie
= sc
;
180 sc
->gpio_chipset
.gp_pin_read
= at91pio_pin_read
;
181 sc
->gpio_chipset
.gp_pin_write
= at91pio_pin_write
;
182 sc
->gpio_chipset
.gp_pin_ctl
= at91pio_pin_ctl
;
183 gba
.gba_gc
= &sc
->gpio_chipset
;
184 gba
.gba_pins
= sc
->pins
;
186 config_found_ia(self
, "gpiobus", &gba
, at91piobus_print
);
190 config_search_ia(at91pio_search
, self
, "at91pio", at91pio_print
);
195 at91piobus_print(void *aux
, const char *name
)
197 struct gpiobus_attach_args
*gba
= aux
;
198 struct at91pio_softc
*sc
= (struct at91pio_softc
*)gba
->gba_gc
->gp_cookie
;
200 gpiobus_print(aux
, name
);
201 aprint_normal(": port %s (mask %08"PRIX32
")",
202 at91_peripheral_name(sc
->sc_pid
),
203 at91_gpio_mask(sc
->sc_pid
));
211 at91pio_search(device_t parent
, cfdata_t cf
,
212 const int *ldesc
, void *aux
)
214 struct at91pio_softc
*sc
= (struct at91pio_softc
*)parent
;
215 struct at91pio_attach_args paa
;
218 paa
.paa_iot
= sc
->sc_iot
;
219 paa
.paa_pid
= cf
->cf_loc
[AT91PIOCF_PID
];
220 paa
.paa_bit
= cf
->cf_loc
[AT91PIOCF_BIT
];
222 if (config_match(parent
, cf
, &paa
) > 0)
223 config_attach(parent
, cf
, &paa
, at91pio_print
);
229 at91pio_print(void *aux
, const char *name
)
231 struct at91pio_attach_args
*paa
= (struct at91pio_attach_args
*)aux
;
232 // struct at91pio_softc *sc = (struct at91pio_softc*)paa->paa_sc;
235 if (paa
->paa_pid
> -1)
236 aprint_normal(" port %s", at91_peripheral_name(paa
->paa_pid
));
237 if (paa
->paa_bit
> -1)
238 aprint_normal(" bit %d", paa
->paa_bit
);
244 at91pio_read(struct at91pio_softc
*sc
, int bit
)
247 sc
->pins
[bit
].pin_caps
= 0;
249 return (PIO_READ(sc
, PIO_PDSR
) >> bit
) & 1;
253 at91pio_set(struct at91pio_softc
*sc
, int bit
)
256 sc
->pins
[bit
].pin_caps
= 0;
258 PIO_WRITE(sc
, PIO_SODR
, (1U << bit
));
262 at91pio_clear(struct at91pio_softc
*sc
, int bit
)
265 sc
->pins
[bit
].pin_caps
= 0;
267 PIO_WRITE(sc
, PIO_CODR
, (1U << bit
));
271 at91pio_in(struct at91pio_softc
*sc
, int bit
)
274 sc
->pins
[bit
].pin_caps
= 0;
276 PIO_WRITE(sc
, PIO_ODR
, (1U << bit
));
280 at91pio_out(struct at91pio_softc
*sc
, int bit
)
283 sc
->pins
[bit
].pin_caps
= 0;
285 PIO_WRITE(sc
, PIO_OER
, (1U << bit
));
288 void at91pio_per(struct at91pio_softc
*sc
, int bit
, int perab
)
291 sc
->pins
[bit
].pin_caps
= 0;
295 PIO_WRITE(sc
, PIO_PER
, (1U << bit
));
298 PIO_WRITE(sc
, PIO_ASR
, (1U << bit
));
299 PIO_WRITE(sc
, PIO_PDR
, (1U << bit
));
302 PIO_WRITE(sc
, PIO_BSR
, (1U << bit
));
303 PIO_WRITE(sc
, PIO_PDR
, (1U << bit
));
306 panic("%s: perab is invalid: %i", __FUNCTION__
, perab
);
312 at91pio_intr_establish(struct at91pio_softc
*sc
, int bit
,
313 int ipl
, int (*ireq_func
)(void *), void *arg
)
315 struct intr_req
*ireq
;
317 DPRINTFN(1, ("at91pio_intr_establish: port=%s, bit=%d\n", at91_peripheral_name(sc
->sc_pid
), bit
));
319 if (bit
< 0 || bit
>= AT91PIO_NPINS
)
322 ireq
= &sc
->ireq
[bit
];
324 if (ireq
->ireq_func
) /* already used */
327 ireq
->ireq_func
= ireq_func
;
328 ireq
->ireq_arg
= arg
;
329 ireq
->ireq_ipl
= ipl
;
331 PIO_WRITE(sc
, PIO_IDR
, (1U << bit
)); /* disable interrupt for now */
332 at91pio_in(sc
, bit
); /* make sure pin is input */
334 sc
->pins
[bit
].pin_caps
= 0;
337 if (flag
& EDGE_TRIGGER
)
338 at91pio_bit_set(sc
, sc
->xinttype1
, bit
);
339 else /* LEVEL_SENSE */
340 at91pio_bit_clear(sc
, sc
->xinttype1
, bit
);
341 if (flag
& RISING_EDGE
) /* or HIGH_LEVEL */
342 at91pio_bit_set(sc
, sc
->xinttype2
, bit
);
343 else /* FALLING_EDGE or LOW_LEVEL */
344 at91pio_bit_clear(sc
, sc
->xinttype2
, bit
);
346 PIO_WRITE(sc
, PIO_IFER
, (1U << bit
));
348 PIO_WRITE(sc
, PIO_IFDR
, (1U << bit
));
352 // use IPL_BIO because we want lowest possible priority as
353 // we really don't know what priority is going to be used by
354 // the caller.. this is not really optimal but tell me a
356 sc
->ih
= at91_intr_establish(sc
->sc_pid
, IPL_BIO
, INTR_HIGH_LEVEL
,
360 //(void)PIO_READ(sc, PIO_ISR); // clear interrupts
361 PIO_WRITE(sc
, PIO_IER
, (1U << bit
)); // enable interrupt
367 at91pio_intr_disestablish(struct at91pio_softc
*sc
, int bit
, void *cookie
)
369 struct intr_req
*ireq
;
372 DPRINTFN(1, ("at91pio_intr_disestablish: port=%s, bit=%d\n", at91_peripheral_name(sc
->sc_pid
), bit
));
374 if (bit
< 0 || bit
>= AT91PIO_NPINS
)
377 if (cookie
!= sc
->ih
)
380 ireq
= &sc
->ireq
[bit
];
382 if (!ireq
->ireq_func
)
385 PIO_WRITE(sc
, PIO_IDR
, (1U << bit
));
389 for (i
= 0; i
< AT91PIO_NPINS
; i
++) {
390 if (sc
->ireq
[i
].ireq_func
)
394 if (i
>= AT91PIO_NPINS
) {
395 at91_intr_disestablish(sc
->ih
);
401 at91pio_intr(void *arg
)
403 struct at91pio_softc
*sc
= arg
;
407 isr
= (PIO_READ(sc
, PIO_ISR
) & PIO_READ(sc
, PIO_IMR
));
416 panic("%s: isr is zero (0x%X)", __FUNCTION__
, isr
);
418 if (sc
->ireq
[bit
].ireq_func
) {
419 int s
= _splraise(sc
->ireq
[bit
].ireq_ipl
);
420 (*sc
->ireq
[bit
].ireq_func
)(sc
->ireq
[bit
].ireq_arg
);
431 at91pio_pin_read(void *arg
, int pin
)
433 struct at91pio_softc
*sc
= arg
;
435 pin
%= AT91PIO_NPINS
;
436 if (!sc
->pins
[pin
].pin_caps
)
437 return 0; /* EBUSY? */
439 return (PIO_READ(sc
, PIO_PDSR
) >> pin
) & 1;
443 at91pio_pin_write(void *arg
, int pin
, int val
)
445 struct at91pio_softc
*sc
= arg
;
447 pin
%= AT91PIO_NPINS
;
448 if (!sc
->pins
[pin
].pin_caps
)
452 PIO_WRITE(sc
, PIO_SODR
, (1U << pin
));
454 PIO_WRITE(sc
, PIO_CODR
, (1U << pin
));
458 at91pio_pin_ctl(void *arg
, int pin
, int flags
)
460 struct at91pio_softc
*sc
= arg
;
462 pin
%= AT91PIO_NPINS
;
463 if (!sc
->pins
[pin
].pin_caps
)
466 if (flags
& GPIO_PIN_INPUT
)
467 PIO_WRITE(sc
, PIO_ODR
, (1U << pin
));
468 else if (flags
& GPIO_PIN_OUTPUT
)
469 PIO_WRITE(sc
, PIO_OER
, (1U << pin
));
471 if (flags
& GPIO_PIN_OPENDRAIN
)
472 PIO_WRITE(sc
, PIO_MDER
, (1U << pin
));
473 else if (flags
& GPIO_PIN_PUSHPULL
)
474 PIO_WRITE(sc
, PIO_MDDR
, (1U << pin
));
476 if (flags
& GPIO_PIN_PULLUP
)
477 PIO_WRITE(sc
, PIO_PUER
, (1U << pin
));
479 PIO_WRITE(sc
, PIO_PUDR
, (1U << pin
));