1 #include <linux/module.h>
2 #include <linux/platform_device.h>
3 #include <linux/dma-mapping.h>
4 #include <linux/usb/otg.h>
5 #include <linux/usb/usb_phy_generic.h>
6 #include <linux/slab.h>
9 #include <linux/of_address.h>
10 #include <linux/usb/of.h>
12 #include "phy-am335x-control.h"
13 #include "phy-generic.h"
16 struct usb_phy_generic usb_phy_gen
;
17 struct phy_control
*phy_ctrl
;
19 enum usb_dr_mode dr_mode
;
22 static int am335x_init(struct usb_phy
*phy
)
24 struct am335x_phy
*am_phy
= dev_get_drvdata(phy
->dev
);
26 phy_ctrl_power(am_phy
->phy_ctrl
, am_phy
->id
, am_phy
->dr_mode
, true);
30 static void am335x_shutdown(struct usb_phy
*phy
)
32 struct am335x_phy
*am_phy
= dev_get_drvdata(phy
->dev
);
34 phy_ctrl_power(am_phy
->phy_ctrl
, am_phy
->id
, am_phy
->dr_mode
, false);
37 static int am335x_phy_probe(struct platform_device
*pdev
)
39 struct am335x_phy
*am_phy
;
40 struct device
*dev
= &pdev
->dev
;
43 am_phy
= devm_kzalloc(dev
, sizeof(*am_phy
), GFP_KERNEL
);
47 am_phy
->phy_ctrl
= am335x_get_phy_control(dev
);
48 if (!am_phy
->phy_ctrl
)
51 am_phy
->id
= of_alias_get_id(pdev
->dev
.of_node
, "phy");
53 dev_err(&pdev
->dev
, "Missing PHY id: %d\n", am_phy
->id
);
57 am_phy
->dr_mode
= of_usb_get_dr_mode_by_phy(pdev
->dev
.of_node
);
59 ret
= usb_phy_gen_create_phy(dev
, &am_phy
->usb_phy_gen
, NULL
);
63 ret
= usb_add_phy_dev(&am_phy
->usb_phy_gen
.phy
);
66 am_phy
->usb_phy_gen
.phy
.init
= am335x_init
;
67 am_phy
->usb_phy_gen
.phy
.shutdown
= am335x_shutdown
;
69 platform_set_drvdata(pdev
, am_phy
);
70 device_init_wakeup(dev
, true);
73 * If we leave PHY wakeup enabled then AM33XX wakes up
74 * immediately from DS0. To avoid this we mark dev->power.can_wakeup
75 * to false. The same is checked in suspend routine to decide
76 * on whether to enable PHY wakeup or not.
77 * PHY wakeup works fine in standby mode, there by allowing us to
78 * handle remote wakeup, wakeup on disconnect and connect.
81 device_set_wakeup_enable(dev
, false);
82 phy_ctrl_power(am_phy
->phy_ctrl
, am_phy
->id
, am_phy
->dr_mode
, false);
87 static int am335x_phy_remove(struct platform_device
*pdev
)
89 struct am335x_phy
*am_phy
= platform_get_drvdata(pdev
);
91 usb_remove_phy(&am_phy
->usb_phy_gen
.phy
);
95 #ifdef CONFIG_PM_SLEEP
96 static int am335x_phy_suspend(struct device
*dev
)
98 struct platform_device
*pdev
= to_platform_device(dev
);
99 struct am335x_phy
*am_phy
= platform_get_drvdata(pdev
);
102 * Enable phy wakeup only if dev->power.can_wakeup is true.
103 * Make sure to enable wakeup to support remote wakeup in
104 * standby mode ( same is not supported in OFF(DS0) mode).
106 * echo enabled > /sys/bus/platform/devices/<usb-phy-id>/power/wakeup
109 if (device_may_wakeup(dev
))
110 phy_ctrl_wkup(am_phy
->phy_ctrl
, am_phy
->id
, true);
112 phy_ctrl_power(am_phy
->phy_ctrl
, am_phy
->id
, am_phy
->dr_mode
, false);
117 static int am335x_phy_resume(struct device
*dev
)
119 struct platform_device
*pdev
= to_platform_device(dev
);
120 struct am335x_phy
*am_phy
= platform_get_drvdata(pdev
);
122 phy_ctrl_power(am_phy
->phy_ctrl
, am_phy
->id
, am_phy
->dr_mode
, true);
124 if (device_may_wakeup(dev
))
125 phy_ctrl_wkup(am_phy
->phy_ctrl
, am_phy
->id
, false);
131 static SIMPLE_DEV_PM_OPS(am335x_pm_ops
, am335x_phy_suspend
, am335x_phy_resume
);
133 static const struct of_device_id am335x_phy_ids
[] = {
134 { .compatible
= "ti,am335x-usb-phy" },
137 MODULE_DEVICE_TABLE(of
, am335x_phy_ids
);
139 static struct platform_driver am335x_phy_driver
= {
140 .probe
= am335x_phy_probe
,
141 .remove
= am335x_phy_remove
,
143 .name
= "am335x-phy-driver",
144 .pm
= &am335x_pm_ops
,
145 .of_match_table
= am335x_phy_ids
,
149 module_platform_driver(am335x_phy_driver
);
150 MODULE_LICENSE("GPL v2");