input子系统——linux驱动学习笔记(一)

我们下面通过自己编译个最简单的按键输入程序,来学习和理解input子系统。
程序的功能就是一个单独的按键,按下后产生中断并执行相应的程序,代码如下:


#include<linux/init.h>
#include<linux/module.h>
#include<asm/uaccess.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<linux/device.h>
#include<asm/io.h>
#include<linux/kernel.h>
#include<linux/errno.h>
#include<linux/poll.h>
#include<linux/interrupt.h>
#include<linux/input.h>
#include<linux/irq.h>
#include<asm/irq.h>
#include<asm-arm/arch-s3c2410/regs-gpio.h>  //S3C2410_GPF0_EINT
#include<asm/hardware.h>


MODULE_LICENSE("GPL");
MODULE_AUTHOR("Daisy");
MODULE_DESCRIPTION("This is my input button driver for daisy");


#define DEVICE_NAME  "button_daisy"


static struct input_dev *button_dev;


static irqreturn_t button_interrupt(int irq, void* dummy)
{
printk("button_interrupt\n");
input_report_key(button_dev, BTN_0, 1);
input_sync(button_dev);
return IRQ_HANDLED;
}


static int __init input_button_init(void)
{
printk("input_button_init\n");
int err;
s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_EINT0);
set_irq_type(IRQ_EINT0, IRQ_TYPE_EDGE_FALLING);
if (request_irq(IRQ_EINT0, button_interrupt, IRQF_DISABLED, "button_daisy", NULL))
{
printk("Can't request irq\n");
return -EBUSY;
}
button_dev = input_allocate_device();
if(!button_dev)
{
printk("input dev alloc err\n");
err  = -ENOMEM;
goto err_free_irq;
}
button_dev->evbit[0] = BIT(EV_KEY);
button_dev->keybit[BIT_WORD(BTN_0)] = BIT(BTN_0);
err = input_register_device(button_dev);
if (err)
{
printk("fail to register input device\n");
goto err_free_dev;
}

err_free_irq:
free_irq(IRQ_EINT0, button_interrupt);
err_free_dev:
input_free_device(button_dev);
return err;
}


static void input_button_exit(void)
{
printk("input_button_exit\n");
input_free_device(button_dev);
free_irq(IRQ_EINT0, button_interrupt);
}


module_init(input_button_init);
module_exit(input_button_exit);


说明:
1、如果注册中断request_irq不清楚,可以看这篇转载的文章:
http://blog.csdn.net/daisy_chenting/article/details/6948159

2、对于input子系统的使用,首先就是
button_dev = input_allocate_device();
接着设置一些button_dev的参数,我们先来看struct input_dev这个结构体:

struct input_dev {
/* private: */
void *private;/* do not use */
/* public: */


const char *name;
const char *phys;
const char *uniq;
struct input_id id;


unsigned long evbit[BITS_TO_LONGS(EV_CNT)];  //产生或接受什么样的事件的指示位,这里用到的就是EV_KEY,在//ADC中,就用到了EV_SYN、EV_KEY、EV_ABS。
unsigned long relbit[BITS_TO_LONGS(REL_CNT)];      //产生或接受什么样的按键代码
unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
unsigned long swbit[BITS_TO_LONGS(SW_CNT)];


unsigned int keycodemax;
unsigned int keycodesize;
void *keycode;
int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);
int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);


struct ff_device *ff;


unsigned int repeat_key;
struct timer_list timer;


int sync;


int abs[ABS_MAX + 1];
int rep[REP_MAX + 1];


unsigned long key[BITS_TO_LONGS(KEY_CNT)];
unsigned long led[BITS_TO_LONGS(LED_CNT)];
unsigned long snd[BITS_TO_LONGS(SND_CNT)];
unsigned long sw[BITS_TO_LONGS(SW_CNT)];


int absmax[ABS_MAX + 1];
int absmin[ABS_MAX + 1];
int absfuzz[ABS_MAX + 1];
int absflat[ABS_MAX + 1];


int (*open)(struct input_dev *dev);
void (*close)(struct input_dev *dev);
int (*flush)(struct input_dev *dev, struct file *file);
int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);


struct input_handle *grab;


spinlock_t event_lock;
struct mutex mutex;


unsigned int users;
int going_away;


struct device dev;
union {/* temporarily so while we switching to struct device */
struct device *dev;
} cdev;


struct list_headh_list;
struct list_headnode;
};

初始化的最后一步就是input_register_device(button_dev)把自己的input设备注册进input子系统。

下面的文章将会继续介绍Input子系统的其他部分,从而对input子系统的整体有一个全面的认识。
     

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值