r8169: add support for the temperature sensor being available from RTL8125B
authorHeiner Kallweit <hkallweit1@gmail.com>
Mon, 7 Oct 2024 18:34:12 +0000 (20:34 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 9 Oct 2024 12:38:19 +0000 (13:38 +0100)
This adds support for the temperature sensor being available from
RTL8125B. Register information was taken from r8125 vendor driver.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/realtek/r8169_main.c

index 0cc9baaecb1bcbd352a46252802799c3665c432c..c506ffc1c019da947f48cb9bdeca2b712b5f6724 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
+#include <linux/hwmon.h>
 #include <linux/phy.h>
 #include <linux/if_vlan.h>
 #include <linux/in.h>
@@ -5363,6 +5364,43 @@ static bool rtl_aspm_is_safe(struct rtl8169_private *tp)
        return false;
 }
 
+static umode_t r8169_hwmon_is_visible(const void *drvdata,
+                                     enum hwmon_sensor_types type,
+                                     u32 attr, int channel)
+{
+       return 0444;
+}
+
+static int r8169_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+                           u32 attr, int channel, long *val)
+{
+       struct rtl8169_private *tp = dev_get_drvdata(dev);
+       int val_raw;
+
+       val_raw = phy_read_paged(tp->phydev, 0xbd8, 0x12) & 0x3ff;
+       if (val_raw >= 512)
+               val_raw -= 1024;
+
+       *val = 1000 * val_raw / 2;
+
+       return 0;
+}
+
+static const struct hwmon_ops r8169_hwmon_ops = {
+       .is_visible =  r8169_hwmon_is_visible,
+       .read = r8169_hwmon_read,
+};
+
+static const struct hwmon_channel_info * const r8169_hwmon_info[] = {
+       HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
+       NULL
+};
+
+static const struct hwmon_chip_info r8169_hwmon_chip_info = {
+       .ops = &r8169_hwmon_ops,
+       .info = r8169_hwmon_info,
+};
+
 static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        struct rtl8169_private *tp;
@@ -5537,6 +5575,12 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                return rc;
 
+       /* The temperature sensor is available from RTl8125B */
+       if (IS_REACHABLE(CONFIG_HWMON) && tp->mac_version >= RTL_GIGA_MAC_VER_63)
+               /* ignore errors */
+               devm_hwmon_device_register_with_info(&pdev->dev, "nic_temp", tp,
+                                                    &r8169_hwmon_chip_info,
+                                                    NULL);
        rc = register_netdev(dev);
        if (rc)
                return rc;