android系统PS2全键盘驱动(中)-使用input_event实现 .

android系统PS2全键盘驱动(上)-使用linux的标准接口实现 中介绍了使用linux的标准接口实现PS2键盘驱动,由于我的PS2键盘是特殊定制的,有部分按键并不是按照第二套键盘扫描码来的,虽然使用linux提供的PS2驱动可以使用大部分的按键,但有部分按键无法使用。所以要使用linuxPS2键盘驱动的话有两种方式,一种是修改linux PS2驱动对扫描码处理部分的代码,一种是自己写PS2键盘的驱动。这里我选择第二种。实现过程如下:

 a./home/ubuntu/G923/linux/drivers/input/keyboard/目录下添加imapx200_ps2_keyboard.c,imapx200_ps2_keyboard.h文件。
 b./home/ubuntu/G923/linux/drivers/input/keyboard/Makefile文件中添加
  obj-$(CONFIG_KEYBOARD_PS2KEYBOARD) += imapx200_ps2_keyboard.o
 c./home/ubuntu/G923/linux/arch/arm/mach-imapx200/configs/keyboard_config文件添加
  # ps2 keyboard
  config KEYBOARD_PS2KEYBOARD
   bool "ps2 keyboard"
 
  config PS2KEYBOARD_LED_CAPSLOCK
   string "ps2 keyboard capslock led control"
   depends on KEYBOARD_PS2KEYBOARD

  config PS2KEYBOARD_LED_NUMLOCK
   string "ps2 keyboard numlock led control"
   depends on KEYBOARD_PS2KEYBOARD

  config PS2KEYBOARD_HALLONE
   string "hall one gpio"
   depends on KEYBOARD_PS2KEYBOARD

  config PS2KEYBOARD_HALLTWO
   string "hall two gpio"
   depends on KEYBOARD_PS2KEYBOARD
 d./home/ubuntu/G923/linux/arch/arm/mach-imapx200/cpu.c文件修改
  //&imapx200_device_pic0,
  &ps2keyboard_device,
  //amba_device_register(&imap_ps2_device, &(imap_ps2_device.res));
   /home/ubuntu/G923/linux/arch/arm/plat-imap/include/plat/devs.h文件添加
  extern struct platform_device ps2keyboard_device;
 e./home/ubuntu/G923/linux/arch/arm/mach-imapx200/devices.c文件添加
  /************PS2 keyboard***************/
  static struct resource ps2keyboard_resource[]={
   [0] = {
    .start = PIC0_BASE_REG_PA,
    .end   = PIC0_BASE_REG_PA + 0xfff,
    .flags = IORESOURCE_MEM,
   },
   [1] = {
    .start = IRQ_PS2_0,
    .end = IRQ_PS2_0,
    .flags = IORESOURCE_IRQ, 
   }
  };

  struct platform_device ps2keyboard_device = {
   .name  = "ps2keyboard",
   .id   = -1,
   .num_resources = ARRAY_SIZE(ps2keyboard_resource),
   .resource = ps2keyboard_resource,
  };
  EXPORT_SYMBOL(ps2keyboard_device);
 f./home/ubuntu/G923/linux/drivers/soops/soops.c文件添加(这部分主要用来实现shift按键以及capslock功能,这部分功能还需要修改android文件系统)
  #if defined(CONFIG_KEYBOARD_PS2KEYBOARD)
  extern int ps2keyboard_get_caps_locking_status(void);
  extern int ps2keyboard_get_key_shift_locking_status(void);
  extern int ps2keyboard_get_key_alt_locking_status(void);
  #endif
 g.make menuconfig添加相关选项编译内核即可

附上驱动源码

