]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/regulator/as3722-regulator.c
drm/udl: Store active framebuffer in device structure
[linux.git] / drivers / regulator / as3722-regulator.c
index e5fed289b52d3a39693ae6fa1ec19cbc06e2491e..bd5d0bacb08dbf252952d969de826f80d63a24ee 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Voltage regulator support for AMS AS3722 PMIC
  *
@@ -5,21 +6,6 @@
  *
  * Author: Florian Lobmaier <florian.lobmaier@ams.com>
  * Author: Laxman Dewangan <ldewangan@nvidia.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
  */
 
 #include <linux/err.h>
@@ -81,7 +67,6 @@ struct as3722_regulator_config_data {
 struct as3722_regulators {
        struct device *dev;
        struct as3722 *as3722;
-       struct regulator_dev *rdevs[AS3722_REGULATOR_ID_MAX];
        struct regulator_desc desc[AS3722_REGULATOR_ID_MAX];
        struct as3722_regulator_config_data
                        reg_config_data[AS3722_REGULATOR_ID_MAX];
@@ -314,63 +299,10 @@ static const struct as3722_register_mapping as3722_reg_lookup[] = {
        },
 };
 
-
-static const int as3722_ldo_current[] = { 150000, 300000 };
-static const int as3722_sd016_current[] = { 2500000, 3000000, 3500000 };
-
-static int as3722_current_to_index(int min_uA, int max_uA,
-               const int *curr_table, int n_currents)
-{
-       int i;
-
-       for (i = n_currents - 1; i >= 0; i--) {
-               if ((min_uA <= curr_table[i]) && (curr_table[i] <= max_uA))
-                       return i;
-       }
-       return -EINVAL;
-}
-
-static int as3722_ldo_get_current_limit(struct regulator_dev *rdev)
-{
-       struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
-       struct as3722 *as3722 = as3722_regs->as3722;
-       int id = rdev_get_id(rdev);
-       u32 val;
-       int ret;
-
-       ret = as3722_read(as3722, as3722_reg_lookup[id].vsel_reg, &val);
-       if (ret < 0) {
-               dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
-                       as3722_reg_lookup[id].vsel_reg, ret);
-               return ret;
-       }
-       if (val & AS3722_LDO_ILIMIT_MASK)
-               return 300000;
-       return 150000;
-}
-
-static int as3722_ldo_set_current_limit(struct regulator_dev *rdev,
-               int min_uA, int max_uA)
-{
-       struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
-       struct as3722 *as3722 = as3722_regs->as3722;
-       int id = rdev_get_id(rdev);
-       int ret;
-       u32 reg = 0;
-
-       ret = as3722_current_to_index(min_uA, max_uA, as3722_ldo_current,
-                               ARRAY_SIZE(as3722_ldo_current));
-       if (ret < 0) {
-               dev_err(as3722_regs->dev,
-                       "Current range min:max = %d:%d does not support\n",
-                       min_uA, max_uA);
-               return ret;
-       }
-       if (ret)
-               reg = AS3722_LDO_ILIMIT_BIT;
-       return as3722_update_bits(as3722, as3722_reg_lookup[id].vsel_reg,
-                       AS3722_LDO_ILIMIT_MASK, reg);
-}
+static const unsigned int as3722_ldo_current[] = { 150000, 300000 };
+static const unsigned int as3722_sd016_current[] = {
+       2500000, 3000000, 3500000
+};
 
 static const struct regulator_ops as3722_ldo0_ops = {
        .is_enabled = regulator_is_enabled_regmap,
@@ -379,16 +311,16 @@ static const struct regulator_ops as3722_ldo0_ops = {
        .list_voltage = regulator_list_voltage_linear,
        .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
-       .get_current_limit = as3722_ldo_get_current_limit,
-       .set_current_limit = as3722_ldo_set_current_limit,
+       .get_current_limit = regulator_get_current_limit_regmap,
+       .set_current_limit = regulator_set_current_limit_regmap,
 };
 
 static const struct regulator_ops as3722_ldo0_extcntrl_ops = {
        .list_voltage = regulator_list_voltage_linear,
        .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
-       .get_current_limit = as3722_ldo_get_current_limit,
-       .set_current_limit = as3722_ldo_set_current_limit,
+       .get_current_limit = regulator_get_current_limit_regmap,
+       .set_current_limit = regulator_set_current_limit_regmap,
 };
 
 static int as3722_ldo3_set_tracking_mode(struct as3722_regulators *as3722_reg,
@@ -440,8 +372,8 @@ static const struct regulator_ops as3722_ldo6_ops = {
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
        .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .list_voltage = regulator_list_voltage_linear_range,
-       .get_current_limit = as3722_ldo_get_current_limit,
-       .set_current_limit = as3722_ldo_set_current_limit,
+       .get_current_limit = regulator_get_current_limit_regmap,
+       .set_current_limit = regulator_set_current_limit_regmap,
        .get_bypass = regulator_get_bypass_regmap,
        .set_bypass = regulator_set_bypass_regmap,
 };
@@ -451,8 +383,8 @@ static const struct regulator_ops as3722_ldo6_extcntrl_ops = {
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
        .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .list_voltage = regulator_list_voltage_linear_range,
-       .get_current_limit = as3722_ldo_get_current_limit,
-       .set_current_limit = as3722_ldo_set_current_limit,
+       .get_current_limit = regulator_get_current_limit_regmap,
+       .set_current_limit = regulator_set_current_limit_regmap,
        .get_bypass = regulator_get_bypass_regmap,
        .set_bypass = regulator_set_bypass_regmap,
 };
@@ -471,8 +403,8 @@ static const struct regulator_ops as3722_ldo_ops = {
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
        .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .list_voltage = regulator_list_voltage_linear_range,
-       .get_current_limit = as3722_ldo_get_current_limit,
-       .set_current_limit = as3722_ldo_set_current_limit,
+       .get_current_limit = regulator_get_current_limit_regmap,
+       .set_current_limit = regulator_set_current_limit_regmap,
 };
 
 static const struct regulator_ops as3722_ldo_extcntrl_ops = {
@@ -480,8 +412,8 @@ static const struct regulator_ops as3722_ldo_extcntrl_ops = {
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
        .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .list_voltage = regulator_list_voltage_linear_range,
-       .get_current_limit = as3722_ldo_get_current_limit,
-       .set_current_limit = as3722_ldo_set_current_limit,
+       .get_current_limit = regulator_get_current_limit_regmap,
+       .set_current_limit = regulator_set_current_limit_regmap,
 };
 
 static unsigned int as3722_sd_get_mode(struct regulator_dev *rdev)
@@ -539,85 +471,6 @@ static int as3722_sd_set_mode(struct regulator_dev *rdev,
        return ret;
 }
 
-static int as3722_sd016_get_current_limit(struct regulator_dev *rdev)
-{
-       struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
-       struct as3722 *as3722 = as3722_regs->as3722;
-       int id = rdev_get_id(rdev);
-       u32 val, reg;
-       int mask;
-       int ret;
-
-       switch (id) {
-       case AS3722_REGULATOR_ID_SD0:
-               reg = AS3722_OVCURRENT_REG;
-               mask = AS3722_OVCURRENT_SD0_TRIP_MASK;
-               break;
-       case AS3722_REGULATOR_ID_SD1:
-               reg = AS3722_OVCURRENT_REG;
-               mask = AS3722_OVCURRENT_SD1_TRIP_MASK;
-               break;
-       case AS3722_REGULATOR_ID_SD6:
-               reg = AS3722_OVCURRENT_DEB_REG;
-               mask = AS3722_OVCURRENT_SD6_TRIP_MASK;
-               break;
-       default:
-               return -EINVAL;
-       }
-       ret = as3722_read(as3722, reg, &val);
-       if (ret < 0) {
-               dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
-                       reg, ret);
-               return ret;
-       }
-       val &= mask;
-       val >>= ffs(mask) - 1;
-       if (val == 3)
-               return -EINVAL;
-       return as3722_sd016_current[val];
-}
-
-static int as3722_sd016_set_current_limit(struct regulator_dev *rdev,
-               int min_uA, int max_uA)
-{
-       struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
-       struct as3722 *as3722 = as3722_regs->as3722;
-       int id = rdev_get_id(rdev);
-       int ret;
-       int val;
-       int mask;
-       u32 reg;
-
-       ret = as3722_current_to_index(min_uA, max_uA, as3722_sd016_current,
-                               ARRAY_SIZE(as3722_sd016_current));
-       if (ret < 0) {
-               dev_err(as3722_regs->dev,
-                       "Current range min:max = %d:%d does not support\n",
-                       min_uA, max_uA);
-               return ret;
-       }
-
-       switch (id) {
-       case AS3722_REGULATOR_ID_SD0:
-               reg = AS3722_OVCURRENT_REG;
-               mask = AS3722_OVCURRENT_SD0_TRIP_MASK;
-               break;
-       case AS3722_REGULATOR_ID_SD1:
-               reg = AS3722_OVCURRENT_REG;
-               mask = AS3722_OVCURRENT_SD1_TRIP_MASK;
-               break;
-       case AS3722_REGULATOR_ID_SD6:
-               reg = AS3722_OVCURRENT_DEB_REG;
-               mask = AS3722_OVCURRENT_SD6_TRIP_MASK;
-               break;
-       default:
-               return -EINVAL;
-       }
-       ret <<= ffs(mask) - 1;
-       val = ret & mask;
-       return as3722_update_bits(as3722, reg, mask, val);
-}
-
 static bool as3722_sd0_is_low_voltage(struct as3722_regulators *as3722_regs)
 {
        int err;
@@ -649,8 +502,8 @@ static const struct regulator_ops as3722_sd016_ops = {
        .map_voltage = regulator_map_voltage_linear,
        .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
-       .get_current_limit = as3722_sd016_get_current_limit,
-       .set_current_limit = as3722_sd016_set_current_limit,
+       .get_current_limit = regulator_get_current_limit_regmap,
+       .set_current_limit = regulator_set_current_limit_regmap,
        .get_mode = as3722_sd_get_mode,
        .set_mode = as3722_sd_set_mode,
 };
@@ -660,8 +513,8 @@ static const struct regulator_ops as3722_sd016_extcntrl_ops = {
        .map_voltage = regulator_map_voltage_linear,
        .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
-       .get_current_limit = as3722_sd016_get_current_limit,
-       .set_current_limit = as3722_sd016_set_current_limit,
+       .get_current_limit = regulator_get_current_limit_regmap,
+       .set_current_limit = regulator_set_current_limit_regmap,
        .get_mode = as3722_sd_get_mode,
        .set_mode = as3722_sd_set_mode,
 };
@@ -807,42 +660,45 @@ static int as3722_regulator_probe(struct platform_device *pdev)
        config.regmap = as3722->regmap;
 
        for (id = 0; id < AS3722_REGULATOR_ID_MAX; id++) {
+               struct regulator_desc *desc;
+
+               desc = &as3722_regs->desc[id];
                reg_config = &as3722_regs->reg_config_data[id];
 
-               as3722_regs->desc[id].name = as3722_reg_lookup[id].name;
-               as3722_regs->desc[id].supply_name = as3722_reg_lookup[id].sname;
-               as3722_regs->desc[id].id = as3722_reg_lookup[id].regulator_id;
-               as3722_regs->desc[id].n_voltages =
-                                       as3722_reg_lookup[id].n_voltages;
-               as3722_regs->desc[id].type = REGULATOR_VOLTAGE;
-               as3722_regs->desc[id].owner = THIS_MODULE;
-               as3722_regs->desc[id].enable_reg =
-                                       as3722_reg_lookup[id].enable_reg;
-               as3722_regs->desc[id].enable_mask =
-                                       as3722_reg_lookup[id].enable_mask;
-               as3722_regs->desc[id].vsel_reg = as3722_reg_lookup[id].vsel_reg;
-               as3722_regs->desc[id].vsel_mask =
-                                       as3722_reg_lookup[id].vsel_mask;
+               desc->name = as3722_reg_lookup[id].name;
+               desc->supply_name = as3722_reg_lookup[id].sname;
+               desc->id = as3722_reg_lookup[id].regulator_id;
+               desc->n_voltages = as3722_reg_lookup[id].n_voltages;
+               desc->type = REGULATOR_VOLTAGE;
+               desc->owner = THIS_MODULE;
+               desc->enable_reg = as3722_reg_lookup[id].enable_reg;
+               desc->enable_mask = as3722_reg_lookup[id].enable_mask;
+               desc->vsel_reg = as3722_reg_lookup[id].vsel_reg;
+               desc->vsel_mask = as3722_reg_lookup[id].vsel_mask;
                switch (id) {
                case AS3722_REGULATOR_ID_LDO0:
                        if (reg_config->ext_control)
                                ops = &as3722_ldo0_extcntrl_ops;
                        else
                                ops = &as3722_ldo0_ops;
-                       as3722_regs->desc[id].min_uV = 825000;
-                       as3722_regs->desc[id].uV_step = 25000;
-                       as3722_regs->desc[id].linear_min_sel = 1;
-                       as3722_regs->desc[id].enable_time = 500;
+                       desc->min_uV = 825000;
+                       desc->uV_step = 25000;
+                       desc->linear_min_sel = 1;
+                       desc->enable_time = 500;
+                       desc->curr_table = as3722_ldo_current;
+                       desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current);
+                       desc->csel_reg = as3722_reg_lookup[id].vsel_reg;
+                       desc->csel_mask = AS3722_LDO_ILIMIT_MASK;
                        break;
                case AS3722_REGULATOR_ID_LDO3:
                        if (reg_config->ext_control)
                                ops = &as3722_ldo3_extcntrl_ops;
                        else
                                ops = &as3722_ldo3_ops;
-                       as3722_regs->desc[id].min_uV = 620000;
-                       as3722_regs->desc[id].uV_step = 20000;
-                       as3722_regs->desc[id].linear_min_sel = 1;
-                       as3722_regs->desc[id].enable_time = 500;
+                       desc->min_uV = 620000;
+                       desc->uV_step = 20000;
+                       desc->linear_min_sel = 1;
+                       desc->enable_time = 500;
                        if (reg_config->enable_tracking) {
                                ret = as3722_ldo3_set_tracking_mode(as3722_regs,
                                        id, AS3722_LDO3_MODE_PMOS_TRACKING);
@@ -859,18 +715,17 @@ static int as3722_regulator_probe(struct platform_device *pdev)
                                ops = &as3722_ldo6_extcntrl_ops;
                        else
                                ops = &as3722_ldo6_ops;
-                       as3722_regs->desc[id].enable_time = 500;
-                       as3722_regs->desc[id].bypass_reg =
-                                               AS3722_LDO6_VOLTAGE_REG;
-                       as3722_regs->desc[id].bypass_mask =
-                                               AS3722_LDO_VSEL_MASK;
-                       as3722_regs->desc[id].bypass_val_on =
-                                               AS3722_LDO6_VSEL_BYPASS;
-                       as3722_regs->desc[id].bypass_val_off =
-                                               AS3722_LDO6_VSEL_BYPASS;
-                       as3722_regs->desc[id].linear_ranges = as3722_ldo_ranges;
-                       as3722_regs->desc[id].n_linear_ranges =
-                                               ARRAY_SIZE(as3722_ldo_ranges);
+                       desc->enable_time = 500;
+                       desc->bypass_reg = AS3722_LDO6_VOLTAGE_REG;
+                       desc->bypass_mask = AS3722_LDO_VSEL_MASK;
+                       desc->bypass_val_on = AS3722_LDO6_VSEL_BYPASS;
+                       desc->bypass_val_off = AS3722_LDO6_VSEL_BYPASS;
+                       desc->linear_ranges = as3722_ldo_ranges;
+                       desc->n_linear_ranges = ARRAY_SIZE(as3722_ldo_ranges);
+                       desc->curr_table = as3722_ldo_current;
+                       desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current);
+                       desc->csel_reg = as3722_reg_lookup[id].vsel_reg;
+                       desc->csel_mask = AS3722_LDO_ILIMIT_MASK;
                        break;
                case AS3722_REGULATOR_ID_SD0:
                case AS3722_REGULATOR_ID_SD1:
@@ -889,9 +744,25 @@ static int as3722_regulator_probe(struct platform_device *pdev)
                                        AS3722_SD0_VSEL_MAX + 1;
                                as3722_regs->desc[id].min_uV = 610000;
                        }
-                       as3722_regs->desc[id].uV_step = 10000;
-                       as3722_regs->desc[id].linear_min_sel = 1;
-                       as3722_regs->desc[id].enable_time = 600;
+                       desc->uV_step = 10000;
+                       desc->linear_min_sel = 1;
+                       desc->enable_time = 600;
+                       desc->curr_table = as3722_sd016_current;
+                       desc->n_current_limits =
+                               ARRAY_SIZE(as3722_sd016_current);
+                       if (id == AS3722_REGULATOR_ID_SD0) {
+                               desc->csel_reg = AS3722_OVCURRENT_REG;
+                               desc->csel_mask =
+                                       AS3722_OVCURRENT_SD0_TRIP_MASK;
+                       } else if (id == AS3722_REGULATOR_ID_SD1) {
+                               desc->csel_reg = AS3722_OVCURRENT_REG;
+                               desc->csel_mask =
+                                       AS3722_OVCURRENT_SD1_TRIP_MASK;
+                       } else if (id == AS3722_REGULATOR_ID_SD6) {
+                               desc->csel_reg = AS3722_OVCURRENT_DEB_REG;
+                               desc->csel_mask =
+                                       AS3722_OVCURRENT_SD6_TRIP_MASK;
+                       }
                        break;
                case AS3722_REGULATOR_ID_SD2:
                case AS3722_REGULATOR_ID_SD3:
@@ -901,9 +772,8 @@ static int as3722_regulator_probe(struct platform_device *pdev)
                                ops = &as3722_sd2345_extcntrl_ops;
                        else
                                ops = &as3722_sd2345_ops;
-                       as3722_regs->desc[id].linear_ranges =
-                                               as3722_sd2345_ranges;
-                       as3722_regs->desc[id].n_linear_ranges =
+                       desc->linear_ranges = as3722_sd2345_ranges;
+                       desc->n_linear_ranges =
                                        ARRAY_SIZE(as3722_sd2345_ranges);
                        break;
                default:
@@ -911,17 +781,19 @@ static int as3722_regulator_probe(struct platform_device *pdev)
                                ops = &as3722_ldo_extcntrl_ops;
                        else
                                ops = &as3722_ldo_ops;
-                       as3722_regs->desc[id].enable_time = 500;
-                       as3722_regs->desc[id].linear_ranges = as3722_ldo_ranges;
-                       as3722_regs->desc[id].n_linear_ranges =
-                                               ARRAY_SIZE(as3722_ldo_ranges);
+                       desc->enable_time = 500;
+                       desc->linear_ranges = as3722_ldo_ranges;
+                       desc->n_linear_ranges = ARRAY_SIZE(as3722_ldo_ranges);
+                       desc->curr_table = as3722_ldo_current;
+                       desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current);
+                       desc->csel_reg = as3722_reg_lookup[id].vsel_reg;
+                       desc->csel_mask = AS3722_LDO_ILIMIT_MASK;
                        break;
                }
-               as3722_regs->desc[id].ops = ops;
+               desc->ops = ops;
                config.init_data = reg_config->reg_init;
                config.of_node = as3722_regulator_matches[id].of_node;
-               rdev = devm_regulator_register(&pdev->dev,
-                                       &as3722_regs->desc[id], &config);
+               rdev = devm_regulator_register(&pdev->dev, desc, &config);
                if (IS_ERR(rdev)) {
                        ret = PTR_ERR(rdev);
                        dev_err(&pdev->dev, "regulator %d register failed %d\n",
@@ -929,7 +801,6 @@ static int as3722_regulator_probe(struct platform_device *pdev)
                        return ret;
                }
 
-               as3722_regs->rdevs[id] = rdev;
                if (reg_config->ext_control) {
                        ret = regulator_enable_regmap(rdev);
                        if (ret < 0) {