Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: phy: add support for PHY LEDs polarity modes

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>

authored by

Christian Marangi and committed by
Jakub Kicinski
7ae215ee 355c6dc3

+38
+16
drivers/net/phy/phy_device.c
··· 3097 3097 struct device *dev = &phydev->mdio.dev; 3098 3098 struct led_init_data init_data = {}; 3099 3099 struct led_classdev *cdev; 3100 + unsigned long modes = 0; 3100 3101 struct phy_led *phyled; 3101 3102 u32 index; 3102 3103 int err; ··· 3114 3113 return err; 3115 3114 if (index > U8_MAX) 3116 3115 return -EINVAL; 3116 + 3117 + if (of_property_read_bool(led, "active-low")) 3118 + set_bit(PHY_LED_ACTIVE_LOW, &modes); 3119 + if (of_property_read_bool(led, "inactive-high-impedance")) 3120 + set_bit(PHY_LED_INACTIVE_HIGH_IMPEDANCE, &modes); 3121 + 3122 + if (modes) { 3123 + /* Return error if asked to set polarity modes but not supported */ 3124 + if (!phydev->drv->led_polarity_set) 3125 + return -EINVAL; 3126 + 3127 + err = phydev->drv->led_polarity_set(phydev, index, modes); 3128 + if (err) 3129 + return err; 3130 + } 3117 3131 3118 3132 phyled->index = index; 3119 3133 if (phydev->drv->led_brightness_set)
+22
include/linux/phy.h
··· 852 852 bool pst; 853 853 }; 854 854 855 + /* Modes for PHY LED configuration */ 856 + enum phy_led_modes { 857 + PHY_LED_ACTIVE_LOW = 0, 858 + PHY_LED_INACTIVE_HIGH_IMPEDANCE = 1, 859 + 860 + /* keep it last */ 861 + __PHY_LED_MODES_NUM, 862 + }; 863 + 855 864 /** 856 865 * struct phy_led: An LED driven by the PHY 857 866 * ··· 1154 1145 int (*led_hw_control_get)(struct phy_device *dev, u8 index, 1155 1146 unsigned long *rules); 1156 1147 1148 + /** 1149 + * @led_polarity_set: Set the LED polarity modes 1150 + * @dev: PHY device which has the LED 1151 + * @index: Which LED of the PHY device 1152 + * @modes: bitmap of LED polarity modes 1153 + * 1154 + * Configure LED with all the required polarity modes in @modes 1155 + * to make it correctly turn ON or OFF. 1156 + * 1157 + * Returns 0, or an error code. 1158 + */ 1159 + int (*led_polarity_set)(struct phy_device *dev, int index, 1160 + unsigned long modes); 1157 1161 }; 1158 1162 #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ 1159 1163 struct phy_driver, mdiodrv)