• 正文
    • 一、GPIO寄存器查找
    • 二、io命令
    • 三、 通過函數(shù)gpiod_direction_output()
    • 四、通過函數(shù)rockchip_set_mux()
    • 五、如何去掉設(shè)備樹中的復(fù)用引腳信息?
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

rk3568 | rk平臺GPIO沖突檢測小技巧

2022/12/26
34
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

上一篇我們講解了如何編寫gpio驅(qū)動,但是實際操作中,經(jīng)常發(fā)現(xiàn)gpio引腳被占用的情況發(fā)生,那么本篇文章就詳細講解rxw平臺下如何快速定位gpio復(fù)用問題以及如何解決。

一、GPIO寄存器查找

要想查看某個GPIO引腳可以配置的功能以及地址信息,需要查看TRM手冊:

《Rockchip?RK3568?TRM?Part1》
    第一步:對于GPIO2 A2,我們轉(zhuǎn)換成下面字符串然后搜索
gpio2a2_sel

這樣我們就可以直接找到該引腳iomux配置寄存器,bit[10:8]。該寄存器地址:

基地址+0x0020

那么如何找到基地址呢?

    第二步:

搜索該引腳寄存器的名字:

GRF_GPIO2A_IOMUX_L

注意向上搜索

可以得到該寄存器基地址名稱:

SYS_GRF
    • 第三步
    直接進入chapter 3

可得SYS_GRF 基地址

0xFDC60000

那么我們就得到了GPIO2 A2的IOMUX配置寄存器地址為

0xFDC60000?+?0x0020

該寄存器的bit[10:8]用于設(shè)置該寄存器功能。

當(dāng)然也可以用下圖來查找,更加方便:

那么找到了這個寄存器地址,我要如何來直接讀取這個寄存器的值呢?

這個可以借助于一個命令io。

二、io命令

io命令可以直接操作某個寄存器,用于查看設(shè)置某個PIO 引腳配置了什么iomux,非常方便。

1. 移植io命令需要的驅(qū)動

RK 的 Android 平臺,默認(rèn)有包含 io 工具(源碼位置:externalio), linux 系統(tǒng)平臺如果沒有此源碼, 可以將 Android 平臺此源碼打包過去編譯即可( linux 平臺代碼同步最新都已帶有 IO 工具,可直接使用命令)。

    第一步:修改Makefile、Kconfig
vim??drivers/char/Makefile

增加
+obj-$(CONFIG_DEVMEM)???????????+=?mem.o
vim?drivers/char/Kconfig
改文件已經(jīng)包含下面信息
?10?config?DEVMEM
?11?????bool?"/dev/mem?virtual?device?support"
?12?????default?y
?13?????help
?14???????Say?Y?here?if?you?want?to?support?the?/dev/mem?device.
?15???????The?/dev/mem?device?is?used?to?access?areas?of?physical
?16???????memory.
?17???????When?in?doubt,?say?"Y".

    第二步:修改驅(qū)動文件

io命令需要內(nèi)核驅(qū)動支持,驅(qū)動文件如下:

drivers/char/mem.c

找到下面代碼:

#ifdef?CONFIG_DEVMEM
?????????[1]?=?{?"mem",?0,?&mem_fops,?FMODE_UNSIGNED_OFFSET?},
#endif

修改為


+//#ifdef?CONFIG_DEVMEM
?????????[1]?=?{?"mem",?0,?&mem_fops,?FMODE_UNSIGNED_OFFSET?},
+//#endif
    第三步:修改配置文件rockchip_defconfig
vim??arch/arm64/configs/rockchip_defconfig
增加
+CONFIG_DEVMEM=y

重新編譯內(nèi)核,燒錄重啟。

rockchip_defconfig需要根據(jù)平臺選擇

    第四步:查看mem字符設(shè)備:
rk3568_r:/?#?ls?/dev/mem?-l
ls?/dev/mem?-l
crw-------?1?media?media?1,???1?2017-08-04?09:00?/dev/mem

io命令正是通過這個字符設(shè)備來實現(xiàn)寄存器的讀寫的。

2. 命令說明

rk3568_r:/dev?#?io
io
Raw?memory?i/o?utility?-?$Revision:?1.5?$

