Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1260312
  • 博文数量: 548
  • 博客积分: 7597
  • 博客等级: 少将
  • 技术积分: 4224
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-15 13:21
个人简介

嵌入式软件工程师&&太极拳

文章分类

全部博文(548)

文章存档

2014年(10)

2013年(76)

2012年(175)

2011年(287)

分类: 嵌入式

2012-04-28 12:40:58


点击(此处)折叠或打开

  1. /****************************************************************************
  2.  * *
  3.  * Copyright (c) 2004 - 2009 Nuvoton Tech. Corp. All rights reserved. *
  4.  * *
  5.  ****************************************************************************/

  6. /****************************************************************************
  7.  *
  8.  * FILENAME
  9.  * nuc700_keypad.c
  10.  *
  11.  * VERSION
  12.  * 1.0
  13.  *
  14.  * DESCRIPTION
  15.  * NUC700 keypad driver
  16.  *
  17.  * DATA STRUCTURES
  18.  * None
  19.  *
  20.  * FUNCTIONS
  21.  * None
  22.  *
  23.  * HISTORY
  24.  * 2005/09/09         Ver 1.0 Created by PC34 YHan
  25.  *
  26.  * REMARK
  27.  * None
  28.  *************************************************************************/

  29. #include <linux/init.h>
  30. #include <linux/slab.h>
  31. #include <asm/errno.h>
  32. #include <asm/delay.h>
  33. //#include <asm/fcntl.h>
  34. #include <asm/arch/irqs.h>
  35. #include <linux/mm.h>
  36. #include <linux/poll.h>
  37. #include <linux/module.h>
  38. #include <asm/hardware.h>
  39. #include <asm/io.h>
  40. #include <asm/arch/nuc700_keypad.h>

  41. #define MAJOR_NUM 192

  42. static int volatile kpd_get=0;
  43. static int volatile kpd_block=1;
  44. unsigned char DEV_NAME[10] = "Keypad";

  45. typedef struct _keymap
  46. {
  47.     short row;
  48.     short col;    
  49. }keymap;

  50. keymap key __attribute__ ((aligned (4)));

  51. static DECLARE_WAIT_QUEUE_HEAD(read_wait_a);

  52. static void read_task_block()
  53. {    
  54.     DECLARE_WAITQUEUE(wait, current);
  55.     add_wait_queue(&read_wait_a, &wait);
  56.     set_current_state(TASK_INTERRUPTIBLE);

  57.     schedule();
  58.         
  59.     set_current_state(TASK_RUNNING);
  60.     remove_wait_queue(&read_wait_a, &wait);

  61.     return ;
  62. }


  63. static void read_task_wake_up(void)
  64. {
  65.     wake_up_interruptible(&read_wait_a);
  66.     
  67.     return ;
  68. }


  69. void nuc700kpi_irq(int irq, void *dev_id, struct pt_regs *regs)
  70. {
  71.     
  72.     volatile unsigned int status;    
  73.     kpd_get=1;
  74.     
  75.     key.row = 0;
  76.     key.col = 0;
  77.     
  78.     status = readl(KPISTATUS);
  79.     #ifdef KPI_DEBUG
  80.     printk("KPI ISR KPISTATUS=0x%08x\n",status);
  81.     #endif
  82.     if(status&0x00210000)
  83.     {        
  84.      key.row = (status&0x00000078)>>3;
  85.      key.col = (status&0x00000007);        
  86.     }
  87.     
  88.     if(kpd_block)
  89.         read_task_wake_up();
  90.     
  91.     return;
  92.     
  93. }


  94. int nuc700kpi_open(struct inode* i,struct file* f)
  95. {
  96.     int result;
  97.     int irq;
  98.     int old_cfg;
  99.     kpd_block=1;

  100.     if(f->f_flags & 0x800)    //0x800:04000
  101.         kpd_block=0;
  102.     
  103.     
  104.     irq = INT_KEYPAD;
  105.     
  106.     MOD_INC_USE_COUNT;
  107.         
  108.     result = request_irq(irq, nuc700kpi_irq, 0, DEV_NAME,NULL);
  109.     if(result!=0)
  110.         printk("register the keypad_irq failed!\n");
  111.     
  112.     old_cfg=readl(GPIO_CFG);
  113.     old_cfg=old_cfg&GPIO_CFG_MASK;
  114.     old_cfg=old_cfg|GPIO_CFG_VALUE;
  115.     writel(old_cfg,GPIO_CFG);
  116.     
  117.         #ifdef KPI_DEBUG
  118.         printk("KPI OPEN:\nKPICONF=0x%08x\nGPIO_CFG=0x%08x\n",readl(KPICONF),readl(GPIO_CFG));
  119.         #endif

  120.     return 0;
  121. }

  122. int nuc700kpi_close(struct inode* i,struct file* f)
  123. {
  124.     MOD_DEC_USE_COUNT;
  125.     free_irq(INT_KEYPAD,NULL);
  126.     
  127.     return 0;
  128. }


  129. ssize_t nuc700kpi_read(struct file *filp, char *buff, size_t read_mode, loff_t *offp)
  130. {
  131.     kpd_block = read_mode ;
  132.     
  133.     if(kpd_block)
  134.     {
  135.         read_task_block();
  136.     }
  137.     
  138.     if(kpd_get)
  139.     {
  140.         kpd_get=0;
  141.         copy_to_user(buff,(char*)&key,sizeof(keymap));
  142.         key.row = 0;
  143.         key.col = 0;
  144.         return 1;
  145.     }
  146.     else
  147.         return -1;    
  148. }

  149. static int nuc700kpi_ioctl(struct inode *inode, struct file *flip,
  150.                                                              unsigned int cmd, unsigned long arg)
  151. {
  152.     int err = 0;
  153.     
  154.     if(_IOC_TYPE(cmd) != KEYPAD_MAGIC) return -ENOTTY;
  155.     if(_IOC_NR(cmd) > KEYPAD_MAXNR) return -ENOTTY;

  156.     if(_IOC_DIR(cmd) & _IOC_READ)
  157.         err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
  158.     else if(_IOC_DIR(cmd) & _IOC_WRITE)
  159.         err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
  160.         
  161.     if(err)
  162.         return -EFAULT;
  163.     
  164.     switch (cmd)
  165.     {
  166.         case KPD_BLOCK:    
  167.             kpd_block=1;
  168.             flip->f_flags &= ~0x800;
  169.             break;
  170.         case KPD_NONBLOCK:    
  171.             kpd_block=0;
  172.             flip->f_flags |= ~0x800;
  173.             
  174.             break;
  175.         default:
  176.             break;
  177.     }    
  178.     
  179.     return 0;        
  180. }

  181. struct file_operations nuc700kpi_fops =
  182. {
  183.     owner: THIS_MODULE,
  184.     open: nuc700kpi_open,
  185.     read: nuc700kpi_read,
  186.     ioctl:nuc700kpi_ioctl,
  187.     release: nuc700kpi_close,
  188. };


  189. static int __init nuc700kpi_reg(void)
  190. {        
  191.     int result;
  192.     int old_cfg;
  193.     result = register_chrdev(MAJOR_NUM,DEV_NAME,&nuc700kpi_fops);
  194.     if(result<0)
  195.     {
  196.         printk("initial the device error!\n");
  197.         return (result);    
  198.     }    
  199.     
  200.     old_cfg=readl(GPIO_CFG);
  201.     old_cfg=old_cfg&GPIO_CFG_MASK;
  202.     old_cfg=old_cfg|GPIO_CFG_VALUE;
  203.     writel(old_cfg,GPIO_CFG);
  204.     
  205.     writel(0,KPICONF);
  206.     writel(0,KPI3KCONF);
  207.     writel(0,KPISTATUS);    
  208.     old_cfg=readl(GPIO_DIR);
  209.     old_cfg |= 0x3FF0000;
  210.     writel(old_cfg,GPIO_DIR);

  211.     writel(KPICONF_VALUE,KPICONF);    
  212.     
  213.     init_waitqueue_head(&read_wait_a);
  214.     
  215.     printk("NUC700 Keypad initialized successful\n");
  216.     
  217.     return (result);
  218.     
  219. }



  220. static void nuc700kpi_exit(void)
  221. {
  222.     unregister_chrdev(MAJOR_NUM,DEV_NAME);
  223.     
  224.     return;
  225. }

  226. module_init(nuc700kpi_reg);
  227. module_exit(nuc700kpi_exit);


点击(此处)折叠或打开

  1. /****************************************************************************
  2.  *
  3.  * Copyright (c) 2004 - 2006 Nuvoton Tech. Corp. All rights reserved.
  4.  *
  5.  ****************************************************************************/

  6. /****************************************************************************
  7.  *
  8.  * FILENAME
  9.  * nuc700_keypad.h
  10.  *
  11.  * VERSION
  12.  * 1.0
  13.  *
  14.  * DESCRIPTION
  15.  *    kpi driver header file
  16.  *
  17.  * DATA STRUCTURES
  18.  *        None
  19.  *
  20.  * FUNCTIONS
  21.  *        None
  22.  *
  23.  * HISTORY
  24.  *    2005/09/09         Ver 1.0 Created by PC34 YHan
  25.  *
  26.  * REMARK
  27.  * None
  28.  *************************************************************************/

  29. #ifndef NUC700_KEYPAD_H
  30. #define NUC700_KEYPAD_H

  31. //#define KPI_DEBUG

  32. #define KPICONF 0xFFF88000
  33. #define KPI3KCONF 0xFFF88004
  34. #define KPILPCONF 0xFFF88008
  35. #define KPISTATUS 0xFFF8800C


  36. #define GPIO_CFG 0xFFF83020
  37. #define GPIO_DIR    0xFFF83024
  38. #define GPIO_CFG_MASK 0xFFF00000
  39. #define GPIO_CFG_VALUE 0x000AAAAA
  40. #define KPICONF_VALUE 0x000405FA



  41. #define KEYPAD_MAGIC 'k'
  42. #define KEYPAD_MAXNR 2

  43. #define KPD_BLOCK            _IOW('k', 1, unsigned int)
  44. #define KPD_NONBLOCK        _IOW('k', 2, unsigned int)

  45. #endif

阅读(702) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~