imapx200_ps2_keyboard.c

  1. <SPAN style="FONT-SIZE: 16px">#include <linux/init.h>  
  2. #include <linux/module.h>   
  3. #include <linux/types.h>   
  4. #include <linux/fs.h>   
  5. #include <linux/proc_fs.h>   
  6. #include <linux/device.h>   
  7. #include <asm/uaccess.h>   
  8. #include <linux/gpio.h>   
  9. #include <linux/platform_device.h>   
  10. #include <linux/interrupt.h>   
  11. #include <asm/io.h>   
  12. #include <asm/irq.h>   
  13. #include <plat/imapx.h>   
  14. #include <linux/delay.h>   
  15. #include <linux/amba/bus.h>   
  16. #include <linux/amba/kmi.h>   
  17. #include <linux/input.h>   
  18. #include <mach/irqs.h>   
  19. #include <mach/imapx_intr.h>   
  20. #include <mach/imapx_sysmgr.h>   
  21. #include "imapx200_ps2_keyboard.h"   
  22.   
  23.   
  24. #define KMI_BASE    (ps2keyboard_dev0->base_reg)   
  25. //static int shift_pressing = 0;   
  26. //static int leftshift_pressing = 0;   
  27. //static int rightshift_pressing = 0;   
  28. //static int leftalt_pressing = 0;   
  29. //static int rightalt_pressing = 0;   
  30.   
  31. static int shift_key_locking = 0;  
  32. static spinlock_t *shift_key_spinlock = NULL;  
  33. static int alt_key_locking = 0;  
  34. static spinlock_t *alt_key_spinlock = NULL;  
  35. static int caps_locking = 0;  
  36. static spinlock_t *caps_spinlock = NULL;  
  37.   
  38.   
  39. static int flags_numlock = 0;  
  40.   
  41.   
  42.   
  43. static void ps2keyboard_tasklet_fuc(unsigned long);  
  44. static DECLARE_TASKLET_DISABLED(ps2keyboard_tasklet, ps2keyboard_tasklet_fuc, 0);  
  45. static DECLARE_TASKLET_DISABLED(hallone_tasklet, hallone_tasklet_fuc, 0);  
  46. //global ps2 keyborad scancode   
  47. static  const struct ps2keyborad_scancode ps2keyborad_scancodes[]={  
  48.     {MAKE_STATE,KEY_ESC,1,0x76,0,0,0,0,0,0,0},   
  49.     {BREAK_STATE,KEY_ESC,2,0xf0,0x76,0,0,0,0,0,0},  
  50.     {MAKE_STATE,KEY_F1,1,0x05,0,0,0,0,0,0,0},   
  51.     {BREAK_STATE,KEY_F1,2,0xf0,0x05,0,0,0,0,0,0},   
  52.     {MAKE_STATE,KEY_F2,1,0x06,0,0,0,0,0,0,0},   
  53.     {BREAK_STATE,KEY_F2,2,0xf0,0x06,0,0,0,0,0,0},   
  54.     {MAKE_STATE,KEY_F3,1,0x04,0,0,0,0,0,0,0},  
  55.     {BREAK_STATE,KEY_F3,2,0xf0,0x04,0,0,0,0,0,0},   
  56.     {MAKE_STATE,KEY_F4,1,0x0c,0,0,0,0,0,0,0},   
  57.     {BREAK_STATE,KEY_F4,2,0xf0,0x0c,0,0,0,0,0,0},   
  58.     {MAKE_STATE,KEY_F5,1,0x03,0,0,0,0,0,0,0},   
  59.     {BREAK_STATE,KEY_F5,2,0xf0,0x03,0,0,0,0,0,0},   
  60.     {MAKE_STATE,KEY_F6,1,0x0b,0,0,0,0,0,0,0},   
  61.     {BREAK_STATE,KEY_F6,2,0xf0,0x0b,0,0,0,0,0,0},  
  62.     {MAKE_STATE,KEY_F7,1,0x83,0,0,0,0,0,0,0},   
  63.     {BREAK_STATE,KEY_F7,2,0xf0,0x83,0,0,0,0,0,0},    
  64.     {MAKE_STATE,KEY_F8,1,0x0a,0,0,0,0,0,0,0},   
  65.     {BREAK_STATE,KEY_F8,2,0xf0,0x0a,0,0,0,0,0,0},   
  66.     {MAKE_STATE,KEY_VOLUMEDOWN,1,0x1,0,0,0,0,0,0,0},   
  67.     {BREAK_STATE,KEY_VOLUMEDOWN,2,0xf0,0x1,0,0,0,0,0,0},    
  68.     {MAKE_STATE,KEY_VOLUMEUP,1,0x9,0,0,0,0,0,0,0},   
  69.     {BREAK_STATE,KEY_VOLUMEUP,2,0xf0,0x9,0,0,0,0,0,0},   
  70.     {MAKE_STATE,KEY_NUMLOCK,1,0x77,0,0,0,0,0,0,0},  
  71.     {BREAK_STATE,KEY_NUMLOCK,2,0xf0,0x77,0,0,0,0,0,0},  
  72.     {MAKE_STATE,KEY_PRINT,4,0xe0,0x12,0xe0,0x7c,0,0,0,0},  //BASE   
  73.     {BREAK_STATE,KEY_PRINT,6,0xe0,0xf0,0x7c,0xe0,0xf0,0x12,0,0},  
  74.     {MAKE_STATE,KEY_PRINT,2,0xe0,0x7C,0,0,0,0,0,0}, //SHIFT/CTRL   
  75.     {BREAK_STATE,KEY_PRINT,3,0xe0,0xf0,0x7c,0,0,0,0,0},  
  76.     {MAKE_STATE,KEY_PRINT,1,0x84,0,0,0,0,0,0,0}, //ALT   
  77.     {BREAK_STATE,KEY_PRINT,2,0xf0,0x84,0,0,0,0,0,0},  
  78.     {MAKE_STATE,KEY_INSERT,2,0xe0,0x2c,0,0,0,0,0,0},  
  79.     {BREAK_STATE,KEY_INSERT,3,0xe0,0xf0,0x2c,0,0,0,0,0},  
  80.     {MAKE_STATE,KEY_DELETE,2,0xe0,0x71,0,0,0,0,0,0},//Base Case Shift+Num   
  81.     {BREAK_STATE,KEY_DELETE,3,0xe0,0xf0,0x71,0,0,0,0,0},  
  82.     {MAKE_STATE,KEY_DELETE,5,0xe0,0xf0,0x12,0xe0,0x71,0,0,0},//Left-Shift   
  83.     {BREAK_STATE,KEY_DELETE,5,0xe0,0xf0,0x71,0xe0,0x12,0,0,0},  
  84.     {MAKE_STATE,KEY_DELETE,5,0xe0,0xf0,0x59,0xe0,0x71,0,0,0}, //Right-Shift   
  85.     {BREAK_STATE,KEY_DELETE,5,0xe0,0xf0,0x71,0xe0,0x59,0,0,0},  
  86.     {MAKE_STATE,KEY_DELETE,4,0xe0,0x12,0xe0,0x71,0,0,0,0},  //Num Lock   
  87.     {BREAK_STATE,KEY_DELETE,6,0xe0,0xf0,0x71,0xe0,0xf0,0x12,0,0},  
  88.   
  89.     {MAKE_STATE,KEY_GRAVE,1,0x0e,0,0,0,0,0,0,0},  
  90.     {BREAK_STATE,KEY_GRAVE,2,0xf0,0x0e,0,0,0,0,0,0},      
  91.     {MAKE_STATE,KEY_1,1,0x16,0,0,0,0,0,0,0},  
  92.     {BREAK_STATE,KEY_1,2,0xf0,0x16,0,0,0,0,0,0},  
  93.     {MAKE_STATE,KEY_2,1,0x1e,0,0,0,0,0,0,0},  
  94.     {BREAK_STATE,KEY_2,2,0xf0,0x1e,0,0,0,0,0,0},  
  95.     {MAKE_STATE,KEY_3,1,0x26,0,0,0,0,0,0,0},  
  96.     {BREAK_STATE,KEY_3,2,0xf0,0x26,0,0,0,0,0,0},  
  97.     {MAKE_STATE,KEY_4,1,0x25,0,0,0,0,0,0,0},  
  98.     {BREAK_STATE,KEY_4,2,0xf0,0x25,0,0,0,0,0,0},  
  99.     {MAKE_STATE,KEY_5,1,0x2e,0,0,0,0,0,0,0},  
  100.     {BREAK_STATE,KEY_5,2,0xf0,0x2e,0,0,0,0,0,0},  
  101.     {MAKE_STATE,KEY_6,1,0x36,0,0,0,0,0,0,0},  
  102.     {BREAK_STATE,KEY_6,2,0xf0,0x36,0,0,0,0,0,0},  
  103.     {MAKE_STATE,KEY_KP7,1,0x6c,0,0,0,0,0,0,0},  
  104.     {BREAK_STATE,KEY_KP7,2,0xf0,0x6c,0,0,0,0,0,0},  
  105.     {MAKE_STATE,KEY_7,1,0x3d,0,0,0,0,0,0,0},  
  106.     {BREAK_STATE,KEY_7,2,0xf0,0x3d,0,0,0,0,0,0},  
  107.     {MAKE_STATE,KEY_KP8,1,0x75,0,0,0,0,0,0,0},  
  108.     {BREAK_STATE,KEY_KP8,2,0xf0,0x75,0,0,0,0,0,0},  
  109.     {MAKE_STATE,KEY_8,1,0x3e,0,0,0,0,0,0,0},  
  110.     {BREAK_STATE,KEY_8,2,0xf0,0x3e,0,0,0,0,0,0},  
  111.     {MAKE_STATE,KEY_KP9,1,0x7d,0,0,0,0,0,0,0},  
  112.     {BREAK_STATE,KEY_KP9,2,0xf0,0x7d,0,0,0,0,0,0},  
  113.     {MAKE_STATE,KEY_9,1,0x46,0,0,0,0,0,0,0},  
  114.     {BREAK_STATE,KEY_9,2,0xf0,0x46,0,0,0,0,0,0},  
  115.     {MAKE_STATE,KEY_0,1,0x7c,0,0,0,0,0,0,0},  
  116.     {BREAK_STATE,KEY_0,2,0xf0,0x7c,0,0,0,0,0,0},  
  117.     {MAKE_STATE,KEY_0,1,0x45,0,0,0,0,0,0,0},  
  118.     {BREAK_STATE,KEY_0,2,0xf0,0x45,0,0,0,0,0,0},  
  119.     {MAKE_STATE,KEY_MINUS,1,0x4e,0,0,0,0,0,0,0},  
  120.     {BREAK_STATE,KEY_MINUS,2,0xf0,0x4e,0,0,0,0,0,0},  
  121.     {MAKE_STATE,KEY_BACKSPACE,1,0x66,0,0,0,0,0,0,0},  
  122.     {BREAK_STATE,KEY_BACKSPACE,2,0xf0,0x66,0,0,0,0,0,0},  
  123.   
  124.     {MAKE_STATE,KEY_TAB,1,0x0d,0,0,0,0,0,0,0},  
  125.     {BREAK_STATE,KEY_TAB,2,0xf0,0x0d,0,0,0,0,0,0},  
  126.     {MAKE_STATE,KEY_Q,1,0x15,0,0,0,0,0,0,0},  
  127.     {BREAK_STATE,KEY_Q,2,0xf0,0x15,0,0,0,0,0,0},  
  128.     {MAKE_STATE,KEY_W,1,0x1d,0,0,0,0,0,0,0},  
  129.     {BREAK_STATE,KEY_W,2,0xf0,0x1d,0,0,0,0,0,0},  
  130.     {MAKE_STATE,KEY_E,1,0x24,0,0,0,0,0,0,0},  
  131.     {BREAK_STATE,KEY_E,2,0xf0,0x24,0,0,0,0,0,0},  
  132.     {MAKE_STATE,KEY_R,1,0x2d,0,0,0,0,0,0,0},  
  133.     {BREAK_STATE,KEY_R,2,0xf0,0x2d,0,0,0,0,0,0},  
  134.     {MAKE_STATE,KEY_T,1,0x2c,0,0,0,0,0,0,0},  
  135.     {BREAK_STATE,KEY_T,2,0xf0,0x2c,0,0,0,0,0,0},  
  136.     {MAKE_STATE,KEY_Y,1,0x35,0,0,0,0,0,0,0},  
  137.     {BREAK_STATE,KEY_Y,2,0xf0,0x35,0,0,0,0,0,0},  
  138.     {MAKE_STATE,KEY_U,1,0x3c,0,0,0,0,0,0,0},  
  139.     {BREAK_STATE,KEY_U,2,0xf0,0x3c,0,0,0,0,0,0},  
  140.     {MAKE_STATE,KEY_I,1,0x43,0,0,0,0,0,0,0},  
  141.     {BREAK_STATE,KEY_I,2,0xf0,0x43,0,0,0,0,0,0},  
  142.     {MAKE_STATE,KEY_O,1,0x44,0,0,0,0,0,0,0},  
  143.     {BREAK_STATE,KEY_O,2,0xf0,0x44,0,0,0,0,0,0},  
  144.     {MAKE_STATE,KEY_P,1,0x4d,0,0,0,0,0,0,0},  
  145.     {BREAK_STATE,KEY_P,2,0xf0,0x4d,0,0,0,0,0,0},  
  146.     {MAKE_STATE,KEY_EQUAL,1,0x55,0,0,0,0,0,0,0},  
  147.     {BREAK_STATE,KEY_EQUAL,2,0xf0,0x55,0,0,0,0,0,0},  
  148.     {MAKE_STATE,KEY_BACKSPACE,1,0x5d,0,0,0,0,0,0,0},  
  149.     {BREAK_STATE,KEY_BACKSPACE,2,0xf0,0x5d,0,0,0,0,0,0},      
  150.   
  151.     {MAKE_STATE,KEY_CAPSLOCK,1,0x58,0,0,0,0,0,0,0},  
  152.     {BREAK_STATE,KEY_CAPSLOCK,2,0xf0,0x58,0,0,0,0,0,0},  
  153.     {MAKE_STATE,KEY_A,1,0x1c,0,0,0,0,0,0,0},  
  154.     {BREAK_STATE,KEY_A,2,0xf0,0x1c,0,0,0,0,0,0},  
  155.     {MAKE_STATE,KEY_S,1,0x1b,0,0,0,0,0,0,0},  
  156.     {BREAK_STATE,KEY_S,2,0xf0,0x1b,0,0,0,0,0,0},  
  157.     {MAKE_STATE,KEY_D,1,0x23,0,0,0,0,0,0,0},  
  158.     {BREAK_STATE,KEY_D,2,0xf0,0x23,0,0,0,0,0,0},  
  159.     {MAKE_STATE,KEY_F,1,0x2b,0,0,0,0,0,0,0},  
  160.     {BREAK_STATE,KEY_F,2,0xf0,0x2b,0,0,0,0,0,0},  
  161.     {MAKE_STATE,KEY_G,1,0x34,0,0,0,0,0,0,0},  
  162.     {BREAK_STATE,KEY_G,2,0xf0,0x34,0,0,0,0,0,0},  
  163.     {MAKE_STATE,KEY_H,1,0x33,0,0,0,0,0,0,0},  
  164.     {BREAK_STATE,KEY_H,2,0xf0,0x33,0,0,0,0,0,0},  
  165.     {MAKE_STATE,KEY_J,1,0x3b,0,0,0,0,0,0,0},  
  166.     {BREAK_STATE,KEY_J,2,0xf0,0x3b,0,0,0,0,0,0},  
  167.     {MAKE_STATE,KEY_K,1,0x42,0,0,0,0,0,0,0},  
  168.     {BREAK_STATE,KEY_K,2,0xf0,0x42,0,0,0,0,0,0},  
  169.     {MAKE_STATE,KEY_L,1,0x4b,0,0,0,0,0,0,0},  
  170.     {BREAK_STATE,KEY_L,2,0xf0,0x4b,0,0,0,0,0,0},      
  171.     {MAKE_STATE,KEY_SEMICOLON,1,0x4c,0,0,0,0,0,0,0},  
  172.     {BREAK_STATE,KEY_SEMICOLON,2,0xf0,0x4c,0,0,0,0,0,0},  
  173.     {MAKE_STATE,KEY_ENTER,1,0x5a,0,0,0,0,0,0,0},  
  174.     {BREAK_STATE,KEY_ENTER,2,0xf0,0x5a,0,0,0,0,0,0},  
  175.     {MAKE_STATE,KEY_ENTER,2,0xe0,0x5a,0,0,0,0,0,0},  
  176.     {BREAK_STATE,KEY_ENTER,3,0xe0,0xf0,0x5a,0,0,0,0,0},  
  177.   
  178.     {MAKE_STATE,KEY_LEFTSHIFT,1,0x12,0,0,0,0,0,0,0},  
  179.     {BREAK_STATE,KEY_LEFTSHIFT,2,0xf0,0x12,0,0,0,0,0,0},  
  180.     {MAKE_STATE,KEY_BACKSPACE,1,0x61,0,0,0,0,0,0,0},  
  181.     {BREAK_STATE,KEY_BACKSPACE,2,0xf0,0x61,0,0,0,0,0,0},  
  182.     {MAKE_STATE,KEY_Z,1,0x1a,0,0,0,0,0,0,0},  
  183.     {BREAK_STATE,KEY_Z,2,0xf0,0x1a,0,0,0,0,0,0},  
  184.     {MAKE_STATE,KEY_X,1,0x22,0,0,0,0,0,0,0},  
  185.     {BREAK_STATE,KEY_X,2,0xf0,0x22,0,0,0,0,0,0},  
  186.     {MAKE_STATE,KEY_C,1,0x21,0,0,0,0,0,0,0},  
  187.     {BREAK_STATE,KEY_C,2,0xf0,0x21,0,0,0,0,0,0},  
  188.     {MAKE_STATE,KEY_V,1,0x2a,0,0,0,0,0,0,0},  
  189.     {BREAK_STATE,KEY_V,2,0xf0,0x2a,0,0,0,0,0,0},  
  190.     {MAKE_STATE,KEY_B,1,0x32,0,0,0,0,0,0,0},  
  191.     {BREAK_STATE,KEY_B,2,0xf0,0x32,0,0,0,0,0,0},  
  192.     {MAKE_STATE,KEY_N,1,0x31,0,0,0,0,0,0,0},  
  193.     {BREAK_STATE,KEY_N,2,0xf0,0x31,0,0,0,0,0,0},  
  194.     {MAKE_STATE,KEY_M,1,0x3a,0,0,0,0,0,0,0},  
  195.     {BREAK_STATE,KEY_M,2,0xf0,0x3a,0,0,0,0,0,0},  
  196.     {MAKE_STATE,KEY_COMMA,1,0x41,0,0,0,0,0,0,0},  
  197.     {BREAK_STATE,KEY_COMMA,2,0xf0,0x41,0,0,0,0,0,0},  
  198.     {MAKE_STATE,KEY_DOT,1,0x49,0,0,0,0,0,0,0},  
  199.     {BREAK_STATE,KEY_DOT,2,0xf0,0x49,0,0,0,0,0,0},  
  200.     {MAKE_STATE,KEY_SLASH,2,0xe0,0x4a,0,0,0,0,0,0},//BASE   
  201.     {BREAK_STATE,KEY_SLASH,3,0xe0,0xf0,0x4a,0,0,0,0,0},  
  202.     {MAKE_STATE,KEY_SLASH,5,0xe0,0xf0,0x12,0xe0,0x4a,0,0,0},//Left-Shift   
  203.     {BREAK_STATE,KEY_SLASH,5,0xe0,0xf0,0x4a,0xe0,0x12,0,0,0},  
  204.     {MAKE_STATE,KEY_SLASH,5,0xe0,0xf0,0x59,0xe0,0x4a,0,0,0},//Right-Shift   
  205.     {BREAK_STATE,KEY_SLASH,5,0xe0,0xf0,0x4a,0xe0,0x59,0,0,0},     
  206.     {MAKE_STATE,KEY_UP,2,0xe0,0x75,0,0,0,0,0,0},  
  207.     {BREAK_STATE,KEY_UP,3,0xe0,0xf0,0x75,0,0,0,0,0},  
  208.     {MAKE_STATE,KEY_UP,5,0xe0,0xf0,0x12,0xe0,0x75,0,0,0},  
  209.     {BREAK_STATE,KEY_UP,5,0xe0,0xf0,0x75,0xe0,0x12,0,0,0},  
  210.     {MAKE_STATE,KEY_UP,5,0xe0,0xf0,0x59,0xe0,0x75,0,0,0},  
  211.     {BREAK_STATE,KEY_UP,5,0xe0,0xf0,0x75,0xe0,0x59,0,0,0},  
  212.     {MAKE_STATE,KEY_UP,4,0xe0,0x12,0xe0,0x75,0,0,0,0},  
  213.     {BREAK_STATE,KEY_UP,6,0xe0,0xf0,0x75,0xe0,0xf0,0x12,0,0},  
  214.     {MAKE_STATE,KEY_RIGHTSHIFT,1,0x59,0,0,0,0,0,0,0},  
  215.     {BREAK_STATE,KEY_RIGHTSHIFT,2,0xf0,0x59,0,0,0,0,0,0},  
  216.   
  217.   
  218.     {MAKE_STATE,KEY_LEFTCTRL,1,0x14,0,0,0,0,0,0,0},  
  219.     {BREAK_STATE,KEY_LEFTCTRL,2,0xf0,0x14,0,0,0,0,0,0},  
  220.     {MAKE_STATE,KEY_F9,2,0xe0,0x1f,0,0,0,0,0,0}, //mp4   
  221.     {BREAK_STATE,KEY_F9,3,0xe0,0xf0,0x1f,0,0,0,0,0},  
  222.     {MAKE_STATE,KEY_LEFTALT,1,0x11,0,0,0,0,0,0,0},//alt   
  223.     {BREAK_STATE,KEY_LEFTALT,2,0xf0,0x11,0,0,0,0,0,0},  
  224.     {MAKE_STATE,KEY_F10,8,0xe1,0x14,0x77,0xe1,0xf0,0x14,0xf0,0x77}, //mp3   
  225.     {BREAK_STATE,KEY_F10,8,0xe1,0x14,0x77,0xe1,0xf0,0x14,0xf0,0x77},  
  226.     {MAKE_STATE,KEY_SPACE,1,0x29,0,0,0,0,0,0,0},//space   
  227.     {BREAK_STATE,KEY_SPACE,2,0xf0,0x29,0,0,0,0,0,0},  
  228.     {MAKE_STATE,KEY_F11,2,0xe0,0x2f,0,0,0,0,0,0},//输入法   
  229.     {BREAK_STATE,KEY_F11,3,0xe0,0xf0,0x2f,0,0,0,0,0},  
  230.     {MAKE_STATE,KEY_LEFTBRACE,1,0x54,0,0,0,0,0,0,0},//{   
  231.     {BREAK_STATE,KEY_LEFTBRACE,2,0xf0,0x54,0,0,0,0,0,0},  
  232.     {MAKE_STATE,KEY_RIGHTBRACE,1,0x5b,0,0,0,0,0,0,0},//}   
  233.     {BREAK_STATE,KEY_RIGHTBRACE,2,0xf0,0x5b,0,0,0,0,0,0},  
  234.     {MAKE_STATE,KEY_APOSTROPHE,1,0x52,0,0,0,0,0,0,0},//,   
  235.     {BREAK_STATE,KEY_APOSTROPHE,2,0xf0,0x52,0,0,0,0,0,0},  
  236.     {MAKE_STATE,KEY_LEFT,2,0xe0,0x6b,0,0,0,0,0,0},  
  237.     {BREAK_STATE,KEY_LEFT,3,0xe0,0xf0,0x6b,0,0,0,0,0},  
  238.     {MAKE_STATE,KEY_LEFT,5,0xe0,0xf0,0x12,0xe0,0x6b,0,0,0},  
  239.     {BREAK_STATE,KEY_LEFT,5,0xe0,0xf0,0x6b,0xe0,0x12,0,0,0},  
  240.     {MAKE_STATE,KEY_LEFT,5,0xe0,0xf0,0x59,0xe0,0x6b,0,0,0},  
  241.     {BREAK_STATE,KEY_LEFT,5,0xe0,0xf0,0x6b,0xe0,0x59,0,0,0},  
  242.     {MAKE_STATE,KEY_LEFT,4,0xe0,0x12,0xe0,0x6b,0,0,0,0},  
  243.     {BREAK_STATE,KEY_LEFT,6,0xe0,0xf0,0x6b,0xe0,0xf0,0x12,0,0},  
  244.     {MAKE_STATE,KEY_DOWN,2,0xe0,0x72,0,0,0,0,0,0},  
  245.     {BREAK_STATE,KEY_DOWN,3,0xe0,0xf0,0x72,0,0,0,0,0},  
  246.     {MAKE_STATE,KEY_DOWN,5,0xe0,0xf0,0x12,0xe0,0x72,0,0,0},  
  247.     {BREAK_STATE,KEY_DOWN,5,0xe0,0xf0,0x72,0xe0,0x12,0,0,0},  
  248.     {MAKE_STATE,KEY_DOWN,5,0xe0,0xf0,0x59,0xe0,0x72,0,0,0},  
  249.     {BREAK_STATE,KEY_DOWN,5,0xe0,0xf0,0x72,0xe0,0x59,0,0,0},  
  250.     {MAKE_STATE,KEY_DOWN,4,0xe0,0x12,0xe0,0x72,0,0,0,0},  
  251.     {BREAK_STATE,KEY_DOWN,6,0xe0,0xf0,0x72,0xe0,0xf0,0x12,0,0},  
  252.     {MAKE_STATE,KEY_RIGHT,2,0xe0,0x74,0,0,0,0,0,0},  
  253.     {BREAK_STATE,KEY_RIGHT,3,0xe0,0xf0,0x74,0,0,0,0,0},  
  254.     {MAKE_STATE,KEY_RIGHT,5,0xe0,0xf0,0x12,0xe0,0x74,0,0,0},  
  255.     {BREAK_STATE,KEY_RIGHT,5,0xe0,0xf0,0x74,0xe0,0x12,0,0,0},  
  256.     {MAKE_STATE,KEY_RIGHT,5,0xe0,0xf0,0x59,0xe0,0x74,0,0,0},  
  257.     {BREAK_STATE,KEY_RIGHT,5,0xe0,0xf0,0x74,0xe0,0x59,0,0,0},  
  258.     {MAKE_STATE,KEY_RIGHT,4,0xe0,0x12,0xe0,0x74,0,0,0,0},  
  259.     {BREAK_STATE,KEY_RIGHT,6,0xe0,0xf0,0x74,0xe0,0xf0,0x12,0,0},  
  260. };  
  261.   
  262. //struct ps2keyboard_dev ps2keyboard_dev0={   
  263. //  .ps2kbdscancodelist=&ps2keyborad_scancodes[0];   
  264. //  .ps2kbdcancodenum=ARRAY_SIZE(ps2keyborad_scancodes);   
  265. //}   
  266.   
  267.   
  268.   
  269.   
  270.   
  271. /* 
  272. static int ps2keyboard_open(struct inode* inode, struct file* filp); 
  273. static int ps2keyboard_release(struct inode* inode, struct file* filp); 
  274. static int ps2keyboard_ioctl(struct inode *inodep, struct file *filp, unsigned int cmd, unsigned long arg); 
  275. static ssize_t ps2keyboard_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos); 
  276. static ssize_t ps2keyboard_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos); 
  277.  
  278.  
  279. static struct file_operations ps2keyboard_fops = { 
  280.     .owner = THIS_MODULE, 
  281.     .open = ps2keyboard_open, 
  282.     .release = ps2keyboard_release, 
  283.     .read = ps2keyboard_read, 
  284.     .write = ps2keyboard_write,  
  285.     .ioctl = ps2keyboard_ioctl, 
  286. }; 
  287.  
  288.  
  289.  
  290.  
  291. static int ps2keyboard_open(struct inode* inode, struct file* filp) { 
  292.     struct ps2keyboard_dev *  dev;         
  293.     dev = container_of(inode->i_cdev, struct ps2keyboard_dev, input); 
  294.     filp->private_data = dev; 
  295.  
  296.     return 0; 
  297. } 
  298.  
  299.  
  300. static int ps2keyboard_release(struct inode* inode, struct file* filp) { 
  301.     struct ps2keyboard_dev* dev = filp->private_data;         
  302.     return 0; 
  303. } 
  304.  
  305. static ssize_t ps2keyboard_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos) { 
  306.     ssize_t err = 0; 
  307.     struct ps2keyboard_dev* dev = filp->private_data;         
  308.     return err; 
  309. } 
  310.  
  311.  
  312. static ssize_t ps2keyboard_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos) { 
  313.     struct ps2keyboard_dev* dev = filp->private_data; 
  314.     ssize_t err = 0;         
  315.     return err; 
  316. } 
  317. static int ps2keyboard_ioctl(struct inode *inodep, struct file *filp, unsigned int cmd, unsigned long arg) 
  318. { 
  319.     struct ps2keyboard_dev* dev = filp->private_data; 
  320.  
  321.     return ioctlreturn; 
  322. } 
  323. */  
  324.   
  325. int ps2keyboard_get_caps_locking_status(void)  
  326. {  
  327.     int status = 0;  
  328.   
  329.     spin_lock(caps_spinlock);  
  330.     status = caps_locking;  
  331.     printk("keyinput_get_caps_locking_status is %d\n",caps_locking);  
  332.     spin_unlock(caps_spinlock);  
  333.   
  334.     return status;  
  335. }  
  336. EXPORT_SYMBOL(ps2keyboard_get_caps_locking_status);  
  337. int ps2keyboard_get_key_shift_locking_status(void)  
  338. {  
  339.     int status = 0;  
  340.     spin_lock(shift_key_spinlock);  
  341.     status = shift_key_locking;  
  342.     spin_unlock(shift_key_spinlock);  
  343.   
  344.     return status;  
  345. }  
  346. EXPORT_SYMBOL(ps2keyboard_get_key_shift_locking_status);  
  347. int ps2keyboard_get_key_alt_locking_status(void)  
  348. {  
  349.     int status = 0;  
  350.     spin_lock(alt_key_spinlock);  
  351.     status = alt_key_locking;  
  352.     spin_unlock(alt_key_spinlock);  
  353.            
  354.         return status;  
  355. }  
  356. EXPORT_SYMBOL(ps2keyboard_get_key_alt_locking_status);  
  357.   
  358.   
  359.   
  360.   
  361. //ps2 keyboard interrupt thread   
  362. static irqreturn_t ps2keyboard_isr(int irq, void *dev_id)  
  363. {  
  364.     struct ps2keyboard_dev *ps2keyboard_dev0 = dev_id;  
  365.     unsigned int status = readb(KMIIR);  
  366.     int handled = IRQ_NONE;  
  367.     unsigned char readdata;  
  368.     ps2keyboard_dev0->pscancode=kmalloc(sizeof(struct scancode),GFP_KERNEL);     
  369.     if(ps2keyboard_dev0->pscancode==NULL)  
  370.     {     
  371.         printk("ps2keyboard_isr error kmalloc\n");  
  372.         handled = IRQ_HANDLED;  
  373.         goto _return_;  
  374.     }  
  375.     printk("---------\n");  
  376.     memset(ps2keyboard_dev0->pscancode,0,sizeof(struct scancode));   
  377.     while (status & KMIIR_RXINTR) {  
  378.         ps2keyboard_dev0->pscancode->scancode[ps2keyboard_dev0->pscancode->num]=readb(KMIDATA);  
  379.         printk("%x\n",ps2keyboard_dev0->pscancode->scancode[ps2keyboard_dev0->pscancode->num]);  
  380.         ps2keyboard_dev0->pscancode->num++;  
  381.         status = readb(KMIIR);  
  382.         handled = IRQ_HANDLED;  
  383.     }  
  384.     printk("n1=%d\n",ps2keyboard_dev0->pscancode->num);  
  385.     //add key scancode to ps2keyboard_dev0list   
  386.     list_add_tail(&ps2keyboard_dev0->pscancode->list, &ps2keyboard_dev0->keyscancode_list);     
  387.     tasklet_schedule(&ps2keyboard_tasklet);  
  388. _return_:  
  389.     return handled;  
  390. }  
  391.   
  392. static void ps2keyboard_tasklet_fuc(unsigned long data)  
  393. {  
  394.     int i,l;  
  395.     struct scancode *pscancode;  
  396.     struct ps2keyboard_dev *ps2keyboard_dev0 = (struct ps2keyboard_dev *) data;  
  397.     printk("ps2keyboard_tasklet_fuc\n");  
  398.     if(!list_empty(&ps2keyboard_dev0->keyscancode_list))  
  399.     {  
  400.         pscancode=list_first_entry(&ps2keyboard_dev0->keyscancode_list,struct scancode,list);  
  401.           
  402.         for(i=0;i<pscancode->num;i++)  
  403.             printk("%x\n",pscancode->scancode[i]);  
  404.         printk("n2=%d\n",pscancode->num);  
  405.         for(i=0;i<ps2keyboard_dev0->ps2kbdcancodenum;i++)  
  406.         {  
  407.             /* 
  408.             for(l=0;l<8;l++) 
  409.             { 
  410.                 if(ps2keyboard_dev0->ps2kbdscancodelist[i].code[l]!=pscancode->scancode[l]) 
  411.                     break; 
  412.             } 
  413.             if(l==8) 
  414.             { 
  415.                 printk("i==%d\n",i); 
  416.                 break; 
  417.             }*/   
  418.             if(!memcmp(ps2keyboard_dev0->ps2kbdscancodelist[i].code,pscancode->scancode,8))  
  419.             {  
  420.                 printk("i==%d\n",i);  
  421.                 if(KEY_LEFTALT==ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue||KEY_RIGHTALT==ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue){  
  422.                     spin_lock(alt_key_spinlock);  
  423.                     if (ps2keyboard_dev0->ps2kbdscancodelist[i].makeorbreak==MAKE_STATE ) {  
  424.                         alt_key_locking = 1;  
  425.                     } else if (alt_key_locking) {  
  426.                         alt_key_locking = 0;  
  427.                     }  
  428.                     spin_unlock(alt_key_spinlock);  
  429.                 }  
  430.                 else if(KEY_LEFTSHIFT==ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue||KEY_RIGHTSHIFT==ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue){  
  431.                     spin_lock(shift_key_spinlock);  
  432.                     if (ps2keyboard_dev0->ps2kbdscancodelist[i].makeorbreak==MAKE_STATE ) {  
  433.                         shift_key_locking = 1;  
  434.                     } else if (shift_key_locking) {  
  435.                         shift_key_locking = 0;  
  436.                     }  
  437.                     spin_unlock(shift_key_spinlock);  
  438.                 }  
  439.                 else if (KEY_CAPSLOCK==ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue&&ps2keyboard_dev0->ps2kbdscancodelist[i].makeorbreak==BREAK_STATE){  
  440.                     spin_lock(caps_spinlock);  
  441.                     if(caps_locking==1){  
  442.                             caps_locking = 0;  
  443.                                printk(KERN_ALERT "Capslock is disabled.\n");   
  444.                         } else {  
  445.                                caps_locking = 1;  
  446.                             printk(KERN_ALERT "Capslock is enabled.\n");  
  447.                     }  
  448.                     spin_unlock(caps_spinlock);  
  449.                 }  
  450.                 if(ps2keyboard_dev0->ps2kbdscancodelist[i].makeorbreak==MAKE_STATE)  
  451.                     input_event(ps2keyboard_dev0->input, EV_KEY, ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue, 1);  
  452.                 else  
  453.                     input_event(ps2keyboard_dev0->input, EV_KEY, ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue, 0);  
  454.                 break;   
  455.             }  
  456.         }  
  457.         list_del_init(&pscancode->list);  
  458.         kfree(pscancode);  
  459.     }  
  460.   
  461.     //input_event(ps2keyboard_dev0->input, EV_KEY, KEY_1, 1);   
  462.     //input_event(ps2keyboard_dev0->input, EV_KEY, KEY_1, 0);   
  463.   
  464.     /* 
  465.     ps2keyboard_dev0->keyhead=ps2keyboard_dev0->keytail=0; 
  466.     memset(ps2keyboard_dev0->keybuffer,0,MAX_KEY_NUM); 
  467.     if(ps2keyboard_dev0->outindex!=ps2keyboard_dev0->inindex) 
  468.     { 
  469.          
  470.         for(i=0;i<ps2keyboard_dev0->ps2kbdcancodenum;i++) 
  471.         { 
  472.             if(!memcmp(ps2keyboard_dev0->ps2kbdscancodelist[i].code,ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].scancode,ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].readdatalentg)) 
  473.             { 
  474.                 if(ps2keyboard_dev0->ps2kbdscancodelist[i].makeorbreak==MAKE_STATE) 
  475.                 { 
  476.                     //printk("\n"); 
  477.                     for(l=0;l<ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].readdatalentg;l++) 
  478.                         printk("%x\n",ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].scancode[l]); 
  479.                     input_event(ps2keyboard_dev0->input, EV_KEY, ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue, 1); 
  480.                 } 
  481.                 else 
  482.                 { 
  483.                     //printk("\n"); 
  484.                     input_event(ps2keyboard_dev0->input, EV_KEY, ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue, 0); 
  485.                     for(l=0;l<ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].readdatalentg;l++) 
  486.                         printk("%x\n",ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].scancode[l]); 
  487.                 } 
  488.                 memset(ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].scancode,0,8); 
  489.                 ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].readdatalentg=0; 
  490.             } 
  491.         } 
  492.         ps2keyboard_dev0->outindex=(ps2keyboard_dev0->outindex+1)%MAX_KEY_BUFFERNUM; 
  493.     } 
  494.     */  
  495. }  
  496.   
  497.   
  498. static irqreturn_t hallone_isr(int irq, void *dev_id)  
  499. {  
  500.     struct ps2keyboard_dev *ps2keyboard_dev0 = dev_id;  
  501.     tasklet_schedule(&hallone_tasklet);  
  502.     return IRQ_HANDLED;  
  503. }  
  504.   
  505. static void hallone_tasklet_fuc(unsigned long data)  
  506. {  
  507.     struct ps2keyboard_dev *ps2keyboard_dev0 = (struct ps2keyboard_dev *) data;  
  508.     printk("---------------hallone_tasklet_fuc----------------\n");  
  509.     input_event(ps2keyboard_dev0->input, EV_KEY, KEY_1, 1);  
  510.     input_event(ps2keyboard_dev0->input, EV_KEY, KEY_1, 0);  
  511. }  
  512.   
  513. static irqreturn_t halltwo_isr(int irq, void *dev_id)  
  514. {  
  515.     struct ps2keyboard_dev *ps2keyboard_dev0 = dev_id;  
  516.     int handled = IRQ_HANDLED;  
  517.     printk("---------------irqreturn_t halltwo_isr----------------\n");  
  518.     input_event(ps2keyboard_dev0->input, EV_KEY, KEY_2, 1);  
  519.     input_event(ps2keyboard_dev0->input, EV_KEY, KEY_2, 0);  
  520.     //input_sync(ps2keyboard_dev0->input);   
  521. _return_:  
  522.     return handled;  
  523. }  
  524. static int ps2keyboard_probe(struct platform_device *pdev){  
  525.     struct ps2keyboard_dev *ps2keyboard_dev0;  
  526.     struct input_dev *input;  
  527.     struct resource *res;  
  528.     int i,error,ret;  
  529.     printk("---------------ps2keyboard_probe----------------\n");  
  530.     ps2keyboard_dev0 = kzalloc(sizeof(struct ps2keyboard_dev), GFP_KERNEL);  
  531.     if (!ps2keyboard_dev0) {  
  532.         dev_err(&pdev->dev, "No memory for ps2keyboard_dev0\n");  
  533.         return -ENOMEM;  
  534.     }  
  535.     input = input_allocate_device();  
  536.     if (!input) {  
  537.         printk("ps2keyboard allocate input device failed.\n");  
  538.         return -ENOMEM;  
  539.     }  
  540.     ps2keyboard_dev0->ps2kbdscancodelist=&ps2keyborad_scancodes[0];  
  541.     ps2keyboard_dev0->ps2kbdcancodenum=ARRAY_SIZE(ps2keyborad_scancodes);  
  542.     for(i=0;i<ps2keyboard_dev0->ps2kbdcancodenum;i+=2)  
  543.         input_set_capability(input, EV_KEY, ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue);  
  544.     input->name = "ps2keyboard";  
  545.     input->phys = "ps2keyboard/input0";  
  546.     input->dev.parent = &pdev->dev;  
  547.     input->id.bustype = BUS_HOST;  
  548.     input->id.vendor = 0x0001;  
  549.     input->id.product = 0x0001;  
  550.     input->id.version = 0x0100;  
  551.     ps2keyboard_dev0->input = input;  
  552.     error = input_register_device(input);  
  553.     if (error) {  
  554.         printk("ps2keyboard: Unable to register input device, ""error: %d\n", error);  
  555.         goto __fail_exit__;  
  556.     }  
  557.     ps2keyboard_dev0->gpio_capslock=__imapx_name_to_gpio(CONFIG_PS2KEYBOARD_LED_CAPSLOCK);  
  558.     ps2keyboard_dev0->gpio_numlock=__imapx_name_to_gpio(CONFIG_PS2KEYBOARD_LED_NUMLOCK);  
  559.     ps2keyboard_dev0->gpio_hallone=__imapx_name_to_gpio(CONFIG_PS2KEYBOARD_HALLONE);  
  560.     ps2keyboard_dev0->gpio_halltwo=__imapx_name_to_gpio(CONFIG_PS2KEYBOARD_HALLTWO);  
  561.     ps2keyboard_dev0->gpio_halloneirq= imapx_gpio_to_irq(ps2keyboard_dev0->gpio_hallone);  
  562.     ps2keyboard_dev0->gpio_halltwoirq= imapx_gpio_to_irq(ps2keyboard_dev0->gpio_halltwo);  
  563.     imapx_gpio_setcfg(ps2keyboard_dev0->gpio_hallone, IG_INPUT, IG_NORMAL);  
  564.     imapx_gpio_setirq(ps2keyboard_dev0->gpio_hallone, FILTER_MAX, IG_FALL, 1);  
  565.     imapx_gpio_setcfg(ps2keyboard_dev0->gpio_halltwo, IG_INPUT, IG_NORMAL);  
  566.     imapx_gpio_setirq(ps2keyboard_dev0->gpio_halltwo, FILTER_MAX, IG_FALL, 1);  
  567.     ret = request_irq(ps2keyboard_dev0->gpio_halloneirq, hallone_isr, IRQF_DISABLED,dev_name(&pdev->dev), ps2keyboard_dev0);  
  568.     if (ret != 0) {  
  569.         dev_err(&pdev->dev, "cannot claim hallone IRQ %d\n", ps2keyboard_dev0->irq);  
  570.         goto _err_iomap_;  
  571.     }  
  572.     //ret = request_irq(ps2keyboard_dev0->gpio_halltwoirq, halltwo_isr, IRQF_DISABLED,dev_name(&pdev->dev), ps2keyboard_dev0);   
  573.     //if (ret != 0) {   
  574.     //  dev_err(&pdev->dev, "cannot claim halltwo IRQ %d\n", ps2keyboard_dev0->irq);   
  575.     //  goto _err_iomap_;   
  576.     //}   
  577.   
  578.     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  
  579.     if (res == NULL) {  
  580.         dev_err(&pdev->dev, "cannot find IO resource\n");  
  581.         ret = -ENOENT;  
  582.         goto __fail_exit__;  
  583.     }  
  584.     ps2keyboard_dev0->ioarea = request_mem_region(res->start, resource_size(res),pdev->name);  
  585.     if (ps2keyboard_dev0->ioarea == NULL) {  
  586.         dev_err(&pdev->dev, "cannot request IO\n");  
  587.         ret = -ENXIO;  
  588.         goto __fail_exit__;  
  589.     }  
  590.     ps2keyboard_dev0->base_reg = ioremap(res->start, resource_size(res));  
  591.     if (ps2keyboard_dev0->base_reg == NULL) {  
  592.         dev_err(&pdev->dev, "cannot map IO\n");  
  593.         ret = -ENXIO;  
  594.         goto _err_ioarea_;  
  595.     }  
  596.     printk("registers %p (%p, %p)\n",ps2keyboard_dev0->base_reg,ps2keyboard_dev0->ioarea, res);  
  597.     ps2keyboard_dev0->irq = ret = platform_get_irq(pdev, 0);  
  598.     if (ret <= 0) {  
  599.         dev_err(&pdev->dev, "cannot find IRQ\n");  
  600.         goto _err_iomap_;  
  601.     }  
  602.     //ps2keyboard_dev0->inindex=ps2keyboard_dev0->outindex=0;   
  603.     //for(i=0;i<MAX_KEY_BUFFERNUM;i++)   
  604.     //{   
  605.     //  memset(ps2keyboard_dev0->keybuffer[i].scancode,0,8);   
  606.     //  ps2keyboard_dev0->keybuffer[i].readdatalentg=0;   
  607.     //}   
  608.     //init list_head list   
  609.     INIT_LIST_HEAD(&ps2keyboard_dev0->keyscancode_list);  
  610.     ret = request_irq(ps2keyboard_dev0->irq, ps2keyboard_isr, IRQF_DISABLED,  
  611.               dev_name(&pdev->dev), ps2keyboard_dev0);  
  612.   
  613.     if (ret != 0) {  
  614.         dev_err(&pdev->dev, "cannot claim IRQ %d\n", ps2keyboard_dev0->irq);  
  615.         goto _err_iomap_;  
  616.     }  
  617.     writeb(0xF, KMICLKDIV);  
  618.     writeb(KMICR_EN, KMICR);  
  619.     imapx_gpio_setcfg(IMAPX_GPC_RANGE(4, 7), IG_CTRL0, IG_NORMAL);  
  620.     writeb(KMICR_EN | KMICR_RXINTREN, KMICR);  
  621.     platform_set_drvdata(pdev, ps2keyboard_dev0);  
  622.       
  623.     tasklet_enable(&ps2keyboard_tasklet);  
  624.     ps2keyboard_tasklet.data = (unsigned long) ps2keyboard_dev0;  
  625.   
  626.     tasklet_enable(&hallone_tasklet);  
  627.     hallone_tasklet.data = (unsigned long) ps2keyboard_dev0;  
  628.   
  629.     if (caps_spinlock == NULL) {  
  630.         caps_spinlock = (spinlock_t *)kmalloc(sizeof(spinlock_t), GFP_KERNEL);  
  631.         if (caps_spinlock == NULL) {  
  632.             printk("ps2keyboard_probe:kmalloc() for capslock key spinlock error.\n");  
  633.             goto _err_iomap_;  
  634.         }  
  635.         spin_lock_init(caps_spinlock);  
  636.     }  
  637.     if (shift_key_spinlock ==NULL) {  
  638.         shift_key_spinlock = (spinlock_t *)kmalloc(sizeof(spinlock_t), GFP_KERNEL);  
  639.         if (shift_key_spinlock == NULL) {  
  640.             printk(KERN_ERR "ps2keyboard_probe:kmalloc() for shift key spinlock error.\n");  
  641.             goto _err_iomap_;  
  642.         }  
  643.         spin_lock_init(shift_key_spinlock);  
  644.     }  
  645.     if (alt_key_spinlock ==NULL){  
  646.         alt_key_spinlock = (spinlock_t *)kmalloc(sizeof(spinlock_t), GFP_KERNEL);  
  647.         if (alt_key_spinlock == NULL) {  
  648.             printk(KERN_ERR "ps2keyboard_probe:kmalloc() for alt key spinlock error.\n");  
  649.             goto _err_iomap_;  
  650.         }  
  651.             spin_lock_init(alt_key_spinlock);  
  652.     }  
  653.       
  654.     return 0;  
  655.  _err_iomap_:  
  656.     iounmap(ps2keyboard_dev0->base_reg);  
  657.  _err_ioarea_:  
  658.     release_resource(ps2keyboard_dev0->ioarea);  
  659.     kfree(ps2keyboard_dev0->ioarea);   
  660. __fail_exit__:  
  661.     input_free_device(input);  
  662.     return ret;  
  663. }  
  664.   
  665. static int __devexit ps2keyboard_remove(struct platform_device *pdev){  
  666.     struct ps2keyboard_dev *ps2keyboard_dev0=platform_get_drvdata(pdev);  
  667.     input_unregister_device(ps2keyboard_dev0->input);  
  668.     free_irq(ps2keyboard_dev0->irq, ps2keyboard_dev0);  
  669.     free_irq(ps2keyboard_dev0->gpio_halloneirq, ps2keyboard_dev0);  
  670.     free_irq(ps2keyboard_dev0->gpio_halltwoirq, ps2keyboard_dev0);  
  671.     iounmap(ps2keyboard_dev0->base_reg);  
  672.     release_resource(ps2keyboard_dev0->ioarea);  
  673.     kfree(ps2keyboard_dev0->ioarea);  
  674.     tasklet_disable(&ps2keyboard_tasklet);  
  675.     tasklet_kill(&ps2keyboard_tasklet);  
  676.     tasklet_disable(&hallone_tasklet);  
  677.     tasklet_kill(&hallone_tasklet);  
  678.     return 0;  
  679. }  
  680.   
  681.   
  682. #ifdef CONFIG_PM   
  683. static int ps2keyboard_suspend(struct platform_device *pdev, pm_message_t state)   
  684. {  
  685.     struct ps2keyboard_dev *ps2keyboard_dev0=platform_get_drvdata(pdev);  
  686.     return 0;  
  687. }  
  688.   
  689. static int ps2keyboard_resume(struct platform_device *pdev)   
  690. {  
  691.     struct ps2keyboard_dev *ps2keyboard_dev0=platform_get_drvdata(pdev);  
  692.     return 0;  
  693. }  
  694. #else   
  695. #define ps2keyboard_suspend NULL   
  696. #define ps2keyboard_resume  NULL   
  697. #endif   
  698.   
  699. static struct platform_driver ps2keyboard_driver = {  
  700.     .probe      = ps2keyboard_probe,  
  701.     .remove     = __devexit_p(ps2keyboard_remove),  
  702.     .suspend        = ps2keyboard_suspend,  
  703.     .resume     = ps2keyboard_resume,  
  704.     .driver     = {  
  705.         .name   = "ps2keyboard",  
  706.         .owner  = THIS_MODULE,  
  707.     },  
  708. };  
  709.   
  710. static int __init ps2keyboard_init(void){   
  711.     printk("---------------ps2keyboard_init----------------\n");  
  712.     return platform_driver_register(&ps2keyboard_driver);  
  713. }  
  714.   
  715. static void __exit ps2keyboard_exit(void) {  
  716.     printk("---------------ps2keyboard_exit----------------\n");  
  717.     platform_driver_unregister(&ps2keyboard_driver);  
  718. }  
  719.   
  720. module_init(ps2keyboard_init);  
  721. module_exit(ps2keyboard_exit);  
  722. MODULE_DESCRIPTION("PS2Keyboard's Android Driver");  
  723. MODULE_LICENSE("GPL");  
  724.   
  725. imapx200_ps2_keyboard.h</SPAN>  
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <plat/imapx.h>
#include <linux/delay.h>
#include <linux/amba/bus.h>
#include <linux/amba/kmi.h>
#include <linux/input.h>
#include <mach/irqs.h>
#include <mach/imapx_intr.h>
#include <mach/imapx_sysmgr.h>
#include "imapx200_ps2_keyboard.h"


#define KMI_BASE	(ps2keyboard_dev0->base_reg)
//static int shift_pressing = 0;
//static int leftshift_pressing = 0;
//static int rightshift_pressing = 0;
//static int leftalt_pressing = 0;
//static int rightalt_pressing = 0;

static int shift_key_locking = 0;
static spinlock_t *shift_key_spinlock = NULL;
static int alt_key_locking = 0;
static spinlock_t *alt_key_spinlock = NULL;
static int caps_locking = 0;
static spinlock_t *caps_spinlock = NULL;


static int flags_numlock = 0;



static void ps2keyboard_tasklet_fuc(unsigned long);
static DECLARE_TASKLET_DISABLED(ps2keyboard_tasklet, ps2keyboard_tasklet_fuc, 0);
static DECLARE_TASKLET_DISABLED(hallone_tasklet, hallone_tasklet_fuc, 0);
//global ps2 keyborad scancode
static  const struct ps2keyborad_scancode ps2keyborad_scancodes[]={
	{MAKE_STATE,KEY_ESC,1,0x76,0,0,0,0,0,0,0}, 
	{BREAK_STATE,KEY_ESC,2,0xf0,0x76,0,0,0,0,0,0},
	{MAKE_STATE,KEY_F1,1,0x05,0,0,0,0,0,0,0}, 
	{BREAK_STATE,KEY_F1,2,0xf0,0x05,0,0,0,0,0,0}, 
	{MAKE_STATE,KEY_F2,1,0x06,0,0,0,0,0,0,0}, 
	{BREAK_STATE,KEY_F2,2,0xf0,0x06,0,0,0,0,0,0}, 
	{MAKE_STATE,KEY_F3,1,0x04,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_F3,2,0xf0,0x04,0,0,0,0,0,0}, 
	{MAKE_STATE,KEY_F4,1,0x0c,0,0,0,0,0,0,0}, 
	{BREAK_STATE,KEY_F4,2,0xf0,0x0c,0,0,0,0,0,0}, 
	{MAKE_STATE,KEY_F5,1,0x03,0,0,0,0,0,0,0}, 
	{BREAK_STATE,KEY_F5,2,0xf0,0x03,0,0,0,0,0,0}, 
	{MAKE_STATE,KEY_F6,1,0x0b,0,0,0,0,0,0,0}, 
	{BREAK_STATE,KEY_F6,2,0xf0,0x0b,0,0,0,0,0,0},
	{MAKE_STATE,KEY_F7,1,0x83,0,0,0,0,0,0,0}, 
	{BREAK_STATE,KEY_F7,2,0xf0,0x83,0,0,0,0,0,0},  
	{MAKE_STATE,KEY_F8,1,0x0a,0,0,0,0,0,0,0}, 
	{BREAK_STATE,KEY_F8,2,0xf0,0x0a,0,0,0,0,0,0}, 
	{MAKE_STATE,KEY_VOLUMEDOWN,1,0x1,0,0,0,0,0,0,0}, 
	{BREAK_STATE,KEY_VOLUMEDOWN,2,0xf0,0x1,0,0,0,0,0,0},  
	{MAKE_STATE,KEY_VOLUMEUP,1,0x9,0,0,0,0,0,0,0}, 
	{BREAK_STATE,KEY_VOLUMEUP,2,0xf0,0x9,0,0,0,0,0,0}, 
	{MAKE_STATE,KEY_NUMLOCK,1,0x77,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_NUMLOCK,2,0xf0,0x77,0,0,0,0,0,0},
	{MAKE_STATE,KEY_PRINT,4,0xe0,0x12,0xe0,0x7c,0,0,0,0},  //BASE
	{BREAK_STATE,KEY_PRINT,6,0xe0,0xf0,0x7c,0xe0,0xf0,0x12,0,0},
	{MAKE_STATE,KEY_PRINT,2,0xe0,0x7C,0,0,0,0,0,0}, //SHIFT/CTRL
	{BREAK_STATE,KEY_PRINT,3,0xe0,0xf0,0x7c,0,0,0,0,0},
	{MAKE_STATE,KEY_PRINT,1,0x84,0,0,0,0,0,0,0}, //ALT
	{BREAK_STATE,KEY_PRINT,2,0xf0,0x84,0,0,0,0,0,0},
	{MAKE_STATE,KEY_INSERT,2,0xe0,0x2c,0,0,0,0,0,0},
	{BREAK_STATE,KEY_INSERT,3,0xe0,0xf0,0x2c,0,0,0,0,0},
	{MAKE_STATE,KEY_DELETE,2,0xe0,0x71,0,0,0,0,0,0},//Base Case Shift+Num
	{BREAK_STATE,KEY_DELETE,3,0xe0,0xf0,0x71,0,0,0,0,0},
	{MAKE_STATE,KEY_DELETE,5,0xe0,0xf0,0x12,0xe0,0x71,0,0,0},//Left-Shift
	{BREAK_STATE,KEY_DELETE,5,0xe0,0xf0,0x71,0xe0,0x12,0,0,0},
	{MAKE_STATE,KEY_DELETE,5,0xe0,0xf0,0x59,0xe0,0x71,0,0,0}, //Right-Shift
	{BREAK_STATE,KEY_DELETE,5,0xe0,0xf0,0x71,0xe0,0x59,0,0,0},
	{MAKE_STATE,KEY_DELETE,4,0xe0,0x12,0xe0,0x71,0,0,0,0},  //Num Lock
	{BREAK_STATE,KEY_DELETE,6,0xe0,0xf0,0x71,0xe0,0xf0,0x12,0,0},

	{MAKE_STATE,KEY_GRAVE,1,0x0e,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_GRAVE,2,0xf0,0x0e,0,0,0,0,0,0},	
	{MAKE_STATE,KEY_1,1,0x16,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_1,2,0xf0,0x16,0,0,0,0,0,0},
	{MAKE_STATE,KEY_2,1,0x1e,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_2,2,0xf0,0x1e,0,0,0,0,0,0},
	{MAKE_STATE,KEY_3,1,0x26,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_3,2,0xf0,0x26,0,0,0,0,0,0},
	{MAKE_STATE,KEY_4,1,0x25,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_4,2,0xf0,0x25,0,0,0,0,0,0},
	{MAKE_STATE,KEY_5,1,0x2e,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_5,2,0xf0,0x2e,0,0,0,0,0,0},
	{MAKE_STATE,KEY_6,1,0x36,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_6,2,0xf0,0x36,0,0,0,0,0,0},
	{MAKE_STATE,KEY_KP7,1,0x6c,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_KP7,2,0xf0,0x6c,0,0,0,0,0,0},
	{MAKE_STATE,KEY_7,1,0x3d,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_7,2,0xf0,0x3d,0,0,0,0,0,0},
	{MAKE_STATE,KEY_KP8,1,0x75,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_KP8,2,0xf0,0x75,0,0,0,0,0,0},
	{MAKE_STATE,KEY_8,1,0x3e,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_8,2,0xf0,0x3e,0,0,0,0,0,0},
	{MAKE_STATE,KEY_KP9,1,0x7d,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_KP9,2,0xf0,0x7d,0,0,0,0,0,0},
	{MAKE_STATE,KEY_9,1,0x46,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_9,2,0xf0,0x46,0,0,0,0,0,0},
	{MAKE_STATE,KEY_0,1,0x7c,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_0,2,0xf0,0x7c,0,0,0,0,0,0},
	{MAKE_STATE,KEY_0,1,0x45,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_0,2,0xf0,0x45,0,0,0,0,0,0},
	{MAKE_STATE,KEY_MINUS,1,0x4e,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_MINUS,2,0xf0,0x4e,0,0,0,0,0,0},
	{MAKE_STATE,KEY_BACKSPACE,1,0x66,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_BACKSPACE,2,0xf0,0x66,0,0,0,0,0,0},

	{MAKE_STATE,KEY_TAB,1,0x0d,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_TAB,2,0xf0,0x0d,0,0,0,0,0,0},
	{MAKE_STATE,KEY_Q,1,0x15,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_Q,2,0xf0,0x15,0,0,0,0,0,0},
	{MAKE_STATE,KEY_W,1,0x1d,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_W,2,0xf0,0x1d,0,0,0,0,0,0},
	{MAKE_STATE,KEY_E,1,0x24,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_E,2,0xf0,0x24,0,0,0,0,0,0},
	{MAKE_STATE,KEY_R,1,0x2d,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_R,2,0xf0,0x2d,0,0,0,0,0,0},
	{MAKE_STATE,KEY_T,1,0x2c,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_T,2,0xf0,0x2c,0,0,0,0,0,0},
	{MAKE_STATE,KEY_Y,1,0x35,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_Y,2,0xf0,0x35,0,0,0,0,0,0},
	{MAKE_STATE,KEY_U,1,0x3c,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_U,2,0xf0,0x3c,0,0,0,0,0,0},
	{MAKE_STATE,KEY_I,1,0x43,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_I,2,0xf0,0x43,0,0,0,0,0,0},
	{MAKE_STATE,KEY_O,1,0x44,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_O,2,0xf0,0x44,0,0,0,0,0,0},
	{MAKE_STATE,KEY_P,1,0x4d,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_P,2,0xf0,0x4d,0,0,0,0,0,0},
	{MAKE_STATE,KEY_EQUAL,1,0x55,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_EQUAL,2,0xf0,0x55,0,0,0,0,0,0},
	{MAKE_STATE,KEY_BACKSPACE,1,0x5d,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_BACKSPACE,2,0xf0,0x5d,0,0,0,0,0,0},	

	{MAKE_STATE,KEY_CAPSLOCK,1,0x58,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_CAPSLOCK,2,0xf0,0x58,0,0,0,0,0,0},
	{MAKE_STATE,KEY_A,1,0x1c,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_A,2,0xf0,0x1c,0,0,0,0,0,0},
	{MAKE_STATE,KEY_S,1,0x1b,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_S,2,0xf0,0x1b,0,0,0,0,0,0},
	{MAKE_STATE,KEY_D,1,0x23,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_D,2,0xf0,0x23,0,0,0,0,0,0},
	{MAKE_STATE,KEY_F,1,0x2b,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_F,2,0xf0,0x2b,0,0,0,0,0,0},
	{MAKE_STATE,KEY_G,1,0x34,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_G,2,0xf0,0x34,0,0,0,0,0,0},
	{MAKE_STATE,KEY_H,1,0x33,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_H,2,0xf0,0x33,0,0,0,0,0,0},
	{MAKE_STATE,KEY_J,1,0x3b,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_J,2,0xf0,0x3b,0,0,0,0,0,0},
	{MAKE_STATE,KEY_K,1,0x42,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_K,2,0xf0,0x42,0,0,0,0,0,0},
	{MAKE_STATE,KEY_L,1,0x4b,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_L,2,0xf0,0x4b,0,0,0,0,0,0},	
	{MAKE_STATE,KEY_SEMICOLON,1,0x4c,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_SEMICOLON,2,0xf0,0x4c,0,0,0,0,0,0},
	{MAKE_STATE,KEY_ENTER,1,0x5a,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_ENTER,2,0xf0,0x5a,0,0,0,0,0,0},
	{MAKE_STATE,KEY_ENTER,2,0xe0,0x5a,0,0,0,0,0,0},
	{BREAK_STATE,KEY_ENTER,3,0xe0,0xf0,0x5a,0,0,0,0,0},

	{MAKE_STATE,KEY_LEFTSHIFT,1,0x12,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_LEFTSHIFT,2,0xf0,0x12,0,0,0,0,0,0},
	{MAKE_STATE,KEY_BACKSPACE,1,0x61,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_BACKSPACE,2,0xf0,0x61,0,0,0,0,0,0},
	{MAKE_STATE,KEY_Z,1,0x1a,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_Z,2,0xf0,0x1a,0,0,0,0,0,0},
	{MAKE_STATE,KEY_X,1,0x22,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_X,2,0xf0,0x22,0,0,0,0,0,0},
	{MAKE_STATE,KEY_C,1,0x21,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_C,2,0xf0,0x21,0,0,0,0,0,0},
	{MAKE_STATE,KEY_V,1,0x2a,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_V,2,0xf0,0x2a,0,0,0,0,0,0},
	{MAKE_STATE,KEY_B,1,0x32,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_B,2,0xf0,0x32,0,0,0,0,0,0},
	{MAKE_STATE,KEY_N,1,0x31,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_N,2,0xf0,0x31,0,0,0,0,0,0},
	{MAKE_STATE,KEY_M,1,0x3a,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_M,2,0xf0,0x3a,0,0,0,0,0,0},
	{MAKE_STATE,KEY_COMMA,1,0x41,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_COMMA,2,0xf0,0x41,0,0,0,0,0,0},
	{MAKE_STATE,KEY_DOT,1,0x49,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_DOT,2,0xf0,0x49,0,0,0,0,0,0},
	{MAKE_STATE,KEY_SLASH,2,0xe0,0x4a,0,0,0,0,0,0},//BASE
	{BREAK_STATE,KEY_SLASH,3,0xe0,0xf0,0x4a,0,0,0,0,0},
	{MAKE_STATE,KEY_SLASH,5,0xe0,0xf0,0x12,0xe0,0x4a,0,0,0},//Left-Shift
	{BREAK_STATE,KEY_SLASH,5,0xe0,0xf0,0x4a,0xe0,0x12,0,0,0},
	{MAKE_STATE,KEY_SLASH,5,0xe0,0xf0,0x59,0xe0,0x4a,0,0,0},//Right-Shift
	{BREAK_STATE,KEY_SLASH,5,0xe0,0xf0,0x4a,0xe0,0x59,0,0,0},	
	{MAKE_STATE,KEY_UP,2,0xe0,0x75,0,0,0,0,0,0},
	{BREAK_STATE,KEY_UP,3,0xe0,0xf0,0x75,0,0,0,0,0},
	{MAKE_STATE,KEY_UP,5,0xe0,0xf0,0x12,0xe0,0x75,0,0,0},
	{BREAK_STATE,KEY_UP,5,0xe0,0xf0,0x75,0xe0,0x12,0,0,0},
	{MAKE_STATE,KEY_UP,5,0xe0,0xf0,0x59,0xe0,0x75,0,0,0},
	{BREAK_STATE,KEY_UP,5,0xe0,0xf0,0x75,0xe0,0x59,0,0,0},
	{MAKE_STATE,KEY_UP,4,0xe0,0x12,0xe0,0x75,0,0,0,0},
	{BREAK_STATE,KEY_UP,6,0xe0,0xf0,0x75,0xe0,0xf0,0x12,0,0},
	{MAKE_STATE,KEY_RIGHTSHIFT,1,0x59,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_RIGHTSHIFT,2,0xf0,0x59,0,0,0,0,0,0},


	{MAKE_STATE,KEY_LEFTCTRL,1,0x14,0,0,0,0,0,0,0},
	{BREAK_STATE,KEY_LEFTCTRL,2,0xf0,0x14,0,0,0,0,0,0},
	{MAKE_STATE,KEY_F9,2,0xe0,0x1f,0,0,0,0,0,0}, //mp4
	{BREAK_STATE,KEY_F9,3,0xe0,0xf0,0x1f,0,0,0,0,0},
	{MAKE_STATE,KEY_LEFTALT,1,0x11,0,0,0,0,0,0,0},//alt
	{BREAK_STATE,KEY_LEFTALT,2,0xf0,0x11,0,0,0,0,0,0},
	{MAKE_STATE,KEY_F10,8,0xe1,0x14,0x77,0xe1,0xf0,0x14,0xf0,0x77}, //mp3
	{BREAK_STATE,KEY_F10,8,0xe1,0x14,0x77,0xe1,0xf0,0x14,0xf0,0x77},
	{MAKE_STATE,KEY_SPACE,1,0x29,0,0,0,0,0,0,0},//space
	{BREAK_STATE,KEY_SPACE,2,0xf0,0x29,0,0,0,0,0,0},
	{MAKE_STATE,KEY_F11,2,0xe0,0x2f,0,0,0,0,0,0},//输入法
	{BREAK_STATE,KEY_F11,3,0xe0,0xf0,0x2f,0,0,0,0,0},
	{MAKE_STATE,KEY_LEFTBRACE,1,0x54,0,0,0,0,0,0,0},//{
	{BREAK_STATE,KEY_LEFTBRACE,2,0xf0,0x54,0,0,0,0,0,0},
	{MAKE_STATE,KEY_RIGHTBRACE,1,0x5b,0,0,0,0,0,0,0},//}
	{BREAK_STATE,KEY_RIGHTBRACE,2,0xf0,0x5b,0,0,0,0,0,0},
	{MAKE_STATE,KEY_APOSTROPHE,1,0x52,0,0,0,0,0,0,0},//,
	{BREAK_STATE,KEY_APOSTROPHE,2,0xf0,0x52,0,0,0,0,0,0},
	{MAKE_STATE,KEY_LEFT,2,0xe0,0x6b,0,0,0,0,0,0},
	{BREAK_STATE,KEY_LEFT,3,0xe0,0xf0,0x6b,0,0,0,0,0},
	{MAKE_STATE,KEY_LEFT,5,0xe0,0xf0,0x12,0xe0,0x6b,0,0,0},
	{BREAK_STATE,KEY_LEFT,5,0xe0,0xf0,0x6b,0xe0,0x12,0,0,0},
	{MAKE_STATE,KEY_LEFT,5,0xe0,0xf0,0x59,0xe0,0x6b,0,0,0},
	{BREAK_STATE,KEY_LEFT,5,0xe0,0xf0,0x6b,0xe0,0x59,0,0,0},
	{MAKE_STATE,KEY_LEFT,4,0xe0,0x12,0xe0,0x6b,0,0,0,0},
	{BREAK_STATE,KEY_LEFT,6,0xe0,0xf0,0x6b,0xe0,0xf0,0x12,0,0},
	{MAKE_STATE,KEY_DOWN,2,0xe0,0x72,0,0,0,0,0,0},
	{BREAK_STATE,KEY_DOWN,3,0xe0,0xf0,0x72,0,0,0,0,0},
	{MAKE_STATE,KEY_DOWN,5,0xe0,0xf0,0x12,0xe0,0x72,0,0,0},
	{BREAK_STATE,KEY_DOWN,5,0xe0,0xf0,0x72,0xe0,0x12,0,0,0},
	{MAKE_STATE,KEY_DOWN,5,0xe0,0xf0,0x59,0xe0,0x72,0,0,0},
	{BREAK_STATE,KEY_DOWN,5,0xe0,0xf0,0x72,0xe0,0x59,0,0,0},
	{MAKE_STATE,KEY_DOWN,4,0xe0,0x12,0xe0,0x72,0,0,0,0},
	{BREAK_STATE,KEY_DOWN,6,0xe0,0xf0,0x72,0xe0,0xf0,0x12,0,0},
	{MAKE_STATE,KEY_RIGHT,2,0xe0,0x74,0,0,0,0,0,0},
	{BREAK_STATE,KEY_RIGHT,3,0xe0,0xf0,0x74,0,0,0,0,0},
	{MAKE_STATE,KEY_RIGHT,5,0xe0,0xf0,0x12,0xe0,0x74,0,0,0},
	{BREAK_STATE,KEY_RIGHT,5,0xe0,0xf0,0x74,0xe0,0x12,0,0,0},
	{MAKE_STATE,KEY_RIGHT,5,0xe0,0xf0,0x59,0xe0,0x74,0,0,0},
	{BREAK_STATE,KEY_RIGHT,5,0xe0,0xf0,0x74,0xe0,0x59,0,0,0},
	{MAKE_STATE,KEY_RIGHT,4,0xe0,0x12,0xe0,0x74,0,0,0,0},
	{BREAK_STATE,KEY_RIGHT,6,0xe0,0xf0,0x74,0xe0,0xf0,0x12,0,0},
};

