[PATCH] regulator: tps65023: add device tree support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




Add device tree based initialization support for tps65023 regulators.
Add device tree binding document for tps65023 regulators.

Signed-off-by: Thomas Elste <thomas.elste@xxxxxxx>
---
 .../devicetree/bindings/regulator/tps65023.txt     | 58 +++++++++++++++
 drivers/regulator/tps65023-regulator.c             | 83 +++++++++++++++++++++-
 2 files changed, 139 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/regulator/tps65023.txt

diff --git a/Documentation/devicetree/bindings/regulator/tps65023.txt b/Documentation/devicetree/bindings/regulator/tps65023.txt
new file mode 100644
index 0000000..bdd0d96
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/tps65023.txt
@@ -0,0 +1,58 @@
+TPS65023 family of regulators
+
+Required properties:
+- compatible: Must be one of the following.
+	"ti,tps65020",
+	"ti,tps65021",
+	"ti,tps65023",
+- reg: I2C slave address
+- regulators: list of regulators provided by this controller, must be named
+  after their hardware counterparts: VDCDC[1-3] and LDO[1-2]
+- regulators: This is the list of child nodes that specify the regulator
+  initialization data for defined regulators. The definition for each of
+  these nodes is defined using the standard binding for regulators found at
+  Documentation/devicetree/bindings/regulator/regulator.txt.
+
+Example:
+
+	tps65023@48 {
+		compatible = "ti,tps65023";
+		reg = <0x48>;
+
+		regulators {
+			VDCDC1 {
+				regulator-name = "vdd_mpu";
+				regulator-always-on;
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+			};
+
+			VDCDC2 {
+				regulator-name = "vdd_core";
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			VDCDC3 {
+				regulator-name = "vdd_io";
+				regulator-always-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			LDO1 {
+				regulator-name = "vdd_usb18";
+				regulator-always-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			LDO2 {
+				regulator-name = "vdd_usb33";
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+			};
+		};
+	};
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c
index 5cc19b4..5247d23 100644
--- a/drivers/regulator/tps65023-regulator.c
+++ b/drivers/regulator/tps65023-regulator.c
@@ -19,9 +19,12 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/regmap.h>
@@ -199,6 +202,63 @@ static const struct regmap_config tps65023_regmap_config = {
 	.val_bits = 8,
 };
 
+static const struct of_device_id tps65023_of_match[] = {
+	{ .compatible = "ti,tps65020"},
+	{ .compatible = "ti,tps65021"},
+	{ .compatible = "ti,tps65023"},
+	{},
+};
+MODULE_DEVICE_TABLE(of, tps65023_of_match);
+
+static struct of_regulator_match tps65023_matches[] = {
+	{ .name = "VDCDC1"},
+	{ .name = "VDCDC2"},
+	{ .name = "VDCDC3"},
+	{ .name = "LDO1"},
+	{ .name = "LDO2"},
+};
+
+static struct regulator_init_data*
+	of_get_tps65023_platform_data(struct device *dev)
+{
+	struct regulator_init_data *reg_data;
+	struct device_node *np = dev->of_node;
+	struct device_node *regulators;
+	struct of_regulator_match *matches;
+	int idx, count, ret;
+
+	regulators = of_get_child_by_name(np, "regulators");
+	if (!regulators) {
+		dev_err(dev, "Regulator node not found\n");
+		return NULL;
+	}
+
+	count = ARRAY_SIZE(tps65023_matches);
+	matches = tps65023_matches;
+
+	ret = of_regulator_match(dev, regulators, matches, count);
+	of_node_put(regulators);
+	if (ret < 0) {
+		dev_err(dev, "Error parsing regulator init data: %d\n", ret);
+		return NULL;
+	}
+
+	reg_data = devm_kzalloc(dev, sizeof(*reg_data) *
+			TPS65023_NUM_REGULATOR, GFP_KERNEL);
+	if (!reg_data)
+		return NULL;
+
+	for (idx = 0; idx < count; idx++) {
+		if (!matches[idx].init_data || !matches[idx].of_node)
+			continue;
+
+		memcpy(&reg_data[idx], matches[idx].init_data,
+				sizeof(struct regulator_init_data));
+	}
+
+	return reg_data;
+}
+
 static int tps_65023_probe(struct i2c_client *client,
 				     const struct i2c_device_id *id)
 {
@@ -211,13 +271,31 @@ static int tps_65023_probe(struct i2c_client *client,
 	int i;
 	int error;
 
+	if (client->dev.of_node) {
+		const struct of_device_id *match;
+
+		match = of_match_device(of_match_ptr(tps65023_of_match),
+				&client->dev);
+		if (!match) {
+			dev_err(&client->dev, "No device match found\n");
+			return -ENODEV;
+		}
+	}
+
 	/**
 	 * init_data points to array of regulator_init structures
 	 * coming from the board-evm file.
 	 */
 	init_data = dev_get_platdata(&client->dev);
-	if (!init_data)
-		return -EIO;
+
+	/* if not provided by board file, check for OF entry */
+	if (IS_ENABLED(CONFIG_OF) && !init_data && client->dev.of_node)
+		init_data = of_get_tps65023_platform_data(&client->dev);
+
+	if (!init_data) {
+		dev_err(&client->dev, "No platform data\n");
+		return -EINVAL;
+	}
 
 	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
 	if (!tps)
@@ -410,6 +488,7 @@ MODULE_DEVICE_TABLE(i2c, tps_65023_id);
 static struct i2c_driver tps_65023_i2c_driver = {
 	.driver = {
 		.name = "tps65023",
+		.of_match_table = of_match_ptr(tps65023_of_match),
 	},
 	.probe = tps_65023_probe,
 	.id_table = tps_65023_id,
-- 
2.3.6

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux