Subject: RFC: General purpose "general purpose i/o pin" framework
To: None <tech-kern@netbsd.org>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: tech-kern
Date: 08/12/2002 21:10:36
Folks...
Soon I'm going to start work on a generic interface for manipulating
GPIO pins. I'm still trying to figure out exactly what it should have,
but let me give you an idea of what I'm thinking about so far:
* When a device (e.g. a generic GPIO facility in an
I/O processor) wishes to publish its GPIO pins to
the world, it requests one or more chunks of GPIO
"pin number" space from the GPIO framework. A mapping
is then established, e.g. "gpio pin 3 -> i80321 gpio pin 3"
or "gpio pin 5 -> sc520 gpio pin 9".
It's worth mentioning that I'm not entirely happy with
either the dynamic nature of the assignment (what if it
changes when you add a device?) nor with the fact that
the mapping might not necessarily be 1 -> 1, 2 -> 2, etc.
Although, this won't happen unless your system has more
than one device that wants to publish its GPIO pins.
There needs to be some way to mark pins as being "off limits",
as well. For example, on the i80321, if you're using I2C,
2 of the GPIO pins are unavailable, because they're used for
the I2C signals by the on-chip I2C controller.
* There will be a kernel API for manipulating the pins. I was
thinking along these lines:
struct gpio_pin {
int gpio_pin;
int gpio_value;
};
#define GPIO_DIR_IN 0
#define GPIO_DIR_OUT 1
int gpio_get_val(struct gpio_pin *pins, int npins);
int gpio_set_val(struct gpio_pin *pins, int npins);
int gpio_toggle_val(struct gpio_pin *pins, int npins);
int gpio_get_dir(struct gpio_pin *pins, int npins);
int gpio_set_dir(struct gpio_pin *pins, int npins);
* There will also be some kind of API for saying "interrupt
when this GPIO input pin does something" (configurable
for level or edge), but I haven't really thought too much
about how to handle that yet. In particular, what IPL
do folks think GPIO pins should be registered at? Should
they get a new IPL_GPIO (and splgpio())?
* There'll also be a userland API, which takes two forms:
- An ioctl-based API that looks a lot like the
kernel API.
- A /dev/gpioN, where N == pin number, which is meant
for easy frobbing by scripts. The idea is to do:
echo '1' > /dev/gpio0 # turn pin on
echo '0' > /dev/gpio0 # turn pin off
echo 't' > /dev/gpio0 # toggle pin
Similarly, reading will return a '1' or '0', indicating
the current state.
This would allow e.g. easy frobbing of an LED on
an embedded system, setting an error LED if booting
failed, etc.
This idea from Jasper Wallace.
I haven't entirely settled on how the interrupt-driven event
notification might work for userland. Maybe I just punt on
that.
Anyone have any (useful :-) input they could provide on this? (Chris? :-)
--
-- Jason R. Thorpe <thorpej@wasabisystems.com>