1/* 2 * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. 3 * Copyright 2008 Sascha Hauer, kernel@pengutronix.de 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License 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 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20#include <linux/dma-mapping.h> 21#include <linux/module.h> 22#include <linux/platform_device.h> 23#include <linux/serial.h> 24#include <linux/gpio.h> 25#include <mach/hardware.h> 26#include <mach/irqs.h> 27#include <mach/common.h> 28#include <mach/mx3_camera.h> 29 30#include "devices.h" 31 32/* GPIO port description */ 33static struct mxc_gpio_port imx_gpio_ports[] = { 34 { 35 .chip.label = "gpio-0", 36 .base = IO_ADDRESS(GPIO1_BASE_ADDR), 37 .irq = MXC_INT_GPIO1, 38 .virtual_irq_start = MXC_GPIO_IRQ_START, 39 }, { 40 .chip.label = "gpio-1", 41 .base = IO_ADDRESS(GPIO2_BASE_ADDR), 42 .irq = MXC_INT_GPIO2, 43 .virtual_irq_start = MXC_GPIO_IRQ_START + 32, 44 }, { 45 .chip.label = "gpio-2", 46 .base = IO_ADDRESS(GPIO3_BASE_ADDR), 47 .irq = MXC_INT_GPIO3, 48 .virtual_irq_start = MXC_GPIO_IRQ_START + 64, 49 } 50}; 51 52int __init imx3x_register_gpios(void) 53{ 54 return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports)); 55} 56 57static struct resource mxc_w1_master_resources[] = { 58 { 59 .start = OWIRE_BASE_ADDR, 60 .end = OWIRE_BASE_ADDR + SZ_4K - 1, 61 .flags = IORESOURCE_MEM, 62 }, 63}; 64 65struct platform_device mxc_w1_master_device = { 66 .name = "mxc_w1", 67 .id = 0, 68 .num_resources = ARRAY_SIZE(mxc_w1_master_resources), 69 .resource = mxc_w1_master_resources, 70}; 71 72#ifdef CONFIG_ARCH_MX31 73static struct resource mxcsdhc0_resources[] = { 74 { 75 .start = MMC_SDHC1_BASE_ADDR, 76 .end = MMC_SDHC1_BASE_ADDR + SZ_16K - 1, 77 .flags = IORESOURCE_MEM, 78 }, { 79 .start = MXC_INT_MMC_SDHC1, 80 .end = MXC_INT_MMC_SDHC1, 81 .flags = IORESOURCE_IRQ, 82 }, 83}; 84 85static struct resource mxcsdhc1_resources[] = { 86 { 87 .start = MMC_SDHC2_BASE_ADDR, 88 .end = MMC_SDHC2_BASE_ADDR + SZ_16K - 1, 89 .flags = IORESOURCE_MEM, 90 }, { 91 .start = MXC_INT_MMC_SDHC2, 92 .end = MXC_INT_MMC_SDHC2, 93 .flags = IORESOURCE_IRQ, 94 }, 95}; 96 97struct platform_device mxcsdhc_device0 = { 98 .name = "mxc-mmc", 99 .id = 0, 100 .num_resources = ARRAY_SIZE(mxcsdhc0_resources), 101 .resource = mxcsdhc0_resources, 102}; 103 104struct platform_device mxcsdhc_device1 = { 105 .name = "mxc-mmc", 106 .id = 1, 107 .num_resources = ARRAY_SIZE(mxcsdhc1_resources), 108 .resource = mxcsdhc1_resources, 109}; 110 111static struct resource rnga_resources[] = { 112 { 113 .start = RNGA_BASE_ADDR, 114 .end = RNGA_BASE_ADDR + 0x28, 115 .flags = IORESOURCE_MEM, 116 }, 117}; 118 119struct platform_device mxc_rnga_device = { 120 .name = "mxc_rnga", 121 .id = -1, 122 .num_resources = 1, 123 .resource = rnga_resources, 124}; 125#endif /* CONFIG_ARCH_MX31 */ 126 127/* i.MX31 Image Processing Unit */ 128 129/* The resource order is important! */ 130static struct resource mx3_ipu_rsrc[] = { 131 { 132 .start = IPU_CTRL_BASE_ADDR, 133 .end = IPU_CTRL_BASE_ADDR + 0x5F, 134 .flags = IORESOURCE_MEM, 135 }, { 136 .start = IPU_CTRL_BASE_ADDR + 0x88, 137 .end = IPU_CTRL_BASE_ADDR + 0xB3, 138 .flags = IORESOURCE_MEM, 139 }, { 140 .start = MXC_INT_IPU_SYN, 141 .end = MXC_INT_IPU_SYN, 142 .flags = IORESOURCE_IRQ, 143 }, { 144 .start = MXC_INT_IPU_ERR, 145 .end = MXC_INT_IPU_ERR, 146 .flags = IORESOURCE_IRQ, 147 }, 148}; 149 150struct platform_device mx3_ipu = { 151 .name = "ipu-core", 152 .id = -1, 153 .num_resources = ARRAY_SIZE(mx3_ipu_rsrc), 154 .resource = mx3_ipu_rsrc, 155}; 156 157static struct resource fb_resources[] = { 158 { 159 .start = IPU_CTRL_BASE_ADDR + 0xB4, 160 .end = IPU_CTRL_BASE_ADDR + 0x1BF, 161 .flags = IORESOURCE_MEM, 162 }, 163}; 164 165struct platform_device mx3_fb = { 166 .name = "mx3_sdc_fb", 167 .id = -1, 168 .num_resources = ARRAY_SIZE(fb_resources), 169 .resource = fb_resources, 170 .dev = { 171 .coherent_dma_mask = DMA_BIT_MASK(32), 172 }, 173}; 174 175static struct resource camera_resources[] = { 176 { 177 .start = IPU_CTRL_BASE_ADDR + 0x60, 178 .end = IPU_CTRL_BASE_ADDR + 0x87, 179 .flags = IORESOURCE_MEM, 180 }, 181}; 182 183struct platform_device mx3_camera = { 184 .name = "mx3-camera", 185 .id = 0, 186 .num_resources = ARRAY_SIZE(camera_resources), 187 .resource = camera_resources, 188 .dev = { 189 .coherent_dma_mask = DMA_BIT_MASK(32), 190 }, 191}; 192 193static struct resource otg_resources[] = { 194 { 195 .start = MX31_OTG_BASE_ADDR, 196 .end = MX31_OTG_BASE_ADDR + 0x1ff, 197 .flags = IORESOURCE_MEM, 198 }, { 199 .start = MXC_INT_USB3, 200 .end = MXC_INT_USB3, 201 .flags = IORESOURCE_IRQ, 202 }, 203}; 204 205static u64 otg_dmamask = DMA_BIT_MASK(32); 206 207/* OTG gadget device */ 208struct platform_device mxc_otg_udc_device = { 209 .name = "fsl-usb2-udc", 210 .id = -1, 211 .dev = { 212 .dma_mask = &otg_dmamask, 213 .coherent_dma_mask = DMA_BIT_MASK(32), 214 }, 215 .resource = otg_resources, 216 .num_resources = ARRAY_SIZE(otg_resources), 217}; 218 219/* OTG host */ 220struct platform_device mxc_otg_host = { 221 .name = "mxc-ehci", 222 .id = 0, 223 .dev = { 224 .coherent_dma_mask = 0xffffffff, 225 .dma_mask = &otg_dmamask, 226 }, 227 .resource = otg_resources, 228 .num_resources = ARRAY_SIZE(otg_resources), 229}; 230 231/* USB host 1 */ 232 233static u64 usbh1_dmamask = ~(u32)0; 234 235static struct resource mxc_usbh1_resources[] = { 236 { 237 .start = MX31_OTG_BASE_ADDR + 0x200, 238 .end = MX31_OTG_BASE_ADDR + 0x3ff, 239 .flags = IORESOURCE_MEM, 240 }, { 241 .start = MXC_INT_USB1, 242 .end = MXC_INT_USB1, 243 .flags = IORESOURCE_IRQ, 244 }, 245}; 246 247struct platform_device mxc_usbh1 = { 248 .name = "mxc-ehci", 249 .id = 1, 250 .dev = { 251 .coherent_dma_mask = 0xffffffff, 252 .dma_mask = &usbh1_dmamask, 253 }, 254 .resource = mxc_usbh1_resources, 255 .num_resources = ARRAY_SIZE(mxc_usbh1_resources), 256}; 257 258/* USB host 2 */ 259static u64 usbh2_dmamask = ~(u32)0; 260 261static struct resource mxc_usbh2_resources[] = { 262 { 263 .start = MX31_OTG_BASE_ADDR + 0x400, 264 .end = MX31_OTG_BASE_ADDR + 0x5ff, 265 .flags = IORESOURCE_MEM, 266 }, { 267 .start = MXC_INT_USB2, 268 .end = MXC_INT_USB2, 269 .flags = IORESOURCE_IRQ, 270 }, 271}; 272 273struct platform_device mxc_usbh2 = { 274 .name = "mxc-ehci", 275 .id = 2, 276 .dev = { 277 .coherent_dma_mask = 0xffffffff, 278 .dma_mask = &usbh2_dmamask, 279 }, 280 .resource = mxc_usbh2_resources, 281 .num_resources = ARRAY_SIZE(mxc_usbh2_resources), 282}; 283 284#if defined(CONFIG_ARCH_MX35) 285static struct resource mxc_fec_resources[] = { 286 { 287 .start = MXC_FEC_BASE_ADDR, 288 .end = MXC_FEC_BASE_ADDR + 0xfff, 289 .flags = IORESOURCE_MEM, 290 }, { 291 .start = MXC_INT_FEC, 292 .end = MXC_INT_FEC, 293 .flags = IORESOURCE_IRQ, 294 }, 295}; 296 297struct platform_device mxc_fec_device = { 298 .name = "fec", 299 .id = 0, 300 .num_resources = ARRAY_SIZE(mxc_fec_resources), 301 .resource = mxc_fec_resources, 302}; 303#endif 304 305static struct resource imx_ssi_resources0[] = { 306 { 307 .start = SSI1_BASE_ADDR, 308 .end = SSI1_BASE_ADDR + 0xfff, 309 .flags = IORESOURCE_MEM, 310 }, { 311 .start = MX31_INT_SSI1, 312 .end = MX31_INT_SSI1, 313 .flags = IORESOURCE_IRQ, 314 }, 315}; 316 317static struct resource imx_ssi_resources1[] = { 318 { 319 .start = SSI2_BASE_ADDR, 320 .end = SSI2_BASE_ADDR + 0xfff, 321 .flags = IORESOURCE_MEM 322 }, { 323 .start = MX31_INT_SSI2, 324 .end = MX31_INT_SSI2, 325 .flags = IORESOURCE_IRQ, 326 }, 327}; 328 329struct platform_device imx_ssi_device0 = { 330 .name = "imx-ssi", 331 .id = 0, 332 .num_resources = ARRAY_SIZE(imx_ssi_resources0), 333 .resource = imx_ssi_resources0, 334}; 335 336struct platform_device imx_ssi_device1 = { 337 .name = "imx-ssi", 338 .id = 1, 339 .num_resources = ARRAY_SIZE(imx_ssi_resources1), 340 .resource = imx_ssi_resources1, 341}; 342 343static struct resource imx_wdt_resources[] = { 344 { 345 .flags = IORESOURCE_MEM, 346 }, 347}; 348 349struct platform_device imx_wdt_device0 = { 350 .name = "imx2-wdt", 351 .id = 0, 352 .num_resources = ARRAY_SIZE(imx_wdt_resources), 353 .resource = imx_wdt_resources, 354}; 355 356static struct resource imx_rtc_resources[] = { 357 { 358 .start = MX31_RTC_BASE_ADDR, 359 .end = MX31_RTC_BASE_ADDR + 0x3fff, 360 .flags = IORESOURCE_MEM, 361 }, 362 { 363 .start = MX31_INT_RTC, 364 .flags = IORESOURCE_IRQ, 365 }, 366}; 367 368struct platform_device imx_rtc_device0 = { 369 .name = "mxc_rtc", 370 .id = -1, 371 .num_resources = ARRAY_SIZE(imx_rtc_resources), 372 .resource = imx_rtc_resources, 373}; 374 375static struct resource imx_kpp_resources[] = { 376 { 377 .start = MX3x_KPP_BASE_ADDR, 378 .end = MX3x_KPP_BASE_ADDR + 0xf, 379 .flags = IORESOURCE_MEM 380 }, { 381 .start = MX3x_INT_KPP, 382 .end = MX3x_INT_KPP, 383 .flags = IORESOURCE_IRQ, 384 }, 385}; 386 387struct platform_device imx_kpp_device = { 388 .name = "imx-keypad", 389 .id = -1, 390 .num_resources = ARRAY_SIZE(imx_kpp_resources), 391 .resource = imx_kpp_resources, 392}; 393 394static int __init mx3_devices_init(void) 395{ 396#if defined(CONFIG_ARCH_MX31) 397 if (cpu_is_mx31()) { 398 imx_wdt_resources[0].start = MX31_WDOG_BASE_ADDR; 399 imx_wdt_resources[0].end = MX31_WDOG_BASE_ADDR + 0x3fff; 400 mxc_register_device(&mxc_rnga_device, NULL); 401 } 402#endif 403#if defined(CONFIG_ARCH_MX35) 404 if (cpu_is_mx35()) { 405 otg_resources[0].start = MX35_OTG_BASE_ADDR; 406 otg_resources[0].end = MX35_OTG_BASE_ADDR + 0x1ff; 407 otg_resources[1].start = MXC_INT_USBOTG; 408 otg_resources[1].end = MXC_INT_USBOTG; 409 mxc_usbh1_resources[0].start = MX35_OTG_BASE_ADDR + 0x400; 410 mxc_usbh1_resources[0].end = MX35_OTG_BASE_ADDR + 0x5ff; 411 mxc_usbh1_resources[1].start = MXC_INT_USBHS; 412 mxc_usbh1_resources[1].end = MXC_INT_USBHS; 413 imx_ssi_resources0[1].start = MX35_INT_SSI1; 414 imx_ssi_resources0[1].end = MX35_INT_SSI1; 415 imx_ssi_resources1[1].start = MX35_INT_SSI2; 416 imx_ssi_resources1[1].end = MX35_INT_SSI2; 417 imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR; 418 imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff; 419 } 420#endif 421 422 return 0; 423} 424 425subsys_initcall(mx3_devices_init); 426