@@ -95,18 +95,20 @@ enum ina2xx_ids { ina219, ina226 };
9595
9696struct ina2xx_config {
9797 u16 config_default ;
98- int calibration_factor ;
98+ int calibration_value ;
9999 int registers ;
100100 int shunt_div ;
101101 int bus_voltage_shift ;
102102 int bus_voltage_lsb ; /* uV */
103- int power_lsb ; /* uW */
103+ int power_lsb_factor ;
104104};
105105
106106struct ina2xx_data {
107107 const struct ina2xx_config * config ;
108108
109109 long rshunt ;
110+ long current_lsb_uA ;
111+ long power_lsb_uW ;
110112 struct mutex config_lock ;
111113 struct regmap * regmap ;
112114
@@ -116,21 +118,21 @@ struct ina2xx_data {
116118static const struct ina2xx_config ina2xx_config [] = {
117119 [ina219 ] = {
118120 .config_default = INA219_CONFIG_DEFAULT ,
119- .calibration_factor = 40960000 ,
121+ .calibration_value = 4096 ,
120122 .registers = INA219_REGISTERS ,
121123 .shunt_div = 100 ,
122124 .bus_voltage_shift = 3 ,
123125 .bus_voltage_lsb = 4000 ,
124- .power_lsb = 20000 ,
126+ .power_lsb_factor = 20 ,
125127 },
126128 [ina226 ] = {
127129 .config_default = INA226_CONFIG_DEFAULT ,
128- .calibration_factor = 5120000 ,
130+ .calibration_value = 2048 ,
129131 .registers = INA226_REGISTERS ,
130132 .shunt_div = 400 ,
131133 .bus_voltage_shift = 0 ,
132134 .bus_voltage_lsb = 1250 ,
133- .power_lsb = 25000 ,
135+ .power_lsb_factor = 25 ,
134136 },
135137};
136138
@@ -169,12 +171,16 @@ static u16 ina226_interval_to_reg(int interval)
169171 return INA226_SHIFT_AVG (avg_bits );
170172}
171173
174+ /*
175+ * Calibration register is set to the best value, which eliminates
176+ * truncation errors on calculating current register in hardware.
177+ * According to datasheet (eq. 3) the best values are 2048 for
178+ * ina226 and 4096 for ina219. They are hardcoded as calibration_value.
179+ */
172180static int ina2xx_calibrate (struct ina2xx_data * data )
173181{
174- u16 val = DIV_ROUND_CLOSEST (data -> config -> calibration_factor ,
175- data -> rshunt );
176-
177- return regmap_write (data -> regmap , INA2XX_CALIBRATION , val );
182+ return regmap_write (data -> regmap , INA2XX_CALIBRATION ,
183+ data -> config -> calibration_value );
178184}
179185
180186/*
@@ -187,10 +193,6 @@ static int ina2xx_init(struct ina2xx_data *data)
187193 if (ret < 0 )
188194 return ret ;
189195
190- /*
191- * Set current LSB to 1mA, shunt is in uOhms
192- * (equation 13 in datasheet).
193- */
194196 return ina2xx_calibrate (data );
195197}
196198
@@ -268,15 +270,15 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg,
268270 val = DIV_ROUND_CLOSEST (val , 1000 );
269271 break ;
270272 case INA2XX_POWER :
271- val = regval * data -> config -> power_lsb ;
273+ val = regval * data -> power_lsb_uW ;
272274 break ;
273275 case INA2XX_CURRENT :
274- /* signed register, LSB=1mA (selected), in mA */
275- val = (s16 )regval ;
276+ /* signed register, result in mA */
277+ val = regval * data -> current_lsb_uA ;
278+ val = DIV_ROUND_CLOSEST (val , 1000 );
276279 break ;
277280 case INA2XX_CALIBRATION :
278- val = DIV_ROUND_CLOSEST (data -> config -> calibration_factor ,
279- regval );
281+ val = regval ;
280282 break ;
281283 default :
282284 /* programmer goofed */
@@ -304,9 +306,32 @@ static ssize_t ina2xx_show_value(struct device *dev,
304306 ina2xx_get_value (data , attr -> index , regval ));
305307}
306308
307- static ssize_t ina2xx_set_shunt (struct device * dev ,
308- struct device_attribute * da ,
309- const char * buf , size_t count )
309+ /*
310+ * In order to keep calibration register value fixed, the product
311+ * of current_lsb and shunt_resistor should also be fixed and equal
312+ * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order
313+ * to keep the scale.
314+ */
315+ static int ina2xx_set_shunt (struct ina2xx_data * data , long val )
316+ {
317+ unsigned int dividend = DIV_ROUND_CLOSEST (1000000000 ,
318+ data -> config -> shunt_div );
319+ if (val <= 0 || val > dividend )
320+ return - EINVAL ;
321+
322+ mutex_lock (& data -> config_lock );
323+ data -> rshunt = val ;
324+ data -> current_lsb_uA = DIV_ROUND_CLOSEST (dividend , val );
325+ data -> power_lsb_uW = data -> config -> power_lsb_factor *
326+ data -> current_lsb_uA ;
327+ mutex_unlock (& data -> config_lock );
328+
329+ return 0 ;
330+ }
331+
332+ static ssize_t ina2xx_store_shunt (struct device * dev ,
333+ struct device_attribute * da ,
334+ const char * buf , size_t count )
310335{
311336 unsigned long val ;
312337 int status ;
@@ -316,18 +341,9 @@ static ssize_t ina2xx_set_shunt(struct device *dev,
316341 if (status < 0 )
317342 return status ;
318343
319- if (val == 0 ||
320- /* Values greater than the calibration factor make no sense. */
321- val > data -> config -> calibration_factor )
322- return - EINVAL ;
323-
324- mutex_lock (& data -> config_lock );
325- data -> rshunt = val ;
326- status = ina2xx_calibrate (data );
327- mutex_unlock (& data -> config_lock );
344+ status = ina2xx_set_shunt (data , val );
328345 if (status < 0 )
329346 return status ;
330-
331347 return count ;
332348}
333349
@@ -387,7 +403,7 @@ static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL,
387403
388404/* shunt resistance */
389405static SENSOR_DEVICE_ATTR (shunt_resistor , S_IRUGO | S_IWUSR ,
390- ina2xx_show_value , ina2xx_set_shunt ,
406+ ina2xx_show_value , ina2xx_store_shunt ,
391407 INA2XX_CALIBRATION ) ;
392408
393409/* update interval (ina226 only) */
@@ -448,10 +464,7 @@ static int ina2xx_probe(struct i2c_client *client,
448464 val = INA2XX_RSHUNT_DEFAULT ;
449465 }
450466
451- if (val <= 0 || val > data -> config -> calibration_factor )
452- return - ENODEV ;
453-
454- data -> rshunt = val ;
467+ ina2xx_set_shunt (data , val );
455468
456469 ina2xx_regmap_config .max_register = data -> config -> registers ;
457470
0 commit comments