linux下的gpio转串口驱动,X-026-KERNEL-Linux gpio driver的移植之gpio range
X-026-KERNEL-Linux gpio driver的移植之gpio range
作者:wowo 發(fā)布于:2017-9-27 22:27
分類:X Project
1. 前言
我們在[1][2]中提到過,鑒于gpio的特殊性,pinctrl subsystem特意留了一個后門(gpio range),gpio driver可以通過這個后門直接向pinctrl subsystem申請將某個pin用作gpio功能。本文將根據(jù)一個簡單的示例,介紹這個后門的使用方法,以加深對相關(guān)機制的理解。
注1:本文的測試方法和[3]中的一致,即:通過gpiolib sysfs api控制LED0(GPIOA19)的亮滅,因而不再羅列詳細步驟。
2. 移植步驟
由[2]可知,gpio range的主要目的就是將gpio命名空間(gpio)轉(zhuǎn)換為pinctrl命名空間(pin),并由pinctrl subsystem訪問硬件實現(xiàn)gpio有關(guān)的功能控制。因此gpio range的移植步驟注要包括:
2.1 pinctrl命名空間和gpio命名空間的定義
參考”X-025-KERNEL-Linux gpio driver的移植之基本功能[3]”中有關(guān)gpiochip的實現(xiàn),本例中的GPIOA19的gpio命名空間為:
gpiochip:gpioa
編號:19
同理,按照“X-023-KERNEL-Linux pinctrl driver的移植[4]”中的方法,結(jié)合bubblegum-96的原理圖,我們可以把GPIOA19所在的管腳編號為"F3",它對應(yīng)的pinctrl命名空間為:
pin controller:pinctrl@0xe01b0000
編號:52
@@ -68,6 +68,7 @@ static const struct pinctrl_pin_desc s900_pins[] = {
PINCTRL_PIN(15, "B6"),
PINCTRL_PIN(24, "C5"),
PINCTRL_PIN(37, "D8"),
+?????? PINCTRL_PIN(52, "F3"),
PINCTRL_PIN(60, "G1"),
PINCTRL_PIN(61, "G2"),
};
2.2 將gpio number轉(zhuǎn)換為pin number
命名空間定義完成后,可以按照[2]中的步驟,在dts中定義一個gpio range,將gpio number轉(zhuǎn)換為pin number,如下:
@@ -39,7 +39,7 @@
clock-frequency = <24000000>;
};
-?????? pinctrl@0xe01b0000 {
+?????? pinctrl1: pinctrl@0xe01b0000 {
compatible = "actions,s900-pinctrl";
reg = <0 0="" 0xe01b0000="" 0x550="">;
@@ -56,6 +56,7 @@
gpioa: gpio@0xe01b0000 {
compatible = "actions,s900-gpio";
reg = <0 0="" 12="" 0xe01b0000="">;
base = <0>;
+?????????????? gpio-ranges = ;
};
其中黃色背景那一行的含義是:將gpioa中的19號gpio,和pinctrl1中的52號pin,對應(yīng)。
2.3 修改gpio driver和pinctrl driver,二者配合,完成gpio的request、free、direction_input以及direction_output等操作
1)修改pinctrl driver,實現(xiàn)pinmux_ops中g(shù)pio_request_enable、gpio_disable_free、gpio_set_direction等回調(diào)函數(shù)
這三個API的輸入?yún)?shù)都是range指針和offset(如下所示),通過它們可以找到這個GPIO所在的gpiochip、GPIO bank、GPIO number、對應(yīng)pin所在的pin controller、pin number等信息。基于這些信息,可以獲得相應(yīng)的硬件信息(寄存器、bit偏移等)。
int (*gpio_request_enable) (struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset);
void (*gpio_disable_free) (struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset);
int (*gpio_set_direction) (struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset,
bool input);
2)修改gpio chip的.request、.free、.direction_input、.direction_output等回調(diào)函數(shù),讓它們調(diào)用pinctrl subsystem提供的相關(guān)API,如下:
int pinctrl_request_gpio(unsigned gpio) ;
void pinctrl_free_gpio(unsigned gpio) ;
int pinctrl_gpio_direction_input(unsigned gpio);
int pinctrl_gpio_direction_output(unsigned gpio);
注2:有些硬件平臺,在完成上面步驟1)的時候,可能會遇到一些困擾,例如怎么根據(jù)gpio和pin的信息,找到對應(yīng)的硬件控制信息(寄存器、bit偏移等),這時我們可以靈活處理。例如在本文例子所使用的bubblegum-96平臺上,gpio的pinmux功能并沒有單獨的寄存器控制,而是通過gpio的in或者out功能的使能,覆蓋其它的pinmux功能。此時我們可以把硬件配置的操作交給gpio driver,而pinctrl driver只處理管腳的互斥。具體可參考下面patch的改動。
3. 測試步驟
請參考[3]中的測試。測試結(jié)果如下(看到s900_gpio_request_enable中的打印,就說明我們的移植成功了):
/ # mkdir /sys
/ # mount -t sysfs /sys /sys
/ # echo 19 > /sys/class/gpio/export
[?? 55.136218] owl_pinctrl e01b0000.pinctrl: s900_gpio_request_enable, range(19/52/1), offset 52
/ # echo out > /sys/class/gpio/gpio19/direction
[?? 86.886343] owl_gpio e01b0000.gpio: offset 19, value 0
/ # echo 1 > /sys/class/gpio/gpio19/value
[? 100.223812] owl_gpio e01b0000.gpio: offset 19, value 1
/ # echo 0 > /sys/class/gpio/gpio19/value
[? 120.467468] owl_gpio e01b0000.gpio: offset 19, value 0
4. 參考文檔
[5] Schematics_Bubblegum96.pdf
原創(chuàng)文章,轉(zhuǎn)發(fā)請注明出處。蝸窩科技,www.wowotech.net。
評論:
bigpillow
2017-11-10 10:54
剛寫完一套GPIO driver.
當(dāng)時考慮到不同chip通用性使用了gpiochip_add_pin_range function
現(xiàn)在看看在DTS里面原來這么方便。
發(fā)表評論:
昵稱
郵件地址 (選填)
個人主頁 (選填)
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的linux下的gpio转串口驱动,X-026-KERNEL-Linux gpio driver的移植之gpio range的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c 高级语言,C作为高级语言?
- 下一篇: mysql 5.6的gtid_mode_