Add downstream DT property to setup the PHY LEDs of the MaxLinear
GPY211 PHY in such way that the VDD of the LED is driven by the SoC
pin rather than the GND (which is the default).
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/* SGMII */
#define VSPEC1_SGMII_CTRL 0x08
#define VSPEC1_SGMII_CTRL_ANEN BIT(12) /* Aneg enable */
/* SGMII */
#define VSPEC1_SGMII_CTRL 0x08
#define VSPEC1_SGMII_CTRL_ANEN BIT(12) /* Aneg enable */
-@@ -80,6 +87,31 @@ static const struct {
+@@ -80,6 +87,35 @@ static const struct {
+ struct device_node *node = phydev->mdio.dev.of_node;
+ u32 led_regs[PHY_LED_NUM_LEDS];
+ int i, ret;
+ struct device_node *node = phydev->mdio.dev.of_node;
+ u32 led_regs[PHY_LED_NUM_LEDS];
+ int i, ret;
+
+ if (!IS_ENABLED(CONFIG_OF_MDIO))
+ return 0;
+
+ if (!IS_ENABLED(CONFIG_OF_MDIO))
+ return 0;
+ if (of_property_read_u32_array(node, "mxl,led-config", led_regs, PHY_LED_NUM_LEDS))
+ return 0;
+
+ if (of_property_read_u32_array(node, "mxl,led-config", led_regs, PHY_LED_NUM_LEDS))
+ return 0;
+
++ if (of_property_read_bool(node, "mxl,led-drive-vdd"))
++ val &= 0x0fff;
++
+ /* Enable LED function handling on all ports*/
+ /* Enable LED function handling on all ports*/
-+ phy_write(phydev, PHY_LED, 0xFF00);
++ phy_write(phydev, PHY_LED, val);
+
+ /* Write LED register values */
+ for (i = 0; i < PHY_LED_NUM_LEDS; i++) {
+
+ /* Write LED register values */
+ for (i = 0; i < PHY_LED_NUM_LEDS; i++) {
static int gpy_config_init(struct phy_device *phydev)
{
int ret;
static int gpy_config_init(struct phy_device *phydev)
{
int ret;
-@@ -91,7 +123,10 @@ static int gpy_config_init(struct phy_de
+@@ -91,7 +127,10 @@ static int gpy_config_init(struct phy_de
/* Clear all pending interrupts */
ret = phy_read(phydev, PHY_ISTAT);
/* Clear all pending interrupts */
ret = phy_read(phydev, PHY_ISTAT);
/* SGMII */
#define VSPEC1_SGMII_CTRL 0x08
#define VSPEC1_SGMII_CTRL_ANEN BIT(12) /* Aneg enable */
/* SGMII */
#define VSPEC1_SGMII_CTRL 0x08
#define VSPEC1_SGMII_CTRL_ANEN BIT(12) /* Aneg enable */
-@@ -241,6 +248,31 @@ out:
+@@ -241,6 +248,35 @@ out:
+ struct device_node *node = phydev->mdio.dev.of_node;
+ u32 led_regs[PHY_LED_NUM_LEDS];
+ int i, ret;
+ struct device_node *node = phydev->mdio.dev.of_node;
+ u32 led_regs[PHY_LED_NUM_LEDS];
+ int i, ret;
+
+ if (!IS_ENABLED(CONFIG_OF_MDIO))
+ return 0;
+
+ if (!IS_ENABLED(CONFIG_OF_MDIO))
+ return 0;
+ if (of_property_read_u32_array(node, "mxl,led-config", led_regs, PHY_LED_NUM_LEDS))
+ return 0;
+
+ if (of_property_read_u32_array(node, "mxl,led-config", led_regs, PHY_LED_NUM_LEDS))
+ return 0;
+
++ if (of_property_read_bool(node, "mxl,led-drive-vdd"))
++ val &= 0x0fff;
++
+ /* Enable LED function handling on all ports*/
+ /* Enable LED function handling on all ports*/
-+ phy_write(phydev, PHY_LED, 0xFF00);
++ phy_write(phydev, PHY_LED, val);
+
+ /* Write LED register values */
+ for (i = 0; i < PHY_LED_NUM_LEDS; i++) {
+
+ /* Write LED register values */
+ for (i = 0; i < PHY_LED_NUM_LEDS; i++) {
static int gpy_config_init(struct phy_device *phydev)
{
int ret;
static int gpy_config_init(struct phy_device *phydev)
{
int ret;
-@@ -252,7 +284,10 @@ static int gpy_config_init(struct phy_de
+@@ -252,7 +288,10 @@ static int gpy_config_init(struct phy_de
/* Clear all pending interrupts */
ret = phy_read(phydev, PHY_ISTAT);
/* Clear all pending interrupts */
ret = phy_read(phydev, PHY_ISTAT);
--- a/drivers/net/phy/mxl-gpy.c
+++ b/drivers/net/phy/mxl-gpy.c
--- a/drivers/net/phy/mxl-gpy.c
+++ b/drivers/net/phy/mxl-gpy.c
-@@ -191,8 +191,11 @@ static bool gpy_2500basex_chk(struct phy
+@@ -195,8 +195,11 @@ static bool gpy_2500basex_chk(struct phy
phydev->speed = SPEED_2500;
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
phydev->speed = SPEED_2500;
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-@@ -216,6 +219,14 @@ static int gpy_config_aneg(struct phy_de
+@@ -220,6 +223,14 @@ static int gpy_config_aneg(struct phy_de
if (phydev->autoneg == AUTONEG_DISABLE) {
/* Configure half duplex with genphy_setup_forced,
* because genphy_c45_pma_setup_forced does not support.
if (phydev->autoneg == AUTONEG_DISABLE) {
/* Configure half duplex with genphy_setup_forced,
* because genphy_c45_pma_setup_forced does not support.
-@@ -306,6 +317,8 @@ static void gpy_update_interface(struct
+@@ -310,6 +321,8 @@ static void gpy_update_interface(struct
switch (phydev->speed) {
case SPEED_2500:
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
switch (phydev->speed) {
case SPEED_2500:
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
VSPEC1_SGMII_CTRL_ANEN, 0);
if (ret < 0)
ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
VSPEC1_SGMII_CTRL_ANEN, 0);
if (ret < 0)
-@@ -317,7 +330,7 @@ static void gpy_update_interface(struct
+@@ -321,7 +334,7 @@ static void gpy_update_interface(struct
case SPEED_100:
case SPEED_10:
phydev->interface = PHY_INTERFACE_MODE_SGMII;
case SPEED_100:
case SPEED_10:
phydev->interface = PHY_INTERFACE_MODE_SGMII;
--- a/drivers/net/phy/mxl-gpy.c
+++ b/drivers/net/phy/mxl-gpy.c
--- a/drivers/net/phy/mxl-gpy.c
+++ b/drivers/net/phy/mxl-gpy.c
-@@ -367,8 +367,11 @@ static bool gpy_2500basex_chk(struct phy
+@@ -371,8 +371,11 @@ static bool gpy_2500basex_chk(struct phy
phydev->speed = SPEED_2500;
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
phydev->speed = SPEED_2500;
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-@@ -392,6 +395,14 @@ static int gpy_config_aneg(struct phy_de
+@@ -396,6 +399,14 @@ static int gpy_config_aneg(struct phy_de
if (phydev->autoneg == AUTONEG_DISABLE) {
/* Configure half duplex with genphy_setup_forced,
* because genphy_c45_pma_setup_forced does not support.
if (phydev->autoneg == AUTONEG_DISABLE) {
/* Configure half duplex with genphy_setup_forced,
* because genphy_c45_pma_setup_forced does not support.
-@@ -482,6 +493,8 @@ static void gpy_update_interface(struct
+@@ -486,6 +497,8 @@ static void gpy_update_interface(struct
switch (phydev->speed) {
case SPEED_2500:
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
switch (phydev->speed) {
case SPEED_2500:
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
VSPEC1_SGMII_CTRL_ANEN, 0);
if (ret < 0)
ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
VSPEC1_SGMII_CTRL_ANEN, 0);
if (ret < 0)
-@@ -493,7 +506,7 @@ static void gpy_update_interface(struct
+@@ -497,7 +510,7 @@ static void gpy_update_interface(struct
case SPEED_100:
case SPEED_10:
phydev->interface = PHY_INTERFACE_MODE_SGMII;
case SPEED_100:
case SPEED_10:
phydev->interface = PHY_INTERFACE_MODE_SGMII;