Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.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 <asm/mach-types.h>
36 #include <mach/hardware.h>
37 #include <plat/mux.h>
38
39 #include "musb_core.h"
40 #include "omap2430.h"
41
42 #ifdef CONFIG_ARCH_OMAP3430
43 #define get_cpu_rev()   2
44 #endif
45
46
47 static struct timer_list musb_idle_timer;
48
49 static void musb_do_idle(unsigned long _musb)
50 {
51         struct musb     *musb = (void *)_musb;
52         unsigned long   flags;
53 #ifdef CONFIG_USB_MUSB_HDRC_HCD
54         u8      power;
55 #endif
56         u8      devctl;
57
58         spin_lock_irqsave(&musb->lock, flags);
59
60         devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
61
62         switch (musb->xceiv->state) {
63         case OTG_STATE_A_WAIT_BCON:
64                 devctl &= ~MUSB_DEVCTL_SESSION;
65                 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
66
67                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
68                 if (devctl & MUSB_DEVCTL_BDEVICE) {
69                         musb->xceiv->state = OTG_STATE_B_IDLE;
70                         MUSB_DEV_MODE(musb);
71                 } else {
72                         musb->xceiv->state = OTG_STATE_A_IDLE;
73                         MUSB_HST_MODE(musb);
74                 }
75                 break;
76 #ifdef CONFIG_USB_MUSB_HDRC_HCD
77         case OTG_STATE_A_SUSPEND:
78                 /* finish RESUME signaling? */
79                 if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
80                         power = musb_readb(musb->mregs, MUSB_POWER);
81                         power &= ~MUSB_POWER_RESUME;
82                         DBG(1, "root port resume stopped, power %02x\n", power);
83                         musb_writeb(musb->mregs, MUSB_POWER, power);
84                         musb->is_active = 1;
85                         musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
86                                                 | MUSB_PORT_STAT_RESUME);
87                         musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
88                         usb_hcd_poll_rh_status(musb_to_hcd(musb));
89                         /* NOTE: it might really be A_WAIT_BCON ... */
90                         musb->xceiv->state = OTG_STATE_A_HOST;
91                 }
92                 break;
93 #endif
94 #ifdef CONFIG_USB_MUSB_HDRC_HCD
95         case OTG_STATE_A_HOST:
96                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
97                 if (devctl &  MUSB_DEVCTL_BDEVICE)
98                         musb->xceiv->state = OTG_STATE_B_IDLE;
99                 else
100                         musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
101 #endif
102         default:
103                 break;
104         }
105         spin_unlock_irqrestore(&musb->lock, flags);
106 }
107
108
109 void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
110 {
111         unsigned long           default_timeout = jiffies + msecs_to_jiffies(3);
112         static unsigned long    last_timer;
113
114         if (timeout == 0)
115                 timeout = default_timeout;
116
117         /* Never idle if active, or when VBUS timeout is not set as host */
118         if (musb->is_active || ((musb->a_wait_bcon == 0)
119                         && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
120                 DBG(4, "%s active, deleting timer\n", otg_state_string(musb));
121                 del_timer(&musb_idle_timer);
122                 last_timer = jiffies;
123                 return;
124         }
125
126         if (time_after(last_timer, timeout)) {
127                 if (!timer_pending(&musb_idle_timer))
128                         last_timer = timeout;
129                 else {
130                         DBG(4, "Longer idle timer already pending, ignoring\n");
131                         return;
132                 }
133         }
134         last_timer = timeout;
135
136         DBG(4, "%s inactive, for idle timer for %lu ms\n",
137                 otg_state_string(musb),
138                 (unsigned long)jiffies_to_msecs(timeout - jiffies));
139         mod_timer(&musb_idle_timer, timeout);
140 }
141
142 void musb_platform_enable(struct musb *musb)
143 {
144 }
145 void musb_platform_disable(struct musb *musb)
146 {
147 }
148 static void omap_vbus_power(struct musb *musb, int is_on, int sleeping)
149 {
150 }
151
152 static void omap_set_vbus(struct musb *musb, int is_on)
153 {
154         u8              devctl;
155         /* HDRC controls CPEN, but beware current surges during device
156          * connect.  They can trigger transient overcurrent conditions
157          * that must be ignored.
158          */
159
160         devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
161
162         if (is_on) {
163                 musb->is_active = 1;
164                 musb->xceiv->default_a = 1;
165                 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
166                 devctl |= MUSB_DEVCTL_SESSION;
167
168                 MUSB_HST_MODE(musb);
169         } else {
170                 musb->is_active = 0;
171
172                 /* NOTE:  we're skipping A_WAIT_VFALL -> A_IDLE and
173                  * jumping right to B_IDLE...
174                  */
175
176                 musb->xceiv->default_a = 0;
177                 musb->xceiv->state = OTG_STATE_B_IDLE;
178                 devctl &= ~MUSB_DEVCTL_SESSION;
179
180                 MUSB_DEV_MODE(musb);
181         }
182         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
183
184         DBG(1, "VBUS %s, devctl %02x "
185                 /* otg %3x conf %08x prcm %08x */ "\n",
186                 otg_state_string(musb),
187                 musb_readb(musb->mregs, MUSB_DEVCTL));
188 }
189
190 static int musb_platform_resume(struct musb *musb);
191
192 int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
193 {
194         u8      devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
195
196         devctl |= MUSB_DEVCTL_SESSION;
197         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
198
199         return 0;
200 }
201
202 int __init musb_platform_init(struct musb *musb)
203 {
204         u32 l;
205
206 #if defined(CONFIG_ARCH_OMAP2430)
207         omap_cfg_reg(AE5_2430_USB0HS_STP);
208 #endif
209
210         /* We require some kind of external transceiver, hooked
211          * up through ULPI.  TWL4030-family PMICs include one,
212          * which needs a driver, drivers aren't always needed.
213          */
214         musb->xceiv = otg_get_transceiver();
215         if (!musb->xceiv) {
216                 pr_err("HS USB OTG: no transceiver configured\n");
217                 return -ENODEV;
218         }
219
220         musb_platform_resume(musb);
221
222         l = musb_readl(musb->mregs, OTG_SYSCONFIG);
223         l &= ~ENABLEWAKEUP;     /* disable wakeup */
224         l &= ~NOSTDBY;          /* remove possible nostdby */
225         l |= SMARTSTDBY;        /* enable smart standby */
226         l &= ~AUTOIDLE;         /* disable auto idle */
227         l &= ~NOIDLE;           /* remove possible noidle */
228         l |= SMARTIDLE;         /* enable smart idle */
229         /*
230          * MUSB AUTOIDLE don't work in 3430.
231          * Workaround by Richard Woodruff/TI
232          */
233         if (!cpu_is_omap3430())
234                 l |= AUTOIDLE;          /* enable auto idle */
235         musb_writel(musb->mregs, OTG_SYSCONFIG, l);
236
237         l = musb_readl(musb->mregs, OTG_INTERFSEL);
238         l |= ULPI_12PIN;
239         musb_writel(musb->mregs, OTG_INTERFSEL, l);
240
241         pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
242                         "sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
243                         musb_readl(musb->mregs, OTG_REVISION),
244                         musb_readl(musb->mregs, OTG_SYSCONFIG),
245                         musb_readl(musb->mregs, OTG_SYSSTATUS),
246                         musb_readl(musb->mregs, OTG_INTERFSEL),
247                         musb_readl(musb->mregs, OTG_SIMENABLE));
248
249         omap_vbus_power(musb, musb->board_mode == MUSB_HOST, 1);
250
251         if (is_host_enabled(musb))
252                 musb->board_set_vbus = omap_set_vbus;
253
254         setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
255
256         return 0;
257 }
258
259 #ifdef CONFIG_PM
260 void musb_platform_save_context(struct musb *musb,
261                 struct musb_context_registers *musb_context)
262 {
263         musb_context->otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG);
264         musb_context->otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY);
265 }
266
267 void musb_platform_restore_context(struct musb *musb,
268                 struct musb_context_registers *musb_context)
269 {
270         musb_writel(musb->mregs, OTG_SYSCONFIG, musb_context->otg_sysconfig);
271         musb_writel(musb->mregs, OTG_FORCESTDBY, musb_context->otg_forcestandby);
272 }
273 #endif
274
275 int musb_platform_suspend(struct musb *musb)
276 {
277         u32 l;
278
279         if (!musb->clock)
280                 return 0;
281
282         /* in any role */
283         l = musb_readl(musb->mregs, OTG_FORCESTDBY);
284         l |= ENABLEFORCE;       /* enable MSTANDBY */
285         musb_writel(musb->mregs, OTG_FORCESTDBY, l);
286
287         l = musb_readl(musb->mregs, OTG_SYSCONFIG);
288         l |= ENABLEWAKEUP;      /* enable wakeup */
289         musb_writel(musb->mregs, OTG_SYSCONFIG, l);
290
291         otg_set_suspend(musb->xceiv, 1);
292
293         if (musb->set_clock)
294                 musb->set_clock(musb->clock, 0);
295         else
296                 clk_disable(musb->clock);
297
298         return 0;
299 }
300
301 static int musb_platform_resume(struct musb *musb)
302 {
303         u32 l;
304
305         if (!musb->clock)
306                 return 0;
307
308         otg_set_suspend(musb->xceiv, 0);
309
310         if (musb->set_clock)
311                 musb->set_clock(musb->clock, 1);
312         else
313                 clk_enable(musb->clock);
314
315         l = musb_readl(musb->mregs, OTG_SYSCONFIG);
316         l &= ~ENABLEWAKEUP;     /* disable wakeup */
317         musb_writel(musb->mregs, OTG_SYSCONFIG, l);
318
319         l = musb_readl(musb->mregs, OTG_FORCESTDBY);
320         l &= ~ENABLEFORCE;      /* disable MSTANDBY */
321         musb_writel(musb->mregs, OTG_FORCESTDBY, l);
322
323         return 0;
324 }
325
326
327 int musb_platform_exit(struct musb *musb)
328 {
329
330         omap_vbus_power(musb, 0 /*off*/, 1);
331
332         musb_platform_suspend(musb);
333
334         return 0;
335 }