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

📄 s3c2410_kbd_m6x6.c

📁 S3C2410上基于linux的6X6键盘驱动
💻 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 <asm/hardware.h>#define DEVICE_NAME	"kbd_m6x6"#define BUTTON_MAJOR 233static int irq_col_tab[] = { IRQ_EINT16, IRQ_EINT19, IRQ_EINT14, IRQ_EINT15, IRQ_EINT11, IRQ_EINT13 };#define COL_NUM ( (sizeof irq_col_tab) / sizeof (irq_col_tab[0]) )static unsigned gpio_col_tab[] = {GPIO_G8, GPIO_G11, GPIO_G6, GPIO_G7, GPIO_G3, GPIO_G5};static unsigned gpio_row_tab[] = { GPIO_B1, GPIO_B0, GPIO_F4, GPIO_F0, GPIO_F6, GPIO_F5 };#define ROW_NUM ( sizeof gpio_row_tab / sizeof (gpio_row_tab[0]) )static int ready = 0;static int key_value = 0, last_value = 0;static DECLARE_WAIT_QUEUE_HEAD(buttons_wait);static int waitting_down_tab[] = {1, 1, 1, 1, 1, 1};static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg){	int i;	int col_no = -1, row_no = -1;	unsigned long flags;	local_irq_save(flags);	for (i = 0; i < COL_NUM; i++) {		if (irq_col_tab[i] == irq) {			col_no = i;			break;		}	}	if (col_no < 0) {		goto EXIT;	}	if (waitting_down_tab[col_no]) {		for (i = 0; i < COL_NUM; i++) {			set_gpio_ctrl(gpio_col_tab[i] | GPIO_PULLUP_DIS | GPIO_MODE_IN);		}		udelay(300);		for (i = 0; i < ROW_NUM; i++) {			int r;			write_gpio_bit(gpio_row_tab[i], 1);			udelay(300);			r = read_gpio_bit(gpio_col_tab[col_no]);			write_gpio_bit(gpio_row_tab[i], 0);			if (r) { // found				row_no = i;				break;			}		}		udelay(300);		for (i = 0; i < COL_NUM; i++) {			set_gpio_ctrl(gpio_col_tab[i] | GPIO_PULLUP_DIS | GPIO_MODE_ALT0);		}		if (col_no < 0 || row_no < 0) {			goto EXIT;		}		key_value = row_no * 6 + col_no + 1;	} else {		key_value = last_value | 0x80;	}	waitting_down_tab[col_no] = !waitting_down_tab[col_no];	set_external_irq(irq, waitting_down_tab[col_no]? EXT_LOWLEVEL: EXT_HIGHLEVEL, GPIO_PULLUP_DIS);	udelay(300);	ready = 1;	wake_up_interruptible(&buttons_wait);EXIT:	restore_flags(flags);}static void buttons_io_port_init(void){	int i;	for (i = 0; i < ROW_NUM; i ++) {		unsigned gpio = gpio_row_tab[i];		set_gpio_ctrl(gpio | GPIO_PULLUP_DIS | GPIO_MODE_OUT);		write_gpio_bit(gpio, 0);	}}static int matrix4_buttons_read(struct file * file, char * buffer, size_t count, loff_t *ppos){	static int key;	int repeat = key == key_value;	key == key_value;        if (!ready)                return -EAGAIN;        if (count != sizeof key_value)                return -EINVAL;	if (repeat) {		return -EAGAIN;	}        copy_to_user(buffer, &key_value, sizeof key_value);	last_value = key_value;        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 int request_irqs(void){	int i;	for (i = 0; i < COL_NUM; i++) {		int irq = irq_col_tab[i];		int ret = request_irq(irq, &buttons_irq, SA_INTERRUPT, DEVICE_NAME, &buttons_irq);		if (ret) {			unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);			printk(DEVICE_NAME " can't request irq %d\n", irq);			return ret;		}	}}static void free_irqs(void){	int i;	for (i = 0; i < COL_NUM; i++) {		int irq = irq_col_tab[i];		free_irq(irq, buttons_irq);	}}static devfs_handle_t devfs_handle;static int __init matrix4_buttons_init(void){	int ret;	int i;	ready = 0;	ret = register_chrdev(BUTTON_MAJOR, DEVICE_NAME, &matrix4_buttons_fops);	if (ret < 0) {	  printk(DEVICE_NAME " can't register major number\n");	  return ret;	}	buttons_io_port_init();		for (i = 0; i < COL_NUM; i++) {		int irq = irq_col_tab[i];		set_external_irq(irq, EXT_LOWLEVEL, GPIO_PULLUP_DIS);	}	ret = request_irqs();	if (ret) {		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 + -