Lines Matching +full:power +full:- +full:role

1 // SPDX-License-Identifier: GPL-2.0
3 * mtu3_dr.c - dual role switch and host glue layer
24 if (!ssusb->otg_switch.is_u3_drd) { in toggle_opstate()
25 mtu3_setbits(ssusb->mac_base, U3D_DEVICE_CONTROL, DC_SESSION); in toggle_opstate()
26 mtu3_setbits(ssusb->mac_base, U3D_POWER_MANAGEMENT, SOFT_CONN); in toggle_opstate()
30 /* only port0 supports dual-role mode */
34 void __iomem *ibase = ssusb->ippc_base; in ssusb_port0_switch()
37 dev_dbg(ssusb->dev, "%s (switch u%d port0 to %s)\n", __func__, in ssusb_port0_switch()
41 /* 1. power off and disable u2 port0 */ in ssusb_port0_switch()
46 /* 2. power on, enable u2 port0 and select its mode */ in ssusb_port0_switch()
53 /* 1. power off and disable u3 port0 */ in ssusb_port0_switch()
58 /* 2. power on, enable u3 port0 and select its mode */ in ssusb_port0_switch()
73 dev_dbg(ssusb->dev, "%s\n", __func__); in switch_port_to_host()
77 if (ssusb->otg_switch.is_u3_drd) { in switch_port_to_host()
92 dev_dbg(ssusb->dev, "%s\n", __func__); in switch_port_to_device()
96 if (ssusb->otg_switch.is_u3_drd) { in switch_port_to_device()
107 struct regulator *vbus = otg_sx->vbus; in ssusb_set_vbus()
114 dev_dbg(ssusb->dev, "%s: turn %s\n", __func__, is_on ? "on" : "off"); in ssusb_set_vbus()
119 dev_err(ssusb->dev, "vbus regulator enable failed\n"); in ssusb_set_vbus()
134 struct mtu3 *mtu = ssusb->u3d; in ssusb_mode_sw_work()
135 enum usb_role desired_role = otg_sx->desired_role; in ssusb_mode_sw_work()
138 current_role = ssusb->is_host ? USB_ROLE_HOST : USB_ROLE_DEVICE; in ssusb_mode_sw_work()
143 if (otg_sx->default_role == USB_ROLE_DEVICE) in ssusb_mode_sw_work()
150 dev_dbg(ssusb->dev, "set role : %s\n", usb_role_string(desired_role)); in ssusb_mode_sw_work()
151 mtu3_dbg_trace(ssusb->dev, "set role : %s", usb_role_string(desired_role)); in ssusb_mode_sw_work()
152 pm_runtime_get_sync(ssusb->dev); in ssusb_mode_sw_work()
160 ssusb->is_host = true; in ssusb_mode_sw_work()
164 ssusb->is_host = false; in ssusb_mode_sw_work()
171 dev_err(ssusb->dev, "invalid role\n"); in ssusb_mode_sw_work()
173 pm_runtime_put(ssusb->dev); in ssusb_mode_sw_work()
176 static void ssusb_set_mode(struct otg_switch_mtk *otg_sx, enum usb_role role) in ssusb_set_mode() argument
180 if (ssusb->dr_mode != USB_DR_MODE_OTG) in ssusb_set_mode()
183 otg_sx->desired_role = role; in ssusb_set_mode()
184 queue_work(system_freezable_wq, &otg_sx->dr_work); in ssusb_set_mode()
201 struct extcon_dev *edev = otg_sx->edev; in ssusb_extcon_register()
208 otg_sx->id_nb.notifier_call = ssusb_id_notifier; in ssusb_extcon_register()
209 ret = devm_extcon_register_notifier(ssusb->dev, edev, EXTCON_USB_HOST, in ssusb_extcon_register()
210 &otg_sx->id_nb); in ssusb_extcon_register()
212 dev_err(ssusb->dev, "failed to register notifier for USB-HOST\n"); in ssusb_extcon_register()
217 dev_dbg(ssusb->dev, "EXTCON_USB_HOST: %d\n", ret); in ssusb_extcon_register()
229 * This is useful in special cases, such as uses TYPE-A receptacle but also
230 * wants to support dual-role mode.
234 struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; in ssusb_mode_switch()
244 value = mtu3_readl(ssusb->ippc_base, SSUSB_U2_CTRL(0)); in ssusb_set_force_mode()
259 mtu3_writel(ssusb->ippc_base, SSUSB_U2_CTRL(0), value); in ssusb_set_force_mode()
262 static int ssusb_role_sw_set(struct usb_role_switch *sw, enum usb_role role) in ssusb_role_sw_set() argument
265 struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; in ssusb_role_sw_set()
267 ssusb_set_mode(otg_sx, role); in ssusb_role_sw_set()
276 return ssusb->is_host ? USB_ROLE_HOST : USB_ROLE_DEVICE; in ssusb_role_sw_get()
283 struct device *dev = ssusb->dev; in ssusb_role_sw_register()
286 if (!otg_sx->role_sw_used) in ssusb_role_sw_register()
291 otg_sx->default_role = USB_ROLE_DEVICE; in ssusb_role_sw_register()
293 otg_sx->default_role = USB_ROLE_HOST; in ssusb_role_sw_register()
299 otg_sx->role_sw = usb_role_switch_register(dev, &role_sx_desc); in ssusb_role_sw_register()
300 if (IS_ERR(otg_sx->role_sw)) in ssusb_role_sw_register()
301 return PTR_ERR(otg_sx->role_sw); in ssusb_role_sw_register()
303 ssusb_set_mode(otg_sx, otg_sx->default_role); in ssusb_role_sw_register()
310 struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; in ssusb_otg_switch_init()
313 INIT_WORK(&otg_sx->dr_work, ssusb_mode_sw_work); in ssusb_otg_switch_init()
315 if (otg_sx->manual_drd_enabled) in ssusb_otg_switch_init()
317 else if (otg_sx->role_sw_used) in ssusb_otg_switch_init()
327 struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; in ssusb_otg_switch_exit()
329 cancel_work_sync(&otg_sx->dr_work); in ssusb_otg_switch_exit()
330 usb_role_switch_unregister(otg_sx->role_sw); in ssusb_otg_switch_exit()