linux下被遗忘的gpio_keys按键驱动

我们新项目硬件设计上使用gpio口做按键,所以我就需要搞定这个驱动,本来想自己写一个gpio口的按键驱动,然后看了下内核下面的代码,已经有现成的了。Linux内核下游很多很多的现成驱动,只要你想得到的,基本都是有现成的,当然了,不包括一些非正常的需求性问题,学会在Linux下找驱动,看驱动和内核代码,我觉得是一件享受和快乐的事情。

不过我还是在使用这个驱动上遇到了问题。

1. 先说ADC 按键

之前的文章有写过adc按键的实现,无非就是为了省点GPIO口。

RK 利用SARADC 来做多个按键

2. GPIO 按键硬件原理图

3. 驱动代码

kernel-4.4/drivers/input/keyboard/gpio_keys.c

完整代码可查看

https://gitee.com/weiqifa/gpio_key/blob/master/gpio_keys.c

驱动代码流程,从probe处开始

刚开始的时候,我连dts文件都不会写,因为之前没有接触过这个驱动。然后看了gpio_keys_get_devtree_pdata函数,之后又看了内核代码下其他项目其他平台的dts文件,才知道怎么写这个驱动的dts文件。

实话说,这个驱动完成了很多我们需要的功能,比如防抖,比如中断,比如按键label等等。

3.1 gpio_keys_get_devtree_pdata 函数解析dts文件

这个文件解析的dts 有两种方式,一种是直接传入irq的,一种是只传入gpio口的。

我们的这个项目,就只传入了gpio口

3.2 gpio_keys_setup_key 函数

这个函数用来设置gpio口的中断的,直接看代码会比较清楚。

下面这个函数,我还没有想清楚它的作用,看了回调函数里面的实现,是为了把开启的工作队列停止掉。但是我加了打印并没有打印,我猜测是为了防止误触发,就是按键按下的时间非常短的时候,才会调用这个。

/*** devm_add_action() - add a custom action to list of managed resources* @dev: Device that owns the action* @action: Function that should be called* @data: Pointer to data passed to @action implementation** This adds a custom action to the list of managed resources so that* it gets executed as part of standard resource unwinding.*/
int devm_add_action(struct device *dev, void (*action)(void *), void *data)
{struct action_devres *devres;devres = devres_alloc(devm_action_release,sizeof(struct action_devres), GFP_KERNEL);if (!devres)return -ENOMEM;devres->data = data;devres->action = action;devres_add(dev, devres);return 0;
}

3.3 驱动修改

驱动修改的代码如下

