1 // SPDX-License-Identifier: GPL-2.0
3 * drd.c - DesignWare USB3 DRD Controller Dual-role support
5 * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com
7 * Authors: Roger Quadros <rogerq@ti.com>
10 #include <linux/extcon.h>
16 static void dwc3_drd_update(struct dwc3
*dwc
)
20 id
= extcon_get_state(dwc
->edev
, EXTCON_USB_HOST
);
24 dwc3_set_mode(dwc
, id
?
25 DWC3_GCTL_PRTCAP_HOST
:
26 DWC3_GCTL_PRTCAP_DEVICE
);
29 static int dwc3_drd_notifier(struct notifier_block
*nb
,
30 unsigned long event
, void *ptr
)
32 struct dwc3
*dwc
= container_of(nb
, struct dwc3
, edev_nb
);
34 dwc3_set_mode(dwc
, event
?
35 DWC3_GCTL_PRTCAP_HOST
:
36 DWC3_GCTL_PRTCAP_DEVICE
);
41 int dwc3_drd_init(struct dwc3
*dwc
)
45 if (dwc
->dev
->of_node
) {
46 if (of_property_read_bool(dwc
->dev
->of_node
, "extcon"))
47 dwc
->edev
= extcon_get_edev_by_phandle(dwc
->dev
, 0);
49 if (IS_ERR(dwc
->edev
))
50 return PTR_ERR(dwc
->edev
);
52 dwc
->edev_nb
.notifier_call
= dwc3_drd_notifier
;
53 ret
= extcon_register_notifier(dwc
->edev
, EXTCON_USB_HOST
,
56 dev_err(dwc
->dev
, "couldn't register cable notifier\n");
66 void dwc3_drd_exit(struct dwc3
*dwc
)
68 extcon_unregister_notifier(dwc
->edev
, EXTCON_USB_HOST
,
71 dwc3_set_mode(dwc
, DWC3_GCTL_PRTCAP_DEVICE
);
72 flush_work(&dwc
->drd_work
);
73 dwc3_gadget_exit(dwc
);