summaryrefslogtreecommitdiff
path: root/drivers/regulator/pca9450-regulator.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/pca9450-regulator.c')
-rw-r--r--drivers/regulator/pca9450-regulator.c141
1 files changed, 137 insertions, 4 deletions
diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
index 14d19a6d6655..feadb21a8f30 100644
--- a/drivers/regulator/pca9450-regulator.c
+++ b/drivers/regulator/pca9450-regulator.c
@@ -17,12 +17,18 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/pca9450.h>
+#include <dt-bindings/regulator/nxp,pca9450-regulator.h>
+
+static unsigned int pca9450_buck_get_mode(struct regulator_dev *rdev);
+static int pca9450_buck_set_mode(struct regulator_dev *rdev, unsigned int mode);
struct pc9450_dvs_config {
unsigned int run_reg; /* dvs0 */
unsigned int run_mask;
unsigned int standby_reg; /* dvs1 */
unsigned int standby_mask;
+ unsigned int mode_reg; /* ctrl */
+ unsigned int mode_mask;
};
struct pca9450_regulator_desc {
@@ -80,6 +86,8 @@ static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
+ .set_mode = pca9450_buck_set_mode,
+ .get_mode = pca9450_buck_get_mode,
};
static const struct regulator_ops pca9450_buck_regulator_ops = {
@@ -90,6 +98,8 @@ static const struct regulator_ops pca9450_buck_regulator_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .set_mode = pca9450_buck_set_mode,
+ .get_mode = pca9450_buck_get_mode,
};
static const struct regulator_ops pca9450_ldo_regulator_ops = {
@@ -285,7 +295,64 @@ static int pca9450_set_dvs_levels(struct device_node *np,
return ret;
}
-static const struct pca9450_regulator_desc pca9450a_regulators[] = {
+static inline unsigned int pca9450_map_mode(unsigned int mode)
+{
+ switch (mode) {
+ case PCA9450_BUCK_MODE_AUTO:
+ return REGULATOR_MODE_NORMAL;
+ case PCA9450_BUCK_MODE_FORCE_PWM:
+ return REGULATOR_MODE_FAST;
+ default:
+ return REGULATOR_MODE_INVALID;
+ }
+}
+
+static int pca9450_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+ struct pca9450_regulator_desc *desc = container_of(rdev->desc,
+ struct pca9450_regulator_desc, desc);
+ const struct pc9450_dvs_config *dvs = &desc->dvs;
+ int val;
+
+ switch (mode) {
+ case REGULATOR_MODE_FAST:
+ val = dvs->mode_mask;
+ break;
+ case REGULATOR_MODE_NORMAL:
+ val = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ dev_dbg(&rdev->dev, "pca9450 buck set_mode %#x, %#x, %#x\n",
+ dvs->mode_reg, dvs->mode_mask, val);
+
+ return regmap_update_bits(rdev->regmap, dvs->mode_reg,
+ dvs->mode_mask, val);
+}
+
+static unsigned int pca9450_buck_get_mode(struct regulator_dev *rdev)
+{
+ struct pca9450_regulator_desc *desc = container_of(rdev->desc,
+ struct pca9450_regulator_desc, desc);
+ const struct pc9450_dvs_config *dvs = &desc->dvs;
+ int ret = 0, regval;
+
+ ret = regmap_read(rdev->regmap, dvs->mode_reg, &regval);
+ if (ret != 0) {
+ dev_err(&rdev->dev,
+ "Failed to get pca9450 buck mode: %d\n", ret);
+ return ret;
+ }
+
+ if ((regval & dvs->mode_mask) == dvs->mode_mask)
+ return REGULATOR_MODE_FAST;
+
+ return REGULATOR_MODE_NORMAL;
+}
+
+static struct pca9450_regulator_desc pca9450a_regulators[] = {
{
.desc = {
.name = "buck1",
@@ -308,12 +375,15 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
.enable_val = BUCK_ENMODE_ONREQ,
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
+ .of_map_mode = pca9450_map_mode,
},
.dvs = {
.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
.run_mask = BUCK1OUT_DVS0_MASK,
.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
.standby_mask = BUCK1OUT_DVS1_MASK,
+ .mode_reg = PCA9450_REG_BUCK1CTRL,
+ .mode_mask = BUCK1_FPWM,
},
},
{
@@ -338,12 +408,15 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
+ .of_map_mode = pca9450_map_mode,
},
.dvs = {
.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
.run_mask = BUCK2OUT_DVS0_MASK,
.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
.standby_mask = BUCK2OUT_DVS1_MASK,
+ .mode_reg = PCA9450_REG_BUCK2CTRL,
+ .mode_mask = BUCK2_FPWM,
},
},
{
@@ -368,12 +441,15 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
+ .of_map_mode = pca9450_map_mode,
},
.dvs = {
.run_reg = PCA9450_REG_BUCK3OUT_DVS0,
.run_mask = BUCK3OUT_DVS0_MASK,
.standby_reg = PCA9450_REG_BUCK3OUT_DVS1,
.standby_mask = BUCK3OUT_DVS1_MASK,
+ .mode_reg = PCA9450_REG_BUCK3CTRL,
+ .mode_mask = BUCK3_FPWM,
},
},
{
@@ -393,6 +469,11 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
.enable_mask = BUCK4_ENMODE_MASK,
.enable_val = BUCK_ENMODE_ONREQ,
.owner = THIS_MODULE,
+ .of_map_mode = pca9450_map_mode,
+ },
+ .dvs = {
+ .mode_reg = PCA9450_REG_BUCK4CTRL,
+ .mode_mask = BUCK4_FPWM,
},
},
{
@@ -412,6 +493,11 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
.enable_mask = BUCK5_ENMODE_MASK,
.enable_val = BUCK_ENMODE_ONREQ,
.owner = THIS_MODULE,
+ .of_map_mode = pca9450_map_mode,
+ },
+ .dvs = {
+ .mode_reg = PCA9450_REG_BUCK5CTRL,
+ .mode_mask = BUCK5_FPWM,
},
},
{
@@ -431,6 +517,11 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
.enable_mask = BUCK6_ENMODE_MASK,
.enable_val = BUCK_ENMODE_ONREQ,
.owner = THIS_MODULE,
+ .of_map_mode = pca9450_map_mode,
+ },
+ .dvs = {
+ .mode_reg = PCA9450_REG_BUCK6CTRL,
+ .mode_mask = BUCK6_FPWM,
},
},
{
@@ -529,7 +620,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
* Buck3 removed on PCA9450B and connected with Buck1 internal for dual phase
* on PCA9450C as no Buck3.
*/
-static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
+static struct pca9450_regulator_desc pca9450bc_regulators[] = {
{
.desc = {
.name = "buck1",
@@ -552,12 +643,15 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
+ .of_map_mode = pca9450_map_mode,
},
.dvs = {
.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
.run_mask = BUCK1OUT_DVS0_MASK,
.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
.standby_mask = BUCK1OUT_DVS1_MASK,
+ .mode_reg = PCA9450_REG_BUCK1CTRL,
+ .mode_mask = BUCK1_FPWM,
},
},
{
@@ -582,12 +676,15 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
+ .of_map_mode = pca9450_map_mode,
},
.dvs = {
.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
.run_mask = BUCK2OUT_DVS0_MASK,
.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
.standby_mask = BUCK2OUT_DVS1_MASK,
+ .mode_reg = PCA9450_REG_BUCK2CTRL,
+ .mode_mask = BUCK2_FPWM,
},
},
{
@@ -607,6 +704,11 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
.enable_mask = BUCK4_ENMODE_MASK,
.enable_val = BUCK_ENMODE_ONREQ,
.owner = THIS_MODULE,
+ .of_map_mode = pca9450_map_mode,
+ },
+ .dvs = {
+ .mode_reg = PCA9450_REG_BUCK4CTRL,
+ .mode_mask = BUCK4_FPWM,
},
},
{
@@ -626,6 +728,11 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
.enable_mask = BUCK5_ENMODE_MASK,
.enable_val = BUCK_ENMODE_ONREQ,
.owner = THIS_MODULE,
+ .of_map_mode = pca9450_map_mode,
+ },
+ .dvs = {
+ .mode_reg = PCA9450_REG_BUCK5CTRL,
+ .mode_mask = BUCK5_FPWM,
},
},
{
@@ -645,6 +752,11 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
.enable_mask = BUCK6_ENMODE_MASK,
.enable_val = BUCK_ENMODE_ONREQ,
.owner = THIS_MODULE,
+ .of_map_mode = pca9450_map_mode,
+ },
+ .dvs = {
+ .mode_reg = PCA9450_REG_BUCK6CTRL,
+ .mode_mask = BUCK6_FPWM,
},
},
{
@@ -739,7 +851,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
},
};
-static const struct pca9450_regulator_desc pca9451a_regulators[] = {
+static struct pca9450_regulator_desc pca9451a_regulators[] = {
{
.desc = {
.name = "buck1",
@@ -761,12 +873,15 @@ static const struct pca9450_regulator_desc pca9451a_regulators[] = {
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
+ .of_map_mode = pca9450_map_mode,
},
.dvs = {
.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
.run_mask = BUCK1OUT_DVS0_MASK,
.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
.standby_mask = BUCK1OUT_DVS1_MASK,
+ .mode_reg = PCA9450_REG_BUCK1CTRL,
+ .mode_mask = BUCK1_FPWM,
},
},
{
@@ -790,12 +905,15 @@ static const struct pca9450_regulator_desc pca9451a_regulators[] = {
.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
.owner = THIS_MODULE,
.of_parse_cb = pca9450_set_dvs_levels,
+ .of_map_mode = pca9450_map_mode,
},
.dvs = {
.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
.run_mask = BUCK2OUT_DVS0_MASK,
.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
.standby_mask = BUCK2OUT_DVS1_MASK,
+ .mode_reg = PCA9450_REG_BUCK2CTRL,
+ .mode_mask = BUCK2_FPWM,
},
},
{
@@ -815,6 +933,11 @@ static const struct pca9450_regulator_desc pca9451a_regulators[] = {
.enable_mask = BUCK4_ENMODE_MASK,
.enable_val = BUCK_ENMODE_ONREQ,
.owner = THIS_MODULE,
+ .of_map_mode = pca9450_map_mode,
+ },
+ .dvs = {
+ .mode_reg = PCA9450_REG_BUCK4CTRL,
+ .mode_mask = BUCK4_FPWM,
},
},
{
@@ -834,6 +957,11 @@ static const struct pca9450_regulator_desc pca9451a_regulators[] = {
.enable_mask = BUCK5_ENMODE_MASK,
.enable_val = BUCK_ENMODE_ONREQ,
.owner = THIS_MODULE,
+ .of_map_mode = pca9450_map_mode,
+ },
+ .dvs = {
+ .mode_reg = PCA9450_REG_BUCK5CTRL,
+ .mode_mask = BUCK5_FPWM,
},
},
{
@@ -853,6 +981,11 @@ static const struct pca9450_regulator_desc pca9451a_regulators[] = {
.enable_mask = BUCK6_ENMODE_MASK,
.enable_val = BUCK_ENMODE_ONREQ,
.owner = THIS_MODULE,
+ .of_map_mode = pca9450_map_mode,
+ },
+ .dvs = {
+ .mode_reg = PCA9450_REG_BUCK6CTRL,
+ .mode_mask = BUCK6_FPWM,
},
},
{
@@ -990,7 +1123,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
{
enum pca9450_chip_type type = (unsigned int)(uintptr_t)
of_device_get_match_data(&i2c->dev);
- const struct pca9450_regulator_desc *regulator_desc;
+ const struct pca9450_regulator_desc *regulator_desc;
struct regulator_config config = { };
struct regulator_dev *ldo5;
struct pca9450 *pca9450;