1 /* arch/arm/mach-lpc313x/ea313x.c
3 * Author: Durgesh Pattamatta
4 * Copyright (C) 2009 NXP semiconductors
6 * ea313x board init routines.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <linux/device.h>
25 #include <linux/init.h>
26 #include <linux/platform_device.h>
27 #include <linux/dm9000.h>
28 #include <linux/i2c.h>
29 #include <linux/irq.h>
30 #include <linux/interrupt.h>
31 #include <linux/spi/spi.h>
33 #include <asm/system.h>
34 #include <mach/hardware.h>
36 #include <asm/pgtable.h>
38 #include <asm/sizes.h>
40 #include <asm/mach/map.h>
41 #include <asm/mach-types.h>
43 #include <asm/mach/arch.h>
44 #include <mach/gpio.h>
46 #include <mach/board.h>
48 #include <linux/can/platform/mcp251x.h>
49 #include <linux/i2c/pca953x.h>
50 #include <linux/serial_sc16is7x2.h>
53 static struct lpc313x_mci_irq_data irq_data = {
58 static int mci_get_cd(u32 slot_id)
60 return 0; //gpio_get_value(GPIO_MNAND_RYBN2);
64 static irqreturn_t ea313x_mci_detect_interrupt(int irq, void *data)
66 struct lpc313x_mci_irq_data *pdata = data;
68 /* select the opposite level senstivity */
69 int level = mci_get_cd(0)?IRQ_TYPE_LEVEL_LOW:IRQ_TYPE_LEVEL_HIGH;
71 set_irq_type(pdata->irq, level);
73 /* change the polarity of irq trigger */
74 return pdata->irq_hdlr(irq, pdata->data);
78 static int mci_init(u32 slot_id, irq_handler_t irqhdlr, void *data)
83 /* enable power to the slot */
84 // gpio_set_value(GPIO_MI2STX_DATA0, 0);
86 /* set cd pins as GPIO pins */
87 // gpio_direction_input(GPIO_MNAND_RYBN2);
89 /* select the opposite level senstivity */
90 level = mci_get_cd(0)?IRQ_TYPE_LEVEL_LOW:IRQ_TYPE_LEVEL_HIGH;
91 /* set card detect irq info */
93 irq_data.irq_hdlr = irqhdlr;
94 set_irq_type(irq_data.irq, level);
95 ret = request_irq(irq_data.irq,
96 ea313x_mci_detect_interrupt,
100 /****temporary for PM testing */
101 enable_irq_wake(irq_data.irq);
108 static int mci_get_ro(u32 slot_id)
113 static int mci_get_ocr(u32 slot_id)
115 return MMC_VDD_32_33 | MMC_VDD_33_34;
118 static void mci_setpower(u32 slot_id, u32 volt)
120 /* on current version of EA board the card detect
121 * pull-up in on switched power side. So can't do
122 * power management so use the always enable power
126 static int mci_get_bus_wd(u32 slot_id)
131 static void mci_exit(u32 slot_id)
133 //free_irq(irq_data.irq, &irq_data);
136 static struct resource lpc313x_mci_resources[] = {
138 .start = IO_SDMMC_PHYS,
139 .end = IO_SDMMC_PHYS + IO_SDMMC_SIZE,
140 .flags = IORESOURCE_MEM,
145 .flags = IORESOURCE_IRQ,
148 static struct lpc313x_mci_board ea313x_mci_platform_data = {
150 .detect_delay_ms = 250,
152 .get_ro = mci_get_ro,
153 .get_cd = mci_get_cd,
154 .get_ocr = mci_get_ocr,
155 .get_bus_wd = mci_get_bus_wd,
156 .setpower = mci_setpower,
160 static u64 mci_dmamask = 0xffffffffUL;
161 static struct platform_device lpc313x_mci_device = {
162 .name = "lpc313x_mmc",
163 .num_resources = ARRAY_SIZE(lpc313x_mci_resources),
165 .dma_mask = &mci_dmamask,
166 .coherent_dma_mask = 0xffffffff,
167 .platform_data = &ea313x_mci_platform_data,
169 .resource = lpc313x_mci_resources,
173 * DM9000 ethernet device
175 #if defined(CONFIG_DM9000)
176 static struct resource dm9000_resource[] = {
178 .start = EXT_SRAM1_PHYS,
179 .end = EXT_SRAM1_PHYS + 0xFF,
180 .flags = IORESOURCE_MEM,
183 .start = EXT_SRAM1_PHYS + 0x10000,
184 .end = EXT_SRAM1_PHYS + 0x100FF,
185 .flags = IORESOURCE_MEM,
188 .start = IRQ_DM9000_ETH_INT,
189 .end = IRQ_DM9000_ETH_INT,
190 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
193 /* ARM MPMC contoller as part of low power design doesn't de-assert nCS and nOE for consecutive
194 reads but just changes address. But DM9000 requires nCS and nOE change between address. So access
195 other chip select area (nCS0) to force de-assertion of nCS1 and nOE1. Or else wait for long time
197 LPC313x has external logic outside of MPMC IP to toggle nOE to split consecutive reads.
198 The latest Apex bootloader pacth makes use of this feture.
199 For this to work SYS_MPMC_WTD_DEL0 & SYS_MPMC_WTD_DEL1 should be programmed with MPMC_STWTRD0
200 & MPMC_STWTRD1 values. The logic only deactivates the nOE for one clock cycle which is
201 11nsec but DM9000 needs 80nsec between nOEs. So lets add some dummy instructions such as
202 reading a GPIO register to compensate for extra 70nsec.
204 # define DM_IO_DELAY() do { gpio_get_value(GPIO_MNAND_RYBN3);} while(0)
206 static void dm9000_dumpblk(void __iomem *reg, int count)
211 count = (count + 1) >> 1;
212 for (i = 0; i < count; i++) {
218 static void dm9000_inblk(void __iomem *reg, void *data, int count)
221 u16* pdata = (u16*)data;
222 count = (count + 1) >> 1;
223 for (i = 0; i < count; i++) {
225 *pdata++ = readw(reg);
229 static struct dm9000_plat_data dm9000_platdata = {
230 .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM | DM9000_PLATF_SIMPLE_PHY,
231 .dumpblk = dm9000_dumpblk,
232 .inblk = dm9000_inblk,
235 static struct platform_device dm9000_device = {
238 .num_resources = ARRAY_SIZE(dm9000_resource),
239 .resource = dm9000_resource,
241 .platform_data = &dm9000_platdata,
244 static void __init ea_add_device_dm9000(void)
247 * Configure Chip-Select 2 on SMC for the DM9000.
248 * Note: These timings were calculated for MASTER_CLOCK = 90000000
249 * according to the DM9000 timings.
251 MPMC_STCONFIG1 = 0x81;
258 /* enable oe toggle between consec reads */
259 SYS_MPMC_WTD_DEL1 = _BIT(5) | 4;
261 /* Configure Interrupt pin as input, no pull-up */
262 gpio_direction_input(GPIO_MNAND_RYBN3);
264 platform_device_register(&dm9000_device);
267 static void __init ea_add_device_dm9000(void) {}
268 #endif /* CONFIG_DM9000 */
271 #if defined (CONFIG_MTD_NAND_LPC313X)
272 static struct resource lpc313x_nand_resources[] = {
274 .start = IO_NAND_PHYS,
275 .end = IO_NAND_PHYS + IO_NAND_SIZE,
276 .flags = IORESOURCE_MEM,
279 .start = IO_NAND_BUF_PHYS,
280 .end = IO_NAND_BUF_PHYS + IO_NAND_BUF_SIZE,
281 .flags = IORESOURCE_MEM,
284 .start = IRQ_NAND_FLASH,
285 .end = IRQ_NAND_FLASH,
286 .flags = IORESOURCE_IRQ,
290 #define BLK_SIZE (2048 * 64)
291 static struct mtd_partition ea313x_nand0_partitions[] = {
292 /* The EA3131 board uses the following block scheme:
293 128K: Blocks 0 - 0 - LPC31xx info and bad block table
294 384K: Blocks 1 - 3 - Apex bootloader
295 256K: Blocks 4 - 5 - Apex environment
296 4M: Blocks 6 - 37 - Kernel image
297 16M: Blocks 38 - 165 - Ramdisk image (if used)
298 ???: Blocks 166 - end - Root filesystem/storage */
300 .name = "lpc313x-rootfs",
301 .offset = (BLK_SIZE * 166),
302 .size = MTDPART_SIZ_FULL
306 static struct lpc313x_nand_timing ea313x_nanddev_timing = {
322 static struct lpc313x_nand_dev_info ea313x_ndev[] = {
325 .nr_partitions = ARRAY_SIZE(ea313x_nand0_partitions),
326 .partitions = ea313x_nand0_partitions
330 static struct lpc313x_nand_cfg ea313x_plat_nand = {
331 .nr_devices = ARRAY_SIZE(ea313x_ndev),
332 .devices = ea313x_ndev,
333 .timing = &ea313x_nanddev_timing,
337 static u64 nand_dmamask = 0xffffffffUL;
338 static struct platform_device lpc313x_nand_device = {
339 .name = "lpc313x_nand",
341 .dma_mask = &nand_dmamask,
342 .coherent_dma_mask = 0xffffffff,
343 .platform_data = &ea313x_plat_nand,
345 .num_resources = ARRAY_SIZE(lpc313x_nand_resources),
346 .resource = lpc313x_nand_resources,
350 #if defined(CONFIG_SPI_LPC313X)
351 static struct resource lpc313x_spi_resources[] = {
354 .end = SPI_PHYS + SZ_4K - 1,
355 .flags = IORESOURCE_MEM,
360 .flags = IORESOURCE_IRQ,
364 static void spi_set_cs_state(int cs_num, int state)
367 /* get the correct GPIO<x> mapping */
370 } else if (cs_num == 0) {
372 } else if ((cs_num > 4) && (cs_num <= 20)) {
373 cs_num = cs_num - 6 ;
376 /* DELETE_MAKRO_ASDQWERTZ089 printk("Chipselect Called with cs_pin=%d to value=%d\n",cs_num,state); */
377 gpio_set_value(cs_num, state);
378 /* DELETE_MAKRO_ASDQWERTZ089 printk("Aftercalled\n"); */
382 struct lpc313x_spics_cfg lpc313x_stdspics_cfg[] =
387 .spi_spo = 0, /* Low clock between transfers */
388 .spi_sph = 0, /* Data capture on first clock edge (high edge with spi_spo=0) */
389 .spi_cs_set = spi_set_cs_state,
393 struct lpc313x_spi_cfg lpc313x_spidata =
395 .num_cs = ARRAY_SIZE(lpc313x_stdspics_cfg),
396 .spics_cfg = lpc313x_stdspics_cfg,
399 static u64 lpc313x_spi_dma_mask = 0xffffffffUL;
400 static struct platform_device lpc313x_spi_device = {
401 .name = "spi_lpc313x",
404 .dma_mask = &lpc313x_spi_dma_mask,
405 .coherent_dma_mask = 0xffffffffUL,
406 .platform_data = &lpc313x_spidata,
408 .num_resources = ARRAY_SIZE(lpc313x_spi_resources),
409 .resource = lpc313x_spi_resources,
415 #if defined(CONFIG_MTD_DATAFLASH)
416 /* MTD Data FLASH driver registration */
417 static int __init lpc313x_spimtd_register(void)
419 struct spi_board_info info =
421 .modalias = "mtd_dataflash",
422 .max_speed_hz = 30000000,
427 return spi_register_board_info(&info, 1);
429 arch_initcall(lpc313x_spimtd_register);
433 static struct platform_device *devices[] __initdata = {
435 #if defined (CONFIG_MTD_NAND_LPC313X)
436 &lpc313x_nand_device,
438 #if defined(CONFIG_SPI_LPC313X)
443 static struct map_desc ea313x_io_desc[] __initdata = {
445 .virtual = io_p2v(EXT_SRAM0_PHYS),
446 .pfn = __phys_to_pfn(EXT_SRAM0_PHYS),
451 .virtual = io_p2v(EXT_SRAM1_PHYS + 0x10000),
452 .pfn = __phys_to_pfn(EXT_SRAM1_PHYS + 0x10000),
457 .virtual = io_p2v(IO_SDMMC_PHYS),
458 .pfn = __phys_to_pfn(IO_SDMMC_PHYS),
459 .length = IO_SDMMC_SIZE,
463 .virtual = io_p2v(IO_USB_PHYS),
464 .pfn = __phys_to_pfn(IO_USB_PHYS),
465 .length = IO_USB_SIZE,
470 struct pca953x_platform_data pca9555_plaform_info = {
473 //.setup = pca_9555_setup,
475 static struct i2c_board_info ea313x_i2c_devices[] __initdata = {
477 I2C_BOARD_INFO("pca9555", 0x20),
478 .platform_data = &pca9555_plaform_info,
483 static struct sc16is7x2_platform_data sc16is7x2_SERIALPORT3_data = {
491 static int __init lpc313x_sc16is7x2_register(void)
493 struct spi_board_info info =
495 .modalias = "sc16is7x2",
496 .platform_data = &sc16is7x2_SERIALPORT3_data,
498 .irq = gpio_to_irq(14),
500 .max_speed_hz = 187500,
502 //.controller_data = &sc16is7x2_mcspi_config,
503 //.modalias = "sc16is7x2",
504 //.max_speed_hz = 10000000,
506 //.irq = IRQ_GPIO_14,//IRQ_GPIO14
510 return spi_register_board_info(&info, 1);
512 arch_initcall(lpc313x_sc16is7x2_register);
514 #if defined(CONFIG_MACH_EA3152)
515 static struct i2c_board_info ea3152_i2c1_devices[] __initdata = {
517 I2C_BOARD_INFO("lpc3152-psu", 0x0C),
523 static void __init ea313x_init(void)
527 platform_add_devices(devices, ARRAY_SIZE(devices));
529 /* register i2cdevices */
530 lpc313x_register_i2c_devices();
531 //i2c_register_board_info(1, ea313x_i2c_devices, ARRAY_SIZE(ea313x_i2c_devices));
533 #if defined(CONFIG_MACH_EA3152)
534 i2c_register_board_info(1, ea3152_i2c1_devices,
535 ARRAY_SIZE(ea3152_i2c1_devices));
541 static void __init ea313x_map_io(void)
544 iotable_init(ea313x_io_desc, ARRAY_SIZE(ea313x_io_desc));
547 #if defined(CONFIG_MACH_EA3152)
548 MACHINE_START(EA3152, "NXP EA3152")
549 /* Maintainer: Durgesh Pattamatta, NXP */
550 .phys_io = IO_APB01_PHYS,
551 .io_pg_offst = (io_p2v(IO_APB01_PHYS) >> 18) & 0xfffc,
552 .boot_params = 0x30000100,
553 .map_io = ea313x_map_io,
554 .init_irq = lpc313x_init_irq,
555 .timer = &lpc313x_timer,
556 .init_machine = ea313x_init,
560 #if defined(CONFIG_MACH_EA313X)
561 MACHINE_START(EA313X, "NXP EA313X")
562 /* Maintainer: Durgesh Pattamatta, NXP */
563 .phys_io = IO_APB01_PHYS,
564 .io_pg_offst = (io_p2v(IO_APB01_PHYS) >> 18) & 0xfffc,
565 .boot_params = 0x30000100,
566 .map_io = ea313x_map_io,
567 .init_irq = lpc313x_init_irq,
568 .timer = &lpc313x_timer,
569 .init_machine = ea313x_init,