diff options
| author | Daniel Golle <daniel@makrotopia.org> | 2025-08-22 18:38:27 +0100 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-08-25 17:07:01 -0700 |
| commit | 29c10aeb316072aacb9ef4d0ebd6e0c9b0461ed3 (patch) | |
| tree | f1e55856b94da8b2f78e25924b4ff67f64f65a55 | |
| parent | b8844aab519a154808dbce15a132f3e8f1c34af6 (diff) | |
net: phy: mxl-86110: add basic support for led_brightness_set op
Add support for forcing each connected LED to be always on or always off
by implementing the led_brightness_set() op.
This is done by modifying the COM_EXT_LED_GEN_CFG register to enable
force-mode and forcing the LED either on or off.
When calling the led_hw_control_set() force-mode is again disabled for
that LED.
Implement mxl86110_modify_extended_reg() locked helper instead of
manually acquiring and releasing the MDIO bus lock for single
__mxl86110_modify_extended_reg() calls.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/58eeefc8c24e06cd2110d3cefbd4236b1a4f44a2.1755884175.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | drivers/net/phy/mxl-86110.c | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/drivers/net/phy/mxl-86110.c b/drivers/net/phy/mxl-86110.c index ff2a3a22bd5b..9ef2a8d7f514 100644 --- a/drivers/net/phy/mxl-86110.c +++ b/drivers/net/phy/mxl-86110.c @@ -71,6 +71,11 @@ #define MXL86110_MAX_LEDS 3 /* LED registers and defines */ +#define MXL86110_COM_EXT_LED_GEN_CFG 0xA00B +# define MXL86110_COM_EXT_LED_GEN_CFG_LFM(x) ((BIT(0) | BIT(1)) << (3 * (x))) +# define MXL86110_COM_EXT_LED_GEN_CFG_LFME(x) (BIT(0) << (3 * (x))) +# define MXL86110_COM_EXT_LED_GEN_CFG_LFE(x) (BIT(2) << (3 * (x))) + #define MXL86110_LED0_CFG_REG 0xA00C #define MXL86110_LED1_CFG_REG 0xA00D #define MXL86110_LED2_CFG_REG 0xA00E @@ -236,6 +241,29 @@ static int mxl86110_read_extended_reg(struct phy_device *phydev, u16 regnum) } /** + * mxl86110_modify_extended_reg() - modify bits of a PHY's extended register + * @phydev: pointer to the PHY device structure + * @regnum: register number to write + * @mask: bit mask of bits to clear + * @set: bit mask of bits to set + * + * Note: register value = (old register value & ~mask) | set. + * + * Return: 0 or negative error code + */ +static int mxl86110_modify_extended_reg(struct phy_device *phydev, + u16 regnum, u16 mask, u16 set) +{ + int ret; + + phy_lock_mdio_bus(phydev); + ret = __mxl86110_modify_extended_reg(phydev, regnum, mask, set); + phy_unlock_mdio_bus(phydev); + + return ret; +} + +/** * mxl86110_get_wol() - report if wake-on-lan is enabled * @phydev: pointer to the phy_device * @wol: a pointer to a &struct ethtool_wolinfo @@ -394,6 +422,7 @@ static int mxl86110_led_hw_control_set(struct phy_device *phydev, u8 index, unsigned long rules) { u16 val = 0; + int ret; if (index >= MXL86110_MAX_LEDS) return -EINVAL; @@ -423,8 +452,43 @@ static int mxl86110_led_hw_control_set(struct phy_device *phydev, u8 index, rules & BIT(TRIGGER_NETDEV_RX)) val |= MXL86110_LEDX_CFG_BLINK; - return mxl86110_write_extended_reg(phydev, + ret = mxl86110_write_extended_reg(phydev, MXL86110_LED0_CFG_REG + index, val); + if (ret) + return ret; + + /* clear manual control bit */ + ret = mxl86110_modify_extended_reg(phydev, + MXL86110_COM_EXT_LED_GEN_CFG, + MXL86110_COM_EXT_LED_GEN_CFG_LFE(index), + 0); + + return ret; +} + +static int mxl86110_led_brightness_set(struct phy_device *phydev, + u8 index, enum led_brightness value) +{ + u16 mask, set; + int ret; + + if (index >= MXL86110_MAX_LEDS) + return -EINVAL; + + /* force manual control */ + set = MXL86110_COM_EXT_LED_GEN_CFG_LFE(index); + /* clear previous force mode */ + mask = MXL86110_COM_EXT_LED_GEN_CFG_LFM(index); + + /* force LED to be permanently on */ + if (value != LED_OFF) + set |= MXL86110_COM_EXT_LED_GEN_CFG_LFME(index); + + ret = mxl86110_modify_extended_reg(phydev, + MXL86110_COM_EXT_LED_GEN_CFG, + mask, set); + + return ret; } /** @@ -596,6 +660,7 @@ static struct phy_driver mxl_phy_drvs[] = { .config_init = mxl86110_config_init, .get_wol = mxl86110_get_wol, .set_wol = mxl86110_set_wol, + .led_brightness_set = mxl86110_led_brightness_set, .led_hw_is_supported = mxl86110_led_hw_is_supported, .led_hw_control_get = mxl86110_led_hw_control_get, .led_hw_control_set = mxl86110_led_hw_control_set, |
