一、前言
前面我們編寫了基于設(shè)備樹的 LED 驅(qū)動,但是驅(qū)動的本質(zhì)還是沒變,都是配置 LED 燈所使用的 GPIO 寄存器,驅(qū)動開發(fā)方式和裸機基本沒啥區(qū)別。本章我們就來學(xué)習(xí)一下如何借助 pinctrl 和 gpio 子系統(tǒng)來簡化 GPIO 驅(qū)動開發(fā)。?
?Linux 內(nèi)核針對 PIN 的配置推出了 pinctrl 子系統(tǒng),對于 GPIO的配置推出了 gpio 子系統(tǒng)。
本節(jié)先講解 gpio?子系統(tǒng)。?
二、gpio 子系統(tǒng)
1、gpio 子系統(tǒng)簡介
上節(jié)講解了 pinctrl 子系統(tǒng),pinctrl 子系統(tǒng)重點是設(shè)置 PIN(有的 SOC 叫做 PAD)的復(fù)用和電氣屬性,如果 pinctrl 子系統(tǒng)將一個 PIN 復(fù)用為 GPIO 的話,那么接下來就要用到 gpio 子系統(tǒng)了。
gpio 子系統(tǒng)顧名思義,就是用于初始化 GPIO 并且提供相應(yīng)的 API 函數(shù),比如設(shè)置 GPIO為輸入輸出,讀取 GPIO 的值等
gpio 子系統(tǒng)的主要目的是:
方便驅(qū)動開發(fā)者使用 gpio,驅(qū)動開發(fā)者在設(shè)備樹中添加 gpio 相關(guān)信息,然后就可以在驅(qū)動程序中使用 gpio 子系統(tǒng)提供的 API函數(shù)來操作 GPIO,Linux 內(nèi)核向驅(qū)動開發(fā)者屏蔽掉了 GPIO 的設(shè)置過程。
2、I.MX6ULL 的 gpio 子系統(tǒng)驅(qū)動?
<1> 設(shè)備樹中的 gpio 信息
上節(jié)我們通過pinctrl 子系統(tǒng),配置了?UART1_RTS_B 這個 PIN 復(fù)用為 GPIO1_IO19(SD卡CD信號檢測引腳),并設(shè)置了電氣屬性:
pinctrl_hog_1: hoggrp-1 {
fsl,pins = <
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
......
>;
};
要想設(shè)備的某個引腳使用?GPIO1_IO19,那么就需要在該設(shè)備對應(yīng)的設(shè)備樹節(jié)點中描述,在描述的同時會通過 gpio子系統(tǒng)配置 GPIO1_IO19。
// SD卡設(shè)備總節(jié)點
// usdhc1 節(jié)點需要描述 SD 卡所有的信息,因為驅(qū)動要使用
&usdhc1 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc1>;
pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
keep-power-in-suspend;
enable-sdio-wakeup;
vmmc-supply = <®_sd1_vmmc>;
status = "okay";
};
<2> 設(shè)備節(jié)點中?pinctrl 信息詳解
pinctrl-names 中保存了節(jié)點對應(yīng)設(shè)備的不同工作狀態(tài),下面的pinctrl-0、1、2代表各個狀態(tài)對應(yīng)的pinctrl 配置集合,也就是說,如果設(shè)備處于default狀態(tài),會使用pinctrl-0的pinctrl 子系統(tǒng)配置,以此類推。但是上面為什么沒有配置GPIO1_IO19 對應(yīng)的pinctrl 子系統(tǒng)配置呢?pinctrl-0 應(yīng)該是這樣才對:
pinctrl-0 = <
&pinctrl_usdhc1
&pinctrl_hog_1 // 上節(jié)的pinctrl配置
>;
如果沒有對GPIO1_IO19 進行功能復(fù)用,該節(jié)點的引腳就無法使用GPIO功能,這是怎么回事呢?我們可以看iomuxc節(jié)點內(nèi)容(上節(jié)),我們發(fā)現(xiàn)iomuxc節(jié)點已經(jīng)將pinctrl 配置進行初始化調(diào)用(沒必要在上面的usdhc1節(jié)點中,只是進行功能復(fù)用,在哪個節(jié)點中都一樣),功能復(fù)用為GPIO。
<3> 設(shè)備節(jié)點中?gpio 信息詳解
usdhc1設(shè)備節(jié)點中下面的代碼,用來配置該設(shè)備(SD卡)的CD引腳使用哪個IO。
cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
- “&gpio1”表示 CD 引腳所使用的 IO 屬于 GPIO1 組;
- “19” 表示 GPIO1 組的第 19 號 IO,通過這兩個值 SD 卡驅(qū)動程序就知道 CD 引腳使用了 GPIO1_IO19這 GPIO;
- “GPIO_ACTIVE_LOW” 表示低電平有效, “GPIO_ACTIVE_HIGH” 就表示高電平有效。?
根據(jù)上面這些信息,SD 卡驅(qū)動程序就可以使用 GPIO1_IO19 來檢測 SD 卡的 CD 信號了,
打開 imx6ul.dtsi,在里面找到如下所示內(nèi)容:?
gpio1: gpio@209c000 {
compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
reg = <0x0209c000 0x4000>;
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
gpio-ranges = <&iomuxc 0 23 10>, <&iomuxc 10 17 6>,
<&iomuxc 16 33 16>;
};
- “gpio-controller”表示 gpio1 節(jié)點是個 GPIO 控制器。?
- #gpio-cells 為 2,表示一共有兩個 cell。第一個 cell 為 GPIO 編號,比如“&gpio1 3”就表示GPIO1_IO03。第二個 cell 表示 GPIO 極性 , 如果為0(GPIO_ACTIVE_HIGH) 的話表示高電平有效 , 如果為1(GPIO_ACTIVE_LOW)的話表示低電平有效。
<4> gpio 驅(qū)動程序詳解
根據(jù) dtsi 文件中 gpio1 節(jié)點(上方代碼)的 compatible 屬性描述了兼容性,在 Linux 內(nèi)核中搜索“fsl,imx6ul-gpio”和“fsl,imx35-gpio”這兩個字符串,可以查找 GPIO 驅(qū)動文件??梢缘?GPIO 驅(qū)動也是個平臺設(shè)備驅(qū)動,因此當設(shè)備樹中的設(shè)備節(jié)點與驅(qū)動的 of_device_id 匹配以后 probe 函數(shù)就會執(zhí)行,在這里就是 mxc_gpio_probe 函數(shù)。
3、設(shè)備樹中添加 gpio 節(jié)點步驟(總結(jié))
上節(jié)我們已經(jīng)講解了如何創(chuàng)建 test 設(shè)備的 pinctrl 節(jié)點。本節(jié)我們來學(xué)習(xí)一下如何創(chuàng)建 test 設(shè)備的 GPIO 節(jié)點。
?? 創(chuàng)建 test 設(shè)備節(jié)點
?在根節(jié)點“/”下創(chuàng)建 test 設(shè)備子節(jié)點:
test {
/* 節(jié)點內(nèi)容 */
};
???添加 pinctrl 信息?
上節(jié)我們創(chuàng)建了 pinctrl_test 節(jié)點,此節(jié)點描述了 test 設(shè)備所使用的 GPIO1_IO00 這個 PIN 的信息,我們要將這節(jié)點添加到 test 設(shè)備節(jié)點中:文章來源:http://www.zghlxwxcb.cn/news/detail-434959.html
test {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_test>;
/* 其他節(jié)點內(nèi)容 */
};
???添加 GPIO 屬性信息?
我們最后需要在 test 節(jié)點中添加 GPIO 屬性信息,表明 test 所使用的 GPIO 是哪個引腳:?文章來源地址http://www.zghlxwxcb.cn/news/detail-434959.html
test {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_test>;
gpio = <&gpio1 0 GPIO_ACTIVE_LOW>;
}
到了這里,關(guān)于【Linux驅(qū)動開發(fā)】011 gpio子系統(tǒng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!