注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

liuyue18301的个人主页

追逐梦想 光辉岁月

 
 
 

日志

 
 

2009年10月27日  

2009-10-27 11:25:49|  分类: linux驱动 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
  1. /********************************************************** 
  2.  * s3c2440-keyboard.c 
  3.  * 
  4.  * keyboard driver for S3C2440 based PDA 
  5.  * 
  6.  * 
  7.  * History:2007/04/30 
  8.  * 
  9.  * 
  10.  ***********************************************************/  
  11.   
  12. #include <linux/config.h>  
  13. #include <linux/module.h>  
  14. #include <linux/kernel.h>  
  15. #include <linux/init.h>  
  16. #include <linux/miscdevice.h>  
  17. #include <linux/sched.h>  
  18. #include <linux/delay.h>  
  19. #include <linux/poll.h>  
  20. #include <linux/spinlock.h>  
  21. #include <asm/irq.h>  
  22. #include <asm/arch/irq.h>  
  23. #include <asm/arch/irqs.h>  
  24. #include <asm/arch/clocks.h>  
  25. #include <asm/hardware.h>  
  26. #include <asm/arch/S3C2440.h>  
  27.  
  28. #define DEVICE_NAME "s3c2440-kb" //键盘设备名  
  29.   
  30. static int kbMajor = 0; //默认的主设备号  
  31.  
  32. #define MAX_KB_BUF 10 //循环队列的尺寸   
  33.   
  34. typedef struct {  
  35.  unsigned int keyStatus;  
  36.  int irq;  
  37. // int timeCount;  
  38.  u_short buf[MAX_KB_BUF];  /* 循环队列*/  
  39.  unsigned int head, tail; /* 循环队列的读写指针*/  
  40.  spinlock_t lock;   /*锁*/  
  41. } KB_DEV;  
  42.   
  43. static KB_DEV kbdev;  
  44.  
  45. #define KEY_UP  0  //按键弹起  
  46. #define KEY_DOWN 1 //按键按下  
  47. #define NO_KEY_DOWN 2  //没有键按下  
  48.  
  49. #define EINT1_DOWN 0  
  50. #define EINT3_DOWN 1  
  51. #define EINT8_DOWN  2  
  52. #define NO_EINT_DOWN 3  
  53.   
  54. /*循环队列操作*/  
  55. #define BUF_HEAD (kbdev.buf[kbdev.head])  
  56. #define BUF_TAIL (kbdev.buf[kbdev.tail])  
  57. #define INCBUF(x)  if((++x)==MAX_KB_BUF) x=0  
  58.   
  59. /*定时器设置*/  
  60. #define KB_TIMER_DELAY  (HZ/50) /*HZ表示每秒产生的时钟滴答数,定时器超时为20ms*/  
  61. #define REPEAT_START_DELAY  (HZ) /* 自动重复开始延时:1秒*/  
  62. #define REPEAT_DELAY (HZ/2)  /*自动重复延时:0.5秒*/  
  63.   
  64. static struct timer_list kb_timer;  
  65. static struct timer_list repeat_timer;  
  66. spinlock_t repeat_lock;  
  67. static int timeCount =1;  
  68. static int TIME_OUT  =5;  
  69.   
  70. /*键盘矩阵*/  
  71.   
  72. static u_short keyboard_code_map[4][3]={  
  73.            {1 , 2 , 3 },  
  74.            {4 , 5 , 6 },  
  75.            {7 , 8 , 9 },  
  76.            {10, 11, 12}  
  77.           }; //每个按键对应的键盘码  
  78. static u_short pre_keyboard_code  = 0; //上次扫描得到的按键值  
  79. static u_short curr_keyboard_code = 0;//当前扫描得到的按键值  
  80. static u_short snap_keyboard_code[4][3]={  
  81.            {0 , 0 , 0 },  
  82.            {0 , 0 , 0 },  
  83.            {0 , 0 , 0 },  
  84.            {0,  0,  0}  
  85.           }; //临时按键值  
  86. #define DETECTION_THROLD 3  
  87.   
  88.   
  89. static int requestIrq();  
  90. static int s3c2440_kb_release(struct inode *inode, struct file *filp);  
  91.   
  92.    
  93.   
  94. /*---------------------------------------------------- 
  95. *  func: 初始化GPJCON寄存器,将GPJ9,GPJ10,GPJ11,GPJ12 
  96. *        配置成output管腿 
  97. *   
  98. ------------------------------------------------------*/  
  99. static void init_gpjcon()  
  100. {  
  101.    
  102.  //GPJ9,GPJ10,GPJ11,GPJ12------>output  
  103.  GPJCON &= 0xFC03FFFF;  
  104.  GPJCON |= 0x01540000;  
  105. }  
  106.   
  107. /*---------------------------------------------------- 
  108. *  func:  向GPJ9,GPJ10,GPJ11,GPJ12输出value 
  109. *  param:  
  110. *        value: 输出值 
  111. *   
  112. ------------------------------------------------------*/  
  113. //  
  114. static inline void output_giop(int value )  //往所有行输出  
  115. {  
  116.  value &= 0x0000000F;  
  117.  value <<= 9;  
  118.  GPJDAT &= 0xE1FF;  
  119.  GPJDAT |= value;  
  120.  udelay(2);  
  121. }  
  122.   
  123. /*---------------------------------------------------- 
  124. *  func:  判断eint当前是否是低电平 
  125. *  param:  
  126. *        irq: 当前引发中断的eint的irq号 
  127. *  return:  
  128. *           EINT1_DOWN: eint1上是低电平 
  129. *           EINT3_DOWN: eint3上是低电平 
  130. *           EINT8_DOWN: eint8上是低电平 
  131. *   NO_EINT_DOWN:eint上不是低电平 
  132. ------------------------------------------------------*/  
  133. int get_eint_value(int irq)  
  134. {  
  135.  u_int IOValue;  
  136.   
  137.  IOValue = GPFDAT ;  
  138.    
  139.  if( (irq == 1) && (( IOValue & 0x00000002)==0)    )                
  140.  {    
  141.    return EINT1_DOWN;  
  142.  }  
  143.  if((irq ==3 ) && (( IOValue & 0x00000008)==0) )  
  144.  {  
  145.   return EINT3_DOWN;  
  146.  }  
  147.  IOValue = GPGDAT ;  
  148.  if((irq ==36) && (( IOValue & 0x0000001)==0) )  
  149.  {  
  150.     
  151.    return EINT8_DOWN;  
  152.  }  
  153.   
  154.  return NO_EINT_DOWN;  
  155.   
  156. }  
  157.   
  158. /*---------------------------------------------------- 
  159. *  func:  扫描键盘,判断哪一个键被按下 
  160. *  param:  
  161. *        x: 得到按键的行号 
  162. *   y: 得到按键的列号 
  163. *  return:  
  164. *           KEY_DOWN: 键盘上有键被按下 
  165. *           NO_KEY_DOWN: 键盘上没有键被按下 
  166. ------------------------------------------------------*/  
  167.   
  168. static inline int scan_keyboard(int* x,int* y)  
  169. {  
  170.  int matrix_row,matrix_col,matrix_col_status;  
  171.   
  172.  output_giop(0xF);  //往所有行输出1  
  173.    
  174.   
  175.  //判断按键在哪一行  
  176.  matrix_row=matrix_col=-1;  
  177.   
  178.  output_giop(0xE);//在第1行上输出1,其余行输出0  
  179.  matrix_col_status = get_eint_value(kbdev.irq);  
  180.  if(matrix_col_status != NO_EINT_DOWN)  
  181.  {  
  182.   matrix_row = 0;  
  183.   matrix_col = matrix_col_status;  
  184.   goto scanend;  
  185.   
  186.  }  
  187.   
  188.  output_giop(0xD);//在第2行上输出1,其余行输出0  
  189.   
  190.  matrix_col_status = get_eint_value(kbdev.irq);  
  191.  if(matrix_col_status != NO_EINT_DOWN)  
  192.  {  
  193.   matrix_row=1;  
  194.   matrix_col = matrix_col_status;  
  195.   goto scanend;  
  196.   
  197.   
  198.  }  
  199.   
  200.  output_giop(0xB);//在第3行上输出1,其余行输出0  
  201.  matrix_col_status =get_eint_value(kbdev.irq);  
  202.  if(matrix_col_status != NO_EINT_DOWN)  
  203.  {  
  204.   matrix_row=2;  
  205.   matrix_col = matrix_col_status;  
  206.   goto scanend;  
  207.   
  208.   
  209.  }  
  210.   
  211.  output_giop(0x7);//在第4行上输出1,其余行输出0  
  212.  matrix_col_status =get_eint_value(kbdev.irq);  
  213.  if(matrix_col_status != NO_EINT_DOWN)  
  214.  {  
  215.   matrix_row=3;  
  216.   matrix_col = matrix_col_status;  
  217.   goto scanend;  
  218.   
  219.   
  220.  }  
  221. scanend:  
  222.  output_giop(0);  
  223.  if(matrix_row >=0 )  
  224.  {  
  225.   snap_keyboard_code[matrix_row][matrix_col_status]= snap_keyboard_code[matrix_row][matrix_col_status] + 1;  
  226.   if(snap_keyboard_code[matrix_row][matrix_col]>=DETECTION_THROLD)  
  227.   {  
  228.    *x=matrix_row;  
  229.    *y=matrix_col;  
  230.    curr_keyboard_code = keyboard_code_map[matrix_row][matrix_col];  
  231.    return KEY_DOWN;  
  232.   }  
  233.   
  234.   
  235.  }  
  236.  return NO_KEY_DOWN;  
  237.   
  238. }  
  239.   
  240. /*---------------------------------------------------- 
  241. *  func:  判断本次按键是否与上次按键相同 
  242. *  param:  
  243. *         
  244. *  return:  
  245. *           0: 相同 
  246. *           1: 不同 
  247. ------------------------------------------------------*/  
  248. static inline int key_changed()  
  249. {  
  250.    
  251.  return (pre_keyboard_code == curr_keyboard_code)? 0 : 1;  
  252. }  
  253.   
  254. /*---------------------------------------------------- 
  255. *  func:  将按键对应的键盘码保存到循环队列中 
  256. *  param:  
  257. *        keyValue: 按键的对应的键盘码 
  258.  
  259. *  return:  
  260. *                    
  261. ------------------------------------------------------*/  
  262.   
  263. static inline void save_key_to_queue(u_short keyValue)  
  264. {  
  265.  if (kbdev.keyStatus == KEY_DOWN)  
  266.  {  
  267.   BUF_HEAD = keyValue;  
  268.   INCBUF(kbdev.head);  
  269.   //wake_up_interruptible(&(kbdev.wq));  
  270.  }  
  271.   
  272. }  
  273.   
  274. /*---------------------------------------------------- 
  275. *  func:  重复按键定时器处理程序,如果一直按住某键, 
  276.           则将该键的键盘码定时存到循环队列中 
  277. *  param:  
  278. *        data: 无参数 
  279.  
  280. *  return:  
  281. *                    
  282. ------------------------------------------------------*/  
  283. static inline void repeat_timer_handler(unsigned long data)  
  284. {  
  285.  spin_lock_irq(&(repeat_lock));  
  286.   
  287.  if(kbdev.keyStatus ==KEY_DOWN)  
  288.  {  
  289.   repeat_timer.expires = jiffies + REPEAT_DELAY;//设置自动重复延时  
  290.   add_timer(&repeat_timer);//将定时器加入队列  
  291.   if(pre_keyboard_code != 0)  
  292.   {  
  293.    //printk("repeat save keyvalue\n   %d",pre_keyboard_code);  
  294.    save_key_to_queue(pre_keyboard_code);//将按键值存入循环队列  
  295.   }  
  296.  }  
  297.  else//如果按键弹起  
  298.  {  
  299.   //del_timer(&repeat_timer);  
  300.  // printk("del repeat timer\n");  
  301.  }  
  302.   
  303.  spin_unlock_irq(&(repeat_lock));  
  304.   
  305.   
  306. }  
  307.   
  308. /*---------------------------------------------------- 
  309. *  func:  使能中断 
  310. *  param:  
  311. *  return:  
  312. *                    
  313. ------------------------------------------------------*/  
  314. //使能中断  
  315. static inline void enableIrq()  
  316. {  
  317.  //清除SRCPND寄存器中eint1 eint2 eint8相应位  
  318.  SRCPND = 0x0000002A;  
  319.  //使能中断  
  320.  enable_irq(IRQ_EINT1);  
  321.  enable_irq(IRQ_EINT3);  
  322.  enable_irq(IRQ_EINT8);  
  323.   
  324. }  
  325.   
  326. /*---------------------------------------------------- 
  327. *  func:  键盘定时扫描程序,如果得到稳定键码,将键码存 
  328. *    入循环队列;如果没有,则延时20ms后继续扫描 
  329. *  param:  
  330. *        data: 无参数 
  331.  
  332. *  return:  
  333. *                    
  334. ------------------------------------------------------*/  
  335. static inline void kb_timer_handler(unsigned long data)  
  336. {  
  337.  int x,y;  
  338.  spin_lock_irq(&(kbdev.lock));  
  339.  x = y = 0;  
  340.    
  341.    
  342.  if(scan_keyboard(&x,&y) == KEY_DOWN)  
  343.  {  
  344.  // printk("snap_keyboard_code=%d, %d, %d, %d\n", snap_keyboard_code[0][1],snap_keyboard_code[1][1],snap_keyboard_code[2][1],snap_keyboard_code[3][1]);  
  345.   kbdev.keyStatus =KEY_DOWN;  
  346.   if(key_changed())  
  347.   {  
  348.    pre_keyboard_code = curr_keyboard_code;  
  349.    save_key_to_queue(pre_keyboard_code);  
  350.    //printk("KEY_DOWN:%d  x=%d  y =%d\n",timeCount,x,y);  
  351.    //设置自动重复开始延时定时器  
  352.    /*repeat_timer.expires = jiffies + REPEAT_START_DELAY; 
  353.    add_timer(&repeat_timer);*/  
  354.      
  355.   }  
  356.     
  357.   timeCount=1;  
  358.   memset(snap_keyboard_code,0,12*sizeof(u_short));  
  359.   //curr_keyboard_code =0;  
  360.     
  361.   kb_timer.expires = jiffies + KB_TIMER_DELAY;  
  362.   add_timer(&kb_timer);  
  363.     
  364.     
  365.   
  366.  }  
  367.  else  
  368.  {  
  369.   //printk("snap_keyboard_code=%d, %d, %d, %d\n", snap_keyboard_code[3][0],snap_keyboard_code[3][1],snap_keyboard_code[3][2],snap_keyboard_code[3][3]);  
  370.   kb_timer.expires = jiffies + KB_TIMER_DELAY;  
  371.   add_timer(&kb_timer);  
  372.   
  373.   //printk("timeCount:%d\n",timeCount);  
  374.     
  375.   if (timeCount==TIME_OUT) //扫描5次后仍然没有得到稳定键值  
  376.   {  
  377.    //复位计数器  
  378.    timeCount=1;  
  379.    kbdev.keyStatus =KEY_UP;  
  380.    //使能中断  
  381.    enableIrq();  
  382.    //关闭定时器  
  383.    del_timer(&kb_timer);  
  384.   
  385.    del_timer(&repeat_timer);  
  386.    //printk("enable irq \n\n\n");  
  387.    curr_keyboard_code = 0;  
  388.    pre_keyboard_code= 0 ;  
  389.    memset(snap_keyboard_code,0,12*sizeof(u_short));  
  390.   }  
  391.   else  
  392.    timeCount++;  
  393.  }  
  394.    
  395.  spin_unlock_irq(&(kbdev.lock));  
  396.    
  397. }  
  398.   
  399. /*---------------------------------------------------- 
  400. *  func:  从循环队列中读取按键的键码 
  401.  
  402. *  param:  
  403.  
  404.  
  405. *  return: 按键的键码 
  406. *                    
  407. ------------------------------------------------------*/  
  408. static inline int kbRead()  
  409. {  
  410.  u_short keyvalue;  
  411.   
  412.  spin_lock_irq(&(kbdev.lock));  
  413.    
  414.   keyvalue = BUF_TAIL;  
  415.   
  416.  INCBUF(kbdev.tail );  
  417.   
  418.  spin_unlock_irq(&(tsdev.lock));  
  419.   
  420.  return keyvalue;  
  421. }  
  422.   
  423. /*---------------------------------------------------- 
  424. *  func:  对应文件读的函数,如果循环队列中有键码, 
  425.     则将键码拷贝到用户空间的buffer中 
  426. *  param:  
  427. *         
  428.  
  429. *  return:  
  430. *         返回从循环队列中读取的键码的字节数 
  431. * 
  432. *                    
  433. ------------------------------------------------------*/  
  434.   
  435. static ssize_t  
  436. S3C2440_kb_read(struct file *filp, char *buffer, size_t count, loff_t * ppos)  
  437. {  
  438.  u_short keyvalue;  
  439.  if(kbdev.head == kbdev.tail)  
  440.  {  
  441.     
  442.   return 0;  
  443.  }  
  444.  else  
  445.  {  
  446.     
  447.   keyvalue = kbRead();  
  448.   count = sizeof(keyvalue);  
  449.   /*将数据拷贝到用户空间*/  
  450.   copy_to_user(buffer,&(keyvalue),count);  
  451.   return count;  
  452.  }  
  453.   
  454.    
  455. }  
  456.   
  457. /*---------------------------------------------------- 
  458. *  func:  与打开文件对应的open函数,初始化全局变量和定 
  459. *         时器以及请求中断 
  460. *  param:  
  461. *         
  462. * 
  463. *  return:  
  464. *                    
  465. ------------------------------------------------------*/  
  466.   
  467. static int S3C2440_kb_open(struct inode *inode, struct file *filp)  
  468. {  
  469.   
  470.  kbdev.keyStatus = KEY_UP;  
  471.  kbdev.head=kbdev.tail = 0;  
  472.  kbdev.lock = SPIN_LOCK_UNLOCKED;  
  473.  repeat_lock = SPIN_LOCK_UNLOCKED;  
  474.   
  475.  output_giop(0);  
  476.   
  477.  //初始化定时器  
  478.  init_timer(&kb_timer);  
  479.  kb_timer.function = kb_timer_handler;  
  480.   
  481.  //初始化重复按键定时器   
  482.  init_timer(&repeat_timer);  
  483.  repeat_timer.function = repeat_timer_handler;  
  484.   
  485.   
  486.  /*if(requestIrq() !=0) 
  487.   return -1;*/  
  488.  enableIrq();  
  489.   
  490.  MOD_INC_USE_COUNT;  
  491.   
  492.  return 0;  
  493. }  
  494.   
  495.    
  496.   
  497. static struct file_operations kb_fops = {  
  498.       owner: THIS_MODULE,  
  499.       open:     S3C2440_kb_open,  
  500.       read:     S3C2440_kb_read,  
  501.       release: s3c2440_kb_release,  
  502. };  
  503.   
  504. /*---------------------------------------------------- 
  505. *  func:  中断处理程序,关闭中断开启键盘扫描定时器 
  506. *  param:  
  507. *         
  508. * 
  509. *  return:  
  510. *                    
  511. ------------------------------------------------------*/  
  512. static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)  
  513.   
  514. {     
  515.    
  516.  spin_lock_irq(&kbdev.lock);  
  517.   
  518.  //禁止所有中断  
  519.  disable_irq(IRQ_EINT1);  
  520.  disable_irq(IRQ_EINT3);  
  521.  disable_irq(IRQ_EINT8);  
  522.    
  523.  kbdev.irq = irq;  
  524.  //printk("irq=%d\n",kbdev.irq);  
  525.   
  526.  //启动定时器  
  527.  kb_timer.expires = jiffies + KB_TIMER_DELAY;  
  528.  add_timer(&kb_timer);  
  529.   
  530.  repeat_timer.expires = jiffies + REPEAT_START_DELAY;  
  531.  add_timer(&repeat_timer);  
  532.   
  533.    
  534.    
  535.  spin_unlock_irq(&kbdev.lock);  
  536. }  
  537. /*---------------------------------------------------- 
  538. *  func:  初始化eint中断相关寄存器,安装中断处理程序 
  539. *  param:  
  540. *         
  541. * 
  542. *  return:  
  543. *                    
  544. ------------------------------------------------------*/  
  545. static int requestIrq()  
  546. {  
  547.  int ret;  
  548.  /* Enable  interrupt */  
  549.  //==================================================  
  550.  //  irq: Linux中断号,与硬件中断号不同      
  551.  //  handle: 中断处理程序         
  552.  //  flag:   SA_INTERRUPT指示这是个快速中断处理程序   
  553.  //  dev_id: 用于共享的中断信号线,通常设置成NULL    
  554.  //===================================================  
  555.    
  556.  ret = set_external_irq(IRQ_EINT1,EXT_FALLING_EDGE,GPIO_PULLUP_DIS);  
  557.  if(ret)  
  558.   goto eint_failed ;  
  559.   
  560.  ret = request_irq(IRQ_EINT1, keyboard_interrupt, SA_INTERRUPT,  
  561.      DEVICE_NAME, NULL);  
  562.       
  563.  if(ret)  
  564.   goto eint1_failed;  
  565.  ret = set_external_irq(IRQ_EINT8,EXT_FALLING_EDGE,GPIO_PULLUP_DIS);  //EXT_LOWLEVEL  
  566.  if(ret)  
  567.   goto eint_failed;  
  568.   
  569.  ret = request_irq(IRQ_EINT8, keyboard_interrupt, SA_INTERRUPT,  
  570.      DEVICE_NAME, NULL);  
  571.  if(ret)  
  572.   goto eint8_failed;  
  573.   
  574.  ret = set_external_irq(IRQ_EINT3,EXT_FALLING_EDGE,GPIO_PULLUP_DIS);  
  575.  if(ret)  
  576.   goto eint_failed;  
  577.   
  578.  ret = request_irq(IRQ_EINT3, keyboard_interrupt, SA_INTERRUPT,  
  579.      DEVICE_NAME, NULL);  
  580.  if(ret)  
  581.   goto eint3_failed;  
  582.   
  583.  return 0;  
  584.   
  585. eint3_failed:  
  586.  free_irq(IRQ_EINT3, keyboard_interrupt);  
  587. eint8_failed:  
  588.  free_irq(IRQ_EINT8, keyboard_interrupt);  
  589. eint1_failed:  
  590.  free_irq(IRQ_EINT1, keyboard_interrupt);  
  591.   
  592. eint_failed:  
  593.   
  594.  printk(DEVICE_NAME ": IRQ Requeset Error\n");  
  595.   
  596.  return ret;  
  597.   
  598. }  
  599.   
  600.   
  601. static int s3c2440_kb_release(struct inode *inode, struct file *filp)  
  602. {  
  603.   /*注销设备*/  
  604. // unregister_chrdev(kbMajor, DEVICE_NAME);  
  605.   
  606.     /*释放中断*/  
  607. /* 
  608.  free_irq(IRQ_EINT1,NULL); 
  609.  
  610.  free_irq(IRQ_EINT8,NULL); 
  611.  
  612.  free_irq(IRQ_EINT3,NULL); 
  613.  
  614.  MOD_DEC_USE_COUNT; 
  615. */  
  616.  return 0;  
  617. }  
  618.   
  619. /*---------------------------------------------------- 
  620. *  func: 初始化键盘驱动,注册字符设备 
  621. *  param:  
  622. *         
  623. * 
  624. *  return:  
  625.    >=0 : 初始化键盘驱动成功 
  626.    <0: 失败 
  627. *                    
  628. ------------------------------------------------------*/  
  629. static int __init s3c2440_kb_init(void)  
  630. {  
  631.  int ret;  
  632.   
  633.  /*初始化管腿配置*/  
  634.   
  635.  init_gpjcon();  
  636.   
  637.  output_giop(0);  
  638.   
  639.    
  640.    
  641.  /*注册设备*/  
  642.  ret = register_chrdev(99, DEVICE_NAME, &kb_fops);  
  643.  if(ret < 0) {  
  644.   printk(DEVICE_NAME " can't get major number\n");  
  645.   return ret;  
  646.  }  
  647.  kbMajor = ret;  
  648.   
  649.  printk("%s: major number=99\n",DEVICE_NAME);  
  650.   
  651.  requestIrq();  
  652.    
  653.  //暂时禁止所有中断,等到open时再打开  
  654.  disable_irq(IRQ_EINT1);  
  655.  disable_irq(IRQ_EINT3);  
  656.  disable_irq(IRQ_EINT8);  
  657.   
  658.  return 0;  
  659. }  
  660.   
  661. /*---------------------------------------------------- 
  662. *  func: 注销字符设备,释放中断 
  663. *  param:  
  664. *         
  665. * 
  666. *  return:  
  667.     
  668. *                    
  669. ------------------------------------------------------*/  
  670. static void __exit s3c2440_kb_exit(void)  
  671. {  
  672.    
  673.  /*注销设备*/  
  674.  unregister_chrdev(kbMajor, DEVICE_NAME);  
  675.  printk("exit\n");  
  676.   
  677.     /*释放中断*/  
  678.  free_irq(IRQ_EINT1,NULL);  
  679.   
  680.  free_irq(IRQ_EINT8,NULL);  
  681.   
  682.  free_irq(IRQ_EINT3,NULL);  
  683. }  
  684.   
  685. module_init(s3c2440_kb_init);  
  686. module_exit(s3c2440_kb_exit);  
  687.   
  688. //EXPORT_SYMBOL(s3c2440_kb_init);  
  689. //EXPORT_SYMBOL(s3c2440_kb_exit); 

如果将此驱动和qtopia程序结合起来,需要修改qt源代码的qkeyboard_qws.cpp文件,添加对矩阵键盘的支持

  1. class QWSHPCButtonsHandler : public QWSKeyboardHandler  
  2. {  
  3.     Q_OBJECT  
  4. public:  
  5.     QWSHPCButtonsHandler();  
  6.     virtual ~QWSHPCButtonsHandler();  
  7.   
  8.     bool isOpen() { return buttonFD > 0; }  
  9.   
  10. private slots:  
  11.     void readKeyboardData();  
  12.   
  13. private:  
  14.     QString terminalName;  
  15.     int buttonFD;  
  16.     struct termios newT, oldT;  
  17.     QSocketNotifier *notifier;  
  18. };  
  19.   
  20.    
  21.   
  22. QWSHPCButtonsHandler::QWSHPCButtonsHandler() : QWSKeyboardHandler()  
  23. {  
  24. #ifdef QT_QWS_HPC  
  25.     terminalName = "/dev/keyboard";  
  26.     buttonFD = -1;  
  27.     notifier = 0;  
  28.   
  29.     if ((buttonFD = open(terminalName, O_RDONLY | O_NDELAY, 0)) < 0) {  
  30.  qWarning("Cannot open %s\n", terminalName.latin1());  
  31.   return;  
  32.     }  
  33.   
  34.  notifier = new QSocketNotifier( buttonFD, QSocketNotifier::Read, this );  
  35.  connect( notifier, SIGNAL(activated(int)),this,  
  36.    SLOT(readKeyboardData()) );  
  37.  
  38. #endif  
  39. }  
  40.   
  41. QWSHPCButtonsHandler::~QWSHPCButtonsHandler()  
  42. {  
  43. #ifdef QT_QWS_HPC  
  44.     if ( buttonFD > 0 ) {  
  45.  ::close( buttonFD );  
  46.  buttonFD = -1;  
  47.     }  
  48. #endif  
  49. }  
  50.   
  51. void QWSHPCButtonsHandler::readKeyboardData()  
  52. {  
  53. #ifdef QT_QWS_HPC  
  54. //-----------port form ButtonDetect-begin-----------  
  55.   int tempint,i;  
  56.  unsigned short buffer[1];  
  57.  tempint=0;  
  58.  int current_press=-1;  
  59.    
  60.  do{  
  61.   tempint=read(buttonFD,buffer,1);  
  62.   if(tempint > 0 )  
  63.   {  
  64.   // printf("\nCurrent Press Buttom %d \n",buffer[0]);  
  65.    current_press = (int)buffer[1];  
  66.    goto set_hpckey;  
  67.   }  
  68.   
  69.  }while(tempint >0);  
  70.   
  71.    
  72.   
  73. //-----------port form ButtonDetect-end-------------  
  74.   
  75. set_hpckey:  
  76.   
  77.  int k=(-1);  
  78.         switch(current_press) {          
  79.           case 3:       k=Qt::Key_Up; break//  
  80.           case 11:       k=Qt::Key_Down; break//   
  81.           case 8:       k=Qt::Key_Left;   break//  
  82.           case 6:      k=Qt::Key_Right;  break//  
  83.           case 7:       k=Qt::Key_Enter; break// Enter  
  84.           case 4:       k=Qt::Key_Escape; break// Enter  
  85.           default: k=(-1); break;  
  86.         }  
  87.   
  88.  if ( k >= 0 )   
  89.  {  
  90.   qwsServer->processKeyEvent( 0, k, 0, 1, false );  
  91.  }  
  92.  
  93. #endif  


  评论这张
 
阅读(212)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018