realtek_hwmon.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * HWMON support for Realtek PHY's
  4. *
  5. * Author: Heiner Kallweit <hkallweit1@gmail.com>
  6. */
  7. #include <linux/hwmon.h>
  8. #include <linux/phy.h>
  9. #include "realtek.h"
  10. #define RTL822X_VND2_TSALRM 0xa662
  11. #define RTL822X_VND2_TSRR 0xbd84
  12. #define RTL822X_VND2_TSSR 0xb54c
  13. static int rtl822x_hwmon_get_temp(int raw)
  14. {
  15. if (raw >= 512)
  16. raw -= 1024;
  17. return 1000 * raw / 2;
  18. }
  19. static int rtl822x_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
  20. u32 attr, int channel, long *val)
  21. {
  22. struct phy_device *phydev = dev_get_drvdata(dev);
  23. int raw;
  24. switch (attr) {
  25. case hwmon_temp_input:
  26. raw = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSRR) & 0x3ff;
  27. *val = rtl822x_hwmon_get_temp(raw);
  28. break;
  29. case hwmon_temp_max:
  30. /* Chip reduces speed to 1G if threshold is exceeded */
  31. raw = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSSR) >> 6;
  32. *val = rtl822x_hwmon_get_temp(raw);
  33. break;
  34. default:
  35. return -EINVAL;
  36. }
  37. return 0;
  38. }
  39. static const struct hwmon_ops rtl822x_hwmon_ops = {
  40. .visible = 0444,
  41. .read = rtl822x_hwmon_read,
  42. };
  43. static const struct hwmon_channel_info * const rtl822x_hwmon_info[] = {
  44. HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX),
  45. NULL
  46. };
  47. static const struct hwmon_chip_info rtl822x_hwmon_chip_info = {
  48. .ops = &rtl822x_hwmon_ops,
  49. .info = rtl822x_hwmon_info,
  50. };
  51. int rtl822x_hwmon_init(struct phy_device *phydev)
  52. {
  53. struct device *hwdev, *dev = &phydev->mdio.dev;
  54. /* Ensure over-temp alarm is reset. */
  55. phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSALRM, 3);
  56. hwdev = devm_hwmon_device_register_with_info(dev, NULL, phydev,
  57. &rtl822x_hwmon_chip_info,
  58. NULL);
  59. return PTR_ERR_OR_ZERO(hwdev);
  60. }