From 026703174a2cf8cd9c83a7c797b96b95af5af69b Mon Sep 17 00:00:00 2001 From: Biwen Li Date: Mon, 12 Oct 2020 20:07:35 +0800 Subject: [PATCH] board/freescale/vid: enables writes to all commands for LTC3882 Enable writes to all commands for LTC3882 Signed-off-by: Biwen Li Reviewed-by: Priyanka Jain --- board/freescale/common/vid.c | 42 +++++++++++++++++++++++++++++++++--- board/freescale/common/vid.h | 19 ++++++++++++++++ 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/board/freescale/common/vid.c b/board/freescale/common/vid.c index bf8a5d893f..9c51f50260 100644 --- a/board/freescale/common/vid.c +++ b/board/freescale/common/vid.c @@ -379,6 +379,7 @@ static int set_voltage_to_LTC(int i2caddress, int vdd) { int ret, vdd_last, vdd_target = vdd; int count = 100, temp = 0; + unsigned char value; /* Scale up to the LTC resolution is 1/4096V */ vdd = (vdd * 4096) / 1000; @@ -391,16 +392,51 @@ static int set_voltage_to_LTC(int i2caddress, int vdd) /* Write the desired voltage code to the regulator */ #ifndef CONFIG_DM_I2C + /* Check write protect state */ + ret = i2c_read(I2C_VOL_MONITOR_ADDR, + PMBUS_CMD_WRITE_PROTECT, 1, + (void *)&value, sizeof(value)); + if (ret) + goto exit; + + if (value != EN_WRITE_ALL_CMD) { + value = EN_WRITE_ALL_CMD; + ret = i2c_write(I2C_VOL_MONITOR_ADDR, + PMBUS_CMD_WRITE_PROTECT, 1, + (void *)&value, sizeof(value)); + if (ret) + goto exit; + } + ret = i2c_write(I2C_VOL_MONITOR_ADDR, - PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5); + PMBUS_CMD_PAGE_PLUS_WRITE, 1, + (void *)&buff, sizeof(buff)); #else struct udevice *dev; ret = i2c_get_chip_for_busnum(0, I2C_VOL_MONITOR_ADDR, 1, &dev); - if (!ret) + if (!ret) { + /* Check write protect state */ + ret = dm_i2c_read(dev, + PMBUS_CMD_WRITE_PROTECT, + (void *)&value, sizeof(value)); + if (ret) + goto exit; + + if (value != EN_WRITE_ALL_CMD) { + value = EN_WRITE_ALL_CMD; + ret = dm_i2c_write(dev, + PMBUS_CMD_WRITE_PROTECT, + (void *)&value, sizeof(value)); + if (ret) + goto exit; + } + ret = dm_i2c_write(dev, PMBUS_CMD_PAGE_PLUS_WRITE, - (void *)&buff, 5); + (void *)&buff, sizeof(buff)); + } #endif +exit: if (ret) { printf("VID: I2C failed to write to the volatge regulator\n"); return -1; diff --git a/board/freescale/common/vid.h b/board/freescale/common/vid.h index 99778e9a93..65b348ee42 100644 --- a/board/freescale/common/vid.h +++ b/board/freescale/common/vid.h @@ -18,6 +18,25 @@ /* step the IR regulator in 5mV increments */ #define IR_VDD_STEP_DOWN 5 #define IR_VDD_STEP_UP 5 + +/* LTC3882 */ +#define PMBUS_CMD_WRITE_PROTECT 0x10 +/* + * WRITE_PROTECT command supported values + * 0x80: Disable all writes except WRITE_PROTECT, PAGE, + * STORE_USER_ALL and MFR_EE_UNLOCK commands. + * 0x40: Disable all writes except WRITE_PROTECT, PAGE, STORE_USER_ALL, + * MFR_EE_UNLOCK, OPERATION, CLEAR_PEAKS and CLEAR_FAULTS commands. + * Individual faults can also be cleared by writing a 1 to the + * respective status bit. + * 0x20: Disable all writes except WRITE_PROTECT, PAGE, STORE_USER_ ALL, + * MFR_EE_UNLOCK, OPERATION, CLEAR_PEAKS, CLEAR_FAULTS, ON_OFF_CONFIG + * and VOUT_COMMAND commands. Individual faults can be cleared by + * writing a 1 to the respective status bit. + * 0x00: Enables write to all commands + */ +#define EN_WRITE_ALL_CMD (0) + int adjust_vdd(ulong vdd_override); #endif /* __VID_H_ */