s3c2410平台下linux四键按键驱动程序

#ifndef __KERNEL__

#define __KERNEL__

#endif

#ifndef MODULE

#define MODULE

#endif

#include<linux/config.h>

#include<linux/module.h>

#include<linux/version.h>

#include<linux/init.h>

#include<linux/kernel.h>

#include<linux/errno.h>

#include<linux/sched.h>//声明中断

#include<linux/fs.h>//声明file文件

#include<asm/system.h>/*cli(),*_flages*/

#include<linux/poll.h>

#include<linux/types.h>

#include<linux/slab.h>

#include <asm/arch/S3C2410.h>

#include <asm/hardware.h>//devf

//-------------------------------

#include <asm/io.h>/* ioremap */

#include <linux/delay.h>

#include <asm/delay.h>

//--------------------------------

#include <asm-arm/arch-s3c2410/smdk.h>

#include <linux/ioport.h>

#include <asm/irq.h>

#include <asm/mach/irq.h>

//define the interrupt No.

#define interrupt_k4   IRQ_EINT0

#define interrupt_k3   IRQ_EINT2

#define interrupt_k2   IRQ_EINT11

#define interrupt_k1   IRQ_EINT19

/*

struct IRQ_STRUCT

{

unsigned int irq_no;

void (*irq_fun)();

};

static IRQ_STRUCT irq_struct[4];

*/

//定义键盘的主设备号define the major of keypad

#define KEYPAD_MAJOR 59

#ifndef MOD_INC_USE_COUNT

#define MOD_INC_USE_COUNT

#endif

#ifndef MOD_DEC_USE_COUNT

#define MOD_DEC_USE_COUNT

#endif

#define COMMAND1 1

#define KBD_GETKEY 1

static int keyvalue;

#define DEVICE_NAME "keypad"

//setup the GPIO F ports register

#define key_rGPFCON (*(volatile unsigned long *) key_r_GPFCON)

#define key_rGPFUP (*(volatile unsigned long *) key_r_GPFUP)

#define key_rGPFDAT (*(volatile unsigned long *) key_r_GPFDAT)

//setup the GPIO G ports register

#define key_rGPGCON (*(volatile unsigned long *) key_r_GPGCON)

#define key_rGPGUP (*(volatile unsigned long *) key_r_GPGUP)

#define key_rGPGDAT (*(volatile unsigned long *) key_r_GPGDAT)

unsigned long *key_r_GPFCON, *key_r_GPFDAT, *key_r_GPFUP;

unsigned long *key_r_GPGCON, *key_r_GPGDAT, *key_r_GPGUP;

static int __init keypad_init(void);

static void __exit keypad_cleanup(void);

static void key1_irq(int irq,void *dev_id,struct pt_regs *regs);

static void key2_irq(int irq,void *dev_id,struct pt_regs *regs);

static void key3_irq(int irq,void *dev_id,struct pt_regs *regs);

static void key4_irq(int irq,void *dev_id,struct pt_regs *regs);

static int keypad_getkey(void);

static int keypad_open(struct inode *inode,struct file *file);

static int keypad_close(struct inode *inode,struct file *file);

static int keypad_ioctl(struct inode *inode ,struct file* file,unsigned int cmd,unsigned long arg);

void keypad_setup(void);

/********************************************************************/

static devfs_handle_t   devfs_handle;

static struct file_operations keypad_fops=

{

owner:THIS_MODULE,

llseek:NULL,

read: NULL,

write: NULL,

ioctl: keypad_ioctl,

open:   keypad_open,

release: keypad_close,  

};

/********************************************************************/

void keypad_setup(void)

{

keyvalue = 0;

}

static int keypad_open(struct inode * inode,struct file *file)

{

printk(KERN_CRIT"DEMO:Keypad Device Open /n");

MOD_INC_USE_COUNT;

return 0;

}

static int keypad_close(struct inode * inode,struct file *file)

{

printk(KERN_CRIT"DEMO:Keypad device close/n");

MOD_DEC_USE_COUNT;

return 0;

}

static int keypad_ioctl(struct inode *inode ,struct file* file,unsigned int cmd,unsigned long arg)

{

int value=0;

switch(cmd)

   {//接受一个按键

   case KBD_GETKEY:

    value = keypad_getkey();

    if(value!=0)

     keyvalue=0;

    return value;

 

   }

}

static void key1_irq(int irq,void *dev_id,struct pt_regs *regs)

{

//屏蔽键盘中断

disable_irq(irq);

printk("Key1 Interrupt ok/n");

   keyvalue=1;  

   enable_irq(irq);

}

static void key2_irq(int irq,void *dev_id,struct pt_regs *regs)

{

//屏蔽键盘中断

disable_irq(irq);

printk("Key2 Interrupt ok/n");

    keyvalue=2;

    enable_irq(irq);

}

static void key3_irq(int irq,void *dev_id,struct pt_regs *regs)

{

//屏蔽键盘中断

disable_irq(irq);

printk("Key3 Interrupt ok/n");

    keyvalue=3;

    enable_irq(irq);

}

