]> git.karo-electronics.de Git - linux-beck.git/commitdiff
mfd: Add device tree bindings for Arizona class devices
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 25 Mar 2013 00:11:27 +0000 (00:11 +0000)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 20 May 2013 13:13:36 +0000 (08:13 -0500)
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Documentation/devicetree/bindings/mfd/arizona.txt [new file with mode: 0644]
drivers/mfd/arizona-core.c
drivers/mfd/arizona-i2c.c
drivers/mfd/arizona-spi.c
drivers/mfd/arizona.h

diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt
new file mode 100644 (file)
index 0000000..0e295c9
--- /dev/null
@@ -0,0 +1,62 @@
+Wolfson Arizona class audio SoCs
+
+These devices are audio SoCs with extensive digital capabilites and a range
+of analogue I/O.
+
+Required properties:
+
+  - compatible : one of the following chip-specific strings:
+       "wlf,wm5102"
+       "wlf,wm5110"
+  - reg : I2C slave address when connected using I2C, chip select number when
+    using SPI.
+
+  - interrupts : The interrupt line the /IRQ signal for the device is
+    connected to.
+  - interrupt-controller : Arizona class devices contain interrupt controllers
+    and may provide interrupt services to other devices.
+  - interrupt-parent : The parent interrupt controller.
+  - #interrupt-cells: the number of cells to describe an IRQ, this should be 2.
+    The first cell is the IRQ number.
+    The second cell is the flags, encoded as the trigger masks from
+    Documentation/devicetree/bindings/interrupts.txt
+
+  - gpio-controller : Indicates this device is a GPIO controller.
+  - #gpio-cells : Must be 2. The first cell is the pin number and the
+    second cell is used to specify optional parameters (currently unused).
+
+  - AVDD1-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply,
+    SPKVDDL-supply, SPKVDDR-supply : power supplies for the device, as covered
+    in Documentation/devicetree/bindings/regulator/regulator.txt
+
+Optional properties:
+
+  - wlf,reset : GPIO specifier for the GPIO controlling /RESET
+  - wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA
+
+  - wlf,gpio-defaults : A list of GPIO configuration register values. If
+    absent, no configuration of these registers is performed. If any
+    entry has a value that is out of range for a 16 bit register then
+    the chip default will be used.  If present exactly five values must
+    be specified.
+
+Example:
+
+codec: wm5102@1a {
+       compatible = "wlf,wm5102";
+       reg = <0x1a>;
+       interrupts = <347>;
+       #interrupt-cells = <2>;
+        interrupt-parent = <&gic>;
+
+       gpio-controller;
+       #gpio-cells = <2>;
+
+       wlf,gpio-defaults = <
+               0x00000000, /* AIF1TXLRCLK */
+               0xffffffff,
+               0xffffffff,
+               0xffffffff,
+               0xffffffff,
+       >;
+};
index 549db0ad72573275d237ea84aeec7e85179bf150..d8d30c0a488d2be079f76f900cc10ce7b2a02af7 100644 (file)
@@ -16,6 +16,9 @@
 #include <linux/interrupt.h>
 #include <linux/mfd/core.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
@@ -462,6 +465,70 @@ const struct dev_pm_ops arizona_pm_ops = {
 };
 EXPORT_SYMBOL_GPL(arizona_pm_ops);
 
+#ifdef CONFIG_OF
+int arizona_of_get_type(struct device *dev)
+{
+       const struct of_device_id *id = of_match_device(arizona_of_match, dev);
+
+       if (id)
+               return (int)id->data;
+       else
+               return 0;
+}
+EXPORT_SYMBOL_GPL(arizona_of_get_type);
+
+static int arizona_of_get_core_pdata(struct arizona *arizona)
+{
+       int ret, i;
+
+       arizona->pdata.reset = of_get_named_gpio(arizona->dev->of_node,
+                                                "wlf,reset", 0);
+       if (arizona->pdata.reset < 0)
+               arizona->pdata.reset = 0;
+
+       arizona->pdata.ldoena = of_get_named_gpio(arizona->dev->of_node,
+                                                 "wlf,ldoena", 0);
+       if (arizona->pdata.ldoena < 0)
+               arizona->pdata.ldoena = 0;
+
+       ret = of_property_read_u32_array(arizona->dev->of_node,
+                                        "wlf,gpio-defaults",
+                                        arizona->pdata.gpio_defaults,
+                                        ARRAY_SIZE(arizona->pdata.gpio_defaults));
+       if (ret >= 0) {
+               /*
+                * All values are literal except out of range values
+                * which are chip default, translate into platform
+                * data which uses 0 as chip default and out of range
+                * as zero.
+                */
+               for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
+                       if (arizona->pdata.gpio_defaults[i] > 0xffff)
+                               arizona->pdata.gpio_defaults[i] = 0;
+                       if (arizona->pdata.gpio_defaults[i] == 0)
+                               arizona->pdata.gpio_defaults[i] = 0x10000;
+               }
+       } else {
+               dev_err(arizona->dev, "Failed to parse GPIO defaults: %d\n",
+                       ret);
+       }
+
+       return 0;
+}
+
+const struct of_device_id arizona_of_match[] = {
+       { .compatible = "wlf,wm5102", .data = (void *)WM5102 },
+       { .compatible = "wlf,wm5110", .data = (void *)WM5110 },
+       {},
+};
+EXPORT_SYMBOL_GPL(arizona_of_match);
+#else
+static inline int arizona_of_get_core_pdata(struct arizona *arizona)
+{
+       return 0;
+}
+#endif
+
 static struct mfd_cell early_devs[] = {
        { .name = "arizona-ldo1" },
 };
@@ -495,6 +562,8 @@ int arizona_dev_init(struct arizona *arizona)
        dev_set_drvdata(arizona->dev, arizona);
        mutex_init(&arizona->clk_lock);
 
+       arizona_of_get_core_pdata(arizona);
+
        if (dev_get_platdata(arizona->dev))
                memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
                       sizeof(arizona->pdata));
index 44a1bb96984185e3757f31330a37d50266fdbbed..deb267ebf84e3cdff73619d1f8dbe1c6f44b4e8a 100644 (file)
@@ -27,9 +27,14 @@ static int arizona_i2c_probe(struct i2c_client *i2c,
 {
        struct arizona *arizona;
        const struct regmap_config *regmap_config;
-       int ret;
+       int ret, type;
 
-       switch (id->driver_data) {
+       if (i2c->dev.of_node)
+               type = arizona_of_get_type(&i2c->dev);
+       else
+               type = id->driver_data;
+
+       switch (type) {
 #ifdef CONFIG_MFD_WM5102
        case WM5102:
                regmap_config = &wm5102_i2c_regmap;
@@ -84,6 +89,7 @@ static struct i2c_driver arizona_i2c_driver = {
                .name   = "arizona",
                .owner  = THIS_MODULE,
                .pm     = &arizona_pm_ops,
+               .of_match_table = of_match_ptr(arizona_of_match),
        },
        .probe          = arizona_i2c_probe,
        .remove         = arizona_i2c_remove,
index b57e642d2b4a3eedaad99e65822e728ab6ff0ae6..47be7b35b5c5b09c9e17c4ef0cb7dae32b0c2855 100644 (file)
@@ -27,9 +27,14 @@ static int arizona_spi_probe(struct spi_device *spi)
        const struct spi_device_id *id = spi_get_device_id(spi);
        struct arizona *arizona;
        const struct regmap_config *regmap_config;
-       int ret;
+       int ret, type;
 
-       switch (id->driver_data) {
+       if (spi->dev.of_node)
+               type = arizona_of_get_type(&spi->dev);
+       else
+               type = id->driver_data;
+
+       switch (type) {
 #ifdef CONFIG_MFD_WM5102
        case WM5102:
                regmap_config = &wm5102_spi_regmap;
@@ -84,6 +89,7 @@ static struct spi_driver arizona_spi_driver = {
                .name   = "arizona",
                .owner  = THIS_MODULE,
                .pm     = &arizona_pm_ops,
+               .of_match_table = of_match_ptr(arizona_of_match),
        },
        .probe          = arizona_spi_probe,
        .remove         = arizona_spi_remove,
index 9798ae5da67be2b72f2d52101266c825d0e47a19..db55d9854a5587cb1d87fd46bb3d1eee6c085c00 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef _WM5102_H
 #define _WM5102_H
 
+#include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/pm.h>
 
@@ -26,6 +27,8 @@ extern const struct regmap_config wm5110_spi_regmap;
 
 extern const struct dev_pm_ops arizona_pm_ops;
 
+extern const struct of_device_id arizona_of_match[];
+
 extern const struct regmap_irq_chip wm5102_aod;
 extern const struct regmap_irq_chip wm5102_irq;
 
@@ -37,4 +40,13 @@ int arizona_dev_exit(struct arizona *arizona);
 int arizona_irq_init(struct arizona *arizona);
 int arizona_irq_exit(struct arizona *arizona);
 
+#ifdef CONFIG_OF
+int arizona_of_get_type(struct device *dev);
+#else
+static inline int arizona_of_get_type(struct device *dev)
+{
+       return 0;
+}
+#endif
+
 #endif