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

📄 xsb_edr_keypad.c

📁 在PXA270上的IO驱动
💻 C
字号:
#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/miscdevice.h>#include <linux/sched.h>#include <linux/delay.h>#include <linux/poll.h>#include <linux/spinlock.h>#include <linux/delay.h>#include <asm/io.h>#include <asm/hardware.h>#include <asm/arch-pxa/pxa-regs.h>#include <linux/fs.h>#include <linux/mm.h>/* debug macros */#define MAX_KBD_BUF	16	/* how many do we want to buffer */#define IRQ_KEYPAD      4#define DEVICE_NAME	"emdoor_kbd"#define KEYVALUE_HAVE  1#define KEYVALUE_NO    0#define KPC_DIR		1<<5#define KPC_MAT		1<<22static int Emdoor_kbd_fasync(int, struct file* ,int);typedef unsigned char KBD_RET;struct fasync_struct * fasync;typedef struct {	KBD_RET kbd_buff;		/* protect against overrun */	unsigned int kbd_status;	wait_queue_head_t wq;	spinlock_t lock;//struct fasync_struct * fasync;} KBD_DEV;static KBD_DEV kbddev;static int kbdMajor=0;static ssize_t Emdoor_kbd_read(struct file *filp, char *buffer, size_t count, loff_t *ppos){				KBD_DEV * kbd=filp->private_data;		KBD_RET kbd_ret;		while(1)		{			if(kbd->kbd_status==KEYVALUE_HAVE)			{			 kbd_ret = kbd->kbd_buff;			 copy_to_user(buffer, &kbd_ret, sizeof(KBD_RET));			 kbd->kbd_status=KEYVALUE_NO;			 return sizeof(KBD_RET);			}			else{
			if (filp->f_flags & O_NONBLOCK)			  return -EAGAIN;			interruptible_sleep_on(&(kbd->wq));			if (signal_pending(current))			return -ERESTARTSYS;			}		}		return sizeof(KBD_RET);				}static void Emdoor_isr_kbd(int irq, void *dev_id, struct pt_regs *reg){		int kpc_value;		KBD_DEV * kbd = (KBD_DEV *) dev_id;		spin_lock_irq(&(kbd->lock));//		printk(KERN_EMERG"INTERRUPT OCCOUR\n");		kpc_value=KPC;		if(kpc_value&KPC_MAT)		{			kbd->kbd_buff=KPAS&0xFF;			if(kbd->kbd_buff!=0xFF){			    switch(kbd->kbd_buff){				case 0x0:  kbd->kbd_buff=5;  break;				case 0x1:  kbd->kbd_buff=6;  break;				case 0x2:  kbd->kbd_buff=7;  break;				case 0x5:  kbd->kbd_buff=8;  break;				case 0x10: kbd->kbd_buff=9;  break;				case 0x11: kbd->kbd_buff=10; break;				case 0x12: kbd->kbd_buff=11; break;				case 0x15: kbd->kbd_buff=12; break;				case 0x20: kbd->kbd_buff=13; break;				case 0x21: kbd->kbd_buff=14; break;				case 0x22: kbd->kbd_buff=15; break;				case 0x25: kbd->kbd_buff=16; break;				default:    break;				}				kbd->kbd_status=KEYVALUE_HAVE;//		wake_up_interruptible(&(kbd->wq));					}		}		else if(kpc_value&KPC_DIR){			kbd->kbd_buff=KPDK&0xFF;			if(kbd->kbd_buff!=0x0){			    switch(kbd->kbd_buff){				case 0x40:  kbd->kbd_buff=1;  break;				case 0x2:   kbd->kbd_buff=2;  break;				case 0x4:   kbd->kbd_buff=3;  break;				case 0x20:  kbd->kbd_buff=4;  break;				default:	   break;				}			kbd->kbd_status=KEYVALUE_HAVE;//	wake_up_interruptible(&(kbd->wq));					}								}		if ( fasync )			kill_fasync( &(fasync), SIGIO, POLL_IN );		wake_up_interruptible(&(kbd->wq));	spin_unlock_irq(&(kbd->lock));}static int Emdoor_kbd_open(struct inode *inode, struct file *filp){	int ret;	KBD_DEV * kbd;	MOD_INC_USE_COUNT;	kbd =(KBD_DEV *) kmalloc(sizeof(KBD_DEV ), GFP_KERNEL);//	KPC=0x2FAFF9C3;               //键盘中断初始化		KPC=KPC_ASACT | (3<<26) | (7<<23 ) | KPC_IMKP | KPC_MS6 | KPC_MS5 | KPC_MS4 | KPC_MS3 | KPC_MS2 | KPC_MS1 | KPC_MS0 | KPC_ME | KPC_MIE | (7<<6) | KPC_DE | KPC_DIE;		init_waitqueue_head(&(kbd->wq));	set_GPIO_mode(94  | GPIO_ALT_FN_1_IN);	set_GPIO_mode(95  | GPIO_ALT_FN_1_IN);	set_GPIO_mode(98  | GPIO_ALT_FN_1_IN);	set_GPIO_mode(99  | GPIO_ALT_FN_1_IN);	set_GPIO_mode(100 | GPIO_ALT_FN_1_IN);	set_GPIO_mode(101 | GPIO_ALT_FN_1_IN);	set_GPIO_mode(102 | GPIO_ALT_FN_1_IN);	set_GPIO_mode(103 | GPIO_ALT_FN_2_OUT);	set_GPIO_mode(104 | GPIO_ALT_FN_2_OUT);	set_GPIO_mode(105 | GPIO_ALT_FN_2_OUT);	set_GPIO_mode(108 | GPIO_ALT_FN_2_OUT);	kbd->kbd_status=KEYVALUE_NO;//	kbddev.kbd_status=KEYVALUE_NO;	filp->private_data=kbd;	// Enable interrupt	ret = request_irq(IRQ_KEYPAD, Emdoor_isr_kbd, SA_INTERRUPT, DEVICE_NAME, kbd);		if (ret)	{	printk(KERN_EMERG " Interrupt init=%x!!!!\n",ret);	return ret;	}		return 0;}static unsigned int Emdoor_kbd_poll(struct file *filp,struct poll_table_struct *wait){	KBD_DEV * kbd=filp->private_data;	poll_wait(filp,&(kbd->wq),wait);	return (kbd->kbd_status==KEYVALUE_HAVE) ?  (POLLIN|POLLRDNORM): 0  ;}static int Emdoor_kbd_release(struct inode *inode, struct file *filp){		KBD_DEV * kbd = filp->private_data;	KPC=0x0;	Emdoor_kbd_fasync(-1, filp, 0);		kfree(kbd );	free_irq(IRQ_KEYPAD, kbd);	MOD_DEC_USE_COUNT;	return 0;}static int Emdoor_kbd_fasync(int fd, struct file * file, int mode){	KBD_DEV *kbd = file->private_data;	return  fasync_helper(fd, file, mode, &(fasync) );	}static struct file_operations Emdoor_fops = {	open:		Emdoor_kbd_open,	read:		Emdoor_kbd_read,		release:	Emdoor_kbd_release,	poll:		Emdoor_kbd_poll,	fasync:		Emdoor_kbd_fasync,	owner:		THIS_MODULE,	};static int __init Emdoor_kbd_init(void){	int ret;	ret = register_chrdev(62, DEVICE_NAME, &Emdoor_fops);	if (ret < 0) {		printk(DEVICE_NAME " can't get major number\n");		return ret;	}		free_irq(IRQ_KEYPAD,NULL);	udelay(10);	//printk(KERN_INFO " Emdoor_kpd initialized\n");	return 0;}static void __exit Emdoor_kbd_exit(void){		unregister_chrdev(62, DEVICE_NAME);}module_init(Emdoor_kbd_init);module_exit(Emdoor_kbd_exit);

⌨️ 快捷键说明

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