1
votes

I am writing a linux device driver and need to define the following clock-tree in a device tree file:

linux, common clock framework, clock tree

Note: Selecting an oscillator in the multiplexer is done by pulling an gpio output high or low. The clock generator is programmed via I2C.

Here is an example of what I have so far:

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>;
        };
    };
};

References:

How do I define a simple gpio-controlled clock multiplexer in a device tree?

4

4 Answers

2
votes

As correctly pointed out by @h3n, at the time of asking this question, the kernel did not provide support for gpio-controlled clock multiplexers. So, I had to add a common clock driver for such devices.

This driver (drivers/clk/clk-gpio.c) is in the mainline since 4.3-rc1.

A device tree binding for the above mentioned use-case could look like this:

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>;
    };
};
1
votes

The simple answer you don't need to have a device tree support for the clock muxing. The idea as far as I can see is to provide the API that your clock driver may use to choose the parent clock.

If you can see to the code of the Silicon Labs si5351c driver (drivers/clk/clk-si5351.c) it has a device tree support. Documentation/devicetree/bindings/clock/silabs,si5351.txt has detailed description of the allowed fields. I guess you have to define as many clkin as you need.

1
votes

The current kernel does not support that. You have to write your own kernel module.

1
votes

The mux can be used to select one of the parent clocks: osc22 or osc24. BUT you need to write your own binding for property "mux-clock" in your driver.

I don't know if the below link can help you directly but take a look at it: https://www.kernel.org/doc/Documentation/devicetree/bindings/clock/ti/mux.txt

Above link defines the mux binding to be used in DT

Here the mux binding "ti,mux-clock" is defined in the driver as per common clk framework: http://lxr.free-electrons.com/source/drivers/clk/ti/mux.c

May be you can derive some idea how to implement your binding.