linux驱动通过地址配置按键,linux输入子系统之多个按键

文章目录

linux输入子系统:驱动多个按键

驱动多个按键

一个按键有多个与其相关的元素:

中断号码

按键状态

按键的值

input_dev的详细描述如下图

cfeba4b292a86bff28d52eb405e25875.png

在设备树文件中增加以下信息:

按键定义配置信息如下

key_int_node

{

compatible = "test_key";

#address-cells = <1>; //表示下边寄存器的地址占一个位 reg

#size-cells = <1>; //表示下边寄存器的长度占一个位 reg

key_int@0

{

key_name = "key2_power_eint";

key_code = <116>;

gpio = ;

//中断号描述

reg = <0x11000c20 0x18>;

interrupt-parent = ;

interrupts = <1 0>;

};

key_int@1

{

key_name = "key3_vup_eint";

key_code = <115>;

gpio = ;

reg = <0x11000c20 0x18>;

interrupt-parent = ;

interrupts = <2 0>;

};

};

在代码中也会设计这几个元素

struct device_node *of_get_next_child(const struct device_node *node,struct device_node *prev)

参数1:表示节点

参数2:之前的节点,如果是第一个节点,设置成NULL

#define KEY_NUMS 3

//设计一个对象出来

struct key_desc

{

int irqno;

int key_code;

char *name;

int gpionum;

void *reg_base;

struct device_node *cnp; //可以随时去获取节点各个信息

};

struct key_desc all_key[KEY_NUMS];

void get_all_child_from_node(void)

{

struct device_node *np = of_find_node_by_path("/key_int_node");

if(np)

{

printk("find node ok\n");

}

else

{

printk("find node failed\n");

}

struct device_node *cnp;

struct device_node *prev = NULL;

char *key_name;

u32 code;

int gpionum;

int irqno;

int i = 0;

do

{

//获取到子节点

cnp = of_get_next_child(np,prev);

//找到了子节点

/*

if(cnp != NULL)

{

//获取中断号

irqno = irq_of_parse_and_map(cnp,0);

printk("irqno = %d\n",irqno);

//获取按键name

of_property_read_string(cnp,"key_name",&key_name);

//获取key_code

of_property_read_u32(cnp,"key_code",&code);

//获取gpio

gpionum = of_get_named_gpio(cnp,"gpio",0);

printk("name = %s,code = %s,gpionum = %d,irqno = %d\n",key_name,code,gpionum,irqno);

}*/

if(cnp != NULL)

{

all_key[i++].cnp = cnp; //将当前的节点记录下来

}

prev = cnp; //把当前的设置位prev

} while(of_get_next_child(np,prev) != NULL);

}

在init函数中

//分配inputDev

__set_bit(EV_KEY,inputdev->evbit);

int i;

for(i = 0; i < KEY_NUMS; i++)

{

//设置key_bit,支持哪些按键

//按键值从设备树来

int code;

struct device_node *cnp = all_key[i].cnp;

code = of_property_read_u32(cnp,"key_code",&code);

__set_bit(code,inputdev->keybit);

all_key[i].key_code = code; //先记录下来

//申请中断

int irqno;

irqno = irq_of_parse_and_map(cnp,0);

all_key[i].irqno = irqno;

int irqflags = IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING;

char *key_name;

of_property_read_string(cnp,"key_name",&key_name);

all_key[i].name = key_name;

ret = request_irq(irqno,input_key_irq_handler,irqflags,"key_name",&all_key[i]);

if(ret != 0)

{

printk("request_irq error\n");

goto err_0;

}

}

中断处理

irqreturn_t input_key_irq_handler(int irqno,void *devid)

{

//区分不同的按键

struct key_desc *pdesc = (struct key_desc *)devid;

int gpionum = of_get_named_gpio(pdesc->cnp,"gpio",0);

//直接通过gpio获取按键状态

int value = gpio_get_value();

if(value)

{

input_report_key(inputdev,EV_KEY,pdesc->key_code,1);

input_sync(inputdev); //上报数据结束

}

else

{

input_event(inputdev,EV_KEY,pdesc->key_code,1);

input_sync(inputdev); //上报数据结束

}

return IRQ_HANDLED;

}

标签:node,code,name,cnp,int,linux,key,按键,子系统

来源: https://blog.csdn.net/qq_41782149/article/details/100652158

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值