]> bbs.cooldavid.org Git - net-next-2.6.git/blame - arch/arm/mach-mx2/devices.c
Merge branch 'for-rmk/samsung6' of git://git.fluff.org/bjdooks/linux into devel-stable
[net-next-2.6.git] / arch / arm / mach-mx2 / devices.c
CommitLineData
fc80a5e3
JB
1/*
2 * Author: MontaVista Software, Inc.
3 * <source@mvista.com>
4 *
5 * Based on the OMAP devices.c
6 *
7 * 2005 (c) MontaVista Software, Inc. This file is licensed under the
8 * terms of the GNU General Public License version 2. This program is
9 * licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 *
12 * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
13 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27 * MA 02110-1301, USA.
28 */
29#include <linux/module.h>
30#include <linux/kernel.h>
31#include <linux/init.h>
32#include <linux/platform_device.h>
33#include <linux/gpio.h>
34
80b02c17 35#include <mach/irqs.h>
a09e64fb 36#include <mach/hardware.h>
058b7a6f 37#include <mach/common.h>
1a02be0e 38#include <mach/mmc.h>
058b7a6f
HS
39
40#include "devices.h"
fc80a5e3 41
f420db84
SH
42/*
43 * SPI master controller
44 *
45 * - i.MX1: 2 channel (slighly different register setting)
46 * - i.MX21: 2 channel
47 * - i.MX27: 3 channel
48 */
68c94b40
UKK
49#define DEFINE_IMX_SPI_DEVICE(n, baseaddr, irq) \
50 static struct resource mxc_spi_resources ## n[] = { \
51 { \
52 .start = baseaddr, \
53 .end = baseaddr + SZ_4K - 1, \
54 .flags = IORESOURCE_MEM, \
55 }, { \
56 .start = irq, \
57 .end = irq, \
58 .flags = IORESOURCE_IRQ, \
59 }, \
60 }; \
61 \
62 struct platform_device mxc_spi_device ## n = { \
63 .name = "spi_imx", \
64 .id = n, \
65 .num_resources = ARRAY_SIZE(mxc_spi_resources ## n), \
66 .resource = mxc_spi_resources ## n, \
67 }
f420db84 68
68c94b40
UKK
69DEFINE_IMX_SPI_DEVICE(0, MX2x_CSPI1_BASE_ADDR, MX2x_INT_CSPI1);
70DEFINE_IMX_SPI_DEVICE(1, MX2x_CSPI2_BASE_ADDR, MX2x_INT_CSPI2);
f420db84
SH
71
72#ifdef CONFIG_MACH_MX27
68c94b40 73DEFINE_IMX_SPI_DEVICE(2, MX27_CSPI3_BASE_ADDR, MX27_INT_CSPI3);
f420db84
SH
74#endif
75
fc80a5e3
JB
76/*
77 * General Purpose Timer
bf50bcc2
SH
78 * - i.MX21: 3 timers
79 * - i.MX27: 6 timers
fc80a5e3 80 */
2b84a364
UKK
81#define DEFINE_IMX_GPT_DEVICE(n, baseaddr, irq) \
82 static struct resource timer ## n ##_resources[] = { \
83 { \
84 .start = baseaddr, \
85 .end = baseaddr + SZ_4K - 1, \
86 .flags = IORESOURCE_MEM, \
87 }, { \
88 .start = irq, \
89 .end = irq, \
90 .flags = IORESOURCE_IRQ, \
91 } \
92 }; \
93 \
94 struct platform_device mxc_gpt ## n = { \
95 .name = "imx_gpt", \
96 .id = n, \
97 .num_resources = ARRAY_SIZE(timer ## n ## _resources), \
98 .resource = timer ## n ## _resources, \
fc80a5e3 99 }
fc80a5e3 100
2b84a364
UKK
101/* We use gpt1 as system timer, so do not add a device for this one */
102DEFINE_IMX_GPT_DEVICE(1, MX2x_GPT2_BASE_ADDR, MX2x_INT_GPT2);
103DEFINE_IMX_GPT_DEVICE(2, MX2x_GPT3_BASE_ADDR, MX2x_INT_GPT3);
fc80a5e3
JB
104
105#ifdef CONFIG_MACH_MX27
2b84a364
UKK
106DEFINE_IMX_GPT_DEVICE(3, MX27_GPT4_BASE_ADDR, MX27_INT_GPT4);
107DEFINE_IMX_GPT_DEVICE(4, MX27_GPT5_BASE_ADDR, MX27_INT_GPT5);
108DEFINE_IMX_GPT_DEVICE(5, MX27_GPT6_BASE_ADDR, MX27_INT_GPT6);
fc80a5e3
JB
109#endif
110
111/*
112 * Watchdog:
113 * - i.MX1
114 * - i.MX21
115 * - i.MX27
116 */
117static struct resource mxc_wdt_resources[] = {
118 {
58152a16
UKK
119 .start = MX2x_WDOG_BASE_ADDR,
120 .end = MX2x_WDOG_BASE_ADDR + SZ_4K - 1,
121 .flags = IORESOURCE_MEM,
fc80a5e3
JB
122 },
123};
124
125struct platform_device mxc_wdt = {
126 .name = "mxc_wdt",
127 .id = 0,
128 .num_resources = ARRAY_SIZE(mxc_wdt_resources),
129 .resource = mxc_wdt_resources,
130};
131
3d89baa7
SH
132static struct resource mxc_w1_master_resources[] = {
133 {
58152a16
UKK
134 .start = MX2x_OWIRE_BASE_ADDR,
135 .end = MX2x_OWIRE_BASE_ADDR + SZ_4K - 1,
3d89baa7
SH
136 .flags = IORESOURCE_MEM,
137 },
138};
139
140struct platform_device mxc_w1_master_device = {
141 .name = "mxc_w1",
142 .id = 0,
143 .num_resources = ARRAY_SIZE(mxc_w1_master_resources),
144 .resource = mxc_w1_master_resources,
145};
146
f0d3ab49
UKK
147#define DEFINE_MXC_NAND_DEVICE(pfx, baseaddr, irq) \
148 static struct resource pfx ## _nand_resources[] = { \
149 { \
150 .start = baseaddr, \
151 .end = baseaddr + SZ_4K - 1, \
152 .flags = IORESOURCE_MEM, \
153 }, { \
154 .start = irq, \
155 .end = irq, \
156 .flags = IORESOURCE_IRQ, \
157 }, \
158 }; \
159 \
160 struct platform_device pfx ## _nand_device = { \
161 .name = "mxc_nand", \
162 .id = 0, \
163 .num_resources = ARRAY_SIZE(pfx ## _nand_resources), \
164 .resource = pfx ## _nand_resources, \
165 }
02870978 166
f0d3ab49
UKK
167#ifdef CONFIG_MACH_MX21
168DEFINE_MXC_NAND_DEVICE(imx21, MX21_NFC_BASE_ADDR, MX21_INT_NANDFC);
169#endif
170
171#ifdef CONFIG_MACH_MX27
172DEFINE_MXC_NAND_DEVICE(imx27, MX27_NFC_BASE_ADDR, MX27_INT_NANDFC);
173#endif
02870978 174
e4813551
HS
175/*
176 * lcdc:
177 * - i.MX1: the basic controller
178 * - i.MX21: to be checked
179 * - i.MX27: like i.MX1, with slightly variations
180 */
181static struct resource mxc_fb[] = {
182 {
58152a16
UKK
183 .start = MX2x_LCDC_BASE_ADDR,
184 .end = MX2x_LCDC_BASE_ADDR + SZ_4K - 1,
e4813551 185 .flags = IORESOURCE_MEM,
bf50bcc2 186 }, {
58152a16
UKK
187 .start = MX2x_INT_LCDC,
188 .end = MX2x_INT_LCDC,
e4813551
HS
189 .flags = IORESOURCE_IRQ,
190 }
191};
192
193/* mxc lcd driver */
194struct platform_device mxc_fb_device = {
195 .name = "imx-fb",
196 .id = 0,
197 .num_resources = ARRAY_SIZE(mxc_fb),
198 .resource = mxc_fb,
199 .dev = {
200 .coherent_dma_mask = 0xFFFFFFFF,
201 },
202};
203
879fea1b
SH
204#ifdef CONFIG_MACH_MX27
205static struct resource mxc_fec_resources[] = {
206 {
58152a16
UKK
207 .start = MX27_FEC_BASE_ADDR,
208 .end = MX27_FEC_BASE_ADDR + SZ_4K - 1,
209 .flags = IORESOURCE_MEM,
879fea1b 210 }, {
58152a16
UKK
211 .start = MX27_INT_FEC,
212 .end = MX27_INT_FEC,
213 .flags = IORESOURCE_IRQ,
879fea1b
SH
214 },
215};
216
217struct platform_device mxc_fec_device = {
218 .name = "fec",
219 .id = 0,
220 .num_resources = ARRAY_SIZE(mxc_fec_resources),
221 .resource = mxc_fec_resources,
222};
e4813551
HS
223#endif
224
9309b2ba
UKK
225#define DEFINE_IMX_I2C_DEVICE(n, baseaddr, irq) \
226 static struct resource mxc_i2c_resources ## n[] = { \
227 { \
228 .start = baseaddr, \
229 .end = baseaddr + SZ_4K - 1, \
230 .flags = IORESOURCE_MEM, \
231 }, { \
232 .start = irq, \
233 .end = irq, \
234 .flags = IORESOURCE_IRQ, \
235 } \
236 }; \
237 \
238 struct platform_device mxc_i2c_device ## n = { \
239 .name = "imx-i2c", \
240 .id = n, \
241 .num_resources = ARRAY_SIZE(mxc_i2c_resources ## n), \
242 .resource = mxc_i2c_resources ## n, \
c5d4dbff 243 }
c5d4dbff 244
9309b2ba 245DEFINE_IMX_I2C_DEVICE(0, MX2x_I2C_BASE_ADDR, MX2x_INT_I2C);
c5d4dbff
SH
246
247#ifdef CONFIG_MACH_MX27
9309b2ba 248DEFINE_IMX_I2C_DEVICE(1, MX27_I2C2_BASE_ADDR, MX27_INT_I2C2);
c5d4dbff
SH
249#endif
250
824b16e6 251static struct resource mxc_pwm_resources[] = {
bf50bcc2 252 {
58152a16
UKK
253 .start = MX2x_PWM_BASE_ADDR,
254 .end = MX2x_PWM_BASE_ADDR + SZ_4K - 1,
255 .flags = IORESOURCE_MEM,
bf50bcc2 256 }, {
58152a16
UKK
257 .start = MX2x_INT_PWM,
258 .end = MX2x_INT_PWM,
259 .flags = IORESOURCE_IRQ,
824b16e6
SH
260 }
261};
262
263struct platform_device mxc_pwm_device = {
264 .name = "mxc_pwm",
265 .id = 0,
266 .num_resources = ARRAY_SIZE(mxc_pwm_resources),
bf50bcc2 267 .resource = mxc_pwm_resources,
824b16e6
SH
268};
269
1a02be0e
SH
270/*
271 * Resource definition for the MXC SDHC
272 */
ccd0e42c
UKK
273#define DEFINE_MXC_MMC_DEVICE(n, baseaddr, irq, dmareq) \
274 static struct resource mxc_sdhc_resources ## n[] = { \
275 { \
276 .start = baseaddr, \
277 .end = baseaddr + SZ_4K - 1, \
278 .flags = IORESOURCE_MEM, \
279 }, { \
280 .start = irq, \
281 .end = irq, \
282 .flags = IORESOURCE_IRQ, \
283 }, { \
284 .start = dmareq, \
285 .end = dmareq, \
286 .flags = IORESOURCE_DMA, \
287 }, \
288 }; \
289 \
290 static u64 mxc_sdhc ## n ## _dmamask = 0xffffffffUL; \
291 \
292 struct platform_device mxc_sdhc_device ## n = { \
293 .name = "mxc-mmc", \
294 .id = n, \
295 .dev = { \
296 .dma_mask = &mxc_sdhc ## n ## _dmamask, \
297 .coherent_dma_mask = 0xffffffff, \
298 }, \
299 .num_resources = ARRAY_SIZE(mxc_sdhc_resources ## n), \
300 .resource = mxc_sdhc_resources ## n, \
301 }
1a02be0e 302
ccd0e42c
UKK
303DEFINE_MXC_MMC_DEVICE(0, MX2x_SDHC1_BASE_ADDR, MX2x_INT_SDHC1, MX2x_DMA_REQ_SDHC1);
304DEFINE_MXC_MMC_DEVICE(1, MX2x_SDHC2_BASE_ADDR, MX2x_INT_SDHC2, MX2x_DMA_REQ_SDHC2);
1a02be0e 305
f6d2fa7d 306#ifdef CONFIG_MACH_MX27
627fb3b9
M
307static struct resource otg_resources[] = {
308 {
58152a16
UKK
309 .start = MX27_USBOTG_BASE_ADDR,
310 .end = MX27_USBOTG_BASE_ADDR + 0x1ff,
311 .flags = IORESOURCE_MEM,
627fb3b9 312 }, {
58152a16
UKK
313 .start = MX27_INT_USB3,
314 .end = MX27_INT_USB3,
315 .flags = IORESOURCE_IRQ,
627fb3b9
M
316 },
317};
318
319static u64 otg_dmamask = 0xffffffffUL;
320
321/* OTG gadget device */
322struct platform_device mxc_otg_udc_device = {
58152a16
UKK
323 .name = "fsl-usb2-udc",
324 .id = -1,
325 .dev = {
326 .dma_mask = &otg_dmamask,
327 .coherent_dma_mask = 0xffffffffUL,
627fb3b9 328 },
58152a16
UKK
329 .resource = otg_resources,
330 .num_resources = ARRAY_SIZE(otg_resources),
627fb3b9
M
331};
332
333/* OTG host */
334struct platform_device mxc_otg_host = {
335 .name = "mxc-ehci",
336 .id = 0,
337 .dev = {
338 .coherent_dma_mask = 0xffffffff,
339 .dma_mask = &otg_dmamask,
340 },
341 .resource = otg_resources,
342 .num_resources = ARRAY_SIZE(otg_resources),
343};
344
345/* USB host 1 */
346
347static u64 usbh1_dmamask = 0xffffffffUL;
348
349static struct resource mxc_usbh1_resources[] = {
350 {
58152a16
UKK
351 .start = MX27_USBOTG_BASE_ADDR + 0x200,
352 .end = MX27_USBOTG_BASE_ADDR + 0x3ff,
627fb3b9
M
353 .flags = IORESOURCE_MEM,
354 }, {
58152a16
UKK
355 .start = MX27_INT_USB1,
356 .end = MX27_INT_USB1,
627fb3b9
M
357 .flags = IORESOURCE_IRQ,
358 },
359};
360
361struct platform_device mxc_usbh1 = {
362 .name = "mxc-ehci",
363 .id = 1,
364 .dev = {
365 .coherent_dma_mask = 0xffffffff,
366 .dma_mask = &usbh1_dmamask,
367 },
368 .resource = mxc_usbh1_resources,
369 .num_resources = ARRAY_SIZE(mxc_usbh1_resources),
370};
371
372/* USB host 2 */
373static u64 usbh2_dmamask = 0xffffffffUL;
374
375static struct resource mxc_usbh2_resources[] = {
376 {
58152a16
UKK
377 .start = MX27_USBOTG_BASE_ADDR + 0x400,
378 .end = MX27_USBOTG_BASE_ADDR + 0x5ff,
627fb3b9
M
379 .flags = IORESOURCE_MEM,
380 }, {
58152a16
UKK
381 .start = MX27_INT_USB2,
382 .end = MX27_INT_USB2,
627fb3b9
M
383 .flags = IORESOURCE_IRQ,
384 },
385};
386
387struct platform_device mxc_usbh2 = {
388 .name = "mxc-ehci",
389 .id = 2,
390 .dev = {
391 .coherent_dma_mask = 0xffffffff,
392 .dma_mask = &usbh2_dmamask,
393 },
394 .resource = mxc_usbh2_resources,
395 .num_resources = ARRAY_SIZE(mxc_usbh2_resources),
396};
f6d2fa7d 397#endif
627fb3b9 398
69ddb488
UKK
399#define DEFINE_IMX_SSI_DMARES(_name, ssin, suffix) \
400 { \
401 .name = _name, \
402 .start = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \
403 .end = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \
404 .flags = IORESOURCE_DMA, \
405 }
23291df4 406
69ddb488
UKK
407#define DEFINE_IMX_SSI_DEVICE(n, ssin, baseaddr, irq) \
408 static struct resource imx_ssi_resources ## n[] = { \
409 { \
410 .start = MX2x_SSI ## ssin ## _BASE_ADDR, \
411 .end = MX2x_SSI ## ssin ## _BASE_ADDR + 0x6f, \
412 .flags = IORESOURCE_MEM, \
413 }, { \
414 .start = MX2x_INT_SSI1, \
415 .end = MX2x_INT_SSI1, \
416 .flags = IORESOURCE_IRQ, \
417 }, \
418 DEFINE_IMX_SSI_DMARES("tx0", ssin, TX0), \
419 DEFINE_IMX_SSI_DMARES("rx0", ssin, RX0), \
420 DEFINE_IMX_SSI_DMARES("tx1", ssin, TX1), \
421 DEFINE_IMX_SSI_DMARES("rx1", ssin, RX1), \
422 }; \
423 \
424 struct platform_device imx_ssi_device ## n = { \
425 .name = "imx-ssi", \
426 .id = n, \
427 .num_resources = ARRAY_SIZE(imx_ssi_resources ## n), \
428 .resource = imx_ssi_resources ## n, \
429 }
23291df4 430
69ddb488
UKK
431DEFINE_IMX_SSI_DEVICE(0, 1, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
432DEFINE_IMX_SSI_DEVICE(1, 2, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
23291df4 433
fc80a5e3 434/* GPIO port description */
897359d5
UKK
435#define DEFINE_MXC_GPIO_PORT_IRQ(SOC, n, _irq) \
436 { \
437 .chip.label = "gpio-" #n, \
438 .irq = _irq, \
439 .base = SOC ## _IO_ADDRESS(MX2x_GPIO_BASE_ADDR + \
440 n * 0x100), \
441 .virtual_irq_start = MXC_GPIO_IRQ_START + n * 32, \
442 }
443
444#define DEFINE_MXC_GPIO_PORT(SOC, n) \
445 { \
446 .chip.label = "gpio-" #n, \
447 .base = SOC ## _IO_ADDRESS(MX2x_GPIO_BASE_ADDR + \
448 n * 0x100), \
449 .virtual_irq_start = MXC_GPIO_IRQ_START + n * 32, \
fc80a5e3 450 }
897359d5
UKK
451
452#define DEFINE_MXC_GPIO_PORTS(SOC, pfx) \
453 static struct mxc_gpio_port pfx ## _gpio_ports[] = { \
454 DEFINE_MXC_GPIO_PORT_IRQ(SOC, 0, SOC ## _INT_GPIO), \
455 DEFINE_MXC_GPIO_PORT(SOC, 1), \
456 DEFINE_MXC_GPIO_PORT(SOC, 2), \
457 DEFINE_MXC_GPIO_PORT(SOC, 3), \
458 DEFINE_MXC_GPIO_PORT(SOC, 4), \
459 DEFINE_MXC_GPIO_PORT(SOC, 5), \
460 }
461
462#ifdef CONFIG_MACH_MX21
463DEFINE_MXC_GPIO_PORTS(MX21, imx21);
464#endif
465
466#ifdef CONFIG_MACH_MX27
467DEFINE_MXC_GPIO_PORTS(MX27, imx27);
468#endif
fc80a5e3
JB
469
470int __init mxc_register_gpios(void)
471{
897359d5
UKK
472#ifdef CONFIG_MACH_MX21
473 if (cpu_is_mx21())
474 return mxc_gpio_init(imx21_gpio_ports, ARRAY_SIZE(imx21_gpio_ports));
475 else
476#endif
477#ifdef CONFIG_MACH_MX27
478 if (cpu_is_mx27())
479 return mxc_gpio_init(imx27_gpio_ports, ARRAY_SIZE(imx27_gpio_ports));
480 else
481#endif
482 return 0;
fc80a5e3 483}