Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 Nov 2009 06:57:36 +0200
From:      Oleksandr Tymoshenko <gonzo@freebsd.org>
To:        arch@freebsd.org
Cc:        embedded@frebsd.org
Subject:   [RFC] GPIO framework
Message-ID:  <20091126045736.GA25431@bluezbox.com>

next in thread | raw e-mail | index | archive | help
Recently I've been working on GPIO framework that, I believe, 
is much needed for embedded applications of FreeBSD. Now framework
is  mature enough to show it to the world, so this is my request 
for review.

Patch: http://people.freebsd.org/~gonzo/mips/gpio.diff
sys/gpio.h is based on the same file from NetBSD but all the other 
files have been written from the scratch.

Description:

GPIO stands for General Purpose Input/Output. This interface may be
thought of as a set of pins which could serve as input or output 
having logical 0 and logical 1 as their values (some other options
are applicable, but they're not crucial for this explanation).
Most common usage of GPIO interface is LED and button control for
various SoCs.

Architecture:

I tried to separate hardware implementation from logic as much as
possible. All the HW-independent stuff resides in sys/dev/gpio 
directory. It consists of gpioc (GPIO controller device), 
gpiobus (bus that manages devices attached to GPIO controller)
and gpioled (implementation of LED driver that illustrates usage
pattern of gpiobus, utilizes led(4) interface).

HW-dependent part might be a part of SoC, I2C extender, whatever.
It should implement interface defined in sys/dev/gpio/gpio_if.m:
  gpio_pin_max           - get maximum pin available
  gpio_pin_getcaps       - get capabilities for given pin
  gpio_pin_getflags      - get flags for given pin
  gpio_pin_setflags      - set flags for given pin
  gpio_pin_getname       - get pin name (if any)
  gpio_pin_set           - set pin value
  gpio_pin_get           - get pin value
  gpio_pin_toggle        - toggle(invert) pin value
And on attaching HW driver should add gpioc and gpiobus as its
children.

gpioc creates /dev/gpiocX entry that is used by gpioctl application 
for managing GPIO pins using following ioctls:
  GPIOMAXPIN            - get maximum pin available
  GPIOGETCONFIG         - get flags/capabilities/name for given pin
  GPIOSETCONFIG         - set flags for given pin
  GPIOGET               - get pin value
  GPIOSET               - set pin value
  GPIOTOGGLE            - toggle(invert) pin value
gpioctl usage:
  gpioctl -f ctldev -l [-v]
  gpioctl -f ctldev -t pin
  gpioctl -f ctldev -c pin flag ...
  gpioctl -f ctldev pin [0|1]

gpiobus manages devices attached to gpio controller. Its interface
is a subset of of gpio_if.m interface and allows child devices talk
to GPIO controller. At the moment children could be set only by hints
file and pin space is limited to 32. Example:

# RF led
hint.gpioled.0.at="gpiobus0"
hint.gpioled.0.name="rf"
# pin 2
hint.gpioled.0.pins=0x0004

Interface functions:
  gpiobus_pin_getcaps    - get capabilities for given pin
  gpiobus_pin_getflags   - get flags for given pin
  gpiobus_pin_setflags   - set flags for given pin
  gpiobus_pin_set        - set pin value
  gpiobus_pin_get        - get pin value
  gpiobus_pin_toggle     - toggle(invert) pin value

Reference implementation of child device is sys/dev/gpio/gpioled.c
It provides on/off function for led(4) API

Any comments/feedback are welcome

-- 
gonzo



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20091126045736.GA25431>