summaryrefslogtreecommitdiff
path: root/drivers/regulator/tps65086-regulator.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/tps65086-regulator.c')
-rw-r--r--drivers/regulator/tps65086-regulator.c188
1 files changed, 180 insertions, 8 deletions
diff --git a/drivers/regulator/tps65086-regulator.c b/drivers/regulator/tps65086-regulator.c
index 663789198ba5..2d284c64eeb7 100644
--- a/drivers/regulator/tps65086-regulator.c
+++ b/drivers/regulator/tps65086-regulator.c
@@ -15,7 +15,15 @@
#include <linux/mfd/tps65086.h>
enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1,
- LDOA2, LDOA3, SWA1, SWB1, SWB2, VTT };
+ LDOA2, LDOA3, VTT, SWA1, SWB1, SWB2 };
+
+/* Selector for regulator configuration regarding PMIC chip ID. */
+enum tps65086_ids {
+ TPS6508640 = 0,
+ TPS65086401,
+ TPS6508641,
+ TPS65086470,
+};
#define TPS65086_REGULATOR(_name, _of, _id, _nv, _vr, _vm, _er, _em, _lr, _dr, _dm) \
[_id] = { \
@@ -57,12 +65,24 @@ enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1,
}, \
}
+
+#define TPS65086_REGULATOR_CONFIG(_chip_id, _config) \
+ [_chip_id] = { \
+ .config = _config, \
+ .num_elems = ARRAY_SIZE(_config), \
+ }
+
struct tps65086_regulator {
struct regulator_desc desc;
unsigned int decay_reg;
unsigned int decay_mask;
};
+struct tps65086_regulator_config {
+ struct tps65086_regulator * const config;
+ const unsigned int num_elems;
+};
+
static const struct linear_range tps65086_10mv_ranges[] = {
REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
REGULATOR_LINEAR_RANGE(410000, 0x1, 0x7F, 10000),
@@ -114,7 +134,125 @@ static int tps65086_of_parse_cb(struct device_node *dev,
const struct regulator_desc *desc,
struct regulator_config *config);
-static struct tps65086_regulator regulators[] = {
+static struct tps65086_regulator tps6508640_regulator_config[] = {
+ TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
+ tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
+ tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
+ BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK4VID,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
+ BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
+ BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
+ VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
+ tps65086_ldoa1_ranges, 0, 0),
+ TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
+ VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
+ tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
+ VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
+ tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
+ TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
+ TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
+ TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_LDOA1CTRL, BIT(0)),
+};
+
+static struct tps65086_regulator tps65086401_regulator_config[] = {
+ TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
+ tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
+ tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
+ BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK4VID,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
+ BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
+ BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
+ VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
+ tps65086_ldoa1_ranges, 0, 0),
+ TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
+ VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
+ tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
+ VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
+ tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
+ TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
+ TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
+};
+
+static struct tps65086_regulator tps6508641_regulator_config[] = {
+ TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
+ tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
+ tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
+ BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK4VID,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
+ BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
+ BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
+ VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
+ tps65086_ldoa1_ranges, 0, 0),
+ TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
+ VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
+ tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
+ VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
+ tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
+ TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
+ TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
+};
+
+static struct tps65086_regulator tps65086470_regulator_config[] = {
TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
@@ -148,16 +286,25 @@ static struct tps65086_regulator regulators[] = {
TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_SWVTT_EN, BIT(7)),
- TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
+};
+
+static const struct tps65086_regulator_config regulator_configs[] = {
+ TPS65086_REGULATOR_CONFIG(TPS6508640, tps6508640_regulator_config),
+ TPS65086_REGULATOR_CONFIG(TPS65086401, tps65086401_regulator_config),
+ TPS65086_REGULATOR_CONFIG(TPS6508641, tps6508641_regulator_config),
+ TPS65086_REGULATOR_CONFIG(TPS65086470, tps65086470_regulator_config)
};
static int tps65086_of_parse_cb(struct device_node *node,
const struct regulator_desc *desc,
struct regulator_config *config)
{
+ struct tps65086 * const tps = dev_get_drvdata(config->dev);
+ struct tps65086_regulator *regulators = tps->reg_config->config;
int ret;
/* Check for 25mV step mode */
@@ -203,9 +350,30 @@ static int tps65086_regulator_probe(struct platform_device *pdev)
{
struct tps65086 *tps = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { };
+ unsigned int selector_reg_config;
struct regulator_dev *rdev;
int i;
+ /* Select regulator configuration for used PMIC device */
+ switch (tps->chip_id) {
+ case TPS6508640_ID:
+ selector_reg_config = TPS6508640;
+ break;
+ case TPS65086401_ID:
+ selector_reg_config = TPS65086401;
+ break;
+ case TPS6508641_ID:
+ selector_reg_config = TPS6508641;
+ break;
+ case TPS65086470_ID:
+ selector_reg_config = TPS65086470;
+ break;
+ default:
+ dev_err(tps->dev, "Unknown device ID. Cannot determine regulator config.\n");
+ return -ENODEV;
+ }
+ tps->reg_config = &regulator_configs[selector_reg_config];
+
platform_set_drvdata(pdev, tps);
config.dev = &pdev->dev;
@@ -213,12 +381,16 @@ static int tps65086_regulator_probe(struct platform_device *pdev)
config.driver_data = tps;
config.regmap = tps->regmap;
- for (i = 0; i < ARRAY_SIZE(regulators); i++) {
- rdev = devm_regulator_register(&pdev->dev, &regulators[i].desc,
- &config);
+ for (i = 0; i < tps->reg_config->num_elems; ++i) {
+ struct regulator_desc * const desc_ptr = &tps->reg_config->config[i].desc;
+
+ dev_dbg(tps->dev, "Index: %u; Regulator name: \"%s\"; Regulator ID: %d\n",
+ i, desc_ptr->name, desc_ptr->id);
+
+ rdev = devm_regulator_register(&pdev->dev, desc_ptr, &config);
if (IS_ERR(rdev)) {
- dev_err(tps->dev, "failed to register %s regulator\n",
- pdev->name);
+ dev_err(tps->dev, "failed to register %d \"%s\" regulator\n",
+ i, desc_ptr->name);
return PTR_ERR(rdev);
}
}