devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christian Marangi <ansuelsmth@gmail.com>
To: Andrew Lunn <andrew@lunn.ch>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	Russell King <linux@armlinux.org.uk>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Christian Marangi <ansuelsmth@gmail.com>,
	netdev@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Tobias Waldekranz <tobias@waldekranz.com>
Subject: [net-next PATCH v4 2/4] net: phy: add support for PHY LEDs polarity modes
Date: Fri, 15 Dec 2023 22:22:42 +0100	[thread overview]
Message-ID: <20231215212244.1658-3-ansuelsmth@gmail.com> (raw)
In-Reply-To: <20231215212244.1658-1-ansuelsmth@gmail.com>

Add support for PHY LEDs polarity modes. Some device might require
special polarity mode for the LED to correctly work and those mode
doesn't reflect what the PHY sets by default.

An example is a PHY device that set LED to active high but the attached
LEDs require to be active low to correctly work (and turn on when
actually requested)

PHY driver needs to declare .led_polarity_set() to configure LED
polarity. Index of the LED is passed and the polarity mode in the enum.

If a polarity is not set in DT and .led_polarity_set() is declared,
PHY_LED_POLARITY_DEFAULT is passed as polarity mode to let the PHY
driver decide a default polarity mode for the attached LEDs.

This is needed for PHY that sets active high on reset and the common
configuration is LEDs with active low polarity.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
Changes v4:
- Drop for global active-low
- Rework to polarity option (for marvell10g series support)
Changes v3:
- Out of RFC
Changes v2:
- Add this patch

 drivers/net/phy/phy_device.c | 45 ++++++++++++++++++++++++++++++++++++
 include/linux/phy.h          | 25 ++++++++++++++++++++
 2 files changed, 70 insertions(+)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index d8e9335d415c..b35b7a8717cc 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -43,6 +43,13 @@ MODULE_DESCRIPTION("PHY library");
 MODULE_AUTHOR("Andy Fleming");
 MODULE_LICENSE("GPL");
 
+static const char * const phy_led_polarity_mode_strings[] = {
+	[PHY_LED_POLARITY_ACTIVE_LOW] = "active-low",
+	[PHY_LED_POLARITY_ACTIVE_HIGH] = "active-high",
+	[PHY_LED_POLARITY_ACTIVE_LOW_TRISTATED] = "active-low-tristated",
+	[PHY_LED_POLARITY_ACTIVE_HIGH_TRISTATED] = "active-low-tristated",
+};
+
 __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_features) __ro_after_init;
 EXPORT_SYMBOL_GPL(phy_basic_features);
 
@@ -3086,6 +3093,40 @@ static void phy_leds_unregister(struct phy_device *phydev)
 	}
 }
 
+static int of_phy_set_led_polarity(struct phy_device *phydev,
+				   struct device_node *led, u32 index)
+{
+	const char *polarity_str;
+	int i, err;
+
+	err = of_property_read_string(led, "polarity", &polarity_str);
+	if (err) {
+		if (err != -EINVAL)
+			return err;
+
+		/* Nothing to do, polarity setting not supported */
+		if (!phydev->drv->led_polarity_set)
+			return 0;
+
+		/* Apply default polarity if supported */
+		return phydev->drv->led_polarity_set(phydev, index,
+						     PHY_LED_POLARITY_DEFAULT);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(phy_led_polarity_mode_strings); i++)
+		if (!strcmp(phy_led_polarity_mode_strings[i], polarity_str)) {
+			if (!phydev->drv->led_polarity_set) {
+				phydev_warn(phydev, "Ignoring LED polarity in DT. Setting polarity not supported\n");
+				return 0;
+			}
+
+			return phydev->drv->led_polarity_set(phydev, index, i);
+		}
+
+	/* Unknown polarity mode declared */
+	return -EINVAL;
+}
+
 static int of_phy_led(struct phy_device *phydev,
 		      struct device_node *led)
 {
@@ -3109,6 +3150,10 @@ static int of_phy_led(struct phy_device *phydev,
 	if (index > U8_MAX)
 		return -EINVAL;
 
+	err = of_phy_set_led_polarity(phydev, led, index);
+	if (err)
+		return err;
+
 	phyled->index = index;
 	if (phydev->drv->led_brightness_set)
 		cdev->brightness_set_blocking = phy_led_set_brightness;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 6e7ebcc50b85..88ff4195bc4f 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -852,6 +852,16 @@ struct phy_plca_status {
 	bool pst;
 };
 
+enum phy_led_polarity_modes {
+	PHY_LED_POLARITY_ACTIVE_LOW,
+	PHY_LED_POLARITY_ACTIVE_HIGH,
+	PHY_LED_POLARITY_ACTIVE_LOW_TRISTATED,
+	PHY_LED_POLARITY_ACTIVE_HIGH_TRISTATED,
+
+	/* PHY driver apply a default value */
+	PHY_LED_POLARITY_DEFAULT,
+};
+
 /**
  * struct phy_led: An LED driven by the PHY
  *
@@ -1145,6 +1155,21 @@ struct phy_driver {
 	int (*led_hw_control_get)(struct phy_device *dev, u8 index,
 				  unsigned long *rules);
 
+	/**
+	 * @led_polarity_set: Set the LED polarity mode
+	 * @dev: PHY device which has the LED
+	 * @index: Which LED of the PHY device
+	 * @polarity_mode: LED polarity mode from enum
+	 *
+	 * Set PHY to requested LED polarity mode.
+	 *
+	 * If polarity mode PHY_LED_POLARITY_DEFAULT is passed,
+	 * PHY driver should apply a default LED polarity mode.
+	 *
+	 * Returns 0, or an error code.
+	 */
+	int (*led_polarity_set)(struct phy_device *dev, int index,
+				enum phy_led_polarity_modes polarity_mode);
 };
 #define to_phy_driver(d) container_of(to_mdio_common_driver(d),		\
 				      struct phy_driver, mdiodrv)
-- 
2.40.1


  parent reply	other threads:[~2023-12-16  0:23 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-15 21:22 [net-next PATCH v4 0/4] net: phy: generic polarity + LED support for qca808x Christian Marangi
2023-12-15 21:22 ` [net-next PATCH v4 1/4] dt-bindings: net: phy: Document new LEDs polarity property Christian Marangi
2023-12-20 15:22   ` Rob Herring
2023-12-20 22:53     ` Christian Marangi
2023-12-21  9:43       ` Andrew Lunn
2023-12-22 15:20         ` Conor Dooley
2023-12-21  9:34     ` Andrew Lunn
2023-12-22 22:09       ` Christian Marangi
2023-12-15 21:22 ` Christian Marangi [this message]
2023-12-15 21:22 ` [net-next PATCH v4 3/4] dt-bindings: net: Document QCA808x PHYs Christian Marangi
2023-12-15 21:22 ` [net-next PATCH v4 4/4] net: phy: at803x: add LED support for qca808x Christian Marangi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231215212244.1658-3-ansuelsmth@gmail.com \
    --to=ansuelsmth@gmail.com \
    --cc=andrew@lunn.ch \
    --cc=conor+dt@kernel.org \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=f.fainelli@gmail.com \
    --cc=hkallweit1@gmail.com \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=robh+dt@kernel.org \
    --cc=tobias@waldekranz.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).