[PATCH v2] clk: si5351: Allow user to define disabled state for every clock output
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
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
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); > -