Add device tree support for the TI PMIC TPS65090.
The device can be registered through platform or DT.

Add device tree binding document for this device.

Signed-off-by: Laxman Dewangan <ldewan...@nvidia.com>
---
 .../devicetree/bindings/regulator/tps65090.txt     |  121 ++++++++++++++++++++
 drivers/mfd/tps65090.c                             |   52 ++++++++-
 include/linux/mfd/tps65090.h                       |    1 +
 3 files changed, 172 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/regulator/tps65090.txt

diff --git a/Documentation/devicetree/bindings/regulator/tps65090.txt 
b/Documentation/devicetree/bindings/regulator/tps65090.txt
new file mode 100644
index 0000000..e81f47d
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/tps65090.txt
@@ -0,0 +1,121 @@
+TPS65090 regulators
+
+Required properties:
+- compatible: "ti,tps65090"
+- reg: I2C slave address
+- interrupts: the interrupt outputs of the controller
+- regulators: A node that houses a sub-node for each regulator within the
+  device. Each sub-node is identified using the node's name (or the deprecated
+  regulator-compatible property if present), with valid values listed below.
+  The content of each sub-node is defined by the standard binding for
+  regulators; see regulator.txt.
+  dcdc[1-3], fet[1-7] and ldo[1-2] respectively.
+- vsys[1-3]-supply: The input supply for DCDC[1-3] respectively.
+- infet[1-7]-supply: The input supply for FET[1-7] respectively.
+- vsys_l[1-2]-supply: The input supply for LDO[1-2] respectively.
+
+Optional properties:
+- ti,enable-ext-control: This is applicable for DCDC1, DCDC2 and DCDC3.
+  If DCDCs are externally controlled then this property should be there.
+- gpio: This is applicable for DCDC1, DCDC2 and DCDC3. If DCDCs are
+  extrenally controlled and if it is from GPIO then gpio number should
+  be provided. If it is externally controlled and no gpio entry then
+  driver will just configure this rails as external control and will not
+  provide any enable/disable APIs.
+
+Each regulator is defined using the standard binding for regulators.
+
+Example:
+
+       tps65090@48 {
+               compatible = "ti,tps65090";
+               reg = <0x48>;
+               interrupts = <0 88 0x4>;
+
+               vsys1-supply = <&some_reg>;
+               vsys2-supply = <&some_reg>;
+               vsys3-supply = <&some_reg>;
+               infet1-supply = <&some_reg>;
+               infet2-supply = <&some_reg>;
+               infet3-supply = <&some_reg>;
+               infet4-supply = <&some_reg>;
+               infet5-supply = <&some_reg>;
+               infet6-supply = <&some_reg>;
+               infet7-supply = <&some_reg>;
+               vsys_l1-supply = <&some_reg>;
+               vsys_l2-supply = <&some_reg>;
+
+               regulators {
+                       dcdc1 {
+                               regulator-name = "dcdc1";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       dcdc2 {
+                               regulator-name = "dcdc2";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       dcdc3 {
+                               regulator-name = "dcdc3";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       fet1 {
+                               regulator-name = "fet1";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       fet2 {
+                               regulator-name = "fet2";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       fet3 {
+                               regulator-name = "fet3";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       fet4 {
+                               regulator-name = "fet4";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       fet5 {
+                               regulator-name = "fet5";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       fet6 {
+                               regulator-name = "fet6";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       fet7 {
+                               regulator-name = "fet7";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo1 {
+                               regulator-name = "ldo1";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo2 {
+                               regulator-name = "ldo2";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+               };
+       };
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c
index 8d12a8e..e4cf030 100644
--- a/drivers/mfd/tps65090.c
+++ b/drivers/mfd/tps65090.c
@@ -25,6 +25,8 @@
 #include <linux/i2c.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/tps65090.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/err.h>
 
 #define NUM_INT_REG 2
@@ -148,6 +150,37 @@ static const struct regmap_config tps65090_regmap_config = 
{
        .volatile_reg = is_volatile_reg,
 };
 
+#ifdef CONFIG_OF
+static const struct of_device_id tps65090_of_match[] = {
+       { .compatible = "ti,tps65090",},
+       {},
+};
+MODULE_DEVICE_TABLE(of, tps65090_of_match);
+
+static struct tps65090_platform_data *
+       of_get_tps65090_platform_data(struct device *dev)
+{
+       struct tps65090_platform_data *pdata;
+
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata) {
+               dev_err(dev, "Memory alloc failed for platform data\n");
+               return ERR_PTR(-ENOMEM);
+       }
+       /*
+        * Nothing to set/parse here as DT parsing of regulators will be
+        * done in regulator driver.
+        */
+       return pdata;
+}
+#else
+static struct tps65090_platform_data *
+       of_get_tps65090_platform_data(struct device *dev)
+{
+       return NULL;
+}
+#endif
+
 static int tps65090_i2c_probe(struct i2c_client *client,
                                        const struct i2c_device_id *id)
 {
@@ -155,9 +188,22 @@ static int tps65090_i2c_probe(struct i2c_client *client,
        struct tps65090 *tps65090;
        int ret;
 
-       if (!pdata) {
+       if (client->dev.of_node) {
+               const struct of_device_id *match;
+
+               match = of_match_device(of_match_ptr(tps65090_of_match),
+                               &client->dev);
+               if (!match) {
+                       dev_err(&client->dev, "No match device found\n");
+                       return -ENODEV;
+               }
+       }
+
+       if (!pdata && client->dev.of_node)
+               pdata = of_get_tps65090_platform_data(&client->dev);
+       if (IS_ERR_OR_NULL(pdata)) {
                dev_err(&client->dev, "tps65090 requires platform data\n");
-               return -EINVAL;
+               return (pdata) ? PTR_ERR(pdata) : -EINVAL;
        }
 
        tps65090 = devm_kzalloc(&client->dev, sizeof(*tps65090), GFP_KERNEL);
@@ -167,6 +213,7 @@ static int tps65090_i2c_probe(struct i2c_client *client,
        }
 
        tps65090->dev = &client->dev;
+       tps65090->pdata = pdata;
        i2c_set_clientdata(client, tps65090);
 
        tps65090->rmap = devm_regmap_init_i2c(client, &tps65090_regmap_config);
@@ -247,6 +294,7 @@ static struct i2c_driver tps65090_driver = {
        .driver = {
                .name   = "tps65090",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(tps65090_of_match),
                .pm     = &tps65090_pm_ops,
        },
        .probe          = tps65090_i2c_probe,
diff --git a/include/linux/mfd/tps65090.h b/include/linux/mfd/tps65090.h
index 6694cf4..4403c54 100644
--- a/include/linux/mfd/tps65090.h
+++ b/include/linux/mfd/tps65090.h
@@ -67,6 +67,7 @@ struct tps65090 {
        struct device           *dev;
        struct regmap           *rmap;
        struct regmap_irq_chip_data *irq_data;
+       struct tps65090_platform_data *pdata;
 };
 
 /*
-- 
1.7.1.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to