
From: Jerome Neanne jneanne@baylibre.com
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 Signed-off-by: Apelete Seketeli aseketeli@baylibre.com --- drivers/power/pmic/tps65941.c | 61 +++++++++++++++++++++++++++++++++++ include/power/tps65941.h | 27 ++++++++++++++-- 2 files changed, 86 insertions(+), 2 deletions(-)
diff --git a/drivers/power/pmic/tps65941.c b/drivers/power/pmic/tps65941.c index 83d0f83c64..974c8c90dc 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,61 @@ static int tps65941_bind(struct udevice *dev) return dm_scan_fdt_dev(dev); }
+static int stop_watchdog(struct udevice *wd_i2c_dev) +{ + int ret; + + /* Maintain WD long window */ + ret = dm_i2c_reg_read(wd_i2c_dev, TPS65941_WD_MODE_REG); + if (ret < 0) { + debug("failed to read i2c reg (%d)\n", ret); + return ret; + } + + 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_PWRHOLD fail!\n", __func__, wd_i2c_dev->name); + return ret; + } + + 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 ret; + } + + /* Disable WD */ + ret = dm_i2c_reg_read(wd_i2c_dev, TPS65941_WD_THR_CFG); + if (ret < 0) { + debug("failed to read i2c reg (%d)\n", ret); + return ret; + } + + ret &= ~TPS65941_WD_EN_MASK; + ret = dm_i2c_reg_write(wd_i2c_dev, TPS65941_WD_THR_CFG, ret); + if (ret) { + debug("%s: %s write WD_EN fail!\n", __func__, wd_i2c_dev->name); + return ret; + } + + ret = dm_i2c_reg_read(wd_i2c_dev, TPS65941_WD_THR_CFG); + if (ret < 0) { + debug("failed to read back i2c reg (%d)\n", ret); + return ret; + } + + 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 +131,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 +142,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..f3bf25a6d2 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,31 @@ #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) + +#define TPS65941_WD_THR_CFG 0x409 +#define TPS65941_WD_EN_MASK BIT(6)