gpio rk3399 控制 GPIO 使用

2021-10-17 05:54:42 字數 4138 閱讀 8035

復用¶

如何定義 gpio 有哪些功能可以復用,在執行時又如何切換功能呢?以 i2c4 為例作簡單的介紹。

查規格表可知,i2c4_sda 與 i2c4_scl 的功能定義如下:

pad# func0 func1

i2c4_sda/gpio1_b3 gpio1b3 i2c4_sda

i2c4_scl/gpio1_b4 gpio1b4 i2c4_scl

在 kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi 裡有:

i2c4: i2c@ff3d0000{

compatible = "rockchip,rk3399-i2c";

reg = <0x0 0xff3d0000 0x0 0x1000>;

clocks = , ;

clock-names = "i2c", "pclk";

interrupts = ;

pinctrl-names = "default", "gpio";

pinctrl-0 = ;

pinctrl-1 = ; //此處原始碼未新增

#address-cells = <1>;

#size-cells = <0>;

status = "disabled";

pinctrl-names 定義了狀態名稱列表: default (i2c 功能) 和 gpio 兩種狀態。

pinctrl-0 定義了狀態 0 (即 default)時需要設定的 pinctrl: &i2c4_xfer

pinctrl-1 定義了狀態 1 (即 gpio)時需要設定的 pinctrl: &i2c4_gpio

這些 pinctrl 在 kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi 中這樣定義:

pinctrl: pinctrl {

compatible = "rockchip,rk3399-pinctrl";

rockchip,grf = ;

rockchip,pmu = ;

#address-cells = <0x2>;

#size-cells = <0x2>;

ranges;

i2c4{

i2c4_xfer: i2c4-xfer{

rockchip,pins = <1 12 rk_func_1 &pcfg_pull_none>, <1 11 rk_func_1 &pcfg_pull_none>;

i2c4_gpio: i2c4-gpio {

rockchip,pins = <1 12 rk_func_gpio &pcfg_pull_none>, <1 11 rk_func_gpio &pcfg_pull_none>;

rk_func_1,rk_func_gpio 的定義在 kernel/include/dt-bindings/pinctrl/rk.h 中:

#define rk_func_gpio 0

#define rk_func_1 1

#define rk_func_2 2

#define rk_func_3 3

#define rk_func_4 4

#define rk_func_5 5

#define rk_func_6 6

#define rk_func_7 7

另外,像 「1 11」,」1 12」 這樣的值是有編碼規則的,編碼方式與上一小節 「輸入輸出」 描述的一樣,」1 11」 代表 gpio1_b3,」1 12」 代表 gpio1_b4。

在復用時,如果選擇了 default (即 i2c 功能),系統會應用 i2c4_xfer 這個 pinctrl,最終將 gpio1_b3 和 gpio1_b4 兩個針腳切換成對應的 i2c 功能;而如果選擇了 gpio ,系統會應用 i2c4_gpio 這個 pinctrl,將 gpio1_b3 和 gpio1_b4 兩個針腳還原為 gpio 功能。

我們看看 i2c 的驅動程式 kernel/drivers/i2c/busses/i2c-rockchip.c 是如何切換復用功能的:

static int rockchip_i2c_probe(struct platform_device *pdev)

struct rockchip_i2c *i2c = null; struct resource *res;

struct device_node *np = pdev->dev.of_node; int ret;//

i2c->sda_gpio = of_get_gpio(np, 0);

if (!gpio_is_valid(i2c->sda_gpio)) {

dev_err(&pdev->dev, "sda gpio is invalid\n");

return -einval;

ret = devm_gpio_request(&pdev->dev, i2c->sda_gpio, dev_name(&i2c->adap.dev));

if (ret) {

dev_err(&pdev->dev, "failed to request sda gpio\n");

return ret;

i2c->scl_gpio = of_get_gpio(np, 1);

if (!gpio_is_valid(i2c->scl_gpio)) {

dev_err(&pdev->dev, "scl gpio is invalid\n");

return -einval;

ret = devm_gpio_request(&pdev->dev, i2c->scl_gpio, dev_name(&i2c->adap.dev));

if (ret) {

dev_err(&pdev->dev, "failed to request scl gpio\n");

return ret;

i2c->gpio_state = pinctrl_lookup_state(i2c->dev->pins->p, "gpio");

if (is_err(i2c->gpio_state)) {

dev_err(&pdev->dev, "no gpio pinctrl state\n");

return ptr_err(i2c->gpio_state);

pinctrl_select_state(i2c->dev->pins->p, i2c->gpio_state);

gpio_direction_input(i2c->sda_gpio);

gpio_direction_input(i2c->scl_gpio);

pinctrl_select_state(i2c->dev->pins->p, i2c->dev->pins->default_state);

首先是呼叫 of_get_gpio 取出裝置樹中 i2c4 結點的 gpios 屬於所定義的兩個 gpio:

gpios = , ;

然後是呼叫 devm_gpio_request 來申請 gpio,接著是呼叫 pinctrl_lookup_state 來查詢 gpio 狀態,而預設狀態 default 已經由框架儲存到 i2c->dev-pins->default_state 中了。

最後呼叫 pinctrl_select_state 來選擇是 default 還是 gpio 功能。

下面是常用的復用 api 定義:

#include

struct device {

#ifdef config_pinctrl

struct dev_pin_info*pins;

#endif

struct dev_pin_info {

struct pinctrl *p;

struct pinctrl_state *default_state;

#ifdef config_pm

struct pinctrl_state *sleep_state;

struct pinctrl_state *idle_state;

#endif

struct pinctrl_state * pinctrl_lookup_state(struct pinctrl *p, const char *name);

int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *s);

RK3399RO 4G 乙太網 WIFI共存

rk3399ro 4g 乙太網 wifi共存 系統 android8.1 基於此文章的修改點,直接按此文件,sepolicy會報neverallow不相容問題。修改點 1.te檔案目錄修改到 device rockchip comm sepolicy 修改對應的file contexts 2.ro ...

RK3399核心板與人臉識別機櫃控制之間的「聯絡」

一 產品背景 i cabinetc是一款基於物聯網技術為完善物品溯源管理而生的智慧型儲存終端,旨在解決當前高值備品管理的弊端。配套的智慧型管理系統可實時記錄人員資訊,物品有效期,領還記錄等管理資訊,為精細化管理提供有力的基礎性保障。由電腦和微控制器組成的多功能備品管理控制系統終端裝置,是工具管理現代...

Oracle控制檔案 10g

作用 二進位制檔案 記錄了資料庫當前例項的結構和行為,資料檔案日誌檔案的資訊,維護資料庫一致性 引數檔案中定義了控制檔案的位置和大小 很小的二進位制檔案,一般不超過100m mount階段open以後,一直在用 一套控制檔案只能連線乙個database 分散放置,至少乙份,至多八份 相關檢視 v c...