[PATCH 1/2] phy: introduce phy mode PHY_MODE_UART and phy_get_mode_ext()

Chunfeng Yun chunfeng.yun at mediatek.com
Tue Jul 27 18:35:03 PDT 2021


On Tue, 2021-07-27 at 18:50 +0800, Macpaul Lin wrote:
> Some embedded platform shared PINs between USB and UART.
> 
> For example, some phone will use special cable detection in boot loader
> to switch USB port function into UART mode. Hence Kernel need to query
> the hardware state from PHY registers to confirm the initialzation flow
> for PHY and USB driver.
> 
> To support this kind of PIN switch, new PHY MODE and query API is
> required. Here we introduce a new PHY mode: PHY_MODE_UART.
> 
> API phy_get_mode_ext() can be used to query the MODE from hardware
> instead of reading it from phy attributes.
> 
> Signed-off-by: Macpaul Lin <macpaul.lin at mediatek.com>
> ---
>  drivers/phy/phy-core.c  |   17 +++++++++++++++++
>  include/linux/phy/phy.h |    3 +++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
> index ccb575b..b8f6539 100644
> --- a/drivers/phy/phy-core.c
> +++ b/drivers/phy/phy-core.c
> @@ -373,6 +373,23 @@ int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
>  }
>  EXPORT_SYMBOL_GPL(phy_set_mode_ext);
>  
> +int phy_get_mode_ext(struct phy *phy)
> +{
> +	int ret;
> +
> +	if (!phy || !phy->ops->get_mode_ext)
> +		return 0;
> +
> +	mutex_lock(&phy->mutex);
> +	ret = phy->ops->get_mode_ext(phy);
> +	if (!ret)
> +		ret = phy->attrs.mode;
> +	mutex_unlock(&phy->mutex);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(phy_get_mode_ext);
> +
>  int phy_set_media(struct phy *phy, enum phy_media media)
>  {
>  	int ret;
> diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
> index 0ed434d..7d32c6b 100644
> --- a/include/linux/phy/phy.h
> +++ b/include/linux/phy/phy.h
> @@ -34,6 +34,7 @@ enum phy_mode {
>  	PHY_MODE_USB_DEVICE_HS,
>  	PHY_MODE_USB_DEVICE_SS,
>  	PHY_MODE_USB_OTG,
> +	PHY_MODE_UART,
>  	PHY_MODE_UFS_HS_A,
>  	PHY_MODE_UFS_HS_B,
>  	PHY_MODE_PCIE,
> @@ -70,6 +71,7 @@ enum phy_media {
>   * @power_on: powering on the phy
>   * @power_off: powering off the phy
>   * @set_mode: set the mode of the phy
> + * @get_mode_ext: get the extented 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
> @@ -83,6 +85,7 @@ 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	(*get_mode_ext)(struct phy *phy);
>  	int	(*set_media)(struct phy *phy, enum phy_media media);
>  	int	(*set_speed)(struct phy *phy, int speed);
>  
add prototype of phy_get_mode_ext(struct phy *phy) for both cases that
CONFIG_GENERIC_PHY is enabled or not in linux/phy/phy.h



More information about the linux-phy mailing list