📄 key_scan.bak
字号:
/*********************************************************************** * * (C) Copyright 2004,12 * * Himai tech * All rights left. * * * a simple Device Driver for HM901ESP led device * * Can be loaded as module * * $Id: led.c,v 1.1 2004/12/15 $ * ***********************************************************************//* * Standard in kernel modules */#include <linux/kernel.h> /* We're doing kernel work */#include <linux/module.h> /* Specifically, a module */#include <asm/uaccess.h> /* for put_user */#include <linux/init.h> /* for __initfunc */#include <linux/sched.h>#include <linux/fs.h>#include <linux/interrupt.h> #include <linux/timer.h>#include <asm/io.h> /* for ioremap */#include <asm/arch/hardware.h> /* atmel RM9200 */ #include <asm/arch/pio.h>#undef DEBUG//#define DEBUG 1#ifdef DEBUG# define debugk(fmt,args...) printk(fmt ,##args)#else# define debugk(fmt,args...)#endif/* * Deal with CONFIG_MODVERSIONS */#if CONFIG_MODVERSIONS==1/* # define MODVERSIONS */# include <linux/modversions.h>#endifMODULE_LICENSE("GPL");#ifndef KERNEL_VERSION# define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))#endif#define SUCCESS 0#define TIMER_INTERVAL 50 /* timer interval ms *//* see ATMEL RM9200 datasheet */#define AT91C_BASE_KBS 0x808c0018 /* scan output base address */#define AT91C_BASE_KR 0x80840018 /* scan input base address */#define BASE_MEM_LEN 0x04 /* address length for ioremap */#define MY_BOARD_MAJOR 251/* * Prototypes */static int __init scankey_init (void );struct timer_list scan_timer;int status; /*0: Null 1: press 2:wait unpress*/static unsigned char input_data = 0xff;static void *kbs_base;static void *kr_base;struct key_map { unsigned char scan_code; unsigned char *disp_str; };struct key_map hm_5x4_keymap[] = { { 0x0e, "1" }, { 0x1e, "2" }, { 0x2e, "3" }, { 0x3e, "F1" }, { 0x4e, "F2" }, { 0x0d, "4" }, { 0x1d, "5" }, { 0x2d, "6" }, { 0x3d, "F3" }, { 0x4d, "CR" }, { 0x0b, "7" }, { 0x1b, "8" }, { 0x2b, "9" }, { 0x3b, "UP" }, { 0x4b, "DOWN" }, { 0x07, "*" }, { 0x17, "0" }, { 0x27, "#" }, { 0x37, "LEFT" }, { 0x47, "RIGHT" } };static int myboard_open(struct inode *, struct file *);static int myboard_close(struct inode *, struct file *);static int myboard_read(struct file *, char *, size_t, loff_t *);static int myboard_write(struct file *, const char *, size_t, loff_t *);static struct file_operations myboard_fops = { open: myboard_open, read: myboard_read, write: myboard_write, release: myboard_close,};static int myboard_open (struct inode *inode, struct file *file){ MOD_INC_USE_COUNT; return 0;}static int myboard_close (struct inode *inode, struct file *file){ //DBG_ZLG7289("zlg7289_close\n"); MOD_DEC_USE_COUNT; return 0;}static int myboard_read (struct file *file, char *buf, size_t count, loff_t *ppos){ put_user(input_data, buf); input_data = 0xff; return count;}static int myboard_write (struct file *file, const char *buf, size_t count, loff_t *ppos){ return count;}static void trans_key (unsigned char scan_code){ int i; for (i=0; i < sizeof(hm_5x4_keymap)/sizeof(struct key_map); i++) { if (scan_code == hm_5x4_keymap[i].scan_code) { input_data = hm_5x4_keymap[i].scan_code; printk("Pressed key is %s \n",hm_5x4_keymap[i].disp_str); } } }void hm_scankey(void* data){ unsigned char i,k; unsigned char scan_code; switch (status) { case 0: writeb(0xe0, kbs_base); if ((readb(kr_base) & 0x0f) != 0x0f) status = 1; break; case 1: writeb (0xe0, kbs_base); if ((readb(kr_base) & 0x0f) == 0x0f) status = 0; for (i=0; i<5; i++){ writeb(~(1<<i), kbs_base); k = readb(kr_base) & 0x0f; if (k!=0x0f) { scan_code = (k & 0x0f) | (i<<4); debugk("Key Scan = %02x \n", scan_code); trans_key(scan_code); status = 2; writeb(0xff, kbs_base); break; } } break; case 2: writeb(0xe0, kbs_base); k = readb(kr_base) & 0x0f; if (k == 0x0f) status = 0; break; } init_timer(&scan_timer); scan_timer.function = (void (*)(unsigned long))hm_scankey; //scan_timer.data = (unsigned long)&_data; scan_timer.expires = TIMER_INTERVAL * HZ /1000; mod_timer(&scan_timer, jiffies + TIMER_INTERVAL * HZ/1000); }/* * Initialize the driver - Register the character device */static int __init scankey_init(void){ //9.26 edit if (register_chrdev(MY_BOARD_MAJOR, "myboard", &myboard_fops)) printk("reg dev error\n"); /* get the remmapped port base address register */ kbs_base = ioremap_nocache(AT91C_BASE_KBS, BASE_MEM_LEN); kr_base = ioremap_nocache(AT91C_BASE_KR, BASE_MEM_LEN); status = 0; init_timer(&scan_timer); scan_timer.function = (void(*)(unsigned long))hm_scankey;// runled_timer.data = (unsigned long)&runled_data; scan_timer.expires = jiffies + TIMER_INTERVAL * HZ /1000; add_timer(&scan_timer); return 0;}/****************************** **** Module Declarations ***** **************************** */#ifdef MODULE/* * Cleanup - unregister */static void __exit cleanup_scankey_module (void){ iounmap (kbs_base); iounmap (kr_base); del_timer(&scan_timer); return;}module_init(scankey_init);module_exit(cleanup_scankey_module);MODULE_AUTHOR("Himai");MODULE_DESCRIPTION("scan key for HM901ESP");#endif /* MODULE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -