📄 s3c2410_mykbd_drv.c
字号:
/* This program was generated by Guo Pan in June, 2006. And modified by KGB in March, 2007. The key "IRQ_EINT11" is modified as the outputsignal of "LCD ON" */#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/kbd_kern.h> /* for keyboard_tasklet */#include <linux/kbd_ll.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/hardware.h>#include <asm/keyboard.h>#include <asm/errno.h>#define LCDON 1 /* Turn on LCD */#define LCDOFF 0 /* Turn off LCD */#define KK_1 0x02 /* EINT0 key scancode */#define KK_2 0x03 /* EINT2 key scancode */#define KK_3 0x04 /* EINT11 key scancode */ /*按键所使用的CPU资源*/static struct key_info{ int irq_no; unsigned int gpio_port; int key_no;} key_info_tab [] ={// { IRQ_EINT0, GPIO_F0, KK_1 }, { IRQ_EINT2, GPIO_F2, KK_2 }, { IRQ_EINT11, GPIO_G3, KK_3 } };/*按键的中断服务程序*/static void key_interrupt(int irq, void *dev_id, struct pt_regs *reg){ struct key_info *k; int found = 0; int i = 0;// int key = 1; cli(); mdelay(20); // 消除按键按下的抖动// save_flags(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) && ((read_gpio_bit(k->gpio_port) & 0x01) == 0)) { found = 1; break; } } set_external_irq(k->irq_no, EXT_FALLING_EDGE, GPIO_PULLUP_DIS); if (!found) { printk("bad irq %d in keyboard \n", irq); } else { printk("key KK_%d is pressed. \n", k->key_no-1); handle_scancode(k->key_no, 1);// printk("handle scancode done. \n"); tasklet_schedule(&keyboard_tasklet);// printk("keyboard tasklet done. \n"); handle_scancode(k->key_no, 0);// printk("handle scancode done. \n"); tasklet_schedule(&keyboard_tasklet); }}/*申请系统中断,中断方式在下降沿发生中断*/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_FALLING_EDGE, GPIO_PULLUP_DIS ); if (request_irq(k->irq_no, key_interrupt, SA_INTERRUPT, "GPIO_Keyboard", key_interrupt)) 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, key_interrupt); }}/* 初始化中断*/static int __init s3c2410_kbd_init(void){ int ret = -ENODEV; // int delay ; ret = request_irqs(); printk("%d \n",ret); if (ret) { printk(KERN_INFO "request IRQ failed (%d)\n", IRQ_KBD); return ret; }/* Turn on LCD */ set_gpio_ctrl(GPIO_G3 | GPIO_MODE_OUT); write_gpio_bit(GPIO_G3, LCDON); return ret;}/* 扫描码到键盘码的转换 static int my_kbd_translate(u_char scancode, u_char *keycode, char raw_mode){// *keycode = scancode & 0x7f; *keycode = scancode; return 1;}static int __init my_kbd_init(void) { int ret = -ENODEV; ret = HW_kbd_init(); if (ret < 0) return ret; // include/asm/keyboard.h , we have not key_ops_struct k_translate = my_kbd_translate; return 0;}*/static void __exit s3c2410_kbd_exit(void){ free_irqs(); /* Turn off LCD */ write_gpio_bit(GPIO_G3, LCDOFF); set_gpio_ctrl(GPIO_G3 | GPIO_MODE_IN);}module_init(s3c2410_kbd_init);module_exit(s3c2410_kbd_exit);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -