免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1229 | 回复: 0
打印 上一主题 下一主题

MINI6410 input类型按键驱动 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-23 01:46 |只看该作者 |倒序浏览
 
交叉编译是arm-linux-gcc 4.4.1 内核是linux-2.6.28.6
 
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <mach/map.h>
#include <plat/gpio-cfg.h>
#include <plat/regs-clock.h>
#include <plat/regs-gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-bank-n.h>
MODULE_AUTHOR("HaNdAEr");
MODULE_LICENSE("GPL");
 
struct input_dev* button_devp;
static char *name = "s3c6410_buttons";
struct button_irq_desc{
 int irq;
 //int pin;
 int number;
 char *name;
};
static struct button_irq_desc button_irqs[] = {
 { IRQ_EINT(0),  /*S3C64XX_GPN(0), */  0,  "KEY1"},
 { IRQ_EINT(1),  /*S3C64XX_GPN(1), */  1,  "KEY2"},
 { IRQ_EINT(2),  /*S3C64XX_GPN(2), */  2,  "KEY3"},
 { IRQ_EINT(3),  /*S3C64XX_GPN(3), */  3,  "KEY4"},
 { IRQ_EINT(4),  /*S3C64XX_GPN(4), */  4,  "KEY5"},
 { IRQ_EINT(5),  /*S3C64XX_GPN(5), */  5,  "KEY6"},
 { IRQ_EINT(19), /*S3C64XX_GPL(11),*/  11, "KEY7"},
 { IRQ_EINT(20), /*S3C64XX_GPL(12),*/  12, "KEY8"},
};
static irqreturn_t  button_interrupt(int irq, void* dev_id)
{
 struct button_irq_desc *button_irqs = (struct button_irq_desc*)dev_id;
 int updown,reportval;
 if(button_irqs->number <0){
  return -1;
 }
 if(button_irqs->number <=5){
  updown = readl(S3C64XX_GPNDAT) & ( 0x1 << button_irqs->number);
 }
if(button_irqs->number == 11 || button_irqs->number == 12){
  updown = readl(S3C64XX_GPLDAT) & ( 0x1 << button_irqs->number);
 }
 reportval = updown ? 0 : 1;
 switch(button_irqs->number)
 {
  case IRQ_EINT(0):
   input_report_key(button_devp, BTN_0, reportval);
   break;
  case IRQ_EINT(1):
   input_report_key(button_devp, BTN_1, reportval);
   break;
  case IRQ_EINT(2):
   input_report_key(button_devp, BTN_2, reportval);
   break;
  case IRQ_EINT(3):
   input_report_key(button_devp, BTN_3, reportval);
   break;
  case IRQ_EINT(4):
   input_report_key(button_devp, BTN_4, reportval);
   break;
  case IRQ_EINT(5):
   input_report_key(button_devp, BTN_5, reportval);
   break;
  case IRQ_EINT(19):
   input_report_key(button_devp, BTN_6, reportval);
   break;
  case IRQ_EINT(20):
   input_report_key(button_devp, BTN_7, reportval);
   break;
  default:
   break;
 }   
 input_sync(button_devp);
 return IRQ_RETVAL(IRQ_HANDLED);
}
static int __init button_init(void)
{
 int i;
 int err = 0;
 int ret = 0;
 struct input_dev *input_dev;
 input_dev = input_allocate_device();
 if(!input_dev){
  printk(KERN_ERR"Unable to alloc the input device!!\n");
 }
 button_devp = input_dev;
/* 
button_devp->evbit[0] = BIT(EV_KEY) | BIT(EV_SYN);
 button_devp->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0) | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) |
  BIT_MASK(BTN_3) | BIT_MASK(BTN_4) | BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7);
*/
 button_devp->name = name;
 for(i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++)
 {
  err = request_irq(button_irqs[i].irq, button_interrupt, IRQ_TYPE_EDGE_BOTH, button_irqs[i].name, (void *)&button_irqs[i]);
  if(err)
  {
   break;
  }
 }
 if(err)
 {
  i--;
  for(; i >= 0; i--)
  {
   if(button_irqs[i].irq < 0)
   {
    continue;
   }
   disable_irq(button_irqs[i].irq);
   free_irq(button_irqs[i].irq, (void*)&button_irqs[i]);
  }
  return -EBUSY;
 }
 
 set_bit(EV_KEY, button_devp->evbit);
 set_bit(BTN_0,  button_devp->keybit);
 set_bit(BTN_1,  button_devp->keybit);
 set_bit(BTN_2,  button_devp->keybit);
 set_bit(BTN_3,  button_devp->keybit);
 set_bit(BTN_4,  button_devp->keybit);
 set_bit(BTN_5,  button_devp->keybit);
 set_bit(BTN_6,  button_devp->keybit);
 set_bit(BTN_7,  button_devp->keybit);
 ret = input_register_device(button_devp);
 
 if(ret < 0){
  printk("input_register_device(): failed !! \n");
 }
 return ret;
}
static void __exit button_exit(void)
{
 int i;
 for(i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++)
 {
  disable_irq(button_irqs[i].irq);
  free_irq(button_irqs[i].irq, (void*)&button_irqs[i]);
 }
 input_unregister_device(button_devp);
}
module_init(button_init);
module_exit(button_exit);
 
 
 
 
 
 
测试函数:
 
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
#include <linux/input.h>
int main(void)
{
 struct input_event ievent;
 int fd = open("/dev/input/event1",O_RDWR );
 if(fd < 0){
  printf("Unable open /dev/input/event0\n");
  return -1;
 }
 while(1){
  if(read(fd, &ievent, sizeof(struct input_event)) < 0);
  return -1;
  if(ievent.type == EV_KEY){
   switch(ievent.code){
    case BTN_0:
     ievent.value ? printf("key1 is pressed!\n"):printf("key1 is released!!\n");
     break;
    case BTN_1:
     ievent.value ? printf("key2 is pressed!\n"):printf("key2 is released!!\n");
     break;
    case BTN_2:
     ievent.value ? printf("key3 is pressed!\n"):printf("key3 is released!!\n");
     break;
    case BTN_3:
     ievent.value ? printf("key4 is pressed!\n"):printf("key4 is released!!\n");
     break;
    case BTN_4:
     ievent.value ? printf("key5 is pressed!\n"):printf("key5 is released!!\n");
     break;
    case BTN_5:
     ievent.value ? printf("key6 is pressed!\n"):printf("key6 is released!!\n");
     break;
    case BTN_6:
     ievent.value ? printf("key7 is pressed!\n"):printf("key7 is released!!\n");
     break;
    case BTN_7:
     ievent.value ? printf("key8 is pressed!\n"):printf("key8 is released!!\n");
     break;
   }
  }
 }
 close(fd);
 return 0;
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP