Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 Nov 2009 07:07:02 +0100
From:      Milan Obuch <freebsd-arch@dino.sk>
To:        freebsd-arch@freebsd.org
Cc:        Oleksandr Tymoshenko <gonzo@freebsd.org>
Subject:   Re: [RFC] GPIO framework
Message-ID:  <200911260707.03168.freebsd-arch@dino.sk>
In-Reply-To: <20091126045736.GA25431@bluezbox.com>
References:  <20091126045736.GA25431@bluezbox.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thursday 26 November 2009 05:57:36 Oleksandr Tymoshenko wrote:
> 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.
>

I was working some time ago on something similar, but did not have enough time 
to make it able to show to public, then lost it in some disk crash or some 
such. Nevertheless, my work was based on some older gio work, probably for 
4-something, available on the web somewhere (I have no URL now at hand), and 
OpenBSD implementation. They differed in one area - one implementation used 
bit array for pins' internal structure, the other some linked list structure, 
what makes it easy to build a non-contiguous pin array. I am not sure which 
one was used in my implementation then... I try to find it - somewhere on my 
disks or CFs.

Anyway, I will try to look at your work in next amount of my free time and 
comment on the code side, if I will have anything, but now, some general 
comments on your mail. I have some WRAP boards, where some GPIOs are used to 
drive three status LEDs and attach a soft reset button, add-on board with LPC 
SuperIO chip with some tens of GPIOs and some other SuperIOs where I can test 
things, x86 based.

Also there are some PRs open for NSLU2 (ARM SoC based), where some GPIOs are 
used for LEDs and button(s), too. You might consider them too, if you did not 
already. I can test something for NSLU2, too, but I did not manage to master 
it completely yet.

And, one more general note, I found GPIOs are used internally in many various 
add-on cards, like atheros based wireless adapters (ath driver), various TV 
grabber cards - mostly for i2c setting of tuner parameters etc. Usefullness 
of covering these with general GPIO framework should be considered, though.

> 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).
>

I was able to build and think it is still usefull to add gpioi2c. It worked 
for me well as a bit banged replacement for geode's access.bus controller, 
which I was unable to use directly, but that's another story. I think it is 
usefull addition.

> 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.
>

Did you think about ability to use interrupt abilities of GPIO? In my work I 
added a hook to call a script via devd for pins selected (a special flag or 
something). This way it is easy to execute a script on a button press.

> 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

It's all for now, but I hope I showed I am definitely interested in such a 
framework being incorporated in FreeBSD. When time permits, I will work a bit 
on it, too.

Regards,
Milan



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