- 论坛徽章:
- 0
|
GPIO Drivers
贴上一个s3c24402440的GPIO驱动源代码。可以实现对几个IO口的读写操作。写操作中,可以使用已经移植好的API接口函数如s3c2410_gpio_cfgpin等,可是读取函数使用s3c2410_gpio_getpin却不能正确读回IO的状态。后来改用了直接读取寄存器的方式,解决了这个问题。
/* gpio.c EPC's gpio driver. GUANGZHOU ZHIYUAN
Copyright (c) 2006 GUANGZHOU ZHIYUAN ELECTRONICS CO.LTD By Chenxibing */
#include #include #include #include #include #include #include #include #include #include #include
#include
#include #include #include #include #include #include
#include
#include "gpiodrv.h"
#define DEV_NAME "gpio01"
static struct semaphore gpio01_sem;
static unsigned int GPIO01[4] = {S3C2410_GPG8, S3C2410_GPG9, S3C2410_GPG10, S3C2410_GPG11};static unsigned int GPIO01_OUTP[4]= {S3C2410_GPG8_OUTP, S3C2410_GPG9_OUTP, \ S3C2410_GPG10_OUTP, S3C2410_GPG11_OUTP};static unsigned int GPIO01_INP[4] = {S3C2410_GPG8_INP, S3C2410_GPG9_INP, \ S3C2410_GPG10_INP, S3C2410_GPG11_INP};
static int tp_gpio01_open(struct inode *inode, struct file *filp){ try_module_get(THIS_MODULE); printk( KERN_INFO DEV_NAME " opened!\n"); return 0;}
static int tp_gpio01_release(struct inode *inode, struct file *filp){ module_put(THIS_MODULE); printk(KERN_INFO DEV_NAME " released!\n"); return 0;}
static ssize_t tp_gpio01_read(struct file *filp, const char __user *buff, size_t count, loff_t *ppos){ unsigned char status=0; unsigned int temp, i;
void __iomem *base = S3C24XX_GPIO_BASE(S3C2410_GPG8); //unsigned long offs = S3C2410_GPIO_OFFSET(pin);
if (count > 1) { return -EFBIG; }
if (down_interruptible(&gpio01_sem)) return -ERESTARTSYS;
#if 1//NOT OK for(i=0; i s3c2410_gpio_cfgpin(GPIO01, GPIO01_INP); s3c2410_gpio_pullup(GPIO01, 0); //enable pullup// status |= (s3c2410_gpio_getpin(GPIO01) mdelay(10); }#endif
status = (__raw_readl(base + 0x04)&0x0F00)>>8;
printk("read data status = 0x%0x\n", status); put_user(status, (u8 *)buff);
up(&gpio01_sem); return count;}
static ssize_t tp_gpio01_write(struct file *filp, const char __user *buff, size_t count, loff_t *ppos){ int i; unsigned char ctrl=0; unsigned int set, clear; if (count > 1) { return -EFBIG; } if (down_interruptible(&gpio01_sem)) return -ERESTARTSYS;
get_user(ctrl, (u8 *)buff); printk("write date ctrl=0x%0x\n", ctrl);
for(i=0; i s3c2410_gpio_cfgpin(GPIO01, GPIO01_OUTP); s3c2410_gpio_pullup(GPIO01, 0); //enable pullup s3c2410_gpio_setpin(GPIO01, ((ctrl)>>i)&0x01); // printk("write %d %d\n", i, (((ctrl)>>i)&0x01)); mdelay(10); }
up(&gpio01_sem); return count;}
static int tp_gpio01_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ int level;
if (_IOC_TYPE(cmd) != GPIO_IOC_MAGIC) { return -ENOTTY; }
if (_IOC_NR(cmd) >= GPIO_IOC_MAXNR) { return -ENOTTY; }
if (arg > 7) { return -ENODEV; }// printk("arg=0x%x\n", arg);
switch (cmd) { case GPIO_RESET_ALL: case GPIO_CLEAR_ALL: //tp_gpio01_reset(); break;
case GPIO_SET_PIN_LOW:// GPCR(GPO[arg]) = GPIO_bit(GPO[arg]); break; case GPIO_SET_PIN_HIGH:// GPSR(GPO[arg]) = GPIO_bit(GPO[arg]); break;
default: //tp_gpio01_reset(); break; }
return 0;}
static struct file_operations tp_gpio01_fops = { .owner = THIS_MODULE, .read = tp_gpio01_read, .write = tp_gpio01_write, .ioctl = tp_gpio01_ioctl, .open = tp_gpio01_open, .release = tp_gpio01_release,};
static struct miscdevice tp_gpio01_miscdev ={ .minor = MISC_DYNAMIC_MINOR, .name = DEV_NAME, .fops = &tp_gpio01_fops,};
static int tp_gpio01_probe(struct device *dev){ int ret;
printk(KERN_INFO DEV_NAME " probing...\n"); ret = misc_register(&tp_gpio01_miscdev); if (ret) printk(KERN_ERR "Failed to register miscdev.\n");
return ret;}
static int tp_gpio01_remove(struct device *dev){ misc_deregister(&tp_gpio01_miscdev); printk(KERN_INFO DEV_NAME " removed!\n"); return 0;}
struct platform_device *tp_gpio01_device;static struct device_driver tp_gpio01_driver = { .name = DEV_NAME, .owner = THIS_MODULE, .bus = &platform_bus_type, .probe = tp_gpio01_probe, .remove = tp_gpio01_remove,};
static int __init tp_gpio01_init(void){ int rc = 0; int i;
printk(KERN_INFO DEV_NAME " init...\n");
for(i=0; i s3c2410_gpio_cfgpin(GPIO01, GPIO01_OUTP); s3c2410_gpio_pullup(GPIO01, 0); //enable pullup s3c2410_gpio_setpin(GPIO01, 1); //default all HIGH }
tp_gpio01_device = platform_device_register_simple(DEV_NAME, -1, NULL, 0); if(IS_ERR(tp_gpio01_device)) { goto out; } rc = driver_register(&tp_gpio01_driver); if (rc platform_device_unregister(tp_gpio01_device); }
sema_init(&gpio01_sem, 1);out: return rc; }
static void __exit tp_gpio01_exit(void){ printk(KERN_INFO DEV_NAME " init...\n"); driver_unregister(&tp_gpio01_driver); platform_device_unregister(tp_gpio01_device); printk(KERN_INFO "tp_gpio01 exit!\n");}
module_init(tp_gpio01_init);module_exit(tp_gpio01_exit);
MODULE_AUTHOR("Abing ");MODULE_DESCRIPTION("ZHIYUAN epc-gpio Driver");MODULE_LICENSE("GPL");
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/51797/showart_2070546.html |
|