[2/2] clk: cs2000: add AUX_OUT pin select support
diff mbox

Message ID 87d1cjyeb4.wl%kuninori.morimoto.gx@renesas.com
State Under Review
Delegated to: Geert Uytterhoeven
Headers show

Commit Message

Kuninori Morimoto April 11, 2017, 12:36 a.m. UTC
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
---
 .../devicetree/bindings/clock/cs2000-cp.txt        |  9 +++
 drivers/clk/clk-cs2000-cp.c                        | 73 +++++++++++++++++++++-
 2 files changed, 80 insertions(+), 2 deletions(-)

Comments

Geert Uytterhoeven April 11, 2017, 8:35 a.m. UTC | #1
Hi Morimoto-san,

On Tue, Apr 11, 2017 at 2:36 AM, Kuninori Morimoto
<kuninori.morimoto.gx@renesas.com> wrote:
> From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
>
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> Tested-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
> ---
>  .../devicetree/bindings/clock/cs2000-cp.txt        |  9 +++
>  drivers/clk/clk-cs2000-cp.c                        | 73 +++++++++++++++++++++-
>  2 files changed, 80 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/clock/cs2000-cp.txt b/Documentation/devicetree/bindings/clock/cs2000-cp.txt
> index 54e6df0..4c2f9cb 100644
> --- a/Documentation/devicetree/bindings/clock/cs2000-cp.txt
> +++ b/Documentation/devicetree/bindings/clock/cs2000-cp.txt
> @@ -8,6 +8,15 @@ Required properties:
>  - clock-names:         CLK_IN : clk_in, XTI/REF_CLK : ref_clk
>  - #clock-cells:                must be <0>
>
> +Option properties:
> +
> +- auxoutsrc:           select AUX_OUT source from these.
> +                               refclk:         Timing Reference Clock
> +                               clk_in:         Frequency Reference Clock
> +                               pllclkout:      PLL Clock Output
> +                               push-pull:      PLL Lock/Unlock Indication
> +                               open-drain:     PLL Lock/Unlock Indication

AUX_OUT is an output pin?
Hence, isn't this software configuration instead of hardware description?

Selection of refclk vs. clk_in vs. pllclkout can be implemented as a mux clock
driver with three parents.

PLL Lock/Unlock Indication and its pinctrl are something different.
How to support that?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
Kuninori Morimoto April 11, 2017, 9:22 a.m. UTC | #2
Hi Geert

Thank you for your feedback

> > +- auxoutsrc:           select AUX_OUT source from these.
> > +                               refclk:         Timing Reference Clock
> > +                               clk_in:         Frequency Reference Clock
> > +                               pllclkout:      PLL Clock Output
> > +                               push-pull:      PLL Lock/Unlock Indication
> > +                               open-drain:     PLL Lock/Unlock Indication
> 
> AUX_OUT is an output pin?
> Hence, isn't this software configuration instead of hardware description?
> 
> Selection of refclk vs. clk_in vs. pllclkout can be implemented as a mux clock
> driver with three parents.
> 
> PLL Lock/Unlock Indication and its pinctrl are something different.
> How to support that?

I think mux clock is nice idea.
I will use this idea.

Best regards
---
Kuninori Morimoto

Patch
diff mbox

diff --git a/Documentation/devicetree/bindings/clock/cs2000-cp.txt b/Documentation/devicetree/bindings/clock/cs2000-cp.txt
index 54e6df0..4c2f9cb 100644
--- a/Documentation/devicetree/bindings/clock/cs2000-cp.txt
+++ b/Documentation/devicetree/bindings/clock/cs2000-cp.txt
@@ -8,6 +8,15 @@  Required properties:
 - clock-names:		CLK_IN : clk_in, XTI/REF_CLK : ref_clk
 - #clock-cells:		must be <0>
 