//struct ps2keyboard_dev ps2keyboard_dev0={
//	.ps2kbdscancodelist=&ps2keyborad_scancodes[0];
//	.ps2kbdcancodenum=ARRAY_SIZE(ps2keyborad_scancodes);
//}





/*
static int ps2keyboard_open(struct inode* inode, struct file* filp);
static int ps2keyboard_release(struct inode* inode, struct file* filp);
static int ps2keyboard_ioctl(struct inode *inodep, struct file *filp, unsigned int cmd, unsigned long arg);
static ssize_t ps2keyboard_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos);
static ssize_t ps2keyboard_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos);


static struct file_operations ps2keyboard_fops = {
	.owner = THIS_MODULE,
	.open = ps2keyboard_open,
	.release = ps2keyboard_release,
	.read = ps2keyboard_read,
	.write = ps2keyboard_write, 
	.ioctl = ps2keyboard_ioctl,
};




static int ps2keyboard_open(struct inode* inode, struct file* filp) {
	struct ps2keyboard_dev *  dev;        
	dev = container_of(inode->i_cdev, struct ps2keyboard_dev, input);
	filp->private_data = dev;

	return 0;
}


static int ps2keyboard_release(struct inode* inode, struct file* filp) {
	struct ps2keyboard_dev* dev = filp->private_data;        
	return 0;
}

static ssize_t ps2keyboard_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos) {
	ssize_t err = 0;
	struct ps2keyboard_dev* dev = filp->private_data;        
	return err;
}


static ssize_t ps2keyboard_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos) {
	struct ps2keyboard_dev* dev = filp->private_data;
	ssize_t err = 0;        
	return err;
}
static int ps2keyboard_ioctl(struct inode *inodep, struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct ps2keyboard_dev* dev = filp->private_data;

	return ioctlreturn;
}
*/

int ps2keyboard_get_caps_locking_status(void)
{
	int status = 0;

	spin_lock(caps_spinlock);
	status = caps_locking;
	printk("keyinput_get_caps_locking_status is %d\n",caps_locking);
	spin_unlock(caps_spinlock);

	return status;
}
EXPORT_SYMBOL(ps2keyboard_get_caps_locking_status);
int ps2keyboard_get_key_shift_locking_status(void)
{
	int status = 0;
	spin_lock(shift_key_spinlock);
	status = shift_key_locking;
	spin_unlock(shift_key_spinlock);

	return status;
}
EXPORT_SYMBOL(ps2keyboard_get_key_shift_locking_status);
int ps2keyboard_get_key_alt_locking_status(void)
{
	int status = 0;
	spin_lock(alt_key_spinlock);
	status = alt_key_locking;
	spin_unlock(alt_key_spinlock);
		 
        return status;
}
EXPORT_SYMBOL(ps2keyboard_get_key_alt_locking_status);




//ps2 keyboard interrupt thread
static irqreturn_t ps2keyboard_isr(int irq, void *dev_id)
{
	struct ps2keyboard_dev *ps2keyboard_dev0 = dev_id;
	unsigned int status = readb(KMIIR);
	int handled = IRQ_NONE;
	unsigned char readdata;
	ps2keyboard_dev0->pscancode=kmalloc(sizeof(struct scancode),GFP_KERNEL);   
	if(ps2keyboard_dev0->pscancode==NULL)
	{	
		printk("ps2keyboard_isr error kmalloc\n");
		handled = IRQ_HANDLED;
		goto _return_;
	}
	printk("---------\n");
	memset(ps2keyboard_dev0->pscancode,0,sizeof(struct scancode)); 
	while (status & KMIIR_RXINTR) {
		ps2keyboard_dev0->pscancode->scancode[ps2keyboard_dev0->pscancode->num]=readb(KMIDATA);
		printk("%x\n",ps2keyboard_dev0->pscancode->scancode[ps2keyboard_dev0->pscancode->num]);
		ps2keyboard_dev0->pscancode->num++;
		status = readb(KMIIR);
		handled = IRQ_HANDLED;
	}
	printk("n1=%d\n",ps2keyboard_dev0->pscancode->num);
	//add key scancode to ps2keyboard_dev0list
	list_add_tail(&ps2keyboard_dev0->pscancode->list, &ps2keyboard_dev0->keyscancode_list);   
	tasklet_schedule(&ps2keyboard_tasklet);
_return_:
	return handled;
}

static void ps2keyboard_tasklet_fuc(unsigned long data)
{
	int i,l;
	struct scancode *pscancode;
	struct ps2keyboard_dev *ps2keyboard_dev0 = (struct ps2keyboard_dev *) data;
	printk("ps2keyboard_tasklet_fuc\n");
	if(!list_empty(&ps2keyboard_dev0->keyscancode_list))
	{
		pscancode=list_first_entry(&ps2keyboard_dev0->keyscancode_list,struct scancode,list);
		
		for(i=0;i<pscancode->num;i++)
			printk("%x\n",pscancode->scancode[i]);
		printk("n2=%d\n",pscancode->num);
		for(i=0;i<ps2keyboard_dev0->ps2kbdcancodenum;i++)
		{
			/*
			for(l=0;l<8;l++)
			{
				if(ps2keyboard_dev0->ps2kbdscancodelist[i].code[l]!=pscancode->scancode[l])
					break;
			}
			if(l==8)
			{
				printk("i==%d\n",i);
				break;
			}*/	
			if(!memcmp(ps2keyboard_dev0->ps2kbdscancodelist[i].code,pscancode->scancode,8))
			{
				printk("i==%d\n",i);
				if(KEY_LEFTALT==ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue||KEY_RIGHTALT==ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue){
					spin_lock(alt_key_spinlock);
					if (ps2keyboard_dev0->ps2kbdscancodelist[i].makeorbreak==MAKE_STATE ) {
						alt_key_locking = 1;
					} else if (alt_key_locking) {
						alt_key_locking = 0;
					}
					spin_unlock(alt_key_spinlock);
				}
				else if(KEY_LEFTSHIFT==ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue||KEY_RIGHTSHIFT==ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue){
					spin_lock(shift_key_spinlock);
					if (ps2keyboard_dev0->ps2kbdscancodelist[i].makeorbreak==MAKE_STATE ) {
						shift_key_locking = 1;
					} else if (shift_key_locking) {
						shift_key_locking = 0;
					}
					spin_unlock(shift_key_spinlock);
				}
				else if (KEY_CAPSLOCK==ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue&&ps2keyboard_dev0->ps2kbdscancodelist[i].makeorbreak==BREAK_STATE){
					spin_lock(caps_spinlock);
					if(caps_locking==1){
					        caps_locking = 0;
				               printk(KERN_ALERT "Capslock is disabled.\n"); 
				        } else {
				               caps_locking = 1;
					        printk(KERN_ALERT "Capslock is enabled.\n");
					}
					spin_unlock(caps_spinlock);
				}
				if(ps2keyboard_dev0->ps2kbdscancodelist[i].makeorbreak==MAKE_STATE)
					input_event(ps2keyboard_dev0->input, EV_KEY, ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue, 1);
				else
					input_event(ps2keyboard_dev0->input, EV_KEY, ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue, 0);
				break; 
			}
		}
		list_del_init(&pscancode->list);
		kfree(pscancode);
	}

	//input_event(ps2keyboard_dev0->input, EV_KEY, KEY_1, 1);
	//input_event(ps2keyboard_dev0->input, EV_KEY, KEY_1, 0);

	/*
	ps2keyboard_dev0->keyhead=ps2keyboard_dev0->keytail=0;
	memset(ps2keyboard_dev0->keybuffer,0,MAX_KEY_NUM);
	if(ps2keyboard_dev0->outindex!=ps2keyboard_dev0->inindex)
	{
		
		for(i=0;i<ps2keyboard_dev0->ps2kbdcancodenum;i++)
		{
			if(!memcmp(ps2keyboard_dev0->ps2kbdscancodelist[i].code,ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].scancode,ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].readdatalentg))
			{
				if(ps2keyboard_dev0->ps2kbdscancodelist[i].makeorbreak==MAKE_STATE)
				{
					//printk("\n");
					for(l=0;l<ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].readdatalentg;l++)
						printk("%x\n",ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].scancode[l]);
					input_event(ps2keyboard_dev0->input, EV_KEY, ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue, 1);
				}
				else
				{
					//printk("\n");
					input_event(ps2keyboard_dev0->input, EV_KEY, ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue, 0);
					for(l=0;l<ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].readdatalentg;l++)
						printk("%x\n",ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].scancode[l]);
				}
				memset(ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].scancode,0,8);
				ps2keyboard_dev0->keybuffer[ps2keyboard_dev0->outindex].readdatalentg=0;
			}
		}
		ps2keyboard_dev0->outindex=(ps2keyboard_dev0->outindex+1)%MAX_KEY_BUFFERNUM;
	}
	*/
}


