Skip to content

Commit

Permalink
net: phy: add support for PHY LEDs polarity modes
Browse files Browse the repository at this point in the history
Add support for PHY LEDs polarity modes. Some PHY require LED to be set
to active low to be turned ON. Adds support for this by declaring
active-low property in DT.

PHY driver needs to declare .led_polarity_set() to configure LED
polarity modes. Function will pass the index with the LED index and a
bitmap with all the required modes to set.

Current supported modes are:
- active-low with the flag PHY_LED_ACTIVE_LOW. LED is set to active-low
  to turn it ON.
- inactive-high-impedance with the flag PHY_LED_INACTIVE_HIGH_IMPEDANCE.
  LED is set to high impedance to turn it OFF.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20240125203702.4552-4-ansuelsmth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Christian Marangi authored and Jakub Kicinski committed Jan 27, 2024
1 parent 355c6dc commit 7ae215e
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
16 changes: 16 additions & 0 deletions drivers/net/phy/phy_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -3097,6 +3097,7 @@ static int of_phy_led(struct phy_device *phydev,
struct device *dev = &phydev->mdio.dev;
struct led_init_data init_data = {};
struct led_classdev *cdev;
unsigned long modes = 0;
struct phy_led *phyled;
u32 index;
int err;
Expand All @@ -3114,6 +3115,21 @@ static int of_phy_led(struct phy_device *phydev,
if (index > U8_MAX)
return -EINVAL;

if (of_property_read_bool(led, "active-low"))
set_bit(PHY_LED_ACTIVE_LOW, &modes);
if (of_property_read_bool(led, "inactive-high-impedance"))
set_bit(PHY_LED_INACTIVE_HIGH_IMPEDANCE, &modes);

if (modes) {
/* Return error if asked to set polarity modes but not supported */
if (!phydev->drv->led_polarity_set)
return -EINVAL;

err = phydev->drv->led_polarity_set(phydev, index, modes);
if (err)
return err;
}

phyled->index = index;
if (phydev->drv->led_brightness_set)
cdev->brightness_set_blocking = phy_led_set_brightness;
Expand Down
22 changes: 22 additions & 0 deletions include/linux/phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,15 @@ struct phy_plca_status {
bool pst;
};

/* Modes for PHY LED configuration */
enum phy_led_modes {
PHY_LED_ACTIVE_LOW = 0,
PHY_LED_INACTIVE_HIGH_IMPEDANCE = 1,

/* keep it last */
__PHY_LED_MODES_NUM,
};

/**
* struct phy_led: An LED driven by the PHY
*
Expand Down Expand Up @@ -1145,6 +1154,19 @@ struct phy_driver {
int (*led_hw_control_get)(struct phy_device *dev, u8 index,
unsigned long *rules);

/**
* @led_polarity_set: Set the LED polarity modes
* @dev: PHY device which has the LED
* @index: Which LED of the PHY device
* @modes: bitmap of LED polarity modes
*
* Configure LED with all the required polarity modes in @modes
* to make it correctly turn ON or OFF.
*
* Returns 0, or an error code.
*/
int (*led_polarity_set)(struct phy_device *dev, int index,
unsigned long modes);
};
#define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
struct phy_driver, mdiodrv)
Expand Down

0 comments on commit 7ae215e

Please sign in to comment.