aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-mxc/ehci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-mxc/ehci.c')
-rw-r--r--arch/arm/plat-mxc/ehci.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c
new file mode 100644
index 000000000000..cb0b63874482
--- /dev/null
+++ b/arch/arm/plat-mxc/ehci.c
@@ -0,0 +1,194 @@
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 (0x3 << 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 (0x3 << 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 (0x3 << MX31_H1_SIC_SHIFT)
38#define MX31_H1_PM_BIT (1 << 8)
39#define MX31_H1_DT_BIT (1 << 4)
40
41#define MX35_OTG_SIC_SHIFT 29
42#define MX35_OTG_SIC_MASK (0x3 << MX35_OTG_SIC_SHIFT)
43#define MX35_OTG_PM_BIT (1 << 24)
44
45#define MX35_H1_SIC_SHIFT 21
46#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT)
47#define MX35_H1_PM_BIT (1 << 8)
48#define MX35_H1_IPPUE_UP_BIT (1 << 7)
49#define MX35_H1_IPPUE_DOWN_BIT (1 << 6)
50#define MX35_H1_TLL_BIT (1 << 5)
51#define MX35_H1_USBTE_BIT (1 << 4)
52
53int mxc_set_usbcontrol(int port, unsigned int flags)
54{
55 unsigned int v;
56#ifdef CONFIG_ARCH_MX3
57 if (cpu_is_mx31()) {
58 v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
59 USBCTRL_OTGBASE_OFFSET));
60
61 switch (port) {
62 case 0: /* OTG port */
63 v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
64 v |= (flags & MXC_EHCI_INTERFACE_MASK)
65 << MX31_OTG_SIC_SHIFT;
66 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
67 v |= MX31_OTG_PM_BIT;
68
69 break;
70 case 1: /* H1 port */
71 v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT);
72 v |= (flags & MXC_EHCI_INTERFACE_MASK)
73 << MX31_H1_SIC_SHIFT;
74 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
75 v |= MX31_H1_PM_BIT;
76
77 if (!(flags & MXC_EHCI_TTL_ENABLED))
78 v |= MX31_H1_DT_BIT;
79
80 break;
81 case 2: /* H2 port */
82 v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT);
83 v |= (flags & MXC_EHCI_INTERFACE_MASK)
84 << MX31_H2_SIC_SHIFT;
85 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
86 v |= MX31_H2_PM_BIT;
87
88 if (!(flags & MXC_EHCI_TTL_ENABLED))
89 v |= MX31_H2_DT_BIT;
90
91 break;
92 default:
93 return -EINVAL;
94 }
95
96 writel(v, MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
97 USBCTRL_OTGBASE_OFFSET));
98 return 0;
99 }
100
101 if (cpu_is_mx35()) {
102 v = readl(MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR +
103 USBCTRL_OTGBASE_OFFSET));
104
105 switch (port) {
106 case 0: /* OTG port */
107 v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT);
108 v |= (flags & MXC_EHCI_INTERFACE_MASK)
109 << MX35_OTG_SIC_SHIFT;
110 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
111 v |= MX35_OTG_PM_BIT;
112
113 break;
114 case 1: /* H1 port */
115 v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT |
116 MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT);
117 v |= (flags & MXC_EHCI_INTERFACE_MASK)
118 << MX35_H1_SIC_SHIFT;
119 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
120 v |= MX35_H1_PM_BIT;
121
122 if (!(flags & MXC_EHCI_TTL_ENABLED))
123 v |= MX35_H1_TLL_BIT;
124
125 if (flags & MXC_EHCI_INTERNAL_PHY)
126 v |= MX35_H1_USBTE_BIT;
127
128 if (flags & MXC_EHCI_IPPUE_DOWN)
129 v |= MX35_H1_IPPUE_DOWN_BIT;
130
131 if (flags & MXC_EHCI_IPPUE_UP)
132 v |= MX35_H1_IPPUE_UP_BIT;
133
134 break;
135 default:
136 return -EINVAL;
137 }
138
139 writel(v, MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR +
140 USBCTRL_OTGBASE_OFFSET));
141 return 0;
142 }
143#endif /* CONFIG_ARCH_MX3 */
144#ifdef CONFIG_MACH_MX27
145 if (cpu_is_mx27()) {
146 /* On i.MX27 we can use the i.MX31 USBCTRL bits, they
147 * are identical
148 */
149 v = readl(MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR +
150 USBCTRL_OTGBASE_OFFSET));
151 switch (port) {
152 case 0: /* OTG port */
153 v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
154 v |= (flags & MXC_EHCI_INTERFACE_MASK)
155 << MX31_OTG_SIC_SHIFT;
156 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
157 v |= MX31_OTG_PM_BIT;
158 break;
159 case 1: /* H1 port */
160 v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT);
161 v |= (flags & MXC_EHCI_INTERFACE_MASK)
162 << MX31_H1_SIC_SHIFT;
163 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
164 v |= MX31_H1_PM_BIT;
165
166 if (!(flags & MXC_EHCI_TTL_ENABLED))
167 v |= MX31_H1_DT_BIT;
168
169 break;
170 case 2: /* H2 port */
171 v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT);
172 v |= (flags & MXC_EHCI_INTERFACE_MASK)
173 << MX31_H2_SIC_SHIFT;
174 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
175 v |= MX31_H2_PM_BIT;
176
177 if (!(flags & MXC_EHCI_TTL_ENABLED))
178 v |= MX31_H2_DT_BIT;
179
180 break;
181 default:
182 return -EINVAL;
183 }
184 writel(v, MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR +
185 USBCTRL_OTGBASE_OFFSET));
186 return 0;
187 }
188#endif /* CONFIG_MACH_MX27 */
189 printk(KERN_WARNING
190 "%s() unable to setup USBCONTROL for this CPU\n", __func__);
191 return -EINVAL;
192}
193EXPORT_SYMBOL(mxc_set_usbcontrol);
194