+Option properties:
+
+- auxoutsrc:		select AUX_OUT source from these.
+				refclk:		Timing Reference Clock
+				clk_in:		Frequency Reference Clock
+				pllclkout:	PLL Clock Output
+				push-pull:	PLL Lock/Unlock Indication
+				open-drain:	PLL Lock/Unlock Indication
+
 Example:
 
 &i2c2 {
diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c
index 4df38c5..234e3b4 100644
--- a/drivers/clk/clk-cs2000-cp.c
+++ b/drivers/clk/clk-cs2000-cp.c
@@ -42,6 +42,8 @@ 
 /* DEVICE_CFG1 */
 #define RSEL(x)		(((x) & 0x3) << 3)
 #define RSEL_MASK	RSEL(0x3)
+#define AUXOUTSRC(x)	(((x) & 0x3) << 1)
+#define AUXOUTSRC_MASK	AUXOUTSRC(0x3)
 #define ENDEV1		(0x1)
 
 /* DEVICE_CFG2 */
@@ -54,6 +56,8 @@ 
 #define ENDEV2		(0x1)
 
 /* FUNC_CFG1 */
+#define AUXLOCKCFG(x)	(((x) & 0x1) << 6)
+#define AUXLOCKCFG_MASK	AUXLOCKCFG(1)
 #define REFCLKDIV(x)	(((x) & 0x3) << 3)
 #define REFCLKDIV_MASK	REFCLKDIV(0x3)
 
@@ -66,11 +70,20 @@ 
 #define REF_CLK	1
 #define CLK_MAX 2
 
+enum auxoutsrc {
+	AUXSRC_REFCLK = 0,
+	AUXSRC_CLKIN,
+	AUXSRC_PLLCLKOUT,
+	AUXSRC_PUSHPULL,
+	AUXSRC_OPENDRAIN,
+};
+
 struct cs2000_priv {
 	struct clk_hw hw;
 	struct i2c_client *client;
 	struct clk *clk_in;
 	struct clk *ref_clk;
+	enum auxoutsrc auxoutsrc;
 
 	/* suspend/resume */
 	unsigned long saved_rate;
@@ -111,9 +124,27 @@  static int cs2000_bset(struct cs2000_priv *priv, u8 addr, u8 mask, u8 val)
 static int cs2000_enable_dev_config(struct cs2000_priv *priv, bool enable)
 {
 	int ret;
+	u8 dcfg1, fcfg1;
+
+	dcfg1 = 0;
+	fcfg1 = 0;
+	if (enable)
+		dcfg1 |= ENDEV1;
+	switch (priv->auxoutsrc) {
+	case AUXSRC_REFCLK:
+	case AUXSRC_CLKIN:
+	case AUXSRC_PLLCLKOUT:
+		dcfg1 |= AUXOUTSRC(priv->auxoutsrc);
+		break;
+	case AUXSRC_OPENDRAIN:
+		fcfg1 |= AUXLOCKCFG(1);
+		/* fall though */
+	case AUXSRC_PUSHPULL:
+		dcfg1 |= AUXOUTSRC(3);
+		break;
+	}
 
-	ret = cs2000_bset(priv, DEVICE_CFG1, ENDEV1,
-			  enable ? ENDEV1 : 0);
+	ret = cs2000_bset(priv, DEVICE_CFG1, (AUXOUTSRC_MASK | ENDEV1), dcfg1);
 	if (ret < 0)
 		return ret;
 
@@ -122,6 +153,10 @@  static int cs2000_enable_dev_config(struct cs2000_priv *priv, bool enable)
 	if (ret < 0)
 		return ret;
 
+	ret = cs2000_bset(priv, FUNC_CFG1, AUXLOCKCFG_MASK, fcfg1);
+	if (ret < 0)
+		return ret;
+
 	return 0;
 }
 
@@ -479,6 +514,38 @@  static int cs2000_remove(struct i2c_client *client)
 	return 0;
 }
 
+static void cs2000_of_parse(struct cs2000_priv *priv)
+{
+	struct device *dev = priv_to_dev(priv);
+	struct device_node *np = dev->of_node;
+	const char *auxoutsrc;
+
+	auxoutsrc = of_get_property(np, "auxoutsrc", NULL);
+
+	if (auxoutsrc) {
+		int i;
+		struct {
+			char *name;
+			enum auxoutsrc val;
+		} of_table[] = {
+			{"refclk",	AUXSRC_REFCLK},
+			{"clk_in",	AUXSRC_CLKIN},
+			{"pllclkout",	AUXSRC_PLLCLKOUT},
+			{"push-pull",	AUXSRC_PUSHPULL},
+			{"open-drain",	AUXSRC_OPENDRAIN},
+		};
+
+		for (i = 0; i < ARRAY_SIZE(of_table); i++) {
+			if (strcmp(of_table[i].name, auxoutsrc) == 0) {
+				priv->auxoutsrc = of_table[i].val;
+				dev_dbg(dev, "%s was selected\n",
+					of_table[i].name);
+				break;
+			}
+		}
+	}
+}
+
 static int cs2000_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
@@ -493,6 +560,8 @@  static int cs2000_probe(struct i2c_client *client,
 	priv->client = client;
 	i2c_set_clientdata(client, priv);
 
+	cs2000_of_parse(priv);
+
 	ret = cs2000_clk_get(priv);
 	if (ret < 0)
 		return ret;