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: intel-xway: add support for PHY LEDs

The intel-xway PHY driver predates the PHY LED framework and currently
initializes all LED pins to equal default values.

Add PHY LED functions to the drivers and don't set default values if
LEDs are defined in device tree.

According the datasheets 3 LEDs are supported on all Intel XWAY PHYs.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/81f4717ab9acf38f3239727a4540ae96fd01109b.1728558223.git.daniel@makrotopia.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Daniel Golle and committed by
Paolo Abeni
1758af47 eb89c79c

+244 -9
+244 -9
drivers/net/phy/intel-xway.c
··· 151 151 #define XWAY_MMD_LED3H 0x01E8 152 152 #define XWAY_MMD_LED3L 0x01E9 153 153 154 + #define XWAY_GPHY_MAX_LEDS 3 155 + #define XWAY_GPHY_LED_INV(idx) BIT(12 + (idx)) 156 + #define XWAY_GPHY_LED_EN(idx) BIT(8 + (idx)) 157 + #define XWAY_GPHY_LED_DA(idx) BIT(idx) 158 + #define XWAY_MMD_LEDxH(idx) (XWAY_MMD_LED0H + 2 * (idx)) 159 + #define XWAY_MMD_LEDxL(idx) (XWAY_MMD_LED0L + 2 * (idx)) 160 + 154 161 #define PHY_ID_PHY11G_1_3 0x030260D1 155 162 #define PHY_ID_PHY22F_1_3 0x030260E1 156 163 #define PHY_ID_PHY11G_1_4 0xD565A400 ··· 236 229 XWAY_MDIO_MIICTRL_TXSKEW_MASK, val); 237 230 } 238 231 239 - static int xway_gphy_config_init(struct phy_device *phydev) 232 + static int xway_gphy_init_leds(struct phy_device *phydev) 240 233 { 241 234 int err; 242 235 u32 ledxh; 243 236 u32 ledxl; 244 - 245 - /* Mask all interrupts */ 246 - err = phy_write(phydev, XWAY_MDIO_IMASK, 0); 247 - if (err) 248 - return err; 249 - 250 - /* Clear all pending interrupts */ 251 - phy_read(phydev, XWAY_MDIO_ISTAT); 252 237 253 238 /* Ensure that integrated led function is enabled for all leds */ 254 239 err = phy_write(phydev, XWAY_MDIO_LED, ··· 274 275 phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1L, ledxl); 275 276 phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2H, ledxh); 276 277 phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2L, ledxl); 278 + 279 + return 0; 280 + } 281 + 282 + static int xway_gphy_config_init(struct phy_device *phydev) 283 + { 284 + struct device_node *np = phydev->mdio.dev.of_node; 285 + int err; 286 + 287 + /* Mask all interrupts */ 288 + err = phy_write(phydev, XWAY_MDIO_IMASK, 0); 289 + if (err) 290 + return err; 291 + 292 + /* Use default LED configuration if 'leds' node isn't defined */ 293 + if (!of_get_child_by_name(np, "leds")) 294 + xway_gphy_init_leds(phydev); 295 + 296 + /* Clear all pending interrupts */ 297 + phy_read(phydev, XWAY_MDIO_ISTAT); 277 298 278 299 err = xway_gphy_rgmii_init(phydev); 279 300 if (err) ··· 366 347 return IRQ_HANDLED; 367 348 } 368 349 350 + static int xway_gphy_led_brightness_set(struct phy_device *phydev, 351 + u8 index, enum led_brightness value) 352 + { 353 + int ret; 354 + 355 + if (index >= XWAY_GPHY_MAX_LEDS) 356 + return -EINVAL; 357 + 358 + /* clear EN and set manual LED state */ 359 + ret = phy_modify(phydev, XWAY_MDIO_LED, 360 + ((value == LED_OFF) ? XWAY_GPHY_LED_EN(index) : 0) | 361 + XWAY_GPHY_LED_DA(index), 362 + (value == LED_OFF) ? 0 : XWAY_GPHY_LED_DA(index)); 363 + if (ret) 364 + return ret; 365 + 366 + /* clear HW LED setup */ 367 + if (value == LED_OFF) { 368 + ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxH(index), 0); 369 + if (ret) 370 + return ret; 371 + 372 + return phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxL(index), 0); 373 + } else { 374 + return 0; 375 + } 376 + } 377 + 378 + static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_LINK) | 379 + BIT(TRIGGER_NETDEV_LINK_10) | 380 + BIT(TRIGGER_NETDEV_LINK_100) | 381 + BIT(TRIGGER_NETDEV_LINK_1000) | 382 + BIT(TRIGGER_NETDEV_RX) | 383 + BIT(TRIGGER_NETDEV_TX)); 384 + 385 + static int xway_gphy_led_hw_is_supported(struct phy_device *phydev, u8 index, 386 + unsigned long rules) 387 + { 388 + if (index >= XWAY_GPHY_MAX_LEDS) 389 + return -EINVAL; 390 + 391 + /* activity triggers are not possible without combination with a link 392 + * trigger. 393 + */ 394 + if (rules & (BIT(TRIGGER_NETDEV_RX) | BIT(TRIGGER_NETDEV_TX)) && 395 + !(rules & (BIT(TRIGGER_NETDEV_LINK) | 396 + BIT(TRIGGER_NETDEV_LINK_10) | 397 + BIT(TRIGGER_NETDEV_LINK_100) | 398 + BIT(TRIGGER_NETDEV_LINK_1000)))) 399 + return -EOPNOTSUPP; 400 + 401 + /* All other combinations of the supported triggers are allowed */ 402 + if (rules & ~supported_triggers) 403 + return -EOPNOTSUPP; 404 + 405 + return 0; 406 + } 407 + 408 + static int xway_gphy_led_hw_control_get(struct phy_device *phydev, u8 index, 409 + unsigned long *rules) 410 + { 411 + int lval, hval; 412 + 413 + if (index >= XWAY_GPHY_MAX_LEDS) 414 + return -EINVAL; 415 + 416 + hval = phy_read_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxH(index)); 417 + if (hval < 0) 418 + return hval; 419 + 420 + lval = phy_read_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxL(index)); 421 + if (lval < 0) 422 + return lval; 423 + 424 + if (hval & XWAY_MMD_LEDxH_CON_LINK10) 425 + *rules |= BIT(TRIGGER_NETDEV_LINK_10); 426 + 427 + if (hval & XWAY_MMD_LEDxH_CON_LINK100) 428 + *rules |= BIT(TRIGGER_NETDEV_LINK_100); 429 + 430 + if (hval & XWAY_MMD_LEDxH_CON_LINK1000) 431 + *rules |= BIT(TRIGGER_NETDEV_LINK_1000); 432 + 433 + if ((hval & XWAY_MMD_LEDxH_CON_LINK10) && 434 + (hval & XWAY_MMD_LEDxH_CON_LINK100) && 435 + (hval & XWAY_MMD_LEDxH_CON_LINK1000)) 436 + *rules |= BIT(TRIGGER_NETDEV_LINK); 437 + 438 + if (lval & XWAY_MMD_LEDxL_PULSE_TXACT) 439 + *rules |= BIT(TRIGGER_NETDEV_TX); 440 + 441 + if (lval & XWAY_MMD_LEDxL_PULSE_RXACT) 442 + *rules |= BIT(TRIGGER_NETDEV_RX); 443 + 444 + return 0; 445 + } 446 + 447 + static int xway_gphy_led_hw_control_set(struct phy_device *phydev, u8 index, 448 + unsigned long rules) 449 + { 450 + u16 hval = 0, lval = 0; 451 + int ret; 452 + 453 + if (index >= XWAY_GPHY_MAX_LEDS) 454 + return -EINVAL; 455 + 456 + if (rules & BIT(TRIGGER_NETDEV_LINK) || 457 + rules & BIT(TRIGGER_NETDEV_LINK_10)) 458 + hval |= XWAY_MMD_LEDxH_CON_LINK10; 459 + 460 + if (rules & BIT(TRIGGER_NETDEV_LINK) || 461 + rules & BIT(TRIGGER_NETDEV_LINK_100)) 462 + hval |= XWAY_MMD_LEDxH_CON_LINK100; 463 + 464 + if (rules & BIT(TRIGGER_NETDEV_LINK) || 465 + rules & BIT(TRIGGER_NETDEV_LINK_1000)) 466 + hval |= XWAY_MMD_LEDxH_CON_LINK1000; 467 + 468 + if (rules & BIT(TRIGGER_NETDEV_TX)) 469 + lval |= XWAY_MMD_LEDxL_PULSE_TXACT; 470 + 471 + if (rules & BIT(TRIGGER_NETDEV_RX)) 472 + lval |= XWAY_MMD_LEDxL_PULSE_RXACT; 473 + 474 + ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxH(index), hval); 475 + if (ret) 476 + return ret; 477 + 478 + ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxL(index), lval); 479 + if (ret) 480 + return ret; 481 + 482 + return phy_set_bits(phydev, XWAY_MDIO_LED, XWAY_GPHY_LED_EN(index)); 483 + } 484 + 485 + static int xway_gphy_led_polarity_set(struct phy_device *phydev, int index, 486 + unsigned long modes) 487 + { 488 + bool force_active_low = false, force_active_high = false; 489 + u32 mode; 490 + 491 + if (index >= XWAY_GPHY_MAX_LEDS) 492 + return -EINVAL; 493 + 494 + for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { 495 + switch (mode) { 496 + case PHY_LED_ACTIVE_LOW: 497 + force_active_low = true; 498 + break; 499 + case PHY_LED_ACTIVE_HIGH: 500 + force_active_high = true; 501 + break; 502 + default: 503 + return -EINVAL; 504 + } 505 + } 506 + 507 + if (force_active_low) 508 + return phy_set_bits(phydev, XWAY_MDIO_LED, XWAY_GPHY_LED_INV(index)); 509 + 510 + if (force_active_high) 511 + return phy_clear_bits(phydev, XWAY_MDIO_LED, XWAY_GPHY_LED_INV(index)); 512 + 513 + unreachable(); 514 + } 515 + 369 516 static struct phy_driver xway_gphy[] = { 370 517 { 371 518 .phy_id = PHY_ID_PHY11G_1_3, ··· 544 359 .config_intr = xway_gphy_config_intr, 545 360 .suspend = genphy_suspend, 546 361 .resume = genphy_resume, 362 + .led_brightness_set = xway_gphy_led_brightness_set, 363 + .led_hw_is_supported = xway_gphy_led_hw_is_supported, 364 + .led_hw_control_get = xway_gphy_led_hw_control_get, 365 + .led_hw_control_set = xway_gphy_led_hw_control_set, 366 + .led_polarity_set = xway_gphy_led_polarity_set, 547 367 }, { 548 368 .phy_id = PHY_ID_PHY22F_1_3, 549 369 .phy_id_mask = 0xffffffff, ··· 560 370 .config_intr = xway_gphy_config_intr, 561 371 .suspend = genphy_suspend, 562 372 .resume = genphy_resume, 373 + .led_brightness_set = xway_gphy_led_brightness_set, 374 + .led_hw_is_supported = xway_gphy_led_hw_is_supported, 375 + .led_hw_control_get = xway_gphy_led_hw_control_get, 376 + .led_hw_control_set = xway_gphy_led_hw_control_set, 377 + .led_polarity_set = xway_gphy_led_polarity_set, 563 378 }, { 564 379 .phy_id = PHY_ID_PHY11G_1_4, 565 380 .phy_id_mask = 0xffffffff, ··· 576 381 .config_intr = xway_gphy_config_intr, 577 382 .suspend = genphy_suspend, 578 383 .resume = genphy_resume, 384 + .led_brightness_set = xway_gphy_led_brightness_set, 385 + .led_hw_is_supported = xway_gphy_led_hw_is_supported, 386 + .led_hw_control_get = xway_gphy_led_hw_control_get, 387 + .led_hw_control_set = xway_gphy_led_hw_control_set, 388 + .led_polarity_set = xway_gphy_led_polarity_set, 579 389 }, { 580 390 .phy_id = PHY_ID_PHY22F_1_4, 581 391 .phy_id_mask = 0xffffffff, ··· 592 392 .config_intr = xway_gphy_config_intr, 593 393 .suspend = genphy_suspend, 594 394 .resume = genphy_resume, 395 + .led_brightness_set = xway_gphy_led_brightness_set, 396 + .led_hw_is_supported = xway_gphy_led_hw_is_supported, 397 + .led_hw_control_get = xway_gphy_led_hw_control_get, 398 + .led_hw_control_set = xway_gphy_led_hw_control_set, 399 + .led_polarity_set = xway_gphy_led_polarity_set, 595 400 }, { 596 401 .phy_id = PHY_ID_PHY11G_1_5, 597 402 .phy_id_mask = 0xffffffff, ··· 607 402 .config_intr = xway_gphy_config_intr, 608 403 .suspend = genphy_suspend, 609 404 .resume = genphy_resume, 405 + .led_brightness_set = xway_gphy_led_brightness_set, 406 + .led_hw_is_supported = xway_gphy_led_hw_is_supported, 407 + .led_hw_control_get = xway_gphy_led_hw_control_get, 408 + .led_hw_control_set = xway_gphy_led_hw_control_set, 409 + .led_polarity_set = xway_gphy_led_polarity_set, 610 410 }, { 611 411 .phy_id = PHY_ID_PHY22F_1_5, 612 412 .phy_id_mask = 0xffffffff, ··· 622 412 .config_intr = xway_gphy_config_intr, 623 413 .suspend = genphy_suspend, 624 414 .resume = genphy_resume, 415 + .led_brightness_set = xway_gphy_led_brightness_set, 416 + .led_hw_is_supported = xway_gphy_led_hw_is_supported, 417 + .led_hw_control_get = xway_gphy_led_hw_control_get, 418 + .led_hw_control_set = xway_gphy_led_hw_control_set, 419 + .led_polarity_set = xway_gphy_led_polarity_set, 625 420 }, { 626 421 .phy_id = PHY_ID_PHY11G_VR9_1_1, 627 422 .phy_id_mask = 0xffffffff, ··· 637 422 .config_intr = xway_gphy_config_intr, 638 423 .suspend = genphy_suspend, 639 424 .resume = genphy_resume, 425 + .led_brightness_set = xway_gphy_led_brightness_set, 426 + .led_hw_is_supported = xway_gphy_led_hw_is_supported, 427 + .led_hw_control_get = xway_gphy_led_hw_control_get, 428 + .led_hw_control_set = xway_gphy_led_hw_control_set, 429 + .led_polarity_set = xway_gphy_led_polarity_set, 640 430 }, { 641 431 .phy_id = PHY_ID_PHY22F_VR9_1_1, 642 432 .phy_id_mask = 0xffffffff, ··· 652 432 .config_intr = xway_gphy_config_intr, 653 433 .suspend = genphy_suspend, 654 434 .resume = genphy_resume, 435 + .led_brightness_set = xway_gphy_led_brightness_set, 436 + .led_hw_is_supported = xway_gphy_led_hw_is_supported, 437 + .led_hw_control_get = xway_gphy_led_hw_control_get, 438 + .led_hw_control_set = xway_gphy_led_hw_control_set, 439 + .led_polarity_set = xway_gphy_led_polarity_set, 655 440 }, { 656 441 .phy_id = PHY_ID_PHY11G_VR9_1_2, 657 442 .phy_id_mask = 0xffffffff, ··· 667 442 .config_intr = xway_gphy_config_intr, 668 443 .suspend = genphy_suspend, 669 444 .resume = genphy_resume, 445 + .led_brightness_set = xway_gphy_led_brightness_set, 446 + .led_hw_is_supported = xway_gphy_led_hw_is_supported, 447 + .led_hw_control_get = xway_gphy_led_hw_control_get, 448 + .led_hw_control_set = xway_gphy_led_hw_control_set, 449 + .led_polarity_set = xway_gphy_led_polarity_set, 670 450 }, { 671 451 .phy_id = PHY_ID_PHY22F_VR9_1_2, 672 452 .phy_id_mask = 0xffffffff, ··· 682 452 .config_intr = xway_gphy_config_intr, 683 453 .suspend = genphy_suspend, 684 454 .resume = genphy_resume, 455 + .led_brightness_set = xway_gphy_led_brightness_set, 456 + .led_hw_is_supported = xway_gphy_led_hw_is_supported, 457 + .led_hw_control_get = xway_gphy_led_hw_control_get, 458 + .led_hw_control_set = xway_gphy_led_hw_control_set, 459 + .led_polarity_set = xway_gphy_led_polarity_set, 685 460 }, 686 461 }; 687 462 module_phy_driver(xway_gphy);