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>