regulator: tps65023 : Adding support for DT
Jean-Michel Hautbois
jean-michel.hautbois at vodalys.com
Thu Dec 11 00:36:26 PST 2014
Hi,
I have a board with a AM3505 and a tps65023 PMIC.
Until now, this board was running a 2.6.37.
I am trying to use a 3.18.
I started to add support for DT in this regulator, but I can't get a
booting kernel with it. I know it lacks regulator init in the parse_dt
function, but I don't really know what is the best way to do it. I
have used tps6507x as an example until know...
I don't know for instance if a tps_board is needed (it would contain
only a struct regulator_init_data * so probably not very useful) ?
Below is my current status (I also have created a tps65023.dtsi in
arch/arm/boot/dts which is only a copy of tps6507x.dtsi so didn't copy
it here).
diff --git a/drivers/regulator/tps65023-regulator.c
b/drivers/regulator/tps65023-regulator.c
index 7380af8..6e6fd78 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,60 @@ static struct regmap_config tps65023_regmap_config = {
.val_bits = 8,
};
+#if defined(CONFIG_OF)
+static const struct of_device_id tps65023_of_match[] = {
+ { .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 *pdata;
+ struct device_node *np = dev->of_node;
+ struct device_node *regulators;
+ struct of_regulator_match *matches;
+ int i, count, ret;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return NULL;
+
+ 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;
+ }
+
+ return pdata;
+}
+#else
+static struct regulator_init_data*
+ of_get_tps65023_platform_data(struct device *dev)
+{
+ return NULL;
+}
+#endif
+
static int tps_65023_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -211,13 +268,27 @@ 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, "Error: 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 (!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)
@@ -411,6 +482,7 @@ static struct i2c_driver tps_65023_i2c_driver = {
.driver = {
.name = "tps65023",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(tps65023_of_match),
},
.probe = tps_65023_probe,
.id_table = tps_65023_id,
Thanks,
JM
More information about the linux-arm-kernel
mailing list