Merge branch 'reiserfs/kill-bkl' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / arch / arm / plat-mxc / ehci.c
1 /*
2  * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 #include <linux/platform_device.h>
20 #include <linux/io.h>
21
22 #include <mach/hardware.h>
23 #include <mach/mxc_ehci.h>
24
25 #define USBCTRL_OTGBASE_OFFSET  0x600
26
27 #define MX31_OTG_SIC_SHIFT      29
28 #define MX31_OTG_SIC_MASK       (0xf << MX31_OTG_SIC_SHIFT)
29 #define MX31_OTG_PM_BIT         (1 << 24)
30
31 #define MX31_H2_SIC_SHIFT       21
32 #define MX31_H2_SIC_MASK        (0xf << MX31_H2_SIC_SHIFT)
33 #define MX31_H2_PM_BIT          (1 << 16)
34 #define MX31_H2_DT_BIT          (1 << 5)
35
36 #define MX31_H1_SIC_SHIFT       13
37 #define MX31_H1_SIC_MASK        (0xf << MX31_H1_SIC_SHIFT)
38 #define MX31_H1_PM_BIT          (1 << 8)
39 #define MX31_H1_DT_BIT          (1 << 4)
40
41 int mxc_set_usbcontrol(int port, unsigned int flags)
42 {
43         unsigned int v;
44
45         if (cpu_is_mx31()) {
46                 v = readl(IO_ADDRESS(MX31_OTG_BASE_ADDR +
47                                      USBCTRL_OTGBASE_OFFSET));
48
49                 switch (port) {
50                 case 0: /* OTG port */
51                         v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
52                         v |= (flags & MXC_EHCI_INTERFACE_MASK)
53                                         << MX31_OTG_SIC_SHIFT;
54                         if (flags & MXC_EHCI_POWER_PINS_ENABLED)
55                                 v |= MX31_OTG_PM_BIT;
56
57                         break;
58                 case 1: /* H1 port */
59                         v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT);
60                         v |= (flags & MXC_EHCI_INTERFACE_MASK)
61                                                 << MX31_H1_SIC_SHIFT;
62                         if (flags & MXC_EHCI_POWER_PINS_ENABLED)
63                                 v |= MX31_H1_PM_BIT;
64
65                         if (!(flags & MXC_EHCI_TTL_ENABLED))
66                                 v |= MX31_H1_DT_BIT;
67
68                         break;
69                 case 2: /* H2 port */
70                         v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT);
71                         v |= (flags & MXC_EHCI_INTERFACE_MASK)
72                                                 << MX31_H2_SIC_SHIFT;
73                         if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
74                                 v |= MX31_H2_PM_BIT;
75
76                         if (!(flags & MXC_EHCI_TTL_ENABLED))
77                                 v |= MX31_H2_DT_BIT;
78
79                         break;
80                 }
81
82                 writel(v, IO_ADDRESS(MX31_OTG_BASE_ADDR +
83                                      USBCTRL_OTGBASE_OFFSET));
84                 return 0;
85         }
86
87         printk(KERN_WARNING
88                 "%s() unable to setup USBCONTROL for this CPU\n", __func__);
89         return -EINVAL;
90 }
91 EXPORT_SYMBOL(mxc_set_usbcontrol);
92