Lines Matching +full:role +full:- +full:switch +full:- +full:default +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0
3 * mtu3_dr.c - dual role switch and host glue layer
24 mtu3_setbits(ssusb->mac_base, U3D_DEVICE_CONTROL, DC_SESSION); in toggle_opstate()
25 mtu3_setbits(ssusb->mac_base, U3D_POWER_MANAGEMENT, SOFT_CONN); in toggle_opstate()
28 /* only port0 supports dual-role mode */
32 void __iomem *ibase = ssusb->ippc_base; in ssusb_port0_switch()
35 dev_dbg(ssusb->dev, "%s (switch u%d port0 to %s)\n", __func__, in ssusb_port0_switch()
44 /* 2. power on, enable u2 port0 and select its mode */ in ssusb_port0_switch()
56 /* 2. power on, enable u3 port0 and select its mode */ in ssusb_port0_switch()
71 dev_dbg(ssusb->dev, "%s\n", __func__); in switch_port_to_host()
75 if (ssusb->otg_switch.is_u3_drd) { in switch_port_to_host()
90 dev_dbg(ssusb->dev, "%s\n", __func__); in switch_port_to_device()
94 if (ssusb->otg_switch.is_u3_drd) { in switch_port_to_device()
105 struct regulator *vbus = otg_sx->vbus; in ssusb_set_vbus()
112 dev_dbg(ssusb->dev, "%s: turn %s\n", __func__, is_on ? "on" : "off"); in ssusb_set_vbus()
117 dev_err(ssusb->dev, "vbus regulator enable failed\n"); in ssusb_set_vbus()
132 struct mtu3 *mtu = ssusb->u3d; in ssusb_mode_sw_work()
133 enum usb_role desired_role = otg_sx->desired_role; in ssusb_mode_sw_work()
136 current_role = ssusb->is_host ? USB_ROLE_HOST : USB_ROLE_DEVICE; in ssusb_mode_sw_work()
139 /* the default mode is host as probe does */ in ssusb_mode_sw_work()
141 if (otg_sx->default_role == USB_ROLE_DEVICE) in ssusb_mode_sw_work()
148 dev_dbg(ssusb->dev, "set role : %s\n", usb_role_string(desired_role)); in ssusb_mode_sw_work()
149 mtu3_dbg_trace(ssusb->dev, "set role : %s", usb_role_string(desired_role)); in ssusb_mode_sw_work()
150 pm_runtime_get_sync(ssusb->dev); in ssusb_mode_sw_work()
152 switch (desired_role) { in ssusb_mode_sw_work()
158 ssusb->is_host = true; in ssusb_mode_sw_work()
162 ssusb->is_host = false; in ssusb_mode_sw_work()
168 default: in ssusb_mode_sw_work()
169 dev_err(ssusb->dev, "invalid role\n"); in ssusb_mode_sw_work()
171 pm_runtime_put(ssusb->dev); in ssusb_mode_sw_work()
174 static void ssusb_set_mode(struct otg_switch_mtk *otg_sx, enum usb_role role) in ssusb_set_mode() argument
178 if (ssusb->dr_mode != USB_DR_MODE_OTG) in ssusb_set_mode()
181 otg_sx->desired_role = role; in ssusb_set_mode()
182 queue_work(system_freezable_wq, &otg_sx->dr_work); in ssusb_set_mode()
199 struct extcon_dev *edev = otg_sx->edev; in ssusb_extcon_register()
206 otg_sx->id_nb.notifier_call = ssusb_id_notifier; in ssusb_extcon_register()
207 ret = devm_extcon_register_notifier(ssusb->dev, edev, EXTCON_USB_HOST, in ssusb_extcon_register()
208 &otg_sx->id_nb); in ssusb_extcon_register()
210 dev_err(ssusb->dev, "failed to register notifier for USB-HOST\n"); in ssusb_extcon_register()
215 dev_dbg(ssusb->dev, "EXTCON_USB_HOST: %d\n", ret); in ssusb_extcon_register()
217 /* default as host, switch to device mode if needed */ in ssusb_extcon_register()
225 * We provide an interface via debugfs to switch between host and device modes
227 * This is useful in special cases, such as uses TYPE-A receptacle but also
228 * wants to support dual-role mode.
232 struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; in ssusb_mode_switch()
238 enum mtu3_dr_force_mode mode) in ssusb_set_force_mode() argument
242 value = mtu3_readl(ssusb->ippc_base, SSUSB_U2_CTRL(0)); in ssusb_set_force_mode()
243 switch (mode) { in ssusb_set_force_mode()
254 default: in ssusb_set_force_mode()
257 mtu3_writel(ssusb->ippc_base, SSUSB_U2_CTRL(0), value); in ssusb_set_force_mode()
260 static int ssusb_role_sw_set(struct usb_role_switch *sw, enum usb_role role) in ssusb_role_sw_set() argument
263 struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; in ssusb_role_sw_set()
265 ssusb_set_mode(otg_sx, role); in ssusb_role_sw_set()
274 return ssusb->is_host ? USB_ROLE_HOST : USB_ROLE_DEVICE; in ssusb_role_sw_get()
281 struct device *dev = ssusb->dev; in ssusb_role_sw_register()
282 enum usb_dr_mode mode; in ssusb_role_sw_register() local
284 if (!otg_sx->role_sw_used) in ssusb_role_sw_register()
287 mode = usb_get_role_switch_default_mode(dev); in ssusb_role_sw_register()
288 if (mode == USB_DR_MODE_PERIPHERAL) in ssusb_role_sw_register()
289 otg_sx->default_role = USB_ROLE_DEVICE; in ssusb_role_sw_register()
291 otg_sx->default_role = USB_ROLE_HOST; in ssusb_role_sw_register()
298 otg_sx->role_sw = usb_role_switch_register(dev, &role_sx_desc); in ssusb_role_sw_register()
299 if (IS_ERR(otg_sx->role_sw)) in ssusb_role_sw_register()
300 return PTR_ERR(otg_sx->role_sw); in ssusb_role_sw_register()
302 ssusb_set_mode(otg_sx, otg_sx->default_role); in ssusb_role_sw_register()
309 struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; in ssusb_otg_switch_init()
312 INIT_WORK(&otg_sx->dr_work, ssusb_mode_sw_work); in ssusb_otg_switch_init()
314 if (otg_sx->manual_drd_enabled) in ssusb_otg_switch_init()
316 else if (otg_sx->role_sw_used) in ssusb_otg_switch_init()
326 struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; in ssusb_otg_switch_exit()
328 cancel_work_sync(&otg_sx->dr_work); in ssusb_otg_switch_exit()
329 usb_role_switch_unregister(otg_sx->role_sw); in ssusb_otg_switch_exit()