Driver for keys on GPIO using input-subsystem way

/**
  * Driver for keys on GPIO using input-subsystem way

 */

Driver Test:

----------------------------------------------------------driver---------------------------------------------------------------
#include <linux/module.h>
#include <linux/version.h>
  
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <linux/gpio_keys.h>
  
#include <asm/gpio.h>

#define DRIVER_NAME "czinputsubsys_keys"

static struct input_dev *czinput_dev;

//tips: why no static?
struct czkey_desc {
     unsigned char * name;
  int irq;
  int pin;
  int code;
};
//gpio_to_irq(S3C2410_GPF1) is wrong!
static struct czkey_desc aczkey_desc[4] = {
     {"L",                   IRQ_EINT1, S3C2410_GPF1, KEY_L},
     {"S",                   IRQ_EINT4, S3C2410_GPF4, KEY_S},
     {"ENTER",        IRQ_EINT2, S3C2410_GPF2, KEY_ENTER},
     {"LEFTSHIFT", IRQ_EINT0, S3C2410_GPF0, KEY_LEFTSHIFT},
};

 static irqreturn_t czinputsubsys_keys_isr(int irq, void *dev_id)
 {
  printk("driver:czinputsubsys_keys_isr in\n");

  struct czkey_desc *pczkey_desc = (struct czkey_desc *)dev_id;

  int state = (gpio_get_value(pczkey_desc->pin) ? 1 : 0);
 
 
 // input_event(czinput_dev, czinput_dev->evbit[0], pczkey_desc->code, state);
 if(state){
   input_event(czinput_dev, EV_KEY, pczkey_desc->code, 1);//untest 2013.01.15
    printk("driver:czinputsubsys_keys_isr key state:%d\n",state);
  }
 else
  {
  input_event(czinput_dev, EV_KEY, pczkey_desc->code, 0);//untest 2013.01.15
   printk("driver:czinputsubsys_keys_isr key state:%d\n",state);
  }
 
  input_sync(czinput_dev);

  return IRQ_HANDLED;
 }
 
 static int czinputsubsys_keys_init(void)
 {
 printk("driver:czinputsubsys_key_init in\n");
 int error;
 int i ;

 czinput_dev = input_allocate_device();
 if (!czinput_dev){
  printk(KERN_ERR "Cannot request keypad device\n");
  return -ENOMEM;}
 else
  printk("Can request keypad device\n");

 //czinput_dev->evbit[0] =  BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
 //czinput_dev->keybit[0] = BIT(KEY_L) | BIT(KEY_S) | BIT(KEY_ENTER) | BIT(KEY_LEFTSHIFT);
 //czinput_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 set_bit(EV_KEY, czinput_dev->evbit);//untest 2013.01.15

 set_bit(KEY_ENTER, czinput_dev->keybit);
 set_bit(KEY_L, czinput_dev->keybit);
 set_bit(KEY_S, czinput_dev->keybit);
 set_bit(KEY_LEFTSHIFT, czinput_dev->keybit);

 

 czinput_dev->name = DRIVER_NAME;
 //czinput_dev->phys = "gpio-keys/input0";
 //czinput_dev->dev.parent = &pdev->dev;

 //czinput_dev->id.bustype = BUS_HOST;
 //czinput_dev->id.vendor = 0x0001;
 //czinput_dev->id.product = 0x0001;
 //czinput_dev->id.version = 0x0100;

 error = input_register_device(czinput_dev);
 if (error)
    printk(KERN_ERR "Unable to register gpio-keys input device\n");
 else
    printk(KERN_ERR "able to register gpio-keys input device\n");
 
 //for(i=0;i<4;i++)
       // set_irq_type(aczkey_desc[i].irq, IRQ_TYPE_EDGE_BOTH);
//tips: about KERN_ERR?; about IRQF_SAMPLE_RANDOM
//tips: about IRQT_BOTHEDGE is the right way
 for(i=0;i<4;i++){
        error = request_irq(aczkey_desc[i].irq, czinputsubsys_keys_isr, IRQT_BOTHEDGE,
         aczkey_desc[i].name,&aczkey_desc[i]);
        if (error)
              printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n",aczkey_desc[i].irq, error);
     else
      printk("gpio-keys: able to claim irq %d\n",aczkey_desc[i].irq);
  }

 return 0;
 }

 static void czinputsubsys_keys_exit(void)
{
 printk("driver:czinputsubsys_key_exit in\n");
 int i;

 for(i=0;i<4;i++)
   free_irq(aczkey_desc[i].irq, &aczkey_desc[i]);

 input_unregister_device(czinput_dev);
 
 return;
}
 module_init(czinputsubsys_keys_init);
 module_exit(czinputsubsys_keys_exit);
 MODULE_AUTHOR("chaozang(cz) <zangchao.cn@gmail.com>, copy frm teacher:weidongshan,thanks so much!");
 MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs");
 MODULE_LICENSE("GPL");

----------------------------------------------------test commands----------------------------------------------------------

# exec 0</dev/tty1

-------------------------------------------------

Contact: zangchao.cn@gmail.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值