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
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()
29 /* only port0 supports dual-role mode */
33 void __iomem *ibase = ssusb->ippc_base; in ssusb_port0_switch()
36 dev_dbg(ssusb->dev, "%s (switch u%d port0 to %s)\n", __func__, in ssusb_port0_switch()
40 /* 1. power off and disable u2 port0 */ in ssusb_port0_switch()
45 /* 2. power on, enable u2 port0 and select its mode */ in ssusb_port0_switch()
52 /* 1. power off and disable u3 port0 */ in ssusb_port0_switch()
57 /* 2. power on, enable u3 port0 and select its mode */ in ssusb_port0_switch()
72 dev_dbg(ssusb->dev, "%s\n", __func__); in switch_port_to_host()
76 if (ssusb->otg_switch.is_u3_drd) { in switch_port_to_host()
91 dev_dbg(ssusb->dev, "%s\n", __func__); in switch_port_to_device()
95 if (ssusb->otg_switch.is_u3_drd) { in switch_port_to_device()
106 struct regulator *vbus = otg_sx->vbus; in ssusb_set_vbus()
113 dev_dbg(ssusb->dev, "%s: turn %s\n", __func__, str_on_off(is_on)); in ssusb_set_vbus()
118 dev_err(ssusb->dev, "vbus regulator enable failed\n"); in ssusb_set_vbus()
133 struct mtu3 *mtu = ssusb->u3d; in ssusb_mode_sw_work()
134 enum usb_role desired_role = otg_sx->desired_role; in ssusb_mode_sw_work()
137 current_role = ssusb->is_host ? USB_ROLE_HOST : USB_ROLE_DEVICE; in ssusb_mode_sw_work()
142 if (otg_sx->default_role == USB_ROLE_DEVICE) in ssusb_mode_sw_work()
149 dev_dbg(ssusb->dev, "set role : %s\n", usb_role_string(desired_role)); in ssusb_mode_sw_work()
150 mtu3_dbg_trace(ssusb->dev, "set role : %s", usb_role_string(desired_role)); in ssusb_mode_sw_work()
151 pm_runtime_get_sync(ssusb->dev); in ssusb_mode_sw_work()
159 ssusb->is_host = true; in ssusb_mode_sw_work()
163 ssusb->is_host = false; in ssusb_mode_sw_work()
170 dev_err(ssusb->dev, "invalid role\n"); in ssusb_mode_sw_work()
172 pm_runtime_put(ssusb->dev); in ssusb_mode_sw_work()
175 static void ssusb_set_mode(struct otg_switch_mtk *otg_sx, enum usb_role role) in ssusb_set_mode() argument
179 if (ssusb->dr_mode != USB_DR_MODE_OTG) in ssusb_set_mode()
182 otg_sx->desired_role = role; in ssusb_set_mode()
183 queue_work(system_freezable_wq, &otg_sx->dr_work); in ssusb_set_mode()
200 struct extcon_dev *edev = otg_sx->edev; in ssusb_extcon_register()
207 otg_sx->id_nb.notifier_call = ssusb_id_notifier; in ssusb_extcon_register()
208 ret = devm_extcon_register_notifier(ssusb->dev, edev, EXTCON_USB_HOST, in ssusb_extcon_register()
209 &otg_sx->id_nb); in ssusb_extcon_register()
211 dev_err(ssusb->dev, "failed to register notifier for USB-HOST\n"); in ssusb_extcon_register()
216 dev_dbg(ssusb->dev, "EXTCON_USB_HOST: %d\n", ret); in ssusb_extcon_register()
228 * This is useful in special cases, such as uses TYPE-A receptacle but also
229 * wants to support dual-role mode.
233 struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; in ssusb_mode_switch()
243 value = mtu3_readl(ssusb->ippc_base, SSUSB_U2_CTRL(0)); in ssusb_set_force_mode()
258 mtu3_writel(ssusb->ippc_base, SSUSB_U2_CTRL(0), value); in ssusb_set_force_mode()
261 static int ssusb_role_sw_set(struct usb_role_switch *sw, enum usb_role role) in ssusb_role_sw_set() argument
264 struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; in ssusb_role_sw_set()
266 ssusb_set_mode(otg_sx, role); in ssusb_role_sw_set()
275 return ssusb->is_host ? USB_ROLE_HOST : USB_ROLE_DEVICE; in ssusb_role_sw_get()
282 struct device *dev = ssusb->dev; in ssusb_role_sw_register()
285 if (!otg_sx->role_sw_used) in ssusb_role_sw_register()
290 otg_sx->default_role = USB_ROLE_DEVICE; in ssusb_role_sw_register()
292 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()