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

📄 keyboard.c

📁 基于S3C2410开发板
💻 C
字号:
#ifndef __KERNEL__# define __KERNEL__#endif#ifndef MODULE# define MODULE#endif#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/irq.h>#include <linux/tqueue.h>#include <linux/delay.h>#include <linux/timer.h>#include <asm/uaccess.h>#include <asm/hardware.h>#define	DEV_NAME	"keyboard"#define	IRQ_KEYBOARD	IRQ_EINT13#define GPIO_KEYBOARD	GPIO_G5#define KBD_ROW_NUM	4#define KBD_COL_NUM	3#define KEY_ROW_SHIFT	4#define KEY_COL_SHIFT	0#define CHECK_NUM	2#define	GPIO_ROW0	GPIO_F7#define	GPIO_ROW1	GPIO_F5#define	GPIO_ROW2	GPIO_F3#define	GPIO_ROW3	GPIO_F1#define	GPIO_COL0	GPIO_F6#define	GPIO_COL1	GPIO_F4#define	GPIO_COL2	GPIO_F2static DECLARE_WAIT_QUEUE_HEAD(keyboard_wait);static DECLARE_WAIT_QUEUE_HEAD(timer_wait);static int key_major = 121;static int int_cnt;static int key[CHECK_NUM];static char key_val;static unsigned long row[KBD_ROW_NUM] = {GPIO_ROW0, GPIO_ROW1, GPIO_ROW2, GPIO_ROW3};static unsigned long col[KBD_COL_NUM] = {GPIO_COL0, GPIO_COL1, GPIO_COL2};static int key_open(struct inode *inode, struct file *filp);static int key_close(struct inode *inode, struct file *filp);static ssize_t key_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);static char key_map(int key);static void keyboard_scan(void *data);static void keyboard_handler(int irq, void *dev_id, struct pt_regs *regs);static int key_open(struct inode *inode, struct file *filp){	int result;	set_external_irq(IRQ_KEYBOARD, EXT_FALLING_EDGE, GPIO_PULLUP_DIS);	result = request_irq(IRQ_KEYBOARD, keyboard_handler, SA_INTERRUPT, DEV_NAME, NULL);	if(result)	{		printk(KERN_INFO DEV_NAME":IRQ requstion failed!\n");		return -EFAULT;	}	MOD_INC_USE_COUNT;	return 0;}static int key_close(struct inode *inode, struct file *filp){	free_irq(IRQ_KEYBOARD, NULL);	MOD_DEC_USE_COUNT;	return 0;}static ssize_t key_read(struct file *filp, char *buf, size_t count, loff_t *f_pos){	interruptible_sleep_on(&keyboard_wait);	copy_to_user(buf, &key_val, 1);	return 1;}static struct file_operations key_fops ={	owner:	THIS_MODULE,	open:	key_open,	release:key_close,	read:	key_read,};static char key_map(int key){	if(key <= 0x12)	{		switch(key)		{			case 0x00: return 0x00;			case 0x01: return 0x01;			case 0x02: return 0x02;			case 0x10: return 0x03;			case 0x11: return 0x04;			case 0x12: return 0x05;		}	}	else if(key <= 0x32)	{		switch(key)		{			case 0x20: return 0x06;			case 0x21: return 0x07;			case 0x22: return 0x08;			case 0x30: return 0x09;			case 0x31: return 0x0a;			case 0x32: return 0x0b;		}	}}static void keyboard_scan(void *data){//	unsigned long row,col;	int i,j,k;	for(k=0; k<CHECK_NUM; k++)	{		for(i=0; i<KBD_ROW_NUM; i++)		{			if(!read_gpio_bit(row[i]))			{				break;			}		}				if(i >= KBD_ROW_NUM)		{			goto fini;		}		for(j=0; j<KBD_COL_NUM; j++)		{			write_gpio_bit(col[j], 1);			if(read_gpio_bit(row[i]))			{				write_gpio_bit(col[j], 0);				break;			}			write_gpio_bit(col[j], 0);		}				if(j >= KBD_COL_NUM)		{			goto fini;		}		key[k] = (i << KEY_ROW_SHIFT) | (j << KEY_COL_SHIFT);		if(k < (CHECK_NUM-1))		{			interruptible_sleep_on_timeout(&timer_wait, 10);		}	}		for(k=1; k<CHECK_NUM; k++)	{		if(key[k] != key[0])		{			key[0] = 0xff;			break;		}	}	if(key[0] != 0xff)	{//		printk(KERN_INFO"0x%02x\n", key[0]);		key_val = key_map(key[0]);	}//	printk(KERN_INFO"0x%02x\n", key_val);fini:	wake_up_interruptible(&keyboard_wait);	int_cnt = 0;}static struct tq_struct keyboard_task ={	routine:keyboard_scan,};static void keyboard_handler(int irq, void *dev_id, struct pt_regs *regs){	if(++int_cnt > 1)	{//		printk(KERN_INFO"%d added int!\n",int_cnt);		int_cnt -= 1;		return;	}	schedule_task(&keyboard_task);}int __init keyboard_init(void){	int result;	int i;/* set the ROW and COL level of the keyboard*/		for(i=0; i<KBD_ROW_NUM; i++)	{		set_gpio_ctrl(row[i] | GPIO_PULLUP_DIS | GPIO_MODE_IN);	}	for(i=0; i<KBD_COL_NUM; i++)	{		set_gpio_ctrl(col[i] | GPIO_PULLUP_DIS | GPIO_MODE_OUT);	}	for(i=0; i<KBD_COL_NUM; i++)	{		write_gpio_bit(col[i], 0);	}	result = register_chrdev(key_major, DEV_NAME, &key_fops);	if(result < 0)	{		printk(KERN_INFO DEV_NAME":Device registion failed!\n");		return -EFAULT;	}	int_cnt = 0;	printk(KERN_INFO"Keyboard init OK!\n");	return 0;}void __exit keyboard_exit(void){	int result;	result = unregister_chrdev(key_major, DEV_NAME);	if(result == -EFAULT)	{		printk(KERN_INFO DEV_NAME":Device unregistion failled!\n");	}/* restore the IRQ ports */	set_external_irq(IRQ_EINT1, EXT_FALLING_EDGE, GPIO_PULLUP_DIS);	set_external_irq(IRQ_EINT3, EXT_FALLING_EDGE, GPIO_PULLUP_DIS);		printk(KERN_INFO"Keyboard exit OK!\n");}module_init(keyboard_init);module_exit(keyboard_exit);MODULE_LICENSE("Bill KeyBoard module GPL/MPL");

⌨️ 快捷键说明

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