diff options
Diffstat (limited to 'drivers/usb/musb/ux500.c')
-rw-r--r-- | drivers/usb/musb/ux500.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 13a392913769..2c80004e0a83 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/usb/musb-ux500.h> | ||
29 | 30 | ||
30 | #include "musb_core.h" | 31 | #include "musb_core.h" |
31 | 32 | ||
@@ -36,6 +37,98 @@ struct ux500_glue { | |||
36 | }; | 37 | }; |
37 | #define glue_to_musb(g) platform_get_drvdata(g->musb) | 38 | #define glue_to_musb(g) platform_get_drvdata(g->musb) |
38 | 39 | ||
40 | static void ux500_musb_set_vbus(struct musb *musb, int is_on) | ||
41 | { | ||
42 | u8 devctl; | ||
43 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); | ||
44 | /* HDRC controls CPEN, but beware current surges during device | ||
45 | * connect. They can trigger transient overcurrent conditions | ||
46 | * that must be ignored. | ||
47 | */ | ||
48 | |||
49 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
50 | |||
51 | if (is_on) { | ||
52 | if (musb->xceiv->state == OTG_STATE_A_IDLE) { | ||
53 | /* start the session */ | ||
54 | devctl |= MUSB_DEVCTL_SESSION; | ||
55 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); | ||
56 | /* | ||
57 | * Wait for the musb to set as A device to enable the | ||
58 | * VBUS | ||
59 | */ | ||
60 | while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) { | ||
61 | |||
62 | if (time_after(jiffies, timeout)) { | ||
63 | dev_err(musb->controller, | ||
64 | "configured as A device timeout"); | ||
65 | break; | ||
66 | } | ||
67 | } | ||
68 | |||
69 | } else { | ||
70 | musb->is_active = 1; | ||
71 | musb->xceiv->otg->default_a = 1; | ||
72 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | ||
73 | devctl |= MUSB_DEVCTL_SESSION; | ||
74 | MUSB_HST_MODE(musb); | ||
75 | } | ||
76 | } else { | ||
77 | musb->is_active = 0; | ||
78 | |||
79 | /* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and jumping | ||
80 | * right to B_IDLE... | ||
81 | */ | ||
82 | musb->xceiv->otg->default_a = 0; | ||
83 | devctl &= ~MUSB_DEVCTL_SESSION; | ||
84 | MUSB_DEV_MODE(musb); | ||
85 | } | ||
86 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); | ||
87 | |||
88 | /* | ||
89 | * Devctl values will be updated after vbus goes below | ||
90 | * session_valid. The time taken depends on the capacitance | ||
91 | * on VBUS line. The max discharge time can be upto 1 sec | ||
92 | * as per the spec. Typically on our platform, it is 200ms | ||
93 | */ | ||
94 | if (!is_on) | ||
95 | mdelay(200); | ||
96 | |||
97 | dev_dbg(musb->controller, "VBUS %s, devctl %02x\n", | ||
98 | usb_otg_state_string(musb->xceiv->state), | ||
99 | musb_readb(musb->mregs, MUSB_DEVCTL)); | ||
100 | } | ||
101 | |||
102 | static int musb_otg_notifications(struct notifier_block *nb, | ||
103 | unsigned long event, void *unused) | ||
104 | { | ||
105 | struct musb *musb = container_of(nb, struct musb, nb); | ||
106 | |||
107 | dev_dbg(musb->controller, "musb_otg_notifications %ld %s\n", | ||
108 | event, usb_otg_state_string(musb->xceiv->state)); | ||
109 | |||
110 | switch (event) { | ||
111 | case UX500_MUSB_ID: | ||
112 | dev_dbg(musb->controller, "ID GND\n"); | ||
113 | ux500_musb_set_vbus(musb, 1); | ||
114 | break; | ||
115 | case UX500_MUSB_VBUS: | ||
116 | dev_dbg(musb->controller, "VBUS Connect\n"); | ||
117 | break; | ||
118 | case UX500_MUSB_NONE: | ||
119 | dev_dbg(musb->controller, "VBUS Disconnect\n"); | ||
120 | if (is_host_active(musb)) | ||
121 | ux500_musb_set_vbus(musb, 0); | ||
122 | else | ||
123 | musb->xceiv->state = OTG_STATE_B_IDLE; | ||
124 | break; | ||
125 | default: | ||
126 | dev_dbg(musb->controller, "ID float\n"); | ||
127 | return NOTIFY_DONE; | ||
128 | } | ||
129 | return NOTIFY_OK; | ||
130 | } | ||
131 | |||
39 | static irqreturn_t ux500_musb_interrupt(int irq, void *__hci) | 132 | static irqreturn_t ux500_musb_interrupt(int irq, void *__hci) |
40 | { | 133 | { |
41 | unsigned long flags; | 134 | unsigned long flags; |
@@ -58,12 +151,21 @@ static irqreturn_t ux500_musb_interrupt(int irq, void *__hci) | |||
58 | 151 | ||
59 | static int ux500_musb_init(struct musb *musb) | 152 | static int ux500_musb_init(struct musb *musb) |
60 | { | 153 | { |
154 | int status; | ||
155 | |||
61 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 156 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
62 | if (IS_ERR_OR_NULL(musb->xceiv)) { | 157 | if (IS_ERR_OR_NULL(musb->xceiv)) { |
63 | pr_err("HS USB OTG: no transceiver configured\n"); | 158 | pr_err("HS USB OTG: no transceiver configured\n"); |
64 | return -EPROBE_DEFER; | 159 | return -EPROBE_DEFER; |
65 | } | 160 | } |
66 | 161 | ||
162 | musb->nb.notifier_call = musb_otg_notifications; | ||
163 | status = usb_register_notifier(musb->xceiv, &musb->nb); | ||
164 | if (status < 0) { | ||
165 | dev_dbg(musb->controller, "notification register failed\n"); | ||
166 | return status; | ||
167 | } | ||
168 | |||
67 | musb->isr = ux500_musb_interrupt; | 169 | musb->isr = ux500_musb_interrupt; |
68 | 170 | ||
69 | return 0; | 171 | return 0; |
@@ -71,6 +173,8 @@ static int ux500_musb_init(struct musb *musb) | |||
71 | 173 | ||
72 | static int ux500_musb_exit(struct musb *musb) | 174 | static int ux500_musb_exit(struct musb *musb) |
73 | { | 175 | { |
176 | usb_unregister_notifier(musb->xceiv, &musb->nb); | ||
177 | |||
74 | usb_put_phy(musb->xceiv); | 178 | usb_put_phy(musb->xceiv); |
75 | 179 | ||
76 | return 0; | 180 | return 0; |
@@ -79,6 +183,8 @@ static int ux500_musb_exit(struct musb *musb) | |||
79 | static const struct musb_platform_ops ux500_ops = { | 183 | static const struct musb_platform_ops ux500_ops = { |
80 | .init = ux500_musb_init, | 184 | .init = ux500_musb_init, |
81 | .exit = ux500_musb_exit, | 185 | .exit = ux500_musb_exit, |
186 | |||
187 | .set_vbus = ux500_musb_set_vbus, | ||
82 | }; | 188 | }; |
83 | 189 | ||
84 | static int ux500_probe(struct platform_device *pdev) | 190 | static int ux500_probe(struct platform_device *pdev) |