0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <linux/kernel.h>
0021 #include <linux/module.h>
0022 #include <linux/init.h>
0023 #include <linux/err.h>
0024 #include <linux/slab.h>
0025 #include <linux/bug.h>
0026 #include <linux/i2c.h>
0027 #include <linux/hwmon.h>
0028 #include <linux/hwmon-sysfs.h>
0029
0030 #include <linux/platform_data/ina2xx.h>
0031
0032
0033 #define INA209_CONFIGURATION 0x00
0034 #define INA209_STATUS 0x01
0035 #define INA209_STATUS_MASK 0x02
0036 #define INA209_SHUNT_VOLTAGE 0x03
0037 #define INA209_BUS_VOLTAGE 0x04
0038 #define INA209_POWER 0x05
0039 #define INA209_CURRENT 0x06
0040 #define INA209_SHUNT_VOLTAGE_POS_PEAK 0x07
0041 #define INA209_SHUNT_VOLTAGE_NEG_PEAK 0x08
0042 #define INA209_BUS_VOLTAGE_MAX_PEAK 0x09
0043 #define INA209_BUS_VOLTAGE_MIN_PEAK 0x0a
0044 #define INA209_POWER_PEAK 0x0b
0045 #define INA209_SHUNT_VOLTAGE_POS_WARN 0x0c
0046 #define INA209_SHUNT_VOLTAGE_NEG_WARN 0x0d
0047 #define INA209_POWER_WARN 0x0e
0048 #define INA209_BUS_VOLTAGE_OVER_WARN 0x0f
0049 #define INA209_BUS_VOLTAGE_UNDER_WARN 0x10
0050 #define INA209_POWER_OVER_LIMIT 0x11
0051 #define INA209_BUS_VOLTAGE_OVER_LIMIT 0x12
0052 #define INA209_BUS_VOLTAGE_UNDER_LIMIT 0x13
0053 #define INA209_CRITICAL_DAC_POS 0x14
0054 #define INA209_CRITICAL_DAC_NEG 0x15
0055 #define INA209_CALIBRATION 0x16
0056
0057 #define INA209_REGISTERS 0x17
0058
0059 #define INA209_CONFIG_DEFAULT 0x3c47
0060 #define INA209_SHUNT_DEFAULT 10000
0061
0062 struct ina209_data {
0063 struct i2c_client *client;
0064
0065 struct mutex update_lock;
0066 bool valid;
0067 unsigned long last_updated;
0068
0069 u16 regs[INA209_REGISTERS];
0070
0071 u16 config_orig;
0072 u16 calibration_orig;
0073 u16 update_interval;
0074 };
0075
0076 static struct ina209_data *ina209_update_device(struct device *dev)
0077 {
0078 struct ina209_data *data = dev_get_drvdata(dev);
0079 struct i2c_client *client = data->client;
0080 struct ina209_data *ret = data;
0081 s32 val;
0082 int i;
0083
0084 mutex_lock(&data->update_lock);
0085
0086 if (!data->valid ||
0087 time_after(jiffies, data->last_updated + data->update_interval)) {
0088 for (i = 0; i < ARRAY_SIZE(data->regs); i++) {
0089 val = i2c_smbus_read_word_swapped(client, i);
0090 if (val < 0) {
0091 ret = ERR_PTR(val);
0092 goto abort;
0093 }
0094 data->regs[i] = val;
0095 }
0096 data->last_updated = jiffies;
0097 data->valid = true;
0098 }
0099 abort:
0100 mutex_unlock(&data->update_lock);
0101 return ret;
0102 }
0103
0104
0105
0106
0107
0108 static long ina209_from_reg(const u8 reg, const u16 val)
0109 {
0110 switch (reg) {
0111 case INA209_SHUNT_VOLTAGE:
0112 case INA209_SHUNT_VOLTAGE_POS_PEAK:
0113 case INA209_SHUNT_VOLTAGE_NEG_PEAK:
0114 case INA209_SHUNT_VOLTAGE_POS_WARN:
0115 case INA209_SHUNT_VOLTAGE_NEG_WARN:
0116
0117 return DIV_ROUND_CLOSEST((s16)val, 100);
0118
0119 case INA209_BUS_VOLTAGE:
0120 case INA209_BUS_VOLTAGE_MAX_PEAK:
0121 case INA209_BUS_VOLTAGE_MIN_PEAK:
0122 case INA209_BUS_VOLTAGE_OVER_WARN:
0123 case INA209_BUS_VOLTAGE_UNDER_WARN:
0124 case INA209_BUS_VOLTAGE_OVER_LIMIT:
0125 case INA209_BUS_VOLTAGE_UNDER_LIMIT:
0126
0127 return (val >> 3) * 4;
0128
0129 case INA209_CRITICAL_DAC_POS:
0130
0131 return val >> 8;
0132
0133 case INA209_CRITICAL_DAC_NEG:
0134
0135 return -1 * (val >> 8);
0136
0137 case INA209_POWER:
0138 case INA209_POWER_PEAK:
0139 case INA209_POWER_WARN:
0140 case INA209_POWER_OVER_LIMIT:
0141
0142 return val * 20 * 1000L;
0143
0144 case INA209_CURRENT:
0145
0146 return (s16)val;
0147 }
0148
0149
0150 WARN_ON_ONCE(1);
0151 return 0;
0152 }
0153
0154
0155
0156
0157
0158 static int ina209_to_reg(u8 reg, u16 old, long val)
0159 {
0160 switch (reg) {
0161 case INA209_SHUNT_VOLTAGE_POS_WARN:
0162 case INA209_SHUNT_VOLTAGE_NEG_WARN:
0163
0164 return clamp_val(val, -320, 320) * 100;
0165
0166 case INA209_BUS_VOLTAGE_OVER_WARN:
0167 case INA209_BUS_VOLTAGE_UNDER_WARN:
0168 case INA209_BUS_VOLTAGE_OVER_LIMIT:
0169 case INA209_BUS_VOLTAGE_UNDER_LIMIT:
0170
0171
0172
0173
0174
0175
0176 return (DIV_ROUND_CLOSEST(clamp_val(val, 0, 32000), 4) << 3)
0177 | (old & 0x7);
0178
0179 case INA209_CRITICAL_DAC_NEG:
0180
0181
0182
0183
0184
0185
0186
0187 return (clamp_val(-val, 0, 255) << 8) | (old & 0xff);
0188
0189 case INA209_CRITICAL_DAC_POS:
0190
0191
0192
0193
0194
0195
0196 return (clamp_val(val, 0, 255) << 8) | (old & 0xff);
0197
0198 case INA209_POWER_WARN:
0199 case INA209_POWER_OVER_LIMIT:
0200
0201 return DIV_ROUND_CLOSEST(val, 20 * 1000);
0202 }
0203
0204
0205 return -EACCES;
0206 }
0207
0208 static int ina209_interval_from_reg(u16 reg)
0209 {
0210 return 68 >> (15 - ((reg >> 3) & 0x0f));
0211 }
0212
0213 static u16 ina209_reg_from_interval(u16 config, long interval)
0214 {
0215 int i, adc;
0216
0217 if (interval <= 0) {
0218 adc = 8;
0219 } else {
0220 adc = 15;
0221 for (i = 34 + 34 / 2; i; i >>= 1) {
0222 if (i < interval)
0223 break;
0224 adc--;
0225 }
0226 }
0227 return (config & 0xf807) | (adc << 3) | (adc << 7);
0228 }
0229
0230 static ssize_t ina209_interval_store(struct device *dev,
0231 struct device_attribute *da,
0232 const char *buf, size_t count)
0233 {
0234 struct ina209_data *data = ina209_update_device(dev);
0235 long val;
0236 u16 regval;
0237 int ret;
0238
0239 if (IS_ERR(data))
0240 return PTR_ERR(data);
0241
0242 ret = kstrtol(buf, 10, &val);
0243 if (ret < 0)
0244 return ret;
0245
0246 mutex_lock(&data->update_lock);
0247 regval = ina209_reg_from_interval(data->regs[INA209_CONFIGURATION],
0248 val);
0249 i2c_smbus_write_word_swapped(data->client, INA209_CONFIGURATION,
0250 regval);
0251 data->regs[INA209_CONFIGURATION] = regval;
0252 data->update_interval = ina209_interval_from_reg(regval);
0253 mutex_unlock(&data->update_lock);
0254 return count;
0255 }
0256
0257 static ssize_t ina209_interval_show(struct device *dev,
0258 struct device_attribute *da, char *buf)
0259 {
0260 struct ina209_data *data = dev_get_drvdata(dev);
0261
0262 return sysfs_emit(buf, "%d\n", data->update_interval);
0263 }
0264
0265
0266
0267
0268
0269
0270
0271 static u16 ina209_reset_history_regs[] = {
0272 INA209_SHUNT_VOLTAGE_POS_PEAK,
0273 INA209_SHUNT_VOLTAGE_NEG_PEAK,
0274 INA209_BUS_VOLTAGE_MAX_PEAK,
0275 INA209_BUS_VOLTAGE_MIN_PEAK,
0276 INA209_POWER_PEAK
0277 };
0278
0279 static ssize_t ina209_history_store(struct device *dev,
0280 struct device_attribute *da,
0281 const char *buf, size_t count)
0282 {
0283 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
0284 struct ina209_data *data = dev_get_drvdata(dev);
0285 struct i2c_client *client = data->client;
0286 u32 mask = attr->index;
0287 long val;
0288 int i, ret;
0289
0290 ret = kstrtol(buf, 10, &val);
0291 if (ret < 0)
0292 return ret;
0293
0294 mutex_lock(&data->update_lock);
0295 for (i = 0; i < ARRAY_SIZE(ina209_reset_history_regs); i++) {
0296 if (mask & (1 << i))
0297 i2c_smbus_write_word_swapped(client,
0298 ina209_reset_history_regs[i], 1);
0299 }
0300 data->valid = false;
0301 mutex_unlock(&data->update_lock);
0302 return count;
0303 }
0304
0305 static ssize_t ina209_value_store(struct device *dev,
0306 struct device_attribute *da,
0307 const char *buf, size_t count)
0308 {
0309 struct ina209_data *data = ina209_update_device(dev);
0310 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
0311 int reg = attr->index;
0312 long val;
0313 int ret;
0314
0315 if (IS_ERR(data))
0316 return PTR_ERR(data);
0317
0318 ret = kstrtol(buf, 10, &val);
0319 if (ret < 0)
0320 return ret;
0321
0322 mutex_lock(&data->update_lock);
0323 ret = ina209_to_reg(reg, data->regs[reg], val);
0324 if (ret < 0) {
0325 count = ret;
0326 goto abort;
0327 }
0328 i2c_smbus_write_word_swapped(data->client, reg, ret);
0329 data->regs[reg] = ret;
0330 abort:
0331 mutex_unlock(&data->update_lock);
0332 return count;
0333 }
0334
0335 static ssize_t ina209_value_show(struct device *dev,
0336 struct device_attribute *da, char *buf)
0337 {
0338 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
0339 struct ina209_data *data = ina209_update_device(dev);
0340 long val;
0341
0342 if (IS_ERR(data))
0343 return PTR_ERR(data);
0344
0345 val = ina209_from_reg(attr->index, data->regs[attr->index]);
0346 return sysfs_emit(buf, "%ld\n", val);
0347 }
0348
0349 static ssize_t ina209_alarm_show(struct device *dev,
0350 struct device_attribute *da, char *buf)
0351 {
0352 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
0353 struct ina209_data *data = ina209_update_device(dev);
0354 const unsigned int mask = attr->index;
0355 u16 status;
0356
0357 if (IS_ERR(data))
0358 return PTR_ERR(data);
0359
0360 status = data->regs[INA209_STATUS];
0361
0362
0363
0364
0365
0366 return sysfs_emit(buf, "%u\n", !!(status & mask));
0367 }
0368
0369
0370 static SENSOR_DEVICE_ATTR_RO(in0_input, ina209_value, INA209_SHUNT_VOLTAGE);
0371 static SENSOR_DEVICE_ATTR_RO(in0_input_highest, ina209_value,
0372 INA209_SHUNT_VOLTAGE_POS_PEAK);
0373 static SENSOR_DEVICE_ATTR_RO(in0_input_lowest, ina209_value,
0374 INA209_SHUNT_VOLTAGE_NEG_PEAK);
0375 static SENSOR_DEVICE_ATTR_WO(in0_reset_history, ina209_history,
0376 (1 << 0) | (1 << 1));
0377 static SENSOR_DEVICE_ATTR_RW(in0_max, ina209_value,
0378 INA209_SHUNT_VOLTAGE_POS_WARN);
0379 static SENSOR_DEVICE_ATTR_RW(in0_min, ina209_value,
0380 INA209_SHUNT_VOLTAGE_NEG_WARN);
0381 static SENSOR_DEVICE_ATTR_RW(in0_crit_max, ina209_value,
0382 INA209_CRITICAL_DAC_POS);
0383 static SENSOR_DEVICE_ATTR_RW(in0_crit_min, ina209_value,
0384 INA209_CRITICAL_DAC_NEG);
0385
0386 static SENSOR_DEVICE_ATTR_RO(in0_min_alarm, ina209_alarm, 1 << 11);
0387 static SENSOR_DEVICE_ATTR_RO(in0_max_alarm, ina209_alarm, 1 << 12);
0388 static SENSOR_DEVICE_ATTR_RO(in0_crit_min_alarm, ina209_alarm, 1 << 6);
0389 static SENSOR_DEVICE_ATTR_RO(in0_crit_max_alarm, ina209_alarm, 1 << 7);
0390
0391
0392 static SENSOR_DEVICE_ATTR_RO(in1_input, ina209_value, INA209_BUS_VOLTAGE);
0393 static SENSOR_DEVICE_ATTR_RO(in1_input_highest, ina209_value,
0394 INA209_BUS_VOLTAGE_MAX_PEAK);
0395 static SENSOR_DEVICE_ATTR_RO(in1_input_lowest, ina209_value,
0396 INA209_BUS_VOLTAGE_MIN_PEAK);
0397 static SENSOR_DEVICE_ATTR_WO(in1_reset_history, ina209_history,
0398 (1 << 2) | (1 << 3));
0399 static SENSOR_DEVICE_ATTR_RW(in1_max, ina209_value,
0400 INA209_BUS_VOLTAGE_OVER_WARN);
0401 static SENSOR_DEVICE_ATTR_RW(in1_min, ina209_value,
0402 INA209_BUS_VOLTAGE_UNDER_WARN);
0403 static SENSOR_DEVICE_ATTR_RW(in1_crit_max, ina209_value,
0404 INA209_BUS_VOLTAGE_OVER_LIMIT);
0405 static SENSOR_DEVICE_ATTR_RW(in1_crit_min, ina209_value,
0406 INA209_BUS_VOLTAGE_UNDER_LIMIT);
0407
0408 static SENSOR_DEVICE_ATTR_RO(in1_min_alarm, ina209_alarm, 1 << 14);
0409 static SENSOR_DEVICE_ATTR_RO(in1_max_alarm, ina209_alarm, 1 << 15);
0410 static SENSOR_DEVICE_ATTR_RO(in1_crit_min_alarm, ina209_alarm, 1 << 9);
0411 static SENSOR_DEVICE_ATTR_RO(in1_crit_max_alarm, ina209_alarm, 1 << 10);
0412
0413
0414 static SENSOR_DEVICE_ATTR_RO(power1_input, ina209_value, INA209_POWER);
0415 static SENSOR_DEVICE_ATTR_RO(power1_input_highest, ina209_value,
0416 INA209_POWER_PEAK);
0417 static SENSOR_DEVICE_ATTR_WO(power1_reset_history, ina209_history, 1 << 4);
0418 static SENSOR_DEVICE_ATTR_RW(power1_max, ina209_value, INA209_POWER_WARN);
0419 static SENSOR_DEVICE_ATTR_RW(power1_crit, ina209_value,
0420 INA209_POWER_OVER_LIMIT);
0421
0422 static SENSOR_DEVICE_ATTR_RO(power1_max_alarm, ina209_alarm, 1 << 13);
0423 static SENSOR_DEVICE_ATTR_RO(power1_crit_alarm, ina209_alarm, 1 << 8);
0424
0425
0426 static SENSOR_DEVICE_ATTR_RO(curr1_input, ina209_value, INA209_CURRENT);
0427
0428 static SENSOR_DEVICE_ATTR_RW(update_interval, ina209_interval, 0);
0429
0430
0431
0432
0433
0434 static struct attribute *ina209_attrs[] = {
0435 &sensor_dev_attr_in0_input.dev_attr.attr,
0436 &sensor_dev_attr_in0_input_highest.dev_attr.attr,
0437 &sensor_dev_attr_in0_input_lowest.dev_attr.attr,
0438 &sensor_dev_attr_in0_reset_history.dev_attr.attr,
0439 &sensor_dev_attr_in0_max.dev_attr.attr,
0440 &sensor_dev_attr_in0_min.dev_attr.attr,
0441 &sensor_dev_attr_in0_crit_max.dev_attr.attr,
0442 &sensor_dev_attr_in0_crit_min.dev_attr.attr,
0443 &sensor_dev_attr_in0_max_alarm.dev_attr.attr,
0444 &sensor_dev_attr_in0_min_alarm.dev_attr.attr,
0445 &sensor_dev_attr_in0_crit_max_alarm.dev_attr.attr,
0446 &sensor_dev_attr_in0_crit_min_alarm.dev_attr.attr,
0447
0448 &sensor_dev_attr_in1_input.dev_attr.attr,
0449 &sensor_dev_attr_in1_input_highest.dev_attr.attr,
0450 &sensor_dev_attr_in1_input_lowest.dev_attr.attr,
0451 &sensor_dev_attr_in1_reset_history.dev_attr.attr,
0452 &sensor_dev_attr_in1_max.dev_attr.attr,
0453 &sensor_dev_attr_in1_min.dev_attr.attr,
0454 &sensor_dev_attr_in1_crit_max.dev_attr.attr,
0455 &sensor_dev_attr_in1_crit_min.dev_attr.attr,
0456 &sensor_dev_attr_in1_max_alarm.dev_attr.attr,
0457 &sensor_dev_attr_in1_min_alarm.dev_attr.attr,
0458 &sensor_dev_attr_in1_crit_max_alarm.dev_attr.attr,
0459 &sensor_dev_attr_in1_crit_min_alarm.dev_attr.attr,
0460
0461 &sensor_dev_attr_power1_input.dev_attr.attr,
0462 &sensor_dev_attr_power1_input_highest.dev_attr.attr,
0463 &sensor_dev_attr_power1_reset_history.dev_attr.attr,
0464 &sensor_dev_attr_power1_max.dev_attr.attr,
0465 &sensor_dev_attr_power1_crit.dev_attr.attr,
0466 &sensor_dev_attr_power1_max_alarm.dev_attr.attr,
0467 &sensor_dev_attr_power1_crit_alarm.dev_attr.attr,
0468
0469 &sensor_dev_attr_curr1_input.dev_attr.attr,
0470
0471 &sensor_dev_attr_update_interval.dev_attr.attr,
0472
0473 NULL,
0474 };
0475 ATTRIBUTE_GROUPS(ina209);
0476
0477 static void ina209_restore_conf(struct i2c_client *client,
0478 struct ina209_data *data)
0479 {
0480
0481 i2c_smbus_write_word_swapped(client, INA209_CONFIGURATION,
0482 data->config_orig);
0483 i2c_smbus_write_word_swapped(client, INA209_CALIBRATION,
0484 data->calibration_orig);
0485 }
0486
0487 static int ina209_init_client(struct i2c_client *client,
0488 struct ina209_data *data)
0489 {
0490 struct ina2xx_platform_data *pdata = dev_get_platdata(&client->dev);
0491 u32 shunt;
0492 int reg;
0493
0494 reg = i2c_smbus_read_word_swapped(client, INA209_CALIBRATION);
0495 if (reg < 0)
0496 return reg;
0497 data->calibration_orig = reg;
0498
0499 reg = i2c_smbus_read_word_swapped(client, INA209_CONFIGURATION);
0500 if (reg < 0)
0501 return reg;
0502 data->config_orig = reg;
0503
0504 if (pdata) {
0505 if (pdata->shunt_uohms <= 0)
0506 return -EINVAL;
0507 shunt = pdata->shunt_uohms;
0508 } else if (!of_property_read_u32(client->dev.of_node, "shunt-resistor",
0509 &shunt)) {
0510 if (shunt == 0)
0511 return -EINVAL;
0512 } else {
0513 shunt = data->calibration_orig ?
0514 40960000 / data->calibration_orig : INA209_SHUNT_DEFAULT;
0515 }
0516
0517 i2c_smbus_write_word_swapped(client, INA209_CONFIGURATION,
0518 INA209_CONFIG_DEFAULT);
0519 data->update_interval = ina209_interval_from_reg(INA209_CONFIG_DEFAULT);
0520
0521
0522
0523
0524
0525 i2c_smbus_write_word_swapped(client, INA209_CALIBRATION,
0526 clamp_val(40960000 / shunt, 1, 65535));
0527
0528
0529 i2c_smbus_read_word_swapped(client, INA209_STATUS);
0530
0531 return 0;
0532 }
0533
0534 static int ina209_probe(struct i2c_client *client)
0535 {
0536 struct i2c_adapter *adapter = client->adapter;
0537 struct ina209_data *data;
0538 struct device *hwmon_dev;
0539 int ret;
0540
0541 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
0542 return -ENODEV;
0543
0544 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
0545 if (!data)
0546 return -ENOMEM;
0547
0548 i2c_set_clientdata(client, data);
0549 data->client = client;
0550 mutex_init(&data->update_lock);
0551
0552 ret = ina209_init_client(client, data);
0553 if (ret)
0554 return ret;
0555
0556 hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
0557 client->name,
0558 data, ina209_groups);
0559 if (IS_ERR(hwmon_dev)) {
0560 ret = PTR_ERR(hwmon_dev);
0561 goto out_restore_conf;
0562 }
0563
0564 return 0;
0565
0566 out_restore_conf:
0567 ina209_restore_conf(client, data);
0568 return ret;
0569 }
0570
0571 static int ina209_remove(struct i2c_client *client)
0572 {
0573 struct ina209_data *data = i2c_get_clientdata(client);
0574
0575 ina209_restore_conf(client, data);
0576
0577 return 0;
0578 }
0579
0580 static const struct i2c_device_id ina209_id[] = {
0581 { "ina209", 0 },
0582 { }
0583 };
0584 MODULE_DEVICE_TABLE(i2c, ina209_id);
0585
0586 static const struct of_device_id __maybe_unused ina209_of_match[] = {
0587 { .compatible = "ti,ina209" },
0588 { },
0589 };
0590 MODULE_DEVICE_TABLE(of, ina209_of_match);
0591
0592
0593 static struct i2c_driver ina209_driver = {
0594 .class = I2C_CLASS_HWMON,
0595 .driver = {
0596 .name = "ina209",
0597 .of_match_table = of_match_ptr(ina209_of_match),
0598 },
0599 .probe_new = ina209_probe,
0600 .remove = ina209_remove,
0601 .id_table = ina209_id,
0602 };
0603
0604 module_i2c_driver(ina209_driver);
0605
0606 MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>, Paul Hays <Paul.Hays@cattail.ca>, Guenter Roeck <linux@roeck-us.net>");
0607 MODULE_DESCRIPTION("INA209 driver");
0608 MODULE_LICENSE("GPL");