天嵌 ARM开发社区

 找回密码
 注册
查看: 2062|回复: 2

求助!哪位大哥帮忙看下我这个按键驱动吧…

[复制链接]
vanbreaker 发表于 2012-2-17 14:37:22 | 显示全部楼层 |阅读模式
本帖最后由 vanbreaker 于 2012-2-17 14:42 编辑

看了TQ得例程,有点疑问,例程在驱动里好像没有配置那4个按键口的模式,也没有配置中端的触发方式呀,就是GPFCON和EINT0这2个寄存器,难道都不用配置么?我自己写了一个,但是好像不行,没有配置这2个寄存器的话,4个按键中端刚注册就会各触发一次,但是后面按键就进不去了!加了配置的话就从头到尾都不会触发了。。不过我不知道访问EINT0这个寄存器可不可以用ioremap..还没看内存这部分。。找了半天了还是没找到问题。。前面那些字符设备注册部分应该没问题,都是以前的模板。。麻烦写过按键驱动的兄台帮小弟看看吧,给点意见……!感谢!
#include<linux/module.h>
#include<linux/init.h>
#include<linux/types.h>
#include<linux/fs.h>
#include<linux/mm.h>
#include<linux/cdev.h>
#include<linux/slab.h>
#include<linux/irq.h>
#include<linux/interrupt.h>
#include<linux/platform_device.h>
#include<mach/regs-gpio.h>
#include<mach/hardware.h>
#include<asm/irq.h>
#include<asm/system.h>
#include<asm/io.h>
#include<asm/uaccess.h>



#define KEY_MAJOR 245

#define GPFCON_CFG_VAL ( (2<<0) | (2<<2) | (2<<4) | (2<<8) )

#define EINT0_CFG_VAL  ( (2<<0) | (2<<4) | (2<<8) | (2<<16) )

volatile unsigned int *GPFCON = NULL;
volatile unsigned int *EINT0  = NULL;

static unsigned long key_major = KEY_MAJOR;


struct key_info
{
        int irq_num;
        int pin;
        char* name;
        int key_num;
};

struct key_dev
{
        struct cdev cdev;
        struct key_info key[4];
};

struct key_info key_init_info[4]=
{
        {IRQ_EINT1,S3C2410_GPF1,"key1_irq",1},
        {IRQ_EINT4,S3C2410_GPF4,"key2_irq",2},
        {IRQ_EINT2,S3C2410_GPF2,"key3_irq",3},
        {IRQ_EINT0,S3C2410_GPF0,"key4_irq",4}
};


struct key_dev *key_devp;

int press_num = 0;
int press_flag = 0;


irqreturn_t key_interrupt_handler(int irq,void *dev_id)
{
        int ret;
        struct key_info *key = (struct key_info*)dev_id;
        ret = s3c2410_gpio_getpin(key->pin);
        printk(KERN_NOTICE "Trig,%d\n",ret);
        if(ret == 0)
        {
                printk(KERN_NOTICE "key %d press\n",key->key_num);
                press_flag = 1;
        }
        return IRQ_RETVAL(IRQ_HANDLED);
}

static void load_keyinfo(void)
{
        int i;
        
        for(i=0;i<4;i++)
        {
                key_devp->key = key_init_info;
        }
}

static int key_open(struct inode *inode,struct file *filp)
{

        int i;
        int ret;
        
        for(i=0;i<4;i++)
        {
                 ret = request_irq(key_devp->key.irq_num,
                                  key_interrupt_handler,
                                    IRQF_TRIGGER_FALLING,  
                                  key_devp->key.name,
                                  (void*)&key_devp->key);
                if(ret != 0)
                {
                        printk(KERN_NOTICE "key %d irq register error!\n",i+1);
                }        
        }        

        return 0;

}



static int key_release(struct inode *inode, struct file *filp)
{
        int i;

        for(i=0;i<4;i++)
        {
                free_irq(key_devp->key.irq_num,
                        (void*)&key_devp->key);
        }

        return 0;        
}



static ssize_t key_read(struct file *filp, char __user *buf,
                        size_t size, loff_t *ppos)
{
        return 0;
}




static const struct file_operations key_fops =
{
        .owner = THIS_MODULE,
        .read = key_read,
        .open = key_open,
        .release = key_release,
};




static void key_setup_cdev(struct key_dev *dev, int index)
{
        int err,devno = MKDEV(key_major,index);
        cdev_init(&dev->cdev,&key_fops);
        dev->cdev.owner = THIS_MODULE;
        err = cdev_add(&dev->cdev,devno,1);

        if(err)
        {
                printk(KERN_NOTICE "Error %d adding %d\n",err,index);
        }
}




static int key_irq_init(void)
{
        int result;

        dev_t devno = MKDEV(key_major,0);

        if(key_major)
                result = register_chrdev_region(devno,1,"key");
        else
        {
                result = alloc_chrdev_region(&devno,0,1,"key");
                key_major = MAJOR(devno);
        }

        if(result<0)
        {
                printk("register failed!");
                return result;
        }

        
        /*涓鸿?澶囨弿杩扮粨鏋勫垎閰嶅唴瀛?/
        key_devp =(struct key_dev*)kmalloc(sizeof(struct key_dev),GFP_KERNEL);
        
        if(!key_devp)
        {
                result = -ENOMEM;
                unregister_chrdev_region(devno,1);
        }
        memset(key_devp, 0 ,sizeof(struct key_dev));

        key_setup_cdev(key_devp,0);

        GPFCON = (volatile unsigned int*)ioremap(0x56000050,16);
        *GPFCON = GPFCON_CFG_VAL;
        EINT0 = (volatile unsigned int *)ioremap(0x56000088,32);
        *EINT0 = EINT0_CFG_VAL; // falling trigger
        load_keyinfo();

        return 0;
}



static void key_irq_exit(void)
{
        cdev_del(&key_devp->cdev);
        kfree(key_devp);
        unregister_chrdev_region(MKDEV(key_major,0),1);
}



MODULE_LICENSE("GPL");


module_init(key_irq_init);
module_exit(key_irq_exit);

只写了最基本的部分,只是测试一下能不能正常触发中断和读按键,在测试程序里就是直接调用open打开设备文件,可以正常打开,我就不贴了...
 楼主| vanbreaker 发表于 2012-2-17 16:52:38 | 显示全部楼层
现在按键可以触发了!我在应用程序里open后加了一个while(1)的死循环就行了。。是不是应用程序结束了OPEN也就没用了?不过我还是想知道为什么不用配置引脚和触发方式也可以触发中断。。
亚瑟王 发表于 2012-2-27 13:53:47 | 显示全部楼层
亲,在天嵌科技的中断按键的驱动中的open函数里面,调用了request_irq函数,他完成了你说的那些功能。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号-2 )

GMT+8, 2024-9-29 05:31 , Processed in 1.033137 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表