I am writing a linux device driver and need to define the following clock-tree in a device tree file:
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?
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>;
};
};