diff mbox

ASoC: rt5677: Add a configuration option for LDO2_POW pin

Message ID 1410448118-39936-1-git-send-email-anatol.pomozov@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Anatol Pomozov Sept. 11, 2014, 3:08 p.m. UTC
From: Anatol Pomozov <anatol@google.com>

Some boards have this pin tied to board and do not require any configuration,
some other boards allow to enable chip using GPIO.

Add an option that tells which GPIO is used to power up the codec.

Signed-off-by: Anatol Pomozov <anatol@google.com>
---
 Documentation/devicetree/bindings/sound/rt5677.txt | 41 +++++++++++++++++++++
 sound/soc/codecs/rt5677.c                          | 42 ++++++++++++++++++++++
 sound/soc/codecs/rt5677.h                          |  2 ++
 3 files changed, 85 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/rt5677.txt

Comments

Anatol Pomozov Sept. 11, 2014, 3:27 p.m. UTC | #1
Hi

On Thu, Sep 11, 2014 at 8:08 AM, Anatol Pomozov
<anatol.pomozov@gmail.com> wrote:
> From: Anatol Pomozov <anatol@google.com>
>
> Some boards have this pin tied to board and do not require any configuration,
> some other boards allow to enable chip using GPIO.
>
> Add an option that tells which GPIO is used to power up the codec.
>
> Signed-off-by: Anatol Pomozov <anatol@google.com>
> ---
>  Documentation/devicetree/bindings/sound/rt5677.txt | 41 +++++++++++++++++++++
>  sound/soc/codecs/rt5677.c                          | 42 ++++++++++++++++++++++
>  sound/soc/codecs/rt5677.h                          |  2 ++
>  3 files changed, 85 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/rt5677.txt
>
> diff --git a/Documentation/devicetree/bindings/sound/rt5677.txt b/Documentation/devicetree/bindings/sound/rt5677.txt
> new file mode 100644
> index 0000000..572a42c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/rt5677.txt
> @@ -0,0 +1,41 @@
> +RT5677 audio CODEC
> +
> +This device supports I2C only.
> +
> +Required properties:
> +
> +- compatible : "realtek,rt5677".
> +
> +- reg : The I2C address of the device.
> +
> +- interrupts : The CODEC's interrupt output.
> +
> +Optional properties:
> +
> +- realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin.
> +
> +Pins on the device (for linking into audio routes):
> +
> +  * IN1P
> +  * IN1N
> +  * IN2P
> +  * IN2N
> +  * MICBIAS1
> +  * DMIC1
> +  * DMIC2
> +  * DMIC3
> +  * DMIC4
> +  * LOUT1
> +  * LOUT2
> +  * LOUT3
> +
> +Example:
> +
> +rt5677 {
> +       compatible = "realtek,rt5677";
> +       reg = <0x1c>;
> +       interrupt-parent = <&gpio>;
> +       interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
> +       realtek,pow-ldo2-gpio =
> +               <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
> +};
> diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
> index 40a49ef..cf41e89 100644
> --- a/sound/soc/codecs/rt5677.c
> +++ b/sound/soc/codecs/rt5677.c
> @@ -15,6 +15,7 @@
>  #include <linux/init.h>
>  #include <linux/delay.h>
>  #include <linux/pm.h>
> +#include <linux/of_gpio.h>
>  #include <linux/regmap.h>
>  #include <linux/i2c.h>
>  #include <linux/platform_device.h>
> @@ -3365,6 +3366,24 @@ static const struct i2c_device_id rt5677_i2c_id[] = {
>  };
>  MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
>
> +static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np)
> +{
> +       rt5677->pow_ldo2 = of_get_named_gpio(np,
> +                                       "realtek,pow-ldo2-gpio", 0);
> +

I would like to clarify what is the right way to configure codec. I
see that different drivers use different ways to do it.

It looks like using DTS files is preferred way. RT5640 does it. But
for some reason RT5677 uses rt5677_platform_data structure (is it
populated in the platform driver?).

What I suppose to do here? Use DTS to set pow-ldo2-gpio or add a new
field to rt5677_platform_data?

> +       /*
> +        * POW_LDO2 is optional (it may be statically tied on the board).
> +        * -ENOENT means that the property doesn't exist, i.e. there is no
> +        * GPIO, so is not an error. Any other error code means the property
> +        * exists, but could not be parsed.
> +        */
> +       if (!gpio_is_valid(rt5677->pow_ldo2) &&
> +                       (rt5677->pow_ldo2 != -ENOENT))
> +               return rt5677->pow_ldo2;
> +
> +       return 0;
> +}
> +
>  static int rt5677_i2c_probe(struct i2c_client *i2c,
>                     const struct i2c_device_id *id)
>  {
> @@ -3383,6 +3402,29 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
>         if (pdata)
>                 rt5677->pdata = *pdata;
>
> +       if (i2c->dev.of_node) {
> +               ret = rt5677_parse_dt(rt5677, i2c->dev.of_node);
> +               if (ret) {
> +                       dev_err(&i2c->dev, "Failed to parse device tree: %d\n",
> +                               ret);
> +                       return ret;
> +               }
> +       } else {
> +               rt5677->pow_ldo2 = -EINVAL;
> +       }
> +
> +       if (gpio_is_valid(rt5677->pow_ldo2)) {
> +               ret = devm_gpio_request_one(&i2c->dev, rt5677->pow_ldo2,
> +                                           GPIOF_OUT_INIT_HIGH,
> +                                           "RT5677 POW_LDO2");
> +               if (ret < 0) {
> +                       dev_err(&i2c->dev, "Failed to request POW_LDO2 %d: %d\n",
> +                               rt5677->pow_ldo2, ret);
> +                       return ret;
> +               }
> +               msleep(10);

A question to Realtek people. What delay should be here? The datasheet
is not clear about how much time it is required to get I2C working. I
use 10ms and my board is happy.

> +       }
> +
>         rt5677->regmap = devm_regmap_init_i2c(i2c, &rt5677_regmap);
>         if (IS_ERR(rt5677->regmap)) {
>                 ret = PTR_ERR(rt5677->regmap);
> diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h
> index 8791ab9..3c1b4dc 100644
> --- a/sound/soc/codecs/rt5677.h
> +++ b/sound/soc/codecs/rt5677.h
> @@ -1441,6 +1441,8 @@ struct rt5677_priv {
>         int pll_src;
>         int pll_in;
>         int pll_out;
> +
> +       int pow_ldo2; /* POW_LDO2 pin */
>  };
>
>  #endif /* __RT5677_H__ */
> --
> 2.1.0.rc2.206.gedb03e5
>
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/sound/rt5677.txt b/Documentation/devicetree/bindings/sound/rt5677.txt
new file mode 100644
index 0000000..572a42c
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rt5677.txt
@@ -0,0 +1,41 @@ 
+RT5677 audio CODEC
+
+This device supports I2C only.
+
+Required properties:
+
+- compatible : "realtek,rt5677".
+
+- reg : The I2C address of the device.
+
+- interrupts : The CODEC's interrupt output.
+
+Optional properties:
+
+- realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin.
+
+Pins on the device (for linking into audio routes):
+
+  * IN1P
+  * IN1N
+  * IN2P
+  * IN2N
+  * MICBIAS1
+  * DMIC1
+  * DMIC2
+  * DMIC3
+  * DMIC4
+  * LOUT1
+  * LOUT2
+  * LOUT3
+
+Example:
+
+rt5677 {
+	compatible = "realtek,rt5677";
+	reg = <0x1c>;
+	interrupt-parent = <&gpio>;
+	interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
+	realtek,pow-ldo2-gpio =
+		<&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
+};
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 40a49ef..cf41e89 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -15,6 +15,7 @@ 
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
+#include <linux/of_gpio.h>
 #include <linux/regmap.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
@@ -3365,6 +3366,24 @@  static const struct i2c_device_id rt5677_i2c_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
 
+static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np)
+{
+	rt5677->pow_ldo2 = of_get_named_gpio(np,
+					"realtek,pow-ldo2-gpio", 0);
+
+	/*
+	 * POW_LDO2 is optional (it may be statically tied on the board).
+	 * -ENOENT means that the property doesn't exist, i.e. there is no
+	 * GPIO, so is not an error. Any other error code means the property
+	 * exists, but could not be parsed.
+	 */
+	if (!gpio_is_valid(rt5677->pow_ldo2) &&
+			(rt5677->pow_ldo2 != -ENOENT))
+		return rt5677->pow_ldo2;
+
+	return 0;
+}
+
 static int rt5677_i2c_probe(struct i2c_client *i2c,
 		    const struct i2c_device_id *id)
 {
@@ -3383,6 +3402,29 @@  static int rt5677_i2c_probe(struct i2c_client *i2c,
 	if (pdata)
 		rt5677->pdata = *pdata;
 
+	if (i2c->dev.of_node) {
+		ret = rt5677_parse_dt(rt5677, i2c->dev.of_node);
+		if (ret) {
+			dev_err(&i2c->dev, "Failed to parse device tree: %d\n",
+				ret);
+			return ret;
+		}
+	} else {
+		rt5677->pow_ldo2 = -EINVAL;
+	}
+
+	if (gpio_is_valid(rt5677->pow_ldo2)) {
+		ret = devm_gpio_request_one(&i2c->dev, rt5677->pow_ldo2,
+					    GPIOF_OUT_INIT_HIGH,
+					    "RT5677 POW_LDO2");
+		if (ret < 0) {
+			dev_err(&i2c->dev, "Failed to request POW_LDO2 %d: %d\n",
+				rt5677->pow_ldo2, ret);
+			return ret;
+		}
+		msleep(10);
+	}
+
 	rt5677->regmap = devm_regmap_init_i2c(i2c, &rt5677_regmap);
 	if (IS_ERR(rt5677->regmap)) {
 		ret = PTR_ERR(rt5677->regmap);
diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h
index 8791ab9..3c1b4dc 100644
--- a/sound/soc/codecs/rt5677.h
+++ b/sound/soc/codecs/rt5677.h
@@ -1441,6 +1441,8 @@  struct rt5677_priv {
 	int pll_src;
 	int pll_in;
 	int pll_out;
+
+	int pow_ldo2; /* POW_LDO2 pin */
 };
 
 #endif /* __RT5677_H__ */