phy: Add media type and speed serdes configuration interfaces
authorSteen Hegelund <steen.hegelund@microchip.com>
Thu, 18 Feb 2021 16:14:49 +0000 (17:14 +0100)
committerVinod Koul <vkoul@kernel.org>
Wed, 17 Mar 2021 06:43:19 +0000 (12:13 +0530)
Provide new phy configuration interfaces for media type and speed that
allows e.g. PHYs used for ethernet to be configured with this
information.

Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Acked-By: Kishon Vijay Abraham I <kishon@ti.com>
Link: https://lore.kernel.org/r/20210218161451.3489955-3-steen.hegelund@microchip.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/phy/phy-core.c
include/linux/phy/phy.h

index 71cb108..ccb575b 100644 (file)
@@ -373,6 +373,36 @@ int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
 }
 EXPORT_SYMBOL_GPL(phy_set_mode_ext);
 
+int phy_set_media(struct phy *phy, enum phy_media media)
+{
+       int ret;
+
+       if (!phy || !phy->ops->set_media)
+               return 0;
+
+       mutex_lock(&phy->mutex);
+       ret = phy->ops->set_media(phy, media);
+       mutex_unlock(&phy->mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(phy_set_media);
+
+int phy_set_speed(struct phy *phy, int speed)
+{
+       int ret;
+
+       if (!phy || !phy->ops->set_speed)
+               return 0;
+
+       mutex_lock(&phy->mutex);
+       ret = phy->ops->set_speed(phy, speed);
+       mutex_unlock(&phy->mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(phy_set_speed);
+
 int phy_reset(struct phy *phy)
 {
        int ret;
index e435bdb..0ed434d 100644 (file)
@@ -44,6 +44,12 @@ enum phy_mode {
        PHY_MODE_DP
 };
 
+enum phy_media {
+       PHY_MEDIA_DEFAULT,
+       PHY_MEDIA_SR,
+       PHY_MEDIA_DAC,
+};
+
 /**
  * union phy_configure_opts - Opaque generic phy configuration
  *
@@ -64,6 +70,8 @@ union phy_configure_opts {
  * @power_on: powering on the phy
  * @power_off: powering off the phy
  * @set_mode: set the mode of the phy
+ * @set_media: set the media type of the phy (optional)
+ * @set_speed: set the speed of the phy (optional)
  * @reset: resetting the phy
  * @calibrate: calibrate the phy
  * @release: ops to be performed while the consumer relinquishes the PHY
@@ -75,6 +83,8 @@ struct phy_ops {
        int     (*power_on)(struct phy *phy);
        int     (*power_off)(struct phy *phy);
        int     (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
+       int     (*set_media)(struct phy *phy, enum phy_media media);
+       int     (*set_speed)(struct phy *phy, int speed);
 
        /**
         * @configure:
@@ -215,6 +225,8 @@ int phy_power_off(struct phy *phy);
 int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode);
 #define phy_set_mode(phy, mode) \
        phy_set_mode_ext(phy, mode, 0)
+int phy_set_media(struct phy *phy, enum phy_media media);
+int phy_set_speed(struct phy *phy, int speed);
 int phy_configure(struct phy *phy, union phy_configure_opts *opts);
 int phy_validate(struct phy *phy, enum phy_mode mode, int submode,
                 union phy_configure_opts *opts);
@@ -344,6 +356,20 @@ static inline int phy_set_mode_ext(struct phy *phy, enum phy_mode mode,
 #define phy_set_mode(phy, mode) \
        phy_set_mode_ext(phy, mode, 0)
 
+static inline int phy_set_media(struct phy *phy, enum phy_media media)
+{
+       if (!phy)
+               return 0;
+       return -ENODEV;
+}
+
+static inline int phy_set_speed(struct phy *phy, int speed)
+{
+       if (!phy)
+               return 0;
+       return -ENODEV;
+}
+
 static inline enum phy_mode phy_get_mode(struct phy *phy)
 {
        return PHY_MODE_INVALID;