[PATCH v2] clk: si5351: Allow user to define disabled state for every clock output

2013-05-02 Thread Marek Belisko
From: Sebastian Hesselbarth 

This patch adds platform data and DT bindings to allow to overwrite
the stored disabled state for each clock output.

Signed-off-by: Marek Belisko 
Signed-off-by: Sebastian Hesselbarth 
---
Changes from v1->v2:
Sebastian Hesselbarth send me updated version of patch which was based
on v1. Resending with updates.

 .../devicetree/bindings/clock/silabs,si5351.txt|5 ++
 drivers/clk/clk-si5351.c   |   74 +++-
 drivers/clk/clk-si5351.h   |1 +
 include/linux/platform_data/si5351.h   |   18 +
 4 files changed, 95 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/silabs,si5351.txt 
b/Documentation/devicetree/bindings/clock/silabs,si5351.txt
index cc37465..66c75b2 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 output disable state, shall be
+  0 = clock output is driven LOW when disabled
+  1 = clock output is driven HIGH when disabled
+  2 = clock output is FLOATING (HIGH-Z) when disabled
+  3 = clock output is NEVER disabled
 
 ==Example==
 
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index 8323c31..098f28b 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -851,6 +851,41 @@ static int _si5351_clkout_set_drive_strength(
return 0;
 }
 
+static int _si5351_clkout_set_disable_state(
+   struct si5351_driver_data *drvdata, int num,
+   enum si5351_disable_state state)
+{
+   u8 reg = (num < 4) ? SI5351_CLK3_0_DISABLE_STATE :
+   SI5351_CLK7_4_DISABLE_STATE;
+   u8 shift = (num < 4) ? (2 * num) : (2 * (num-4));
+   u8 mask = SI5351_CLK_DISABLE_STATE_MASK << shift;
+   u8 val;
+
+   if (num > 8)
+   return -EINVAL;
+
+   switch (state) {
+   case SI5351_DISABLE_LOW:
+   val = SI5351_CLK_DISABLE_STATE_LOW;
+   break;
+   case SI5351_DISABLE_HIGH:
+   val = SI5351_CLK_DISABLE_STATE_HIGH;
+   break;
+   case SI5351_DISABLE_FLOATING:
+   val = SI5351_CLK_DISABLE_STATE_FLOAT;
+   break;
+   case SI5351_DISABLE_NEVER:
+   val = SI5351_CLK_DISABLE_STATE_NEVER;
+   break;
+   default:
+   return 0;
+   }
+
+   si5351_set_bits(drvdata, reg, mask, val << shift);
+
+   return 0;
+}
+
 static int si5351_clkout_prepare(struct clk_hw *hw)
 {
struct si5351_hw_data *hwdata =
@@ -1225,6 +1260,33 @@ static int si5351_dt_parse(struct i2c_client *client)
}
}
 
+   if (!of_property_read_u32(child, "silabs,disable-state",
+ &val)) {
+   switch (val) {
+   case 0:
+   pdata->clkout[num].disable_state =
+   SI5351_DISABLE_LOW;
+   break;
+   case 1:
+   pdata->clkout[num].disable_state =
+   SI5351_DISABLE_HIGH;
+   break;
+   case 2:
+   pdata->clkout[num].disable_state =
+   SI5351_DISABLE_FLOATING;
+   break;
+   case 3:
+   pdata->clkout[num].disable_state =
+   SI5351_DISABLE_NEVER;
+   break;
+   default:
+   dev_err(&client->dev,
+   "invalid disable state %d for clkout 
%d\n",
+   val, num);
+   return -EINVAL;
+   }
+   }
+
if (!of_property_read_u32(child, "clock-frequency", &val))
pdata->clkout[num].rate = val;
 
