Lines Matching +full:lgm +full:- +full:usb +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0
3 * Intel LGM USB PHY driver
16 #include <linux/usb/phy.h>
37 static const char *const PHY_RESETS[] = { "phy31", "phy", };
44 struct usb_phy phy; member
56 ret = extcon_get_property(ta->phy.edev, EXTCON_USB_HOST, in get_flipped()
59 dev_err(ta->phy.dev, "no polarity property from extcon\n"); in get_flipped()
68 static int phy_init(struct usb_phy *phy) in phy_init() argument
70 struct tca_apb *ta = container_of(phy, struct tca_apb, phy); in phy_init()
71 void __iomem *ctrl1 = phy->io_priv + CTRL1_OFFSET; in phy_init()
74 if (ta->phy_initialized) in phy_init()
78 reset_control_deassert(ta->resets[i]); in phy_init()
82 dev_err(ta->phy.dev, "SRAM init failed, 0x%x\n", val); in phy_init()
88 ta->phy_initialized = true; in phy_init()
89 if (!ta->phy.edev) { in phy_init()
90 writel(TCPC_CONN, ta->phy.io_priv + TCPC_OFFSET); in phy_init()
91 return phy->set_vbus(phy, true); in phy_init()
94 schedule_work(&ta->wk); in phy_init()
99 static void phy_shutdown(struct usb_phy *phy) in phy_shutdown() argument
101 struct tca_apb *ta = container_of(phy, struct tca_apb, phy); in phy_shutdown()
104 if (!ta->phy_initialized) in phy_shutdown()
107 ta->phy_initialized = false; in phy_shutdown()
108 flush_work(&ta->wk); in phy_shutdown()
109 ta->phy.set_vbus(&ta->phy, false); in phy_shutdown()
111 ta->connected = false; in phy_shutdown()
112 writel(TCPC_DISCONN, ta->phy.io_priv + TCPC_OFFSET); in phy_shutdown()
115 reset_control_assert(ta->resets[i]); in phy_shutdown()
118 static int phy_set_vbus(struct usb_phy *phy, int on) in phy_set_vbus() argument
120 struct tca_apb *ta = container_of(phy, struct tca_apb, phy); in phy_set_vbus()
123 if (!!on == ta->regulator_enabled) in phy_set_vbus()
127 ret = regulator_enable(ta->vbus); in phy_set_vbus()
129 ret = regulator_disable(ta->vbus); in phy_set_vbus()
132 ta->regulator_enabled = on; in phy_set_vbus()
134 dev_dbg(ta->phy.dev, "set vbus: %d\n", on); in phy_set_vbus()
150 connected = extcon_get_state(ta->phy.edev, EXTCON_USB_HOST); in tca_work()
151 if (connected == ta->connected) in tca_work()
154 ta->connected = connected; in tca_work()
159 dev_dbg(ta->phy.dev, "connected%s\n", flipped ? " flipped" : ""); in tca_work()
162 dev_dbg(ta->phy.dev, "disconnected\n"); in tca_work()
165 writel(val, ta->phy.io_priv + TCPC_OFFSET); in tca_work()
167 ret = ta->phy.set_vbus(&ta->phy, connected); in tca_work()
169 dev_err(ta->phy.dev, "failed to set VBUS\n"); in tca_work()
174 struct tca_apb *ta = container_of(nb, struct tca_apb, phy.id_nb); in id_notifier()
176 if (ta->phy_initialized) in id_notifier()
177 schedule_work(&ta->wk); in id_notifier()
190 struct device *dev = &pdev->dev; in phy_probe()
191 struct usb_phy *phy; in phy_probe() local
197 return -ENOMEM; in phy_probe()
200 INIT_WORK(&ta->wk, tca_work); in phy_probe()
202 phy = &ta->phy; in phy_probe()
203 phy->dev = dev; in phy_probe()
204 phy->label = dev_name(dev); in phy_probe()
205 phy->type = USB_PHY_TYPE_USB3; in phy_probe()
206 phy->init = phy_init; in phy_probe()
207 phy->shutdown = phy_shutdown; in phy_probe()
208 phy->set_vbus = phy_set_vbus; in phy_probe()
209 phy->id_nb.notifier_call = id_notifier; in phy_probe()
210 phy->vbus_nb.notifier_call = vbus_notifier; in phy_probe()
212 phy->io_priv = devm_platform_ioremap_resource(pdev, 0); in phy_probe()
213 if (IS_ERR(phy->io_priv)) in phy_probe()
214 return PTR_ERR(phy->io_priv); in phy_probe()
216 ta->vbus = devm_regulator_get(dev, "vbus"); in phy_probe()
217 if (IS_ERR(ta->vbus)) in phy_probe()
218 return PTR_ERR(ta->vbus); in phy_probe()
229 ta->resets[i] = devm_reset_control_get_exclusive(dev, PHY_RESETS[i]); in phy_probe()
230 if (IS_ERR(ta->resets[i])) { in phy_probe()
232 return PTR_ERR(ta->resets[i]); in phy_probe()
240 reset_control_assert(ta->resets[i]); in phy_probe()
242 * Out-of-band reset of the controller after PHY reset will cause in phy_probe()
243 * controller malfunctioning, so we should use in-band controller in phy_probe()
244 * reset only and leave the controller de-asserted here. in phy_probe()
249 /* Need to wait at least 20us after de-assert the controller */ in phy_probe()
252 return usb_add_phy_dev(phy); in phy_probe()
259 usb_remove_phy(&ta->phy); in phy_remove()
263 { .compatible = "intel,lgm-usb-phy" },
270 .name = "lgm-usb-phy",
279 MODULE_DESCRIPTION("Intel LGM USB PHY driver");