網(wǎng)站建設推廣什么意思百度競價排名醫(yī)院事件
總結
pinctrl作為驅(qū)動
iomuxc節(jié)點在設備樹里面 存儲全部所需的引腳配置信息
iomux節(jié)點匹配pinctrl子系統(tǒng)
控制硬件外設的時候 要知道有哪些gpio 再看gpio有哪些服用寄存器
接著在程序配置gpio相關寄存器 這樣搞效率很低
所以用iomux節(jié)點保存所有的引腳組 pinctrl驅(qū)動起來的時候獲得所有引腳信息 保存在內(nèi)存
pinctrl子系統(tǒng)預先確定引腳的數(shù)量和名字
- 為每個引腳的配置信息分配內(nèi)存
- pinctrl子系統(tǒng)統(tǒng)一管理每個引腳的使用狀態(tài)
-iomux節(jié)點存放了各種引腳屬性,pinctrl驅(qū)動解析iomux節(jié)點,存放引腳信息進入內(nèi)存
iomux節(jié)點里如何填寫
//iomuxc節(jié)點
//imx6ull.dtsi
iomuxc: iomuxc@20e0000 {compatible = "fsl,imx6ul-iomuxc";reg = <0x20e0000 0x4000>;};
//繼續(xù)擴展 引用iomux節(jié)點 **imx6ull-seeed-npi.dts**
&iomuxc {pinctrl-names = "default","init","sleep"; //選定引腳狀態(tài)pinctrl-0 = <&pinctrl_uart1>; //一個狀態(tài)就是一組引腳,比如對應下面pinctrl-1 =<&xxx>;pinctrl-2 =<&yyy>;
...pinctrl_uart1: uart1grp {fsl,pins = <MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1>;};...
}
上面 引腳里面的宏是什么意思
MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX
#define MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x0084 0x0310 0x0000 0 0
< mux_reg conf_reg input_reg mux_mode input_val >0x0084 0x0310 0x0000 0x0 0x0
mux_reg:引腳復用設置寄存器 基地址+mux_reg 就是 PIN 的復用寄存器地址。
conf_reg : 設置這個引腳的電氣屬性的寄存器地址 基地址+conf_reg =設置pin的電氣屬性地址
input_reg:引腳輸入設置寄存器 有些外設有 input_reg 寄存器
引腳需要輸入功能時設置
mux_mode:復用寄存器設置值
設置引腳復用
input_val:輸入寄存器設置值
設置引腳輸入特性
宏的最后跟隨了一串數(shù)字 用來設置PIN的電氣屬性值 比如IO 的上/下拉、驅(qū)動能力和速度等
引腳狀態(tài)初始化
在設備樹里面節(jié)點 會變成plantform_dev 會執(zhí)行probe進行匹配驅(qū)動
但是執(zhí)行probe和drv配對之前 先回執(zhí)行really_porbe() 這個函數(shù)和下面的引腳狀態(tài)關系很大
用來初始化引腳值
//iomuxc節(jié)點
//imx6ull.dtsi
iomuxc: iomuxc@20e0000 {compatible = "fsl,imx6ul-iomuxc";reg = <0x20e0000 0x4000>;};
//繼續(xù)擴展 引用iomux節(jié)點 **imx6ull-seeed-npi.dts**
&iomuxc {pinctrl-names = "default","init","sleep"; //選定引腳狀態(tài)pinctrl-0 = <&pinctrl_uart1>; //一個狀態(tài)就是一組引腳,比如對應下面pinctrl-1 =<&xxx>;pinctrl-2 =<&yyy>;
...pinctrl_uart1: uart1grp {fsl,pins = <MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1>;};...
}
還是用上一個設備樹舉例 看了下面的例子
就知道驅(qū)動的引腳其實在 probe之前就已經(jīng)初始化好了電氣屬性了
drivers/base/dd.c
static int really_probe(struct device *dev, struct device_driver *drv)
{int ret = -EPROBE_DEFER;
...
re_probe:dev->driver = drv;ret = pinctrl_bind_pins(dev); //這里根據(jù)iomux節(jié)點的 幾個引腳狀態(tài)來初始化引腳組
...if (dev->bus->probe) {ret = dev->bus->probe(dev);if (ret)goto probe_failed;} else if (drv->probe) {ret = drv->probe(dev); //這個是熟悉的probeif (ret)goto probe_failed;}...}
int pinctrl_bind_pins(struct device *dev)dev->pins->default_state = pinctrl_lookup_state(dev->pins->p,PINCTRL_STATE_DEFAULT);//從設備節(jié)點狀態(tài)找到指定狀態(tài)//本次是default狀態(tài)dev->pins->init_state = pinctrl_lookup_state(dev->pins->p,PINCTRL_STATE_INIT); /這次找init狀態(tài)if (IS_ERR(dev->pins->init_state))pinctrl_select_state(dev->pins->p,dev->pins->default_state);//沒有init狀態(tài)變成default狀態(tài)elseret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);//有的話引腳變成init狀態(tài)