io?-v?-1|2|4?-r|w?[-l?<len>]?[-f?<file>]?<addr>?[<value>]

????-v?????????Verbose,?asks?for?confirmation
????-1|2|4?????Sets?memory?access?size?in?bytes?(default?byte)
????-l?<len>???Length?in?bytes?of?area?to?access?(defaults?to
???????????????one?access,?or?whole?file?length)
????-r|w???????Read?from?or?Write?to?memory?(default?read)
????-f?<file>??File?to?write?on?memory?read,?or
???????????????to?read?on?memory?write
????<addr>?????The?memory?address?to?access
????<val>??????The?value?to?write?(implies?-w)

Examples:
????io?0x1000??????????????????Reads?one?byte?from?0x1000
????io?0x1000?0x12?????????????Writes?0x12?to?location?0x1000
????io?-2?-l?8?0x1000??????????Reads?8?words?from?0x1000
????io?-r?-f?dmp?-l?100?200????Reads?100?bytes?from?addr?200?to?file
????io?-w?-f?img?0x10000???????Writes?the?whole?of?file?to?memory

Note?access?size?(-1|2|4)?does?not?apply?to?file?based?accesses.

3. 舉例1,通過IO讀寄存器:

讀取gpio2 A2引腳配置寄存器

io?-4?-l?0x30?0xFDC60000
-4?????????:?按字(4個字節(jié))?訪問內(nèi)存?
0x30???????:?讀取0x30(48)個字節(jié)
0xFDC60000?:?基地址

由上圖可得0xFDC60020的bit[10:8]值為1

所以該io引腳被設(shè)置的iomux為

3'h1:?SDMMC0_CLK

如果我們是希望通過設(shè)備樹設(shè)置該引腳為普通gpio,那么該值應(yīng)該為0,

那么這就說明了,我們設(shè)置失敗了,

那就可以到設(shè)備樹中查找設(shè)置SDMMC0的地方,將其注釋掉。

要讀取單個寄存器,可以用下面命令:

?io?-4?-r?0xFDC60024

4. 舉例2,通過IO寫寄存器

比如已經(jīng)通過命令:io -4 -r 0xFDC60024讀出了寄存器的值,那么此時想把gpio2 A2修改為普通GPIO,
那么只需要對0xFDC60024這個寄存器的第 3 個 1 寫 0,那么可以如下操作:

io?-4?–w?0xFDC60024?0x01002011

注意:

    • 第三個1對應(yīng)是bit[10:8]通過 io 寫的寄存器值 reboot 后不會保留為什么寄存器地址后面的十六進制值的 bit [24]寫 1?因為該寄存器的 16bit 至31 bit 是寫有效位,默認(rèn)為 0,即不可寫。因為要往[8] bit 寫 1,所以[8] bit ?對應(yīng)的

 

    寫有效位 16 bit 也要對應(yīng)置 1 才可寫入,這個是根據(jù)寄存器描述而定的。

修改過后,再查看,可以發(fā)現(xiàn)對應(yīng)的位的值變?yōu)榱?:

三、 通過函數(shù)gpiod_direction_output()

思 路 :驅(qū) 動 里 如 果 想 要 去 操 作 GPIO , 肯 定 會 調(diào) 用 到 gpio_direction_output 、gpio_direction_input、 gpiod_direction_output、 gpiod_direction_input 這幾個接口, 他們的定義位置是:

?vim?kernel/drivers/gpio/gpiolib.c

在這些接口里添加判斷對應(yīng)查詢的 IO 口條件,通過以下函數(shù)就可以打印出哪些模塊復(fù)用了該引腳:

dump_stack();?

注意:在 linux3.10 內(nèi)核的 sdk 中用的是 gpio_direction_output 和gpio_direction_input 接 口 ,
在 linux4.4 內(nèi) 核 中 則 是 gpiod_direction_output 和gpiod_direction_input。

下面以 linux4.4 版本為例來講解如何查看引腳:gpio4 b3。

首先,需要計算出代表 gpio4b3 的值,算法如下:

gpio4_B3?=?4?*32?+?(B-A)?*?8?+?3?=?3?*32?+?1?*?8?+?3?=?139

計算方法參考:《rk3568 | 瑞芯微平臺GPIO引腳驅(qū)動編寫》

    • 最前面和 32 相乘的數(shù)字因為是 gpio4,所以是 4

