⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 button.c

📁 《linux驱动程序设计从入门到精通》一书中所有的程序代码含驱动和相应的应用程序
💻 C
字号:
/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2007, 2010 fengGuojin(fgjnew@163.com)
 */
#include <linux/module.h>#include <linux/init.h>#include <linux/input.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/arch-s3c2410/irqs.h>#include <asm/signal.h>#include <asm/hardware.h>#include <asm/uaccess.h>#include <asm/arch/regs-gpio.h>#include <asm/arch/regs-irq.h>#include <asm/dma.h>MODULE_AUTHOR("FGJ");MODULE_DESCRIPTION("buttons driver");MODULE_LICENSE("GPL");#define DEBUG_DRIVER 1static unsigned char simplekey_keycode[0x08] = {	[0]	 = KEY_1,	[1]	 = KEY_2,	[2]	 = KEY_3,	[3]	 = KEY_4,	[4]	 = KEY_5,	[5]	 = KEY_6,	[6]	 = KEY_7,	[7]	 = KEY_8,};static int irqArray[4]={	IRQ_EINT0,	IRQ_EINT2,	IRQ_EINT11,	IRQ_EINT19};static struct input_dev simplekey_dev;static char *simplekey_name = "simplekey";static char *simplekey_phys = "input0";struct timer_list polling_timer;static unsigned long  polling_jffs=0;void polling_handler(unsigned long data){        int code=-1;	writel(readl(S3C2410_SRCPND)&0xffffffda,S3C2410_SRCPND);//clear srcpnd 0 2 11 19	mdelay(1);	//扫描按键表,根据中断号,找出所按下的按键。	writel(readl(S3C2410_GPBDAT)|0x80,S3C2410_GPBDAT);//set GPB76 to 10        writel(readl(S3C2410_GPBDAT)&0xffffffBf,S3C2410_GPBDAT);//...	if((readl(S3C2410_GPFDAT)&(1<< 0)) == 0 )	{	    code=0;	    goto IRQ_OUT;	}	else if( (readl(S3C2410_GPFDAT)&(1<< 2)) == 0 )	{	    code=2;	    goto IRQ_OUT;	}	else if( (readl(S3C2410_GPGDAT)&(1<< 3)) ==0 )	{	    code=4;	    goto IRQ_OUT;	}	else if( (readl(S3C2410_GPGDAT)&(1<<11)) == 0 )	{	    code=6;	    goto IRQ_OUT;	}	writel(readl(S3C2410_SRCPND)&0xffffffda,S3C2410_SRCPND);//clear srcpnd 0 2 11 19	mdelay(1);	writel(readl(S3C2410_GPBDAT)|0x40,S3C2410_GPBDAT);//set GPB76 to 01	writel(readl(S3C2410_GPBDAT)&0xffffff7f,S3C2410_GPBDAT);//...        if((readl(S3C2410_GPFDAT)&(1<< 0)) == 0 )	{	    code=1;	    goto IRQ_OUT;	}	else if( (readl(S3C2410_GPFDAT)&(1<< 2)) == 0 )	{	    code=3;	    goto IRQ_OUT;	}	else if( (readl(S3C2410_GPGDAT)&(1<< 3)) ==0 )	{	    code=5;	    goto IRQ_OUT;	}	else if( (readl(S3C2410_GPGDAT)&(1<<11)) == 0 )	{	    code=7;	    goto IRQ_OUT;	}IRQ_OUT:	enable_irq(IRQ_EINT0);	enable_irq(IRQ_EINT2);	enable_irq(IRQ_EINT11);	enable_irq(IRQ_EINT19);	if(code>=0)	{		//避免中断连续出现		if((jiffies-polling_jffs)>100)		{			polling_jffs=jiffies;			input_report_key(&simplekey_dev, simplekey_keycode[code], 1);			input_report_key(&simplekey_dev, simplekey_keycode[code], 0);			input_sync(&simplekey_dev);#if DEBUG_DRIVER			printk("key %d\n",code) ;#endif		}	}	writel(readl(S3C2410_GPBDAT)&0xffffff3f,S3C2410_GPBDAT);}static irqreturn_t simplekey_interrupt(int irq, void *dummy, struct pt_regs *fp){	disable_irq(IRQ_EINT0);	disable_irq(IRQ_EINT2);	disable_irq(IRQ_EINT11);	disable_irq(IRQ_EINT19);	polling_timer.expires = jiffies + HZ/5;	add_timer(&polling_timer);	return IRQ_HANDLED;}void initButton(void){	writel((readl(S3C2410_GPGCON)&(~((3<<22)|(3<<6))))|((2<<22)|(2<<6)),S3C2410_GPGCON);		//GPG11,3 set EINT	writel((readl(S3C2410_GPFCON)&(~((3<<4)|(3<<0))))|((2<<4)|(2<<0)),S3C2410_GPFCON) ;		//GPF2,0 set EINT	writel((readl(S3C2410_EXTINT0)&(~(7|(7<<8)))),S3C2410_EXTINT0);	writel((readl(S3C2410_EXTINT0)|(0|(0<<8))),S3C2410_EXTINT0);	//set eint0,2 falling edge int	writel((readl(S3C2410_EXTINT1)&(~(7<<12))),S3C2410_EXTINT1);	writel((readl(S3C2410_EXTINT1)|(0<<12)),S3C2410_EXTINT1);	//set eint11 falling edge int	writel((readl(S3C2410_EXTINT2)&(~(0xf<<12))),S3C2410_EXTINT2);	writel((readl(S3C2410_EXTINT2)|(0<<12)),S3C2410_EXTINT2);	//set eint19 falling edge int	writel((readl(S3C2410_GPBCON)&(~((3<<12)|(3<<14)))),S3C2410_GPBCON);	writel((readl(S3C2410_GPBCON)|(((1<<12)|(1<<14)))),S3C2410_GPBCON);	writel((readl(S3C2410_GPBUP)|(3<<6)),S3C2410_GPBUP);	writel((readl(S3C2410_GPBDAT)&(~(3<<6))),S3C2410_GPBDAT);	writel((readl(S3C2410_EINTPEND)|((1<<11)|(1<<19))),S3C2410_EINTPEND);		//clear eint 11,19	writel((readl(S3C2410_EINTMASK)&(~((1<<11)|(1<<19)))),S3C2410_EINTMASK);	//enable eint11,19*/}static int __init simplekey_init(void){	int i;		initButton();	polling_jffs=jiffies;	for (i = 0; i <4; i++) {		if (request_irq(irqArray[i], &simplekey_interrupt, SA_INTERRUPT, "simplekey", NULL)) {			printk("request button irq failed!\n");			return -1;		}			}	init_input_dev(&simplekey_dev);	simplekey_dev.evbit[0] = BIT(EV_KEY);// | BIT(EV_REP);	simplekey_dev.keycode = simplekey_keycode;	simplekey_dev.keycodesize = sizeof(unsigned char);	simplekey_dev.keycodemax = ARRAY_SIZE(simplekey_keycode);	//下面的语句必不可少	for (i = 0; i < 0x78; i++)		if (simplekey_keycode[i])			set_bit(simplekey_keycode[i], simplekey_dev.keybit);	simplekey_dev.name = simplekey_name;	simplekey_dev.phys = simplekey_phys;	simplekey_dev.id.bustype = BUS_AMIGA;	simplekey_dev.id.vendor = 0x0001;	simplekey_dev.id.product = 0x0001;	simplekey_dev.id.version = 0x0100;	input_register_device(&simplekey_dev);#if DEBUG_DRIVER	printk(KERN_ERR "initialize button ok!");#endif	init_timer(&polling_timer);	polling_timer.data = (unsigned long)0;	polling_timer.function = polling_handler;	return 0;}static void __exit simplekey_exit(void){	int i;	for (i = 0; i <4; i++) {		free_irq(irqArray[i],simplekey_interrupt);	}	input_unregister_device(&simplekey_dev);}module_init(simplekey_init);module_exit(simplekey_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -