mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 18:51:21 +02:00
Merge branch 'net-phy-realtek-add-hwmon-support'
Heiner Kallweit says: ==================== net: phy: realtek: add hwmon support This adds hwmon support for the temperature sensor on RTL822x. It's available on the standalone versions of the PHY's, and on the internal PHY's of RTL8125B(P)/RTL8125D/RTL8126. ==================== Link: https://patch.msgid.link/7319d8f9-2d6f-4522-92e8-a8a4990042fb@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
7211672004
|
|
@ -350,10 +350,7 @@ config QSEMI_PHY
|
|||
help
|
||||
Currently supports the qs6612
|
||||
|
||||
config REALTEK_PHY
|
||||
tristate "Realtek PHYs"
|
||||
help
|
||||
Supports the Realtek 821x PHY.
|
||||
source "drivers/net/phy/realtek/Kconfig"
|
||||
|
||||
config RENESAS_PHY
|
||||
tristate "Renesas PHYs"
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ obj-$(CONFIG_NXP_CBTX_PHY) += nxp-cbtx.o
|
|||
obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o
|
||||
obj-y += qcom/
|
||||
obj-$(CONFIG_QSEMI_PHY) += qsemi.o
|
||||
obj-$(CONFIG_REALTEK_PHY) += realtek.o
|
||||
obj-$(CONFIG_REALTEK_PHY) += realtek/
|
||||
obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
|
||||
obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
|
||||
obj-$(CONFIG_SMSC_PHY) += smsc.o
|
||||
|
|
|
|||
11
drivers/net/phy/realtek/Kconfig
Normal file
11
drivers/net/phy/realtek/Kconfig
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config REALTEK_PHY
|
||||
tristate "Realtek PHYs"
|
||||
help
|
||||
Currently supports RTL821x/RTL822x and fast ethernet PHYs
|
||||
|
||||
config REALTEK_PHY_HWMON
|
||||
def_bool REALTEK_PHY && HWMON
|
||||
depends on !(REALTEK_PHY=y && HWMON=m)
|
||||
help
|
||||
Optional hwmon support for the temperature sensor
|
||||
4
drivers/net/phy/realtek/Makefile
Normal file
4
drivers/net/phy/realtek/Makefile
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
realtek-y += realtek_main.o
|
||||
realtek-$(CONFIG_REALTEK_PHY_HWMON) += realtek_hwmon.o
|
||||
obj-$(CONFIG_REALTEK_PHY) += realtek.o
|
||||
10
drivers/net/phy/realtek/realtek.h
Normal file
10
drivers/net/phy/realtek/realtek.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef REALTEK_H
|
||||
#define REALTEK_H
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int rtl822x_hwmon_init(struct phy_device *phydev);
|
||||
|
||||
#endif /* REALTEK_H */
|
||||
79
drivers/net/phy/realtek/realtek_hwmon.c
Normal file
79
drivers/net/phy/realtek/realtek_hwmon.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* HWMON support for Realtek PHY's
|
||||
*
|
||||
* Author: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
#include "realtek.h"
|
||||
|
||||
#define RTL822X_VND2_TSALRM 0xa662
|
||||
#define RTL822X_VND2_TSRR 0xbd84
|
||||
#define RTL822X_VND2_TSSR 0xb54c
|
||||
|
||||
static int rtl822x_hwmon_get_temp(int raw)
|
||||
{
|
||||
if (raw >= 512)
|
||||
raw -= 1024;
|
||||
|
||||
return 1000 * raw / 2;
|
||||
}
|
||||
|
||||
static int rtl822x_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
|
||||
u32 attr, int channel, long *val)
|
||||
{
|
||||
struct phy_device *phydev = dev_get_drvdata(dev);
|
||||
int raw;
|
||||
|
||||
switch (attr) {
|
||||
case hwmon_temp_input:
|
||||
raw = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSRR) & 0x3ff;
|
||||
*val = rtl822x_hwmon_get_temp(raw);
|
||||
break;
|
||||
case hwmon_temp_max:
|
||||
/* Chip reduces speed to 1G if threshold is exceeded */
|
||||
raw = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSSR) >> 6;
|
||||
*val = rtl822x_hwmon_get_temp(raw);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hwmon_ops rtl822x_hwmon_ops = {
|
||||
.visible = 0444,
|
||||
.read = rtl822x_hwmon_read,
|
||||
};
|
||||
|
||||
static const struct hwmon_channel_info * const rtl822x_hwmon_info[] = {
|
||||
HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct hwmon_chip_info rtl822x_hwmon_chip_info = {
|
||||
.ops = &rtl822x_hwmon_ops,
|
||||
.info = rtl822x_hwmon_info,
|
||||
};
|
||||
|
||||
int rtl822x_hwmon_init(struct phy_device *phydev)
|
||||
{
|
||||
struct device *hwdev, *dev = &phydev->mdio.dev;
|
||||
const char *name;
|
||||
|
||||
/* Ensure over-temp alarm is reset. */
|
||||
phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSALRM, 3);
|
||||
|
||||
name = devm_hwmon_sanitize_name(dev, dev_name(dev));
|
||||
if (IS_ERR(name))
|
||||
return PTR_ERR(name);
|
||||
|
||||
hwdev = devm_hwmon_device_register_with_info(dev, name, phydev,
|
||||
&rtl822x_hwmon_chip_info,
|
||||
NULL);
|
||||
return PTR_ERR_OR_ZERO(hwdev);
|
||||
}
|
||||
|
|
@ -14,6 +14,8 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include "realtek.h"
|
||||
|
||||
#define RTL821x_PHYSR 0x11
|
||||
#define RTL821x_PHYSR_DUPLEX BIT(13)
|
||||
#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
|
||||
|
|
@ -736,7 +738,11 @@ static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
|
||||
if (devnum == MDIO_MMD_VEND2) {
|
||||
rtl821x_write_page(phydev, regnum >> 4);
|
||||
ret = __phy_read(phydev, 0x10 + ((regnum & 0xf) >> 1));
|
||||
rtl821x_write_page(phydev, 0);
|
||||
} else if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
|
||||
rtl821x_write_page(phydev, 0xa5c);
|
||||
ret = __phy_read(phydev, 0x12);
|
||||
rtl821x_write_page(phydev, 0);
|
||||
|
|
@ -760,7 +766,11 @@ static int rtlgen_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
|
||||
if (devnum == MDIO_MMD_VEND2) {
|
||||
rtl821x_write_page(phydev, regnum >> 4);
|
||||
ret = __phy_write(phydev, 0x10 + ((regnum & 0xf) >> 1), val);
|
||||
rtl821x_write_page(phydev, 0);
|
||||
} else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
|
||||
rtl821x_write_page(phydev, 0xa5d);
|
||||
ret = __phy_write(phydev, 0x10, val);
|
||||
rtl821x_write_page(phydev, 0);
|
||||
|
|
@ -812,6 +822,15 @@ static int rtl822x_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int rtl822x_probe(struct phy_device *phydev)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_REALTEK_PHY_HWMON) &&
|
||||
phydev->phy_id != RTL_GENERIC_PHYID)
|
||||
return rtl822x_hwmon_init(phydev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl822xb_config_init(struct phy_device *phydev)
|
||||
{
|
||||
bool has_2500, has_sgmii;
|
||||
|
|
@ -1511,6 +1530,7 @@ static struct phy_driver realtek_drvs[] = {
|
|||
.match_phy_device = rtl_internal_nbaset_match_phy_device,
|
||||
.name = "Realtek Internal NBASE-T PHY",
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.read_status = rtl822x_read_status,
|
||||
Loading…
Reference in New Issue
Block a user