【问题标题】:How to define a clock multiplexer in a linux kernel device tree如何在 linux 内核设备树中定义时钟多路复用器
【发布时间】:2015-03-19 19:33:28
【问题描述】:

我正在编写一个 linux 设备驱动程序,需要在设备树文件中定义以下时钟树:

注意:选择多路复用器中的振荡器是通过将 gpio 输出拉高或拉低来完成的。时钟发生器通过 I2C 编程。

这是我目前所拥有的一个例子:

clocks {
    /* fixed clock oscillators */
    osc22: oscillator22 {
        compatible = "fixed-clock";
        #clock-cells = <0>;
        clock-frequency = <22579200>;
    };

    osc24: oscillator24 {
        compatible = "fixed-clock";
        #clock-cells = <0>;
        clock-frequency = <24576000>;
    };

    /* clock multiplexer
     * I'm afraid the following is not going to work :( ?
     */
    mux: multiplexer {
        compatible = "mux-clock";     /* <-------- ??? */
        clocks = <&osc22>, <&osc24>;  /* parent clocks */
    };
};

i2c1 {
    /* clock generator */
    si5351: si5351c@60 {
        #address-cells = <1>;
        #size-cells = <0>;
        #clock-cells = <1>;
        compatible = "silabs,si5351c";
        reg = <0x60>;
        clocks = <0>, <&mux>;
        clock-names = "xtal", "clkin";
        status = "okay";

        clkout0 {
            reg = <0>;
            silabs,disable-state = <2>;
            silabs,clock-source = <3>;
        };
    };
};

参考文献

如何在设备树中定义一个简单的gpio-controlled时钟多路复用器?

【问题讨论】:

    标签: linux-kernel linux-device-driver clock gpio device-tree


    【解决方案1】:

    正如@h3n 正确指出的那样,在提出这个问题时,内核并未提供对 gpio 控制的时钟多路复用器的支持。 所以,我不得不为这些设备添加一个通用的时钟驱动程序。

    此驱动程序 (drivers/clk/clk-gpio.c) 自 4.3-rc1 起就在主线中。

    上述用例的设备树绑定可能如下所示:

    clocks {
        /* fixed clock oscillators */
        osc22: oscillator22 {
            compatible = "fixed-clock";
            #clock-cells = <0>;
            clock-frequency = <22579200>;
        };
    
        osc24: oscillator24 {
            compatible = "fixed-clock";
            #clock-cells = <0>;
            clock-frequency = <24576000>;
        };
    
        /* gpio-controlled clock multiplexer */
        mux: multiplexer {
            compatible = "gpio-mux-clock";
            clocks = <&osc22>, <&osc24>;  /* parent clocks */
            #clock-cells = <0>;
            select-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
        };
    };
    

    【讨论】:

      【解决方案2】:

      您不需要设备树支持时钟复用的简单答案。据我所知,这个想法是提供您的时钟驱动程序可以用来选择父时钟的 API。

      如果您可以查看 Silicon Labs si5351c 驱动程序 (drivers/clk/clk-si5351.c) 的代码,它具有设备树支持。 Documentation/devicetree/bindings/clock/silabs,si5351.txt 有允许字段的详细描述。我想您必须根据需要定义尽可能多的clkin

      【讨论】:

      • 感谢您的回答。 si5351c 有两个时钟参考,xtal 和 clkin。 DT 时钟列表中的第一个时钟用作 xtal ref,第二个用作 clkin ref,其他时钟将被忽略。在运行时使用 clk_set_parent() 更改 clkin 的父时钟失败。
      • 函数si5351_pll_set_parent 执行实际的reparent。我不知道您正在努力解决的确切用例,尽管从驱动程序我可以说确切设备的时钟提供程序可能会调用 clk_set_parent() 来重新设置时钟。
      【解决方案3】:

      当前内核不支持。您必须编写自己的内核模块。

      【讨论】:

        【解决方案4】:

        多路复用器可用于选择父时钟之一:osc22 或 osc24。 但是您需要在驱动程序中为属性“mux-clock”编写自己的绑定。

        我不知道下面的链接是否可以直接帮助您,但请看一下: https://www.kernel.org/doc/Documentation/devicetree/bindings/clock/ti/mux.txt

        上面的链接定义了要在DT中使用的mux绑定

        这里的多路复用器绑定“ti,mux-clock”是在驱动程序中根据通用 clk 框架定义的: http://lxr.free-electrons.com/source/drivers/clk/ti/mux.c

        也许您可以得出一些想法如何实现您的绑定。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-03-30
          • 2015-04-13
          • 1970-01-01
          • 2015-01-27
          • 1970-01-01
          • 1970-01-01
          • 2016-04-19
          相关资源
          最近更新 更多