目次
目次
目次
1.LinuxでのGPIOの使用
1.pinctrlサブシステムを介してPINの多重化および電気的特性を設定します。
2.gpioサブシステムを介してGPIOを構成および操作します
2、pinctrlサブシステム
デバイスツリーでピンの関連属性を設定するだけで済みます。他の初期化作業はpinctrlサブシステムによって実行され、pinctrlサブシステムのソースディレクトリはdrivers / pinctrlです。pinctrlサブシステムの主な作業内容は次のとおりです。
①。デバイスツリーでピン情報を取得します。
②取得したピン情報に応じてピン多重化機能を設定します。
③。取得したピン情報(上下、速度、駆動能力など)に応じて、ピンの電気的特性を設定します。
1.デバイスツリーでのpinctrlの表現方法
imx6ull.dtsiを開きます。
1.1 IOMUXCSNVSコントローラー
iomuxc_snvs: iomuxc-snvs@02290000 {
compatible = "fsl,imx6ull-iomuxc-snvs";
reg = <0x02290000 0x10000>;
};
1.2IOMUXCコントローラー
iomuxc: iomuxc@020e0000 {
compatible = "fsl,imx6ul-iomuxc";
reg = <0x020e0000 0x4000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;
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 */
>;
};
………
}
};
デバイスの種類に応じて、対応する子ノードを作成し、デバイスが使用するPINをこのノードに配置します。
1.3gprコントローラー
gpr: iomuxc-gpr@020e4000 {
compatible = "fsl,imx6ul-iomuxc-gpr",
"fsl,imx6q-iomuxc-gpr", "syscon";
reg = <0x020e4000 0x4000>;
};
1.4PIN情報を追加する方法
I.MXシリーズSOCの場合、pinctrlドライバーは、「fsl、pins」属性値を読み取ることによってPIN構成情報を取得します。i.MXシリーズSOCのpinctrlデバイスツリーバインディング情報については、 LinuxソースディレクトリのバインディングドキュメントDocumentation / devicetree / bindings / pinctrl / fsl、imx-pinctrl.txtを参照してください。
pinctrl_hog_1: hoggrp-1 {
fsl,pins = <
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
>;
};
在imx6ul-pinfunc.h中找到:
#define MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x0090 0x031C 0x0000 0x5 0x0
展开后:
pinctrl_hog_1: hoggrp-1 {
fsl,pins = <
0x0090 0x031C 0x0000 0x5 0x0 0x17059 /* SD1 CD */
>;
};
<mux_reg conf_reg input_reg mux_mode input_val>
0x0090 0x031C 0x0000 0x5 0x0
1. mux_reg:UART1_RTS_B、PINマルチプレックス機能レジスタのオフセットアドレス。IOMUXCの親ノードの最初のアドレスは0x020e0000であり、UART1_RTS_Bの多重関数レジスタのアドレスは0x020e0090です。
2. conf_reg:UART1_RTS_BこのPIN電気特性レジスタオフセットアドレス。UART1_RTS_Bの電気特性レジスタアドレスは0x020e0000 + 0x031C = 0x020e031Cです。
3. input_reg、入力レジスタオフセット、0は、UART1_RTS_Bに入力機能がないことを意味します。
4. mux_mode:マルチプレックス機能レジスタアドレスの値。5はGPIO1_IO19として多重化されていることを意味し、0x020e0090に書き込みます。
5. input_val:input_regレジスタに書き込まれる値です。
6. 0x17059:PINの電気的特性のレジスタ値を設定します。
2.pinctrlドライバー
レジスタアドレスやレジスタ値など、すべての準備が整っています。Linuxカーネルの対応するドライバファイルは、これらの値に従って初期化されます。次に、これを行うドライバーファイルを見つけます。iomuxcノードの互換性のある属性の値は「fsl、imx6ul-iomuxc」です。Linuxカーネルで文字列「fsl、imx6ul-iomuxc」をグローバルに検索すると、対応するものが見つかります。ドライバーファイル。ファイルdrivers / pinctrl / freescale /pinctrl-imx6ul.cの内容は次のとおりです。
static struct of_device_id imx6ul_pinctrl_of_match[] = {
{ .compatible = "fsl,imx6ul-iomuxc", .data = &imx6ul_pinctrl_info, },
{ .compatible = "fsl,imx6ull-iomuxc-snvs", .data = &imx6ull_snvs_pinctrl_info, },
{ /* sentinel */ }
};
static int imx6ul_pinctrl_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct imx_pinctrl_soc_info *pinctrl_info;
match = of_match_device(imx6ul_pinctrl_of_match, &pdev->dev);
if (!match)
return -ENODEV;
pinctrl_info = (struct imx_pinctrl_soc_info *) match->data;
return imx_pinctrl_probe(pdev, pinctrl_info);
}
static struct platform_driver imx6ul_pinctrl_driver = {
.driver = {
.name = "imx6ul-pinctrl",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(imx6ul_pinctrl_of_match),
},
.probe = imx6ul_pinctrl_probe,
.remove = imx_pinctrl_remove,
};
デバイスとドライバーが正常に一致すると、platform_driverのプローブメンバー変数で表される関数が実行されます。
3、gpioサブシステム
pinctrlサブシステムは、PINの多重化および電気的特性の設定に重点を置いています(一部のSOCはPADと呼ばれます)。pinctrlサブシステムがPINをGPIOとして再利用する場合、次にgpioサブシステムが使用されます。名前が示すように、gpioサブシステムは、GPIOを初期化し、GPIOを入力および出力として設定したり、GPIO値を読み取ったりするなど、対応するAPI機能を提供するために使用されます。gpioサブシステムの主な目的は、ドライバー開発者によるgpioの使用を容易にすることです。ドライバー開発者はデバイスツリーにgpio関連情報を追加でき、gpioサブシステムによって提供されるAPI関数をドライバーで使用して、GPIOLinuxカーネルをドライバー開発者に操作できます。 GPIO設定プロセスはシールドされているため、ドライバー開発者によるGPIOの使用が大幅に容易になります。
1.デバイスツリーでのgpioの表現方法
I.MXシリーズSOCのGPIOコントローラーのバインディング情報については、ドキュメントDocumentation / devicetree / bindings / gpio /fsl-imx-gpio.txtを参照してください。
&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";
};
cd-gpios属性が定義されています。「&gpio1」は、CDピンが使用するIOがGPIO1グループに属することを意味し、19はGPIO1グループの19番目のIOを意味し、SDカードドライバーは、CDピンがこれら2つの値を通じてGPIO1_IO19を使用することを認識します。このGPIO。「GPIO_ACTIVE_LOW」は低レベルがアクティブであることを意味し、GPIO_ACTIVE_HIGHを変更すると、高レベルがアクティブであることを意味します。
gpio1: gpio@0209c000 {
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>;
};
2.gpioドライバー
検索互換= "FSL、imx6ul-GPIO "、 "FSL、imx35-GPIO"、ドライバ/ GPIO / GPIO-mxc.cが文字列に一致することが見出され、ドライバ/ GPIO / GPIO-mxc.cでありますi.MX6ULLのGPIOドライバーファイル
static const struct of_device_id mxc_gpio_dt_ids[] = {
{ .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], },
{ .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], },
{ .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], },
{ .compatible = "fsl,imx35-gpio", .data = &mxc_gpio_devtype[IMX35_GPIO], },
{ /* sentinel */ }
};
static struct platform_driver mxc_gpio_driver = {
.driver = {
.name = "gpio-mxc",
.of_match_table = mxc_gpio_dt_ids,
},
.probe = mxc_gpio_probe,
.id_table = mxc_gpio_devtype,
};
GPIOドライバーはプラットフォームデバイスドライバーでもあることがわかります。したがって、デバイスツリーのデバイスノードがドライバーのof_device_idと一致すると、プローブ関数が実行されます。実装プロセスはpinctlと同様です。
3.gpioサブシステムAPI
(1)int gpio_request(unsigned gpio、const char * label)
gpio_request関数はGPIOピンを申請するために使用されます。GPIOを使用する前に、gpio_requestを使用して申請する必要があります。
gpio:適用されるgpioラベル。of_get_named_gpio関数を使用して、デバイスツリーから指定されたGPIO属性情報を取得します。この関数はGPIOラベルを返します。
label:gpioの名前を設定します。
戻り値:0、アプリケーションは成功しました。他の値、アプリケーションは失敗しました。
(2)void gpio_free(unsigned gpio)
GPIOを使用しない場合は、gpio_free関数を呼び出して解放できます
gpio:gpioラベルがリリースされます
(3)int gpio_direction_input(unsigned gpio)
この関数は、GPIOを入力として設定するために使用されます
gpio:入力として設定するGPIOラベル。
戻り値:0、正常に設定されました。負の値、設定に失敗しました。
(4)int gpio_direction_output(unsigned gpio、int value)
この関数は、GPIOを出力として設定し、デフォルトの出力値を設定するために使用されます
gpio:出力として設定するGPIOラベル。
値GPIOのデフォルトの出力値。
戻り値:0、正常に設定されました。負の値、設定に失敗しました。
(5)#define gpio_get_value int __gpio_get_value(unsigned gpio)
この関数は、GPIOの値(0または1)を取得するために使用されます
(6)#define gpio_set_value void __gpio_set_value(unsigned gpio、int value)
この関数は、GPIOの値を設定するために使用されます
4.gpioに関連する機能の
(1)int of_gpio_named_count(struct device_node * np、const char * propname)
(2)int of_gpio_count(struct device_node * np)
(3)int of_get_named_gpio(struct device_node * np、const char * propname、int index)
5.ドライバーでのgpioの使用プロセス
1.まず、of_find_node_by_pathなど、GPIOが配置されているデバイスノードを取得します。
2. GPIO番号of_get_named_gpio関数を取得します。戻り値は、GPIO番号です。
3.この番号のGPIO、gpio_request関数を要求します
4. GPIO、入力または出力、gpio_direction_inputまたはgpio_direction_outputを設定します。
5.入力されている場合は、gpio_get_value関数を使用してGPIO値を読み取り、出力されている場合は、gpio_set_valueを介してGPIO値を設定します。