Discussion:
[PATCH 1/2] ASoC: rt5677: Add a configuration option for LDO2_POW pin
Anatol Pomozov
2014-09-17 05:28:58 UTC
Permalink
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 <***@gmail.com>
---
Documentation/devicetree/bindings/sound/rt5677.txt | 41 +++++++++++++++++++++
sound/soc/codecs/rt5677.c | 42 ++++++++++++++++++++++
sound/soc/codecs/rt5677.h | 1 +
3 files changed, 84 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..98509fb
--- /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 = <0x2c>;
+ 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 9847473..fbaceb6 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>
@@ -3495,6 +3496,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)
{
@@ -3513,6 +3532,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 b61b72c..222a4137 100644
--- a/sound/soc/codecs/rt5677.h
+++ b/sound/soc/codecs/rt5677.h
@@ -1550,6 +1550,7 @@ struct rt5677_priv {
int pll_src;
int pll_in;
int pll_out;
+ int pow_ldo2; /* POW_LDO2 pin */
#ifdef CONFIG_GPIOLIB
struct gpio_chip gpio_chip;
#endif
--
2.1.0.rc2.206.gedb03e5
Anatol Pomozov
2014-09-17 05:28:59 UTC
Permalink
Signed-off-by: Anatol Pomozov <***@gmail.com>
---
sound/soc/codecs/rt5677.c | 7 +++++++
sound/soc/codecs/rt5677.h | 4 ++++
2 files changed, 11 insertions(+)

diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index fbaceb6..86cdf82 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -542,6 +542,7 @@ static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
+static const DECLARE_TLV_DB_SCALE(st_vol_tlv, -4650, 150, 0);

/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
static unsigned int bst_tlv[] = {
@@ -578,6 +579,12 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = {
SOC_SINGLE_TLV("IN1 Boost", RT5677_IN1, RT5677_BST_SFT1, 8, 0, bst_tlv),
SOC_SINGLE_TLV("IN2 Boost", RT5677_IN1, RT5677_BST_SFT2, 8, 0, bst_tlv),

+ /* Sidetone Control */
+ SOC_SINGLE("Sidetone Switch", RT5677_SIDETONE_CTRL,
+ RT5677_ST_EN_SFT, 1, 0),
+ SOC_SINGLE_TLV("Sidetone Volume", RT5677_SIDETONE_CTRL,
+ RT5677_ST_VOL_SFT, 31, 0, st_vol_tlv),
+
/* ADC Digital Volume Control */
SOC_DOUBLE("ADC1 Capture Switch", RT5677_STO1_ADC_DIG_VOL,
RT5677_L_MUTE_SFT, RT5677_R_MUTE_SFT, 1, 1),
diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h
index 222a4137..d4eb6d5 100644
--- a/sound/soc/codecs/rt5677.h
+++ b/sound/soc/codecs/rt5677.h
@@ -382,6 +382,10 @@
#define RT5677_ST_SEL_SFT 9
#define RT5677_ST_EN (0x1 << 6)
#define RT5677_ST_EN_SFT 6
+#define RT5677_ST_GAIN (0x1 << 5)
+#define RT5677_ST_GAIN_SFT 5
+#define RT5677_ST_VOL_MASK (0x1f << 0)
+#define RT5677_ST_VOL_SFT 0

/* Analog DAC1/2/3 Source Control (0x15) */
#define RT5677_ANA_DAC3_SRC_SEL_MASK (0x3 << 4)
--
2.1.0.rc2.206.gedb03e5
Mark Brown
2014-09-17 16:58:58 UTC
Permalink
Post by Anatol Pomozov
+ /* Sidetone Control */
+ SOC_SINGLE("Sidetone Switch", RT5677_SIDETONE_CTRL,
+ RT5677_ST_EN_SFT, 1, 0),
If this is enabling and disabling a route (as it will be since it's a
sidetone) I would expect to see the route represented in DAPM.

Mark Brown
2014-09-17 16:57:54 UTC
Permalink
Post by Anatol Pomozov
+ 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);
+ }
This doesn't disable the GPIO on remove which I'd expect, along with
management at at least suspend and resume if not at runtime. The
removal is the most important one though.
Loading...