1/* 2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> 3 * JZ4740 platform devices 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License as published by the 7 * Free Software Foundation; either version 2 of the License, or (at your 8 * option) any later version. 9 * 10 * You should have received a copy of the GNU General Public License along 11 * with this program; if not, write to the Free Software Foundation, Inc., 12 * 675 Mass Ave, Cambridge, MA 02139, USA. 13 * 14 */ 15 16#include <linux/device.h> 17#include <linux/init.h> 18#include <linux/kernel.h> 19#include <linux/platform_device.h> 20#include <linux/resource.h> 21 22#include <linux/dma-mapping.h> 23 24#include <asm/mach-jz4740/platform.h> 25#include <asm/mach-jz4740/base.h> 26#include <asm/mach-jz4740/irq.h> 27 28#include <linux/serial_core.h> 29#include <linux/serial_8250.h> 30 31#include "serial.h" 32#include "clock.h" 33 34/* OHCI controller */ 35static struct resource jz4740_usb_ohci_resources[] = { 36 { 37 .start = JZ4740_UHC_BASE_ADDR, 38 .end = JZ4740_UHC_BASE_ADDR + 0x1000 - 1, 39 .flags = IORESOURCE_MEM, 40 }, 41 { 42 .start = JZ4740_IRQ_UHC, 43 .end = JZ4740_IRQ_UHC, 44 .flags = IORESOURCE_IRQ, 45 }, 46}; 47 48struct platform_device jz4740_usb_ohci_device = { 49 .name = "jz4740-ohci", 50 .id = -1, 51 .dev = { 52 .dma_mask = &jz4740_usb_ohci_device.dev.coherent_dma_mask, 53 .coherent_dma_mask = DMA_BIT_MASK(32), 54 }, 55 .num_resources = ARRAY_SIZE(jz4740_usb_ohci_resources), 56 .resource = jz4740_usb_ohci_resources, 57}; 58 59/* UDC (USB gadget controller) */ 60static struct resource jz4740_usb_gdt_resources[] = { 61 { 62 .start = JZ4740_UDC_BASE_ADDR, 63 .end = JZ4740_UDC_BASE_ADDR + 0x1000 - 1, 64 .flags = IORESOURCE_MEM, 65 }, 66 { 67 .start = JZ4740_IRQ_UDC, 68 .end = JZ4740_IRQ_UDC, 69 .flags = IORESOURCE_IRQ, 70 }, 71}; 72 73struct platform_device jz4740_udc_device = { 74 .name = "jz-udc", 75 .id = -1, 76 .dev = { 77 .dma_mask = &jz4740_udc_device.dev.coherent_dma_mask, 78 .coherent_dma_mask = DMA_BIT_MASK(32), 79 }, 80 .num_resources = ARRAY_SIZE(jz4740_usb_gdt_resources), 81 .resource = jz4740_usb_gdt_resources, 82}; 83 84/* MMC/SD controller */ 85static struct resource jz4740_mmc_resources[] = { 86 { 87 .start = JZ4740_MSC_BASE_ADDR, 88 .end = JZ4740_MSC_BASE_ADDR + 0x1000 - 1, 89 .flags = IORESOURCE_MEM, 90 }, 91 { 92 .start = JZ4740_IRQ_MSC, 93 .end = JZ4740_IRQ_MSC, 94 .flags = IORESOURCE_IRQ, 95 } 96}; 97 98struct platform_device jz4740_mmc_device = { 99 .name = "jz4740-mmc", 100 .id = 0, 101 .dev = { 102 .dma_mask = &jz4740_mmc_device.dev.coherent_dma_mask, 103 .coherent_dma_mask = DMA_BIT_MASK(32), 104 }, 105 .num_resources = ARRAY_SIZE(jz4740_mmc_resources), 106 .resource = jz4740_mmc_resources, 107}; 108 109/* RTC controller */ 110static struct resource jz4740_rtc_resources[] = { 111 { 112 .start = JZ4740_RTC_BASE_ADDR, 113 .end = JZ4740_RTC_BASE_ADDR + 0x38 - 1, 114 .flags = IORESOURCE_MEM, 115 }, 116 { 117 .start = JZ4740_IRQ_RTC, 118 .end = JZ4740_IRQ_RTC, 119 .flags = IORESOURCE_IRQ, 120 }, 121}; 122 123struct platform_device jz4740_rtc_device = { 124 .name = "jz4740-rtc", 125 .id = -1, 126 .num_resources = ARRAY_SIZE(jz4740_rtc_resources), 127 .resource = jz4740_rtc_resources, 128}; 129 130/* I2C controller */ 131static struct resource jz4740_i2c_resources[] = { 132 { 133 .start = JZ4740_I2C_BASE_ADDR, 134 .end = JZ4740_I2C_BASE_ADDR + 0x1000 - 1, 135 .flags = IORESOURCE_MEM, 136 }, 137 { 138 .start = JZ4740_IRQ_I2C, 139 .end = JZ4740_IRQ_I2C, 140 .flags = IORESOURCE_IRQ, 141 } 142}; 143 144struct platform_device jz4740_i2c_device = { 145 .name = "jz4740-i2c", 146 .id = 0, 147 .num_resources = ARRAY_SIZE(jz4740_i2c_resources), 148 .resource = jz4740_i2c_resources, 149}; 150 151/* NAND controller */ 152static struct resource jz4740_nand_resources[] = { 153 { 154 .name = "mmio", 155 .start = JZ4740_EMC_BASE_ADDR, 156 .end = JZ4740_EMC_BASE_ADDR + 0x1000 - 1, 157 .flags = IORESOURCE_MEM, 158 }, 159 { 160 .name = "bank", 161 .start = 0x18000000, 162 .end = 0x180C0000 - 1, 163 .flags = IORESOURCE_MEM, 164 }, 165}; 166 167struct platform_device jz4740_nand_device = { 168 .name = "jz4740-nand", 169 .num_resources = ARRAY_SIZE(jz4740_nand_resources), 170 .resource = jz4740_nand_resources, 171}; 172 173/* LCD controller */ 174static struct resource jz4740_framebuffer_resources[] = { 175 { 176 .start = JZ4740_LCD_BASE_ADDR, 177 .end = JZ4740_LCD_BASE_ADDR + 0x1000 - 1, 178 .flags = IORESOURCE_MEM, 179 }, 180}; 181 182struct platform_device jz4740_framebuffer_device = { 183 .name = "jz4740-fb", 184 .id = -1, 185 .num_resources = ARRAY_SIZE(jz4740_framebuffer_resources), 186 .resource = jz4740_framebuffer_resources, 187 .dev = { 188 .dma_mask = &jz4740_framebuffer_device.dev.coherent_dma_mask, 189 .coherent_dma_mask = DMA_BIT_MASK(32), 190 }, 191}; 192 193/* I2S controller */ 194static struct resource jz4740_i2s_resources[] = { 195 { 196 .start = JZ4740_AIC_BASE_ADDR, 197 .end = JZ4740_AIC_BASE_ADDR + 0x38 - 1, 198 .flags = IORESOURCE_MEM, 199 }, 200}; 201 202struct platform_device jz4740_i2s_device = { 203 .name = "jz4740-i2s", 204 .id = -1, 205 .num_resources = ARRAY_SIZE(jz4740_i2s_resources), 206 .resource = jz4740_i2s_resources, 207}; 208 209/* PCM */ 210struct platform_device jz4740_pcm_device = { 211 .name = "jz4740-pcm", 212 .id = -1, 213}; 214 215/* Codec */ 216static struct resource jz4740_codec_resources[] = { 217 { 218 .start = JZ4740_AIC_BASE_ADDR + 0x80, 219 .end = JZ4740_AIC_BASE_ADDR + 0x88 - 1, 220 .flags = IORESOURCE_MEM, 221 }, 222}; 223 224struct platform_device jz4740_codec_device = { 225 .name = "jz4740-codec", 226 .id = -1, 227 .num_resources = ARRAY_SIZE(jz4740_codec_resources), 228 .resource = jz4740_codec_resources, 229}; 230 231/* ADC controller */ 232static struct resource jz4740_adc_resources[] = { 233 { 234 .start = JZ4740_SADC_BASE_ADDR, 235 .end = JZ4740_SADC_BASE_ADDR + 0x30, 236 .flags = IORESOURCE_MEM, 237 }, 238 { 239 .start = JZ4740_IRQ_SADC, 240 .end = JZ4740_IRQ_SADC, 241 .flags = IORESOURCE_IRQ, 242 }, 243 { 244 .start = JZ4740_IRQ_ADC_BASE, 245 .end = JZ4740_IRQ_ADC_BASE, 246 .flags = IORESOURCE_IRQ, 247 }, 248}; 249 250struct platform_device jz4740_adc_device = { 251 .name = "jz4740-adc", 252 .id = -1, 253 .num_resources = ARRAY_SIZE(jz4740_adc_resources), 254 .resource = jz4740_adc_resources, 255}; 256 257/* Serial */ 258#define JZ4740_UART_DATA(_id) \ 259 { \ 260 .flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE, \ 261 .iotype = UPIO_MEM, \ 262 .regshift = 2, \ 263 .serial_out = jz4740_serial_out, \ 264 .type = PORT_16550, \ 265 .mapbase = JZ4740_UART ## _id ## _BASE_ADDR, \ 266 .irq = JZ4740_IRQ_UART ## _id, \ 267 } 268 269static struct plat_serial8250_port jz4740_uart_data[] = { 270 JZ4740_UART_DATA(0), 271 JZ4740_UART_DATA(1), 272 {}, 273}; 274 275static struct platform_device jz4740_uart_device = { 276 .name = "serial8250", 277 .id = 0, 278 .dev = { 279 .platform_data = jz4740_uart_data, 280 }, 281}; 282 283void jz4740_serial_device_register(void) 284{ 285 struct plat_serial8250_port *p; 286 287 for (p = jz4740_uart_data; p->flags != 0; ++p) 288 p->uartclk = jz4740_clock_bdata.ext_rate; 289 290 platform_device_register(&jz4740_uart_device); 291} 292