输入子系统(二)-35

输入子系统(二)

使用输入子系统设计按键驱动

  • 我们可以将开发板上的按键值设置为input.h文件里面的宏定义的任意一个,比如我们本
    次实验将开发板_上的KEY按键值设置为KEY__0
  • 在编写input设备驱动的时候我们需要先申请一个input dev结构体变量,使用
    input allocate
    device 函数来申请一个input dev.
  • 此函数原型如下所示:
struct input dev *input_allocate_device(void)
  • 函数参数和返回值含义如下:
  • 参数:无。
  • 返回值:申请到的 input dev.

  • 如果要注销的input设备的话需要使用input_ free_ device函数来释放掉前面申请到的input_ dev,

  • input_ free_ _device函数原型如下:

void input_free_device(struct input dev *dev)

函数参数和返回值含义如下:

  • dev:要注册的input dev。

  • 返回值: 0, input_ dev注册成功;负值,input_ dev注册失败。


  • 同样的,注销input 驱动的时候也需要使用input unregister _device 函数来注销掉前面注册

input_ unregister _device函数原型如下:

void input_unregister_device(struct input dev *dev)
  • 函数参数和返回值含义如下:
  • dev:要注销的input dev。
  • 返回值:无。

最终我们需要把事件上报上去,,上报事件我们使用的函数要针对具体的时间来 上报。比
如,按键我们使用input _report. _key 函数。同样的还有一- 些其他的事件上报函数,函数如下
图所示:

void input_report_rel(struct input dev *dev, unsigned int code, int value)
void input_report_abs(struct input dev *dev, unsigned int code, int value)
void input_report_ff_status(struct input dev *dev, unsigned int code, int value)
void input_report_switch(struct input dev *dev, unsigned int code, int value)
void input_mt_sync(struct input dev *dev)

当我们上报事件以后还需要使用input_ sync函数来告诉Linux内核input 子系统上
报结束,input. sync函数本质是上报一个同步事件,

此函数原型如下所示:

void input sync(struct input dev *dev)
  • 函数参数和返回值含义如下:
  • dev:需要上报同步事件的input dev

代码

  • input_test.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/interrupt.h>
#include <linux/of_irq.h>
#include <linux/time.h>
#include <linux/input.h>

int gpio_num;
int irq = 0;
struct device_node *test_device_node;
struct property *test_node_property;
struct input_dev *test_dev;

static void  timer_function(unsigned long data);

DEFINE_TIMER(test_timer, timer_function, 0, 0);

static void timer_function(unsigned long data){

    int  value;

    printk("timer_function \n");
    // mod_timer(&test_timer, jiffies + 1*HZ);
    value = !gpio_get_value(gpio_num);
    input_report_key(test_dev,KEY_1,value);
    input_sync(test_dev);
}
struct of_device_id of_match_table[] = {

    {.compatible = "test_keys"},
    {}

};

irq_handler_t test_key(int irq, void *args){
    printk("test_key \n");

    test_timer.expires = jiffies + msecs_to_jiffies(20);
    add_timer(&test_timer);

    return IRQ_HANDLED;

}

int beep_probe(struct platform_device *pdev){

    int ret = 0;


    printk("beep_probe 匹配成功了 \n");
    test_device_node = of_find_node_by_path("/test_key");
    if (test_device_node == NULL)
    {
        printk("of_find_node_by_path is error \n");
        return -1;
    }
    
    gpio_num = of_get_named_gpio(test_device_node, "touch-gpio", 0);
    if (gpio_num < 0)
    {
        printk("of_get_named_gpio is error \n");
        return -1;
    }
    
    gpio_direction_input(gpio_num);

    
    //irq = gpio_to_irq(gpio_num);

    irq = irq_of_parse_and_map(test_device_node, 0);

    printk("irq is %d \n", irq);

    ret = request_irq(irq, test_key, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, "test_key", NULL);
    if (ret < 0)
    {
        printk("request_irq is error \n");
        return ret;
    }

    test_dev = input_allocate_device();
    test_dev->name = "test_key";
    __set_bit(EV_KEY, test_dev->evbit);
    __set_bit(KEY_1,test_dev->keybit);

    ret = input_register_device(test_dev);
    if (ret <0)
    {
       printk("input_register_device is error \n");
       goto error_input_register;
    }
    
    return 0;

error_input_register:
    input_unregister_device(test_dev);
}

int beep_remove(struct platform_device *pdev){
    printk("beep_remove \n");
    return 0;
}

const struct platform_device_id  beep_idtable = {
    .name = "test_keys"
};

struct platform_driver beep_device =
{
    .probe = beep_probe,
    .remove = beep_remove,
    .driver = {
        .name = "123",
        .owner = THIS_MODULE,
        .of_match_table = of_match_table
    },
    .id_table = &beep_idtable
};

static int beep_driver_init(void){
    printk(KERN_EMERG "hello world enter \n");
    int ret = 0;
    ret = platform_driver_register(&beep_device);
    if (ret < 0)
    {
        printk("platform_driver_register 失败\n");
    }

    printk("platform_driver_register ok\n");
    
    return 0;
}

static void beep_driver_exit(void){
    printk(KERN_EMERG "hello world exit! \n");
    del_timer(&test_timer);
    free_irq(irq, NULL);
    input_unregister_device(test_dev);
    platform_driver_unregister(&beep_device);
}

module_init(beep_driver_init);
module_exit(beep_driver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("LIYU");
  • app.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>

int main(int argc, char * argv[]){
    int  fd;
    int  value;
    fd = open("/dev/input/event3", O_RDWR);
    struct input_event test_event;
    if (fd <0)
    {
        perror("open error \n");
        return fd;
    }

    while (1)
    {
        read(fd, &test_event, sizeof(test_event));
        printf("type all is %#x \n", test_event.type);
        if (test_event.type == EV_KEY)
        {
            printf("type KEY is %#x \n", test_event.type);
            printf("type value is %#x \n", test_event.value);
             printf("type code is %#x \n", test_event.code);
        }
        
    }
    
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值