@@ -44,6 +44,11 @@ Optional child node properties:
- silabs,multisynth-source: source pll A(0) or B(1) of corresponding multisynth
divider.
- silabs,pll-master: boolean, multisynth can change pll frequency.
+- silabs,disable-state : clock disable state (default 0) shall be
+ 0 = CLKx is set to a LOW state when disabled
+ 1 = CLKx is set to a HIGH state when disabled
+ 2 = CLKx is set to a HIGH IMPEDANCE state when disabled
+ 3 = CLKx is NEVER DISABLED
==Example==
@@ -1230,6 +1230,21 @@ static int si5351_dt_parse(struct i2c_client *client)
pdata->clkout[num].pll_master =
of_property_read_bool(child, "silabs,pll-master");
+
+ if (!of_property_read_u32(child, "silabs,disable-state",
+ &val)) {
+ switch (val) {
+ case SI5351_DISABLE_LOW:
+ case SI5351_DISABLE_HIGH:
+ case SI5351_DISABLE_HIGH_IMPEDANCE:
+ case SI5351_NEVER_DISABLED:
+ pdata->clkout[num].disable_state = val;
+ break;
+ default:
+ pdata->clkout[num].disable_state = 0;
+ }
+ }
+
}
client->dev.platform_data = pdata;
@@ -1250,7 +1265,7 @@ static int si5351_i2c_probe(struct i2c_client *client,
struct clk_init_data init;
struct clk *clk;
const char *parent_names[4];
- u8 num_parents, num_clocks;
+ u8 num_parents, num_clocks, disabled;
int ret, n;
ret = si5351_dt_parse(client);
@@ -1281,9 +1296,22 @@ static int si5351_i2c_probe(struct i2c_client *client,
/* Disable interrupts */
si5351_reg_write(drvdata, SI5351_INTERRUPT_MASK, 0xf0);
- /* Set disabled output drivers to drive low */
- si5351_reg_write(drvdata, SI5351_CLK3_0_DISABLE_STATE, 0x00);
- si5351_reg_write(drvdata, SI5351_CLK7_4_DISABLE_STATE, 0x00);
+
+ /* Set disabled output states */
+ disabled = (pdata->clkout[0].disable_state & 0x03) |
+ ((pdata->clkout[1].disable_state << 2) & 0x0C) |
+ ((pdata->clkout[2].disable_state << 4) & 0x30) |
+ ((pdata->clkout[3].disable_state << 6) & 0xC0);
+
+ si5351_reg_write(drvdata, SI5351_CLK3_0_DISABLE_STATE, disabled);
+
+ disabled = (pdata->clkout[4].disable_state & 0x03) |
+ ((pdata->clkout[5].disable_state << 2) & 0x0C) |
+ ((pdata->clkout[6].disable_state << 4) & 0x30) |
+ ((pdata->clkout[7].disable_state << 6) & 0xC0);
+
+ si5351_reg_write(drvdata, SI5351_CLK7_4_DISABLE_STATE, disabled);
+
/* Ensure pll select is on XTAL for Si5351A/B */
if (drvdata->variant != SI5351_VARIANT_C)
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
@@ -79,6 +79,21 @@ enum si5351_drive_strength {
};
/**
+ * enum si5351_disable_state - Si5351 clock output disable state
+ * @SI5351_DISABLE_LOW: CLKx is set to a LOW state when disabled
+ * @SI5351_DISABLE_HIGH: CLKx is set to a HIGH state when disabled
+ * @SI5351_DISABLE_HIGH_IMPEDANCE: CLKx is set to a HIGH IMPEDANCE state
+ * when disabled
+ * @SI5351_NEVER_DISABLED: CLKx is NEVER DISABLED
+ */
+enum si5351_disable_state {
+ SI5351_DISABLE_LOW = 0,
+ SI5351_DISABLE_HIGH,
+ SI5351_DISABLE_HIGH_IMPEDANCE,
+ SI5351_NEVER_DISABLED,
+};
+
+/**
* struct si5351_clkout_config - Si5351 clock output configuration
* @clkout: clkout number
* @multisynth_src: multisynth source clock
@@ -93,6 +108,7 @@ struct si5351_clkout_config {
enum si5351_drive_strength drive;
bool pll_master;
unsigned long rate;
+ enum si5351_disable_state disable_state;
};
/**
Add platform data and dt bindings to allow user override disabled state. Signed-off-by: Marek Belisko <marek.belisko@streamunlimited.com> --- .../devicetree/bindings/clock/silabs,si5351.txt | 5 +++ drivers/clk/clk-si5351.c | 36 +++++++++++++++++--- include/linux/platform_data/si5351.h | 16 +++++++++ 3 files changed, 53 insertions(+), 4 deletions(-)