日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux下被遗忘的gpio_keys按键驱动

發(fā)布時(shí)間:2023/12/20 linux 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux下被遗忘的gpio_keys按键驱动 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

我們新項(xiàng)目硬件設(shè)計(jì)上使用gpio口做按鍵,所以我就需要搞定這個(gè)驅(qū)動(dòng),本來想自己寫一個(gè)gpio口的按鍵驅(qū)動(dòng),然后看了下內(nèi)核下面的代碼,已經(jīng)有現(xiàn)成的了。Linux內(nèi)核下游很多很多的現(xiàn)成驅(qū)動(dòng),只要你想得到的,基本都是有現(xiàn)成的,當(dāng)然了,不包括一些非正常的需求性問題,學(xué)會(huì)在Linux下找驅(qū)動(dòng),看驅(qū)動(dòng)和內(nèi)核代碼,我覺得是一件享受和快樂的事情。

不過我還是在使用這個(gè)驅(qū)動(dòng)上遇到了問題。

1. 先說ADC 按鍵

之前的文章有寫過adc按鍵的實(shí)現(xiàn),無非就是為了省點(diǎn)GPIO口。

RK 利用SARADC 來做多個(gè)按鍵

2. GPIO?按鍵硬件原理圖

3. 驅(qū)動(dòng)代碼

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

完整代碼可查看

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

驅(qū)動(dòng)代碼流程,從probe處開始

剛開始的時(shí)候,我連dts文件都不會(huì)寫,因?yàn)橹皼]有接觸過這個(gè)驅(qū)動(dòng)。然后看了gpio_keys_get_devtree_pdata函數(shù),之后又看了內(nèi)核代碼下其他項(xiàng)目其他平臺(tái)的dts文件,才知道怎么寫這個(gè)驅(qū)動(dòng)的dts文件。

實(shí)話說,這個(gè)驅(qū)動(dòng)完成了很多我們需要的功能,比如防抖,比如中斷,比如按鍵label等等。

3.1 gpio_keys_get_devtree_pdata 函數(shù)解析dts文件

這個(gè)文件解析的dts 有兩種方式,一種是直接傳入irq的,一種是只傳入gpio口的。

我們的這個(gè)項(xiàng)目,就只傳入了gpio口。

3.2 gpio_keys_setup_key 函數(shù)

這個(gè)函數(shù)用來設(shè)置gpio口的中斷的,直接看代碼會(huì)比較清楚。

下面這個(gè)函數(shù),我還沒有想清楚它的作用,看了回調(diào)函數(shù)里面的實(shí)現(xiàn),是為了把開啟的工作隊(duì)列停止掉。但是我加了打印并沒有打印,我猜測(cè)是為了防止誤觸發(fā),就是按鍵按下的時(shí)間非常短的時(shí)候,才會(huì)調(diào)用這個(gè)。

/***?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 驅(qū)動(dòng)修改

驅(qū)動(dòng)修改的代碼如下

---?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:

可以確定的是,如果不修改的話,肯定是會(huì)出錯(cuò)的。

你要知道,這個(gè)驅(qū)動(dòng)是在2005年就完成編寫了,中間經(jīng)過了多少次的系統(tǒng)升級(jí),而且很多廠商主推的還是ADC按鍵驅(qū)動(dòng),GPIO口驅(qū)動(dòng)默認(rèn)情況下是會(huì)被拋棄的,廠商釋放的SDK根本就不會(huì)記得修改這個(gè)驅(qū)動(dòng)代碼,所以別以為你的手機(jī)運(yùn)行正常里面就沒有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. 測(cè)試驅(qū)動(dòng)

燒錄后按下按鍵,可以看到鍵值上報(bào).


推薦閱讀:

專輯|Linux文章匯總

專輯|程序人生

專輯|C語言

我的知識(shí)小密圈

關(guān)注公眾號(hào),后臺(tái)回復(fù)「1024」獲取學(xué)習(xí)資料網(wǎng)盤鏈接。

歡迎點(diǎn)贊,關(guān)注,轉(zhuǎn)發(fā),在看,您的每一次鼓勵(lì),我都將銘記于心~

嵌入式Linux

微信掃描二維碼,關(guān)注我的公眾號(hào)

總結(jié)

以上是生活随笔為你收集整理的linux下被遗忘的gpio_keys按键驱动的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。