765-mxl-gpy-control-LED-reg-from-DT.patch 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. From 94b90966095f3fa625897e8f53d215882f6e19b3 Mon Sep 17 00:00:00 2001
  2. From: David Bauer <[email protected]>
  3. Date: Sat, 11 Mar 2023 17:00:01 +0100
  4. Subject: [PATCH] mxl-gpy: control LED reg from DT
  5. Add dynamic configuration for the LED control registers on MXL PHYs.
  6. This patch has been tested with MaxLinear GPY211C. It is unlikely to be
  7. accepted upstream, as upstream plans on integrating their own framework
  8. for handling these LEDs.
  9. For the time being, use this hack to configure PHY driven device-LEDs to
  10. show the correct state.
  11. A possible alternative might be to expose the LEDs using the kernel LED
  12. framework and bind it to the netdevice. This might also be upstreamable,
  13. although it is a considerable extra amount of work.
  14. Signed-off-by: David Bauer <[email protected]>
  15. ---
  16. drivers/net/phy/mxl-gpy.c | 37 ++++++++++++++++++++++++++++++++++++-
  17. 1 file changed, 36 insertions(+), 1 deletion(-)
  18. --- a/drivers/net/phy/mxl-gpy.c
  19. +++ b/drivers/net/phy/mxl-gpy.c
  20. @@ -10,6 +10,7 @@
  21. #include <linux/bitfield.h>
  22. #include <linux/hwmon.h>
  23. #include <linux/mutex.h>
  24. +#include <linux/of.h>
  25. #include <linux/phy.h>
  26. #include <linux/polynomial.h>
  27. #include <linux/property.h>
  28. @@ -293,10 +294,39 @@ out:
  29. return ret;
  30. }
  31. +static int gpy_led_write(struct phy_device *phydev)
  32. +{
  33. + struct device_node *node = phydev->mdio.dev.of_node;
  34. + u32 led_regs[GPY_MAX_LEDS];
  35. + int i, ret;
  36. + u16 val = 0xff00;
  37. +
  38. + if (!IS_ENABLED(CONFIG_OF_MDIO))
  39. + return 0;
  40. +
  41. + if (of_property_read_u32_array(node, "mxl,led-config", led_regs, GPY_MAX_LEDS))
  42. + return 0;
  43. +
  44. + if (of_property_read_bool(node, "mxl,led-drive-vdd"))
  45. + val &= 0x0fff;
  46. +
  47. + /* Enable LED function handling on all ports*/
  48. + phy_write(phydev, PHY_LED, val);
  49. +
  50. + /* Write LED register values */
  51. + for (i = 0; i < GPY_MAX_LEDS; i++) {
  52. + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(i), (u16)led_regs[i]);
  53. + if (ret < 0)
  54. + return ret;
  55. + }
  56. +
  57. + return 0;
  58. +}
  59. +
  60. static int gpy_config_init(struct phy_device *phydev)
  61. {
  62. /* Nothing to configure. Configuration Requirement Placeholder */
  63. - return 0;
  64. + return gpy_led_write(phydev);
  65. }
  66. static int gpy_probe(struct phy_device *phydev)