📄 key_scan_no_reg
字号:
/*********************************************************************** * * (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 *//* * Prototypes */static int __init scankey_init (void );struct timer_list scan_timer;int status; /*0: Null 1: press 2:wait unpress*/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" } };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) 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){ /* 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 + -