aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2013-06-12 13:34:30 -0400
committerMark Brown <broonie@linaro.org>2013-06-12 14:25:22 -0400
commitdcad9f031240d59e9e1475a8e5b2cb427da94f6e (patch)
tree5bb28075e74375030c5fd2e89531f01660700047
parent997b05203b0a710e11f9b2732bef2d2fdc1d824b (diff)
ASoC: rt5640: add device tree support
Modify the RT5640 driver to parse platform data from device tree. Write a DT binding document to describe those properties. Slight re-ordering of rt5640_i2c_probe() to better fit the DT parsing. Since ldo1_en is optional, guard usage of it with gpio_is_valid(), rather than open-coding an if (gpio) check. Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--Documentation/devicetree/bindings/sound/rt5640.txt30
-rw-r--r--sound/soc/codecs/rt5640.c48
2 files changed, 72 insertions, 6 deletions
diff --git a/Documentation/devicetree/bindings/sound/rt5640.txt b/Documentation/devicetree/bindings/sound/rt5640.txt
new file mode 100644
index 000000000000..005bcb24d72d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rt5640.txt
@@ -0,0 +1,30 @@
1RT5640 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7- compatible : "realtek,rt5640".
8
9- reg : The I2C address of the device.
10
11- interrupts : The CODEC's interrupt output.
12
13Optional properties:
14
15- realtek,in1-differential
16- realtek,in2-differential
17 Boolean. Indicate MIC1/2 input are differential, rather than single-ended.
18
19- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
20
21Example:
22
23rt5640 {
24 compatible = "realtek,rt5640";
25 reg = <0x1c>;
26 interrupt-parent = <&gpio>;
27 interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
28 realtek,ldo1-en-gpios =
29 <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
30};
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 288c17cd6023..8761552882a5 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -18,6 +18,7 @@
18#include <linux/gpio.h> 18#include <linux/gpio.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/regmap.h> 20#include <linux/regmap.h>
21#include <linux/of_gpio.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 23#include <linux/spi/spi.h>
23#include <sound/core.h> 24#include <sound/core.h>
@@ -1998,6 +1999,28 @@ static const struct i2c_device_id rt5640_i2c_id[] = {
1998}; 1999};
1999MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id); 2000MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id);
2000 2001
2002static int rt5640_parse_dt(struct rt5640_priv *rt5640, struct device_node *np)
2003{
2004 rt5640->pdata.in1_diff = of_property_read_bool(np,
2005 "realtek,in1-differential");
2006 rt5640->pdata.in2_diff = of_property_read_bool(np,
2007 "realtek,in2-differential");
2008
2009 rt5640->pdata.ldo1_en = of_get_named_gpio(np,
2010 "realtek,ldo1-en-gpios", 0);
2011 /*
2012 * LDO1_EN is optional (it may be statically tied on the board).
2013 * -ENOENT means that the property doesn't exist, i.e. there is no
2014 * GPIO, so is not an error. Any other error code means the property
2015 * exists, but could not be parsed.
2016 */
2017 if (!gpio_is_valid(rt5640->pdata.ldo1_en) &&
2018 (rt5640->pdata.ldo1_en != -ENOENT))
2019 return rt5640->pdata.ldo1_en;
2020
2021 return 0;
2022}
2023
2001static int rt5640_i2c_probe(struct i2c_client *i2c, 2024static int rt5640_i2c_probe(struct i2c_client *i2c,
2002 const struct i2c_device_id *id) 2025 const struct i2c_device_id *id)
2003{ 2026{
@@ -2011,6 +2034,24 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
2011 GFP_KERNEL); 2034 GFP_KERNEL);
2012 if (NULL == rt5640) 2035 if (NULL == rt5640)
2013 return -ENOMEM; 2036 return -ENOMEM;
2037 i2c_set_clientdata(i2c, rt5640);
2038
2039 if (pdata) {
2040 rt5640->pdata = *pdata;
2041 /*
2042 * Translate zero'd out (default) pdata value to an invalid
2043 * GPIO ID. This makes the pdata and DT paths consistent in
2044 * terms of the value left in this field when no GPIO is
2045 * specified, but means we can't actually use GPIO 0.
2046 */
2047 if (!rt5640->pdata.ldo1_en)
2048 rt5640->pdata.ldo1_en = -EINVAL;
2049 } else if (i2c->dev.of_node) {
2050 ret = rt5640_parse_dt(rt5640, i2c->dev.of_node);
2051 if (ret)
2052 return ret;
2053 } else
2054 rt5640->pdata.ldo1_en = -EINVAL;
2014 2055
2015 rt5640->regmap = devm_regmap_init_i2c(i2c, &rt5640_regmap); 2056 rt5640->regmap = devm_regmap_init_i2c(i2c, &rt5640_regmap);
2016 if (IS_ERR(rt5640->regmap)) { 2057 if (IS_ERR(rt5640->regmap)) {
@@ -2020,12 +2061,7 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
2020 return ret; 2061 return ret;
2021 } 2062 }
2022 2063
2023 if (pdata) 2064 if (gpio_is_valid(rt5640->pdata.ldo1_en)) {
2024 rt5640->pdata = *pdata;
2025
2026 i2c_set_clientdata(i2c, rt5640);
2027
2028 if (rt5640->pdata.ldo1_en) {
2029 ret = devm_gpio_request_one(&i2c->dev, rt5640->pdata.ldo1_en, 2065 ret = devm_gpio_request_one(&i2c->dev, rt5640->pdata.ldo1_en,
2030 GPIOF_OUT_INIT_HIGH, 2066 GPIOF_OUT_INIT_HIGH,
2031 "RT5640 LDO1_EN"); 2067 "RT5640 LDO1_EN");