Merge branch 'upstream/core' into upstream/xen
[cascardo/linux.git] / drivers / usb / musb / omap2430.c
1 /*
2  * Copyright (C) 2005-2007 by Texas Instruments
3  * Some code has been taken from tusb6010.c
4  * Copyrights for that are attributable to:
5  * Copyright (C) 2006 Nokia Corporation
6  * Tony Lindgren <tony@atomide.com>
7  *
8  * This file is part of the Inventra Controller Driver for Linux.
9  *
10  * The Inventra Controller Driver for Linux is free software; you
11  * can redistribute it and/or modify it under the terms of the GNU
12  * General Public License version 2 as published by the Free Software
13  * Foundation.
14  *
15  * The Inventra Controller Driver for Linux is distributed in
16  * the hope that it will be useful, but WITHOUT ANY WARRANTY;
17  * without even the implied warranty of MERCHANTABILITY or
18  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
19  * License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with The Inventra Controller Driver for Linux ; if not,
23  * write to the Free Software Foundation, Inc., 59 Temple Place,
24  * Suite 330, Boston, MA  02111-1307  USA
25  *
26  */
27 #include <linux/module.h>
28 #include <linux/kernel.h>
29 #include <linux/sched.h>
30 #include <linux/init.h>
31 #include <linux/list.h>
32 #include <linux/clk.h>
33 #include <linux/io.h>
34
35 #include <plat/mux.h>
36
37 #include "musb_core.h"
38 #include "omap2430.h"
39
40
41 static struct timer_list musb_idle_timer;
42
43 static void musb_do_idle(unsigned long _musb)
44 {
45         struct musb     *musb = (void *)_musb;
46         unsigned long   flags;
47 #ifdef CONFIG_USB_MUSB_HDRC_HCD
48         u8      power;
49 #endif
50         u8      devctl;
51
52         spin_lock_irqsave(&musb->lock, flags);
53
54         devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
55
56         switch (musb->xceiv->state) {
57         case OTG_STATE_A_WAIT_BCON:
58                 devctl &= ~MUSB_DEVCTL_SESSION;
59                 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
60
61                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
62                 if (devctl & MUSB_DEVCTL_BDEVICE) {
63                         musb->xceiv->state = OTG_STATE_B_IDLE;
64                         MUSB_DEV_MODE(musb);
65                 } else {
66                         musb->xceiv->state = OTG_STATE_A_IDLE;
67                         MUSB_HST_MODE(musb);
68                 }
69                 break;
70 #ifdef CONFIG_USB_MUSB_HDRC_HCD
71         case OTG_STATE_A_SUSPEND:
72                 /* finish RESUME signaling? */
73                 if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
74                         power = musb_readb(musb->mregs, MUSB_POWER);
75                         power &= ~MUSB_POWER_RESUME;
76                         DBG(1, "root port resume stopped, power %02x\n", power);
77                         musb_writeb(musb->mregs, MUSB_POWER, power);
78                         musb->is_active = 1;
79                         musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
80                                                 | MUSB_PORT_STAT_RESUME);
81                         musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
82                         usb_hcd_poll_rh_status(musb_to_hcd(musb));
83                         /* NOTE: it might really be A_WAIT_BCON ... */
84                         musb->xceiv->state = OTG_STATE_A_HOST;
85                 }
86                 break;
87 #endif
88 #ifdef CONFIG_USB_MUSB_HDRC_HCD
89         case OTG_STATE_A_HOST:
90                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
91                 if (devctl &  MUSB_DEVCTL_BDEVICE)
92                         musb->xceiv->state = OTG_STATE_B_IDLE;
93                 else
94                         musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
95 #endif
96         default:
97                 break;
98         }
99         spin_unlock_irqrestore(&musb->lock, flags);
100 }
101
102
103 void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
104 {
105         unsigned long           default_timeout = jiffies + msecs_to_jiffies(3);
106         static unsigned long    last_timer;
107
108         if (timeout == 0)
109                 timeout = default_timeout;
110
111         /* Never idle if active, or when VBUS timeout is not set as host */
112         if (musb->is_active || ((musb->a_wait_bcon == 0)
113                         && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
114                 DBG(4, "%s active, deleting timer\n", otg_state_string(musb));
115                 del_timer(&musb_idle_timer);
116                 last_timer = jiffies;
117                 return;
118         }
119
120         if (time_after(last_timer, timeout)) {
121                 if (!timer_pending(&musb_idle_timer))
122                         last_timer = timeout;
123                 else {
124                         DBG(4, "Longer idle timer already pending, ignoring\n");
125                         return;
126                 }
127         }
128         last_timer = timeout;
129
130         DBG(4, "%s inactive, for idle timer for %lu ms\n",
131                 otg_state_string(musb),
132                 (unsigned long)jiffies_to_msecs(timeout - jiffies));
133         mod_timer(&musb_idle_timer, timeout);
134 }
135
136 void musb_platform_enable(struct musb *musb)
137 {
138 }
139 void musb_platform_disable(struct musb *musb)
140 {
141 }
142 static void omap_set_vbus(struct musb *musb, int is_on)
143 {
144         u8              devctl;
145         /* HDRC controls CPEN, but beware current surges during device
146          * connect.  They can trigger transient overcurrent conditions
147          * that must be ignored.
148          */
149
150         devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
151
152         if (is_on) {
153                 musb->is_active = 1;
154                 musb->xceiv->default_a = 1;
155                 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
156                 devctl |= MUSB_DEVCTL_SESSION;
157
158                 MUSB_HST_MODE(musb);
159         } else {
160                 musb->is_active = 0;
161
162                 /* NOTE:  we're skipping A_WAIT_VFALL -> A_IDLE and
163                  * jumping right to B_IDLE...
164                  */
165
166                 musb->xceiv->default_a = 0;
167                 musb->xceiv->state = OTG_STATE_B_IDLE;
168                 devctl &= ~MUSB_DEVCTL_SESSION;
169
170                 MUSB_DEV_MODE(musb);
171         }
172         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
173
174         DBG(1, "VBUS %s, devctl %02x "
175                 /* otg %3x conf %08x prcm %08x */ "\n",
176                 otg_state_string(musb),
177                 musb_readb(musb->mregs, MUSB_DEVCTL));
178 }
179
180 static int musb_platform_resume(struct musb *musb);
181
182 int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
183 {
184         u8      devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
185
186         devctl |= MUSB_DEVCTL_SESSION;
187         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
188
189         return 0;
190 }
191
192 int __init musb_platform_init(struct musb *musb, void *board_data)
193 {
194         u32 l;
195         struct omap_musb_board_data *data = board_data;
196
197 #if defined(CONFIG_ARCH_OMAP2430)
198         omap_cfg_reg(AE5_2430_USB0HS_STP);
199 #endif
200
201         /* We require some kind of external transceiver, hooked
202          * up through ULPI.  TWL4030-family PMICs include one,
203          * which needs a driver, drivers aren't always needed.
204          */
205         musb->xceiv = otg_get_transceiver();
206         if (!musb->xceiv) {
207                 pr_err("HS USB OTG: no transceiver configured\n");
208                 return -ENODEV;
209         }
210
211         musb_platform_resume(musb);
212
213         l = musb_readl(musb->mregs, OTG_SYSCONFIG);
214         l &= ~ENABLEWAKEUP;     /* disable wakeup */
215         l &= ~NOSTDBY;          /* remove possible nostdby */
216         l |= SMARTSTDBY;        /* enable smart standby */
217         l &= ~AUTOIDLE;         /* disable auto idle */
218         l &= ~NOIDLE;           /* remove possible noidle */
219         l |= SMARTIDLE;         /* enable smart idle */
220         /*
221          * MUSB AUTOIDLE don't work in 3430.
222          * Workaround by Richard Woodruff/TI
223          */
224         if (!cpu_is_omap3430())
225                 l |= AUTOIDLE;          /* enable auto idle */
226         musb_writel(musb->mregs, OTG_SYSCONFIG, l);
227
228         l = musb_readl(musb->mregs, OTG_INTERFSEL);
229
230         if (data->interface_type == MUSB_INTERFACE_UTMI) {
231                 /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
232                 l &= ~ULPI_12PIN;       /* Disable ULPI */
233                 l |= UTMI_8BIT;         /* Enable UTMI  */
234         } else {
235                 l |= ULPI_12PIN;
236         }
237
238         musb_writel(musb->mregs, OTG_INTERFSEL, l);
239
240         pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
241                         "sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
242                         musb_readl(musb->mregs, OTG_REVISION),
243                         musb_readl(musb->mregs, OTG_SYSCONFIG),
244                         musb_readl(musb->mregs, OTG_SYSSTATUS),
245                         musb_readl(musb->mregs, OTG_INTERFSEL),
246                         musb_readl(musb->mregs, OTG_SIMENABLE));
247
248         if (is_host_enabled(musb))
249                 musb->board_set_vbus = omap_set_vbus;
250
251         setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
252
253         return 0;
254 }
255
256 #ifdef CONFIG_PM
257 void musb_platform_save_context(struct musb *musb,
258                 struct musb_context_registers *musb_context)
259 {
260         musb_context->otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG);
261         musb_context->otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY);
262 }
263
264 void musb_platform_restore_context(struct musb *musb,
265                 struct musb_context_registers *musb_context)
266 {
267         musb_writel(musb->mregs, OTG_SYSCONFIG, musb_context->otg_sysconfig);
268         musb_writel(musb->mregs, OTG_FORCESTDBY, musb_context->otg_forcestandby);
269 }
270 #endif
271
272 static int musb_platform_suspend(struct musb *musb)
273 {
274         u32 l;
275
276         if (!musb->clock)
277                 return 0;
278
279         /* in any role */
280         l = musb_readl(musb->mregs, OTG_FORCESTDBY);
281         l |= ENABLEFORCE;       /* enable MSTANDBY */
282         musb_writel(musb->mregs, OTG_FORCESTDBY, l);
283
284         l = musb_readl(musb->mregs, OTG_SYSCONFIG);
285         l |= ENABLEWAKEUP;      /* enable wakeup */
286         musb_writel(musb->mregs, OTG_SYSCONFIG, l);
287
288         otg_set_suspend(musb->xceiv, 1);
289
290         if (musb->set_clock)
291                 musb->set_clock(musb->clock, 0);
292         else
293                 clk_disable(musb->clock);
294
295         return 0;
296 }
297
298 static int musb_platform_resume(struct musb *musb)
299 {
300         u32 l;
301
302         if (!musb->clock)
303                 return 0;
304
305         otg_set_suspend(musb->xceiv, 0);
306
307         if (musb->set_clock)
308                 musb->set_clock(musb->clock, 1);
309         else
310                 clk_enable(musb->clock);
311
312         l = musb_readl(musb->mregs, OTG_SYSCONFIG);
313         l &= ~ENABLEWAKEUP;     /* disable wakeup */
314         musb_writel(musb->mregs, OTG_SYSCONFIG, l);
315
316         l = musb_readl(musb->mregs, OTG_FORCESTDBY);
317         l &= ~ENABLEFORCE;      /* disable MSTANDBY */
318         musb_writel(musb->mregs, OTG_FORCESTDBY, l);
319
320         return 0;
321 }
322
323
324 int musb_platform_exit(struct musb *musb)
325 {
326
327         musb_platform_suspend(musb);
328
329         return 0;
330 }