menf21bmc_hwmon.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * MEN 14F021P00 Board Management Controller (BMC) hwmon driver.
  4. *
  5. * This is the core hwmon driver of the MEN 14F021P00 BMC.
  6. * The BMC monitors the board voltages which can be access with this
  7. * driver through sysfs.
  8. *
  9. * Copyright (C) 2014 MEN Mikro Elektronik Nuernberg GmbH
  10. */
  11. #include <linux/module.h>
  12. #include <linux/kernel.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/hwmon.h>
  15. #include <linux/hwmon-sysfs.h>
  16. #include <linux/jiffies.h>
  17. #include <linux/slab.h>
  18. #include <linux/i2c.h>
  19. #include <linux/err.h>
  20. #define DRV_NAME "menf21bmc_hwmon"
  21. #define BMC_VOLT_COUNT 5
  22. #define MENF21BMC_V33 0
  23. #define MENF21BMC_V5 1
  24. #define MENF21BMC_V12 2
  25. #define MENF21BMC_V5_SB 3
  26. #define MENF21BMC_VBAT 4
  27. #define IDX_TO_VOLT_MIN_CMD(idx) (0x40 + idx)
  28. #define IDX_TO_VOLT_MAX_CMD(idx) (0x50 + idx)
  29. #define IDX_TO_VOLT_INP_CMD(idx) (0x60 + idx)
  30. struct menf21bmc_hwmon {
  31. bool valid;
  32. struct i2c_client *i2c_client;
  33. unsigned long last_update;
  34. int in_val[BMC_VOLT_COUNT];
  35. int in_min[BMC_VOLT_COUNT];
  36. int in_max[BMC_VOLT_COUNT];
  37. };
  38. static const char *const input_names[] = {
  39. [MENF21BMC_V33] = "MON_3_3V",
  40. [MENF21BMC_V5] = "MON_5V",
  41. [MENF21BMC_V12] = "MON_12V",
  42. [MENF21BMC_V5_SB] = "5V_STANDBY",
  43. [MENF21BMC_VBAT] = "VBAT"
  44. };
  45. static struct menf21bmc_hwmon *menf21bmc_hwmon_update(struct device *dev)
  46. {
  47. int i;
  48. int val;
  49. struct menf21bmc_hwmon *drv_data = dev_get_drvdata(dev);
  50. struct menf21bmc_hwmon *data_ret = drv_data;
  51. if (time_after(jiffies, drv_data->last_update + HZ)
  52. || !drv_data->valid) {
  53. for (i = 0; i < BMC_VOLT_COUNT; i++) {
  54. val = i2c_smbus_read_word_data(drv_data->i2c_client,
  55. IDX_TO_VOLT_INP_CMD(i));
  56. if (val < 0) {
  57. data_ret = ERR_PTR(val);
  58. goto abort;
  59. }
  60. drv_data->in_val[i] = val;
  61. }
  62. drv_data->last_update = jiffies;
  63. drv_data->valid = true;
  64. }
  65. abort:
  66. return data_ret;
  67. }
  68. static int menf21bmc_hwmon_get_volt_limits(struct menf21bmc_hwmon *drv_data)
  69. {
  70. int i, val;
  71. for (i = 0; i < BMC_VOLT_COUNT; i++) {
  72. val = i2c_smbus_read_word_data(drv_data->i2c_client,
  73. IDX_TO_VOLT_MIN_CMD(i));
  74. if (val < 0)
  75. return val;
  76. drv_data->in_min[i] = val;
  77. val = i2c_smbus_read_word_data(drv_data->i2c_client,
  78. IDX_TO_VOLT_MAX_CMD(i));
  79. if (val < 0)
  80. return val;
  81. drv_data->in_max[i] = val;
  82. }
  83. return 0;
  84. }
  85. static ssize_t
  86. label_show(struct device *dev, struct device_attribute *devattr, char *buf)
  87. {
  88. struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
  89. return sprintf(buf, "%s\n", input_names[attr->index]);
  90. }
  91. static ssize_t
  92. in_show(struct device *dev, struct device_attribute *devattr, char *buf)
  93. {
  94. struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
  95. struct menf21bmc_hwmon *drv_data = menf21bmc_hwmon_update(dev);
  96. if (IS_ERR(drv_data))
  97. return PTR_ERR(drv_data);
  98. return sprintf(buf, "%d\n", drv_data->in_val[attr->index]);
  99. }
  100. static ssize_t
  101. min_show(struct device *dev, struct device_attribute *devattr, char *buf)
  102. {
  103. struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
  104. struct menf21bmc_hwmon *drv_data = dev_get_drvdata(dev);
  105. return sprintf(buf, "%d\n", drv_data->in_min[attr->index]);
  106. }
  107. static ssize_t
  108. max_show(struct device *dev, struct device_attribute *devattr, char *buf)
  109. {
  110. struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
  111. struct menf21bmc_hwmon *drv_data = dev_get_drvdata(dev);
  112. return sprintf(buf, "%d\n", drv_data->in_max[attr->index]);
  113. }
  114. static SENSOR_DEVICE_ATTR_RO(in0_input, in, 0);
  115. static SENSOR_DEVICE_ATTR_RO(in0_min, min, 0);
  116. static SENSOR_DEVICE_ATTR_RO(in0_max, max, 0);
  117. static SENSOR_DEVICE_ATTR_RO(in0_label, label, 0);
  118. static SENSOR_DEVICE_ATTR_RO(in1_input, in, 1);
  119. static SENSOR_DEVICE_ATTR_RO(in1_min, min, 1);
  120. static SENSOR_DEVICE_ATTR_RO(in1_max, max, 1);
  121. static SENSOR_DEVICE_ATTR_RO(in1_label, label, 1);
  122. static SENSOR_DEVICE_ATTR_RO(in2_input, in, 2);
  123. static SENSOR_DEVICE_ATTR_RO(in2_min, min, 2);
  124. static SENSOR_DEVICE_ATTR_RO(in2_max, max, 2);
  125. static SENSOR_DEVICE_ATTR_RO(in2_label, label, 2);
  126. static SENSOR_DEVICE_ATTR_RO(in3_input, in, 3);
  127. static SENSOR_DEVICE_ATTR_RO(in3_min, min, 3);
  128. static SENSOR_DEVICE_ATTR_RO(in3_max, max, 3);
  129. static SENSOR_DEVICE_ATTR_RO(in3_label, label, 3);
  130. static SENSOR_DEVICE_ATTR_RO(in4_input, in, 4);
  131. static SENSOR_DEVICE_ATTR_RO(in4_min, min, 4);
  132. static SENSOR_DEVICE_ATTR_RO(in4_max, max, 4);
  133. static SENSOR_DEVICE_ATTR_RO(in4_label, label, 4);
  134. static struct attribute *menf21bmc_hwmon_attrs[] = {
  135. &sensor_dev_attr_in0_input.dev_attr.attr,
  136. &sensor_dev_attr_in0_min.dev_attr.attr,
  137. &sensor_dev_attr_in0_max.dev_attr.attr,
  138. &sensor_dev_attr_in0_label.dev_attr.attr,
  139. &sensor_dev_attr_in1_input.dev_attr.attr,
  140. &sensor_dev_attr_in1_min.dev_attr.attr,
  141. &sensor_dev_attr_in1_max.dev_attr.attr,
  142. &sensor_dev_attr_in1_label.dev_attr.attr,
  143. &sensor_dev_attr_in2_input.dev_attr.attr,
  144. &sensor_dev_attr_in2_min.dev_attr.attr,
  145. &sensor_dev_attr_in2_max.dev_attr.attr,
  146. &sensor_dev_attr_in2_label.dev_attr.attr,
  147. &sensor_dev_attr_in3_input.dev_attr.attr,
  148. &sensor_dev_attr_in3_min.dev_attr.attr,
  149. &sensor_dev_attr_in3_max.dev_attr.attr,
  150. &sensor_dev_attr_in3_label.dev_attr.attr,
  151. &sensor_dev_attr_in4_input.dev_attr.attr,
  152. &sensor_dev_attr_in4_min.dev_attr.attr,
  153. &sensor_dev_attr_in4_max.dev_attr.attr,
  154. &sensor_dev_attr_in4_label.dev_attr.attr,
  155. NULL
  156. };
  157. ATTRIBUTE_GROUPS(menf21bmc_hwmon);
  158. static int menf21bmc_hwmon_probe(struct platform_device *pdev)
  159. {
  160. int ret;
  161. struct menf21bmc_hwmon *drv_data;
  162. struct i2c_client *i2c_client = to_i2c_client(pdev->dev.parent);
  163. struct device *hwmon_dev;
  164. drv_data = devm_kzalloc(&pdev->dev, sizeof(struct menf21bmc_hwmon),
  165. GFP_KERNEL);
  166. if (!drv_data)
  167. return -ENOMEM;
  168. drv_data->i2c_client = i2c_client;
  169. ret = menf21bmc_hwmon_get_volt_limits(drv_data);
  170. if (ret) {
  171. dev_err(&pdev->dev, "failed to read sensor limits");
  172. return ret;
  173. }
  174. hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev,
  175. "menf21bmc", drv_data,
  176. menf21bmc_hwmon_groups);
  177. if (IS_ERR(hwmon_dev))
  178. return PTR_ERR(hwmon_dev);
  179. dev_info(&pdev->dev, "MEN 14F021P00 BMC hwmon device enabled");
  180. return 0;
  181. }
  182. static struct platform_driver menf21bmc_hwmon = {
  183. .probe = menf21bmc_hwmon_probe,
  184. .driver = {
  185. .name = DRV_NAME,
  186. },
  187. };
  188. module_platform_driver(menf21bmc_hwmon);
  189. MODULE_AUTHOR("Andreas Werner <[email protected]>");
  190. MODULE_DESCRIPTION("MEN 14F021P00 BMC hwmon");
  191. MODULE_LICENSE("GPL v2");
  192. MODULE_ALIAS("platform:menf21bmc_hwmon");