summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/hwmon/ina2xx.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
index 6a2cebbb9f15..613ffb622b7c 100644
--- a/drivers/hwmon/ina2xx.c
+++ b/drivers/hwmon/ina2xx.c
@@ -135,9 +135,11 @@ struct ina2xx_config {
bool has_update_interval;
int calibration_value;
int shunt_div;
+ int shunt_voltage_shift;
int bus_voltage_shift;
int bus_voltage_lsb; /* uV */
int power_lsb_factor;
+ int current_shift;
};
struct ina2xx_data {
@@ -156,59 +158,69 @@ static const struct ina2xx_config ina2xx_config[] = {
.config_default = INA219_CONFIG_DEFAULT,
.calibration_value = 4096,
.shunt_div = 100,
+ .shunt_voltage_shift = 0,
.bus_voltage_shift = 3,
.bus_voltage_lsb = 4000,
.power_lsb_factor = 20,
.has_alerts = false,
.has_ishunt = false,
.has_power_average = false,
+ .current_shift = 0,
.has_update_interval = false,
},
[ina226] = {
.config_default = INA226_CONFIG_DEFAULT,
.calibration_value = 2048,
.shunt_div = 400,
+ .shunt_voltage_shift = 0,
.bus_voltage_shift = 0,
.bus_voltage_lsb = 1250,
.power_lsb_factor = 25,
.has_alerts = true,
.has_ishunt = false,
.has_power_average = false,
+ .current_shift = 0,
.has_update_interval = true,
},
[ina234] = {
.config_default = INA226_CONFIG_DEFAULT,
.calibration_value = 2048,
- .shunt_div = 400, /* 2.5 µV/LSB raw ADC reading from INA2XX_SHUNT_VOLTAGE */
+ .shunt_div = 25, /* 2.5 µV/LSB raw ADC reading from INA2XX_SHUNT_VOLTAGE */
+ .shunt_voltage_shift = 4,
.bus_voltage_shift = 4,
.bus_voltage_lsb = 25600,
.power_lsb_factor = 32,
.has_alerts = true,
.has_ishunt = false,
.has_power_average = false,
+ .current_shift = 4,
.has_update_interval = true,
},
[ina260] = {
.config_default = INA260_CONFIG_DEFAULT,
.shunt_div = 400,
+ .shunt_voltage_shift = 0,
.bus_voltage_shift = 0,
.bus_voltage_lsb = 1250,
.power_lsb_factor = 8,
.has_alerts = true,
.has_ishunt = true,
.has_power_average = false,
+ .current_shift = 0,
.has_update_interval = true,
},
[sy24655] = {
.config_default = SY24655_CONFIG_DEFAULT,
.calibration_value = 4096,
.shunt_div = 400,
+ .shunt_voltage_shift = 0,
.bus_voltage_shift = 0,
.bus_voltage_lsb = 1250,
.power_lsb_factor = 25,
.has_alerts = true,
.has_ishunt = false,
.has_power_average = true,
+ .current_shift = 0,
.has_update_interval = false,
},
};
@@ -262,7 +274,8 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg,
switch (reg) {
case INA2XX_SHUNT_VOLTAGE:
/* signed register */
- val = DIV_ROUND_CLOSEST((s16)regval, data->config->shunt_div);
+ val = (s16)regval >> data->config->shunt_voltage_shift;
+ val = DIV_ROUND_CLOSEST(val, data->config->shunt_div);
break;
case INA2XX_BUS_VOLTAGE:
val = (regval >> data->config->bus_voltage_shift) *
@@ -274,7 +287,8 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg,
break;
case INA2XX_CURRENT:
/* signed register, result in mA */
- val = (s16)regval * data->current_lsb_uA;
+ val = ((s16)regval >> data->config->current_shift) *
+ data->current_lsb_uA;
val = DIV_ROUND_CLOSEST(val, 1000);
break;
case INA2XX_CALIBRATION:
@@ -368,6 +382,7 @@ static u16 ina226_alert_to_reg(struct ina2xx_data *data, int reg, long val)
case INA2XX_SHUNT_VOLTAGE:
val = clamp_val(val, 0, SHRT_MAX * data->config->shunt_div);
val *= data->config->shunt_div;
+ val <<= data->config->shunt_voltage_shift;
return clamp_val(val, 0, SHRT_MAX);
case INA2XX_BUS_VOLTAGE:
val = clamp_val(val, 0, 200000);
@@ -382,6 +397,7 @@ static u16 ina226_alert_to_reg(struct ina2xx_data *data, int reg, long val)
val = clamp_val(val, INT_MIN / 1000, INT_MAX / 1000);
/* signed register, result in mA */
val = DIV_ROUND_CLOSEST(val * 1000, data->current_lsb_uA);
+ val <<= data->config->current_shift;
return clamp_val(val, SHRT_MIN, SHRT_MAX);
default:
/* programmer goofed */