主题 : 写了份mini6410的GPIO口驱动,求高手指导!! 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 58924
精华: 0
发帖: 5
金钱: 30 两
威望: 6 点
综合积分: 10 分
注册时间: 2011-11-16
最后登录: 2018-02-08
楼主  发表于: 2011-12-09 22:02

 写了份mini6410的GPIO口驱动,求高手指导!!

我需要用GPIO口输出信号,对此参照LED驱动,写了份驱动,调用它的GPE1、2、3口输出。但是没有反应。希望高手看完驱动能指导下,错误在哪!!!我用insmod将驱动已经加载进内核,而且在arm的/dev文件夹下看到注册的设备号。本来GPE口输出3.3V,加载驱动,应用函数调用open函数后没反应。。。

#define DEVICE_NAME "gpio"  


//define gpio_si_out
//writel((readl(S3C64XX_GPECON)& ~(0xaaa << 4))|( 0x111 << 4  ))  

static int sbc2440_ioctl(
    struct inode *inode,
    struct file *file,
    unsigned int cmd,
    unsigned long arg)
{
    switch(cmd) {
        unsigned tmp;
    case 0:
    case 1:
        tmp = readl(S3C64XX_GPEDAT);  
        tmp |= ( ((4+cmd*2)+arg)<< 1 );
        writel(tmp, S3C64XX_GPEDAT);
        //printk (DEVICE_NAME": %d %d\n", arg, cmd);
        return 0;
    default:
        return -EINVAL;
    }
}

static struct file_operations dev_fops = {
    .owner    =    THIS_MODULE,
    .ioctl    =    sbc2440_ioctl,
};

static struct miscdevice misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_NAME,  
    .fops = &dev_fops,
};

static int __init dev_init(void)
{
    int ret;

    {
        unsigned tmp;
        tmp = readl(S3C64XX_GPECON);
        tmp = (tmp & ~(0xfffU<<4))|(0x111U<<4);
        writel(tmp, S3C64XX_GPECON);
    }

    ret = misc_register(&misc);  

    printk (DEVICE_NAME"\tinitialized\n");

    return ret;
}

static void __exit dev_exit(void)
{
    misc_deregister(&misc);    
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");
疯狂的嵌入式爱好者
级别: 论坛版主
UID: 40543
精华: 1
发帖: 169
金钱: 920 两
威望: 184 点
综合积分: 358 分
注册时间: 2011-03-19
最后登录: 2013-05-10
1楼  发表于: 2011-12-10 02:49
兄弟,你没认真看linux内核的文档吧?

S3C24xx平台的GPIO.txt说明,Linux内核提供了下面几个个函数:

void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
unsigned int s3c2410_gpio_getpin(unsigned int pin);
void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);
int s3c2410_gpio_getirq(unsigned int pin);
同样的S3C64xx等平台都有,
void s3c_gpio_setpin(unsigned int pin, unsigned int to);
void s3c_gpio_cfgpin(unsigned int pin, unsigned int function);
int s3c_gpio_getirq(unsigned int pin);

现在基本能明白了吧,很多东西实际上内核已经做完了,我们没必要再直接读写寄存器的值。
如果硬是要这么做(为了时空效率除外),这跟裸跑啥区别,失去了跑linux的意义了.

下面是一个例子:
     //上拉GPIO
      s3c_gpio_setpull(S3C64XX_GPE(1), S3C_GPIO_PULL_UP);
      //设置为输出
      s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C_GPIO_OUTPUT);
      //设置低电平输出
      gpio_set_value(S3C64XX_GPE(1),0);

PS:在调用这些函数之前,添加下面的头文件。
#include <mach/regs-gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
同时,在使用一个GPIO之前,应该向系统确认该GPIO没有被占用。
int gpio_is_valid(int number);
楼主留言:
貌似找到了,我看看,呵呵
[ 此帖被lintel在2011-12-10 02:57重新编辑 ]
别人转角遇见爱,我转角遇见猫T _T .
级别: 风云使者
UID: 36096
精华: 3
发帖: 2513
金钱: 14075 两
威望: 2815 点
综合积分: 5086 分
注册时间: 2011-01-11
最后登录: 2015-11-15
2楼  发表于: 2011-12-10 05:56
路过看下
极度缺钱,求捐赠……支付宝兼邮箱:huming2207@qq.com