static irqreturn_t hallone_isr(int irq, void *dev_id)
{
	struct ps2keyboard_dev *ps2keyboard_dev0 = dev_id;
	tasklet_schedule(&hallone_tasklet);
	return IRQ_HANDLED;
}

static void hallone_tasklet_fuc(unsigned long data)
{
	struct ps2keyboard_dev *ps2keyboard_dev0 = (struct ps2keyboard_dev *) data;
	printk("---------------hallone_tasklet_fuc----------------\n");
	input_event(ps2keyboard_dev0->input, EV_KEY, KEY_1, 1);
	input_event(ps2keyboard_dev0->input, EV_KEY, KEY_1, 0);
}

static irqreturn_t halltwo_isr(int irq, void *dev_id)
{
	struct ps2keyboard_dev *ps2keyboard_dev0 = dev_id;
	int handled = IRQ_HANDLED;
	printk("---------------irqreturn_t halltwo_isr----------------\n");
	input_event(ps2keyboard_dev0->input, EV_KEY, KEY_2, 1);
	input_event(ps2keyboard_dev0->input, EV_KEY, KEY_2, 0);
	//input_sync(ps2keyboard_dev0->input);
_return_:
	return handled;
}
static int ps2keyboard_probe(struct platform_device *pdev){
	struct ps2keyboard_dev *ps2keyboard_dev0;
	struct input_dev *input;
	struct resource *res;
	int i,error,ret;
	printk("---------------ps2keyboard_probe----------------\n");
	ps2keyboard_dev0 = kzalloc(sizeof(struct ps2keyboard_dev), GFP_KERNEL);
	if (!ps2keyboard_dev0) {
		dev_err(&pdev->dev, "No memory for ps2keyboard_dev0\n");
		return -ENOMEM;
	}
	input = input_allocate_device();
	if (!input) {
		printk("ps2keyboard allocate input device failed.\n");
		return -ENOMEM;
	}
	ps2keyboard_dev0->ps2kbdscancodelist=&ps2keyborad_scancodes[0];
	ps2keyboard_dev0->ps2kbdcancodenum=ARRAY_SIZE(ps2keyborad_scancodes);
	for(i=0;i<ps2keyboard_dev0->ps2kbdcancodenum;i+=2)
		input_set_capability(input, EV_KEY, ps2keyboard_dev0->ps2kbdscancodelist[i].keyvalue);
	input->name = "ps2keyboard";
	input->phys = "ps2keyboard/input0";
	input->dev.parent = &pdev->dev;
	input->id.bustype = BUS_HOST;
	input->id.vendor = 0x0001;
	input->id.product = 0x0001;
	input->id.version = 0x0100;
	ps2keyboard_dev0->input = input;
	error = input_register_device(input);
	if (error) {
		printk("ps2keyboard: Unable to register input device, ""error: %d\n", error);
		goto __fail_exit__;
	}
	ps2keyboard_dev0->gpio_capslock=__imapx_name_to_gpio(CONFIG_PS2KEYBOARD_LED_CAPSLOCK);
	ps2keyboard_dev0->gpio_numlock=__imapx_name_to_gpio(CONFIG_PS2KEYBOARD_LED_NUMLOCK);
	ps2keyboard_dev0->gpio_hallone=__imapx_name_to_gpio(CONFIG_PS2KEYBOARD_HALLONE);
	ps2keyboard_dev0->gpio_halltwo=__imapx_name_to_gpio(CONFIG_PS2KEYBOARD_HALLTWO);
	ps2keyboard_dev0->gpio_halloneirq= imapx_gpio_to_irq(ps2keyboard_dev0->gpio_hallone);
	ps2keyboard_dev0->gpio_halltwoirq= imapx_gpio_to_irq(ps2keyboard_dev0->gpio_halltwo);
	imapx_gpio_setcfg(ps2keyboard_dev0->gpio_hallone, IG_INPUT, IG_NORMAL);
	imapx_gpio_setirq(ps2keyboard_dev0->gpio_hallone, FILTER_MAX, IG_FALL, 1);
	imapx_gpio_setcfg(ps2keyboard_dev0->gpio_halltwo, IG_INPUT, IG_NORMAL);
	imapx_gpio_setirq(ps2keyboard_dev0->gpio_halltwo, FILTER_MAX, IG_FALL, 1);
	ret = request_irq(ps2keyboard_dev0->gpio_halloneirq, hallone_isr, IRQF_DISABLED,dev_name(&pdev->dev), ps2keyboard_dev0);
	if (ret != 0) {
		dev_err(&pdev->dev, "cannot claim hallone IRQ %d\n", ps2keyboard_dev0->irq);
		goto _err_iomap_;
	}
	//ret = request_irq(ps2keyboard_dev0->gpio_halltwoirq, halltwo_isr, IRQF_DISABLED,dev_name(&pdev->dev), ps2keyboard_dev0);
	//if (ret != 0) {
	//	dev_err(&pdev->dev, "cannot claim halltwo IRQ %d\n", ps2keyboard_dev0->irq);
	//	goto _err_iomap_;
	//}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "cannot find IO resource\n");
		ret = -ENOENT;
		goto __fail_exit__;
	}
	ps2keyboard_dev0->ioarea = request_mem_region(res->start, resource_size(res),pdev->name);
	if (ps2keyboard_dev0->ioarea == NULL) {
		dev_err(&pdev->dev, "cannot request IO\n");
		ret = -ENXIO;
		goto __fail_exit__;
	}
	ps2keyboard_dev0->base_reg = ioremap(res->start, resource_size(res));
	if (ps2keyboard_dev0->base_reg == NULL) {
		dev_err(&pdev->dev, "cannot map IO\n");
		ret = -ENXIO;
		goto _err_ioarea_;
	}
	printk("registers %p (%p, %p)\n",ps2keyboard_dev0->base_reg,ps2keyboard_dev0->ioarea, res);
	ps2keyboard_dev0->irq = ret = platform_get_irq(pdev, 0);
	if (ret <= 0) {
		dev_err(&pdev->dev, "cannot find IRQ\n");
		goto _err_iomap_;
	}
	//ps2keyboard_dev0->inindex=ps2keyboard_dev0->outindex=0;
	//for(i=0;i<MAX_KEY_BUFFERNUM;i++)
	//{
	//	memset(ps2keyboard_dev0->keybuffer[i].scancode,0,8);
	//	ps2keyboard_dev0->keybuffer[i].readdatalentg=0;
	//}
	//init list_head list
	INIT_LIST_HEAD(&ps2keyboard_dev0->keyscancode_list);
	ret = request_irq(ps2keyboard_dev0->irq, ps2keyboard_isr, IRQF_DISABLED,
			  dev_name(&pdev->dev), ps2keyboard_dev0);

	if (ret != 0) {
		dev_err(&pdev->dev, "cannot claim IRQ %d\n", ps2keyboard_dev0->irq);
		goto _err_iomap_;
	}
	writeb(0xF, KMICLKDIV);
	writeb(KMICR_EN, KMICR);
	imapx_gpio_setcfg(IMAPX_GPC_RANGE(4, 7), IG_CTRL0, IG_NORMAL);
	writeb(KMICR_EN | KMICR_RXINTREN, KMICR);
	platform_set_drvdata(pdev, ps2keyboard_dev0);
	
	tasklet_enable(&ps2keyboard_tasklet);
	ps2keyboard_tasklet.data = (unsigned long) ps2keyboard_dev0;

	tasklet_enable(&hallone_tasklet);
	hallone_tasklet.data = (unsigned long) ps2keyboard_dev0;

	if (caps_spinlock == NULL) {
		caps_spinlock = (spinlock_t *)kmalloc(sizeof(spinlock_t), GFP_KERNEL);
		if (caps_spinlock == NULL) {
			printk("ps2keyboard_probe:kmalloc() for capslock key spinlock error.\n");
			goto _err_iomap_;
		}
		spin_lock_init(caps_spinlock);
	}
	if (shift_key_spinlock ==NULL) {
		shift_key_spinlock = (spinlock_t *)kmalloc(sizeof(spinlock_t), GFP_KERNEL);
		if (shift_key_spinlock == NULL) {
			printk(KERN_ERR "ps2keyboard_probe:kmalloc() for shift key spinlock error.\n");
			goto _err_iomap_;
		}
		spin_lock_init(shift_key_spinlock);
	}
	if (alt_key_spinlock ==NULL){
		alt_key_spinlock = (spinlock_t *)kmalloc(sizeof(spinlock_t), GFP_KERNEL);
		if (alt_key_spinlock == NULL) {
			printk(KERN_ERR "ps2keyboard_probe:kmalloc() for alt key spinlock error.\n");
			goto _err_iomap_;
		}
			spin_lock_init(alt_key_spinlock);
	}
	
	return 0;
 _err_iomap_:
	iounmap(ps2keyboard_dev0->base_reg);
 _err_ioarea_:
	release_resource(ps2keyboard_dev0->ioarea);
	kfree(ps2keyboard_dev0->ioarea);	
