Linux カーネルの pinctrl サブシステム ドライバー フレームワークの詳細な説明

目次

1 はじめに

2 デバイスツリーの pinctrl

2.1 iomuxc ノード

2.2 他のノードで pinctrl コントローラーを使用する方法

3 ピン コントローラーのコード フローと関連データ構造

4 デバイス クライアント コード プロセスと関連データ構造

5 カーネルのソースコードを読む際の関連する質問

6 ファインマン学習法: そこで、pinctrl サブシステムを説明するビデオを録画しました


1 はじめに

STM32 や IMX6ULL に関わらず、特定のピンを使用して LED ライトのオン/オフを制御する場合、一般的には上図に示すようにピンを設定する必要があります。ピンの機能と電気的特性は次のとおりです。 Linux カーネルで設定: これは pinctrl サブシステムによって行われます。pinctrl サブシステムには 3 つの主な機能があります。

  • 機能 1: ピンの列挙と命名
  • 機能2:ピンマルチプレクス(Multiplexing)
  • 機能 3: 電気的特性の設定 (Configuration)

また、Linux カーネルの pinctrl サブシステムに関連するコードはチップ メーカーによって実装されているため、ユーザーはコードを記述する必要がなく、デバイス ツリー ファイルを変更するだけで済みます。 

2 デバイスツリーの pinctrl

pinctrl デバイス ツリーの形式はメーカーごとに異なりますが、ここでは imx6ull プラットフォームを例として、imx6ull が提供する Linux4.9.88 カーネル ソース コードを例として読み取り、説明しています。

2.1 iomuxc ノード

まず、iomuxc ノードを確認します。

iomuxc: iomuxc@020e0000 {
    compatible = "fsl,imx6ul-iomuxc";
    reg = <0x020e0000 0x4000>;
    imx6ul-evk {
        pinctrl_hog_1: hoggrp-1 {
			fsl,pins = <
				MX6UL_PAD_UART1_RTS_B__GPIO1_IO19	0x17059 /* SD1 CD */
				MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT	0x17059 /* SD1 VSELECT */
				MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x17059 /* SD1 RESET */
			>;
		};
        
        pinctrl_csi1: csi1grp {
			fsl,pins = <
				MX6UL_PAD_CSI_MCLK__CSI_MCLK		0x1b088
				MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK	0x1b088
                               ...没写全...
				MX6UL_PAD_CSI_DATA06__CSI_DATA08	0x1b088
				MX6UL_PAD_CSI_DATA07__CSI_DATA09	0x1b088
			>;
		};

        pinctrl_i2c1: i2c1grp {
			fsl,pins = <
				MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
				MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0
			>;
		};
                    
    }
};

fsl と pins の情報は、レジスタのオフセット アドレスと値であり、特定のピンの多重化と電気的特性を構成するために使用されます。

MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */

このうち、MX6UL_PAD_UART1_RTS_B__GPIO1_IO19はマクロ定義であり、

#define MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x0090 0x031c 0x0000 5 0

マクロ定義を置き換える場合、MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */ は

0x0090 0x031c 0x0000 5 0 0x17059

この6つの値は、

mux_reg conf_reg input_reg mux_mode input_val conf_reg 

これら 6 つの値に基づいて、ピンの多重化と電気的特性を設定できます。

2.2 他のノードで pinctrl コントローラーを使用する方法

たとえば、i2c1

&i2c1 {     クロック周波数 = <100000>;     pinctrl-names = "デフォルト";     pinctrl-0 = <&pinctrl_i2c1>;     ステータス = "大丈夫";



};

このように、i2c1 ノードは pinctrl によって提供されるピン構成を使用します。

pinctrl サブシステムは使用できるため、この時点で実際に説明を終えることができますが、以下の説明は理解のためのものであり、その後、Linux カーネルのソース コードを読みます。

3 ピン コントローラーのコード フローと関連データ構造

ピン コントローラーのコード フローと関連するデータ構造を説明する図を直接描きました。

 まず、デバイスツリーのiomuxcノードがplatform_deviceに変換され、compatibility = "fsl,imx6ul-iomuxc"に従ってマッチングされると、imx6ul_pinctrl_probe関数が呼び出されます。この関数では、pinctrl_info = (struct imx_pinctrl_soc_info *)まず match->data を取り出します; これは実際にはピンの列挙であり、次に imx_pinctrl_probe(pdev, pinctrl_info); 関数が呼び出され、この関数内で pinctrl_desc 構造体が割り当てられます。

    imx_pinctrl_desc->name = dev_name(&pdev->dev);

    imx_pinctrl_desc->ピン = 情報->ピン;

    imx_pinctrl_desc->npins = 情報->npins;

    imx_pinctrl_desc->pctlops = &imx_pctrl_ops;

    imx_pinctrl_desc->pmxops = &imx_pmx_ops;

    imx_pinctrl_desc->confops = &imx_pinconf_ops;

    imx_pinctrl_desc->所有者 = THIS_MODULE;

次に、この構造にはピンといくつかの操作関数が含まれており、imx_pinctrl_probe_dt(pdev, info) を呼び出します。ここでデバイス ツリーが解析されて、これらのレジスタ アドレスとレジスタ値が取得されます。次に、 ipctl->pctl = devm_pinctrl_register(&pdev->dev, imx_pinctrl_desc, ipctl); 関数を呼び出します。この関数は struct pinctrl_dev *pctldev; 構造体を構築します。この struct pinctrl_dev *pctldev; 構造体にはピンと操作関数が含まれています。レジスタ値やレジスタアドレスなどのすべての情報。

4 デバイス クライアント コード プロセスと関連データ構造

まず、デバイスクライアントのデータ構造を図で表してみます。

次に、Linux カーネルのソース コードを見て、上記のデータ構造の構築プロセスを見てみましょう。また、直接絵も描きました。

 5 カーネルのソースコードを読む際の関連する質問

 こんにちは!あなたの理解は正しいです。このコードでは、 プラットフォーム デバイスに  関連付けられる 関数 platform_set_drvdata(pdev, ipctl); が呼び出されます 。こうすることで、デバイス ドライバー内のデバイスのプライベート データにアクセスする必要があるときに、  関数を使用してそれを取得 できますplatform_set_drvdataipctlpdevplatform_get_drvdataipctl

ipctlimx_pinctrl デバイス ツリーから解析されたピン レジスタ情報を含む構造体へのポインタ です 。この情報は ipctl->info->pin_regs 配列に格納されており、各要素は imx_pin_reg ピンのレジスタ情報を表す構造体となります。

したがって、このコードでは、デバイス ツリーから解析されたピン レジスタ情報が に保存されます pdev->dev.driver_data 。この情報がお役に立てば幸いです!

6 ファインマン学習法: そこで、pinctrl サブシステムを説明するビデオを録画しました

Linux kernel_bilibili_bilibili の pinctrl サブシステムについての 15 分間の説明 

おすすめ

転載: blog.csdn.net/u013171226/article/details/132431972
おすすめ