700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > linux下被遗忘的gpio_keys按键驱动

linux下被遗忘的gpio_keys按键驱动

时间:2022-09-01 03:45:09

相关推荐

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

完整代码可查看

/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()-addacustomactiontolistofmanagedresources*@dev:Devicethatownstheaction*@action:Functionthatshouldbecalled*@data:Pointertodatapassedto@actionimplementation**Thisaddsacustomactiontothelistofmanagedresourcessothat*itgetsexecutedaspartofstandardresourceunwinding.*/intdevm_add_action(structdevice*dev,void(*action)(void*),void*data){structaction_devres*devres;devres=devres_alloc(devm_action_release,sizeof(structaction_devres),GFP_KERNEL);if(!devres)return-ENOMEM;devres->data=data;devres->action=action;devres_add(dev,devres);return0;}

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>++#defineLOG_TAG"[BUTTON]:%s()line:%d"+#definePRINTK_T(fmt,args...)printk(KERN_INFOLOG_TAGfmt,__FUNCTION__,__LINE__,##args)++structgpio_button_data{conststructgpio_keys_button*button;structinput_dev*input;@@-462,9+467,8@@staticintgpio_keys_setup_key(structplatform_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,"FailedtorequestGPIO%d,error%d\n",button->gpio,error);@@-483,7+487,9@@staticintgpio_keys_setup_key(structplatform_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@@staticintgpio_keys_setup_key(structplatform_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,"Unabletoclaimirq%d;error%d\n",bdata->irq,error);@@-709,6+717,8@@staticintgpio_keys_probe(structplatform_device*pdev)inti,error;intwakeup=0;+PRINTK_T("start.\n");+if(!pdata){pdata=gpio_keys_get_devtree_pdata(dev);if(IS_ERR(pdata))@@-779,6+789,8@@staticintgpio_keys_probe(structplatform_device*pdev)device_init_wakeup(&pdev->dev,wakeup);+PRINTK_T("end.\n");+return0;err_remove_group:

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

你要知道,这个驱动是在就完成编写了,中间经过了多少次的系统升级,而且很多厂商主推的还是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=<&pio49IRQ_TYPE_EDGE_BOTH>;linux,code=<KEY_F13>;label="GPIOF13Power";linux,input-type=<1>;gpio-key,wakeup=<1>;debounce-interval=<100>;};button@1{gpios=<&pio48IRQ_TYPE_EDGE_BOTH>;linux,code=<KEY_F14>;label="GPIOF14Power";linux,input-type=<1>;gpio-key,wakeup=<1>;debounce-interval=<100>;};button@2{gpios=<&pio51IRQ_TYPE_EDGE_BOTH>;linux,code=<KEY_F15>;label="GPIOF15Power";linux,input-type=<1>;gpio-key,wakeup=<1>;debounce-interval=<100>;};};

5. 测试驱动

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

推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

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

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

嵌入式Linux

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。