#ifndef __kernel__
#define __kernel__
#endif
#ifndef module
#define module
#endif#include
#include
#include
#include
#include
#include
#include//声明中断
#include//声明file文件
#include/*cli(),*_flages*/
#include
#include
#include
#include
#include //devf
//-------------------------------
#include /* ioremap */
#include
#include
//--------------------------------
#include
#include
#include
#include
//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 c