32。如果是 gpio3,那就是 3

    32;括號里面的 A、 B、 C、 D 分別代表數(shù)值 0、 1、 2、 3,在計算時候分別對應(yīng)去減即可,這里因為是 B3,所以用 B-A,如果是 C3,就是 C-A;最后的+3 是因為是 ? B3,如果是 GPIO4B2,那么最后就+2。

注:在 linux4.4 內(nèi)核, io 引腳的值有些變化,也就是按照上文算法計算的結(jié)
果要+1000,所以 GPIO4B3 如果是 linux4.4 內(nèi)核里要填 1139。

int?gpiod_direction_output(struct?gpio_desc?*desc,?int?value)
{
?if?(!desc?||?!desc->chip)?{
??pr_warn("%s:?invalid?GPIOn",?__func__);
??return?-EINVAL;
?}
+??if?(?desc_to_gpio(desc)?==?1139)
+??{
+???printk("dump_stack_startn");
+???dump_stack();
+???printk("dump_stack_endn");
+??}
?if?(test_bit(FLAG_ACTIVE_LOW,?&desc->flags))
??value?=?!value;
?return?_gpiod_direction_output_raw(desc,?value);
}

添加后編譯燒錄,只要對應(yīng)判斷的引腳有被調(diào)用,啟動 log 中就會打印出堆棧,可以根據(jù)找出結(jié)果查看,找到驅(qū)動調(diào)用函數(shù)。

四、通過函數(shù)rockchip_set_mux()

配置IOMUX會調(diào)用該接口,

仍然以引腳gpio4 b3為例。

[drivers/pinctrl/pinctrl-rockchip.c]

??@@?-1224,6?+1224,17?@@?static?int?rockchip_set_mux(struct?rockchip_pin_bank?*bank,?int?pin,?int?mux)
???dev_dbg(info->dev,?"setting?mux?of?GPIO%d-%d?to?%dn",
?????????????bank->bank_num,?pin,?mux);
+???????if((bank->bank_num?==?4)&&(pin?==?11)){
+???????????????printk("6902?setting?mux?of?GPIO%d-%d?to?%dn",
+???????????????????????????????bank->bank_num,?pin,?mux);
+???????????????dump_stack();
+???????}
????if?(bank->iomux[iomux_num].type?&?IOMUX_SOURCE_PMU)
????????????regmap?=?info->regmap_pmu;
    bank_num 表示gpio4這里“ pin ==”后面跟的值計算方式為:將 A0 至 D7 32 個引腳順序?qū)?yīng)數(shù)值 0 至 31,b3為11。

五、如何去掉設(shè)備樹中的復(fù)用引腳信息?

剛才分析,發(fā)現(xiàn)GPIO2 A2被SDMMC0占用,那么如何來解決這個沖突呢?

只要從設(shè)備樹下手即可。

瑞芯微平臺的設(shè)備樹,根據(jù)平臺區(qū)分,往往前綴是:

rk?+?平臺??+?板子型號?+?ddr型號?+?版本

比如rk3568系列設(shè)計的設(shè)備樹文件如下:

arch/arm64/boot/dts/rockchip/rk3568-amp.dtsi
arch/arm64/boot/dts/rockchip/rk3568-android9.dtsi
arch/arm64/boot/dts/rockchip/rk3568-android.dtsi
arch/arm64/boot/dts/rockchip/rk3568-dram-default-timing.dtsi
arch/arm64/boot/dts/rockchip/rk3568.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-android9.dts
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtb
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-linux-spi-nor.dts
arch/arm64/boot/dts/rockchip/rk3568-evb2-lp4x-v10-bt1120-to-hdmi.dts
arch/arm64/boot/dts/rockchip/rk3568-evb2-lp4x-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb2-lp4x-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb4-lp3-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb5-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb5-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10-rk628-bt1120-to-hdmi.dts
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10-rk628-rgb2hdmi.dts
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10-rk630-bt656-to-cvbs.dts
arch/arm64/boot/dts/rockchip/rk3568-evb7-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi
arch/arm64/boot/dts/rockchip/rk3568-iotest-ddr3-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-iotest-ddr3-v10-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-linux.dtsi
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v10-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v10-linux-spi-nand.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v12.dtsi
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v12-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v12-linux-spi-nand.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr.dtsi
arch/arm64/boot/dts/rockchip/rk3568-nvr-linux.dtsi
arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi

一口君的板子是evb1,ddr4,v10版本,所以去掉其他的文件,

我們只需要關(guān)注以下文件即可。

arch/arm64/boot/dts/rockchip/rk3568-android.dtsi
與安卓相關(guān)的信息

arch/arm64/boot/dts/rockchip/rk3568.dtsi?
描述cpu、memory、timer、clk、sata、usb?host、gic、視頻控制器、sram、cru、i2c控制器、uart、pwm、pmu等各種Soc內(nèi)部硬件信息

arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi
與evb1底板相關(guān)的外設(shè)硬件信息

arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
pinctl相關(guān)硬件信息

還有1個描述pinctl引腳驅(qū)動能力的文件:

rockchip-pinconf.dtsi

使用grep命令來查詢:

grep?sdmmc0?arch/arm64/boot/dts/rockchip/rk3568*?-nr

好在信息不多,逐個查看,下面這個文件,我們找到了復(fù)用的地方。

rk3568-pinctrl.dtsi

該引腳被定義為sdmmc0_clk,作為時鐘被使用了。

?sdmmc0?{
??………………
??/omit-if-no-ref/
??sdmmc0_clk:?sdmmc0-clk?{
???rockchip,pins?=
????/*?sdmmc0_clk?*/
????<2?RK_PA2?1?&pcfg_pull_up_drv_level_2>;
??};

修改的方法有很多種:

投機取巧法
將sdmmc0_clk改成其他沒有用的gpio

簡單粗暴法
如果確定沒有使用sdmmc0,可以將所有sdmmc0地方全部注釋掉

設(shè)備樹支持下面這種方法:

#if?0
#endif
    硬件飛線法

找硬件工程師飛線,改用其他的GPIO

    1. 最優(yōu)法

 

    如果sdmmc0也用到了,

那就只能修改沖突的GPIO,

但是這種情況,往往會牽一發(fā)而動全身,

要改好幾處,那就需要各位老鐵細心慢慢修改了。

好了,本文到底結(jié)束。

一口君目標(biāo)是寫100篇瑞芯微平臺的文章,

有喜歡瑞芯微的老鐵,

歡迎大家關(guān)注學(xué)習(xí)。

瑞芯微電子

瑞芯微電子

瑞芯微專注于移動互聯(lián)網(wǎng)、數(shù)字多媒體芯片設(shè)計,是專業(yè)的個人移動信息終端SOC解決方案供應(yīng)商。瑞芯微在移動互聯(lián)網(wǎng)領(lǐng)域有多個較完整的自主創(chuàng)新的知識產(chǎn)權(quán)群,為中國電子業(yè)發(fā)展做出積極努力。目前產(chǎn)品涵蓋Android平板電腦、Android電視機頂盒(智能電視)、電子書、WIFI/藍牙音頻解決方案等。

瑞芯微專注于移動互聯(lián)網(wǎng)、數(shù)字多媒體芯片設(shè)計,是專業(yè)的個人移動信息終端SOC解決方案供應(yīng)商。瑞芯微在移動互聯(lián)網(wǎng)領(lǐng)域有多個較完整的自主創(chuàng)新的知識產(chǎn)權(quán)群,為中國電子業(yè)發(fā)展做出積極努力。目前產(chǎn)品涵蓋Android平板電腦、Android電視機頂盒(智能電視)、電子書、WIFI/藍牙音頻解決方案等。收起

查看更多

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

公眾號『一口Linux』號主彭老師,擁有15年嵌入式開發(fā)經(jīng)驗和培訓(xùn)經(jīng)驗。曾任職ZTE,某研究所,華清遠見教學(xué)總監(jiān)。擁有多篇網(wǎng)絡(luò)協(xié)議相關(guān)專利和軟件著作。精通計算機網(wǎng)絡(luò)、Linux系統(tǒng)編程、ARM、Linux驅(qū)動、龍芯、物聯(lián)網(wǎng)。原創(chuàng)內(nèi)容基本從實際項目出發(fā),保持原理+實踐風(fēng)格,適合Linux驅(qū)動新手入門和技術(shù)進階。