• [dts]DTS实例分析


     此篇源文件arch/arm/boot/dts/imx6sx.dtsi

    1. dts和dtsi完成的功能

    以下是两段较为常见的dtsi和dts代码

     1 uart5: serial@021f4000 {
     2     compatible = "fsl,imx6sx-uart",
     3                 "fsl,imx6q-uart", "fsl,imx21-uart";
     4     reg = <0x021f4000 0x4000>;
     5     interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
     6     clocks = <&clks IMX6SX_CLK_UART_IPG>,
     7             <&clks IMX6SX_CLK_UART_SERIAL>;
     8     clock-names = "ipg", "per";
     9     dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
    10     dma-names = "rx", "tx";
    11     status = "disabled";
    12 };

    以上这段代码更多出现在*.dtsi中

    一般会在*.dtsi中将芯片的外设接口资源都做定义,

    如uart5作为该外设的label,node-name@unit-address作为设备的名称,node-name只是设备类型,uart1/uart2/uart3等可以都是serial名称,而@后面则跟着设备寄存器起始地址。

    compatible默认属性,

    reg寄存器地址和长度,该uart5节点的父节点为aips2,在父节点中指明#address-cells = <1>;#size-cells = <1>;这决定了子节点字段长度address为1, length为1. 所以reg格式为reg = <0x021f4000 0x4000>;

    interrupts对应的中断号和中断出发方式,uart5的父节点为aips2,而aips2的父节点为soc,soc节点定义了interrupt-parent = <&intc>;给出了节点所依附的中断控制器,如果节点没有指定interrupt-parent,那么就从父节点继承,所以该uart5节点继承了soc的中断控制器,即intc. 而intc节点的#interrupt-cells = <3>;所以就有了该节点中interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;三个字段,具体这三个字段的含义可以参考芯片文档的描述。其中GIC_SPI定义在include/dt-bindings/interrupt-controller/arm-gic.h值为0,  

    clock外设时钟,在include/dt-bindings/clock/imx6sx-clock.h,指定设备工作时钟

    status一般会设为disabled。

    1 &uart5 {
    2     pinctrl-names = "default";
    3     pinctrl-0 = <&pinctrl_uart5>;
    4     fsl,uart-has-rtscts;
    5     status = "okay";
    6 };

    以上这段代码更多出现在*.dts中

    在*.dts中如果想对该设备进行操作,需要进行override,至少status需要从disabled设置为okay, 当然也有可能需要对compatible属性进行重写(为了和自己的driver匹配),另外需要使用&label首先引用该设备,使用pinctrl-names和pinctrl-0进行引脚的配置,当然这里可能出现多组引脚的配置,如下代码:

     1 &usdhc3 {
     2     pinctrl-names = "default", "state_100mhz", "state_200mhz";
     3     pinctrl-0 = <&pinctrl_usdhc3>;
     4     pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
     5     pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
     6     bus-width = <8>;
     7     cd-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
     8     wp-gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>;
     9     keep-power-in-suspend;
    10     enable-sdio-wakeup;
    11     vmmc-supply = <&vcc_sd3>;
    12     status = "okay";
    13 };

    而这里面的pinctrl-0对应的pinctrl_usdhc3内容如下:

     1 pinctrl_usdhc3: usdhc3grp {
     2     fsl,pins = <
     3         MX6SX_PAD_SD3_CMD__USDHC3_CMD        0x17069
     4         MX6SX_PAD_SD3_CLK__USDHC3_CLK        0x10071
     5         MX6SX_PAD_SD3_DATA0__USDHC3_DATA0    0x17069
     6         MX6SX_PAD_SD3_DATA1__USDHC3_DATA1    0x17069
     7         MX6SX_PAD_SD3_DATA2__USDHC3_DATA2    0x17069
     8         MX6SX_PAD_SD3_DATA3__USDHC3_DATA3    0x17069
     9         MX6SX_PAD_SD3_DATA4__USDHC3_DATA4    0x17069
    10         MX6SX_PAD_SD3_DATA5__USDHC3_DATA5    0x17069
    11         MX6SX_PAD_SD3_DATA6__USDHC3_DATA6    0x17069
    12         MX6SX_PAD_SD3_DATA7__USDHC3_DATA7    0x17069
    13         MX6SX_PAD_KEY_COL0__GPIO2_IO_10        0x17059 /* CD */
    14         MX6SX_PAD_KEY_ROW0__GPIO2_IO_15        0x17059 /* WP */
    15         >;
    16 };

     这种pinctrl的设置可参照/Documentation/devicetree/bindinsg/pinctrl下示例代码

    2. 通常会碰到的实际问题

    到此,问题出现了

    1. 当写一个按键驱动,应该如何在*.dts或者*.dtsi中操作?

    2. 当在串口driver中需要使用到某个pin脚作为普通输出IO,该如何操作?

    3. 当在串口driver中需要使用某个muxpin脚作为ADC或者其他服用功能该如何操作?

    4. 当在串口driver中有可能想使能某个功能而不想写定在driver代码中,该如何操作?

    5. 当想向driver中传入一个常数如做delay延时操作等等,该如何操作?

    解答

    1. 当写一个按键驱动,应该如何在*.dts或者*.dtsi中操作?

     1 gpio-keys {
     2     compatible = "gpio-keys";
     3     pinctrl-names = "default";
     4     pinctrl-0 = <&pinctrl_gpio_keys>;
     5 
     6     volume-up {
     7         label = "Volume Up";
     8         gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
     9         linux,code = <KEY_VOLUMEUP>;
    10     };
    11 
    12     volume-down {
    13         label = "Volume Down";
    14         gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
    15         linux,code = <KEY_VOLUMEDOWN>;
    16     };
    17 };
    1 pinctrl_gpio_keys: gpio_keysgrp {
    2     fsl,pins = <
    3         MX6SX_PAD_CSI_DATA04__GPIO1_IO_18 0x17059
    4         MX6SX_PAD_CSI_DATA05__GPIO1_IO_19 0x17059
    5         >;
    6 };

    2. 当在串口driver中需要使用到某个pin脚作为普通输出IO,该如何操作?

    1 sii902x_reset: sii902x-reset {
    2     compatible = "gpio-reset";
    3     reset-gpios = <&gpio3 27 1>;
    4     reset-delay-us = <100000>;
    5     #reset-cells = <0>;
    6     status = "disabled";
    7 };

    最简单的不需要pinctrl来进行pin脚的设置,为什么???

    3. 当在串口driver中需要使用某个muxpin脚作为ADC或者其他服用功能该如何操作?

    这个问题其实上面有提到,就像上述的多个pin-names和多个pinctrl在后面的pinctrl中配置这个复用的管脚即可。

    4. 当在串口driver中有可能想使能某个功能而不想写定在driver代码中,该如何操作?

    1 &uart5 { 
    2     pinctrl-names = "default";
    3     pinctrl-0 = <&pinctrl_uart5>;
    4     fsl,uart-has-rtscts;
    5     status = "okay";
    6 
    7 };

    只需要在driver中使用of函数读取此属性,如果有此字段,可以使能某些操作;如果没有就失能某些操作。

    5. 当想向driver中传入一个常数如做delay延时操作等等,该如何操作?

     1 &usdhc3 {
     2     pinctrl-names = "default", "state_100mhz", "state_200mhz";
     3     pinctrl-0 = <&pinctrl_usdhc3>;
     4     pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
     5     pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
     6     bus-width = <8>;
     7     cd-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
     8     wp-gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>;
     9     keep-power-in-suspend;
    10     enable-sdio-wakeup;
    11     vmmc-supply = <&vcc_sd3>;
    12     status = "okay";
    13 };

    只需要在driver中读取bus-width字段的值,即可获取到8这个常量,注意在devicetree中命名字段更多使用"-"而非下划线"_".

  • 相关阅读:
    机器学习中的贝叶斯方法---当后验分布无法计算时如何求得预测模型?
    机器学习中的贝叶斯方法---先验概率、似然函数、后验概率的理解及如何使用贝叶斯进行模型预测(2)
    机器学习中的贝叶斯方法---先验概率、似然函数、后验概率的理解及如何使用贝叶斯进行模型预测(1)
    使用最大似然法来求解线性模型(4)-最大化似然函数背后的数学原理
    使用最大似然法来求解线性模型(3)-求解似然函数
    使用最大似然法来求解线性模型(2)-为什么是最大化似然函数?
    使用最大似然法来求解线性模型(1)
    关于CPU的User、Nice、System、Wait、Idle各个参数的解释
    Redhat Linux FTP配置
    基于at91rm9200的i2c分析(DS1307实时时钟芯片)
  • 原文地址:https://www.cnblogs.com/aaronLinux/p/5551441.html
Copyright © 2020-2023  润新知