static void key4_irq(int irq,void *dev_id,struct pt_regs *regs)

{

//屏蔽键盘中断

disable_irq(irq);

printk("Key4 Interrupt ok/n");

    keyvalue=4;

    enable_irq(irq);

}

static int keypad_getkey()

{

   //如果有键按下,则反回键值

         if (keyvalue)

         {

          return keyvalue;

         }

         //printk("Waiting......./n");

         //无键按下,返回0

         return 0;

   }

static int __init keypad_init(void)

{

int result;

//int i;

//setup the F_PORT register

key_r_GPFCON =ioremap(0x56000050,4);

key_r_GPFDAT =ioremap(0x56000054,4);

key_r_GPFUP =ioremap(0x56000058,4);

key_rGPFUP =0xff;

key_rGPFCON = 0xffee;

//setup the G_PORT register

key_r_GPGCON = ioremap(0x56000060,4);

key_r_GPGDAT = ioremap(0x56000064,4);

key_r_GPGUP = ioremap(0x56000068,4);

key_rGPGUP = 0xffff;

key_rGPFCON = 0xffbfffbf;

/*

irq_struct[0].irq_no=interrupt_k1;

irq_struct[0].irq_fun=key1_irq;

irq_struct[1].irq_no=interrupt_k2;

irq_struct[1].irq_fun=key2_irq;

irq_struct[2].irq_no=interrupt_k3;

irq_struct[2].irq_fun=key3_irq;

irq_struct[3].irq_no=interrupt_k4;

irq_struct[3].irq_fun=key4_irq;

*/

devfs_handle = devfs_register(NULL,DEVICE_NAME, DEVFS_FL_DEFAULT,KEYPAD_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR,&keypad_fops, NULL);

result = register_chrdev(KEYPAD_MAJOR,DEVICE_NAME,&keypad_fops);

if(result<0)

{

   printk(KERN_INFO "[FAILED:Cannot register keypad Device!]/n");

   return -EIO;

}

else

   printk("Initializing Keypad Device/t---->/t/n");

keypad_setup();

//register the external interrupt

//for(i=0;i<4;i++)

//{

   set_external_irq(interrupt_k1, EXT_FALLING_EDGE, GPIO_PULLUP_EN);

   result=request_irq(interrupt_k1,&key1_irq,SA_INTERRUPT,DEVICE_NAME,&key1_irq);

   if (result<0)

   {

     printk(KERN_INFO"[FAILED:Cannot registe key1 interrupt!]/n");

     return result;

    }

   else

    printk("[key 1 has been registed!]/n");

   set_external_irq(interrupt_k2, EXT_FALLING_EDGE, GPIO_PULLUP_EN);

   result=request_irq(interrupt_k2,&key2_irq,SA_INTERRUPT,DEVICE_NAME,&key2_irq);

   if (result<0)

   {

     printk(KERN_INFO"[FAILED:Cannot registe key2 interrupt!]/n");

     return result;

    }

   else

    printk("[key 2 has been registed!]/n");

   set_external_irq(interrupt_k3, EXT_FALLING_EDGE, GPIO_PULLUP_EN);

   result=request_irq(interrupt_k3,&key3_irq,SA_INTERRUPT,DEVICE_NAME,&key3_irq);

   if (result<0)

   {

     printk(KERN_INFO"[FAILED:Cannot registe key3 interrupt!]/n");

     return result;

    }

   else

    printk("[key 3 has been registed!]/n");

   set_external_irq(interrupt_k4, EXT_FALLING_EDGE, GPIO_PULLUP_EN);

   result=request_irq(interrupt_k4,&key4_irq,SA_INTERRUPT,DEVICE_NAME,&key4_irq);

   if (result<0)

   {

     printk(KERN_INFO"[FAILED:Cannot registe key4 interrupt!]/n");

     return result;

    }

   else

    printk("[key 4 has been registed!]/n");

//}

printk("Keypad Driver has been installed!/n");

return 0;

}

static void __exit keypad_cleanup(void)

{

//int i;

//for(i=0;i<4;i++)

devfs_unregister(devfs_handle);

unregister_chrdev(KEYPAD_MAJOR,DEVICE_NAME);

free_irq(interrupt_k1,key1_irq);

free_irq(interrupt_k2,key2_irq);

free_irq(interrupt_k3,key3_irq);

free_irq(interrupt_k4,key4_irq);

    printk("DEMO:Keypad device is cleanup/n");

return ;

}

/********************************************************************/

#ifdef MODULE

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Zhu jacky<jianqi.zhu@gmail.com >");

MODULE_DESCRIPTION("Keypad Device");

#endif

module_init(keypad_init);

module_exit(keypad_cleanup);

/*

linux在io.h头文件中声明了函数ioremap(),用来将I/O内存资源的物理地址映射到核心虚地址空间(3GB-4GB)中,如下:

void * ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);

void iounmap(void * addr);函数用于取消ioremap()所做的映射,参数addr是指向核心虚地址的指针。

这两个函数都是实现在mm/ioremap.c文件中。

*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值