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

📄 kbd.c

📁 一个简单的ARM9+Linux-2.4下的键盘驱动
💻 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/irq.h>#include <linux/delay.h>#include <linux/tty.h>#include <asm/hardware.h>#define DEVICE_NAME "buttons"static int BUTTON_MAJOR;static struct key_info {	int irq_no;	unsigned int gpio_port;	int key_no;}key_info_tab[5] = {	{ IRQ_EINT5, GPIO_F5, 0 },	{ IRQ_EINT8, GPIO_G0, 1 },	{ IRQ_EINT2, GPIO_F2, 2 },	{ IRQ_EINT16, GPIO_G8, 3 },	{ IRQ_EINT17, GPIO_G9, 4 },};static int ready = 0;static int key_value = 0;static DECLARE_WAIT_QUEUE_HEAD(buttons_wait);#if 0static void printStr(char *str)  {  	int len = 0;	struct tty_struct *my_tty;      my_tty = current->tty;  	len = strlen(str);	    if(my_tty != NULL)      {      	(*(my_tty->driver).write)(my_tty,0,str,len);  		if (str[len-1] != '\012')        	(*(my_tty->driver).write)(my_tty,0,"\012",1);      }  }   #endifstatic void buttons_irq(int irq, void *dev_id, struct pt_regs *reg){	struct key_info *k;	int i;	int found = 0;	int up;	int flags;		for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++) 	{		k = key_info_tab + i;		if (k->irq_no == irq) 		{			found = 1;			break;		}	}		if (!found) 	{		return;	}	save_flags(flags);	cli();//	set_gpio_mode_user(k->gpio_port, GPIO_MODE_IN);	up = read_gpio_bit(k->gpio_port);	set_external_irq(k->irq_no, EXT_BOTH_EDGES, GPIO_PULLUP_DIS);	restore_flags(flags);		if (up) 	{		key_value = k->key_no + 0x80;	} 	else 	{		key_value = k->key_no;	}		ready = 1;	wake_up_interruptible(&buttons_wait);}static int request_irqs(void){	struct key_info *k;	int i;	for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++) 	{		k = key_info_tab + i;		set_external_irq(k->irq_no, EXT_BOTH_EDGES, GPIO_PULLUP_DIS);		if (request_irq(k->irq_no, &buttons_irq, SA_INTERRUPT, DEVICE_NAME, &buttons_irq)) 		{			return -1;		}	}		return 0;}static void free_irqs(void){	struct key_info *k;	int i;	for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++) 	{		k = key_info_tab + i;		free_irq(k->irq_no, buttons_irq);	}}static int matrix4_buttons_read(struct file * file, char * buffer, size_t count, loff_t *ppos){	static int key;	int flags;	int repeat;	if (!ready)		return -EAGAIN;	if (count != sizeof key_value)		return -EINVAL;	save_flags(flags);	if (key != key_value) 	{		key = key_value;		repeat = 0;	} 	else 	{		repeat = 1;	}		restore_flags(flags);	if (repeat) 	{		return -EAGAIN;	}	copy_to_user(buffer, &key, sizeof key);	ready = 0;		return sizeof key_value;}static unsigned int matrix4_buttons_select(struct file *file,struct poll_table_struct *wait){	if (ready)		return 1;	poll_wait(file, &buttons_wait, wait);	return 0;}static int matrix4_buttons_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	switch(cmd) 	{		default:			return -EINVAL;	}}static struct file_operations matrix4_buttons_fops = {	owner: THIS_MODULE,	ioctl: matrix4_buttons_ioctl,	poll: matrix4_buttons_select,	read: matrix4_buttons_read,};static devfs_handle_t devfs_handle;static int __init matrix4_buttons_init(void){	int ret;	ready = 0;	ret = register_chrdev(0, DEVICE_NAME, &matrix4_buttons_fops);	if (ret < 0) 	{		return ret;	}		BUTTON_MAJOR = ret;	printk(KERN_EMERG "Major: %d. Init successed\n",BUTTON_MAJOR);	ret = request_irqs();	if (ret) 	{		unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);		return ret;	}	devfs_handle = devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT,	BUTTON_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR, &matrix4_buttons_fops, NULL);	return 0;}static void __exit matrix4_buttons_exit(void){	devfs_unregister(devfs_handle);	free_irqs();	unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);}module_init(matrix4_buttons_init);module_exit(matrix4_buttons_exit);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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