//初始化重复按键定时器
init_timer(&repeat_timer);
repeat_timer.function = repeat_timer_handler;
/*if(requestIrq() !=0)
return -1;*/
enableIrq();
MOD_INC_USE_COUNT;
return 0;
}
static struct file_operations kb_fops = {
owner: THIS_MODULE,
open: S3C2440_kb_open,
read: S3C2440_kb_read,
release: s3c2440_kb_release,
};
/*----------------------------------------------------
* func: 中断处理程序,关闭中断开启键盘扫描定时器
* param:
*
*
* return:
*
------------------------------------------------------*/
static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
spin_lock_irq(&kbdev.lock);
//禁止所有中断
disable_irq(IRQ_EINT1);
disable_irq(IRQ_EINT3);
disable_irq(IRQ_EINT8);
kbdev.irq = irq;
//printk("irq=%d\n",kbdev.irq);
//启动定时器
kb_timer.expires = jiffies + KB_TIMER_DELAY;
add_timer(&kb_timer);
repeat_timer.expires = jiffies + REPEAT_START_DELAY;
add_timer(&repeat_timer);
spin_unlock_irq(&kbdev.lock);
}
/*----------------------------------------------------
* func: 初始化eint中断相关寄存器,安装中断处理程序
* param:
*
*
* return:
*
------------------------------------------------------*/
static int requestIrq()
{
int ret;
/* Enable interrupt */
//==================================================
// irq: Linux中断号,与硬件中断号不同
// handle: 中断处理程序
// flag: SA_INTERRUPT指示这是个快速中断处理程序
// dev_id: 用于共享的中断信号线,通常设置成NULL
//===================================================
ret = set_external_irq(IRQ_EINT1,EXT_FALLING_EDGE,GPIO_PULLUP_DIS);
if(ret)
goto eint_failed ;
ret = request_irq(IRQ_EINT1, keyboard_interrupt, SA_INTERRUPT,
DEVICE_NAME, NULL);
if(ret)
goto eint1_failed;
if(ret)
goto eint_failed;
ret = request_irq(IRQ_EINT8, keyboard_interrupt, SA_INTERRUPT,
DEVICE_NAME, NULL);
if(ret)
goto eint8_failed;
ret = set_external_irq(IRQ_EINT3,EXT_FALLING_EDGE,GPIO_PULLUP_DIS);
if(ret)
goto eint_failed;
ret = request_irq(IRQ_EINT3, keyboard_interrupt, SA_INTERRUPT,
DEVICE_NAME, NULL);
if(ret)
goto eint3_failed;
return 0;
eint3_failed:
free_irq(IRQ_EINT3, keyboard_interrupt);
eint8_failed:
free_irq(IRQ_EINT8, keyboard_interrupt);
eint1_failed:
free_irq(IRQ_EINT1, keyboard_interrupt);
eint_failed:
printk(DEVICE_NAME ": IRQ Requeset Error\n");
return ret;
}
static int s3c2440_kb_release(struct inode *inode, struct file *filp)
{
/*注销设备*/
// unregister_chrdev(kbMajor, DEVICE_NAME);
/*释放中断*/
/*
free_irq(IRQ_EINT1,NULL);
free_irq(IRQ_EINT8,NULL);
free_irq(IRQ_EINT3,NULL);
MOD_DEC_USE_COUNT;
*/
return 0;
}
/*----------------------------------------------------
* func: 初始化键盘驱动,注册字符设备
* param:
*
*
* return:
>=0 : 初始化键盘驱动成功
<0: 失败
*
------------------------------------------------------*/
static int __init s3c2440_kb_init(void)
{
int ret;
/*初始化管腿配置*/
init_gpjcon();
output_giop(0);
/*注册设备*/
ret = register_chrdev(99, DEVICE_NAME, &kb_fops);
if(ret < 0) {
printk(DEVICE_NAME " can't get major number\n");
return ret;
}
kbMajor = ret;
printk("%s