diff mbox

clk: si5351: Allow user to define disabled state for every clock output.

Message ID 1367320607-25657-1-git-send-email-marek.belisko@streamunlimited.com (mailing list archive)
State New, archived
Headers show

Commit Message

Belisko Marek April 30, 2013, 11:16 a.m. UTC
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(-)
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/clock/silabs,si5351.txt b/Documentation/devicetree/bindings/clock/silabs,si5351.txt
index cc37465..2f24c12 100644
--- a/Documentation/devicetree/bindings/clock/silabs,si5351.txt
+++ b/Documentation/devicetree/bindings/clock/silabs,si5351.txt
@@ -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==
 
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index 8323c31..bfe92b8 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -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,
diff --git a/include/linux/platform_data/si5351.h b/include/linux/platform_data/si5351.h
index 92dabca..6702991 100644
--- a/include/linux/platform_data/si5351.h
+++ b/include/linux/platform_data/si5351.h
@@ -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;
 };
 
 /**