
This is not a proper WD driver because it's not planned to support WD driver for PMIC in u-boot at any time. The purpose is just WD disable.
Signed-off-by: Jerome Neanne jneanne@baylibre.com --- drivers/power/pmic/tps65941.c | 36 +++++++++++++++++++++++++++++++++++ include/power/tps65941.h | 25 ++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/drivers/power/pmic/tps65941.c b/drivers/power/pmic/tps65941.c index 83d0f83c64..643ea6179c 100644 --- a/drivers/power/pmic/tps65941.c +++ b/drivers/power/pmic/tps65941.c @@ -47,6 +47,9 @@ static int tps65941_bind(struct udevice *dev) ofnode regulators_node; int children;
+ if (dev->driver_data == TPS65941_WD) + return 0; + regulators_node = dev_read_subnode(dev, "regulators"); if (!ofnode_valid(regulators_node)) { debug("%s: %s regulators subnode not found!\n", __func__, @@ -64,6 +67,36 @@ static int tps65941_bind(struct udevice *dev) return dm_scan_fdt_dev(dev); }
+static int stop_watchdog(struct udevice *wd_i2c_dev) +{ + int ret; + + ret = dm_i2c_reg_read(wd_i2c_dev, TPS65941_WD_MODE_REG); + if (ret < 0) { + debug("failed to write i2c reg (%d)\n", ret); + return 0; + } + + ret &= ~TPS65941_WD_PWRHOLD_MASK; + ret |= TPS65941_WD_PWRHOLD_MASK; + ret = dm_i2c_reg_write(wd_i2c_dev, TPS65941_WD_MODE_REG, ret); + if (ret) + debug("%s: %s write WD disable fail!\n", __func__, wd_i2c_dev->name); + ret = dm_i2c_reg_read(wd_i2c_dev, TPS65941_WD_MODE_REG); + if (ret < 0) { + debug("failed to read back i2c reg (%d)\n", ret); + return 0; + } + return 0; +} + +static int tps65941_probe(struct udevice *dev) +{ + if (dev->driver_data == TPS65941_WD) + return stop_watchdog(dev); + return 0; +} + static struct dm_pmic_ops tps65941_ops = { .read = tps65941_read, .write = tps65941_write, @@ -73,7 +106,9 @@ static const struct udevice_id tps65941_ids[] = { { .compatible = "ti,tps659411", .data = TPS659411 }, { .compatible = "ti,tps659412", .data = TPS659411 }, { .compatible = "ti,tps659413", .data = TPS659413 }, + { .compatible = "ti,tps659312", .data = TPS659312 }, { .compatible = "ti,lp876441", .data = LP876441 }, + { .compatible = "ti,tps65941_watchdog", .data = TPS65941_WD }, { } };
@@ -82,5 +117,6 @@ U_BOOT_DRIVER(pmic_tps65941) = { .id = UCLASS_PMIC, .of_match = tps65941_ids, .bind = tps65941_bind, + .probe = tps65941_probe, .ops = &tps65941_ops, }; diff --git a/include/power/tps65941.h b/include/power/tps65941.h index a2bc6814ba..70c7274355 100644 --- a/include/power/tps65941.h +++ b/include/power/tps65941.h @@ -2,7 +2,9 @@ #define TPS659412 0x1 #define TPS659413 0x2 #define TPS659414 0x3 -#define LP876441 0x4 +#define TPS659312 0x4 +#define LP876441 0x5 +#define TPS65941_WD 0x20
/* I2C device address for pmic tps65941 */ #define TPS65941_I2C_ADDR (0x12 >> 1) @@ -18,10 +20,29 @@ #define TPS65941_BUCK_VOLT_MAX 3340000 #define TPS65941_BUCK_MODE_MASK 0x1
-#define TPS65941_LDO_VOLT_MASK 0x3E +#define TPS65941_LDO_VOLT_MASK 0x7F #define TPS65941_LDO_VOLT_MAX_HEX 0x3A #define TPS65941_LDO_VOLT_MIN_HEX 0x4 #define TPS65941_LDO_VOLT_MAX 3300000 #define TPS65941_LDO_MODE_MASK 0x1 #define TPS65941_LDO_BYPASS_EN 0x80 #define TP65941_BUCK_CONF_SLEW_MASK 0x7 + +/* BYPASS is bit7 of VOUT TPS65941_LDO_BYP_MASK */ +#define TPS65941_LDO123_BYP_CONFIG 7 + +#define TPS65941_LDO123_VOLT_BYP_MIN 1700000 +#define TPS65941_LDO123_VOLT_BYP_MAX 3600000 +#define TPS65941_LDO123_VOLT_MIN 600000 +#define TPS65941_LDO4_VOLT_MIN 1200000 +#define TPS65941_LDO4_VOLT_MIN 1200000 +#define TPS65941_LDO123_VSET_MIN 0x04 +#define TPS65941_LDO4_VSET_MIN 0x20 +#define TPS65941_LDO123_VSET_MAX 0x3A +#define TPS65941_LDO4_VSET_MAX 0x74 +#define TPS65941_LDO123_STEP 50000 +#define TPS65941_LDO4_STEP 25000 + +#define TPS65941_WD_MODE_REG 0x406 +#define TPS65941_WD_PWRHOLD_MASK BIT(2) +