aquantia_hwmon.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* HWMON driver for Aquantia PHY
  3. *
  4. * Author: Nikita Yushchenko <[email protected]>
  5. * Author: Andrew Lunn <[email protected]>
  6. * Author: Heiner Kallweit <[email protected]>
  7. */
  8. #include <linux/phy.h>
  9. #include <linux/device.h>
  10. #include <linux/ctype.h>
  11. #include <linux/hwmon.h>
  12. #include "aquantia.h"
  13. /* Vendor specific 1, MDIO_MMD_VEND2 */
  14. #define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
  15. #define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
  16. #define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
  17. #define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
  18. #define VEND1_THERMAL_STAT1 0xc820
  19. #define VEND1_THERMAL_STAT2 0xc821
  20. #define VEND1_THERMAL_STAT2_VALID BIT(0)
  21. #define VEND1_GENERAL_STAT1 0xc830
  22. #define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
  23. #define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
  24. #define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
  25. #define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
  26. #if IS_REACHABLE(CONFIG_HWMON)
  27. static umode_t aqr_hwmon_is_visible(const void *data,
  28. enum hwmon_sensor_types type,
  29. u32 attr, int channel)
  30. {
  31. if (type != hwmon_temp)
  32. return 0;
  33. switch (attr) {
  34. case hwmon_temp_input:
  35. case hwmon_temp_min_alarm:
  36. case hwmon_temp_max_alarm:
  37. case hwmon_temp_lcrit_alarm:
  38. case hwmon_temp_crit_alarm:
  39. return 0444;
  40. case hwmon_temp_min:
  41. case hwmon_temp_max:
  42. case hwmon_temp_lcrit:
  43. case hwmon_temp_crit:
  44. return 0644;
  45. default:
  46. return 0;
  47. }
  48. }
  49. static int aqr_hwmon_get(struct phy_device *phydev, int reg, long *value)
  50. {
  51. int temp = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
  52. if (temp < 0)
  53. return temp;
  54. /* 16 bit value is 2's complement with LSB = 1/256th degree Celsius */
  55. *value = (s16)temp * 1000 / 256;
  56. return 0;
  57. }
  58. static int aqr_hwmon_set(struct phy_device *phydev, int reg, long value)
  59. {
  60. int temp;
  61. if (value >= 128000 || value < -128000)
  62. return -ERANGE;
  63. temp = value * 256 / 1000;
  64. /* temp is in s16 range and we're interested in lower 16 bits only */
  65. return phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, (u16)temp);
  66. }
  67. static int aqr_hwmon_test_bit(struct phy_device *phydev, int reg, int bit)
  68. {
  69. int val = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
  70. if (val < 0)
  71. return val;
  72. return !!(val & bit);
  73. }
  74. static int aqr_hwmon_status1(struct phy_device *phydev, int bit, long *value)
  75. {
  76. int val = aqr_hwmon_test_bit(phydev, VEND1_GENERAL_STAT1, bit);
  77. if (val < 0)
  78. return val;
  79. *value = val;
  80. return 0;
  81. }
  82. static int aqr_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
  83. u32 attr, int channel, long *value)
  84. {
  85. struct phy_device *phydev = dev_get_drvdata(dev);
  86. int reg;
  87. if (type != hwmon_temp)
  88. return -EOPNOTSUPP;
  89. switch (attr) {
  90. case hwmon_temp_input:
  91. reg = aqr_hwmon_test_bit(phydev, VEND1_THERMAL_STAT2,
  92. VEND1_THERMAL_STAT2_VALID);
  93. if (reg < 0)
  94. return reg;
  95. if (!reg)
  96. return -EBUSY;
  97. return aqr_hwmon_get(phydev, VEND1_THERMAL_STAT1, value);
  98. case hwmon_temp_lcrit:
  99. return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
  100. value);
  101. case hwmon_temp_min:
  102. return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
  103. value);
  104. case hwmon_temp_max:
  105. return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
  106. value);
  107. case hwmon_temp_crit:
  108. return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
  109. value);
  110. case hwmon_temp_lcrit_alarm:
  111. return aqr_hwmon_status1(phydev,
  112. VEND1_GENERAL_STAT1_LOW_TEMP_FAIL,
  113. value);
  114. case hwmon_temp_min_alarm:
  115. return aqr_hwmon_status1(phydev,
  116. VEND1_GENERAL_STAT1_LOW_TEMP_WARN,
  117. value);
  118. case hwmon_temp_max_alarm:
  119. return aqr_hwmon_status1(phydev,
  120. VEND1_GENERAL_STAT1_HIGH_TEMP_WARN,
  121. value);
  122. case hwmon_temp_crit_alarm:
  123. return aqr_hwmon_status1(phydev,
  124. VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL,
  125. value);
  126. default:
  127. return -EOPNOTSUPP;
  128. }
  129. }
  130. static int aqr_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
  131. u32 attr, int channel, long value)
  132. {
  133. struct phy_device *phydev = dev_get_drvdata(dev);
  134. if (type != hwmon_temp)
  135. return -EOPNOTSUPP;
  136. switch (attr) {
  137. case hwmon_temp_lcrit:
  138. return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
  139. value);
  140. case hwmon_temp_min:
  141. return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
  142. value);
  143. case hwmon_temp_max:
  144. return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
  145. value);
  146. case hwmon_temp_crit:
  147. return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
  148. value);
  149. default:
  150. return -EOPNOTSUPP;
  151. }
  152. }
  153. static const struct hwmon_ops aqr_hwmon_ops = {
  154. .is_visible = aqr_hwmon_is_visible,
  155. .read = aqr_hwmon_read,
  156. .write = aqr_hwmon_write,
  157. };
  158. static u32 aqr_hwmon_chip_config[] = {
  159. HWMON_C_REGISTER_TZ,
  160. 0,
  161. };
  162. static const struct hwmon_channel_info aqr_hwmon_chip = {
  163. .type = hwmon_chip,
  164. .config = aqr_hwmon_chip_config,
  165. };
  166. static u32 aqr_hwmon_temp_config[] = {
  167. HWMON_T_INPUT |
  168. HWMON_T_MAX | HWMON_T_MIN |
  169. HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM |
  170. HWMON_T_CRIT | HWMON_T_LCRIT |
  171. HWMON_T_CRIT_ALARM | HWMON_T_LCRIT_ALARM,
  172. 0,
  173. };
  174. static const struct hwmon_channel_info aqr_hwmon_temp = {
  175. .type = hwmon_temp,
  176. .config = aqr_hwmon_temp_config,
  177. };
  178. static const struct hwmon_channel_info *aqr_hwmon_info[] = {
  179. &aqr_hwmon_chip,
  180. &aqr_hwmon_temp,
  181. NULL,
  182. };
  183. static const struct hwmon_chip_info aqr_hwmon_chip_info = {
  184. .ops = &aqr_hwmon_ops,
  185. .info = aqr_hwmon_info,
  186. };
  187. int aqr_hwmon_probe(struct phy_device *phydev)
  188. {
  189. struct device *dev = &phydev->mdio.dev;
  190. struct device *hwmon_dev;
  191. char *hwmon_name;
  192. int i, j;
  193. hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
  194. if (!hwmon_name)
  195. return -ENOMEM;
  196. for (i = j = 0; hwmon_name[i]; i++) {
  197. if (isalnum(hwmon_name[i])) {
  198. if (i != j)
  199. hwmon_name[j] = hwmon_name[i];
  200. j++;
  201. }
  202. }
  203. hwmon_name[j] = '\0';
  204. hwmon_dev = devm_hwmon_device_register_with_info(dev, hwmon_name,
  205. phydev, &aqr_hwmon_chip_info, NULL);
  206. return PTR_ERR_OR_ZERO(hwmon_dev);
  207. }
  208. #endif