diff options
author | Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com> | 2017-08-30 09:54:05 (GMT) |
---|---|---|
committer | Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com> | 2017-08-30 09:54:05 (GMT) |
commit | de23ed62192579338359e37040701b35153d3d5e (patch) | |
tree | fde701176e4fb9866d96a5816e80c055c70a679b /board/freescale/common | |
parent | 12b9315fb9e410662bb745c1e2495ef7e7b977f0 (diff) | |
download | u-boot-de23ed62192579338359e37040701b35153d3d5e.tar.xz |
board: common: vid: Add support for LTC3882 voltage regulator chip
Restructures common driver to support LTC3882 voltage regulator
chip.
Signed-off-by: Ashish Kumar <Ashish.Kumar@nxp.com>
Signed-off-by: Rajesh Bhagat <rajesh.bhagat@nxp.com>
Diffstat (limited to 'board/freescale/common')
-rw-r--r-- | board/freescale/common/vid.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/board/freescale/common/vid.c b/board/freescale/common/vid.c index a920849..dcff1d1 100644 --- a/board/freescale/common/vid.c +++ b/board/freescale/common/vid.c @@ -171,6 +171,35 @@ static int read_voltage_from_IR(int i2caddress) } #endif +#ifdef CONFIG_VOL_MONITOR_LTC3882_READ +/* read the current value of the LTC Regulator Voltage */ +static int read_voltage_from_LTC(int i2caddress) +{ + int ret, vcode = 0; + + /* select the PAGE 0 using PMBus commands PAGE for VDD*/ + ret = i2c_write(I2C_VOL_MONITOR_ADDR, + PMBUS_CMD_PAGE, 1, PWM_CHANNEL0, 1); + if (ret) { + printf("VID: failed to select VDD Page 0\n"); + return ret; + } + + /*read the output voltage using PMBus command READ_VOUT*/ + ret = i2c_read(I2C_VOL_MONITOR_ADDR, + PMBUS_CMD_READ_VOUT, 1, (void *)&vcode, 2); + if (ret) { + printf("VID: failed to read the volatge\n"); + return ret; + } + + /* Scale down to the real mV as LTC resolution is 1/4096V,rounding up */ + vcode = DIV_ROUND_UP(vcode * 1000, 4096); + + return vcode; +} +#endif + static int read_voltage(int i2caddress) { int voltage_read; @@ -178,6 +207,8 @@ static int read_voltage(int i2caddress) voltage_read = read_voltage_from_INA220(i2caddress); #elif defined CONFIG_VOL_MONITOR_IR36021_READ voltage_read = read_voltage_from_IR(i2caddress); +#elif defined CONFIG_VOL_MONITOR_LTC3882_READ + voltage_read = read_voltage_from_LTC(i2caddress); #else return -1; #endif @@ -278,6 +309,42 @@ static int set_voltage_to_IR(int i2caddress, int vdd) debug("VID: Current voltage is %d mV\n", vdd_last); return vdd_last; } + +#endif + +#ifdef CONFIG_VOL_MONITOR_LTC3882_SET +/* this function sets the VDD and returns the value set */ +static int set_voltage_to_LTC(int i2caddress, int vdd) +{ + int ret, vdd_last, vdd_target = vdd; + + /* Scale up to the LTC resolution is 1/4096V */ + vdd = (vdd * 4096) / 1000; + + /* 5-byte buffer which needs to be sent following the + * PMBus command PAGE_PLUS_WRITE. + */ + u8 buff[5] = {0x04, PWM_CHANNEL0, PMBUS_CMD_VOUT_COMMAND, + vdd & 0xFF, (vdd & 0xFF00) >> 8}; + + /* Write the desired voltage code to the regulator */ + ret = i2c_write(I2C_VOL_MONITOR_ADDR, + PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5); + if (ret) { + printf("VID: I2C failed to write to the volatge regulator\n"); + return -1; + } + + /* Wait for the volatge to get to the desired value */ + do { + vdd_last = read_voltage_from_LTC(i2caddress); + if (vdd_last < 0) { + printf("VID: Couldn't read sensor abort VID adjust\n"); + return -1; + } + } while (vdd_last != vdd_target); + return vdd_last; +} #endif static int set_voltage(int i2caddress, int vdd) @@ -286,6 +353,8 @@ static int set_voltage(int i2caddress, int vdd) #ifdef CONFIG_VOL_MONITOR_IR36021_SET vdd_last = set_voltage_to_IR(i2caddress, vdd); +#elif defined CONFIG_VOL_MONITOR_LTC3882_SET + vdd_last = set_voltage_to_LTC(i2caddress, vdd); #else #error Specific voltage monitor must be defined #endif @@ -452,6 +521,11 @@ int adjust_vdd(ulong vdd_override) } vdd_current = vdd_last; debug("VID: Core voltage is currently at %d mV\n", vdd_last); + +#ifdef CONFIG_VOL_MONITOR_LTC3882_SET + /* Set the target voltage */ + vdd_last = vdd_current = set_voltage(i2caddress, vdd_target); +#else /* * Adjust voltage to at or one step above target. * As measurements are less precise than setting the values @@ -469,6 +543,7 @@ int adjust_vdd(ulong vdd_override) vdd_last = set_voltage(i2caddress, vdd_current); } +#endif if (board_adjust_vdd(vdd_target) < 0) { ret = -1; goto exit; |