added ea313x.c file ...
authorhackbard <hackbard@hackdaworld.org>
Fri, 17 Jul 2015 15:49:49 +0000 (17:49 +0200)
committerhackbard <hackbard@hackdaworld.org>
Fri, 17 Jul 2015 15:49:49 +0000 (17:49 +0200)
files/nellboard/ea313x.c [new file with mode: 0644]

diff --git a/files/nellboard/ea313x.c b/files/nellboard/ea313x.c
new file mode 100644 (file)
index 0000000..bbcddaa
--- /dev/null
@@ -0,0 +1,572 @@
+/*  arch/arm/mach-lpc313x/ea313x.c
+ *
+ *  Author:    Durgesh Pattamatta
+ *  Copyright (C) 2009 NXP semiconductors
+ *
+ *  ea313x board init routines.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dm9000.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/spi/spi.h>
+
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <mach/gpio.h>
+#include <mach/i2c.h>
+#include <mach/board.h>
+
+#include <linux/can/platform/mcp251x.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/serial_sc16is7x2.h>
+
+/*
+static struct lpc313x_mci_irq_data irq_data = {
+       .irq = IRQ_SDMMC_CD,
+};
+*/
+
+static int mci_get_cd(u32 slot_id)
+{
+       return 0; //gpio_get_value(GPIO_MNAND_RYBN2);
+}
+
+#if 0
+static irqreturn_t ea313x_mci_detect_interrupt(int irq, void *data)
+{
+       struct lpc313x_mci_irq_data     *pdata = data;
+
+       /* select the opposite level senstivity */
+       int level = mci_get_cd(0)?IRQ_TYPE_LEVEL_LOW:IRQ_TYPE_LEVEL_HIGH;
+
+       set_irq_type(pdata->irq, level);
+
+       /* change the polarity of irq trigger */
+       return pdata->irq_hdlr(irq, pdata->data);
+}
+#endif
+
+static int mci_init(u32 slot_id, irq_handler_t irqhdlr, void *data)
+{
+       //int ret;
+       //int level;
+
+       /* enable power to the slot */
+//     gpio_set_value(GPIO_MI2STX_DATA0, 0);
+
+       /* set cd pins as GPIO pins */
+//     gpio_direction_input(GPIO_MNAND_RYBN2);
+#if 0
+       /* select the opposite level senstivity */
+       level = mci_get_cd(0)?IRQ_TYPE_LEVEL_LOW:IRQ_TYPE_LEVEL_HIGH;
+       /* set card detect irq info */
+       irq_data.data = data;
+       irq_data.irq_hdlr = irqhdlr;
+       set_irq_type(irq_data.irq, level);
+       ret = request_irq(irq_data.irq,
+                       ea313x_mci_detect_interrupt,
+                       level,
+                       "mmc-cd", 
+                       &irq_data);
+       /****temporary for PM testing */
+       enable_irq_wake(irq_data.irq);
+
+       return irq_data.irq;
+#endif
+       return 0;
+}
+
+static int mci_get_ro(u32 slot_id)
+{
+       return 0;
+}
+
+static int mci_get_ocr(u32 slot_id)
+{
+       return MMC_VDD_32_33 | MMC_VDD_33_34;
+}
+
+static void mci_setpower(u32 slot_id, u32 volt)
+{
+       /* on current version of EA board the card detect
+        * pull-up in on switched power side. So can't do
+        * power management so use the always enable power 
+        * jumper.
+        */
+}
+static int mci_get_bus_wd(u32 slot_id)
+{
+       return 4;
+}
+
+static void mci_exit(u32 slot_id)
+{
+       //free_irq(irq_data.irq, &irq_data);
+}
+
+static struct resource lpc313x_mci_resources[] = {
+       [0] = {
+               .start  = IO_SDMMC_PHYS,
+               .end    = IO_SDMMC_PHYS + IO_SDMMC_SIZE,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_MCI,
+               .end    = IRQ_MCI,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+static struct lpc313x_mci_board ea313x_mci_platform_data = {
+       .num_slots              = 1,
+       .detect_delay_ms        = 250,
+       .init                   = mci_init,
+       .get_ro                 = mci_get_ro,
+       .get_cd                 = mci_get_cd,
+       .get_ocr                = mci_get_ocr,
+       .get_bus_wd             = mci_get_bus_wd,
+       .setpower               = mci_setpower,
+       .exit                   = mci_exit,
+};
+
+static u64 mci_dmamask = 0xffffffffUL;
+static struct platform_device  lpc313x_mci_device = {
+       .name           = "lpc313x_mmc",
+       .num_resources  = ARRAY_SIZE(lpc313x_mci_resources),
+       .dev            = {
+               .dma_mask               = &mci_dmamask,
+               .coherent_dma_mask      = 0xffffffff,
+               .platform_data          = &ea313x_mci_platform_data,
+       },
+       .resource       = lpc313x_mci_resources,
+};
+
+/*
+ * DM9000 ethernet device
+ */
+#if defined(CONFIG_DM9000)
+static struct resource dm9000_resource[] = {
+       [0] = {
+               .start  = EXT_SRAM1_PHYS,
+               .end    = EXT_SRAM1_PHYS + 0xFF,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = EXT_SRAM1_PHYS + 0x10000,
+               .end    = EXT_SRAM1_PHYS + 0x100FF,
+               .flags  = IORESOURCE_MEM,
+       },
+       [2] = {
+               .start  = IRQ_DM9000_ETH_INT,
+               .end    = IRQ_DM9000_ETH_INT,
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       }
+};
+/* ARM MPMC contoller as part of low power design doesn't de-assert nCS and nOE for consecutive 
+reads but just changes address. But DM9000 requires nCS and nOE change between address. So access
+other chip select area (nCS0) to force de-assertion of nCS1 and nOE1. Or else wait for long time 
+such as 80 usecs. 
+LPC313x has external logic outside of MPMC IP to toggle nOE to split consecutive reads.
+The latest Apex bootloader pacth makes use of this feture.
+For this to work SYS_MPMC_WTD_DEL0 & SYS_MPMC_WTD_DEL1 should be programmed with MPMC_STWTRD0
+& MPMC_STWTRD1 values. The logic only deactivates the nOE for one clock cycle which is
+11nsec but DM9000 needs 80nsec between nOEs. So lets add some dummy instructions such as
+reading a GPIO register to compensate for extra 70nsec.
+*/
+# define DM_IO_DELAY() do { gpio_get_value(GPIO_MNAND_RYBN3);} while(0)
+
+static void dm9000_dumpblk(void __iomem *reg, int count)
+{
+       int i;
+       int tmp;
+
+       count = (count + 1) >> 1;
+       for (i = 0; i < count; i++) {
+               DM_IO_DELAY();
+               tmp = readw(reg);
+       }
+}
+
+static void dm9000_inblk(void __iomem *reg, void *data, int count)
+{
+       int i;
+       u16* pdata = (u16*)data;
+       count = (count + 1) >> 1;
+       for (i = 0; i < count; i++) {
+               DM_IO_DELAY();
+               *pdata++ = readw(reg);
+       }
+}
+
+static struct dm9000_plat_data dm9000_platdata = {
+       .flags          = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM | DM9000_PLATF_SIMPLE_PHY,
+       .dumpblk = dm9000_dumpblk,
+       .inblk = dm9000_inblk,
+};
+
+static struct platform_device dm9000_device = {
+       .name           = "dm9000",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(dm9000_resource),
+       .resource       = dm9000_resource,
+       .dev            = {
+               .platform_data  = &dm9000_platdata,
+       }
+};
+static void __init ea_add_device_dm9000(void)
+{
+       /*
+        * Configure Chip-Select 2 on SMC for the DM9000.
+        * Note: These timings were calculated for MASTER_CLOCK = 90000000
+        *  according to the DM9000 timings.
+        */
+       MPMC_STCONFIG1 = 0x81;
+       MPMC_STWTWEN1 = 1;
+       MPMC_STWTOEN1 = 1;
+       MPMC_STWTRD1 = 4;
+       MPMC_STWTPG1 = 1;
+       MPMC_STWTWR1 = 1;
+       MPMC_STWTTURN1 = 2;
+       /* enable oe toggle between consec reads */
+       SYS_MPMC_WTD_DEL1 = _BIT(5) | 4;
+
+       /* Configure Interrupt pin as input, no pull-up */
+       gpio_direction_input(GPIO_MNAND_RYBN3);
+
+       platform_device_register(&dm9000_device);
+}
+#else
+static void __init ea_add_device_dm9000(void) {}
+#endif /* CONFIG_DM9000 */
+
+
+#if defined (CONFIG_MTD_NAND_LPC313X)
+static struct resource lpc313x_nand_resources[] = {
+       [0] = {
+               .start  = IO_NAND_PHYS,
+               .end    = IO_NAND_PHYS + IO_NAND_SIZE,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IO_NAND_BUF_PHYS,
+               .end    = IO_NAND_BUF_PHYS + IO_NAND_BUF_SIZE,
+               .flags  = IORESOURCE_MEM,
+       },
+       [2] = {
+               .start  = IRQ_NAND_FLASH,
+               .end    = IRQ_NAND_FLASH,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+#define BLK_SIZE (2048 * 64)
+static struct mtd_partition ea313x_nand0_partitions[] = {
+       /* The EA3131 board uses the following block scheme:
+       128K: Blocks 0   - 0    - LPC31xx info and bad block table
+       384K: Blocks 1   - 3    - Apex bootloader
+       256K: Blocks 4   - 5    - Apex environment
+       4M:   Blocks 6   - 37   - Kernel image
+       16M:  Blocks 38  - 165  - Ramdisk image (if used)
+       ???:  Blocks 166 - end  - Root filesystem/storage */
+       {
+               .name   = "lpc313x-rootfs",
+               .offset = (BLK_SIZE * 166),
+               .size   = MTDPART_SIZ_FULL
+       },
+};
+
+static struct lpc313x_nand_timing ea313x_nanddev_timing = {
+       .ns_trsd        = 36,
+       .ns_tals        = 36,
+       .ns_talh        = 12,
+       .ns_tcls        = 36,
+       .ns_tclh        = 12,
+       .ns_tdrd        = 36,
+       .ns_tebidel     = 12,
+       .ns_tch         = 12,
+       .ns_tcs         = 48,
+       .ns_treh        = 24,
+       .ns_trp         = 48,
+       .ns_trw         = 24,
+       .ns_twp         = 36
+};
+
+static struct lpc313x_nand_dev_info ea313x_ndev[] = {
+       {
+               .name           = "nand0",
+               .nr_partitions  = ARRAY_SIZE(ea313x_nand0_partitions),
+               .partitions     = ea313x_nand0_partitions
+       }
+};
+
+static struct lpc313x_nand_cfg ea313x_plat_nand = {
+       .nr_devices     = ARRAY_SIZE(ea313x_ndev),
+       .devices        = ea313x_ndev,
+       .timing         = &ea313x_nanddev_timing,
+       .support_16bit  = 0,
+};
+
+static u64 nand_dmamask = 0xffffffffUL;
+static struct platform_device  lpc313x_nand_device = {
+       .name           = "lpc313x_nand",
+       .dev            = {
+               .dma_mask               = &nand_dmamask,
+               .coherent_dma_mask      = 0xffffffff,
+                               .platform_data  = &ea313x_plat_nand,
+       },
+       .num_resources  = ARRAY_SIZE(lpc313x_nand_resources),
+       .resource       = lpc313x_nand_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_LPC313X)
+static struct resource lpc313x_spi_resources[] = {
+       [0] = {
+               .start  = SPI_PHYS,
+               .end    = SPI_PHYS + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_SPI,
+               .end    = IRQ_SPI,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static void spi_set_cs_state(int cs_num, int state)
+{
+
+       /* get the correct GPIO<x> mapping */
+       if (cs_num == 1) {
+       cs_num = 0 ;
+       } else if (cs_num == 0) {
+       cs_num = 1 ;
+       } else if ((cs_num > 4) && (cs_num <= 20)) {
+       cs_num = cs_num - 6 ;
+       }
+
+       /* DELETE_MAKRO_ASDQWERTZ089 printk("Chipselect Called with cs_pin=%d to value=%d\n",cs_num,state); */ 
+       gpio_set_value(cs_num, state);
+       /* DELETE_MAKRO_ASDQWERTZ089 printk("Aftercalled\n");   */ 
+       
+}
+
+struct lpc313x_spics_cfg lpc313x_stdspics_cfg[] =
+{
+       /* SPI CS0 */
+       [0] =
+       {
+               .spi_spo        = 0, /* Low clock between transfers */
+               .spi_sph        = 0, /* Data capture on first clock edge (high edge with spi_spo=0) */
+               .spi_cs_set     = spi_set_cs_state,
+       },
+};
+
+struct lpc313x_spi_cfg lpc313x_spidata =
+{
+       .num_cs                 = ARRAY_SIZE(lpc313x_stdspics_cfg),
+       .spics_cfg              = lpc313x_stdspics_cfg,
+};
+
+static u64 lpc313x_spi_dma_mask = 0xffffffffUL;
+static struct platform_device lpc313x_spi_device = {
+       .name           = "spi_lpc313x",
+       .id             = 0,
+       .dev            = {
+               .dma_mask = &lpc313x_spi_dma_mask,
+               .coherent_dma_mask = 0xffffffffUL,
+               .platform_data  = &lpc313x_spidata,
+       },
+       .num_resources  = ARRAY_SIZE(lpc313x_spi_resources),
+       .resource       = lpc313x_spi_resources,
+};
+
+
+
+
+#if defined(CONFIG_MTD_DATAFLASH)
+/* MTD Data FLASH driver registration */
+static int __init lpc313x_spimtd_register(void)
+{
+       struct spi_board_info info =
+       {
+               .modalias = "mtd_dataflash",
+               .max_speed_hz = 30000000,
+               .bus_num = 0,
+               .chip_select = 0,
+       };
+
+       return spi_register_board_info(&info, 1);
+}
+arch_initcall(lpc313x_spimtd_register);
+#endif
+#endif
+
+static struct platform_device *devices[] __initdata = {
+       &lpc313x_mci_device,
+#if defined (CONFIG_MTD_NAND_LPC313X)
+       &lpc313x_nand_device,
+#endif
+#if defined(CONFIG_SPI_LPC313X)
+       &lpc313x_spi_device,
+#endif
+};
+
+static struct map_desc ea313x_io_desc[] __initdata = {
+       {
+               .virtual        = io_p2v(EXT_SRAM0_PHYS),
+               .pfn            = __phys_to_pfn(EXT_SRAM0_PHYS),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE
+       },
+       {
+               .virtual        = io_p2v(EXT_SRAM1_PHYS + 0x10000),
+               .pfn            = __phys_to_pfn(EXT_SRAM1_PHYS + 0x10000),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE
+       },
+       {
+               .virtual        = io_p2v(IO_SDMMC_PHYS),
+               .pfn            = __phys_to_pfn(IO_SDMMC_PHYS),
+               .length         = IO_SDMMC_SIZE,
+               .type           = MT_DEVICE
+       },
+       {
+               .virtual        = io_p2v(IO_USB_PHYS),
+               .pfn            = __phys_to_pfn(IO_USB_PHYS),
+               .length         = IO_USB_SIZE,
+               .type           = MT_DEVICE
+       },
+};
+/*
+struct pca953x_platform_data pca9555_plaform_info = {
+               .gpio_base = 98,
+               .invert = 0,
+               //.setup = pca_9555_setup,
+};
+static struct i2c_board_info ea313x_i2c_devices[] __initdata = {
+       {
+               I2C_BOARD_INFO("pca9555", 0x20),
+               .platform_data = &pca9555_plaform_info,
+       },
+};
+*/
+/*
+static struct sc16is7x2_platform_data sc16is7x2_SERIALPORT3_data = {
+    .uartclk = 1843200,
+    .uart_base = 0,
+    .gpio_base = 178,
+    .label = NULL,
+    .names = NULL,
+};
+
+static int __init lpc313x_sc16is7x2_register(void)
+{
+    struct spi_board_info info =
+    {
+            .modalias               = "sc16is7x2",
+        .platform_data          = &sc16is7x2_SERIALPORT3_data,
+        .bus_num                = 0,
+        .irq                    = gpio_to_irq(14),
+        .chip_select            = 15,
+        .max_speed_hz           = 187500,
+        .mode                   = SPI_MODE_0,
+        //.controller_data    = &sc16is7x2_mcspi_config,
+        //.modalias = "sc16is7x2",
+        //.max_speed_hz = 10000000,
+        //.bus_num = 0,
+        //.irq = IRQ_GPIO_14,//IRQ_GPIO14
+        //.chip_select = 1,
+    };
+
+    return spi_register_board_info(&info, 1);
+}
+arch_initcall(lpc313x_sc16is7x2_register); 
+*/
+#if defined(CONFIG_MACH_EA3152)
+static struct i2c_board_info ea3152_i2c1_devices[] __initdata = {
+       {
+               I2C_BOARD_INFO("lpc3152-psu", 0x0C),
+       },
+};
+#endif
+
+
+static void __init ea313x_init(void)
+{
+       lpc313x_init();
+       
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+
+       /* register i2cdevices */
+       lpc313x_register_i2c_devices();
+       //i2c_register_board_info(1, ea313x_i2c_devices, ARRAY_SIZE(ea313x_i2c_devices));
+       
+#if defined(CONFIG_MACH_EA3152)
+       i2c_register_board_info(1, ea3152_i2c1_devices,
+               ARRAY_SIZE(ea3152_i2c1_devices));
+#endif
+
+
+}
+
+static void __init ea313x_map_io(void)
+{
+       lpc313x_map_io();
+       iotable_init(ea313x_io_desc, ARRAY_SIZE(ea313x_io_desc));
+}
+
+#if defined(CONFIG_MACH_EA3152)
+MACHINE_START(EA3152, "NXP EA3152")
+       /* Maintainer: Durgesh Pattamatta, NXP */
+       .phys_io        = IO_APB01_PHYS,
+       .io_pg_offst    = (io_p2v(IO_APB01_PHYS) >> 18) & 0xfffc,
+       .boot_params    = 0x30000100,
+       .map_io         = ea313x_map_io,
+       .init_irq       = lpc313x_init_irq,
+       .timer          = &lpc313x_timer,
+       .init_machine   = ea313x_init,
+MACHINE_END
+#endif
+
+#if defined(CONFIG_MACH_EA313X)
+MACHINE_START(EA313X, "NXP EA313X")
+       /* Maintainer: Durgesh Pattamatta, NXP */
+       .phys_io        = IO_APB01_PHYS,
+       .io_pg_offst    = (io_p2v(IO_APB01_PHYS) >> 18) & 0xfffc,
+       .boot_params    = 0x30000100,
+       .map_io         = ea313x_map_io,
+       .init_irq       = lpc313x_init_irq,
+       .timer          = &lpc313x_timer,
+       .init_machine   = ea313x_init,
+MACHINE_END
+#endif
+