Home Gumstix GPIO

Gumstix GPIO

How to use GPIO with Gumstix Overo.

 

Kernel GPIO

Here is a small project that demonstrates some gpio access within a kernel module - overo-irqlat.

The motivation for the project was to measure the latency in the gpio sub-system of a Linux OMAP3 kernel.

There are two tests in the code.

  1. Test how long it takes to toggle gpio pins. For this the code runs a tight loop setting a pin high then low.

  2. Test how long to get into the irq handler for an interrupt enabled gpio pin after the pin has been changed.

Both tests require an oscilloscope to monitor the timings, but you can just look at the code to get an example of how to use gpio in your own module. If you have an oscope, you might want to go ahead and do the measurements yourself. The README for the project explains where to measure.

Another good place to look for gpio code is in the Overo board file arch/arm/mach-omap2/board-overo.c

 

Userland GPIO

You can control GPIO pins from userspace like so

root@overo# echo 146 > /sys/class/gpio/export
root@overo:/sys/class/gpio# cat gpio146/direction
in
root@overo# echo out > /sys/class/gpio/gpio146/direction
root@overo:/sys/class/gpio# cat gpio146/direction
out
root@overo# cat /sys/class/gpio/gpio146/value
0
root@overo# echo 1 > /sys/class/gpio/gpio146/value
root@overo# cat /sys/class/gpio/gpio146/value
1

If you have an expansion card with a 40 pin header, then this will be controlling pin 27. You can use pin 1 for a ground. Schematics and pin-outs for the Gumstix expansion boards can be found here.

 

Now for some details.

 

See the kernel docs gpio.txt for an overview of gpio and the userspace sysfs interface. The "Sysfs Interface for Userspace (OPTIONAL)" section near the end discusses the userspace implementation.

See the OMAP35X Technical Reference Manual Section 7.6.3 PADCONFS Register Description and Table 7.5 Core Control Module PadConf Register Field in Section 7.4.4.3 Pad Multiplexing Register Fields for identifying the possible MUX configuration for each GPIO.

Then see the U-Boot source code, board/overo/overo.h for how the pins on the Overo are actually being muxed. See include/asm-arm/arch-omap3/mux.h in the U-Boot tree for the definitions used in overo.h. The pins in mux mode M4 are already configured for GPIO.

 

Currently most of the GPIO multiplexing for the Overo's is being done by the bootloader U-Boot, so the conventional way to modify the pin muxing is to edit board/overo/overo.h in the U-Boot source and rebuild it. I have some instructions for that here - Gumstix U-Boot development.

 

You can also change the pin mux configuration from within Linux. One simple approach is to do it from userspace accessing /dev/mem. A program devmem2 is part of the omap3-console-image and will work. See the examples below.

If you are writing your own kernel module, you can also read/write the PADCONF registers the way you normally would after an ioremap.

 

Third, there is a mux framework in the kernel now that gives you some additional utility functions to change the pin muxing during initialization. There are some examples in the latest overo board file arch/arm/mach-omap2/ board-overo.c. Search for omap_mux_init_signal(). I believe you can only use this framework during initialization so it wouldn't work for an external loadable module. I'm not sure about this and need to check.

 

Just because pins are configured as GPIO in u-boot, doesn't necessarily mean you can use them. If you look at /sys/class/gpio on a default Overo, you'll get something like this.

root@overo:~# ls /sys/class/gpio
export gpio164 gpio65 gpiochip160 gpiochip64
gpio15 gpio168 gpiochip0 gpiochip192 gpiochip96
gpio16 gpio176 gpiochip128 gpiochip32 unexport

The reason you see some GPIO already exported is because the linux code in arch/arm/mach-omap2/board-overo.c is explicitly exporting these pins for another use. Whether the pins are required depends on the expansion board you are using. The kernel also uses pins configured as GPIO that it doesn't export. These depend on the kernel drivers included which is specified in the kernel configuration.

To be more explicit, look inside board-overo.c, you'll see these definitions

#define OVERO_GPIO_BT_XGATE     15
#define OVERO_GPIO_W2W_NRESET   16
#define OVERO_GPIO_PENDOWN      114
#define OVERO_GPIO_BT_NRESET    164
#define OVERO_GPIO_USBH_CPEN    168
#define OVERO_GPIO_USBH_NRESET  183
...
#define OVERO_SMSC911X_GPIO    176
#define OVERO_SMSC911X2_GPIO   65
...
#define OVERO_GPIO_LCD_EN 144
#define OVERO_GPIO_LCD_BL 145

