📄 键盘驱动程序.c
字号:
#include<linux/module.h>
#include<linux/init.h>
#include<linux/config.h>
#include<linux/kernel.h>
#include<linux/fs.h>
#include<linux/interrupt.h>
#include<linux/wait.h>
#include<linux/cdev.h>
#include<linux/sched.h>
#include<linux/devfs_fs_kernel.h>
#include<asm/hardware.h>
#include<asm/delay.h>
#include<asm/uaccess.h>
#include<asm/io.h>
#include<asm/arch-s3c2410/regs-gpio.h>
#include<asm/arch-s3c2410/irqs.h>
#define KEY_NUM 4
#define DEVICE_NAME "key"
#define KEY_MAJOR 0
#define KEY_MINOR 0
#define MAX_KEY_BUF 16
#define KEY_IRQ1 IRQ_EINT0
#define KEY_IRQ2 IRQ_EINT2
#define KEY_IRQ3 IRQ_EINT11
#define KEY_IRQ4 IRQ_EINT19
#define KEY_STATUS_1 0
#define KEY_STATUS_2 2
#define KEY_STATUS_3 11
#define KEY_STATUS_4 19
define KEY_STATUS_DOWNX 0
#define KEY_STATUS_DOWN 1
#define KEY_STATUS_UP 2
#define KEY_TIMER_DELAY1 HZ/100 //100ms
#define KEY_TIMER_DELAY2 HZ/5 //200ms
#define KEY_TIMER_DELAY3 HZ //1000ms
//unsigned long rINTPND;
void __iomem * rINTPND;
void __iomem * rINTMASK;
void __iomem * rEINPEND;
void __iomem * rEINPMASK;
void __iomem * rSRCPND;
void __iomem * rEXTINT0;
void __iomem * rEXTINT1;
void __iomem * rEXTINT2;
void __iomem * rGPFDATA;
void __iomem * rGPGDATA;
void __iomem * rGPFCON;
void __iomem * rGPGCON;
#define INT_IRQ1 1<<0
#define INT_IRQ2 1<<2
#define INT_IRQ11 1<<11
#define INT_IRQ19 1<<19
#define INT_IRQ8_23 1<<5
static int key_major=KEY_MAJOR;
static int flag=0;
typedef struct {
unsigned int keyStatus[KEY_NUM];
unsigned char buf[MAX_KEY_BUF];
unsigned int head,tail;
wait_queue_head_t wq;
struct cdev k_dev;
} key_dev;
static struct timer_list key_timer[KEY_NUM];
static key_dev * k_dev;
static struct key_info
{
int irq_no;
unsigned int gpio_port;
unsigned int gpio_function;
int key_no;
} key_info_tab[KEY_NUM]=
{
{ KEY_IRQ1,S3C2410_GPF0,S3C2410_GPF0_EINT0 ,0 }
,
{ KEY_IRQ2,S3C2410_GPF2,S3C2410_GPF2_EINT2,1 }
,
{ KEY_IRQ3,S3C2410_GPG3,S3C2410_GPG3_EINT11,2 }
,
{ KEY_IRQ4,S3C2410_GPG11,S3C2410_GPG11_EINT19 ,3 }
};
static unsigned char key_read(void)
{
unsigned char ret;
ret=k_dev->buf[k_dev->tail];
k_dev->tail++;
k_dev->tail=(k_dev->tail)%(MAX_KEY_BUF);
return ret;
}
static void key_write(unsigned char key)
{
k_dev->buf[k_dev->head]=key;
k_dev->head++;
k_dev->head=(k_dev->head)%(MAX_KEY_BUF);
}
static void key_event(int key)
{
unsigned char key_no='0';
printk("key_event key =%d !\n",key);
if(key==0)
key_no='a';
else if(key==1)
key_no='b';
else if(key==2)
key_no='c';
else if(key==3)
key_no='d';
key_write(key_no);
key_num=key;
flag=1;
wake_up_interruptible(&(k_dev->wq));
}
static void clear_pending(unsigned int value)
{
writel(value,rSRCPND);
writel(value,rINTPND);
}
static void clear_sub_pending(unsigned int value)
{
writel(value,rEINPEND);
//writel(value,rINTPND);
}
static void clear_interrupt(int key)
{
unsigned int value;
value=ioread32(rINTPND);
if(value==INT_IRQ1)
{
clear_pending(INT_IRQ1);
}
else if(value==INT_IRQ2)
{
clear_pending(INT_IRQ1);
}
else if(value==INT_IRQ8_23)
{
clear_pending(INT_IRQ8_23);
value=ioread32(rEINPEND);
if(value==INT_IRQ11)
{
clear_sub_pending(INT_IRQ11);
}
else if(value==INT_IRQ19)
{
clear_sub_pending(INT_IRQ19);
}
}
}
static int Is_key_down(int key)
{
int ret;
int value;
value=s3c2410_gpio_getpin(key_info_tab[key].gpio_port);
if(value==0)
ret=1;
else
ret=0;
return ret;
}
static void key_timer_handle(unsigned long arg)
{
int key=(int)arg;
if(Is_key_down(key))
{
if(k_dev->keyStatus[key]==KEY_STATUS_DOWNX)
{
k_dev->keyStatus[key]=KEY_STATUS_DOWN;
key_timer[key].expires=jiffies+KEY_TIMER_DELAY3;
key_event(key);
add_timer(&key_timer[key]);
}
else
{
key_timer[key].expires=jiffies+KEY_TIMER_DELAY2;
add_timer(&key_timer[key]);
}
}
else
{
printk("key %d up!\n",key);
k_dev->keyStatus[key]=KEY_STATUS_UP;
enable_irq(key_info_tab[key].irq_no);
}
}
static irqreturn_t s3c2410_key_ISR(int irq,void *dev_id,struct pt_regs *regs)
{
int value;
int key;
struct key_info * k;
k=(struct key_info *)dev_id;
key=k->key_no;
if(key<0 || key>3 )
{
printk("Error irq no!\n");
return -1;
}
disable_irq(key_info_tab[key].irq_no); //绂佹
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -