regulator: tps6507x: Use regulator_map_voltage_ascend
[firefly-linux-kernel-4.4.55.git] / drivers / regulator / tps6507x-regulator.c
index 0233cfb5656058a57ccd0dce40591701c16ce8b6..4117ff52dba185909cc3db4e3df9329d4ecadaa8 100644 (file)
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/tps6507x.h>
+#include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/mfd/tps6507x.h>
+#include <linux/regulator/of_regulator.h>
 
 /* DCDC's */
 #define TPS6507X_DCDC_1                                0
@@ -354,8 +356,83 @@ static struct regulator_ops tps6507x_pmic_ops = {
        .get_voltage_sel = tps6507x_pmic_get_voltage_sel,
        .set_voltage_sel = tps6507x_pmic_set_voltage_sel,
        .list_voltage = regulator_list_voltage_table,
+       .map_voltage = regulator_map_voltage_ascend,
 };
 
+#ifdef CONFIG_OF
+static struct of_regulator_match tps6507x_matches[] = {
+       { .name = "VDCDC1"},
+       { .name = "VDCDC2"},
+       { .name = "VDCDC3"},
+       { .name = "LDO1"},
+       { .name = "LDO2"},
+};
+
+static struct tps6507x_board *tps6507x_parse_dt_reg_data(
+               struct platform_device *pdev,
+               struct of_regulator_match **tps6507x_reg_matches)
+{
+       struct tps6507x_board *tps_board;
+       struct device_node *np = pdev->dev.parent->of_node;
+       struct device_node *regulators;
+       struct of_regulator_match *matches;
+       static struct regulator_init_data *reg_data;
+       int idx = 0, count, ret;
+
+       tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board),
+                                       GFP_KERNEL);
+       if (!tps_board) {
+               dev_err(&pdev->dev, "Failure to alloc pdata for regulators.\n");
+               return NULL;
+       }
+
+       regulators = of_find_node_by_name(np, "regulators");
+       if (!regulators) {
+               dev_err(&pdev->dev, "regulator node not found\n");
+               return NULL;
+       }
+
+       count = ARRAY_SIZE(tps6507x_matches);
+       matches = tps6507x_matches;
+
+       ret = of_regulator_match(&pdev->dev, regulators, matches, count);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",
+                       ret);
+               return NULL;
+       }
+
+       *tps6507x_reg_matches = matches;
+
+       reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data)
+                                       * TPS6507X_NUM_REGULATOR), GFP_KERNEL);
+       if (!reg_data) {
+               dev_err(&pdev->dev, "Failure to alloc init data for regulators.\n");
+               return NULL;
+       }
+
+       tps_board->tps6507x_pmic_init_data = reg_data;
+
+       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 tps_board;
+}
+#else
+static inline struct tps6507x_board *tps6507x_parse_dt_reg_data(
+                       struct platform_device *pdev,
+                       struct of_regulator_match **tps6507x_reg_matches)
+{
+       *tps6507x_reg_matches = NULL;
+       return NULL;
+}
+#endif
 static int tps6507x_pmic_probe(struct platform_device *pdev)
 {
        struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
@@ -365,8 +442,10 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
        struct regulator_dev *rdev;
        struct tps6507x_pmic *tps;
        struct tps6507x_board *tps_board;
+       struct of_regulator_match *tps6507x_reg_matches = NULL;
        int i;
        int error;
+       unsigned int prop;
 
        /**
         * tps_board points to pmic related constants
@@ -374,6 +453,9 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
         */
 
        tps_board = dev_get_platdata(tps6507x_dev->dev);
+       if (!tps_board && tps6507x_dev->dev->of_node)
+               tps_board = tps6507x_parse_dt_reg_data(pdev,
+                                               &tps6507x_reg_matches);
        if (!tps_board)
                return -EINVAL;
 
@@ -415,6 +497,17 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
                config.init_data = init_data;
                config.driver_data = tps;
 
+               if (tps6507x_reg_matches) {
+                       error = of_property_read_u32(
+                               tps6507x_reg_matches[i].of_node,
+                                       "ti,defdcdc_default", &prop);
+
+                       if (!error)
+                               tps->info[i]->defdcdc_default = prop;
+
+                       config.of_node = tps6507x_reg_matches[i].of_node;
+               }
+
                rdev = regulator_register(&tps->desc[i], &config);
                if (IS_ERR(rdev)) {
                        dev_err(tps6507x_dev->dev,