Linux kernel 如何在linux内核设备树中定义时钟多路复用器

Linux kernel 如何在linux内核设备树中定义时钟多路复用器,linux-kernel,linux-device-driver,clock,gpio,device-tree,Linux Kernel,Linux Device Driver,Clock,Gpio,Device Tree,我正在编写linux设备驱动程序,需要在设备树文件中定义以下时钟树: 注意:在多路复用器中选择振荡器是通过将gpio输出拉高或拉低来完成的。时钟发生器通过I2C编程 以下是我迄今为止的一个例子: clocks { /* fixed clock oscillators */ osc22: oscillator22 { compatible = "fixed-clock"; #clock-cells = <0>; cloc

我正在编写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>;
        };
    };
};
时钟{
/*固定时钟振荡器*/
振荡器22{
compatible=“固定时钟”;
#时钟单元=;
时钟频率=;
};
osc24:振荡器24{
compatible=“固定时钟”;
#时钟单元=;
时钟频率=;
};
/*时钟多路复用器
*恐怕下列措施行不通?
*/
多路复用器{

compatible=“mux clock”/*简单的答案是,您不需要为时钟复用提供设备树支持。据我所知,这个想法是提供API,您的时钟驱动程序可以使用它来选择父时钟


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

一个简单的答案是,你不需要为时钟多路复用提供设备树支持。据我所知,这个想法是e时钟驱动程序可用于选择父时钟的API


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

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

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

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

我不知道下面的链接是否可以直接帮助您,但请看一下:

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

这里,mux绑定“ti,mux时钟”是根据通用clk框架在驱动程序中定义的:


也许您可以了解如何实现绑定。

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

我不知道下面的链接是否可以直接帮助您,但请看一下:

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

这里,mux绑定“ti,mux时钟”是根据通用clk框架在驱动程序中定义的:


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

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

该驱动程序()自4.3-rc1以来一直在主线中

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

时钟{
/*固定时钟振荡器*/
振荡器22{
compatible=“固定时钟”;
#时钟单元=;
时钟频率=;
};
osc24:振荡器24{
compatible=“固定时钟”;
#时钟单元=;
时钟频率=;
};
/*gpio控制时钟多路复用器*/
多路复用器{
compatible=“gpio mux时钟”;
时钟=,;/*父时钟*/
#时钟单元=;
选择gpios=;
};
};

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

该驱动程序()自4.3-rc1以来一直在主线中

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

时钟{
/*固定时钟振荡器*/
振荡器22{
compatible=“固定时钟”;
#时钟单元=;
时钟频率=;
};
osc24:振荡器24{
compatible=“固定时钟”;
#时钟单元=;
时钟频率=;
};
/*gpio控制时钟多路复用器*/
多路复用器{
compatible=“gpio mux时钟”;
时钟=,;/*父时钟*/
#时钟单元=;
选择gpios=;
};
};

谢谢您的回答。si5351c有两个时钟参考,xtal和clkin。DT时钟列表中的第一个时钟用作xtal参考,第二个时钟用作clkin参考,其他时钟将被忽略。在运行时使用
clk_set_parent()更改clkin的父时钟
失败。功能
si5351\u pll\u set\u parent
执行实际的重新分配。我不知道您正在努力解决的确切用例,但从驱动程序上我可以说,确切设备的时钟提供程序可能会调用
clk\u set\u parent()
重新分配时钟。感谢您的回答。si5351c有两个时钟参考,xtal和clkin。DT时钟列表中的第一个时钟用作xtal ref,第二个时钟用作clkin ref,其他时钟将被忽略。在运行时使用
clk_set_parent()更改clkin的父时钟
失败。函数
si5351\u pll\u set\u parent
执行实际的重新分配。我不知道您正在处理的确切用例,但从驱动程序中,我可以说确切设备的时钟提供程序可以调用
clk\u set\u parent()
来重新分配时钟。