Follow their usage inside the file and you will be able to explain the /sys/class/gpio output you see above.

 

Any of the pins may have been configured as input-only or output-only when they were mux'd or when they were explicitly exported by the kernel. In those cases you won't be able to change the direction from userspace.

Remember, the logic is 1.8v.

 

Here's a few GPIO on the expansion header you can use immediately from userspace without any u-boot or kernel changes.

Pin 4 - gpio114
It's the pendown signal on the touchscreen controller but it's available if you aren't using a touchscreen.
Configured as input only when exported by the kernel in board-overo.h. Can't change the direction from userspace without modifying kernel.
Pulled-low, reads 0 with no input, reads 1 with an input applied

Pin 19 - gpio170
The HDQ/1-Wire output. Not used unless you explicitly enable the 1-wire module.
User exportable
Output only - configured this way in the u-boot muxing

Pin 27 - gpio146
Pin 29 - gpio147
User exportable
Direction can be changed
Floating state

Pin 28 - gpio145
Pin 30 - gpio144
Used with LCD, but available if not using an LCD
Configured as output only when exported by the kernel in board-overo.h. Can't change direction from userspace without modifying kernel.
Set to ON by kernel during init (not all configs, see board-overo.c). This could be a problem for real use, but okay for testing. I always patch the board-overo.c file to stop the pins from being toggled on boot when I am using them for gpio.

 

There are some addition GPIO exposed on the Gumstix LCD capable expansion boards.

 

For kernels prior to 2.6.36 or if you disable the 'leds-gpio' or 'gpio-keys' platform drivers in your kernel, you can use these pins in the following fashion.

LED D2 - gpio21
LED D3 - gpio22
Userspace exportable, set the direction as out
echo 0 > gpioxx/value to turn on, echo 1 > gpioxx/value to turn off

Switch - gpio14
Switch - gpio23
Userspace exportable, leave direction as in
With the switch open (not pushed) will register a value of 1
Push the switch and the value will be 0

 

For kernels 2.6.36 and greater, there are additional drivers controlling the LED and button pins. Instructions for their use can be found here Button and LED control on Gumstix LCD boards.

 

If you aren't using SPI bus 1, then are 5 SPI pins on the 40-pin expansion header that you could re-purpose for GPIO. The SPI bus is used by the touchscreen controller, but if you aren't using a touchscreen then these pins are available.

Pin 3 - gpio171(spi1_clk)
Pin 5 - gpio172 (spi1_mosi)
Pin 6 - gpio174 (spi1_cs0)
Pin 7 - gpio173 (spi1_miso)
Pin 8 - gpio175 (spi1_cs1)

The first step is to find the appropriate PADCONF register address for each gpio from Table 7.5 of the TRM. Pay attention to whether it is the low or high order 16 bits for each gpio. You should find these values.

gpio171 : 0x4800 21C8
gpio172 : 0x4800 21CA
gpio173 : 0x4800 21CC
gpio174 : 0x4800 21CE
gpio175 : 0x4800 21D0

Using devmem2, here is how you could read the current PADCONF value for what could be gpio171

root@overo# devmem2 0x480021c8 h
...
Value at address 0x480021C8 (0x400201c8): 0x100

Which corresponds to a mux value of (IEN | PTD | DIS | M0) using the U-Boot mux.h definitions. Mux mode 0 for this pin is the spi1_clk configuration found by looking in Table 7.5 of the TRM.

To reconfigure pin 3 to be gpio171, as input or output with inputs pulled low, write 0x010C to the controlling PADCONF register. This would correspond to (IEN | PTD | EN | M4). The bit fields are defined in the TRM Section 7.6.3.

root@overo# devmem2 0x480021c8 h 0x10c

Now you can export and configure this gpio171 from userspace like the example with gpio146 at the beginning.

If you want this multiplexing to be permanent, then you would modify the U-Boot file board/overo/overo.h and rebuild U-Boot. If you are using OE, then you'll want to generate a patch file to be used in the u-boot-omap3 recipe. Instructions for doing that are here.

 

More Links

The Beagleboard guide to OMAP3 pin muxing - BeagleBoardPinMux

I wrote a small kernel module to probe the PADCONF registers of a running system. It's just for debugging but it will show you the pin mux state of any gpio pin you pass it. The project is here on github - omap3-mux.