Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
msp_usb.c
Go to the documentation of this file.
1 /*
2  * The setup file for USB related hardware on PMC-Sierra MSP processors.
3  *
4  * Copyright 2006 PMC-Sierra, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; either version 2 of the License, or (at your
9  * option) any later version.
10  *
11  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
12  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
14  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
17  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
18  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21  *
22  * You should have received a copy of the GNU General Public License along
23  * with this program; if not, write to the Free Software Foundation, Inc.,
24  * 675 Mass Ave, Cambridge, MA 02139, USA.
25  */
26 #if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET)
27 
28 #include <linux/init.h>
29 #include <linux/ioport.h>
30 #include <linux/platform_device.h>
31 
32 #include <asm/mipsregs.h>
33 
34 #include <msp_regs.h>
35 #include <msp_int.h>
36 #include <msp_prom.h>
37 #include <msp_usb.h>
38 
39 
40 #if defined(CONFIG_USB_EHCI_HCD)
41 static struct resource msp_usbhost0_resources[] = {
42  [0] = { /* EHCI-HS operational and capabilities registers */
44  .end = MSP_USB0_HS_END,
45  .flags = IORESOURCE_MEM,
46  },
47  [1] = {
48  .start = MSP_INT_USB,
49  .end = MSP_INT_USB,
50  .flags = IORESOURCE_IRQ,
51  },
52  [2] = { /* MSBus-to-AMBA bridge register space */
53  .start = MSP_USB0_MAB_START,
54  .end = MSP_USB0_MAB_END,
55  .flags = IORESOURCE_MEM,
56  },
57  [3] = { /* Identification and general hardware parameters */
58  .start = MSP_USB0_ID_START,
59  .end = MSP_USB0_ID_END,
60  .flags = IORESOURCE_MEM,
61  },
62 };
63 
64 static u64 msp_usbhost0_dma_mask = 0xffffffffUL;
65 
66 static struct mspusb_device msp_usbhost0_device = {
67  .dev = {
68  .name = "pmcmsp-ehci",
69  .id = 0,
70  .dev = {
71  .dma_mask = &msp_usbhost0_dma_mask,
72  .coherent_dma_mask = 0xffffffffUL,
73  },
74  .num_resources = ARRAY_SIZE(msp_usbhost0_resources),
75  .resource = msp_usbhost0_resources,
76  },
77 };
78 
79 /* MSP7140/MSP82XX has two USB2 hosts. */
80 #ifdef CONFIG_MSP_HAS_DUAL_USB
81 static u64 msp_usbhost1_dma_mask = 0xffffffffUL;
82 
83 static struct resource msp_usbhost1_resources[] = {
84  [0] = { /* EHCI-HS operational and capabilities registers */
86  .end = MSP_USB1_HS_END,
87  .flags = IORESOURCE_MEM,
88  },
89  [1] = {
90  .start = MSP_INT_USB,
91  .end = MSP_INT_USB,
92  .flags = IORESOURCE_IRQ,
93  },
94  [2] = { /* MSBus-to-AMBA bridge register space */
95  .start = MSP_USB1_MAB_START,
96  .end = MSP_USB1_MAB_END,
97  .flags = IORESOURCE_MEM,
98  },
99  [3] = { /* Identification and general hardware parameters */
100  .start = MSP_USB1_ID_START,
101  .end = MSP_USB1_ID_END,
102  .flags = IORESOURCE_MEM,
103  },
104 };
105 
106 static struct mspusb_device msp_usbhost1_device = {
107  .dev = {
108  .name = "pmcmsp-ehci",
109  .id = 1,
110  .dev = {
111  .dma_mask = &msp_usbhost1_dma_mask,
112  .coherent_dma_mask = 0xffffffffUL,
113  },
114  .num_resources = ARRAY_SIZE(msp_usbhost1_resources),
115  .resource = msp_usbhost1_resources,
116  },
117 };
118 #endif /* CONFIG_MSP_HAS_DUAL_USB */
119 #endif /* CONFIG_USB_EHCI_HCD */
120 
121 #if defined(CONFIG_USB_GADGET)
122 static struct resource msp_usbdev0_resources[] = {
123  [0] = { /* EHCI-HS operational and capabilities registers */
125  .end = MSP_USB0_HS_END,
126  .flags = IORESOURCE_MEM,
127  },
128  [1] = {
129  .start = MSP_INT_USB,
130  .end = MSP_INT_USB,
131  .flags = IORESOURCE_IRQ,
132  },
133  [2] = { /* MSBus-to-AMBA bridge register space */
134  .start = MSP_USB0_MAB_START,
135  .end = MSP_USB0_MAB_END,
136  .flags = IORESOURCE_MEM,
137  },
138  [3] = { /* Identification and general hardware parameters */
139  .start = MSP_USB0_ID_START,
140  .end = MSP_USB0_ID_END,
141  .flags = IORESOURCE_MEM,
142  },
143 };
144 
145 static u64 msp_usbdev_dma_mask = 0xffffffffUL;
146 
147 /* This may need to be converted to a mspusb_device, too. */
148 static struct mspusb_device msp_usbdev0_device = {
149  .dev = {
150  .name = "msp71xx_udc",
151  .id = 0,
152  .dev = {
153  .dma_mask = &msp_usbdev_dma_mask,
154  .coherent_dma_mask = 0xffffffffUL,
155  },
156  .num_resources = ARRAY_SIZE(msp_usbdev0_resources),
157  .resource = msp_usbdev0_resources,
158  },
159 };
160 
161 #ifdef CONFIG_MSP_HAS_DUAL_USB
162 static struct resource msp_usbdev1_resources[] = {
163  [0] = { /* EHCI-HS operational and capabilities registers */
165  .end = MSP_USB1_HS_END,
166  .flags = IORESOURCE_MEM,
167  },
168  [1] = {
169  .start = MSP_INT_USB,
170  .end = MSP_INT_USB,
171  .flags = IORESOURCE_IRQ,
172  },
173  [2] = { /* MSBus-to-AMBA bridge register space */
174  .start = MSP_USB1_MAB_START,
175  .end = MSP_USB1_MAB_END,
176  .flags = IORESOURCE_MEM,
177  },
178  [3] = { /* Identification and general hardware parameters */
179  .start = MSP_USB1_ID_START,
180  .end = MSP_USB1_ID_END,
181  .flags = IORESOURCE_MEM,
182  },
183 };
184 
185 /* This may need to be converted to a mspusb_device, too. */
186 static struct mspusb_device msp_usbdev1_device = {
187  .dev = {
188  .name = "msp71xx_udc",
189  .id = 0,
190  .dev = {
191  .dma_mask = &msp_usbdev_dma_mask,
192  .coherent_dma_mask = 0xffffffffUL,
193  },
194  .num_resources = ARRAY_SIZE(msp_usbdev1_resources),
195  .resource = msp_usbdev1_resources,
196  },
197 };
198 
199 #endif /* CONFIG_MSP_HAS_DUAL_USB */
200 #endif /* CONFIG_USB_GADGET */
201 
202 static int __init msp_usb_setup(void)
203 {
204  char *strp;
205  char envstr[32];
206  struct platform_device *msp_devs[NUM_USB_DEVS];
207  unsigned int val;
208 
209  /* construct environment name usbmode */
210  /* set usbmode <host/device> as pmon environment var */
211  /*
212  * Could this perhaps be integrated into the "features" env var?
213  * Use the features key "U", and follow with "H" for host-mode,
214  * "D" for device-mode. If it works for Ethernet, why not USB...
215  * -- hammtrev, 2007/03/22
216  */
217  snprintf((char *)&envstr[0], sizeof(envstr), "usbmode");
218 
219  /* set default host mode */
220  val = 1;
221 
222  /* get environment string */
223  strp = prom_getenv((char *)&envstr[0]);
224  if (strp) {
225  /* compare string */
226  if (!strcmp(strp, "device"))
227  val = 0;
228  }
229 
230  if (val) {
231 #if defined(CONFIG_USB_EHCI_HCD)
232  msp_devs[0] = &msp_usbhost0_device.dev;
233  ppfinit("platform add USB HOST done %s.\n", msp_devs[0]->name);
234 #ifdef CONFIG_MSP_HAS_DUAL_USB
235  msp_devs[1] = &msp_usbhost1_device.dev;
236  ppfinit("platform add USB HOST done %s.\n", msp_devs[1]->name);
237 #endif
238 #else
239  ppfinit("%s: echi_hcd not supported\n", __FILE__);
240 #endif /* CONFIG_USB_EHCI_HCD */
241  } else {
242 #if defined(CONFIG_USB_GADGET)
243  /* get device mode structure */
244  msp_devs[0] = &msp_usbdev0_device.dev;
245  ppfinit("platform add USB DEVICE done %s.\n"
246  , msp_devs[0]->name);
247 #ifdef CONFIG_MSP_HAS_DUAL_USB
248  msp_devs[1] = &msp_usbdev1_device.dev;
249  ppfinit("platform add USB DEVICE done %s.\n"
250  , msp_devs[1]->name);
251 #endif
252 #else
253  ppfinit("%s: usb_gadget not supported\n", __FILE__);
254 #endif /* CONFIG_USB_GADGET */
255  }
256  /* add device */
257  platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs));
258 
259  return 0;
260 }
261 
262 subsys_initcall(msp_usb_setup);
263 #endif /* CONFIG_USB_EHCI_HCD || CONFIG_USB_GADGET */