d)
{
enable_irq(IRQ_EINT0);
enable_irq(IRQ_EINT2);
enable_irq(IRQ_EINT11);
enable_irq(IRQ_EINT19);
}
/*
*功能: 屏蔽中断
*入口:
*/
static __inline void disable_irqs(void)
{
disable_irq(IRQ_EINT0);
disable_irq(IRQ_EINT2);
disable_irq(IRQ_EINT11);
disable_irq(IRQ_EINT19);
}
/*
*功能: 进入中断后, 扫描铵键码
*入口:
*返回: 按键码(1-16), 0xff表示错误
*/
static __inline unsigned char button_scan(int irq)
{
long lGPF, lGPG;
writel((readl(gpfcon) | 0x33) & 0xffffffcc, gpfcon); //GPF2,0 input
writel((readl(gpgcon) | (3<<22) | (3<<6)) & (~((3<<22) | (3<<6))), gpgcon); //GPG11,3 input
//不利用irq号, 直接扫描键盘
//设置G2低位, G6, E11, E13高位
writel((readl(gpgdat) | (1<<6)) & (~(1<<2)), gpgdat);
writel(readl(gpedat) | (1<<11) | (1<<13), gpedat);
//取GPF0, GPF2, GPG3, GPG11的值
lGPF = readl(gpfdat);
lGPG = readl(gpgdat);
//判断按键
if ((lGPF & (1<<0)) == 0) return 16;
else if((lGPF & (1<<2)) == 0) return 15;
else if((lGPG & (1<<3)) == 0) return 14;
else if((lGPG & (1<<11)) == 0) return 13;
//设置G6低位, G2, E11, E13高位
writel((readl(gpgdat) | (1<<2)) & (~(1<<6)), gpgdat);
lGPF = readl(gpfdat);
lGPG = readl(gpgdat);
if ((lGPF & (1<<0)) == 0) return 11;
else if((lGPF & (1<<2)) == 0) return 8;
else if((lGPG & (1<<3)) == 0) return 5;
else if((lGPG & (1<<11)) == 0) return 2;
//设置E11低位, G2, G6, E13高位
writel(readl(gpgdat) | (1<<6) | (1<<2), gpgdat);
writel((readl(gpedat) | (1<<13)) & (~(1<<11)), gpedat);
lGPF = readl(gpfdat);
lGPG = readl(gpgdat);
if ((lGPF & (1<<0)) == 0) return 10;
else if((lGPF & (1<<2)) == 0) return 7;
else if((lGPG & (1<<3)) == 0) return 4;
else if((lGPG & (1<<11)) == 0) return 1;
//设置E13低位, G2, G6, E11高位
//writel(readl(gpgdat) | (1<<6) | (1<<2), gpgdat);
writel((readl(gpedat) | (1<<11)) & (~(1<<13)), gpedat);
lGPF = readl(gpfdat);
lGPG = readl(gpgdat);
if ((lGPF & (1<<0)) == 0) return 12;
else if((lGPF & (1<<2)) == 0) return 9;
else if((lGPG & (1<<3)) == 0) return 6;
else if((lGPG & (1<<11)) == 0) return 3;
return 0xff ;
}
/*
*功能: 中断函数,
*入口: irq 中断号
*
*/
static irqreturn_t button_irq(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned char ucKey;
disable_irqs();
printk("in irq\n");
//延迟50毫秒, 屏蔽按键毛刺
__udelay(50000);
ucKey = button_scan(irq);
if ((ucKey >= 1) && (ucKey <= 16))
{
//如果缓冲区已满, 则不添加
if (((g_keyBuffer.head + 1) & (MAX_KEY_COUNT - 1)) != g_keyBuffer.tail)
{
spin_lock_irq(&buffer_lock);
g_keyBuffer.buf[g_keyBuffer.tail] = ucKey;
g_keyBuffer.jiffy[g_keyBuffer.tail] = GetTickCount();
g_keyBuffer.tail ++;
g_keyBuffer.tail &= (MAX_KEY_COUNT -1);
spin_unlock_irq(&buffer_lock);
}
}
init_gpio();
enable_irqs();
//printk("in irq! %x\n",EXTINT0);
return IRQ_HANDLED;//2.6内核返回值一般是这个宏。
}
/*
*功能: 申请中断
*入口:
*
*/
static int request_irqs()
{
int ret;
ret = request_irq(IRQ_EINT0, button_irq, SA_INTERRUPT, DEVICE_NAME, NULL);
if (ret < 0)
return ret;
ret = request_irq(IRQ_EINT2, button_irq, SA_INTERRUPT, DEVICE_NAME, NULL);
if (ret >= 0)
{
ret = request_irq(IRQ_EINT11, button_irq, SA_INTERRUPT, DEVICE_NAME, NULL);
if (ret >= 0)
{
ret = request_irq(IRQ_EINT19, button_irq, SA_INTERRUPT, DEVICE_NAME, NULL);
if (ret >= 0)
return ret;
free_irq(IRQ_EINT11, button_irq);
}
free_irq(IRQ_EINT2, button_irq);
}
free_irq(IRQ_EINT0, button_irq);
return ret;
}
/*
*功能: 释放中断
*入口:
*
*/
static __inline void free_irqs()
{
free_irq(IRQ_EINT0, NULL);//button_irq);
free_irq(IRQ_EINT2, NULL);//button_irq);
free_irq(IRQ_EINT11, NULL);//button_irq);
free_irq(IRQ_EINT19, NULL);//button_irq);
}
/*
*功能: 打开文件, 开始中断
*入口:
*
*/
static int button_open(struct inode *inode,struct file *filp)
{
int ret = no