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

Configure Feed

Select the types of activity you want to include in your feed.

net: phy: dp83td510: introduce LED framework support

Add LED brightness, mode, HW control and polarity functions to enable
external LED control in the TI DP83TD510 PHY.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Link: https://patch.msgid.link/20250205103846.2273833-1-o.rempel@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Oleksij Rempel and committed by
Jakub Kicinski
5b281fe7 39f54262

+187
+187
drivers/net/phy/dp83td510.c
··· 204 204 #define DP83TD510E_UNKN_030E 0x30e 205 205 #define DP83TD510E_030E_VAL 0x2520 206 206 207 + #define DP83TD510E_LEDS_CFG_1 0x460 208 + #define DP83TD510E_LED_FN(idx, val) (((val) & 0xf) << ((idx) * 4)) 209 + #define DP83TD510E_LED_FN_MASK(idx) (0xf << ((idx) * 4)) 210 + /* link OK */ 211 + #define DP83TD510E_LED_MODE_LINK_OK 0x0 212 + /* TX/RX activity */ 213 + #define DP83TD510E_LED_MODE_TX_RX_ACTIVITY 0x1 214 + /* TX activity */ 215 + #define DP83TD510E_LED_MODE_TX_ACTIVITY 0x2 216 + /* RX activity */ 217 + #define DP83TD510E_LED_MODE_RX_ACTIVITY 0x3 218 + /* LR */ 219 + #define DP83TD510E_LED_MODE_LR 0x4 220 + /* SR */ 221 + #define DP83TD510E_LED_MODE_SR 0x5 222 + /* LED SPEED: High for 10Base-T */ 223 + #define DP83TD510E_LED_MODE_LED_SPEED 0x6 224 + /* Duplex mode */ 225 + #define DP83TD510E_LED_MODE_DUPLEX 0x7 226 + /* link + blink on activity with stretch option */ 227 + #define DP83TD510E_LED_MODE_LINK_BLINK 0x8 228 + /* blink on activity with stretch option */ 229 + #define DP83TD510E_LED_MODE_BLINK_ACTIVITY 0x9 230 + /* blink on tx activity with stretch option */ 231 + #define DP83TD510E_LED_MODE_BLINK_TX 0xa 232 + /* blink on rx activity with stretch option */ 233 + #define DP83TD510E_LED_MODE_BLINK_RX 0xb 234 + /* link_lost */ 235 + #define DP83TD510E_LED_MODE_LINK_LOST 0xc 236 + /* PRBS error: toggles on error */ 237 + #define DP83TD510E_LED_MODE_PRBS_ERROR 0xd 238 + /* XMII TX/RX Error with stretch option */ 239 + #define DP83TD510E_LED_MODE_XMII_ERR 0xe 240 + 241 + #define DP83TD510E_LED_COUNT 4 242 + 243 + #define DP83TD510E_LEDS_CFG_2 0x469 244 + #define DP83TD510E_LED_POLARITY(idx) BIT((idx) * 4 + 2) 245 + #define DP83TD510E_LED_DRV_VAL(idx) BIT((idx) * 4 + 1) 246 + #define DP83TD510E_LED_DRV_EN(idx) BIT((idx) * 4) 247 + 207 248 #define DP83TD510E_ALCD_STAT 0xa9f 208 249 #define DP83TD510E_ALCD_COMPLETE BIT(15) 209 250 #define DP83TD510E_ALCD_CABLE_LENGTH GENMASK(10, 0) 251 + 252 + static int dp83td510_led_brightness_set(struct phy_device *phydev, u8 index, 253 + enum led_brightness brightness) 254 + { 255 + u32 val; 256 + 257 + if (index >= DP83TD510E_LED_COUNT) 258 + return -EINVAL; 259 + 260 + val = DP83TD510E_LED_DRV_EN(index); 261 + 262 + if (brightness) 263 + val |= DP83TD510E_LED_DRV_VAL(index); 264 + 265 + return phy_modify_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_LEDS_CFG_2, 266 + DP83TD510E_LED_DRV_VAL(index) | 267 + DP83TD510E_LED_DRV_EN(index), val); 268 + } 269 + 270 + static int dp83td510_led_mode(u8 index, unsigned long rules) 271 + { 272 + if (index >= DP83TD510E_LED_COUNT) 273 + return -EINVAL; 274 + 275 + switch (rules) { 276 + case BIT(TRIGGER_NETDEV_LINK): 277 + return DP83TD510E_LED_MODE_LINK_OK; 278 + case BIT(TRIGGER_NETDEV_LINK_10): 279 + return DP83TD510E_LED_MODE_LED_SPEED; 280 + case BIT(TRIGGER_NETDEV_FULL_DUPLEX): 281 + return DP83TD510E_LED_MODE_DUPLEX; 282 + case BIT(TRIGGER_NETDEV_TX): 283 + return DP83TD510E_LED_MODE_TX_ACTIVITY; 284 + case BIT(TRIGGER_NETDEV_RX): 285 + return DP83TD510E_LED_MODE_RX_ACTIVITY; 286 + case BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX): 287 + return DP83TD510E_LED_MODE_TX_RX_ACTIVITY; 288 + case BIT(TRIGGER_NETDEV_LINK) | BIT(TRIGGER_NETDEV_TX) | 289 + BIT(TRIGGER_NETDEV_RX): 290 + return DP83TD510E_LED_MODE_LINK_BLINK; 291 + default: 292 + return -EOPNOTSUPP; 293 + } 294 + } 295 + 296 + static int dp83td510_led_hw_is_supported(struct phy_device *phydev, u8 index, 297 + unsigned long rules) 298 + { 299 + int ret; 300 + 301 + ret = dp83td510_led_mode(index, rules); 302 + if (ret < 0) 303 + return ret; 304 + 305 + return 0; 306 + } 307 + 308 + static int dp83td510_led_hw_control_set(struct phy_device *phydev, u8 index, 309 + unsigned long rules) 310 + { 311 + int mode, ret; 312 + 313 + mode = dp83td510_led_mode(index, rules); 314 + if (mode < 0) 315 + return mode; 316 + 317 + ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_LEDS_CFG_1, 318 + DP83TD510E_LED_FN_MASK(index), 319 + DP83TD510E_LED_FN(index, mode)); 320 + if (ret) 321 + return ret; 322 + 323 + return phy_modify_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_LEDS_CFG_2, 324 + DP83TD510E_LED_DRV_EN(index), 0); 325 + } 326 + 327 + static int dp83td510_led_hw_control_get(struct phy_device *phydev, 328 + u8 index, unsigned long *rules) 329 + { 330 + int val; 331 + 332 + val = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_LEDS_CFG_1); 333 + if (val < 0) 334 + return val; 335 + 336 + val &= DP83TD510E_LED_FN_MASK(index); 337 + val >>= index * 4; 338 + 339 + switch (val) { 340 + case DP83TD510E_LED_MODE_LINK_OK: 341 + *rules = BIT(TRIGGER_NETDEV_LINK); 342 + break; 343 + /* LED mode: LED SPEED (10BaseT1L indicator) */ 344 + case DP83TD510E_LED_MODE_LED_SPEED: 345 + *rules = BIT(TRIGGER_NETDEV_LINK_10); 346 + break; 347 + case DP83TD510E_LED_MODE_DUPLEX: 348 + *rules = BIT(TRIGGER_NETDEV_FULL_DUPLEX); 349 + break; 350 + case DP83TD510E_LED_MODE_TX_ACTIVITY: 351 + *rules = BIT(TRIGGER_NETDEV_TX); 352 + break; 353 + case DP83TD510E_LED_MODE_RX_ACTIVITY: 354 + *rules = BIT(TRIGGER_NETDEV_RX); 355 + break; 356 + case DP83TD510E_LED_MODE_TX_RX_ACTIVITY: 357 + *rules = BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX); 358 + break; 359 + case DP83TD510E_LED_MODE_LINK_BLINK: 360 + *rules = BIT(TRIGGER_NETDEV_LINK) | 361 + BIT(TRIGGER_NETDEV_TX) | 362 + BIT(TRIGGER_NETDEV_RX); 363 + break; 364 + default: 365 + *rules = 0; 366 + break; 367 + } 368 + 369 + return 0; 370 + } 371 + 372 + static int dp83td510_led_polarity_set(struct phy_device *phydev, int index, 373 + unsigned long modes) 374 + { 375 + u16 polarity = DP83TD510E_LED_POLARITY(index); 376 + u32 mode; 377 + 378 + for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { 379 + switch (mode) { 380 + case PHY_LED_ACTIVE_LOW: 381 + polarity = 0; 382 + break; 383 + default: 384 + return -EINVAL; 385 + } 386 + } 387 + 388 + return phy_modify_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_LEDS_CFG_2, 389 + DP83TD510E_LED_POLARITY(index), polarity); 390 + } 210 391 211 392 /** 212 393 * dp83td510_update_stats - Update the PHY statistics for the DP83TD510 PHY. ··· 892 711 .cable_test_get_status = dp83td510_cable_test_get_status, 893 712 .get_phy_stats = dp83td510_get_phy_stats, 894 713 .update_stats = dp83td510_update_stats, 714 + 715 + .led_brightness_set = dp83td510_led_brightness_set, 716 + .led_hw_is_supported = dp83td510_led_hw_is_supported, 717 + .led_hw_control_set = dp83td510_led_hw_control_set, 718 + .led_hw_control_get = dp83td510_led_hw_control_get, 719 + .led_polarity_set = dp83td510_led_polarity_set, 895 720 896 721 .suspend = genphy_suspend, 897 722 .resume = genphy_resume,