ltc2990.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Driver for Linear Technology LTC2990 power monitor
  3. *
  4. * Copyright (C) 2014 Topic Embedded Products
  5. * Author: Mike Looijmans <mike.looijmans@topic.nl>
  6. *
  7. * License: GPLv2
  8. *
  9. * This driver assumes the chip is wired as a dual current monitor, and
  10. * reports the voltage drop across two series resistors. It also reports
  11. * the chip's internal temperature and Vcc power supply voltage.
  12. */
  13. #include <linux/err.h>
  14. #include <linux/hwmon.h>
  15. #include <linux/hwmon-sysfs.h>
  16. #include <linux/i2c.h>
  17. #include <linux/kernel.h>
  18. #include <linux/module.h>
  19. #define LTC2990_STATUS 0x00
  20. #define LTC2990_CONTROL 0x01
  21. #define LTC2990_TRIGGER 0x02
  22. #define LTC2990_TINT_MSB 0x04
  23. #define LTC2990_V1_MSB 0x06
  24. #define LTC2990_V2_MSB 0x08
  25. #define LTC2990_V3_MSB 0x0A
  26. #define LTC2990_V4_MSB 0x0C
  27. #define LTC2990_VCC_MSB 0x0E
  28. #define LTC2990_CONTROL_KELVIN BIT(7)
  29. #define LTC2990_CONTROL_SINGLE BIT(6)
  30. #define LTC2990_CONTROL_MEASURE_ALL (0x3 << 3)
  31. #define LTC2990_CONTROL_MODE_CURRENT 0x06
  32. #define LTC2990_CONTROL_MODE_VOLTAGE 0x07
  33. /* convert raw register value to sign-extended integer in 16-bit range */
  34. static int ltc2990_voltage_to_int(int raw)
  35. {
  36. if (raw & BIT(14))
  37. return -(0x4000 - (raw & 0x3FFF)) << 2;
  38. else
  39. return (raw & 0x3FFF) << 2;
  40. }
  41. /* Return the converted value from the given register in uV or mC */
  42. static int ltc2990_get_value(struct i2c_client *i2c, u8 reg, int *result)
  43. {
  44. int val;
  45. val = i2c_smbus_read_word_swapped(i2c, reg);
  46. if (unlikely(val < 0))
  47. return val;
  48. switch (reg) {
  49. case LTC2990_TINT_MSB:
  50. /* internal temp, 0.0625 degrees/LSB, 13-bit */
  51. val = (val & 0x1FFF) << 3;
  52. *result = (val * 1000) >> 7;
  53. break;
  54. case LTC2990_V1_MSB:
  55. case LTC2990_V3_MSB:
  56. /* Vx-Vy, 19.42uV/LSB. Depends on mode. */
  57. *result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);
  58. break;
  59. case LTC2990_VCC_MSB:
  60. /* Vcc, 305.18μV/LSB, 2.5V offset */
  61. *result = (ltc2990_voltage_to_int(val) * 30518 /
  62. (4 * 100 * 1000)) + 2500;
  63. break;
  64. default:
  65. return -EINVAL; /* won't happen, keep compiler happy */
  66. }
  67. return 0;
  68. }
  69. static ssize_t ltc2990_show_value(struct device *dev,
  70. struct device_attribute *da, char *buf)
  71. {
  72. struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
  73. int value;
  74. int ret;
  75. ret = ltc2990_get_value(dev_get_drvdata(dev), attr->index, &value);
  76. if (unlikely(ret < 0))
  77. return ret;
  78. return snprintf(buf, PAGE_SIZE, "%d\n", value);
  79. }
  80. static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL,
  81. LTC2990_TINT_MSB);
  82. static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL,
  83. LTC2990_V1_MSB);
  84. static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL,
  85. LTC2990_V3_MSB);
  86. static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL,
  87. LTC2990_VCC_MSB);
  88. static struct attribute *ltc2990_attrs[] = {
  89. &sensor_dev_attr_temp1_input.dev_attr.attr,
  90. &sensor_dev_attr_curr1_input.dev_attr.attr,
  91. &sensor_dev_attr_curr2_input.dev_attr.attr,
  92. &sensor_dev_attr_in0_input.dev_attr.attr,
  93. NULL,
  94. };
  95. ATTRIBUTE_GROUPS(ltc2990);
  96. static int ltc2990_i2c_probe(struct i2c_client *i2c,
  97. const struct i2c_device_id *id)
  98. {
  99. int ret;
  100. struct device *hwmon_dev;
  101. if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
  102. I2C_FUNC_SMBUS_WORD_DATA))
  103. return -ENODEV;
  104. /* Setup continuous mode, current monitor */
  105. ret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL,
  106. LTC2990_CONTROL_MEASURE_ALL |
  107. LTC2990_CONTROL_MODE_CURRENT);
  108. if (ret < 0) {
  109. dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
  110. return ret;
  111. }
  112. /* Trigger once to start continuous conversion */
  113. ret = i2c_smbus_write_byte_data(i2c, LTC2990_TRIGGER, 1);
  114. if (ret < 0) {
  115. dev_err(&i2c->dev, "Error: Failed to start acquisition.\n");
  116. return ret;
  117. }
  118. hwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev,
  119. i2c->name,
  120. i2c,
  121. ltc2990_groups);
  122. return PTR_ERR_OR_ZERO(hwmon_dev);
  123. }
  124. static const struct i2c_device_id ltc2990_i2c_id[] = {
  125. { "ltc2990", 0 },
  126. {}
  127. };
  128. MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);
  129. static struct i2c_driver ltc2990_i2c_driver = {
  130. .driver = {
  131. .name = "ltc2990",
  132. },
  133. .probe = ltc2990_i2c_probe,
  134. .id_table = ltc2990_i2c_id,
  135. };
  136. module_i2c_driver(ltc2990_i2c_driver);
  137. MODULE_DESCRIPTION("LTC2990 Sensor Driver");
  138. MODULE_AUTHOR("Topic Embedded Products");
  139. MODULE_LICENSE("GPL v2");