Lines Matching +full:phy +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Meson GXL and GXM USB2 PHY driver
15 #include <linux/phy/phy.h>
18 /* bits [31:27] are read-only */
66 /* bits [31:14] are read-only */
94 enum phy_mode mode; member
107 static int phy_meson_gxl_usb2_init(struct phy *phy) in phy_meson_gxl_usb2_init() argument
109 struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy); in phy_meson_gxl_usb2_init()
112 ret = reset_control_reset(priv->reset); in phy_meson_gxl_usb2_init()
116 ret = clk_prepare_enable(priv->clk); in phy_meson_gxl_usb2_init()
118 reset_control_rearm(priv->reset); in phy_meson_gxl_usb2_init()
125 static int phy_meson_gxl_usb2_exit(struct phy *phy) in phy_meson_gxl_usb2_exit() argument
127 struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy); in phy_meson_gxl_usb2_exit()
129 clk_disable_unprepare(priv->clk); in phy_meson_gxl_usb2_exit()
130 reset_control_rearm(priv->reset); in phy_meson_gxl_usb2_exit()
135 static int phy_meson_gxl_usb2_reset(struct phy *phy) in phy_meson_gxl_usb2_reset() argument
137 struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy); in phy_meson_gxl_usb2_reset()
139 if (priv->is_enabled) { in phy_meson_gxl_usb2_reset()
140 /* reset the PHY and wait until settings are stabilized */ in phy_meson_gxl_usb2_reset()
141 regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, in phy_meson_gxl_usb2_reset()
144 regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, in phy_meson_gxl_usb2_reset()
152 static int phy_meson_gxl_usb2_set_mode(struct phy *phy, in phy_meson_gxl_usb2_set_mode() argument
153 enum phy_mode mode, int submode) in phy_meson_gxl_usb2_set_mode() argument
155 struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy); in phy_meson_gxl_usb2_set_mode()
157 switch (mode) { in phy_meson_gxl_usb2_set_mode()
160 regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN, in phy_meson_gxl_usb2_set_mode()
162 regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN, in phy_meson_gxl_usb2_set_mode()
164 regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP, in phy_meson_gxl_usb2_set_mode()
169 regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN, in phy_meson_gxl_usb2_set_mode()
171 regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN, in phy_meson_gxl_usb2_set_mode()
173 regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP, in phy_meson_gxl_usb2_set_mode()
178 return -EINVAL; in phy_meson_gxl_usb2_set_mode()
181 phy_meson_gxl_usb2_reset(phy); in phy_meson_gxl_usb2_set_mode()
183 priv->mode = mode; in phy_meson_gxl_usb2_set_mode()
188 static int phy_meson_gxl_usb2_power_off(struct phy *phy) in phy_meson_gxl_usb2_power_off() argument
190 struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy); in phy_meson_gxl_usb2_power_off()
192 priv->is_enabled = 0; in phy_meson_gxl_usb2_power_off()
194 /* power off the PHY by putting it into reset mode */ in phy_meson_gxl_usb2_power_off()
195 regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, in phy_meson_gxl_usb2_power_off()
201 static int phy_meson_gxl_usb2_power_on(struct phy *phy) in phy_meson_gxl_usb2_power_on() argument
203 struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy); in phy_meson_gxl_usb2_power_on()
206 priv->is_enabled = 1; in phy_meson_gxl_usb2_power_on()
208 /* power on the PHY by taking it out of reset mode */ in phy_meson_gxl_usb2_power_on()
209 regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0); in phy_meson_gxl_usb2_power_on()
211 ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode, 0); in phy_meson_gxl_usb2_power_on()
213 phy_meson_gxl_usb2_power_off(phy); in phy_meson_gxl_usb2_power_on()
215 dev_err(&phy->dev, "Failed to initialize PHY with mode %d\n", in phy_meson_gxl_usb2_power_on()
216 priv->mode); in phy_meson_gxl_usb2_power_on()
235 struct device *dev = &pdev->dev; in phy_meson_gxl_usb2_probe()
238 struct phy *phy; in phy_meson_gxl_usb2_probe() local
244 return -ENOMEM; in phy_meson_gxl_usb2_probe()
252 /* start in host mode */ in phy_meson_gxl_usb2_probe()
253 priv->mode = PHY_MODE_USB_HOST; in phy_meson_gxl_usb2_probe()
255 priv->regmap = devm_regmap_init_mmio(dev, base, in phy_meson_gxl_usb2_probe()
257 if (IS_ERR(priv->regmap)) in phy_meson_gxl_usb2_probe()
258 return PTR_ERR(priv->regmap); in phy_meson_gxl_usb2_probe()
260 priv->clk = devm_clk_get_optional(dev, "phy"); in phy_meson_gxl_usb2_probe()
261 if (IS_ERR(priv->clk)) in phy_meson_gxl_usb2_probe()
262 return PTR_ERR(priv->clk); in phy_meson_gxl_usb2_probe()
264 priv->reset = devm_reset_control_get_optional_shared(dev, "phy"); in phy_meson_gxl_usb2_probe()
265 if (IS_ERR(priv->reset)) in phy_meson_gxl_usb2_probe()
266 return PTR_ERR(priv->reset); in phy_meson_gxl_usb2_probe()
268 phy = devm_phy_create(dev, NULL, &phy_meson_gxl_usb2_ops); in phy_meson_gxl_usb2_probe()
269 if (IS_ERR(phy)) { in phy_meson_gxl_usb2_probe()
270 ret = PTR_ERR(phy); in phy_meson_gxl_usb2_probe()
271 if (ret != -EPROBE_DEFER) in phy_meson_gxl_usb2_probe()
272 dev_err(dev, "failed to create PHY\n"); in phy_meson_gxl_usb2_probe()
277 phy_set_drvdata(phy, priv); in phy_meson_gxl_usb2_probe()
285 { .compatible = "amlogic,meson-gxl-usb2-phy", },
293 .name = "phy-meson-gxl-usb2",
300 MODULE_DESCRIPTION("Meson GXL and GXM USB2 PHY driver");