Re: IBM OCP GPIO driver for linux 2.6
From: Dale Farnsworth <hidden>
Date: 2006-08-03 13:53:00
In article <1154603751.17247.10.camel@jb-portable> you write:
I'm porting a custom PPC 405GP card based on a Walnut from Montavista Linux 3.0 (kernel 2.4.18) to linux 2.6, and I was wondering if there is a port of the IBM OCP GPIO driver (a char driver providing device /dev/gpio, major 10 minor 185). The driver was written by Armin Kuster, and it doesn't exist in the stock kernel 2.6.17.7. Let me known if a port exists, or if there is a new way of accessing the PPC 405GP GPIO under linux 2.6.
The recommended way of accessing GPIO registers is to mmap them
and manipulate them directly in user space.
Below, I've included a quick hack that blinks a LED on a Walnut-like
board.
-Dale
#include <stdint.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#define GPIO_PAGE_ADDR 0xef600000
#define OUTPUT_REG 0x0700
#define TRISTATE_REG 0x0704
#define OPENDRAIN_REG 0x0718
#define INPUT_REG 0x071c
#define MEDIA_LED_BIT 0x20000000
#define reg_addr(p, o) ((uint32_t *)((void *)p + o))
int main(int argc, char *argv[])
{
int i;
uint32_t *p;
char *filename = "/dev/mem";
void *addr = 0;
size_t length = 4096;
int prot = PROT_READ | PROT_WRITE;
int flags = MAP_SHARED;
int fd = open(filename, O_RDWR);
off_t offset = (off_t)GPIO_PAGE_ADDR;
if (fd < 0) {
perror("open");
return 1;
}
p = mmap(addr, length, prot, flags, fd, offset);
if (p == MAP_FAILED) {
perror("mmap");
return 4;
}
/* drive led output */
*reg_addr(p, TRISTATE_REG) |= MEDIA_LED_BIT;
/* blink media led 10 times */
for (i = 0; i < 10; i++) {
/* turn media led on */
*reg_addr(p, OUTPUT_REG) &= ~MEDIA_LED_BIT;
sleep(1);
/* turn media led off */
*reg_addr(p, OUTPUT_REG) |= MEDIA_LED_BIT;
sleep(1);
}
return 0;
}