--- a/kernel-4.4/drivers/input/keyboard/gpio_keys.c
+++ b/kernel-4.4/drivers/input/keyboard/gpio_keys.c
@@ -32,6 +32,11 @@#include <linux/of_irq.h>#include <linux/spinlock.h>+
+#define LOG_TAG "[BUTTON]: %s() line: %d "
+#define PRINTK_T(fmt, args...)  printk(KERN_INFO LOG_TAG fmt, __FUNCTION__, __LINE__,  ##args)
+
+struct gpio_button_data {const struct gpio_keys_button *button;struct input_dev *input;
@@ -462,9 +467,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,spin_lock_init(&bdata->lock);if (gpio_is_valid(button->gpio)) {
-
-               error = devm_gpio_request_one(&pdev->dev, button->gpio,
-                                             GPIOF_IN, desc);
+               PRINTK_T("gpio:%d\n",button->gpio);
+               error = devm_gpio_request(&pdev->dev, button->gpio,desc);if (error < 0) {dev_err(dev, "Failed to request GPIO %d, error %d\n",button->gpio, error);
@@ -483,7 +487,9 @@ static int gpio_keys_setup_key(struct platform_device *pdev,if (button->irq) {bdata->irq = button->irq;} else {
+                       gpio_direction_input(button->gpio);irq = gpio_to_irq(button->gpio);
+                       PRINTK_T("===weiqifa=== irq :%d\n",irq);if (irq < 0) {error = irq;dev_err(dev,
@@ -540,8 +546,10 @@ static int gpio_keys_setup_key(struct platform_device *pdev,if (!button->can_disable)irqflags |= IRQF_SHARED;-       error = devm_request_any_context_irq(&pdev->dev, bdata->irq,
-                                            isr, irqflags, desc, bdata);
+       PRINTK_T("===weiqifa=== devm_request_threaded_irq()\n");
+
+       error = devm_request_threaded_irq(&pdev->dev, bdata->irq,NULL,
+                                            isr, irqflags| IRQF_ONESHOT, desc, bdata);if (error < 0) {dev_err(dev, "Unable to claim irq %d; error %d\n",bdata->irq, error);
@@ -709,6 +717,8 @@ static int gpio_keys_probe(struct platform_device *pdev)int i, error;int wakeup = 0;+       PRINTK_T("start.\n");
+if (!pdata) {pdata = gpio_keys_get_devtree_pdata(dev);if (IS_ERR(pdata))
@@ -779,6 +789,8 @@ static int gpio_keys_probe(struct platform_device *pdev)device_init_wakeup(&pdev->dev, wakeup);+       PRINTK_T("end.\n");
+return 0;err_remove_group:

可以确定的是,如果不修改的话,肯定是会出错的。

你要知道,这个驱动是在2005年就完成编写了,中间经过了多少次的系统升级,而且很多厂商主推的还是ADC按键驱动,GPIO口驱动默认情况下是会被抛弃的,厂商释放的SDK根本就不会记得修改这个驱动代码,所以别以为你的手机运行正常里面就没有bug,bug无处不在,只是我们有了重启大法而已。

4. dts 代码

gpio-keys {compatible = "gpio-keys";#address-cells = <1>;#size-cells = <0>;autorepeat;//pinctrl-names = "default";//pinctrl-0 = <&pwrbtn>;button@0 {gpios = <&pio 49 IRQ_TYPE_EDGE_BOTH>;linux,code = <KEY_F13>;label = "GPIO F13 Power";linux,input-type = <1>;gpio-key,wakeup = <1>;debounce-interval = <100>;};button@1 {gpios = <&pio 48 IRQ_TYPE_EDGE_BOTH>;linux,code = <KEY_F14>;label = "GPIO F14 Power";linux,input-type = <1>;gpio-key,wakeup = <1>;debounce-interval = <100>;};button@2 {gpios = <&pio 51 IRQ_TYPE_EDGE_BOTH>;linux,code = <KEY_F15>;label = "GPIO F15 Power";linux,input-type = <1>;gpio-key,wakeup = <1>;debounce-interval = <100>;};};

5. 测试驱动

烧录后按下按键,可以看到键值上报.


推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

关注公众号,后台回复「1024」获取学习资料网盘链接。

欢迎点赞,关注,转发,在看,您的每一次鼓励,我都将铭记于心~

嵌入式Linux

微信扫描二维码,关注我的公众号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/465854.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何通过审计安全事件日志检测密码喷洒(Password Spraying)攻击

许多渗透测试人员和攻击者通常都会使用一种被称为“密码喷洒&#xff08;Password Spraying&#xff09;”的技术来进行测试和攻击。对密码进行喷洒式的攻击&#xff0c;这个叫法很形象&#xff0c;因为它属于自动化密码猜测的一种。这种针对所有用户的自动密码猜测通常是为了避…

单片机编程技巧—状态机编程

摘要&#xff1a;不知道大家有没有这样一种感觉&#xff0c;就是感觉自己玩单片机还可以&#xff0c;各个功能模块也都会驱动&#xff0c;但是如果让你完整的写一套代码&#xff0c;却无逻辑与框架可言&#xff0c;上来就是开始写&#xff01;东抄抄写抄抄。说明编程还处于比较…

啥叫旁路电容?啥叫去耦?可以不再争论了吗

1. 旁路和去耦先谈两个比较重要的概念&#xff1a;旁路电容(Bypass Capacitor)&#xff0c;去耦电容(Decoupling Capacitor)。只要是设计过硬件电路的同学肯定对这两个词不陌生&#xff0c;但真正理解这两个概念的可能并不多。我刚毕业时就问过我的师傅&#xff0c;为什么总是在…

H5活动产品设计指南基础版

本文来自 网易云社区 。 H5一般页面不会很多&#xff0c;看似简单&#xff0c;实际上会有很多细节需要注意&#xff0c;我自己在做过了几个H5之后&#xff0c;发现了一些常犯的问题&#xff0c;做了小结&#xff0c;希望给新开始做H5的产品相关的同学提供一些帮助。 首先说说一…

图解丨在嵌入式设备上实现HTTP服务器

您好呀&#xff0c;我是小二。本期为大家带来一个 WiFi 应用的实际场景&#xff0c;其实在之前「我对 WiFi 驱动移植过程&#xff0c;做了一次总结复盘」这篇文章中有简单提过&#xff0c;但由于内容较多&#xff0c;就单独摘出来了。来自读者的催更????????????&a…

maven详解之仓库

在Maven中&#xff0c;任何一个依赖、插件或者项目构建的输出&#xff0c;都可以称之为构件。 Maven在某个统一的位置存储所有项目的共享的构件&#xff0c;这个统一的位置&#xff0c;我们就称之为仓库。&#xff08;仓库就是存放依赖和插件的地方&#xff09; 任何的构件都有…

Linux内核代码,第一次看到这样使用的宏

晚上看内核代码&#xff0c;看到一个有意思的宏&#xff0c;我之前没有见到过&#xff0c;当然&#xff0c;肯定有人见到过&#xff0c;我写出来是给那些没有看到过的人看的。我说是深夜&#xff0c;那就肯定是深夜代码是从内核里面看到的我们正常使用宏是这样的C语言、嵌入式中…

flex柱状图和折线图的混合图使用

<?xml version"1.0"?> <mx:Application xmlns:mx"http://www.adobe.com/2006/mxml"> <mx:Script> <!--[CDATA[ import mx.collections.ArrayCollection; [Bindable] public var data1:ArrayCollectionnew ArrayCollection([{date:&…

给高通提个问题解决为啥那么久?

我第一次接触高通芯片是在中兴那&#xff0c;我们用的是一款很老的芯片&#xff0c;高通的文档非常多&#xff0c;资料非常丰富&#xff0c;如果有问题的话我一般都会从文档里面找答案。但是&#xff0c;但是&#xff0c;并不是所有的问题都是能自己搞定&#xff0c;比如遇到一…

新公司上班第一天

大家好&#xff0c;文章转自我的朋友helloworld&#xff0c;文中的我并不是我&#xff0c;感谢大家阅读&#xff0c;转载&#xff0c;在看。Hello 各位小伙伴&#xff0c;周一愉快~今天是我到新公司上班的第一天&#xff0c;入职新公司&#xff0c;就好像刚刚谈恋爱一样&#x…

[CTO札记]从Cloud Computing看战略决策:想做、能做与可做 -

1&#xff09;想做--未来方向很多人已经意识到&#xff0c;Cloud Computing未来将是基础设施&#xff0c;扮演水、电、气的角色。可以说&#xff0c;Cloud Computing是很多互联网、电信大公司想做的事。因为&#xff1a;》不仅重要&#xff08;大公司都不想自己的命运掌握在别人…

JAVA基础学习之路(三)类定义及构造方法

类的定义及使用 一&#xff0c;类的定义 class Book {//定义一个类int price;//定义一个属性int num;public static int getMonney(int price, int num) {//定义一个方法return price*num;} }public class test2 {public static void main(String args[]) {Book monney new B…

电子火折子的电路原理

d▲本文要分析的电路看古装剧时&#xff0c;不时可以看到这样的场景&#xff1a;有人从怀里掏出一个“火折子”&#xff0c;对着吹一吹就点着了火&#xff0c;觉得很神奇&#xff1a;更加神奇的是&#xff0c;有才的电子工程师们&#xff0c;重新发明了火折子&#xff0c;也就是…

如何快速构建嵌入式全栈知识体系?

嵌入式是一门交叉学科。一个嵌入式电子产品&#xff08;比如手机&#xff09;从底层到上层&#xff0c;一般会涉及半导体芯片、电子电路、计算机、操作系统、多媒体等不同专业领域的知识。很多从事嵌入式开发的朋友&#xff0c;通常来自不同的专业&#xff08;电子、电气、计算…

台湾高僧称游戏中杀人是罪业死后要下地狱

台湾著名高僧净空法师的一段谈因果报应的视频&#xff0c;近来被上传到网络上&#xff0c;引发网友特别是游戏玩家的极大反应。净空法师在这段视频中说&#xff0c;在电子游戏中杀人所造下 的罪业和杀真人是相同的&#xff0c;死后肯定会下阿鼻地狱&#xff0c;出来后也还要慢慢…

嵌入式系统开发者需要掌握什么技术?

大家好&#xff0c;我是小嵌&#xff0c;在知乎上看到这个问题&#xff0c;其中有一个答主的答案很经典&#xff0c;特此分享给大家。说实话&#xff0c;问题中嵌入式开发这个话题有点庞大&#xff0c;毕竟它涵盖的领域和范围很宽泛。作为一个在嵌入式软件开发方面工作了十多年…

做决定要趁早

之前接触的一个读者朋友&#xff0c;几个月前跟我咨询了问题&#xff0c;那时候因为有个决定困扰他&#xff0c;已经快抑郁了&#xff0c;不过到现在为止&#xff0c;还没有做决定。做决定这个事情&#xff0c;我希望不要拖太久&#xff0c;不要咨询太多无关的人&#xff0c;做…

2009第二届C++技术大会即将在上海隆重召开

2009第二届C技术大会即将在上海隆重召开 作为软件开发语言的翘楚&#xff0c;C对于现代软件的发展功不可没&#xff0c;特别是在系统软件开发领域&#xff0c;C扮演着关键的角色。中国作为全球软件产业最具潜力的市场&#xff0c;越来越多的企业认识到了C及相关系统软件技术在软…

大数据开发你需要知道的十个技术

前言 “当你不创造东西时&#xff0c;你只会根据自己的感觉而不是能力去看待问题。” – WhyTheLuckyStiff 汇总一些自己在大数据路上走过的弯路&#xff0c;愿大家不再掉坑… 1.分布式存储 传统化集中式存储存在已有一段时间。但大数据并非真的适合集中式存储架构。Hadoop设计…

华为这个事,是不是刷KPI?

最近闹的比较热闹的事情是&#xff0c;华为有人提交到Linux 上的代码被审核员点名批评刷KPI&#xff0c;并且&#xff0c;这个邮件还上了头条。提交的代码修改如下From: Zhen Lei <thunder.leizhenhuawei.com> To: Kees Cook <keescookchromium.org>,Anton Voronts…