__fail_exit__:
	input_free_device(input);
	return ret;
}

static int __devexit ps2keyboard_remove(struct platform_device *pdev){
	struct ps2keyboard_dev *ps2keyboard_dev0=platform_get_drvdata(pdev);
	input_unregister_device(ps2keyboard_dev0->input);
	free_irq(ps2keyboard_dev0->irq, ps2keyboard_dev0);
	free_irq(ps2keyboard_dev0->gpio_halloneirq, ps2keyboard_dev0);
	free_irq(ps2keyboard_dev0->gpio_halltwoirq, ps2keyboard_dev0);
	iounmap(ps2keyboard_dev0->base_reg);
	release_resource(ps2keyboard_dev0->ioarea);
	kfree(ps2keyboard_dev0->ioarea);
	tasklet_disable(&ps2keyboard_tasklet);
	tasklet_kill(&ps2keyboard_tasklet);
	tasklet_disable(&hallone_tasklet);
	tasklet_kill(&hallone_tasklet);
	return 0;
}


#ifdef CONFIG_PM
static int ps2keyboard_suspend(struct platform_device *pdev, pm_message_t state) 
{
	struct ps2keyboard_dev *ps2keyboard_dev0=platform_get_drvdata(pdev);
	return 0;
}

static int ps2keyboard_resume(struct platform_device *pdev) 
{
	struct ps2keyboard_dev *ps2keyboard_dev0=platform_get_drvdata(pdev);
	return 0;
}
#else
#define ps2keyboard_suspend	NULL
#define ps2keyboard_resume	NULL
#endif

static struct platform_driver ps2keyboard_driver = {
	.probe		= ps2keyboard_probe,
	.remove		= __devexit_p(ps2keyboard_remove),
	.suspend		= ps2keyboard_suspend,
	.resume		= ps2keyboard_resume,
	.driver		= {
		.name	= "ps2keyboard",
		.owner	= THIS_MODULE,
	},
};

static int __init ps2keyboard_init(void){ 
	printk("---------------ps2keyboard_init----------------\n");
	return platform_driver_register(&ps2keyboard_driver);
}

static void __exit ps2keyboard_exit(void) {
	printk("---------------ps2keyboard_exit----------------\n");
	platform_driver_unregister(&ps2keyboard_driver);
}

module_init(ps2keyboard_init);
module_exit(ps2keyboard_exit);
MODULE_DESCRIPTION("PS2Keyboard's Android Driver");
MODULE_LICENSE("GPL");

imapx200_ps2_keyboard.h
  1. <SPAN style="FONT-SIZE: 16px">#ifndef _PS2KEYBOARD_FOR_ANDROID_H_    
  2. #define _PS2KEYBOARD_FOR_ANDROID_H_      
  3.   
  4. #include <linux/cdev.h>     
  5. #include <linux/semaphore.h>     
  6. #include <linux/ioctl.h>   
  7. #define ATMELCRYPTIC_MAGIC    'k'   
  8. #define WRITE_MTZ _IOW(ATMELCRYPTIC_MAGIC,0,struct ps2keyboard_inout_data)   
  9. #define READ_MTZ _IOWR(ATMELCRYPTIC_MAGIC,1,struct ps2keyboard_inout_data)   
  10. #define ATMELCRYPTIC_MAXNR 3   
  11. //ps2 keyboard press state    
  12. #define MAKE_STATE   0   
  13. #define BREAK_STATE  1   
  14. //ps2 keyboard scan code structure    
  15. #define MAX_KEY_NUM 200   
  16. #define MAX_KEY_BUFFERNUM 10   
  17. struct ps2keyborad_scancode  
  18. {  
  19.     unsigned char   makeorbreak;  
  20.     unsigned char   keyvalue;  
  21.     unsigned char   len;  
  22.     unsigned char   code[8];  
  23. };  
  24. struct scancode{  
  25.     //scancode   
  26.     unsigned char scancode[8];  
  27.     //scancode length   
  28.     int num;  
  29.     struct list_head list;     
  30. };  
  31. //ps2 keyboard driver structure    
  32. struct ps2keyboard_dev {  
  33.     //PS2 keyborad scan code list   
  34.     struct ps2keyborad_scancode *ps2kbdscancodelist;   
  35.     //GPIO base address   
  36.     void __iomem    *base_reg;  
  37.     //mem space   
  38.     struct resource *ioarea;  
  39.     //PS2 keyborad scan code number   
  40.     int ps2kbdcancodenum;  
  41.     //PS2 keyborad capslock led control gpio   
  42.     unsigned int gpio_capslock;  
  43.     //PS2 keyborad num led control gpio   
  44.     unsigned int gpio_numlock;  
  45.     //hall interrupt gpio1   
  46.     unsigned int gpio_hallone;  
  47.     unsigned int gpio_halloneirq;  
  48.     //hall interrupt gpio2   
  49.     unsigned int gpio_halltwo;  
  50.     unsigned int gpio_halltwoirq;  
  51.     //ps2 keyboard interrupt number   
  52.     unsigned int        irq;  
  53.     struct input_dev *input;  
  54.     struct list_head keyscancode_list;    
  55.     //struct scancode keybuffer[MAX_KEY_BUFFERNUM];   
  56.     //int     inindex,outindex;   
  57.     struct scancode *pscancode;  
  58.   
  59. };  
  60. #endif     
  61. </SPAN>  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值