📄 kbd7312.c
字号:
#include <linux/config.h>#include <linux/utsname.h>#include <linux/kernel.h>#include <linux/major.h>#include <linux/string.h>#include <linux/fcntl.h>#include <linux/slab.h>#include <linux/timer.h>#include <linux/module.h>#include <linux/init.h>#include <linux/poll.h>#include <asm/irq.h>#include <asm/segment.h>#define KBD_IRQ_NUM 0#define KEYBOARD_MAJOR 59 static short Ready;static char KeyValue;static DECLARE_WAIT_QUEUE_HEAD(KbdWait);static int col_global;void dly(int n){ int i, j; for(i = 0; i < 1000; i++) for(j = 0; j < n; j++) ;}static void KbdInterrupt(int irq, void *dev_id, struct pt_regs *regs){ unsigned char value; Ready = 0; value = *(unsigned char *)0xff000000; if(col_global == 0) { if(value == 0x1) { KeyValue = 1; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 1\n", col_global + 1); } if(value & 0x2) { KeyValue = 5; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 2\n", col_global + 1); } if(value & 0x4) { KeyValue = 9; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 3\n", col_global + 1); } if(value & 0x8) { KeyValue = 13; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 4\n", col_global + 1); } dly(1000); } else if (col_global == 1) { if(value & 0x1) { KeyValue = 2; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 1\n", col_global + 1); } if(value & 0x2) { KeyValue = 6; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 2\n", col_global + 1); } if(value & 0x4) { KeyValue = 10; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 3\n", col_global + 1); } if(value & 0x8) { KeyValue = 14; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 4\n", col_global + 1); } dly(1000); } else if(col_global == 2) { if(value & 0x1) { KeyValue = 3; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 1\n", col_global + 1); } if(value & 0x2) { KeyValue = 7; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 2\n", col_global + 1); } if(value & 0x4) { KeyValue = 11; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 3\n", col_global + 1); } if(value & 0x8) { KeyValue = 15; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 4\n", col_global + 1); } dly(1000); } else if(col_global == 3) { if(value & 0x1) { KeyValue = 4; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 1\n", col_global + 1); } if(value & 0x2) { KeyValue = 8; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 2\n", col_global + 1); } if(value & 0x4) { KeyValue = 12; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 3\n", col_global + 1); } if(value & 0x8) { KeyValue = 16; printk("KeyValue = %d\n", KeyValue);// printk("col = %d, row = 4\n", col_global + 1); } dly(1000); }#if 0 //test ok if(value & 0x1) { printk("col = %d, row = 1\n", col_global + 1); } if(value & 0x2) { printk("col = %d, row = 2\n", col_global + 1); } if(value & 0x4) { printk("col = %d, row = 3\n", col_global + 1); } if(value & 0x8) { printk("col = %d, row = 4\n", col_global + 1); } // printk("value = 0x%02x\n", value); dly(500);#endif #if 0 while(1){ again: printk("\n0x80000100 : 0x%08x\n", *(unsigned char *)0xff000100); printk("0x80000000 : 0x%08x\n", *(unsigned char *)0xff000000); printk("n= %d\n", n); printk("interrupt\n"); value = *(unsigned char *)0xff000000; if(value & 0x1) { printk("col = %d, row = 1\n", n + 1); } if(value & 0x2) { printk("col = %d, row = 2\n", n + 1); } if(value & 0x4) { printk("col = %d, row = 3\n", n + 1); } if(value & 0x8) { printk("col = %d, row = 4\n", n + 1); }// printk("value = 0x%02x\n", value); dly(500); *(unsigned long *)0xff000100 += 1; *(unsigned long *)0xff001700 |= 0xff; //clear n += 1; if( n == 4) { *(unsigned long *)0xff000100 -= 4; n -= 4; goto scan_exit; } goto again; }#endif // *(unsigned long *)0xff001700 |= 0xff; //clear}static int KbdClose(struct inode * inode, struct file * file){ MOD_DEC_USE_COUNT; return 0;}static int KbdOpen(struct inode * inode, struct file * file){ MOD_INC_USE_COUNT; *(unsigned long *)0xff000040 |= 0xfffffffff; *(unsigned long *)0xff001100 |= 0x000000008; *(unsigned long *)0xff000100 |= 0x000000009; enable_irq(16); return 0;}static int KbdRead(struct file * file, char * buffer, size_t count, loff_t *ppos){ unsigned char *kbuf=kmalloc(16, GFP_KERNEL); *kbuf = KeyValue; copy_to_user(buffer, kbuf, 1); kfree(kbuf); //copy_to_user(buffer, &KeyValue, sizeof KeyValue); //Ready = 0; return sizeof 1;}/* * select for mouse input */static unsigned int KbdSelect( struct file *file, struct poll_table_struct *wait){ if (Ready) return 1; poll_wait(file, &KbdWait, wait); return 0;}static int KbdIoctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ int flag = 0; switch(cmd) { case 0: for(col_global = 0; col_global < 4; col_global++){ if(col_global == 0 ) { *(unsigned long *)0xff000100 &= ~0xf; *(unsigned long *)0xff000100 |= 0x8; dly(1000); } else if( col_global == 1) { *(unsigned long *)0xff000100 &= ~0xf; *(unsigned long *)0xff000100 |= 0x9; dly(1000); } else if( col_global == 2) { *(unsigned long *)0xff000100 &= ~0xf; *(unsigned long *)0xff000100 |= 0xa; dly(1000); } else if( col_global == 3) { *(unsigned long *)0xff000100 &= ~0xf; *(unsigned long *)0xff000100 |= 0xb; dly(1000); } } break; case 2: if( flag == 0) { *(unsigned long *)0xff000100 += 1; flag = 1; } else if (flag == 1){ *(unsigned long *)0xff000100 -= 1; flag = 0; } break; case 1: { unsigned char value; int n = 0; while(1){ again:// printk("0x80000100 : 0x%08x\n", *(unsigned char *)0xff000100);// printk("0x80000000 : 0x%08x\n", *(unsigned char *)0xff000000); // printk("n= %d\n", n); value = *(unsigned char *)0xff000000; if(value & 0x1) { printk("col = %d, row = 1\n", n + 1); } if(value & 0x2) { printk("col = %d, row = 2\n", n + 1); } if(value & 0x4) { printk("col = %d, row = 3\n", n + 1); } if(value & 0x8) { printk("col = %d, row = 4\n", n + 1); }// printk("value = 0x%02x\n", value); dly(500); *(unsigned long *)0xff000100 += 1; n += 1; if( n == 4) { *(unsigned long *)0xff000100 -= 4; n -= 4; break; } goto again; }// end for break; } //end case 0 default: return -EINVAL; } return 1;}struct file_operations Kbd_fops = { read: KbdRead, poll: KbdSelect, /* select */ open: KbdOpen, ioctl: KbdIoctl, release: KbdClose,};int keyboard_init(void){ int rc; Ready = 0; rc = register_chrdev(KEYBOARD_MAJOR, "ep7312-keyboard", &Kbd_fops); if (rc < 0) { printk(KERN_WARNING "Keyboard: can't get Major %d\n", KEYBOARD_MAJOR); return rc; } printk("Keyboard Driver Support\n"); *(unsigned long *)0xff000040 |= 0xfffffffff; *(unsigned long *)0xff001100 |= 0x000000008; *(unsigned long *)0xff000100 |= 0x000000009; if ( request_irq(16, KbdInterrupt, 0, "mykbd", NULL) ) { printk("Keyboard: Cannot register interrupt.\n"); return -EBUSY; } return 0;}void keyboard_cleanup(void){ free_irq(16, NULL); unregister_chrdev(KEYBOARD_MAJOR, "ep7312-keyboard"); return;} module_init(keyboard_init);module_exit(keyboard_cleanup);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -