1 #include <linux/module.h>
2 #include <linux/platform_device.h>
6 #include <linux/delay.h>
7 #include <linux/usb/otg.h>
8 #include "phy-am335x-control.h"
10 struct am335x_control_usb
{
12 void __iomem
*phy_reg
;
15 struct phy_control phy_ctrl
;
18 #define AM335X_USB0_CTRL 0x0
19 #define AM335X_USB1_CTRL 0x8
20 #define AM335x_USB_WKUP 0x0
22 #define USBPHY_CM_PWRDN (1 << 0)
23 #define USBPHY_OTG_PWRDN (1 << 1)
24 #define USBPHY_OTGVDET_EN (1 << 19)
25 #define USBPHY_OTGSESSEND_EN (1 << 20)
27 #define AM335X_PHY0_WK_EN (1 << 0)
28 #define AM335X_PHY1_WK_EN (1 << 8)
30 static void am335x_phy_wkup(struct phy_control
*phy_ctrl
, u32 id
, bool on
)
32 struct am335x_control_usb
*usb_ctrl
;
36 usb_ctrl
= container_of(phy_ctrl
, struct am335x_control_usb
, phy_ctrl
);
40 reg
= AM335X_PHY0_WK_EN
;
43 reg
= AM335X_PHY1_WK_EN
;
50 spin_lock(&usb_ctrl
->lock
);
51 val
= readl(usb_ctrl
->wkup
);
58 writel(val
, usb_ctrl
->wkup
);
59 spin_unlock(&usb_ctrl
->lock
);
62 static void am335x_phy_power(struct phy_control
*phy_ctrl
, u32 id
,
63 enum usb_dr_mode dr_mode
, bool on
)
65 struct am335x_control_usb
*usb_ctrl
;
69 usb_ctrl
= container_of(phy_ctrl
, struct am335x_control_usb
, phy_ctrl
);
73 reg
= AM335X_USB0_CTRL
;
76 reg
= AM335X_USB1_CTRL
;
83 val
= readl(usb_ctrl
->phy_reg
+ reg
);
85 if (dr_mode
== USB_DR_MODE_HOST
) {
86 val
&= ~(USBPHY_CM_PWRDN
| USBPHY_OTG_PWRDN
|
88 val
|= USBPHY_OTGSESSEND_EN
;
90 val
&= ~(USBPHY_CM_PWRDN
| USBPHY_OTG_PWRDN
);
91 val
|= USBPHY_OTGVDET_EN
| USBPHY_OTGSESSEND_EN
;
94 val
|= USBPHY_CM_PWRDN
| USBPHY_OTG_PWRDN
;
97 writel(val
, usb_ctrl
->phy_reg
+ reg
);
100 * Give the PHY ~1ms to complete the power up operation.
101 * Tests have shown unstable behaviour if other USB PHY related
102 * registers are written too shortly after such a transition.
108 static const struct phy_control ctrl_am335x
= {
109 .phy_power
= am335x_phy_power
,
110 .phy_wkup
= am335x_phy_wkup
,
113 static const struct of_device_id omap_control_usb_id_table
[] = {
114 { .compatible
= "ti,am335x-usb-ctrl-module", .data
= &ctrl_am335x
},
117 MODULE_DEVICE_TABLE(of
, omap_control_usb_id_table
);
119 static struct platform_driver am335x_control_driver
;
120 static int match(struct device
*dev
, void *data
)
122 struct device_node
*node
= (struct device_node
*)data
;
123 return dev
->of_node
== node
&&
124 dev
->driver
== &am335x_control_driver
.driver
;
127 struct phy_control
*am335x_get_phy_control(struct device
*dev
)
129 struct device_node
*node
;
130 struct am335x_control_usb
*ctrl_usb
;
132 node
= of_parse_phandle(dev
->of_node
, "ti,ctrl_mod", 0);
136 dev
= bus_find_device(&platform_bus_type
, NULL
, node
, match
);
140 ctrl_usb
= dev_get_drvdata(dev
);
143 return &ctrl_usb
->phy_ctrl
;
145 EXPORT_SYMBOL_GPL(am335x_get_phy_control
);
147 static int am335x_control_usb_probe(struct platform_device
*pdev
)
149 struct resource
*res
;
150 struct am335x_control_usb
*ctrl_usb
;
151 const struct of_device_id
*of_id
;
152 const struct phy_control
*phy_ctrl
;
154 of_id
= of_match_node(omap_control_usb_id_table
, pdev
->dev
.of_node
);
158 phy_ctrl
= of_id
->data
;
160 ctrl_usb
= devm_kzalloc(&pdev
->dev
, sizeof(*ctrl_usb
), GFP_KERNEL
);
164 ctrl_usb
->dev
= &pdev
->dev
;
166 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "phy_ctrl");
167 ctrl_usb
->phy_reg
= devm_ioremap_resource(&pdev
->dev
, res
);
168 if (IS_ERR(ctrl_usb
->phy_reg
))
169 return PTR_ERR(ctrl_usb
->phy_reg
);
171 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "wakeup");
172 ctrl_usb
->wkup
= devm_ioremap_resource(&pdev
->dev
, res
);
173 if (IS_ERR(ctrl_usb
->wkup
))
174 return PTR_ERR(ctrl_usb
->wkup
);
176 spin_lock_init(&ctrl_usb
->lock
);
177 ctrl_usb
->phy_ctrl
= *phy_ctrl
;
179 dev_set_drvdata(ctrl_usb
->dev
, ctrl_usb
);
183 static struct platform_driver am335x_control_driver
= {
184 .probe
= am335x_control_usb_probe
,
186 .name
= "am335x-control-usb",
187 .of_match_table
= omap_control_usb_id_table
,
191 module_platform_driver(am335x_control_driver
);
192 MODULE_LICENSE("GPL v2");