@@ -94,18 +94,20 @@ enum ina2xx_ids { ina219, ina226 };
9494
9595struct ina2xx_config {
9696 u16 config_default ;
97- int calibration_factor ;
97+ int calibration_value ;
9898 int registers ;
9999 int shunt_div ;
100100 int bus_voltage_shift ;
101101 int bus_voltage_lsb ; /* uV */
102- int power_lsb ; /* uW */
102+ int power_lsb_factor ;
103103};
104104
105105struct ina2xx_data {
106106 const struct ina2xx_config * config ;
107107
108108 long rshunt ;
109+ long current_lsb_uA ;
110+ long power_lsb_uW ;
109111 struct mutex config_lock ;
110112 struct regmap * regmap ;
111113
@@ -115,21 +117,21 @@ struct ina2xx_data {
115117static const struct ina2xx_config ina2xx_config [] = {
116118 [ina219 ] = {
117119 .config_default = INA219_CONFIG_DEFAULT ,
118- .calibration_factor = 40960000 ,
120+ .calibration_value = 4096 ,
119121 .registers = INA219_REGISTERS ,
120122 .shunt_div = 100 ,
121123 .bus_voltage_shift = 3 ,
122124 .bus_voltage_lsb = 4000 ,
123- .power_lsb = 20000 ,
125+ .power_lsb_factor = 20 ,
124126 },
125127 [ina226 ] = {
126128 .config_default = INA226_CONFIG_DEFAULT ,
127- .calibration_factor = 5120000 ,
129+ .calibration_value = 2048 ,
128130 .registers = INA226_REGISTERS ,
129131 .shunt_div = 400 ,
130132 .bus_voltage_shift = 0 ,
131133 .bus_voltage_lsb = 1250 ,
132- .power_lsb = 25000 ,
134+ .power_lsb_factor = 25 ,
133135 },
134136};
135137
@@ -168,12 +170,16 @@ static u16 ina226_interval_to_reg(int interval)
168170 return INA226_SHIFT_AVG (avg_bits );
169171}
170172
173+ /*
174+ * Calibration register is set to the best value, which eliminates
175+ * truncation errors on calculating current register in hardware.
176+ * According to datasheet (eq. 3) the best values are 2048 for
177+ * ina226 and 4096 for ina219. They are hardcoded as calibration_value.
178+ */
171179static int ina2xx_calibrate (struct ina2xx_data * data )
172180{
173- u16 val = DIV_ROUND_CLOSEST (data -> config -> calibration_factor ,
174- data -> rshunt );
175-
176- return regmap_write (data -> regmap , INA2XX_CALIBRATION , val );
181+ return regmap_write (data -> regmap , INA2XX_CALIBRATION ,
182+ data -> config -> calibration_value );
177183}
178184
179185/*
@@ -186,10 +192,6 @@ static int ina2xx_init(struct ina2xx_data *data)
186192 if (ret < 0 )
187193 return ret ;
188194
189- /*
190- * Set current LSB to 1mA, shunt is in uOhms
191- * (equation 13 in datasheet).
192- */
193195 return ina2xx_calibrate (data );
194196}
195197
@@ -267,15 +269,15 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg,
267269 val = DIV_ROUND_CLOSEST (val , 1000 );
268270 break ;
269271 case INA2XX_POWER :
270- val = regval * data -> config -> power_lsb ;
272+ val = regval * data -> power_lsb_uW ;
271273 break ;
272274 case INA2XX_CURRENT :
273- /* signed register, LSB=1mA (selected), in mA */
274- val = (s16 )regval ;
275+ /* signed register, result in mA */
276+ val = regval * data -> current_lsb_uA ;
277+ val = DIV_ROUND_CLOSEST (val , 1000 );
275278 break ;
276279 case INA2XX_CALIBRATION :
277- val = DIV_ROUND_CLOSEST (data -> config -> calibration_factor ,
278- regval );
280+ val = regval ;
279281 break ;
280282 default :
281283 /* programmer goofed */
@@ -303,9 +305,32 @@ static ssize_t ina2xx_show_value(struct device *dev,
303305 ina2xx_get_value (data , attr -> index , regval ));
304306}
305307
306- static ssize_t ina2xx_set_shunt (struct device * dev ,
307- struct device_attribute * da ,
308- const char * buf , size_t count )
308+ /*
309+ * In order to keep calibration register value fixed, the product
310+ * of current_lsb and shunt_resistor should also be fixed and equal
311+ * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order
312+ * to keep the scale.
313+ */
314+ static int ina2xx_set_shunt (struct ina2xx_data * data , long val )
315+ {
316+ unsigned int dividend = DIV_ROUND_CLOSEST (1000000000 ,
317+ data -> config -> shunt_div );
318+ if (val <= 0 || val > dividend )
319+ return - EINVAL ;
320+
321+ mutex_lock (& data -> config_lock );
322+ data -> rshunt = val ;
323+ data -> current_lsb_uA = DIV_ROUND_CLOSEST (dividend , val );
324+ data -> power_lsb_uW = data -> config -> power_lsb_factor *
325+ data -> current_lsb_uA ;
326+ mutex_unlock (& data -> config_lock );
327+
328+ return 0 ;
329+ }
330+
331+ static ssize_t ina2xx_store_shunt (struct device * dev ,
332+ struct device_attribute * da ,
333+ const char * buf , size_t count )
309334{
310335 unsigned long val ;
311336 int status ;
@@ -315,18 +340,9 @@ static ssize_t ina2xx_set_shunt(struct device *dev,
315340 if (status < 0 )
316341 return status ;
317342
318- if (val == 0 ||
319- /* Values greater than the calibration factor make no sense. */
320- val > data -> config -> calibration_factor )
321- return - EINVAL ;
322-
323- mutex_lock (& data -> config_lock );
324- data -> rshunt = val ;
325- status = ina2xx_calibrate (data );
326- mutex_unlock (& data -> config_lock );
343+ status = ina2xx_set_shunt (data , val );
327344 if (status < 0 )
328345 return status ;
329-
330346 return count ;
331347}
332348
@@ -386,7 +402,7 @@ static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL,
386402
387403/* shunt resistance */
388404static SENSOR_DEVICE_ATTR (shunt_resistor , S_IRUGO | S_IWUSR ,
389- ina2xx_show_value , ina2xx_set_shunt ,
405+ ina2xx_show_value , ina2xx_store_shunt ,
390406 INA2XX_CALIBRATION ) ;
391407
392408/* update interval (ina226 only) */
@@ -441,10 +457,7 @@ static int ina2xx_probe(struct i2c_client *client,
441457 val = INA2XX_RSHUNT_DEFAULT ;
442458 }
443459
444- if (val <= 0 || val > data -> config -> calibration_factor )
445- return - ENODEV ;
446-
447- data -> rshunt = val ;
460+ ina2xx_set_shunt (data , val );
448461
449462 ina2xx_regmap_config .max_register = data -> config -> registers ;
450463
0 commit comments