int iounmap(volatile void *start, size_t length) { unsigned long ofs_addr; ofs_addr = (unsigned long)start & (getpagesize()-1);
/* do some cleanup when you 're done with it */ return munmap((void*)start-ofs_addr, length+ofs_addr); }
void sysLedSet(unsigned char value) { /* For obscure HW reasons, we have to negated it and shift the value 23 bits to the left */ *ledRegister = (( unsigned long ) ~value < <23) ; out_32(ledRegister, ( unsigned long ) ~value < <23 ); }
int main (int argc, char *argv[]) { unsigned char j; printf( "%s: %s %s\n ", __FUNCTION__, __DATE__, __TIME__ ); //输出main: Feb 9 2007 18:13:55
/* HW initialisation */ ledRegister = (unsigned long *)mapDirectIoRegister(HCU3_LED_REGISTER, MAP_SIZE); //MAP_SIZE=4096UL //上面一行输出:Memory map 0xef600700 -> 0x30001000 offset 0x700 virtual 0x30001700 /* next we set the correct control mask in the GPIO_TCR */
//ledRegister[1] = 0x7ffe0000; /* Three State Control */
/* Now scroll our leds and pause a little bit between */ /*for (j=0; j < 8; j++) { sleep(1); printf( ". "); fflush(stdout); sysLedSet(1 < < j); }*/
以下是dev_gpio.c /* src/dev_gpio.c * * This file provide IO reading and writing from user space. * Pls create some device file in diretory /dev/gpiotest whose major is 220. * This driver support 0-255 devices. In user space user can read and write * IO through open and ioctl function provided by glibc. * */ #include "dev_gpio.h "
static ioport_device_t gpio_devices[256];
int __init gpio_init(void) { int i; register_chrdev(IOPORT_MAJOR, "gpiotest ", &gpio_ctl_fops); return 0; } __initcall(gpio_init); /* * Open/close code for raw IO. */ int gpio_open(struct inode *inode, struct file *filp) { int minor; minor = MINOR(inode-> i_rdev);
/* if (ioport_devices[minor].io_lock) { printk( "Device is busy\n "); return -1; }*/ *(volatile unsigned short*)(0xfff00000+0x962)&=~0x0080; *(volatile unsigned short*)(0xfff00000+0x960)|=0x0080; gpio_devices[minor]++; return 0; } //__ioremap int gpio_release(struct inode *inode, struct file *filp) { int minor; minor = MINOR(inode-> i_rdev); if (gpio_devices[minor]) gpio_devices[minor]--; *(volatile unsigned short*)(0xfff00000+0x960)&=~0x0080; *(volatile unsigned short*)(0xfff00000+0x962)|=0x0080; return 0; } /* * Deal with ioctls against the raw-device control interface, to bind * and unbind other raw devices. */ int gpio_ctl_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg) { int err = 0; int minor = MINOR(inode-> i_rdev); switch (command) { case IOWRITE: *(volatile unsigned short*)(0xfff00000+0x966)&=~0x0080; return 0; case IOCLEAR: *(volatile unsigned short*)(0xfff00000+0x966)|=0x0080; return 0; default: err = -EINVAL; } return err; }