@@ -1281,9 +1343,6 @@ 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);
/* Ensure pll select is on XTAL for Si5351A/B */
if (drvdata->variant != SI5351_VARIANT_C)
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
@@ -1327,6 +1386,15 @@ static int si5351_i2c_probe(struct i2c_client *client,
  

Re: [PATCH v2] clk: si5351: Allow user to define disabled state for every clock output

2013-05-03 Thread Sebastian Hesselbarth

On 05/03/2013 07:33 AM, Marek Belisko wrote:

From: Sebastian Hesselbarth

This patch adds platform data and DT bindings to allow to overwrite
the stored disabled state for each clock output.

Signed-off-by: Marek Belisko
Signed-off-by: Sebastian Hesselbarth
---
Changes from v1->v2:
Sebastian Hesselbarth send me updated version of patch which was based
on v1. Resending with updates.


Marek,

it is ok to be a little bit more noisy about changes. But as I took
your v1 and did it, here is the Changelog:

- add helper to set disabled state for clkout
- make disabled-state property behave like other properties, i.e.
  only overwrite disabled state when set through platform_data or DT

Sebastian
___
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss


Re: [PATCH v2] clk: si5351: Allow user to define disabled state for every clock output

2013-05-14 Thread Mike Turquette
Quoting Marek Belisko (2013-05-02 22:33:27)
> From: Sebastian Hesselbarth 
> 
> This patch adds platform data and DT bindings to allow to overwrite
> the stored disabled state for each clock output.
> 
> Signed-off-by: Marek Belisko 
> Signed-off-by: Sebastian Hesselbarth 

Taken into clk-next.

Thanks,
Mike

> ---
> Changes from v1->v2:
> Sebastian Hesselbarth send me updated version of patch which was based
> on v1. Resending with updates.
> 
>  .../devicetree/bindings/clock/silabs,si5351.txt|5 ++
>  drivers/clk/clk-si5351.c   |   74 
> +++-
>  drivers/clk/clk-si5351.h   |1 +
>  include/linux/platform_data/si5351.h   |   18 +
>  4 files changed, 95 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/clock/silabs,si5351.txt 
> b/Documentation/devicetree/bindings/clock/silabs,si5351.txt
> index cc37465..66c75b2 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 output disable state, shall be
> +  0 = clock output is driven LOW when disabled
> +  1 = clock output is driven HIGH when disabled
> +  2 = clock output is FLOATING (HIGH-Z) when disabled
> +  3 = clock output is NEVER disabled
>  
>  ==Example==
>  
> diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
> index 8323c31..098f28b 100644
> --- a/drivers/clk/clk-si5351.c
> +++ b/drivers/clk/clk-si5351.c
> @@ -851,6 +851,41 @@ static int _si5351_clkout_set_drive_strength(
> return 0;
>  }
>  
> +static int _si5351_clkout_set_disable_state(
> +   struct si5351_driver_data *drvdata, int num,
> +   enum si5351_disable_state state)
> +{
> +   u8 reg = (num < 4) ? SI5351_CLK3_0_DISABLE_STATE :
> +   SI5351_CLK7_4_DISABLE_STATE;
> +   u8 shift = (num < 4) ? (2 * num) : (2 * (num-4));
> +   u8 mask = SI5351_CLK_DISABLE_STATE_MASK << shift;
> +   u8 val;
> +
> +   if (num > 8)
> +   return -EINVAL;
> +
> +   switch (state) {
> +   case SI5351_DISABLE_LOW:
> +   val = SI5351_CLK_DISABLE_STATE_LOW;
> +   break;
> +   case SI5351_DISABLE_HIGH:
> +   val = SI5351_CLK_DISABLE_STATE_HIGH;
> +   break;
> +   case SI5351_DISABLE_FLOATING:
> +   val = SI5351_CLK_DISABLE_STATE_FLOAT;
> +   break;
> +   case SI5351_DISABLE_NEVER:
> +   val = SI5351_CLK_DISABLE_STATE_NEVER;
> +   break;
> +   default:
> +   return 0;
> +   }
> +
> +   si5351_set_bits(drvdata, reg, mask, val << shift);
> +
> +   return 0;
> +}
> +
>  static int si5351_clkout_prepare(struct clk_hw *hw)
>  {
> struct si5351_hw_data *hwdata =
> @@ -1225,6 +1260,33 @@ static int si5351_dt_parse(struct i2c_client *client)
> }
> }
>  
> +   if (!of_property_read_u32(child, "silabs,disable-state",
> + &val)) {
> +   switch (val) {
> +   case 0:
> +   pdata->clkout[num].disable_state =
> +   SI5351_DISABLE_LOW;
> +   break;
> +   case 1:
> +   pdata->clkout[num].disable_state =
> +   SI5351_DISABLE_HIGH;
> +   break;
> +   case 2:
> +   pdata->clkout[num].disable_state =
> +   SI5351_DISABLE_FLOATING;
> +   break;
> +   case 3:
> +   pdata->clkout[num].disable_state =
> +   SI5351_DISABLE_NEVER;
> +   break;
> +   default:
> +   dev_err(&client->dev,
> +   "invalid disable state %d for clkout 
> %d\n",
> +   val, num);
> +   return -EINVAL;
> +   }
> +   }
> +
> if (!of_property_read_u32(child, "clock-frequency", &val))
> pdata->clkout[num].rate = val;
>  
> @@ -1281,9 +1343,6 @@ 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);
> -