]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
Initial import of extra code in arch/arm/*omap* into omap-pool branch
authorTony Lindgren <tony@atomide.com>
Fri, 3 Apr 2009 22:23:40 +0000 (15:23 -0700)
committerTony Lindgren <tony@atomide.com>
Fri, 3 Apr 2009 22:23:40 +0000 (15:23 -0700)
This patch moves all arch/arm/*omap* changes not in mainline kernel
into omap-pool branch where it can be worked into patches for mainline,
or removed.

Signed-off-by: Tony Lindgren <tony@atomide.com>
73 files changed:
arch/arm/mach-omap1/Kconfig
arch/arm/mach-omap1/Makefile
arch/arm/mach-omap1/board-h2-mmc.c
arch/arm/mach-omap1/board-h3-mmc.c
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-nokia770.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-2430sdp-flash.c [new file with mode: 0644]
arch/arm/mach-omap2/board-2430sdp.c
arch/arm/mach-omap2/board-3430sdp-flash.c [new file with mode: 0644]
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-apollon-keys.c [new file with mode: 0644]
arch/arm/mach-omap2/board-apollon-mmc.c [new file with mode: 0644]
arch/arm/mach-omap2/board-apollon.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-omap2/board-ldp.c
arch/arm/mach-omap2/board-n800-bt.c [new file with mode: 0644]
arch/arm/mach-omap2/board-n800-camera.c [new file with mode: 0644]
arch/arm/mach-omap2/board-n800-dsp.c [new file with mode: 0644]
arch/arm/mach-omap2/board-n800-flash.c [new file with mode: 0644]
arch/arm/mach-omap2/board-n800-mmc.c [new file with mode: 0644]
arch/arm/mach-omap2/board-n800-usb.c [new file with mode: 0644]
arch/arm/mach-omap2/board-n800.c [new file with mode: 0644]
arch/arm/mach-omap2/board-n800.h [new file with mode: 0644]
arch/arm/mach-omap2/board-n810.c [new file with mode: 0644]
arch/arm/mach-omap2/board-omap2evm.c [new file with mode: 0644]
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap3evm-flash.c [new file with mode: 0644]
arch/arm/mach-omap2/board-omap3evm.c [new file with mode: 0644]
arch/arm/mach-omap2/board-omap3pandora.c
arch/arm/mach-omap2/board-overo.c
arch/arm/mach-omap2/board-rx51-flash.c [new file with mode: 0644]
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/board-rx51-sdram.c [new file with mode: 0644]
arch/arm/mach-omap2/board-rx51-video.c [new file with mode: 0644]
arch/arm/mach-omap2/board-rx51.c
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/id.c
arch/arm/mach-omap2/mmc-twl4030.c
arch/arm/mach-omap2/mmc-twl4030.h
arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h [new file with mode: 0644]
arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h [new file with mode: 0644]
arch/arm/mach-omap2/twl4030-generic-scripts.c [new file with mode: 0644]
arch/arm/mach-omap2/twl4030-generic-scripts.h [new file with mode: 0644]
arch/arm/mach-omap2/usb-ehci.c [new file with mode: 0644]
arch/arm/mach-omap2/usb-musb.c
arch/arm/mach-omap2/usb-tusb6010.c
arch/arm/plat-omap/Kconfig
arch/arm/plat-omap/Makefile
arch/arm/plat-omap/bootreason.c [new file with mode: 0644]
arch/arm/plat-omap/common.c
arch/arm/plat-omap/component-version.c [new file with mode: 0644]
arch/arm/plat-omap/dma.c [changed mode: 0644->0755]
arch/arm/plat-omap/dmtimer.c
arch/arm/plat-omap/fb.c
arch/arm/plat-omap/gpio-switch.c [new file with mode: 0644]
arch/arm/plat-omap/gpio.c
arch/arm/plat-omap/include/mach/board-nokia.h [new file with mode: 0644]
arch/arm/plat-omap/include/mach/board-rx51.h [new file with mode: 0644]
arch/arm/plat-omap/include/mach/board.h
arch/arm/plat-omap/include/mach/dma.h
arch/arm/plat-omap/include/mach/gpio-switch.h
arch/arm/plat-omap/include/mach/gpioexpander.h [deleted file]
arch/arm/plat-omap/include/mach/gpmc.h
arch/arm/plat-omap/include/mach/irqs.h
arch/arm/plat-omap/include/mach/keypad.h
arch/arm/plat-omap/include/mach/mmc.h
arch/arm/plat-omap/include/mach/sti.h [new file with mode: 0644]
arch/arm/plat-omap/include/mach/usb.h
arch/arm/plat-omap/include/mach/vmalloc.h
arch/arm/plat-omap/sram.c

index 3f325d3718a9909a1e4c8edce9b34d4b115ce4fe..a51c730da64aa90294833747fd8cebe5615ac6e2 100644 (file)
@@ -46,7 +46,6 @@ config MACH_OMAP_H2
 config MACH_OMAP_H3
        bool "TI H3 Support"
        depends on ARCH_OMAP1 && ARCH_OMAP16XX
-#      select GPIOEXPANDER_OMAP
        help
          TI OMAP 1710 H3 board support. Say Y here if you have such
          a board.
index 1bda8f5d754666550c24d3881cf0b7c59185848e..6867cd3ad0b4a7c9c391256afe760328541ccc0e 100644 (file)
@@ -13,6 +13,10 @@ obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
 # Power Management
 obj-$(CONFIG_PM) += pm.o sleep.o
 
+# DSP
+obj-$(CONFIG_OMAP_MBOX_FWK)    += mailbox_mach.o
+mailbox_mach-objs              := mailbox.o
+
 led-y := leds.o
 
 # Specific board support
index 44d4a966bed9b3aa4c6ea06efa678396f641ae52..46098f546824853499151687cb1f7bd46fc45a83 100644 (file)
 static int mmc_set_power(struct device *dev, int slot, int power_on,
                                int vdd)
 {
-       if (power_on)
-               gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 1);
-       else
-               gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0);
-
+       gpio_set_value(H2_TPS_GPIO_MMC_PWR_EN, power_on);
        return 0;
 }
 
 static int mmc_late_init(struct device *dev)
 {
-       int ret;
-
-       ret = gpio_request(H2_TPS_GPIO_MMC_PWR_EN, "MMC power");
+       int ret = gpio_request(H2_TPS_GPIO_MMC_PWR_EN, "MMC power");
        if (ret < 0)
                return ret;
 
@@ -47,7 +41,7 @@ static int mmc_late_init(struct device *dev)
        return ret;
 }
 
-static void mmc_shutdown(struct device *dev)
+static void mmc_cleanup(struct device *dev)
 {
        gpio_free(H2_TPS_GPIO_MMC_PWR_EN);
 }
@@ -60,7 +54,7 @@ static void mmc_shutdown(struct device *dev)
 static struct omap_mmc_platform_data mmc1_data = {
        .nr_slots                       = 1,
        .init                           = mmc_late_init,
-       .shutdown                       = mmc_shutdown,
+       .cleanup                        = mmc_cleanup,
        .dma_mask                       = 0xffffffff,
        .slots[0]       = {
                .set_power              = mmc_set_power,
index 0d8a3c195e2e01872efd43394e333dea2f7aa43d..5e8877ce35e09718f811578ffbcf93ee166bdf2c 100644 (file)
 static int mmc_set_power(struct device *dev, int slot, int power_on,
                                int vdd)
 {
-       if (power_on)
-               gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 1);
-       else
-               gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0);
-
+       gpio_set_value(H3_TPS_GPIO_MMC_PWR_EN, power_on);
        return 0;
 }
 
index 4695965114c4e67e86456439fa4435149e0cf374..f597968733b4f2baa980419519edade5e0203961 100644 (file)
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
-#include <mach/gpioexpander.h>
 #include <mach/irqs.h>
 #include <mach/mux.h>
 #include <mach/tc.h>
 #include <mach/nand.h>
-#include <mach/irda.h>
 #include <mach/usb.h>
 #include <mach/keypad.h>
 #include <mach/dma.h>
@@ -276,104 +274,6 @@ static struct platform_device h3_kp_device = {
        .resource       = h3_kp_resources,
 };
 
-
-/* Select between the IrDA and aGPS module
- */
-static int h3_select_irda(struct device *dev, int state)
-{
-       unsigned char expa;
-       int err = 0;
-
-       if ((err = read_gpio_expa(&expa, 0x26))) {
-               printk(KERN_ERR "Error reading from I/O EXPANDER \n");
-               return err;
-       }
-
-       /* 'P6' enable/disable IRDA_TX and IRDA_RX */
-       if (state & IR_SEL) { /* IrDA */
-               if ((err = write_gpio_expa(expa | 0x40, 0x26))) {
-                       printk(KERN_ERR "Error writing to I/O EXPANDER \n");
-                       return err;
-               }
-       } else {
-               if ((err = write_gpio_expa(expa & ~0x40, 0x26))) {
-                       printk(KERN_ERR "Error writing to I/O EXPANDER \n");
-                       return err;
-               }
-       }
-       return err;
-}
-
-static void set_trans_mode(struct work_struct *work)
-{
-       struct omap_irda_config *irda_config =
-               container_of(work, struct omap_irda_config, gpio_expa.work);
-       int mode = irda_config->mode;
-       unsigned char expa;
-       int err = 0;
-
-       if ((err = read_gpio_expa(&expa, 0x27)) != 0) {
-               printk(KERN_ERR "Error reading from I/O expander\n");
-       }
-
-       expa &= ~0x03;
-
-       if (mode & IR_SIRMODE) {
-               expa |= 0x01;
-       } else { /* MIR/FIR */
-               expa |= 0x03;
-       }
-
-       if ((err = write_gpio_expa(expa, 0x27)) != 0) {
-               printk(KERN_ERR "Error writing to I/O expander\n");
-       }
-}
-
-static int h3_transceiver_mode(struct device *dev, int mode)
-{
-       struct omap_irda_config *irda_config = dev->platform_data;
-
-       irda_config->mode = mode;
-       cancel_delayed_work(&irda_config->gpio_expa);
-       PREPARE_DELAYED_WORK(&irda_config->gpio_expa, set_trans_mode);
-       schedule_delayed_work(&irda_config->gpio_expa, 0);
-
-       return 0;
-}
-
-static struct omap_irda_config h3_irda_data = {
-       .transceiver_cap        = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
-       .transceiver_mode       = h3_transceiver_mode,
-       .select_irda            = h3_select_irda,
-       .rx_channel             = OMAP_DMA_UART3_RX,
-       .tx_channel             = OMAP_DMA_UART3_TX,
-       .dest_start             = UART3_THR,
-       .src_start              = UART3_RHR,
-       .tx_trigger             = 0,
-       .rx_trigger             = 0,
-};
-
-static struct resource h3_irda_resources[] = {
-       [0] = {
-               .start  = INT_UART3,
-               .end    = INT_UART3,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static u64 irda_dmamask = 0xffffffff;
-
-static struct platform_device h3_irda_device = {
-       .name           = "omapirda",
-       .id             = 0,
-       .dev            = {
-               .platform_data  = &h3_irda_data,
-               .dma_mask       = &irda_dmamask,
-       },
-       .num_resources  = ARRAY_SIZE(h3_irda_resources),
-       .resource       = h3_irda_resources,
-};
-
 static struct platform_device h3_lcd_device = {
        .name           = "lcd_h3",
        .id             = -1,
@@ -395,7 +295,6 @@ static struct platform_device *devices[] __initdata = {
        &nand_device,
         &smc91x_device,
        &intlat_device,
-       &h3_irda_device,
        &h3_kp_device,
        &h3_lcd_device,
 };
index 7bc7a3cb9c510459953bb45012f9c70653e55a6c..8780ca66639832b0fe54749aae4a21ab103eeb62 100644 (file)
@@ -35,6 +35,7 @@
 #include <mach/omapfb.h>
 #include <mach/lcd_mipid.h>
 #include <mach/mmc.h>
+#include <mach/usb.h>
 
 #define ADS7846_PENDOWN_GPIO   15
 
@@ -181,11 +182,7 @@ static struct omap_usb_config nokia770_usb_config __initdata = {
 static int nokia770_mmc_set_power(struct device *dev, int slot, int power_on,
                                int vdd)
 {
-       if (power_on)
-               gpio_set_value(NOKIA770_GPIO_MMC_POWER, 1);
-       else
-               gpio_set_value(NOKIA770_GPIO_MMC_POWER, 0);
-
+       gpio_set_value(NOKIA770_GPIO_MMC_POWER, power_on);
        return 0;
 }
 
index 64ab386a65c775ff7553d24b65ab8c4928d64210..3a2214cb37aba18fb5f4964223d79693902b1029 100644 (file)
@@ -10,10 +10,13 @@ config ARCH_OMAP2420
        depends on ARCH_OMAP24XX
        select OMAP_DM_TIMER
        select ARCH_OMAP_OTG
+       select CPU_V6
 
 config ARCH_OMAP2430
        bool "OMAP2430 support"
        depends on ARCH_OMAP24XX
+       select ARCH_OMAP_OTG
+       select CPU_V6
 
 config ARCH_OMAP34XX
        bool "OMAP34xx Based System"
@@ -23,6 +26,7 @@ config ARCH_OMAP3430
        bool "OMAP3430 support"
        depends on ARCH_OMAP3 && ARCH_OMAP34XX
        select ARCH_OMAP_OTG
+       select CPU_V7
 
 comment "OMAP Board Type"
        depends on ARCH_OMAP2 || ARCH_OMAP3
@@ -31,25 +35,98 @@ config MACH_OMAP_GENERIC
        bool "Generic OMAP board"
        depends on ARCH_OMAP2 && ARCH_OMAP24XX
 
+config MACH_NOKIA_N800
+       bool "Nokia N800"
+       depends on ARCH_OMAP2420
+       select VIDEO_TCM825X if VIDEO_OMAP2 && VIDEO_HELPER_CHIPS_AUTO
+       select CBUS if VIDEO_TCM825X
+       select CBUS_RETU if VIDEO_TCM825X
+       select MENELAUS if VIDEO_TCM825X
+       select OMAP_GPIO_SWITCH
+
+config MACH_NOKIA_N810
+       bool "Nokia N810"
+       depends on MACH_NOKIA_N800
+
+config MACH_NOKIA_N810_WIMAX
+       bool "Nokia N810 WiMAX"
+       depends on MACH_NOKIA_N800
+       select MACH_NOKIA_N810
+
+config MACH_NOKIA_RX51
+       bool "Nokia RX-51 board"
+       depends on ARCH_OMAP3 && ARCH_OMAP34XX
+
+config MACH_OMAP2_TUSB6010
+       bool
+       depends on ARCH_OMAP2 && ARCH_OMAP2420
+       default y if MACH_NOKIA_N800
+
 config MACH_OMAP_H4
        bool "OMAP 2420 H4 board"
-       depends on ARCH_OMAP2 && ARCH_OMAP24XX
+       depends on ARCH_OMAP2 && ARCH_OMAP2420
        select OMAP_DEBUG_DEVICES
 
+config MACH_OMAP_H4_TUSB
+       bool "TUSB 6010 EVM board"
+       depends on MACH_OMAP_H4
+       select MACH_OMAP2_TUSB6010
+       help
+         Set this if you've got a TUSB6010 high speed USB board.
+         You may need to consult the schematics for your revisions
+         of the Menelaus and TUSB boards, and make changes to be
+         sure this is set up properly for your board stack.
+
+         Be sure to select OTG mode operation, not host-only or
+         peripheral-only.
+
+config MACH_OMAP_H4_OTG
+       bool "Use USB OTG connector, not device connector (S1.10)"
+       depends on MACH_OMAP_H4
+       help
+         Set this if you've set S1.10 (on the mainboard) to use the
+         Mini-AB (OTG) connector and OTG transceiver with the USB0
+         port, instead of the Mini-B ("download") connector with its
+         non-OTG transceiver.
+
+         Note that the "download" connector can be used to bootstrap
+         the system from the OMAP mask ROM.  Also, since this is a
+         development platform, you can also force the OTG port into
+         a non-OTG operational mode.
+
+config MACH_OMAP2_H4_USB1
+       bool "Use USB1 port, not UART2 (S3.3)"
+       depends on MACH_OMAP_H4
+       help
+         Set this if you've set SW3.3 (on the CPU card) so that the
+         expansion connectors receive USB1 signals instead of UART2.
+
 config MACH_OMAP_APOLLON
        bool "OMAP 2420 Apollon board"
-       depends on ARCH_OMAP2 && ARCH_OMAP24XX
+       depends on ARCH_OMAP2 && ARCH_OMAP2420
 
 config MACH_OMAP_2430SDP
        bool "OMAP 2430 SDP board"
+       depends on ARCH_OMAP2 && ARCH_OMAP2430
+
+config MACH_OMAP_LDP
+       bool "OMAP3 LDP board"
+       depends on ARCH_OMAP3 && ARCH_OMAP34XX
+
+config MACH_OMAP2EVM 
+       bool "OMAP 2530 EVM board"
        depends on ARCH_OMAP2 && ARCH_OMAP24XX
 
-config MACH_OMAP3_BEAGLE
-       bool "OMAP3 BEAGLE board"
+config MACH_OMAP_3430SDP
+       bool "OMAP 3430 SDP board"
        depends on ARCH_OMAP3 && ARCH_OMAP34XX
 
-config MACH_OMAP_LDP
-       bool "OMAP3 LDP board"
+config MACH_OMAP3EVM
+       bool "OMAP 3530 EVM board"
+       depends on ARCH_OMAP3 && ARCH_OMAP34XX
+
+config MACH_OMAP3_BEAGLE
+       bool "OMAP3 BEAGLE board"
        depends on ARCH_OMAP3 && ARCH_OMAP34XX
 
 config MACH_OVERO
index a2c3fcc27a22990e4d1a2f3220b3d6a079100148..76acefa0c765384648fb44e29797a8c6d50be087 100644 (file)
@@ -28,26 +28,59 @@ endif
 obj-$(CONFIG_ARCH_OMAP2)               += clock24xx.o
 obj-$(CONFIG_ARCH_OMAP3)               += clock34xx.o
 
+# DSP
+obj-$(CONFIG_OMAP_MBOX_FWK)    += mailbox_mach.o
+mailbox_mach-objs              := mailbox.o
+
 # Specific board support
 obj-$(CONFIG_MACH_OMAP_GENERIC)                += board-generic.o
 obj-$(CONFIG_MACH_OMAP_H4)             += board-h4.o
 obj-$(CONFIG_MACH_OMAP_2430SDP)                += board-2430sdp.o \
+                                          board-2430sdp-flash.o \
                                           mmc-twl4030.o
-obj-$(CONFIG_MACH_OMAP_APOLLON)                += board-apollon.o
-obj-$(CONFIG_MACH_OMAP3_BEAGLE)                += board-omap3beagle.o \
+obj-$(CONFIG_MACH_OMAP2EVM)            += board-omap2evm.o \
                                           mmc-twl4030.o
+obj-$(CONFIG_MACH_OMAP_3430SDP)                += board-3430sdp.o \
+                                          mmc-twl4030.o \
+                                          board-3430sdp-flash.o
+obj-$(CONFIG_MACH_OMAP3EVM)            += board-omap3evm.o \
+                                          mmc-twl4030.o \
+                                          board-omap3evm-flash.o \
+                                          twl4030-generic-scripts.o
+obj-$(CONFIG_MACH_OMAP3_BEAGLE)                += board-omap3beagle.o \
+                                          mmc-twl4030.o \
+                                          twl4030-generic-scripts.o
 obj-$(CONFIG_MACH_OMAP_LDP)            += board-ldp.o \
                                           mmc-twl4030.o
-obj-$(CONFIG_MACH_OVERO)               += board-overo.o \
+obj-$(CONFIG_MACH_OMAP_APOLLON)                += board-apollon.o \
+                                          board-apollon-mmc.o  \
+                                          board-apollon-keys.o
+obj-$(CONFIG_MACH_NOKIA_N800)          += board-n800.o board-n800-flash.o \
+                                          board-n800-mmc.o board-n800-bt.o \
+                                          board-n800-usb.o \
+                                          board-n800-dsp.o \
+                                          board-n800-camera.o
+obj-$(CONFIG_MACH_NOKIA_N810)          += board-n810.o
+obj-$(CONFIG_MACH_NOKIA_RX51)          += board-rx51.o \
+                                          board-n800-flash.o \
+                                          board-rx51-flash.o \
+                                          board-rx51-sdram.o \
+                                          board-rx51-video.o \
+                                          board-rx51-peripherals.o \
                                           mmc-twl4030.o
+
+obj-$(CONFIG_MACH_OVERO)               += board-overo.o \
+                                          mmc-twl4030.o \
+                                          twl4030-generic-scripts.o
 obj-$(CONFIG_MACH_OMAP3_PANDORA)       += board-omap3pandora.o \
                                           mmc-twl4030.o
-obj-$(CONFIG_MACH_OMAP_3430SDP)                += board-3430sdp.o \
-                                          mmc-twl4030.o
 
-obj-$(CONFIG_MACH_NOKIA_RX51)          += board-rx51.o \
-                                          board-rx51-peripherals.o \
 # Platform specific device init code
-ifeq ($(CONFIG_USB_MUSB_SOC),y)
-obj-y                                  += usb-musb.o
+obj-$(CONFIG_USB_MUSB_SOC)             += usb-musb.o
+obj-$(CONFIG_MACH_OMAP2_TUSB6010)      += usb-tusb6010.o
+
+ifneq ($(CONFIG_USB_EHCI_HCD),)
+       obj-y                           += usb-ehci.o
 endif
+
+
diff --git a/arch/arm/mach-omap2/board-2430sdp-flash.c b/arch/arm/mach-omap2/board-2430sdp-flash.c
new file mode 100644 (file)
index 0000000..57d3b55
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * linux/arch/arm/mach-omap2/board-2430sdp-flash.c
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
+ * Author: Kevin Hilman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <asm/mach/flash.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/onenand_regs.h>
+
+#include <asm/io.h>
+#include <mach/onenand.h>
+#include <mach/board.h>
+#include <mach/gpmc.h>
+#include <mach/nand.h>
+
+#define ONENAND_MAP 0x20000000
+#define GPMC_OFF_CONFIG1_0 0x60
+
+enum fstype {
+       NAND = 0,
+       NOR,
+       ONENAND,
+       UNKNOWN = -1
+};
+
+static enum fstype flash_type = NAND;
+
+static struct mtd_partition nand_partitions[] = {
+       {
+               .name           = "X-Loader",
+               .offset         = 0,
+               .size           = 4*(64*2048),  /* 0-3 blks reserved.
+                                                  Mandated by ROM code */
+               .mask_flags     = MTD_WRITEABLE /* force read-only */
+       },
+       {
+               .name           = "U-Boot",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           =  4*(64*2048),
+               .mask_flags     = MTD_WRITEABLE /* force read-only */
+       },
+       {
+               .name           = "U-Boot Environment",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 2*(64*2048),
+       },
+       {
+               .name           = "Kernel",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 32*(64*2048),         /* 4*1M */
+       },
+       {
+               .name           = "File System",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = MTDPART_SIZ_FULL,
+       },
+};
+static struct omap_nand_platform_data sdp_nand_data = {
+       .parts          = nand_partitions,
+       .nr_parts       = ARRAY_SIZE(nand_partitions),
+       .dma_channel    = -1,   /* disable DMA in OMAP OneNAND driver */
+};
+
+static struct platform_device sdp_nand_device = {
+       .name           = "omap2-nand",
+       .id             = -1,
+       .dev = {
+               .platform_data = &sdp_nand_data,
+       },
+};
+
+static struct mtd_partition onenand_partitions[] = {
+       {
+               .name           = "(OneNAND)X-Loader",
+               .offset         = 0,
+               .size           = 4*(64*2048),  /* 0-3 blks reserved.
+                                                  Mandated by ROM code */
+               .mask_flags     = MTD_WRITEABLE /* force read-only */
+       },
+       {
+               .name           = "(OneNAND)U-Boot",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           =  2*(64*2048),
+               .mask_flags     = MTD_WRITEABLE /* force read-only */
+       },
+       {
+               .name           = "(OneNAND)U-Boot Environment",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 1*(64*2048),
+       },
+       {
+               .name           = "(OneNAND)Kernel",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 4*(64*2048),
+       },
+       {
+               .name           = "(OneNAND)File System",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct omap_onenand_platform_data sdp_onenand_data = {
+       .parts          = onenand_partitions,
+       .nr_parts       = ARRAY_SIZE(onenand_partitions),
+       .dma_channel    = -1,   /* disable DMA in OMAP OneNAND driver */
+};
+
+static struct platform_device sdp_onenand_device = {
+       .name           = "omap2-onenand",
+       .id             = -1,
+       .dev = {
+               .platform_data = &sdp_onenand_data,
+       },
+};
+
+void __init sdp2430_flash_init(void)
+{
+       void __iomem *gpmc_base_add, *gpmc_cs_base_add;
+       unsigned char cs = 0;
+
+       gpmc_base_add = (__force void __iomem *)OMAP243X_GPMC_VIRT;
+       while (cs < GPMC_CS_NUM) {
+               int ret = 0;
+
+               /* Each GPMC set for a single CS is at offset 0x30 */
+               gpmc_cs_base_add = (gpmc_base_add + GPMC_OFF_CONFIG1_0 +
+                                   (cs*0x30));
+
+               /* xloader/Uboot would have programmed the NAND/oneNAND
+                * base address for us This is a ugly hack. The proper
+                * way of doing this is to pass the setup of u-boot up
+                * to kernel using kernel params - something on the
+                * lines of machineID. Check if Nand/oneNAND is
+                * configured */
+               ret = __raw_readl(gpmc_cs_base_add + GPMC_CS_CONFIG1);
+               if ((ret & 0xC00) == (0x800)) {
+                       /* Found it!! */
+                       printk(KERN_INFO "NAND: Found NAND on CS %d \n", cs);
+                       flash_type = NAND;
+                       break;
+               }
+               ret = __raw_readl(gpmc_cs_base_add + GPMC_CS_CONFIG7);
+               if ((ret & 0x3F) == (ONENAND_MAP >> 24)) {
+                       /* Found it!! */
+                       flash_type = ONENAND;
+                       break;
+               }
+               cs++;
+       }
+       if (cs >= GPMC_CS_NUM) {
+               printk(KERN_INFO "MTD: Unable to find MTD configuration in "
+                                "GPMC   - not registering.\n");
+               return;
+       }
+
+       if (flash_type == NAND) {
+               sdp_nand_data.cs               = cs;
+               sdp_nand_data.gpmc_cs_baseaddr = gpmc_cs_base_add;
+               sdp_nand_data.gpmc_baseaddr    = gpmc_base_add;
+
+               if (platform_device_register(&sdp_nand_device) < 0) {
+                       printk(KERN_ERR "Unable to register NAND device\n");
+                       return;
+               }
+       }
+
+       if (flash_type == ONENAND) {
+               sdp_onenand_data.cs = cs;
+
+               if (platform_device_register(&sdp_onenand_device) < 0) {
+                       printk(KERN_ERR "Unable to register OneNAND device\n");
+                       return;
+               }
+       }
+}
index 22143651037e3b62c526f128c282e1132deac9fd..899e6e3402dd2051484d4f6aef7afaf57b7a80ad 100644 (file)
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/delay.h>
+#include <linux/input.h>
 #include <linux/i2c/twl4030.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <mach/gpio.h>
 #include <mach/mux.h>
 #include <mach/board.h>
+#include <mach/usb.h>
 #include <mach/common.h>
 #include <mach/gpmc.h>
-#include <mach/usb.h>
+#include <mach/mcspi.h>
+
 
 #include "mmc-twl4030.h"
 
 #define SDP2430_CS0_BASE       0x04000000
 #define        SDP2430_FLASH_CS        0
 #define        SDP2430_SMC91X_CS       5
-
 #define SDP2430_ETHR_GPIO_IRQ          149
 
+/* GPIO used for TSC2046 (touchscreen)
+ *
+ * Also note that the tsc2046 is the same silicon as the ads7846, so
+ * that driver is used for the touchscreen. */
+#define TS_GPIO                 24
+
+#define TWL4030_MSECURE_GPIO   118
+#define SECONDARY_LCD_GPIO     147
+
+extern void sdp2430_flash_init(void);
+
 static struct mtd_partition sdp2430_partitions[] = {
        /* bootloader (U-Boot, etc) in first sector */
        {
@@ -112,6 +127,11 @@ static struct resource sdp2430_smc91x_resources[] = {
        },
 };
 
+static struct platform_device sdp2430_lcd_device = {
+       .name           = "sdp2430_lcd",
+       .id             = -1,
+};
+
 static struct platform_device sdp2430_smc91x_device = {
        .name           = "smc91x",
        .id             = -1,
@@ -119,9 +139,125 @@ static struct platform_device sdp2430_smc91x_device = {
        .resource       = sdp2430_smc91x_resources,
 };
 
+/*
+ * Key mapping for 2430 SDP board
+ */
+
+static int sdp2430_keymap[] = {
+       KEY(0, 0, KEY_LEFT),
+       KEY(0, 1, KEY_RIGHT),
+       KEY(0, 2, KEY_A),
+       KEY(0, 3, KEY_B),
+       KEY(0, 4, KEY_C),
+       KEY(1, 0, KEY_DOWN),
+       KEY(1, 1, KEY_UP),
+       KEY(1, 2, KEY_E),
+       KEY(1, 3, KEY_F),
+       KEY(1, 4, KEY_G),
+       KEY(2, 0, KEY_ENTER),
+       KEY(2, 1, KEY_I),
+       KEY(2, 2, KEY_J),
+       KEY(2, 3, KEY_K),
+       KEY(2, 4, KEY_3),
+       KEY(3, 0, KEY_M),
+       KEY(3, 1, KEY_N),
+       KEY(3, 2, KEY_O),
+       KEY(3, 3, KEY_P),
+       KEY(3, 4, KEY_Q),
+       KEY(4, 0, KEY_R),
+       KEY(4, 1, KEY_4),
+       KEY(4, 2, KEY_T),
+       KEY(4, 3, KEY_U),
+       KEY(4, 4, KEY_D),
+       KEY(5, 0, KEY_V),
+       KEY(5, 1, KEY_W),
+       KEY(5, 2, KEY_L),
+       KEY(5, 3, KEY_S),
+       KEY(5, 4, KEY_H),
+       0
+};
+
+static struct twl4030_keypad_data sdp2430_kp_data = {
+       .rows           = 5,
+       .cols           = 6,
+       .keymap         = sdp2430_keymap,
+       .keymapsize     = ARRAY_SIZE(sdp2430_keymap),
+       .rep            = 1,
+};
+
+static int __init msecure_init(void)
+{
+       int ret = 0;
+
+#ifdef CONFIG_RTC_DRV_TWL4030
+       ret = gpio_request(TWL4030_MSECURE_GPIO, "msecure");
+       if (ret < 0) {
+               printk(KERN_ERR "msecure_init: can't reserve GPIO:%d !\n",
+                       TWL4030_MSECURE_GPIO);
+               goto out;
+       }
+       /*
+        * TWL4030 will be in secure mode if msecure line from OMAP is low.
+        * Make msecure line high in order to change the TWL4030 RTC time
+        * and calender registers.
+        */
+       gpio_direction_output(TWL4030_MSECURE_GPIO, 1);
+out:
+#endif
+
+       return ret;
+}
+
 static struct platform_device *sdp2430_devices[] __initdata = {
        &sdp2430_smc91x_device,
        &sdp2430_flash_device,
+       &sdp2430_lcd_device,
+};
+
+static void ads7846_dev_init(void)
+{
+       if (gpio_request(TS_GPIO, "ads7846 irq") < 0)
+               printk(KERN_ERR "can't get ads746 pen down GPIO\n");
+
+       gpio_direction_input(TS_GPIO);
+
+       omap_set_gpio_debounce(TS_GPIO, 1);
+       omap_set_gpio_debounce_time(TS_GPIO, 0xa);
+}
+
+static int ads7846_get_pendown_state(void)
+{
+       return !gpio_get_value(TS_GPIO);
+}
+
+static struct ads7846_platform_data tsc2046_config __initdata = {
+       .get_pendown_state = ads7846_get_pendown_state,
+       .keep_vref_on      = 1,
+};
+
+static struct omap2_mcspi_device_config tsc2046_mcspi_config = {
+       .turbo_mode     = 0,
+       .single_channel = 0,  /* 0: slave, 1: master */
+};
+
+static struct omap_lcd_config sdp2430_lcd_config __initdata = {
+       .ctrl_name      = "internal",
+};
+
+static struct spi_board_info sdp2430_spi_board_info[] __initdata = {
+       [0] = {
+               /*
+                * TSC2046 operates at a max freqency of 2MHz, so
+                * operate slightly below at 1.5MHz
+                */
+               .modalias        = "ads7846",
+               .bus_num         = 1,
+               .chip_select     = 0,
+               .max_speed_hz    = 1500000,
+               .controller_data = &tsc2046_mcspi_config,
+               .irq             = OMAP_GPIO_IRQ(TS_GPIO),
+               .platform_data   = &tsc2046_config,
+       },
 };
 
 static inline void __init sdp2430_init_smc91x(void)
@@ -199,8 +335,16 @@ static struct omap_uart_config sdp2430_uart_config __initdata = {
        .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
 };
 
-static struct omap_board_config_kernel sdp2430_config[] = {
+static
+struct omap_serial_console_config sdp2430_serial_console_config __initdata = {
+       .console_uart = 1,
+       .console_speed = 115200,
+};
+
+static struct omap_board_config_kernel sdp2430_config[] __initdata = {
        {OMAP_TAG_UART, &sdp2430_uart_config},
+       {OMAP_TAG_LCD, &sdp2430_lcd_config},
+       {OMAP_TAG_SERIAL_CONSOLE, &sdp2430_serial_console_config},
 };
 
 
@@ -210,12 +354,23 @@ static struct twl4030_gpio_platform_data sdp2430_gpio_data = {
        .irq_end        = TWL4030_GPIO_IRQ_END,
 };
 
+static struct twl4030_usb_data sdp2430_usb_data = {
+       .usb_mode       = T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_madc_platform_data sdp2430_madc_data = {
+       .irq_line       = 1,
+};
+
 static struct twl4030_platform_data sdp2430_twldata = {
        .irq_base       = TWL4030_IRQ_BASE,
        .irq_end        = TWL4030_IRQ_END,
 
        /* platform_data for children goes here */
        .gpio           = &sdp2430_gpio_data,
+       .madc           = &sdp2430_madc_data,
+       .keypad         = &sdp2430_kp_data,
+       .usb            = &sdp2430_usb_data,
 };
 
 static struct i2c_board_info __initdata sdp2430_i2c_boardinfo[] = {
@@ -254,8 +409,19 @@ static void __init omap_2430sdp_init(void)
        omap_board_config = sdp2430_config;
        omap_board_config_size = ARRAY_SIZE(sdp2430_config);
        omap_serial_init();
-       twl4030_mmc_init(mmc);
+
+       msecure_init();
+
+       sdp2430_flash_init();
        usb_musb_init();
+
+       spi_register_board_info(sdp2430_spi_board_info,
+                               ARRAY_SIZE(sdp2430_spi_board_info));
+       ads7846_dev_init();
+       twl4030_mmc_init(mmc);
+
+       /* turn off secondary LCD backlight */
+       gpio_direction_output(SECONDARY_LCD_GPIO, 0);
 }
 
 static void __init omap_2430sdp_map_io(void)
diff --git a/arch/arm/mach-omap2/board-3430sdp-flash.c b/arch/arm/mach-omap2/board-3430sdp-flash.c
new file mode 100644 (file)
index 0000000..f0e25a4
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * linux/arch/arm/mach-omap2/board-3430sdp-flash.c
+ *
+ * Copyright (c) 2007 Texas Instruments
+ *
+ * Modified from mach-omap2/board-2430sdp-flash.c
+ * Author: Rohit Choraria <rohitkc@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/onenand_regs.h>
+#include <linux/types.h>
+#include <linux/io.h>
+
+#include <asm/mach/flash.h>
+#include <mach/onenand.h>
+#include <mach/board.h>
+#include <mach/gpmc.h>
+#include <mach/nand.h>
+
+#define NAND_BLOCK_SIZE                SZ_128K
+
+/* NAND */
+/* IMPORTANT NOTE ON MAPPING
+ * 3430SDP - 34XX
+ * ----------
+ * NOR always on 0x04000000 for SDPV1
+ * NOR always on 0x10000000 for SDPV2
+ * MPDB always on 0x08000000
+ * NAND always on 0x0C000000
+ * OneNand Mapped to 0x20000000
+ * Boot Mode(NAND/NOR). The other on CS1
+ */
+#define FLASH_BASE_SDPV1       0x04000000 /* NOR flash (64 Meg aligned) */
+#define FLASH_BASE_SDPV2       0x10000000 /* NOR flash (256 Meg aligned) */
+#define DEBUG_BASE             0x08000000 /* debug board */
+#define NAND_BASE              0x0C000000 /* NAND flash */
+#define ONENAND_MAP            0x20000000 /* OneNand flash */
+
+/* various memory sizes */
+#define FLASH_SIZE_SDPV1       SZ_64M
+#define FLASH_SIZE_SDPV2       SZ_128M
+
+static struct mtd_partition sdp_nor_partitions[] = {
+       /* bootloader (U-Boot, etc) in first sector */
+       {
+               .name           = "Bootloader-NOR",
+               .offset         = 0,
+               .size           = SZ_256K,
+               .mask_flags     = MTD_WRITEABLE, /* force read-only */
+       },
+       /* bootloader params in the next sector */
+       {
+               .name           = "Params-NOR",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = SZ_256K,
+               .mask_flags     = 0,
+       },
+       /* kernel */
+       {
+               .name           = "Kernel-NOR",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = SZ_2M,
+               .mask_flags     = 0
+       },
+       /* file system */
+       {
+               .name           = "Filesystem-NOR",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = MTDPART_SIZ_FULL,
+               .mask_flags     = 0
+       }
+};
+
+static struct flash_platform_data sdp_nor_data = {
+       .map_name       = "cfi_probe",
+       .width          = 2,
+       .parts          = sdp_nor_partitions,
+       .nr_parts       = ARRAY_SIZE(sdp_nor_partitions),
+};
+
+static struct resource sdp_nor_resource = {
+       .start          = 0,
+       .end            = 0,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device sdp_nor_device = {
+       .name           = "omapflash",
+       .id             = 0,
+       .dev            = {
+                       .platform_data = &sdp_nor_data,
+       },
+       .num_resources  = 1,
+       .resource       = &sdp_nor_resource,
+};
+
+static int sdp_onenand_setup(void __iomem *, int freq);
+
+static struct mtd_partition sdp_onenand_partitions[] = {
+       {
+               .name           = "X-Loader-OneNAND",
+               .offset         = 0,
+               .size           = 4 * (64 * 2048),
+               .mask_flags     = MTD_WRITEABLE  /* force read-only */
+       },
+       {
+               .name           = "U-Boot-OneNAND",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 2 * (64 * 2048),
+               .mask_flags     = MTD_WRITEABLE  /* force read-only */
+       },
+       {
+               .name           = "U-Boot Environment-OneNAND",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 1 * (64 * 2048),
+       },
+       {
+               .name           = "Kernel-OneNAND",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 16 * (64 * 2048),
+       },
+       {
+               .name           = "File System-OneNAND",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct omap_onenand_platform_data sdp_onenand_data = {
+       .parts          = sdp_onenand_partitions,
+       .nr_parts       = ARRAY_SIZE(sdp_onenand_partitions),
+       .onenand_setup  = sdp_onenand_setup,
+       .dma_channel    = -1,   /* disable DMA in OMAP OneNAND driver */
+};
+
+static struct platform_device sdp_onenand_device = {
+       .name           = "omap2-onenand",
+       .id             = -1,
+       .dev = {
+               .platform_data = &sdp_onenand_data,
+       },
+};
+
+/*
+ * sdp_onenand_setup - The function configures the onenand flash.
+ * @onenand_base: Onenand base address
+ *
+ * @return int:        Currently always returning zero.
+ */
+static int sdp_onenand_setup(void __iomem *onenand_base, int freq)
+{
+       /* Onenand setup does nothing at present */
+       return 0;
+}
+
+static struct mtd_partition sdp_nand_partitions[] = {
+       /* All the partition sizes are listed in terms of NAND block size */
+       {
+               .name           = "X-Loader-NAND",
+               .offset         = 0,
+               .size           = 4 * NAND_BLOCK_SIZE,
+               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
+       },
+       {
+               .name           = "U-Boot-NAND",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x80000 */
+               .size           = 4 * NAND_BLOCK_SIZE,
+               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
+       },
+       {
+               .name           = "Boot Env-NAND",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x100000 */
+               .size           = 2 * NAND_BLOCK_SIZE,
+       },
+       {
+               .name           = "Kernel-NAND",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x140000 */
+               .size           = 32 * NAND_BLOCK_SIZE,
+       },
+       {
+               .name           = "File System - NAND",
+               .size           = MTDPART_SIZ_FULL,
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x540000 */
+       },
+};
+
+static struct omap_nand_platform_data sdp_nand_data = {
+       .parts          = sdp_nand_partitions,
+       .nr_parts       = ARRAY_SIZE(sdp_nand_partitions),
+       .nand_setup     = NULL,
+       .dma_channel    = -1,           /* disable DMA in OMAP NAND driver */
+       .dev_ready      = NULL,
+};
+
+static struct resource sdp_nand_resource = {
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device sdp_nand_device = {
+       .name           = "omap2-nand",
+       .id             = 0,
+       .dev            = {
+       .platform_data  = &sdp_nand_data,
+       },
+       .num_resources  = 1,
+       .resource       = &sdp_nand_resource,
+};
+
+
+/**
+ * sdp3430_flash_init - Identify devices connected to GPMC and register.
+ *
+ * @return - void.
+ */
+void __init sdp3430_flash_init(void)
+{
+       u8              cs = 0;
+       u8              nandcs = GPMC_CS_NUM + 1;
+       u8              onenandcs = GPMC_CS_NUM + 1;
+       unsigned long   gpmc_base_add;
+
+       gpmc_base_add   = OMAP34XX_GPMC_VIRT;
+
+       /* Configure start address and size of NOR device */
+       if (omap_rev() > OMAP3430_REV_ES1_0) {
+               sdp_nor_resource.start  = FLASH_BASE_SDPV2;
+               sdp_nor_resource.end    = FLASH_BASE_SDPV2
+                                               + FLASH_SIZE_SDPV2 - 1;
+       } else {
+               sdp_nor_resource.start  = FLASH_BASE_SDPV1;
+               sdp_nor_resource.end    = FLASH_BASE_SDPV1
+                                               + FLASH_SIZE_SDPV1 - 1;
+       }
+
+       if (platform_device_register(&sdp_nor_device) < 0)
+               printk(KERN_ERR "Unable to register NOR device\n");
+
+       while (cs < GPMC_CS_NUM) {
+               u32 ret = 0;
+               ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+               /*
+               * xloader/Uboot would have programmed the NAND/oneNAND
+               * base address for us This is a ugly hack. The proper
+               * way of doing this is to pass the setup of u-boot up
+               * to kernel using kernel params - something on the
+               * lines of machineID. Check if oneNAND is configured
+               */
+               if ((ret & 0xC00) == 0x800) {
+                       /* Found it!! */
+                       if (nandcs > GPMC_CS_NUM)
+                               nandcs = cs;
+               } else {
+                       ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+                       if ((ret & 0x3F) == (ONENAND_MAP >> 24))
+                       onenandcs = cs;
+               }
+               cs++;
+       }
+       if ((nandcs > GPMC_CS_NUM) && (onenandcs > GPMC_CS_NUM)) {
+               printk(KERN_INFO "NAND/OneNAND: Unable to find configuration "
+                               " in GPMC\n ");
+               return;
+       }
+
+       if (nandcs < GPMC_CS_NUM) {
+               sdp_nand_data.cs        = nandcs;
+               sdp_nand_data.gpmc_cs_baseaddr   = (void *)(gpmc_base_add +
+                                       GPMC_CS0_BASE + nandcs*GPMC_CS_SIZE);
+               sdp_nand_data.gpmc_baseaddr     = (void *) (gpmc_base_add);
+
+               if (platform_device_register(&sdp_nand_device) < 0)
+                       printk(KERN_ERR "Unable to register NAND device\n");
+       }
+
+       if (onenandcs < GPMC_CS_NUM) {
+               sdp_onenand_data.cs = onenandcs;
+               if (platform_device_register(&sdp_onenand_device) < 0)
+                       printk(KERN_ERR "Unable to register OneNAND device\n");
+       }
+}
index ed9274972122e782fcc1d94b2570f82f2b0733fb..03acac79adfc730cb697d1d4dcff29312c48fc2d 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/input.h>
+#include <linux/err.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/i2c/twl4030.h>
 #include <linux/regulator/machine.h>
 #include <linux/io.h>
-#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -30,6 +30,7 @@
 #include <asm/mach/map.h>
 
 #include <mach/mcspi.h>
+#include <mach/gpio.h>
 #include <mach/mux.h>
 #include <mach/board.h>
 #include <mach/usb.h>
 #include <mach/gpmc.h>
 
 #include <mach/control.h>
-#include <mach/keypad.h>
 
+#include "sdram-qimonda-hyb18m512160af-6.h"
 #include "mmc-twl4030.h"
 
 #define CONFIG_DISABLE_HFCLK 1
 
+#define SDP3430_ETHR_START             DEBUG_BASE
 #define SDP3430_ETHR_GPIO_IRQ_SDPV1    29
 #define SDP3430_ETHR_GPIO_IRQ_SDPV2    6
 #define SDP3430_SMC91X_CS              3
 #define ENABLE_VAUX3_DEDICATED 0x03
 #define ENABLE_VAUX3_DEV_GRP   0x20
 
+#define ENABLE_VAUX3_DEDICATED 0x03
+#define ENABLE_VAUX3_DEV_GRP   0x20
+
 #define TWL4030_MSECURE_GPIO 22
 
+extern void sdp3430_flash_init(void);
+
 static struct resource sdp3430_smc91x_resources[] = {
        [0] = {
                .flags  = IORESOURCE_MEM,
@@ -118,6 +125,42 @@ static struct twl4030_keypad_data sdp3430_kp_data = {
 
 static int ts_gpio;    /* Needed for ads7846_get_pendown_state */
 
+static int __init msecure_init(void)
+{
+       int ret = 0;
+
+#ifdef CONFIG_RTC_DRV_TWL4030
+       /* 3430ES2.0 doesn't have msecure/gpio-22 line connected to T2 */
+       if (omap_type() == OMAP2_DEVICE_TYPE_GP &&
+                       omap_rev() < OMAP3430_REV_ES2_0) {
+               void __iomem *msecure_pad_config_reg = omap_ctrl_base_get() +
+                       0xA3C;
+               int mux_mask = 0x04;
+               u16 tmp;
+
+               ret = gpio_request(TWL4030_MSECURE_GPIO, "msecure");
+               if (ret < 0) {
+                       printk(KERN_ERR "msecure_init: can't"
+                               "reserve GPIO:%d !\n", TWL4030_MSECURE_GPIO);
+                       goto out;
+               }
+               /*
+                * TWL4030 will be in secure mode if msecure line from OMAP
+                * is low. Make msecure line high in order to change the
+                * TWL4030 RTC time and calender registers.
+                */
+               tmp = __raw_readw(msecure_pad_config_reg);
+               tmp &= 0xF8; /* To enable mux mode 03/04 = GPIO_RTC */
+               tmp |= mux_mask;/* To enable mux mode 03/04 = GPIO_RTC */
+               __raw_writew(tmp, msecure_pad_config_reg);
+
+               gpio_direction_output(TWL4030_MSECURE_GPIO, 1);
+       }
+out:
+#endif
+       return ret;
+}
+
 /**
  * @brief ads7846_dev_init : Requests & sets GPIO line for pen-irq
  *
@@ -141,9 +184,42 @@ static int ads7846_get_pendown_state(void)
        return !gpio_get_value(ts_gpio);
 }
 
+/*
+ * This enable(1)/disable(0) the voltage for TS: uses twl4030 calls
+ */
+static int ads7846_vaux_control(int vaux_cntrl)
+{
+       int ret = 0;
+
+       /* FIXME use regulator calls */
+
+#ifdef CONFIG_TWL4030_CORE
+       /* check for return value of ldo_use: if success it returns 0 */
+       if (vaux_cntrl == VAUX_ENABLE) {
+               if (ret != twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                       ENABLE_VAUX3_DEDICATED, TWL4030_VAUX3_DEDICATED))
+                       return -EIO;
+               if (ret != twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                       ENABLE_VAUX3_DEV_GRP, TWL4030_VAUX3_DEV_GRP))
+                       return -EIO;
+       } else if (vaux_cntrl == VAUX_DISABLE) {
+               if (ret != twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                       0x00, TWL4030_VAUX3_DEDICATED))
+                       return -EIO;
+               if (ret != twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                       0x00, TWL4030_VAUX3_DEV_GRP))
+                       return -EIO;
+       }
+#else
+       ret = -EIO;
+#endif
+       return ret;
+}
+
 static struct ads7846_platform_data tsc2046_config __initdata = {
        .get_pendown_state      = ads7846_get_pendown_state,
        .keep_vref_on           = 1,
+       .vaux_control           = ads7846_vaux_control,
 };
 
 
@@ -222,7 +298,7 @@ static inline void __init sdp3430_init_smc91x(void)
 
 static void __init omap_3430sdp_init_irq(void)
 {
-       omap2_init_common_hw(NULL);
+       omap2_init_common_hw(hyb18m512160af6_sdrc_params);
        omap_init_irq();
        omap_gpio_init();
        sdp3430_init_smc91x();
@@ -331,6 +407,87 @@ static struct twl4030_madc_platform_data sdp3430_madc_data = {
        .irq_line       = 1,
 };
 
+
+static struct twl4030_ins __initdata sleep_on_seq[] = {
+/*
+ * Turn off VDD1 and VDD2.
+ */
+       {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_OFF), 4},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_OFF), 2},
+#ifdef CONFIG_DISABLE_HFCLK
+/*
+ * And also turn off the OMAP3 PLLs and the sysclk output.
+ */
+       {MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_OFF), 3},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x19, RES_STATE_OFF), 3},
+#endif
+};
+
+static struct twl4030_script sleep_on_script __initdata = {
+       .script = sleep_on_seq,
+       .size   = ARRAY_SIZE(sleep_on_seq),
+       .flags  = TRITON_SLEEP_SCRIPT,
+};
+
+static struct twl4030_ins wakeup_seq[] __initdata = {
+#ifndef CONFIG_DISABLE_HFCLK
+/*
+ * Wakeup VDD1 and VDD2.
+ */
+       {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_ACTIVE), 4},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_ACTIVE), 2},
+#else
+/*
+ * Reenable the OMAP3 PLLs.
+ * Wakeup VDD1 and VDD2.
+ * Reenable sysclk output.
+ */
+       {MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_ACTIVE), 0x30},
+       {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_ACTIVE), 0x30},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_ACTIVE), 0x37},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x19, RES_STATE_ACTIVE), 3},
+#endif /* #ifndef CONFIG_DISABLE_HFCLK */
+};
+
+static struct twl4030_script wakeup_script __initdata = {
+       .script = wakeup_seq,
+       .size   = ARRAY_SIZE(wakeup_seq),
+       .flags  = TRITON_WAKEUP12_SCRIPT | TRITON_WAKEUP3_SCRIPT,
+};
+
+static struct twl4030_ins wrst_seq[] __initdata = {
+/*
+ * Reset twl4030.
+ * Reset VDD1 regulator.
+ * Reset VDD2 regulator.
+ * Reset VPLL1 regulator.
+ * Enable sysclk output.
+ * Reenable twl4030.
+ */
+       {MSG_SINGULAR(DEV_GRP_NULL, 0x1b, RES_STATE_OFF), 2},
+       {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_WRST), 15},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_WRST), 15},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_WRST), 0x60},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x19, RES_STATE_ACTIVE), 2},
+       {MSG_SINGULAR(DEV_GRP_NULL, 0x1b, RES_STATE_ACTIVE), 2},
+};
+static struct twl4030_script wrst_script __initdata = {
+       .script = wrst_seq,
+       .size   = ARRAY_SIZE(wakeup_seq),
+       .flags  = TRITON_WRST_SCRIPT,
+};
+
+static struct twl4030_script *twl4030_scripts[] __initdata = {
+       &sleep_on_script,
+       &wakeup_script,
+       &wrst_script,
+};
+
+static struct twl4030_power_data sdp3430_t2scripts_data __initdata = {
+       .scripts        = twl4030_scripts,
+       .size           = ARRAY_SIZE(twl4030_scripts),
+};
+
 /*
  * Apply all the fixed voltages since most versions of U-Boot
  * don't bother with that initialization.
@@ -472,6 +629,7 @@ static struct twl4030_platform_data sdp3430_twldata = {
        .gpio           = &sdp3430_gpio_data,
        .madc           = &sdp3430_madc_data,
        .keypad         = &sdp3430_kp_data,
+       .power          = &sdp3430_t2scripts_data,
        .usb            = &sdp3430_usb_data,
 
        .vaux1          = &sdp3430_vaux1,
@@ -520,8 +678,11 @@ static void __init omap_3430sdp_init(void)
        spi_register_board_info(sdp3430_spi_board_info,
                                ARRAY_SIZE(sdp3430_spi_board_info));
        ads7846_dev_init();
+       sdp3430_flash_init();
+       msecure_init();
        omap_serial_init();
        usb_musb_init();
+       usb_ehci_init();
 }
 
 static void __init omap_3430sdp_map_io(void)
diff --git a/arch/arm/mach-omap2/board-apollon-keys.c b/arch/arm/mach-omap2/board-apollon-keys.c
new file mode 100644 (file)
index 0000000..10329c0
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * linux/arch/arm/mach-omap2/board-apollon-keys.c
+ *
+ * Copyright (C) 2007 Samsung Electronics
+ * Author: Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <mach/gpio.h>
+#include <mach/mux.h>
+
+#define SW_ENTER_GPIO16                16
+#define SW_UP_GPIO17           17
+#define SW_DOWN_GPIO58         58
+#define SW_LEFT_GPIO95         95
+#define SW_RIGHT_GPIO96                96
+#define SW_ESC_GPIO97          97
+
+extern int apollon_plus(void);
+
+static struct gpio_keys_button apollon_gpio_keys_buttons[] = {
+       [0] = {
+               .code           = KEY_ENTER,
+               .gpio           = SW_ENTER_GPIO16,
+               .desc           = "enter sw",
+       },
+       [1] = {
+               .code           = KEY_UP,
+               .gpio           = SW_UP_GPIO17,
+               .desc           = "up sw",
+       },
+       [2] = {
+               .code           = KEY_DOWN,
+               .gpio           = SW_DOWN_GPIO58,
+               .desc           = "down sw",
+       },
+       [3] = {
+               .code           = KEY_LEFT,
+               .gpio           = SW_LEFT_GPIO95,
+               .desc           = "left sw",
+       },
+       [4] = {
+               .code           = KEY_RIGHT,
+               .gpio           = SW_RIGHT_GPIO96,
+               .desc           = "right sw",
+       },
+       [5] = {
+               .code           = KEY_ESC,
+               .gpio           = SW_ESC_GPIO97,
+               .desc           = "esc sw",
+       },
+};
+
+static struct gpio_keys_platform_data apollon_gpio_keys = {
+       .buttons                = apollon_gpio_keys_buttons,
+       .nbuttons               = ARRAY_SIZE(apollon_gpio_keys_buttons),
+};
+
+static struct platform_device apollon_gpio_keys_device = {
+       .name                   = "gpio-keys",
+       .id                     = -1,
+       .dev                    = {
+               .platform_data  = &apollon_gpio_keys,
+       },
+};
+
+static void __init apollon_sw_init(void)
+{
+       /* Enter SW - Y11 */
+       omap_cfg_reg(Y11_242X_GPIO16);
+       /* Up SW - AA12 */
+       omap_cfg_reg(AA12_242X_GPIO17);
+       /* Down SW - AA8 */
+       omap_cfg_reg(AA8_242X_GPIO58);
+
+       if (apollon_plus()) {
+               /* Left SW - P18 */
+               omap_cfg_reg(P18_24XX_GPIO95);
+               /* Right SW - M18 */
+               omap_cfg_reg(M18_24XX_GPIO96);
+               /* Esc SW - L14 */
+               omap_cfg_reg(L14_24XX_GPIO97);
+       } else
+               apollon_gpio_keys.nbuttons = 3;
+}
+
+static int __init omap_apollon_keys_init(void)
+{
+       apollon_sw_init();
+
+       return platform_device_register(&apollon_gpio_keys_device);
+}
+
+arch_initcall(omap_apollon_keys_init);
diff --git a/arch/arm/mach-omap2/board-apollon-mmc.c b/arch/arm/mach-omap2/board-apollon-mmc.c
new file mode 100644 (file)
index 0000000..3197741
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * linux/arch/arm/mach-omap2/board-apollon-mmc.c
+ *
+ * Copyright (C) 2005-2007 Samsung Electronics
+ * Author: Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/gpio.h>
+#include <mach/mmc.h>
+
+#ifdef CONFIG_MMC_OMAP
+
+static struct device *mmc_device;
+
+static int apollon_mmc_set_power(struct device *dev, int slot, int power_on,
+                                       int vdd)
+{
+#ifdef CONFIG_MMC_DEBUG
+       dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
+               power_on ? "on" : "off", vdd);
+#endif
+       if (slot != 0) {
+               dev_err(dev, "No such slot %d\n", slot + 1);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int apollon_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
+{
+#ifdef CONFIG_MMC_DEBUG
+       dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1,
+               bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
+#endif
+       if (slot != 0) {
+               dev_err(dev, "No such slot %d\n", slot + 1);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int apollon_mmc_late_init(struct device *dev)
+{
+       mmc_device = dev;
+
+       return 0;
+}
+
+static void apollon_mmc_cleanup(struct device *dev)
+{
+}
+
+/*
+ * Note: If you want to detect card feature, please assign GPIO 37
+ */
+static struct omap_mmc_platform_data mmc1_data = {
+       .nr_slots                       = 1,
+       .init                           = apollon_mmc_late_init,
+       .cleanup                        = apollon_mmc_cleanup,
+       .dma_mask                       = 0xffffffff,
+       .slots[0]       = {
+               .wires                  = 4,
+
+               /*
+                * Use internal loop-back in MMC/SDIO Module Input Clock
+                * selection
+                */
+               .internal_clock         = 1,
+
+               .set_power              = apollon_mmc_set_power,
+               .set_bus_mode           = apollon_mmc_set_bus_mode,
+               .ocr_mask               = MMC_VDD_30_31 | MMC_VDD_31_32 |
+                                         MMC_VDD_32_33 | MMC_VDD_33_34,
+               .name                   = "mmcblk",
+       },
+};
+
+static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC];
+
+void __init apollon_mmc_init(void)
+{
+       mmc_data[0] = &mmc1_data;
+       omap2_init_mmc(mmc_data, OMAP24XX_NR_MMC);
+}
+
+#else  /* !CONFIG_MMC_OMAP */
+
+void __init apollon_mmc_init(void)
+{
+}
+
+#endif /* CONFIG_MMC_OMAP */
index 06dfba888b0ca408b9691e1623774f366e1569d3..936cb49bdd0c0156b78476a8977c4824284761e8 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * linux/arch/arm/mach-omap2/board-apollon.c
  *
- * Copyright (C) 2005,2006 Samsung Electronics
+ * Copyright (C) 2005-2008 Samsung Electronics
  * Author: Kyungmin Park <kyungmin.park@samsung.com>
  *
- * Modified from mach-omap/omap2/board-h4.c
+ * Modified from mach-omap2/board-h4.c
  *
  * Code for apollon OMAP2 board. Should work on many OMAP2 systems where
  * the bootloader passes the board-specific data to the kernel.
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/onenand.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/leds.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/tsc210x.h>
 
+#include <asm/io.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <mach/board.h>
 #include <mach/common.h>
 #include <mach/gpmc.h>
-#include <mach/control.h>
 
 /* LED & Switch macros */
 #define LED0_GPIO13            13
 #define LED1_GPIO14            14
 #define LED2_GPIO15            15
-#define SW_ENTER_GPIO16                16
-#define SW_UP_GPIO17           17
-#define SW_DOWN_GPIO58         58
+#define LED3_GPIO92            92
+#define LED4_GPIO93            93
 
 #define APOLLON_FLASH_CS       0
 #define APOLLON_ETH_CS         1
+#define APOLLON_NOR_CS         3
 #define APOLLON_ETHR_GPIO_IRQ  74
 
+#define APOLLON_ONENAND_CS2_ADDRESS    (0x00000e40 | (0x10000000 >> 24))
+#define APOLLON_EXT_CS3_ADDRESS                (0x00000c40 | (0x18000000 >> 24))
+
+extern apollon_mmc_init(void);
+
+int apollon_plus(void)
+{
+       /* The apollon plus has IDCODE revision 5 */
+       return omap_rev() & 0xc0;
+}
+
 static struct mtd_partition apollon_partitions[] = {
        {
                .name           = "X-Loader + U-Boot",
@@ -108,6 +123,63 @@ static struct platform_device apollon_onenand_device = {
        .resource       = apollon_flash_resource,
 };
 
+static struct mtd_partition apollon_nor_partitions[] = {
+       {
+               .name           = "U-Boot",
+               .offset         = 0,
+               .size           = SZ_128K,
+               .mask_flags     = MTD_WRITEABLE,
+       },
+       {
+               .name           = "params",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = SZ_128K,
+       },
+       {
+               .name           = "kernel",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = SZ_2M,
+       },
+       {
+               .name           = "rootfs",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = SZ_4M - SZ_256K,
+       },
+       {
+               .name           = "application",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = SZ_8M + SZ_2M,
+       },
+       {
+               .name           = "reserved",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct flash_platform_data apollon_nor_data = {
+       .map_name               = "cfi_probe",
+       .width          = 2,
+       .parts          = apollon_nor_partitions,
+       .nr_parts       = ARRAY_SIZE(apollon_nor_partitions),
+};
+
+static struct resource apollon_nor_resource[] = {
+       [0] = {
+               .flags  = IORESOURCE_MEM,
+       }
+};
+
+static struct platform_device apollon_nor_device = {
+       .name           = "omapflash",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &apollon_nor_data,
+       },
+       .num_resources  = ARRAY_SIZE(apollon_nor_resource),
+       .resource       = apollon_nor_resource,
+};
+
 static void __init apollon_flash_init(void)
 {
        unsigned long base;
@@ -118,6 +190,13 @@ static void __init apollon_flash_init(void)
        }
        apollon_flash_resource[0].start = base;
        apollon_flash_resource[0].end   = base + SZ_128K - 1;
+
+       if (gpmc_cs_request(APOLLON_NOR_CS, SZ_32M, &base) < 0) {
+               printk(KERN_ERR "Cannot request NOR GPMC CS\n");
+               return;
+       }
+       apollon_nor_resource[0].start = base;
+       apollon_nor_resource[0].end   = base + SZ_32M - 1;
 }
 
 static struct resource apollon_smc91x_resources[] = {
@@ -143,34 +222,37 @@ static struct platform_device apollon_lcd_device = {
        .id             = -1,
 };
 
-static struct omap_led_config apollon_led_config[] = {
+static struct gpio_led apollon_led_config[] = {
        {
-               .cdev   = {
-                       .name   = "apollon:led0",
-               },
-               .gpio   = LED0_GPIO13,
+               .name                   = "d2",
+               .gpio                   = LED0_GPIO13,
+               .default_trigger        = "heartbeat",
        },
        {
-               .cdev   = {
-                       .name   = "apollon:led1",
-               },
-               .gpio   = LED1_GPIO14,
+               .name                   = "d3",
+               .gpio                   = LED1_GPIO14,
        },
        {
-               .cdev   = {
-                       .name   = "apollon:led2",
-               },
-               .gpio   = LED2_GPIO15,
+               .name                   = "d4",
+               .gpio                   = LED2_GPIO15,
+       },
+       {
+               .name                   = "d5",
+               .gpio                   = LED3_GPIO92,
+       },
+       {
+               .name                   = "d6",
+               .gpio                   = LED4_GPIO93,
        },
 };
 
-static struct omap_led_platform_data apollon_led_data = {
-       .nr_leds        = ARRAY_SIZE(apollon_led_config),
+static struct gpio_led_platform_data apollon_led_data = {
+       .num_leds       = ARRAY_SIZE(apollon_led_config),
        .leds           = apollon_led_config,
 };
 
 static struct platform_device apollon_led_device = {
-       .name           = "omap-led",
+       .name           = "leds-gpio",
        .id             = -1,
        .dev            = {
                .platform_data  = &apollon_led_data,
@@ -179,6 +261,7 @@ static struct platform_device apollon_led_device = {
 
 static struct platform_device *apollon_devices[] __initdata = {
        &apollon_onenand_device,
+       &apollon_nor_device,
        &apollon_smc91x_device,
        &apollon_lcd_device,
        &apollon_led_device,
@@ -187,7 +270,6 @@ static struct platform_device *apollon_devices[] __initdata = {
 static inline void __init apollon_init_smc91x(void)
 {
        unsigned long base;
-
        unsigned int rate;
        struct clk *gpmc_fck;
        int eth_cs;
@@ -226,7 +308,7 @@ static inline void __init apollon_init_smc91x(void)
                gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
        }
 
-       if (gpmc_cs_request(APOLLON_ETH_CS, SZ_16M, &base) < 0) {
+       if (gpmc_cs_request(eth_cs, SZ_16M, &base) < 0) {
                printk(KERN_ERR "Failed to request GPMC CS for smc91x\n");
                goto out;
        }
@@ -238,7 +320,7 @@ static inline void __init apollon_init_smc91x(void)
        if (gpio_request(APOLLON_ETHR_GPIO_IRQ, "SMC91x irq") < 0) {
                printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
                        APOLLON_ETHR_GPIO_IRQ);
-               gpmc_cs_free(APOLLON_ETH_CS);
+               gpmc_cs_free(eth_cs);
                goto out;
        }
        gpio_direction_input(APOLLON_ETHR_GPIO_IRQ);
@@ -256,6 +338,24 @@ static void __init omap_apollon_init_irq(void)
        apollon_init_smc91x();
 }
 
+static struct tsc210x_config tsc_platform_data = {
+       .use_internal           = 1,
+       .monitor                = TSC_TEMP,
+       .mclk                   = "sys_clkout",
+};
+
+static struct spi_board_info apollon_spi_board_info[] = {
+       [0] = {
+               .modalias       = "tsc2101",
+               .irq            = OMAP_GPIO_IRQ(85),
+               .bus_num        = 1,
+               .chip_select    = 0,
+               .mode           = SPI_MODE_1,
+               .max_speed_hz   = 6000000,
+               .platform_data  = &tsc_platform_data,
+       },
+};
+
 static struct omap_uart_config apollon_uart_config __initdata = {
        .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2),
 };
@@ -271,7 +371,7 @@ static struct omap_lcd_config apollon_lcd_config __initdata = {
        .ctrl_name      = "internal",
 };
 
-static struct omap_board_config_kernel apollon_config[] = {
+static struct omap_board_config_kernel apollon_config[] __initdata = {
        { OMAP_TAG_UART,        &apollon_uart_config },
        { OMAP_TAG_LCD,         &apollon_lcd_config },
 };
@@ -280,16 +380,18 @@ static void __init apollon_led_init(void)
 {
        /* LED0 - AA10 */
        omap_cfg_reg(AA10_242X_GPIO13);
-       gpio_request(LED0_GPIO13, "LED0");
-       gpio_direction_output(LED0_GPIO13, 0);
        /* LED1  - AA6 */
        omap_cfg_reg(AA6_242X_GPIO14);
-       gpio_request(LED1_GPIO14, "LED1");
-       gpio_direction_output(LED1_GPIO14, 0);
        /* LED2  - AA4 */
        omap_cfg_reg(AA4_242X_GPIO15);
-       gpio_request(LED2_GPIO15, "LED2");
-       gpio_direction_output(LED2_GPIO15, 0);
+
+       if (apollon_plus()) {
+               /* LED3 - M15 */
+               omap_cfg_reg(M15_24XX_GPIO92);
+               /* LED4 - P20 */
+               omap_cfg_reg(P20_24XX_GPIO93);
+       } else
+               apollon_led_data.num_leds = 3;
 }
 
 static void __init apollon_usb_init(void)
@@ -302,21 +404,101 @@ static void __init apollon_usb_init(void)
        omap_usb_init(&apollon_usb_config);
 }
 
-static void __init omap_apollon_init(void)
+static void __init apollon_tsc_init(void)
+{
+       /* TSC2101 */
+       omap_cfg_reg(N15_24XX_GPIO85);
+       gpio_request(85, "tsc2101 irq");
+       gpio_direction_input(85);
+
+       omap_cfg_reg(W14_24XX_SYS_CLKOUT);      /* mclk */
+}
+
+static void __init apollon_cs_init(void)
 {
-       u32 v;
+       unsigned long base;
+       unsigned int rate;
+       struct clk *l3ck;
+       u32 value;
+       int cs, sync = 0;
+
+       l3ck = clk_get(NULL, "core_l3_ck");
+       if (IS_ERR(l3ck))
+               rate = 100000000;
+       else
+               rate = clk_get_rate(l3ck);
+
+       /* CS2: OneNAND */
+       cs = 2;
+       value = gpmc_cs_read_reg(0, GPMC_CS_CONFIG1);
+       gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, value);
+       value = gpmc_cs_read_reg(0, GPMC_CS_CONFIG2);
+       gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, value);
+       value = gpmc_cs_read_reg(0, GPMC_CS_CONFIG3);
+       gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, value);
+       value = gpmc_cs_read_reg(0, GPMC_CS_CONFIG4);
+       gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, value);
+       value = gpmc_cs_read_reg(0, GPMC_CS_CONFIG5);
+       gpmc_cs_write_reg(cs, GPMC_CS_CONFIG5, value);
+       value = gpmc_cs_read_reg(0, GPMC_CS_CONFIG6);
+       gpmc_cs_write_reg(cs, GPMC_CS_CONFIG6, value);
+
+       gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, APOLLON_ONENAND_CS2_ADDRESS);
+
+       /* CS3: External NOR */
+       cs = APOLLON_NOR_CS;
+       if (rate >= 160000000) {
+               sync = 1;
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, 0xe5011211);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, 0x00090b01);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, 0x00020201);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, 0x09030b03);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG5, 0x010a0a0c);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG6, 0x00000000);
+       } else if (rate >= 130000000) {
+               /* Not yet know ... Use the async values */
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, 0x00021201);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, 0x00121601);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, 0x00040401);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, 0x12061605);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG5, 0x01151317);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG6, 0x00000000);
+       } else {/* rate = 100000000 */
+               sync = 1;
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, 0xe1001202);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, 0x00151501);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, 0x00050501);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, 0x0e070e07);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG5, 0x01131F1F);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG6, 0x00000000);
+       }
+
+       gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, APOLLON_EXT_CS3_ADDRESS);
+
+       if (gpmc_cs_request(cs, SZ_32M, &base) < 0) {
+               printk(KERN_ERR "Failed to request GPMC CS for external\n");
+               return;
+       }
 
+       /* Synchronous mode */
+       if (sync) {
+               void __iomem *addr = ioremap(base, SZ_32M);
+               writew(0xaa, addr + 0xaaa);
+               writew(0x55, addr + 0x554);
+               writew(0xc0, addr + 0x24aaa);
+               iounmap(addr);
+       }
+
+       gpmc_cs_free(cs);
+}
+
+static void __init omap_apollon_init(void)
+{
+       apollon_cs_init();
        apollon_led_init();
        apollon_flash_init();
        apollon_usb_init();
-
-       /* REVISIT: where's the correct place */
-       omap_cfg_reg(W19_24XX_SYS_NIRQ);
-
-       /* Use Interal loop-back in MMC/SDIO Module Input Clock selection */
-       v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
-       v |= (1 << 24);
-       omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
+       apollon_tsc_init();
 
        /*
         * Make sure the serial ports are muxed on at this point.
@@ -327,6 +509,13 @@ static void __init omap_apollon_init(void)
        omap_board_config = apollon_config;
        omap_board_config_size = ARRAY_SIZE(apollon_config);
        omap_serial_init();
+       omap_register_i2c_bus(1, 100, NULL, 0);
+       omap_register_i2c_bus(2, 100, NULL, 0);
+
+       spi_register_board_info(apollon_spi_board_info,
+                               ARRAY_SIZE(apollon_spi_board_info));
+
+       apollon_mmc_init();
 }
 
 static void __init omap_apollon_map_io(void)
index 3492162a65c383907bb093702b0c9921ff1b8ac2..0e353b3611f373503dbb6674e1ce15d85d606125 100644 (file)
@@ -41,7 +41,7 @@ static struct omap_uart_config generic_uart_config __initdata = {
        .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
 };
 
-static struct omap_board_config_kernel generic_config[] = {
+static struct omap_board_config_kernel generic_config[] __initdata = {
        { OMAP_TAG_UART,        &generic_uart_config },
 };
 
@@ -50,6 +50,8 @@ static void __init omap_generic_init(void)
        omap_board_config = generic_config;
        omap_board_config_size = ARRAY_SIZE(generic_config);
        omap_serial_init();
+       omap_register_i2c_bus(1, 100, NULL, 0);
+       omap_register_i2c_bus(2, 100, NULL, 0);
 }
 
 static void __init omap_generic_map_io(void)
index a0267a9ab466e9638b9bd74c1e045d2e1321c5de..cbca22a0199a27de88333a054db3c4cc54e2d67f 100644 (file)
 #include <linux/mtd/partitions.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
 #include <linux/input.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+
+#include <linux/i2c/at24.h>
+#include <linux/i2c/menelaus.h>
+#include <linux/i2c/pcf857x.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/tsc210x.h>
+
+#include <media/v4l2-int-device.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/flash.h>
 
 #include <mach/control.h>
-#include <mach/gpio.h>
-#include <mach/gpioexpander.h>
 #include <mach/mux.h>
 #include <mach/usb.h>
 #include <mach/irda.h>
 #include <mach/board.h>
 #include <mach/common.h>
 #include <mach/keypad.h>
-#include <mach/menelaus.h>
 #include <mach/dma.h>
 #include <mach/gpmc.h>
 
 
 #define H4_ETHR_GPIO_IRQ               92
 
+/* FPGA on debug board has 32 GPIOs:  16 dedicated to leds,
+ * 8 outputs on a header, and 6 inputs from a DIP switch.
+ */
+#define H4_DEBUG_GPIO_BASE             OMAP_MAX_GPIO_LINES
+#      define H4_DEBUG_GPIO_SW3_1      (H4_DEBUG_GPIO_BASE + 24)
+#      define H4_DEBUG_GPIO_SW3_2      (H4_DEBUG_GPIO_BASE + 25)
+#      define H4_DEBUG_GPIO_SW3_3      (H4_DEBUG_GPIO_BASE + 26)
+#      define H4_DEBUG_GPIO_SW3_4      (H4_DEBUG_GPIO_BASE + 27)
+#      define H4_DEBUG_GPIO_SW3_5      (H4_DEBUG_GPIO_BASE + 28)
+#      define H4_DEBUG_GPIO_SW3_8      (H4_DEBUG_GPIO_BASE + 29)
+
+/* H4 baseboard has 3 PCF8574 (8 bit) I2C GPIO expanders */
+#define H4_U191_GPIO_BASE              (H4_DEBUG_GPIO_BASE + 32)
+#      define H4_GPIO_IRDA_FIRSEL      (H4_U191_GPIO_BASE + 0)
+#      define H4_GPIO_MODEM_MOD_EN     (H4_U191_GPIO_BASE + 1)
+#      define H4_GPIO_WLAN_MOD_EN      (H4_U191_GPIO_BASE + 2)
+#      define H4_GPIO_CAM_MODULE_EN    (H4_U191_GPIO_BASE + 3)
+#      define H4_GPIO_HANDSET_EN       (H4_U191_GPIO_BASE + 4)
+#      define H4_GPIO_LCD_ENBKL        (H4_U191_GPIO_BASE + 5)
+#      define H4_GPIO_AUDIO_ENVDD      (H4_U191_GPIO_BASE + 6)
+#      define H4_GPIO_LCD_ENVDD        (H4_U191_GPIO_BASE + 7)
+
+#define H4_U192_GPIO_BASE              (H4_U191_GPIO_BASE + 8)
+#      define H4_GPIO_IRDA_AGPSn       (H4_U192_GPIO_BASE + 0)
+#      define H4_GPIO_AGPS_PWREN       (H4_U192_GPIO_BASE + 1)
+#      define H4_GPIO_AGPS_RSTn        (H4_U192_GPIO_BASE + 2)
+#      define H4_GPIO_AGPS_SLEEP       (H4_U192_GPIO_BASE + 3)
+#      define H4_GPIO_AGPS_PA_XMT      (H4_U192_GPIO_BASE + 4)
+#      define H4_GPIO_MODEM_SPR2       (H4_U192_GPIO_BASE + 5)
+#      define H4_GPIO_MODEM_SPR1       (H4_U192_GPIO_BASE + 6)
+#      define H4_GPIO_BT_ACLK_ENn      (H4_U192_GPIO_BASE + 7)
+
+#define H4_U193_GPIO_BASE              (H4_U192_GPIO_BASE + 8)
+#      define H4_GPIO_SPR0             (H4_U193_GPIO_BASE + 0)
+#      define H4_GPIO_SPR1             (H4_U193_GPIO_BASE + 1)
+#      define H4_GPIO_WLAN_SHUTDOWN    (H4_U193_GPIO_BASE + 2)
+#      define H4_GPIO_WLAN_RESET       (H4_U193_GPIO_BASE + 3)
+#      define H4_GPIO_WLAN_CLK_ENn     (H4_U193_GPIO_BASE + 4)
+       /* 5, 6 not connected */
+#      define H4_GPIO_CAM_RST          (H4_U193_GPIO_BASE + 7)
+
 static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 };
 static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 };
 
@@ -138,31 +186,16 @@ static struct platform_device h4_flash_device = {
        .resource       = &h4_flash_resource,
 };
 
-/* Select between the IrDA and aGPS module
- */
+#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
+
+/* Select between the IrDA and aGPS module */
 static int h4_select_irda(struct device *dev, int state)
 {
-       unsigned char expa;
-       int err = 0;
-
-       if ((err = read_gpio_expa(&expa, 0x21))) {
-               printk(KERN_ERR "Error reading from I/O expander\n");
-               return err;
-       }
+       /* U192.P0 = high for IRDA; else AGPS */
+       gpio_set_value_cansleep(H4_GPIO_IRDA_AGPSn, state & IR_SEL);
 
-       /* 'P6' enable/disable IRDA_TX and IRDA_RX */
-       if (state & IR_SEL) {   /* IrDa */
-               if ((err = write_gpio_expa(expa | 0x01, 0x21))) {
-                       printk(KERN_ERR "Error writing to I/O expander\n");
-                       return err;
-               }
-       } else {
-               if ((err = write_gpio_expa(expa & ~0x01, 0x21))) {
-                       printk(KERN_ERR "Error writing to I/O expander\n");
-                       return err;
-               }
-       }
-       return err;
+       /* NOTE:  UART3 can also hook up to a DB9 or to GSM ... */
+       return 0;
 }
 
 static void set_trans_mode(struct work_struct *work)
@@ -170,22 +203,9 @@ static void set_trans_mode(struct work_struct *work)
        struct omap_irda_config *irda_config =
                container_of(work, struct omap_irda_config, gpio_expa.work);
        int mode = irda_config->mode;
-       unsigned char expa;
-       int err = 0;
-
-       if ((err = read_gpio_expa(&expa, 0x20)) != 0) {
-               printk(KERN_ERR "Error reading from I/O expander\n");
-       }
 
-       expa &= ~0x01;
-
-       if (!(mode & IR_SIRMODE)) { /* MIR/FIR */
-               expa |= 0x01;
-       }
-
-       if ((err = write_gpio_expa(expa, 0x20)) != 0) {
-               printk(KERN_ERR "Error writing to I/O expander\n");
-       }
+       /* U191.P0 = low for SIR; else MIR/FIR */
+       gpio_set_value_cansleep(H4_GPIO_IRDA_FIRSEL, !(mode & IR_SIRMODE));
 }
 
 static int h4_transceiver_mode(struct device *dev, int mode)
@@ -199,6 +219,10 @@ static int h4_transceiver_mode(struct device *dev, int mode)
 
        return 0;
 }
+#else
+static int h4_select_irda(struct device *dev, int state) { return 0; }
+static int h4_transceiver_mode(struct device *dev, int mode) { return 0; }
+#endif
 
 static struct omap_irda_config h4_irda_data = {
        .transceiver_cap        = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
@@ -269,6 +293,8 @@ static u32 get_sysboot_value(void)
                 OMAP2_SYSBOOT_1_MASK | OMAP2_SYSBOOT_0_MASK));
 }
 
+/* FIXME: This function should be moved to some other file, gpmc.c? */
+
 /* H4-2420's always used muxed mode, H4-2422's always use non-muxed
  *
  * Note: OMAP-GIT doesn't correctly do is_cpu_omap2422 and is_cpu_omap2423
@@ -372,7 +398,11 @@ static void __init omap_h4_init_irq(void)
 }
 
 static struct omap_uart_config h4_uart_config __initdata = {
+#ifdef CONFIG_MACH_OMAP2_H4_USB1
+       .enabled_uarts = ((1 << 0) | (1 << 1)),
+#else
        .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+#endif
 };
 
 static struct omap_lcd_config h4_lcd_config __initdata = {
@@ -412,21 +442,309 @@ static struct omap_usb_config h4_usb_config __initdata = {
 #endif
 };
 
-static struct omap_board_config_kernel h4_config[] = {
+/* ----------------------------------------------------------------------- */
+
+static struct tsc210x_config tsc_platform_data = {
+       .use_internal           = 1,
+       .monitor                = TSC_VBAT | TSC_TEMP,
+       /* REVISIT temp calibration data -- board-specific; from EEPROM? */
+       .mclk                   = "sys_clkout",
+};
+
+static struct spi_board_info h4_spi_board_info[] __initdata = {
+       {
+               .modalias       = "tsc2101",
+               .bus_num        = 1,
+               .chip_select    = 0,
+               .mode           = SPI_MODE_1,
+               .irq            = OMAP_GPIO_IRQ(93),
+               .max_speed_hz   = 16000000,
+               .platform_data  = &tsc_platform_data,
+       },
+
+       /* nCS1 -- to lcd board, but unused
+        * nCS2 -- to WLAN/miniPCI
+        */
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct omap_board_config_kernel h4_config[] __initdata = {
        { OMAP_TAG_UART,        &h4_uart_config },
        { OMAP_TAG_LCD,         &h4_lcd_config },
 };
 
+#ifdef CONFIG_MACH_OMAP_H4_TUSB
+
+#include <linux/usb/musb.h>
+
+static struct musb_hdrc_platform_data tusb_data = {
+       .mode           = MUSB_OTG,
+       .min_power      = 25,   /* x2 = 50 mA drawn from VBUS as peripheral */
+
+       /* 1.8V supplied by Menelaus, other voltages supplied by VBAT;
+        * so no switching.
+        */
+};
+
+static void __init tusb_evm_setup(void)
+{
+       static char     announce[] __initdata =
+                               KERN_INFO "TUSB 6010 EVM\n";
+       int             irq;
+       unsigned        dmachan = 0;
+
+       /* There are at least 32 different combinations of boards that
+        * are loosely called "H4", with a 2420 ... different OMAP chip
+        * revisions (with pin mux changes for DMAREQ, GPMC errata, etc),
+        * modifications of the CPU board, mainboard, EVM, TUSB etc.
+        * Plus omap2422, omap2423, etc.
+        *
+        * So you might need to tweak this setup to make the TUSB EVM
+        * behave on your particular setup ...
+        */
+
+       /* Already set up:  GPMC AD[0..15], CLK, nOE, nWE, nADV_ALE */
+       omap_cfg_reg(E2_GPMC_NCS2);
+       omap_cfg_reg(L2_GPMC_NCS7);
+       omap_cfg_reg(M1_GPMC_WAIT2);
+
+       switch ((omap_rev() >> 8) & 0x0f) {
+       case 0:         /* ES 1.0 */
+       case 1:         /* ES 2.0 */
+               /* Assume early board revision without optional ES2.0
+                * rework to swap J15 & AA10 so DMAREQ0 works
+                */
+               omap_cfg_reg(AA10_242X_GPIO13);
+               irq = 13;
+               /* omap_cfg_reg(J15_24XX_DMAREQ0); */
+               break;
+       default:
+               /* Later Menelaus boards can support all 6 DMA request
+                * lines, at the price of boot flash A23-A26.
+                */
+               omap_cfg_reg(J15_24XX_GPIO99);
+               irq = 99;
+               dmachan = (1 << 1) | (1 << 0);
+#if !(defined(CONFIG_MTD_OMAP_NOR) || defined(CONFIG_MTD_OMAP_NOR_MODULE))
+               dmachan |= (1 << 5) | (1 << 4) (1 << 3) | (1 << 2);
+#endif
+               break;
+       }
+
+       if (tusb6010_setup_interface(&tusb_data,
+                       TUSB6010_REFCLK_24, /* waitpin */ 2,
+                       /* async cs */ 2, /* sync cs */ 7,
+                       irq, dmachan) == 0)
+               printk(announce);
+}
+
+#endif
+
+#if defined(CONFIG_VIDEO_OV9640) || defined(CONFIG_VIDEO_OV9640_MODULE)
+/*
+ * Common OV9640 register initialization for all image sizes, pixel formats,
+ * and frame rates
+ */
+const static struct ov9640_reg ov9640_common[] = {
+       { 0x12, 0x80 }, { 0x11, 0x80 }, { 0x13, 0x8F }, /* COM7, CLKRC, COM8 */
+       { 0x01, 0x80 }, { 0x02, 0x80 }, { 0x04, 0x00 }, /* BLUE, RED, COM1 */
+       { 0x0E, 0x81 }, { 0x0F, 0x4F }, { 0x14, 0x4A }, /* COM5, COM6, COM9 */
+       { 0x16, 0x02 }, { 0x1B, 0x01 }, { 0x24, 0x70 }, /* ?, PSHFT, AEW */
+       { 0x25, 0x68 }, { 0x26, 0xD3 }, { 0x27, 0x90 }, /* AEB, VPT, BBIAS */
+       { 0x2A, 0x00 }, { 0x2B, 0x00 }, { 0x32, 0x24 }, /* EXHCH, EXHCL, HREF */
+       { 0x33, 0x02 }, { 0x37, 0x02 }, { 0x38, 0x13 }, /* CHLF, ADC, ACOM */
+       { 0x39, 0xF0 }, { 0x3A, 0x00 }, { 0x3B, 0x01 }, /* OFON, TSLB, COM11 */
+       { 0x3D, 0x90 }, { 0x3E, 0x02 }, { 0x3F, 0xF2 }, /* COM13, COM14, EDGE */
+       { 0x41, 0x02 }, { 0x42, 0xC8 },         /* COM16, COM17 */
+       { 0x43, 0xF0 }, { 0x44, 0x10 }, { 0x45, 0x6C }, /* ?, ?, ? */
+       { 0x46, 0x6C }, { 0x47, 0x44 }, { 0x48, 0x44 }, /* ?, ?, ? */
+       { 0x49, 0x03 }, { 0x59, 0x49 }, { 0x5A, 0x94 }, /* ?, ?, ? */
+       { 0x5B, 0x46 }, { 0x5C, 0x84 }, { 0x5D, 0x5C }, /* ?, ?, ? */
+       { 0x5E, 0x08 }, { 0x5F, 0x00 }, { 0x60, 0x14 }, /* ?, ?, ? */
+       { 0x61, 0xCE },                                 /* ? */
+       { 0x62, 0x70 }, { 0x63, 0x00 }, { 0x64, 0x04 }, /* LCC1, LCC2, LCC3 */
+       { 0x65, 0x00 }, { 0x66, 0x00 },                 /* LCC4, LCC5 */
+       { 0x69, 0x00 }, { 0x6A, 0x3E }, { 0x6B, 0x3F }, /* HV, MBD, DBLV */
+       { 0x6C, 0x40 }, { 0x6D, 0x30 }, { 0x6E, 0x4B }, /* GSP1, GSP2, GSP3 */
+       { 0x6F, 0x60 }, { 0x70, 0x70 }, { 0x71, 0x70 }, /* GSP4, GSP5, GSP6 */
+       { 0x72, 0x70 }, { 0x73, 0x70 }, { 0x74, 0x60 }, /* GSP7, GSP8, GSP9 */
+       { 0x75, 0x60 }, { 0x76, 0x50 }, { 0x77, 0x48 }, /* GSP10,GSP11,GSP12 */
+       { 0x78, 0x3A }, { 0x79, 0x2E }, { 0x7A, 0x28 }, /* GSP13,GSP14,GSP15 */
+       { 0x7B, 0x22 }, { 0x7C, 0x04 }, { 0x7D, 0x07 }, /* GSP16,GST1, GST2 */
+       { 0x7E, 0x10 }, { 0x7F, 0x28 }, { 0x80, 0x36 }, /* GST3, GST4, GST5 */
+       { 0x81, 0x44 }, { 0x82, 0x52 }, { 0x83, 0x60 }, /* GST6, GST7, GST8 */
+       { 0x84, 0x6C }, { 0x85, 0x78 }, { 0x86, 0x8C }, /* GST9, GST10,GST11 */
+       { 0x87, 0x9E }, { 0x88, 0xBB }, { 0x89, 0xD2 }, /* GST12,GST13,GST14 */
+       { 0x8A, 0xE6 }, { 0x13, 0x8F }, { 0x00, 0x7F }, /* GST15, COM8 */
+       { OV9640_REG_TERM, OV9640_VAL_TERM }
+};
+
+static int ov9640_sensor_power_set(int power)
+{
+       /* power up the sensor? */
+       gpio_set_value_cansleep(H4_GPIO_CAM_MODULE_EN, power);
+
+       /* take it out of reset if it's not powered */
+       gpio_direction_output(H4_GPIO_CAM_RST, !power);
+
+       return 0;
+}
+
+static struct v4l2_ifparm ifparm = {
+       .if_type = V4L2_IF_TYPE_BT656,
+       .u = {
+               .bt656 = {
+                        .frame_start_on_rising_vs = 1,
+                        .nobt_vs_inv = 1,
+                        .mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT,
+                        .clock_min = OV9640_XCLK_MIN,
+                        .clock_max = OV9640_XCLK_MAX,
+                },
+       },
+};
+
+static int ov9640_ifparm(struct v4l2_ifparm *p)
+{
+       *p = ifparm;
+
+       return 0;
+}
+
+static struct ov9640_platform_data h4_ov9640_platform_data = {
+       .power_set      = ov9640_sensor_power_set,
+       .default_regs   = ov9640_common,
+       .ifparm         = ov9640_ifparm,
+};
+
+#endif
+
+/* leave LCD powered off unless it will be used */
+#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
+#define LCD_ENABLED            true
+#else
+#define LCD_ENABLED            false
+#endif
+
+static struct gpio_led backlight_leds[] = {
+       {
+               .name                   = "lcd_h4",
+               .default_trigger        = "backlight",
+               .gpio                   = H4_GPIO_LCD_ENBKL,
+       },
+       { },
+};
+
+static struct gpio_led_platform_data backlight_led_data = {
+       .num_leds               = 1,
+       .leds                   = backlight_leds,
+};
+
+static struct platform_device h4_backlight_device = {
+       .name                   = "leds-gpio",
+       .id                     = 0,
+       .dev.platform_data      = &backlight_led_data,
+};
+
+static int
+u191_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *context)
+{
+       /* P0 = IRDA control, FIR/MIR vs SIR */
+       gpio_request(H4_GPIO_IRDA_FIRSEL, "irda_firsel");
+       gpio_direction_output(H4_GPIO_IRDA_FIRSEL, false);
+
+       /* P3 = camera sensor module PWDN */
+       gpio_request(H4_GPIO_CAM_MODULE_EN, "camera_en");
+       gpio_direction_output(H4_GPIO_CAM_MODULE_EN, false);
+
+       /* P7 = LCD_ENVDD ... controls power to LCD (including backlight)
+        * P5 = LCD_ENBKL ... switches backlight
+        */
+       gpio_request(H4_GPIO_LCD_ENVDD, "lcd_power");
+       gpio_direction_output(H4_GPIO_LCD_ENVDD, LCD_ENABLED);
+       if (LCD_ENABLED) {
+               h4_backlight_device.dev.parent = &client->dev;
+               platform_device_register(&h4_backlight_device);
+       }
+
+       /* P6 = AUDIO_ENVDD ... switch power to microphone */
+       gpio_request(H4_GPIO_AUDIO_ENVDD, "audio_power");
+       gpio_direction_output(H4_GPIO_AUDIO_ENVDD, true);
+
+       return 0;
+}
+
+
+static struct pcf857x_platform_data u191_platform_data = {
+       .gpio_base      = H4_U191_GPIO_BASE,
+       .setup          = u191_setup,
+};
+
+static int
+u192_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *context)
+{
+       gpio_request(H4_GPIO_IRDA_AGPSn, "irda/agps");
+       gpio_direction_output(H4_GPIO_IRDA_AGPSn, false);
+
+       return 0;
+}
+
+static struct pcf857x_platform_data u192_platform_data = {
+       .gpio_base      = H4_U192_GPIO_BASE,
+       .setup          = u192_setup,
+};
+
+static int
+u193_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *context)
+{
+       /* reset sensor */
+       gpio_request(H4_GPIO_CAM_RST, "camera_rst");
+       gpio_direction_output(H4_GPIO_CAM_RST, true);
+
+       return 0;
+}
+
+static struct pcf857x_platform_data u193_platform_data = {
+       .gpio_base      = H4_U193_GPIO_BASE,
+       .setup          = u193_setup,
+};
+
 static struct at24_platform_data m24c01 = {
        .byte_len       = SZ_1K / 8,
        .page_size      = 16,
 };
 
 static struct i2c_board_info __initdata h4_i2c_board_info[] = {
+       {       /* U191 gpios */
+               I2C_BOARD_INFO("pcf8574", 0x20),
+               .platform_data  = &u191_platform_data,
+       },
+       {       /* U192 gpios */
+               I2C_BOARD_INFO("pcf8574", 0x21),
+               .platform_data  = &u192_platform_data,
+       },
+       {       /* U193 gpios */
+               I2C_BOARD_INFO("pcf8574", 0x22),
+               .platform_data  = &u193_platform_data,
+       },
+       {
+               I2C_BOARD_INFO("rv5c387a", 0x32),
+               /* no IRQ wired to OMAP; nINTB goes to AGPS */
+       },
+       {
+               I2C_BOARD_INFO("menelaus", 0x72),
+               .irq = INT_24XX_SYS_NIRQ,
+       },
        {
                I2C_BOARD_INFO("isp1301_omap", 0x2d),
                .irq            = OMAP_GPIO_IRQ(125),
        },
+#if defined(CONFIG_VIDEO_OV9640) || defined(CONFIG_VIDEO_OV9640_MODULE)
+       {
+               I2C_BOARD_INFO("ov9640", 0x30),
+               .platform_data = &h4_ov9640_platform_data,
+       },
+#endif
        {       /* EEPROM on mainboard */
                I2C_BOARD_INFO("24c01", 0x52),
                .platform_data  = &m24c01,
@@ -457,14 +775,54 @@ static void __init omap_h4_init(void)
        }
 #endif
 
-       i2c_register_board_info(1, h4_i2c_board_info,
-                       ARRAY_SIZE(h4_i2c_board_info));
+#ifdef CONFIG_MACH_OMAP2_H4_USB1
+       /* S3.3 controls whether these pins are for UART2 or USB1 */
+       omap_cfg_reg(N14_24XX_USB1_SE0);
+       omap_cfg_reg(P15_24XX_USB1_DAT);
+       omap_cfg_reg(W20_24XX_USB1_TXEN);
+       omap_cfg_reg(V19_24XX_USB1_RCV);
+#endif
+
+       /* Menelaus interrupt */
+       omap_cfg_reg(W19_24XX_SYS_NIRQ);
 
        platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
        omap_board_config = h4_config;
        omap_board_config_size = ARRAY_SIZE(h4_config);
-       omap_usb_init(&h4_usb_config);
        omap_serial_init();
+       omap_usb_init(&h4_usb_config);
+       omap_register_i2c_bus(1, 100, h4_i2c_board_info,
+                             ARRAY_SIZE(h4_i2c_board_info));
+
+       /* smc91x, debug leds, ps/2, extra uarts */
+       h4_init_debug();
+
+#ifdef CONFIG_MACH_OMAP_H4_TUSB
+       tusb_evm_setup();
+#endif
+
+       /* defaults seem ok for:
+        * omap_cfg_reg(U18_24XX_SPI1_SCK);
+        * omap_cfg_reg(V20_24XX_SPI1_MOSI);
+        * omap_cfg_reg(T18_24XX_SPI1_MISO);
+        * omap_cfg_reg(U19_24XX_SPI1_NCS0);
+        */
+
+       /* TSC2101 */
+       omap_cfg_reg(P20_24XX_GPIO93);
+       gpio_request(93, "tsc_irq");
+       gpio_direction_input(93);
+
+       omap_cfg_reg(W14_24XX_SYS_CLKOUT);      /* mclk */
+       /* defaults seem ok for:
+        * omap_cfg_reg(Y15_EAC_AC_SCLK);       // bclk
+        * omap_cfg_reg(R14_EAC_AC_FS);
+        * omap_cfg_reg(V15_EAC_AC_DOUT);
+        * omap_cfg_reg(W15_EAC_AC_DIN);
+        */
+
+       spi_register_board_info(h4_spi_board_info,
+                               ARRAY_SIZE(h4_spi_board_info));
 }
 
 static void __init omap_h4_map_io(void)
index e096f776f996cf51df6aeb5271764cc88d7368be..91fd0889a3581890df5335856c8f56d1d1b57c56 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/input.h>
+#include <linux/gpio_keys.h>
 #include <linux/workqueue.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/i2c/twl4030.h>
-#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <mach/board.h>
 #include <mach/common.h>
 #include <mach/gpmc.h>
+#include <mach/usb.h>
 
+#include <asm/io.h>
 #include <asm/delay.h>
 #include <mach/control.h>
-#include <mach/usb.h>
 
 #include "mmc-twl4030.h"
 
 #define LDP_SMC911X_GPIO       152
 #define DEBUG_BASE             0x08000000
 #define LDP_ETHR_START         DEBUG_BASE
+#define ENABLE_VAUX1_DEDICATED 0x03
+#define ENABLE_VAUX1_DEV_GRP   0x20
+
+#define TWL4030_MSECURE_GPIO   22
 
 static struct resource ldp_smc911x_resources[] = {
        [0] = {
@@ -66,8 +71,244 @@ static struct platform_device ldp_smc911x_device = {
        .resource       = ldp_smc911x_resources,
 };
 
+static int ldp_twl4030_keymap[] = {
+       KEY(0, 0, KEY_1),
+       KEY(1, 0, KEY_2),
+       KEY(2, 0, KEY_3),
+       KEY(0, 1, KEY_4),
+       KEY(1, 1, KEY_5),
+       KEY(2, 1, KEY_6),
+       KEY(3, 1, KEY_F5),
+       KEY(0, 2, KEY_7),
+       KEY(1, 2, KEY_8),
+       KEY(2, 2, KEY_9),
+       KEY(3, 2, KEY_F6),
+       KEY(0, 3, KEY_F7),
+       KEY(1, 3, KEY_0),
+       KEY(2, 3, KEY_F8),
+       PERSISTENT_KEY(4, 5),
+       KEY(4, 4, KEY_VOLUMEUP),
+       KEY(5, 5, KEY_VOLUMEDOWN),
+       0
+};
+
+static struct twl4030_keypad_data ldp_kp_twl4030_data = {
+       .rows           = 6,
+       .cols           = 6,
+       .keymap         = ldp_twl4030_keymap,
+       .keymapsize     = ARRAY_SIZE(ldp_twl4030_keymap),
+       .rep            = 1,
+};
+
+static struct gpio_keys_button ldp_gpio_keys_buttons[] = {
+       [0] = {
+               .code                   = KEY_ENTER,
+               .gpio                   = 101,
+               .desc                   = "enter sw",
+               .active_low             = 1,
+               .debounce_interval      = 30,
+       },
+       [1] = {
+               .code                   = KEY_F1,
+               .gpio                   = 102,
+               .desc                   = "func 1",
+               .active_low             = 1,
+               .debounce_interval      = 30,
+       },
+       [2] = {
+               .code                   = KEY_F2,
+               .gpio                   = 103,
+               .desc                   = "func 2",
+               .active_low             = 1,
+               .debounce_interval      = 30,
+       },
+       [3] = {
+               .code                   = KEY_F3,
+               .gpio                   = 104,
+               .desc                   = "func 3",
+               .active_low             = 1,
+               .debounce_interval      = 30,
+       },
+       [4] = {
+               .code                   = KEY_F4,
+               .gpio                   = 105,
+               .desc                   = "func 4",
+               .active_low             = 1,
+               .debounce_interval      = 30,
+       },
+       [5] = {
+               .code                   = KEY_LEFT,
+               .gpio                   = 106,
+               .desc                   = "left sw",
+               .active_low             = 1,
+               .debounce_interval      = 30,
+       },
+       [6] = {
+               .code                   = KEY_RIGHT,
+               .gpio                   = 107,
+               .desc                   = "right sw",
+               .active_low             = 1,
+               .debounce_interval      = 30,
+       },
+       [7] = {
+               .code                   = KEY_UP,
+               .gpio                   = 108,
+               .desc                   = "up sw",
+               .active_low             = 1,
+               .debounce_interval      = 30,
+       },
+       [8] = {
+               .code                   = KEY_DOWN,
+               .gpio                   = 109,
+               .desc                   = "down sw",
+               .active_low             = 1,
+               .debounce_interval      = 30,
+       },
+};
+
+static struct gpio_keys_platform_data ldp_gpio_keys = {
+       .buttons                = ldp_gpio_keys_buttons,
+       .nbuttons               = ARRAY_SIZE(ldp_gpio_keys_buttons),
+       .rep                    = 1,
+};
+
+static struct platform_device ldp_gpio_keys_device = {
+       .name           = "gpio-keys",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &ldp_gpio_keys,
+       },
+};
+
+static int ts_gpio;
+
+static int __init msecure_init(void)
+{
+       int ret = 0;
+
+#ifdef CONFIG_RTC_DRV_TWL4030
+       /* 3430ES2.0 doesn't have msecure/gpio-22 line connected to T2 */
+       if (omap_type() == OMAP2_DEVICE_TYPE_GP &&
+                       omap_rev() < OMAP3430_REV_ES2_0) {
+               void __iomem *msecure_pad_config_reg =
+                       omap_ctrl_base_get() + 0xA3C;
+               int mux_mask = 0x04;
+               u16 tmp;
+
+               ret = gpio_request(TWL4030_MSECURE_GPIO, "msecure");
+               if (ret < 0) {
+                       printk(KERN_ERR "msecure_init: can't"
+                               "reserve GPIO:%d !\n", TWL4030_MSECURE_GPIO);
+                       goto out;
+               }
+               /*
+                * TWL4030 will be in secure mode if msecure line from OMAP
+                * is low. Make msecure line high in order to change the
+                * TWL4030 RTC time and calender registers.
+                */
+
+               tmp = __raw_readw(msecure_pad_config_reg);
+               tmp &= 0xF8;    /* To enable mux mode 03/04 = GPIO_RTC */
+               tmp |= mux_mask;/* To enable mux mode 03/04 = GPIO_RTC */
+               __raw_writew(tmp, msecure_pad_config_reg);
+
+               gpio_direction_output(TWL4030_MSECURE_GPIO, 1);
+       }
+out:
+#endif
+       return ret;
+}
+
+/**
+ * @brief ads7846_dev_init : Requests & sets GPIO line for pen-irq
+ *
+ * @return - void. If request gpio fails then Flag KERN_ERR.
+ */
+static void ads7846_dev_init(void)
+{
+       if (gpio_request(ts_gpio, "ads7846 irq") < 0) {
+               printk(KERN_ERR "can't get ads746 pen down GPIO\n");
+               return;
+       }
+
+       gpio_direction_input(ts_gpio);
+
+       omap_set_gpio_debounce(ts_gpio, 1);
+       omap_set_gpio_debounce_time(ts_gpio, 0xa);
+}
+
+static int ads7846_get_pendown_state(void)
+{
+       return !gpio_get_value(ts_gpio);
+}
+
+/*
+ * This enable(1)/disable(0) the voltage for TS: uses twl4030 calls
+ */
+static int ads7846_vaux_control(int vaux_cntrl)
+{
+       int ret = 0;
+
+#ifdef CONFIG_TWL4030_CORE
+       /* check for return value of ldo_use: if success it returns 0 */
+       if (vaux_cntrl == VAUX_ENABLE) {
+               if (ret != twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                       ENABLE_VAUX1_DEDICATED, TWL4030_VAUX1_DEDICATED))
+                       return -EIO;
+               if (ret != twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                       ENABLE_VAUX1_DEV_GRP, TWL4030_VAUX1_DEV_GRP))
+                       return -EIO;
+       } else if (vaux_cntrl == VAUX_DISABLE) {
+               if (ret != twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                       0x00, TWL4030_VAUX1_DEDICATED))
+                       return -EIO;
+               if (ret != twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                       0x00, TWL4030_VAUX1_DEV_GRP))
+                       return -EIO;
+       }
+#else
+       ret = -EIO;
+#endif
+       return ret;
+}
+
+static struct ads7846_platform_data tsc2046_config __initdata = {
+       .get_pendown_state      = ads7846_get_pendown_state,
+       .keep_vref_on           = 1,
+       .vaux_control           = ads7846_vaux_control,
+};
+
+
+static struct omap2_mcspi_device_config tsc2046_mcspi_config = {
+       .turbo_mode     = 0,
+       .single_channel = 1,    /* 0: slave, 1: master */
+};
+
+static struct spi_board_info ldp_spi_board_info[] __initdata = {
+       [0] = {
+               /*
+                * TSC2046 operates at a max freqency of 2MHz, so
+                * operate slightly below at 1.5MHz
+                */
+               .modalias               = "ads7846",
+               .bus_num                = 1,
+               .chip_select            = 0,
+               .max_speed_hz           = 1500000,
+               .controller_data        = &tsc2046_mcspi_config,
+               .irq                    = 0,
+               .platform_data          = &tsc2046_config,
+       },
+};
+
+static struct platform_device ldp_lcd_device = {
+       .name           = "ldp_lcd",
+       .id             = -1,
+};
+
 static struct platform_device *ldp_devices[] __initdata = {
        &ldp_smc911x_device,
+       &ldp_lcd_device,
+       &ldp_gpio_keys_device,
 };
 
 static inline void __init ldp_init_smc911x(void)
@@ -99,6 +340,7 @@ static inline void __init ldp_init_smc911x(void)
        gpio_direction_input(eth_gpio);
 }
 
+
 static void __init omap_ldp_init_irq(void)
 {
        omap2_init_common_hw(NULL);
@@ -111,8 +353,114 @@ static struct omap_uart_config ldp_uart_config __initdata = {
        .enabled_uarts  = ((1 << 0) | (1 << 1) | (1 << 2)),
 };
 
+static struct omap_lcd_config ldp_lcd_config __initdata = {
+       .ctrl_name      = "internal",
+};
+
 static struct omap_board_config_kernel ldp_config[] __initdata = {
        { OMAP_TAG_UART,        &ldp_uart_config },
+       { OMAP_TAG_LCD,         &ldp_lcd_config },
+};
+
+static int ldp_batt_table[] = {
+/* 0 C*/
+30800, 29500, 28300, 27100,
+26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900,
+17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100,
+11600, 11200, 10800, 10400, 10000, 9630,   9280,   8950,   8620,   8310,
+8020,   7730,   7460,   7200,   6950,   6710,   6470,   6250,   6040,   5830,
+5640,   5450,   5260,   5090,   4920,   4760,   4600,   4450,   4310,   4170,
+4040,   3910,   3790,   3670,   3550
+};
+
+static struct twl4030_ins __initdata sleep_on_seq[] = {
+/*
+ * Turn off VDD1 and VDD2.
+ */
+       {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_OFF), 4},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_OFF), 2},
+#ifdef CONFIG_DISABLE_HFCLK
+/*
+ * And also turn off the OMAP3 PLLs and the sysclk output.
+ */
+       {MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_OFF), 3},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x19, RES_STATE_OFF), 3},
+#endif
+};
+
+static struct twl4030_script sleep_on_script __initdata = {
+       .script = sleep_on_seq,
+       .size   = ARRAY_SIZE(sleep_on_seq),
+       .flags  = TRITON_SLEEP_SCRIPT,
+};
+
+static struct twl4030_ins wakeup_seq[] __initdata = {
+#ifndef CONFIG_DISABLE_HFCLK
+/*
+ * Wakeup VDD1 and VDD2.
+ */
+       {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_ACTIVE), 4},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_ACTIVE), 2},
+#else
+/*
+ * Reenable the OMAP3 PLLs.
+ * Wakeup VDD1 and VDD2.
+ * Reenable sysclk output.
+ */
+       {MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_ACTIVE), 0x30},
+       {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_ACTIVE), 0x30},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_ACTIVE), 0x37},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x19, RES_STATE_ACTIVE), 3},
+#endif /* #ifndef CONFIG_DISABLE_HFCLK */
+};
+
+static struct twl4030_script wakeup_script __initdata = {
+       .script = wakeup_seq,
+       .size   = ARRAY_SIZE(wakeup_seq),
+       .flags  = TRITON_WAKEUP12_SCRIPT | TRITON_WAKEUP3_SCRIPT,
+};
+
+static struct twl4030_ins wrst_seq[] __initdata = {
+/*
+ * Reset twl4030.
+ * Reset VDD1 regulator.
+ * Reset VDD2 regulator.
+ * Reset VPLL1 regulator.
+ * Enable sysclk output.
+ * Reenable twl4030.
+ */
+       {MSG_SINGULAR(DEV_GRP_NULL, 0x1b, RES_STATE_OFF), 2},
+       {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_WRST), 15},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_WRST), 15},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_WRST), 0x60},
+       {MSG_SINGULAR(DEV_GRP_P1, 0x19, RES_STATE_ACTIVE), 2},
+       {MSG_SINGULAR(DEV_GRP_NULL, 0x1b, RES_STATE_ACTIVE), 2},
+};
+
+static struct twl4030_script wrst_script __initdata = {
+       .script = wrst_seq,
+       .size   = ARRAY_SIZE(wakeup_seq),
+       .flags  = TRITON_WRST_SCRIPT,
+};
+
+static struct twl4030_script *twl4030_scripts[] __initdata = {
+       &sleep_on_script,
+       &wakeup_script,
+       &wrst_script,
+};
+
+static struct twl4030_power_data sdp3430_t2scripts_data __initdata = {
+       .scripts        = twl4030_scripts,
+       .size           = ARRAY_SIZE(twl4030_scripts),
+};
+
+static struct twl4030_bci_platform_data ldp_bci_data = {
+       .battery_tmp_tbl        = ldp_batt_table,
+       .tblsize                = ARRAY_SIZE(ldp_batt_table),
+};
+
+static struct twl4030_usb_data ldp_usb_data = {
+       .usb_mode       = T2_USB_MODE_ULPI,
 };
 
 static struct twl4030_gpio_platform_data ldp_gpio_data = {
@@ -121,12 +469,21 @@ static struct twl4030_gpio_platform_data ldp_gpio_data = {
        .irq_end        = TWL4030_GPIO_IRQ_END,
 };
 
+static struct twl4030_madc_platform_data ldp_madc_data = {
+       .irq_line       = 1,
+};
+
 static struct twl4030_platform_data ldp_twldata = {
        .irq_base       = TWL4030_IRQ_BASE,
        .irq_end        = TWL4030_IRQ_END,
 
        /* platform_data for children goes here */
+       .bci            = &ldp_bci_data,
+       .madc           = &ldp_madc_data,
+       .usb            = &ldp_usb_data,
+       .power          = &sdp3430_t2scripts_data,
        .gpio           = &ldp_gpio_data,
+       .keypad         = &ldp_kp_twl4030_data,
 };
 
 static struct i2c_board_info __initdata ldp_i2c_boardinfo[] = {
@@ -163,9 +520,15 @@ static void __init omap_ldp_init(void)
        platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
        omap_board_config = ldp_config;
        omap_board_config_size = ARRAY_SIZE(ldp_config);
+       ts_gpio = 54;
+       ldp_spi_board_info[0].irq = gpio_to_irq(ts_gpio);
+       spi_register_board_info(ldp_spi_board_info,
+                               ARRAY_SIZE(ldp_spi_board_info));
+       msecure_init();
+       ads7846_dev_init();
        omap_serial_init();
-       twl4030_mmc_init(mmc);
        usb_musb_init();
+       twl4030_mmc_init(mmc);
 }
 
 static void __init omap_ldp_map_io(void)
diff --git a/arch/arm/mach-omap2/board-n800-bt.c b/arch/arm/mach-omap2/board-n800-bt.c
new file mode 100644 (file)
index 0000000..da3a7bb
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Nokia N800 platform-specific data for Bluetooth
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation
+ * Contact: Ville Tervo <ville.tervo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <mach/board.h>
+#include <mach/board-nokia.h>
+
+static struct platform_device n800_bt_device = {
+       .name           = "hci_h4p",
+       .id             = -1,
+       .num_resources  = 0,
+};
+
+void __init n800_bt_init(void)
+{
+       const struct omap_bluetooth_config *bt_config;
+
+       bt_config = (void *) omap_get_config(OMAP_TAG_NOKIA_BT,
+                                            struct omap_bluetooth_config);
+       n800_bt_device.dev.platform_data = (void *) bt_config;
+       if (platform_device_register(&n800_bt_device) < 0)
+               BUG();
+}
+
diff --git a/arch/arm/mach-omap2/board-n800-camera.c b/arch/arm/mach-omap2/board-n800-camera.c
new file mode 100644 (file)
index 0000000..3959128
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * arch/arm/mach-omap2/board-n800-camera.c
+ *
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ * Contact: Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <linux/gpio.h>
+#include <linux/i2c/menelaus.h>
+
+#include <media/v4l2-int-device.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/board.h>
+
+#include <../drivers/cbus/retu.h>
+#include <../drivers/media/video/tcm825x.h>
+
+#include "board-n800.h"
+
+#if defined (CONFIG_VIDEO_TCM825X) || defined (CONFIG_VIDEO_TCM825X_MODULE)
+
+#define OMAP24XX_CAMERA_JAM_HACK
+
+#ifdef OMAP24XX_CAMERA_JAM_HACK
+/*
+ * We don't need to check every pixel to assume that the frame is
+ * corrupt and the sensor is jammed. CHECK_X and CHECK_Y are the
+ * number of u32s to check per line / row, plus there are two lines in
+ * the bottom of the frame.
+ */
+#define CHECK_X 8
+#define CHECK_Y 6
+/*
+ * Start checking after this many frames since resetting the sensor.
+ * Sometimes the first frame(s) is(/are) black which could trigger
+ * unwanted reset(s).
+ */
+#define JAM_CHECK_AFTER 3
+/*
+ * If the sensor is quickly brought into bright conditions from dark,
+ * it may temporarily be saturated, leaving out the normal background
+ * noise. This many saturated frames may go through before the sensor
+ * is considered jammed.
+ */
+#define SATURATED_MAX 30
+#endif
+
+#define N800_CAM_SENSOR_RESET_GPIO     53
+
+static int sensor_okay;
+#ifdef OMAP24XX_CAMERA_JAM_HACK
+static int frames_after_reset;
+static int saturated_count;
+#endif
+
+const static struct tcm825x_reg tcm825x_regs_n800[] = {
+       /* initial settings for 2.5 V */
+       {0x00, 0x03}, {0x03, 0x29}, {0xaa, 0x2a}, {0xc0, 0x2b},
+       {0x10, 0x2c}, {0x4c, 0x2d}, {0x9c, 0x3f},
+
+       /* main settings */
+       {0x00, 0x00}, {0x30, 0x01}, {0x0e, 0x02}, /* initial */
+       {0x0f, 0x04}, {0x02, 0x05}, {0x0d, 0x06}, {0xc0, 0x07},
+       {0x38, 0x08}, {0x50, 0x09}, {0x80, 0x0a}, {0x40, 0x0b},
+       {0x40, 0x0c}, {0x00, 0x0d}, {0x04, 0x0e}, {0x04, 0x0f},
+       {0x22, 0x10}, {0x96, 0x11}, {0xf0, 0x12}, {0x08, 0x13},
+       {0x08, 0x14}, {0x30, 0x15}, {0x30, 0x16}, {0x01, 0x17},
+       {0x40, 0x18}, {0x87, 0x19}, {0x2b, 0x1a}, {0x84, 0x1b},
+       {0x52, 0x1c}, {0x44, 0x1d}, {0x68, 0x1e}, {0x00, 0x1f},
+       {0x00, 0x20}, {0x01, 0x21}, {0x27, 0x22}, {0x40, 0x23},
+       {0x27, 0x24}, {0x5f, 0x25}, {0x00, 0x26}, {0x16, 0x27},
+       {0x23, 0x28}, /* initial */ /* initial */ /* initial */
+       /* initial */ /* initial */ {0x00, 0x2e}, {0x00, 0x2f},
+       {0x00, 0x30}, {0x00, 0x31}, {0x00, 0x32}, {0x00, 0x33},
+       {0x00, 0x34}, {0x00, 0x35}, {0x00, 0x36}, {0x00, 0x37},
+       {0x00, 0x38}, {0x8c, 0x39}, {0xc8, 0x3A}, {0x80, 0x3b},
+       {0x00, 0x3c}, {0x17, 0x3d}, {0x85, 0x3e}, /* initial */
+       {0xa0, 0x40}, {0x00, 0x41}, {0x00, 0x42}, {0x00, 0x43},
+       {0x08, 0x44}, {0x12, 0x45}, {0x00, 0x46}, {0x20, 0x47},
+       {0x30, 0x48}, {0x18, 0x49}, {0x20, 0x4a}, {0x4d, 0x4b},
+       {0x0c, 0x4c}, {0xe0, 0x4d}, {0x20, 0x4e}, {0x89, 0x4f},
+       {0x21, 0x50}, {0x80, 0x51}, {0x02, 0x52}, {0x00, 0x53},
+       {0x30, 0x54}, {0x90, 0x55}, {0x40, 0x56}, {0x06, 0x57},
+       {0x0f, 0x58}, {0x23, 0x59}, {0x08, 0x5A}, {0x04, 0x5b},
+       {0x08, 0x5c}, {0x08, 0x5d}, {0x08, 0x5e}, {0x08, 0x5f},
+       {TCM825X_VAL_TERM, TCM825X_REG_TERM}
+};
+
+const static struct tcm825x_reg tcm825x_regs_n810[] = {
+       /* initial settings for 2.5 V */
+       {0x00, 0x03}, {0x03, 0x29}, {0xaa, 0x2a}, {0xc0, 0x2b},
+       {0x10, 0x2c}, {0x4c, 0x2d}, {0x9c, 0x3f},
+
+       /* main settings */
+       {0x00, 0x00}, {0x30, 0x01}, {0x0e, 0x02}, /* initial */
+       {0xcf, 0x04}, {0x02, 0x05}, {0x0d, 0x06}, {0xc0, 0x07},
+       {0x38, 0x08}, {0x50, 0x09}, {0x80, 0x0a}, {0x40, 0x0b},
+       {0x40, 0x0c}, {0x00, 0x0d}, {0x04, 0x0e}, {0x04, 0x0f},
+       {0x22, 0x10}, {0x96, 0x11}, {0xf0, 0x12}, {0x08, 0x13},
+       {0x08, 0x14}, {0x30, 0x15}, {0x30, 0x16}, {0x01, 0x17},
+       {0x40, 0x18}, {0x87, 0x19}, {0x2b, 0x1a}, {0x84, 0x1b},
+       {0x52, 0x1c}, {0x44, 0x1d}, {0x68, 0x1e}, {0x00, 0x1f},
+       {0x00, 0x20}, {0x01, 0x21}, {0x27, 0x22}, {0x40, 0x23},
+       {0x27, 0x24}, {0x5f, 0x25}, {0x00, 0x26}, {0x16, 0x27},
+       {0x23, 0x28}, /* initial */ /* initial */ /* initial */
+       /* initial */ /* initial */ {0x00, 0x2e}, {0x00, 0x2f},
+       {0x00, 0x30}, {0x00, 0x31}, {0x00, 0x32}, {0x00, 0x33},
+       {0x00, 0x34}, {0x00, 0x35}, {0x00, 0x36}, {0x00, 0x37},
+       {0x00, 0x38}, {0x8c, 0x39}, {0xc8, 0x3A}, {0x80, 0x3b},
+       {0x00, 0x3c}, {0x17, 0x3d}, {0x85, 0x3e}, /* initial */
+       {0xa0, 0x40}, {0x00, 0x41}, {0x00, 0x42}, {0x00, 0x43},
+       {0x08, 0x44}, {0x12, 0x45}, {0x00, 0x46}, {0x20, 0x47},
+       {0x30, 0x48}, {0x18, 0x49}, {0x20, 0x4a}, {0x4d, 0x4b},
+       {0x0c, 0x4c}, {0xe0, 0x4d}, {0x20, 0x4e}, {0x89, 0x4f},
+       {0x21, 0x50}, {0x80, 0x51}, {0x02, 0x52}, {0x00, 0x53},
+       {0x30, 0x54}, {0x90, 0x55}, {0x40, 0x56}, {0x06, 0x57},
+       {0x0f, 0x58}, {0x23, 0x59}, {0x08, 0x5A}, {0x04, 0x5b},
+       {0x08, 0x5c}, {0x08, 0x5d}, {0x08, 0x5e}, {0x08, 0x5f},
+       {TCM825X_VAL_TERM, TCM825X_REG_TERM}
+};
+
+static int tcm825x_is_okay(void)
+{
+       return sensor_okay;
+}
+
+/*
+ * VSIM1       --> CAM_IOVDD   --> IOVDD (1.8 V)
+ */
+static int tcm825x_power_on(void)
+{
+       int ret;
+
+       /* Set VMEM to 1.5V and VIO to 2.5V */
+       ret = menelaus_set_vmem(1500);
+       if (ret < 0) {
+               /* Try once more, it seems the sensor power up causes
+                * some problems on the I2C bus. */
+               ret = menelaus_set_vmem(1500);
+               if (ret < 0)
+                       return ret;
+       }
+       msleep(1);
+
+       ret = menelaus_set_vio(2500);
+       if (ret < 0)
+               return ret;
+
+       /* Set VSim1 on */
+       retu_write_reg(RETU_REG_CTRL_SET, 0x0080);
+       msleep(1);
+
+       gpio_set_value(N800_CAM_SENSOR_RESET_GPIO, 1);
+       msleep(1);
+
+       saturated_count = 0;
+       frames_after_reset = 0;
+
+       return 0;
+}
+
+static int tcm825x_power_off(void)
+{
+       int ret;
+
+       gpio_set_value(N800_CAM_SENSOR_RESET_GPIO, 0);
+       msleep(1);
+
+       /* Set VSim1 off */
+       retu_write_reg(RETU_REG_CTRL_CLR, 0x0080);
+       msleep(1);
+
+       /* Set VIO_MODE to off */
+       ret = menelaus_set_vio(0);
+       if (ret < 0)
+               return ret;
+       msleep(1);
+
+       /* Set VMEM_MODE to off */
+       ret = menelaus_set_vmem(0);
+       if (ret < 0)
+               return ret;
+       msleep(1);
+
+       return 0;
+}
+
+static int tcm825x_power_set(int power)
+{
+       BUG_ON(!sensor_okay);
+
+       if (power)
+               return tcm825x_power_on();
+       else
+               return tcm825x_power_off();
+}
+
+static const struct tcm825x_reg *tcm825x_default_regs(void)
+{
+       if (machine_is_nokia_n810())
+               return tcm825x_regs_n810;
+
+       return tcm825x_regs_n800;
+}
+
+#ifdef OMAP24XX_CAMERA_JAM_HACK
+/*
+ * Check for jammed sensor, in which case all horizontal lines are
+ * equal. Handle also case where sensor could be saturated awhile in
+ * case of rapid increase of brightness.
+ */
+static int tcm825x_needs_reset(struct v4l2_int_device *s, void *buf,
+                              struct v4l2_pix_format *pix)
+{
+       int i, j;
+       uint32_t xor, xor2;
+       uint32_t offset;
+       uint32_t dx_offset;
+       uint32_t saturated_pattern;
+       int is_saturated = 1;
+
+       switch (pix->pixelformat) {
+       default:
+       case V4L2_PIX_FMT_RGB565:
+               saturated_pattern = 0xffffffff; /* guess */
+               break;
+       case V4L2_PIX_FMT_UYVY:
+               saturated_pattern = 0xe080e080;
+               break;
+       }
+
+       /* This won't work for height under 2 at all. */
+       if (pix->height < 2)
+               return 0;
+       /* Check that there is enough image data. */
+       if (pix->width * TCM825X_BYTES_PER_PIXEL < sizeof(uint32_t))
+               return 0;
+       /*
+        * Don't check for jamming immediately. Sometimes frames
+        * immediately after reset are black.
+        */
+       if (frames_after_reset < JAM_CHECK_AFTER) {
+               frames_after_reset++;
+               return 0;
+       }
+
+       dx_offset = ((pix->width - sizeof(uint32_t) / TCM825X_BYTES_PER_PIXEL)
+                    * TCM825X_BYTES_PER_PIXEL) / (CHECK_X - 1);
+       dx_offset = dx_offset - dx_offset % TCM825X_BYTES_PER_PIXEL;
+       /*
+        * Check two lines in the bottom first. They're unlikely to be
+        * saturated and quick to check.
+        */
+       offset = (pix->height - 2) * pix->bytesperline;
+       xor = xor2 = 0;
+       for (j = 0; j < CHECK_X; j++) {
+               uint32_t *val = buf + offset;
+               uint32_t *val2 = buf + offset + pix->bytesperline;
+               xor ^= *val;
+               if (*val != saturated_pattern)
+                       is_saturated = 0;
+               xor2 ^= *val2;
+               if (xor2 != xor) {
+                       saturated_count = 0;
+                       return 0;
+               }
+               offset += dx_offset;
+       }
+       /* Check the rest of the picture. */
+       offset = 0;
+       for (i = 0; i < CHECK_Y; i++) {
+               uint32_t offset2 = offset;
+               xor2 = 0;
+               for (j = 0; j < CHECK_X; j++) {
+                       uint32_t *val = buf + offset2;
+                       xor2 ^= *val;
+                       offset2 += dx_offset;
+               }
+               if (xor2 != xor) {
+                       saturated_count = 0;
+                       return 0;
+               }
+               offset += pix->bytesperline * ((pix->height - 2) / CHECK_Y);
+       }
+
+       if (is_saturated && saturated_count++ < SATURATED_MAX)
+               return 0;
+
+       return -EIO;
+}
+#else
+static int tcm825x_needs_reset(struct v4l2_int_device *s, void *buf,
+                              struct v4l2_pix_format *pix)
+{
+       return 0;
+}
+#endif
+
+static const struct v4l2_ifparm ifparm = {
+       .if_type = V4L2_IF_TYPE_BT656,
+       .u = {
+               .bt656 = {
+                        .frame_start_on_rising_vs = 1,
+                        .latch_clk_inv = 1,
+                        .mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT,
+                        .clock_min = TCM825X_XCLK_MIN,
+                        .clock_max = TCM825X_XCLK_MAX,
+                },
+       },
+};
+
+static int tcm825x_ifparm(struct v4l2_ifparm *p)
+{
+       *p = ifparm;
+
+       return 0;
+}
+
+static int tcm825x_is_upside_down(void)
+{
+       return machine_is_nokia_n810();
+}
+
+const struct tcm825x_platform_data n800_tcm825x_platform_data = {
+       .is_okay        = tcm825x_is_okay,
+       .power_set      = tcm825x_power_set,
+       .default_regs   = tcm825x_default_regs,
+       .needs_reset    = tcm825x_needs_reset,
+       .ifparm         = tcm825x_ifparm,
+       .is_upside_down = tcm825x_is_upside_down,
+};
+
+void __init n800_cam_init(void)
+{
+       int r;
+
+       r = gpio_request(N800_CAM_SENSOR_RESET_GPIO, "TCM825x reset");
+       if (r < 0) {
+               printk(KERN_WARNING "%s: failed to request gpio\n",
+                       __func__);
+               return;
+       }
+
+       gpio_direction_output(N800_CAM_SENSOR_RESET_GPIO, 0);
+
+       sensor_okay = 1;
+}
+
+#else
+void __init n800_cam_init(void)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-omap2/board-n800-dsp.c b/arch/arm/mach-omap2/board-n800-dsp.c
new file mode 100644 (file)
index 0000000..5f3f0d6
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * linux/arch/arm/mach-omap2/board-n800-dsp.c
+ *
+ * Copyright (C) 2006 Nokia Corporation.
+ *
+ * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <asm/io.h>
+#include <mach/clock.h>
+#include <mach/board.h>
+#include <mach/dsp_common.h>
+
+#if    defined(CONFIG_OMAP_DSP)
+
+/*
+ * dsp peripheral device: AUDIO
+ */
+static struct dsp_kfunc_device n800_audio_device = {
+       .name    = "audio",
+       .type    = DSP_KFUNC_DEV_TYPE_AUDIO,
+       .enable  = n800_audio_enable,
+       .disable = n800_audio_disable,
+};
+
+/*
+ * dsp peripheral device: TIMER
+ */
+static int dsp_timer_probe(struct dsp_kfunc_device *kdev, int stage)
+{
+       char clockname[20];
+
+       strcpy(clockname, kdev->name);
+       strcat(clockname, "_fck");
+
+       kdev->fck = clk_get(NULL, clockname);
+       if (IS_ERR(kdev->fck)) {
+               printk(KERN_ERR "couldn't acquire %s\n", clockname);
+               return PTR_ERR(kdev->fck);
+       }
+       pr_debug("%s probed successfully\n", clockname);
+
+       strcpy(clockname, kdev->name);
+       strcat(clockname, "_ick");
+       kdev->ick = clk_get(NULL, clockname);
+       if (IS_ERR(kdev->ick)) {
+               printk(KERN_ERR "couldn't acquire %s\n", clockname);
+               goto fail;
+       }
+       pr_debug("%s probed successfully\n", clockname);
+
+       return 0;
+ fail:
+       clk_put(kdev->fck);
+
+       return PTR_ERR(kdev->ick);
+}
+
+static int dsp_timer_remove(struct dsp_kfunc_device *kdev, int stage)
+{
+       clk_put(kdev->ick);
+       clk_put(kdev->fck);
+       pr_debug("%s removed successfully\n", kdev->name);
+       return 0;
+}
+
+static int dsp_timer_enable(struct dsp_kfunc_device *kdev, int stage)
+{
+       pr_debug("%s enabled(%d)\n", kdev->name, stage);
+
+       spin_lock(&kdev->lock);
+
+       if (kdev->enabled)
+               goto out;
+       kdev->enabled = 1;
+
+       clk_enable(kdev->fck);
+       clk_enable(kdev->ick);
+ out:
+       spin_unlock(&kdev->lock);
+
+       return 0;
+}
+
+static int dsp_timer_disable(struct dsp_kfunc_device *kdev, int stage)
+{
+       pr_debug("%s disabled(%d)\n", kdev->name, stage);
+
+       spin_lock(&kdev->lock);
+
+       if (kdev->enabled == 0)
+               goto out;
+       kdev->enabled = 0;
+
+       clk_disable(kdev->ick);
+       clk_disable(kdev->fck);
+ out:
+       spin_unlock(&kdev->lock);
+
+       return 0;
+}
+
+static struct dsp_kfunc_device n800_timer_device = {
+       .name    = "gpt5",
+       .type    = DSP_KFUNC_DEV_TYPE_COMMON,
+       .probe   = dsp_timer_probe,
+       .remove  = dsp_timer_remove,
+       .enable  = dsp_timer_enable,
+       .disable = dsp_timer_disable,
+};
+
+static struct dsp_kfunc_device *n800_kfunc_dev[] = {
+       &n800_audio_device,
+       &n800_timer_device,
+};
+
+void __init n800_dsp_init(void)
+{
+       int i, ret;
+       struct dsp_kfunc_device **p = n800_kfunc_dev;
+
+       for (i = 0; i < ARRAY_SIZE(n800_kfunc_dev); i++) {
+               ret = dsp_kfunc_device_register(p[i]);
+               if (ret) {
+                       printk(KERN_ERR
+                              "KFUNC device registration failed: %s\n",
+                              p[i]->name);
+               }
+       }
+}
+
+#else
+void __init n800_dsp_init(void) { }
+#endif /* CONFIG_OMAP_DSP */
diff --git a/arch/arm/mach-omap2/board-n800-flash.c b/arch/arm/mach-omap2/board-n800-flash.c
new file mode 100644 (file)
index 0000000..52aaf76
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ * linux/arch/arm/mach-omap2/board-n800-flash.c
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ * Author: Juha Yrjola
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <asm/mach/flash.h>
+#include <linux/mtd/onenand_regs.h>
+
+#include <asm/io.h>
+#include <mach/onenand.h>
+#include <mach/board.h>
+#include <mach/gpmc.h>
+
+struct mtd_partition n800_partitions[ONENAND_MAX_PARTITIONS];
+
+int n800_onenand_setup(void __iomem *, int freq);
+
+static struct omap_onenand_platform_data n800_onenand_data = {
+       .cs = 0,
+       .parts = n800_partitions,
+       .nr_parts = 0, /* filled later */
+       .onenand_setup = n800_onenand_setup,
+};
+
+static struct platform_device n800_onenand_device = {
+       .name           = "omap2-onenand",
+       .id             = -1,
+       .dev = {
+               .platform_data = &n800_onenand_data,
+       },
+};
+
+static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
+{
+       struct gpmc_timings t;
+
+       const int t_cer = 15;
+       const int t_avdp = 12;
+       const int t_aavdh = 7;
+       const int t_ce = 76;
+       const int t_aa = 76;
+       const int t_oe = 20;
+       const int t_cez = 20; /* max of t_cez, t_oez */
+       const int t_ds = 30;
+       const int t_wpl = 40;
+       const int t_wph = 30;
+
+       memset(&t, 0, sizeof(t));
+       t.sync_clk = 0;
+       t.cs_on = 0;
+       t.adv_on = 0;
+
+       /* Read */
+       t.adv_rd_off = gpmc_round_ns_to_ticks(max_t(int, t_avdp, t_cer));
+       t.oe_on  = t.adv_rd_off + gpmc_round_ns_to_ticks(t_aavdh);
+       t.access = t.adv_on + gpmc_round_ns_to_ticks(t_aa);
+       t.access = max_t(int, t.access, t.cs_on + gpmc_round_ns_to_ticks(t_ce));
+       t.access = max_t(int, t.access, t.oe_on + gpmc_round_ns_to_ticks(t_oe));
+       t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
+       t.cs_rd_off = t.oe_off;
+       t.rd_cycle  = t.cs_rd_off + gpmc_round_ns_to_ticks(t_cez);
+
+       /* Write */
+       t.adv_wr_off = t.adv_rd_off;
+       t.we_on  = t.oe_on;
+       if (cpu_is_omap34xx()) {
+               t.wr_data_mux_bus = t.we_on;
+               t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
+       }
+       t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
+       t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
+       t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
+
+       /* Configure GPMC for asynchronous read */
+       gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
+                         GPMC_CONFIG1_DEVICESIZE_16 |
+                         GPMC_CONFIG1_MUXADDDATA);
+
+       return gpmc_cs_set_timings(cs, &t);
+}
+
+static unsigned short omap2_onenand_readw(void __iomem *addr)
+{
+       return readw(addr);
+}
+
+static void omap2_onenand_writew(unsigned short value, void __iomem *addr)
+{
+       writew(value, addr);
+}
+
+static void set_onenand_cfg(void __iomem *onenand_base, int latency,
+                           int sync_write, int hf)
+{
+       u32 reg;
+
+       reg = omap2_onenand_readw(onenand_base + ONENAND_REG_SYS_CFG1);
+       reg &= ~((0x7 << ONENAND_SYS_CFG1_BRL_SHIFT) | (0x7 << 9));
+       reg |=  (latency << ONENAND_SYS_CFG1_BRL_SHIFT) |
+               ONENAND_SYS_CFG1_SYNC_READ |
+               ONENAND_SYS_CFG1_BL_16;
+       if (sync_write)
+               reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
+       else
+               reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE;
+       if (hf)
+               reg |= ONENAND_SYS_CFG1_HF;
+       else
+               reg &= ~ONENAND_SYS_CFG1_HF;
+       omap2_onenand_writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
+}
+
+static int omap2_onenand_set_sync_mode(int cs, void __iomem *onenand_base,
+                                      int freq)
+{
+       struct gpmc_timings t;
+       const int t_cer  = 15;
+       const int t_avdp = 12;
+       const int t_cez  = 20; /* max of t_cez, t_oez */
+       const int t_ds   = 30;
+       const int t_wpl  = 40;
+       const int t_wph  = 30;
+       int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
+       int tick_ns, div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency;
+       int err, ticks_cez, sync_write = 0, first_time = 0, hf = 0;
+       u32 reg;
+
+       if (!freq) {
+               /* Very first call freq is not known */
+               err = omap2_onenand_set_async_mode(cs, onenand_base);
+               if (err)
+                       return err;
+               reg = omap2_onenand_readw(onenand_base +
+                                         ONENAND_REG_VERSION_ID);
+               switch ((reg >> 4) & 0xf) {
+               case 0:
+                       freq = 40;
+                       break;
+               case 1:
+                       freq = 54;
+                       break;
+               case 2:
+                       freq = 66;
+                       break;
+               case 3:
+                       freq = 83;
+                       break;
+               case 4:
+                       freq = 104;
+                       break;
+               default:
+                       freq = 54;
+                       break;
+               }
+               first_time = 1;
+       }
+
+       switch (freq) {
+       case 83:
+               min_gpmc_clk_period = 12; /* 83 MHz */
+               t_ces   = 5;
+               t_avds  = 4;
+               t_avdh  = 2;
+               t_ach   = 6;
+               t_aavdh = 6;
+               t_rdyo  = 9;
+               if (cpu_is_omap34xx())
+                       sync_write = 1;
+               break;
+       case 66:
+               min_gpmc_clk_period = 15; /* 66 MHz */
+               t_ces   = 6;
+               t_avds  = 5;
+               t_avdh  = 2;
+               t_ach   = 6;
+               t_aavdh = 6;
+               t_rdyo  = 11;
+               if (cpu_is_omap34xx())
+                       sync_write = 1;
+               break;
+       default:
+               min_gpmc_clk_period = 18; /* 54 MHz */
+               t_ces   = 7;
+               t_avds  = 7;
+               t_avdh  = 7;
+               t_ach   = 9;
+               t_aavdh = 7;
+               t_rdyo  = 15;
+               break;
+       }
+
+       tick_ns = gpmc_ticks_to_ns(1);
+       div = gpmc_cs_calc_divider(cs, min_gpmc_clk_period);
+       gpmc_clk_ns = gpmc_ticks_to_ns(div);
+       if (gpmc_clk_ns < 15) /* >66Mhz */
+               hf = 1;
+       if (hf)
+               latency = 6;
+       else if (gpmc_clk_ns >= 25) /* 40 MHz*/
+               latency = 3;
+       else
+               latency = 4;
+
+       if (first_time)
+               set_onenand_cfg(onenand_base, latency, sync_write, hf);
+
+       if (div == 1) {
+               reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
+               reg |= (1 << 7);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
+               reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
+               reg |= (1 << 7);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
+               reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
+               reg |= (1 << 7);
+               reg |= (1 << 23);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
+       } else {
+               reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
+               reg &= ~(1 << 7);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
+               reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
+               reg &= ~(1 << 7);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
+               reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
+               reg &= ~(1 << 7);
+               reg &= ~(1 << 23);
+               gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
+       }
+
+       /* Set synchronous read timings */
+       memset(&t, 0, sizeof(t));
+       t.sync_clk = min_gpmc_clk_period;
+       t.cs_on = 0;
+       t.adv_on = 0;
+       fclk_offset_ns = gpmc_round_ns_to_ticks(max_t(int, t_ces, t_avds));
+       fclk_offset = gpmc_ns_to_ticks(fclk_offset_ns);
+       t.page_burst_access = gpmc_clk_ns;
+
+       /* Read */
+       t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh));
+       t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach));
+       t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div);
+       t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
+       t.cs_rd_off = t.oe_off;
+       ticks_cez = ((gpmc_ns_to_ticks(t_cez) + div - 1) / div) * div;
+       t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
+                    ticks_cez);
+
+       /* Write */
+       if (sync_write) {
+               t.adv_wr_off = t.adv_rd_off;
+               t.we_on  = 0;
+               t.we_off = t.cs_rd_off;
+               t.cs_wr_off = t.cs_rd_off;
+               t.wr_cycle  = t.rd_cycle;
+               if (cpu_is_omap34xx()) {
+                       t.wr_data_mux_bus = gpmc_ticks_to_ns(fclk_offset +
+                                       gpmc_ns_to_ticks(min_gpmc_clk_period +
+                                       t_rdyo));
+                       t.wr_access = t.access;
+               }
+       } else {
+               t.adv_wr_off = gpmc_round_ns_to_ticks(max_t(int, t_avdp, t_cer));
+               t.we_on  = t.adv_wr_off + gpmc_round_ns_to_ticks(t_aavdh);
+               t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
+               t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
+               t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
+               if (cpu_is_omap34xx()) {
+                       t.wr_data_mux_bus = t.we_on;
+                       t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
+               }
+       }
+
+       /* Configure GPMC for synchronous read */
+       gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
+                         GPMC_CONFIG1_WRAPBURST_SUPP |
+                         GPMC_CONFIG1_READMULTIPLE_SUPP |
+                         GPMC_CONFIG1_READTYPE_SYNC |
+                         (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
+                         (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
+                         GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
+                         GPMC_CONFIG1_PAGE_LEN(2) |
+                         (cpu_is_omap34xx() ? 0 :
+                               (GPMC_CONFIG1_WAIT_READ_MON |
+                                GPMC_CONFIG1_WAIT_PIN_SEL(0))) |
+                         GPMC_CONFIG1_DEVICESIZE_16 |
+                         GPMC_CONFIG1_DEVICETYPE_NOR |
+                         GPMC_CONFIG1_MUXADDDATA);
+
+       err = gpmc_cs_set_timings(cs, &t);
+       if (err)
+               return err;
+
+       set_onenand_cfg(onenand_base, latency, sync_write, hf);
+
+       return 0;
+}
+
+int n800_onenand_setup(void __iomem *onenand_base, int freq)
+{
+       struct omap_onenand_platform_data *datap = &n800_onenand_data;
+       struct device *dev = &n800_onenand_device.dev;
+
+       /* Set sync timings in GPMC */
+       if (omap2_onenand_set_sync_mode(datap->cs, onenand_base, freq) < 0) {
+               dev_err(dev, "Unable to set synchronous mode\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+void __init n800_flash_init(void)
+{
+       const struct omap_partition_config *part;
+       int i = 0;
+
+       n800_onenand_data.gpio_irq = cpu_is_omap34xx() ? 65 : 26;
+
+       while ((part = omap_get_nr_config(OMAP_TAG_PARTITION,
+                               struct omap_partition_config, i)) != NULL) {
+               struct mtd_partition *mpart;
+
+               mpart = n800_partitions + i;
+               mpart->name = (char *) part->name;
+               mpart->size = part->size;
+               mpart->offset = part->offset;
+               mpart->mask_flags = part->mask_flags;
+               i++;
+               if (i == ARRAY_SIZE(n800_partitions)) {
+                       printk(KERN_ERR "Too many partitions supplied\n");
+                       return;
+               }
+       }
+       n800_onenand_data.nr_parts = i;
+       if (platform_device_register(&n800_onenand_device) < 0) {
+               printk(KERN_ERR "Unable to register OneNAND device\n");
+               return;
+       }
+}
diff --git a/arch/arm/mach-omap2/board-n800-mmc.c b/arch/arm/mach-omap2/board-n800-mmc.c
new file mode 100644 (file)
index 0000000..b2376a9
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ * linux/arch/arm/mach-omap2/board-n800-mmc.c
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ * Author: Juha Yrjola
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c/menelaus.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/mmc.h>
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static const int slot_switch_gpio = 96;
+
+static const int n810_slot2_pw_vddf = 23;
+static const int n810_slot2_pw_vdd = 9;
+
+static int slot1_cover_open;
+static int slot2_cover_open;
+static struct device *mmc_device;
+
+/*
+ * VMMC   --> slot 1 (N800 & N810)
+ * VDCDC3_APE, VMCS2_APE --> slot 2 on N800
+ * GPIO96 --> Menelaus GPIO2
+ * GPIO23 --> controls slot2 VSD    (N810 only)
+ * GPIO9  --> controls slot2 VIO_SD (N810 only)
+ */
+
+static int n800_mmc_switch_slot(struct device *dev, int slot)
+{
+#ifdef CONFIG_MMC_DEBUG
+       dev_dbg(dev, "Choose slot %d\n", slot + 1);
+#endif
+       gpio_set_value(slot_switch_gpio, slot);
+       return 0;
+}
+
+static int n800_mmc_set_power_menelaus(struct device *dev, int slot,
+                                       int power_on, int vdd)
+{
+       int mV;
+
+#ifdef CONFIG_MMC_DEBUG
+       dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
+               power_on ? "on" : "off", vdd);
+#endif
+       if (slot == 0) {
+               if (!power_on)
+                       return menelaus_set_vmmc(0);
+               switch (1 << vdd) {
+               case MMC_VDD_33_34:
+               case MMC_VDD_32_33:
+               case MMC_VDD_31_32:
+                       mV = 3100;
+                       break;
+               case MMC_VDD_30_31:
+                       mV = 3000;
+                       break;
+               case MMC_VDD_28_29:
+                       mV = 2800;
+                       break;
+               case MMC_VDD_165_195:
+                       mV = 1850;
+                       break;
+               default:
+                       BUG();
+               }
+               return menelaus_set_vmmc(mV);
+       } else {
+               if (!power_on)
+                       return menelaus_set_vdcdc(3, 0);
+               switch (1 << vdd) {
+               case MMC_VDD_33_34:
+               case MMC_VDD_32_33:
+                       mV = 3300;
+                       break;
+               case MMC_VDD_30_31:
+               case MMC_VDD_29_30:
+                       mV = 3000;
+                       break;
+               case MMC_VDD_28_29:
+               case MMC_VDD_27_28:
+                       mV = 2800;
+                       break;
+               case MMC_VDD_24_25:
+               case MMC_VDD_23_24:
+                       mV = 2400;
+                       break;
+               case MMC_VDD_22_23:
+               case MMC_VDD_21_22:
+                       mV = 2200;
+                       break;
+               case MMC_VDD_20_21:
+                       mV = 2000;
+                       break;
+               case MMC_VDD_165_195:
+                       mV = 1800;
+                       break;
+               default:
+                       BUG();
+               }
+               return menelaus_set_vdcdc(3, mV);
+       }
+       return 0;
+}
+
+static void nokia_mmc_set_power_internal(struct device *dev,
+                                        int power_on)
+{
+       dev_dbg(dev, "Set internal slot power %s\n",
+               power_on ? "on" : "off");
+
+       if (power_on) {
+               gpio_set_value(n810_slot2_pw_vddf, 1);
+               udelay(30);
+               gpio_set_value(n810_slot2_pw_vdd, 1);
+               udelay(100);
+       } else {
+               gpio_set_value(n810_slot2_pw_vdd, 0);
+               msleep(50);
+               gpio_set_value(n810_slot2_pw_vddf, 0);
+               msleep(50);
+       }
+}
+
+static int n800_mmc_set_power(struct device *dev, int slot, int power_on,
+                             int vdd)
+{
+       if (machine_is_nokia_n800() || slot == 0)
+               return n800_mmc_set_power_menelaus(dev, slot, power_on, vdd);
+
+       nokia_mmc_set_power_internal(dev, power_on);
+
+       return 0;
+}
+
+static int n800_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
+{
+       int r;
+
+       dev_dbg(dev, "Set slot %d bus mode %s\n", slot + 1,
+               bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
+       BUG_ON(slot != 0 && slot != 1);
+       slot++;
+       switch (bus_mode) {
+       case MMC_BUSMODE_OPENDRAIN:
+               r = menelaus_set_mmc_opendrain(slot, 1);
+               break;
+       case MMC_BUSMODE_PUSHPULL:
+               r = menelaus_set_mmc_opendrain(slot, 0);
+               break;
+       default:
+               BUG();
+       }
+       if (r != 0 && printk_ratelimit())
+               dev_err(dev, "MMC: unable to set bus mode for slot %d\n",
+                       slot);
+       return r;
+}
+
+static int n800_mmc_get_cover_state(struct device *dev, int slot)
+{
+       slot++;
+       BUG_ON(slot != 1 && slot != 2);
+       if (slot == 1)
+               return slot1_cover_open;
+       else
+               return slot2_cover_open;
+}
+
+static void n800_mmc_callback(void *data, u8 card_mask)
+{
+       int bit, *openp, index;
+
+       if (machine_is_nokia_n800()) {
+               bit = 1 << 1;
+               openp = &slot2_cover_open;
+               index = 1;
+       } else {
+               bit = 1;
+               openp = &slot1_cover_open;
+               index = 0;
+       }
+
+       if (card_mask & bit)
+               *openp = 1;
+       else
+               *openp = 0;
+
+       omap_mmc_notify_cover_event(mmc_device, index, *openp);
+}
+
+void n800_mmc_slot1_cover_handler(void *arg, int closed_state)
+{
+       if (mmc_device == NULL)
+               return;
+
+       slot1_cover_open = !closed_state;
+       omap_mmc_notify_cover_event(mmc_device, 0, closed_state);
+}
+
+static int n800_mmc_late_init(struct device *dev)
+{
+       int r, bit, *openp;
+       int vs2sel;
+
+       mmc_device = dev;
+
+       r = menelaus_set_slot_sel(1);
+       if (r < 0)
+               return r;
+
+       if (machine_is_nokia_n800())
+               vs2sel = 0;
+       else
+               vs2sel = 2;
+
+       r = menelaus_set_mmc_slot(2, 0, vs2sel, 1);
+       if (r < 0)
+               return r;
+
+       n800_mmc_set_power(dev, 0, MMC_POWER_ON, 16); /* MMC_VDD_28_29 */
+       n800_mmc_set_power(dev, 1, MMC_POWER_ON, 16);
+
+       r = menelaus_set_mmc_slot(1, 1, 0, 1);
+       if (r < 0)
+               return r;
+       r = menelaus_set_mmc_slot(2, 1, vs2sel, 1);
+       if (r < 0)
+               return r;
+
+       r = menelaus_get_slot_pin_states();
+       if (r < 0)
+               return r;
+
+       if (machine_is_nokia_n800()) {
+               bit = 1 << 1;
+               openp = &slot2_cover_open;
+       } else {
+               bit = 1;
+               openp = &slot1_cover_open;
+               slot2_cover_open = 0;
+       }
+
+       /* All slot pin bits seem to be inversed until first swith change */
+       if (r == 0xf || r == (0xf & ~bit))
+               r = ~r;
+
+       if (r & bit)
+               *openp = 1;
+       else
+               *openp = 0;
+
+       r = menelaus_register_mmc_callback(n800_mmc_callback, NULL);
+
+       return r;
+}
+
+static void n800_mmc_shutdown(struct device *dev)
+{
+       int vs2sel;
+
+       if (machine_is_nokia_n800())
+               vs2sel = 0;
+       else
+               vs2sel = 2;
+
+       menelaus_set_mmc_slot(1, 0, 0, 0);
+       menelaus_set_mmc_slot(2, 0, vs2sel, 0);
+}
+
+static void n800_mmc_cleanup(struct device *dev)
+{
+       menelaus_unregister_mmc_callback();
+
+       gpio_free(slot_switch_gpio);
+
+       if (machine_is_nokia_n810()) {
+               gpio_free(n810_slot2_pw_vddf);
+               gpio_free(n810_slot2_pw_vdd);
+       }
+}
+
+/*
+ * MMC controller1 has two slots that are multiplexed via I2C.
+ * MMC controller2 is not in use.
+ */
+static struct omap_mmc_platform_data mmc1_data = {
+       .nr_slots               = 2,
+       .switch_slot            = n800_mmc_switch_slot,
+       .init                   = n800_mmc_late_init,
+       .cleanup                = n800_mmc_cleanup,
+       .shutdown               = n800_mmc_shutdown,
+       .max_freq               = 24000000,
+       .dma_mask               = 0xffffffff,
+       .slots[0] = {
+               .wires          = 4,
+               .set_power      = n800_mmc_set_power,
+               .set_bus_mode   = n800_mmc_set_bus_mode,
+               .get_cover_state= n800_mmc_get_cover_state,
+               .ocr_mask       = MMC_VDD_165_195 | MMC_VDD_30_31 |
+                                 MMC_VDD_32_33   | MMC_VDD_33_34,
+               .name           = "internal",
+       },
+       .slots[1] = {
+               .set_power      = n800_mmc_set_power,
+               .set_bus_mode   = n800_mmc_set_bus_mode,
+               .get_cover_state= n800_mmc_get_cover_state,
+               .ocr_mask       = MMC_VDD_165_195 | MMC_VDD_20_21 |
+                                 MMC_VDD_21_22 | MMC_VDD_22_23 | MMC_VDD_23_24 |
+                                 MMC_VDD_24_25 | MMC_VDD_27_28 | MMC_VDD_28_29 |
+                                 MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_32_33 |
+                                 MMC_VDD_33_34,
+               .name           = "external",
+       },
+};
+
+static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC];
+
+void __init n800_mmc_init(void)
+
+{
+       if (machine_is_nokia_n810()) {
+               mmc1_data.slots[0].name = "external";
+
+               /*
+                * Some Samsung Movinand chips do not like open-ended
+                * multi-block reads and fall to braind-dead state
+                * while doing so. Reducing the number of blocks in
+                * the transfer or delays in clock disable do not help
+                */
+               mmc1_data.slots[1].name = "internal";
+               mmc1_data.slots[1].ban_openended = 1;
+       }
+
+       if (gpio_request(slot_switch_gpio, "MMC slot switch") < 0)
+               BUG();
+       gpio_direction_output(slot_switch_gpio, 0);
+
+       if (machine_is_nokia_n810()) {
+               if (gpio_request(n810_slot2_pw_vddf, "MMC slot 2 Vddf") < 0)
+                       BUG();
+               gpio_direction_output(n810_slot2_pw_vddf, 0);
+
+               if (gpio_request(n810_slot2_pw_vdd, "MMC slot 2 Vdd") < 0)
+                       BUG();
+               gpio_direction_output(n810_slot2_pw_vdd, 0);
+       }
+
+       mmc_data[0] = &mmc1_data;
+       omap2_init_mmc(mmc_data, OMAP24XX_NR_MMC);
+}
+#else
+
+void __init n800_mmc_init(void)
+{
+}
+
+void n800_mmc_slot1_cover_handler(void *arg, int state)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-omap2/board-n800-usb.c b/arch/arm/mach-omap2/board-n800-usb.c
new file mode 100644 (file)
index 0000000..8250014
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * linux/arch/arm/mach-omap2/board-n800-usb.c
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ * Author: Juha Yrjola
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/usb/musb.h>
+#include <mach/gpmc.h>
+#include <mach/pm.h>
+
+#define TUSB_ASYNC_CS          1
+#define TUSB_SYNC_CS           4
+#define GPIO_TUSB_INT          58
+#define GPIO_TUSB_ENABLE       0
+
+static int tusb_set_power(int state);
+static int tusb_set_clock(struct clk *osc_ck, int state);
+
+#if    defined(CONFIG_USB_MUSB_OTG)
+#      define BOARD_MODE       MUSB_OTG
+#elif  defined(CONFIG_USB_MUSB_PERIPHERAL)
+#      define BOARD_MODE       MUSB_PERIPHERAL
+#else  /* defined(CONFIG_USB_MUSB_HOST) */
+#      define BOARD_MODE       MUSB_HOST
+#endif
+
+static struct musb_hdrc_eps_bits musb_eps[] = {
+       {       "ep1_tx", 5,    },
+       {       "ep1_rx", 5,    },
+       {       "ep2_tx", 5,    },
+       {       "ep2_rx", 5,    },
+       {       "ep3_tx", 3,    },
+       {       "ep3_rx", 3,    },
+       {       "ep4_tx", 3,    },
+       {       "ep4_rx", 3,    },
+       {       "ep5_tx", 2,    },
+       {       "ep5_rx", 2,    },
+       {       "ep6_tx", 2,    },
+       {       "ep6_rx", 2,    },
+       {       "ep7_tx", 2,    },
+       {       "ep7_rx", 2,    },
+       {       "ep8_tx", 2,    },
+       {       "ep8_rx", 2,    },
+       {       "ep9_tx", 2,    },
+       {       "ep9_rx", 2,    },
+       {       "ep10_tx", 2,   },
+       {       "ep10_rx", 2,   },
+       {       "ep11_tx", 2,   },
+       {       "ep11_rx", 2,   },
+       {       "ep12_tx", 2,   },
+       {       "ep12_rx", 2,   },
+       {       "ep13_tx", 2,   },
+       {       "ep13_rx", 2,   },
+       {       "ep14_tx", 2,   },
+       {       "ep14_rx", 2,   },
+       {       "ep15_tx", 2,   },
+       {       "ep15_rx", 2,   },
+};
+
+static struct musb_hdrc_config musb_config = {
+       .multipoint     = 1,
+       .dyn_fifo       = 1,
+       .soft_con       = 1,
+       .dma            = 1,
+       .num_eps        = 16,
+       .dma_channels   = 7,
+       .ram_bits       = 12,
+       .eps_bits       = musb_eps,
+};
+
+static struct musb_hdrc_platform_data tusb_data = {
+       .mode           = BOARD_MODE,
+       .set_power      = tusb_set_power,
+       .set_clock      = tusb_set_clock,
+       .min_power      = 25,   /* x2 = 50 mA drawn from VBUS as peripheral */
+       .power          = 100,  /* Max 100 mA VBUS for host mode */
+       .clock          = "osc_ck",
+       .config         = &musb_config,
+};
+
+/*
+ * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
+ * 1.5 V voltage regulators of PM companion chip. Companion chip will then
+ * provide then PGOOD signal to TUSB6010 which will release it from reset.
+ */
+static int tusb_set_power(int state)
+{
+       int i, retval = 0;
+
+       if (state) {
+               gpio_set_value(GPIO_TUSB_ENABLE, 1);
+               msleep(1);
+
+               /* Wait until TUSB6010 pulls INT pin down */
+               i = 100;
+               while (i && gpio_get_value(GPIO_TUSB_INT)) {
+                       msleep(1);
+                       i--;
+               }
+
+               if (!i) {
+                       printk(KERN_ERR "tusb: powerup failed\n");
+                       retval = -ENODEV;
+               }
+       } else {
+               gpio_set_value(GPIO_TUSB_ENABLE, 0);
+               msleep(10);
+       }
+
+       return retval;
+}
+
+static int             osc_ck_on;
+
+static int tusb_set_clock(struct clk *osc_ck, int state)
+{
+       if (state) {
+               if (osc_ck_on > 0)
+                       return -ENODEV;
+
+               //omap2_block_sleep();
+               clk_enable(osc_ck);
+               osc_ck_on = 1;
+       } else {
+               if (osc_ck_on == 0)
+                       return -ENODEV;
+
+               clk_disable(osc_ck);
+               osc_ck_on = 0;
+               //omap2_allow_sleep();
+       }
+
+       return 0;
+}
+
+void __init n800_usb_init(void)
+{
+       int ret = 0;
+       static char     announce[] __initdata = KERN_INFO "TUSB 6010\n";
+
+       /* PM companion chip power control pin */
+       ret = gpio_request(GPIO_TUSB_ENABLE, "TUSB6010 enable");
+       if (ret != 0) {
+               printk(KERN_ERR "Could not get TUSB power GPIO%i\n",
+                      GPIO_TUSB_ENABLE);
+               return;
+       }
+       gpio_direction_output(GPIO_TUSB_ENABLE, 0);
+
+       tusb_set_power(0);
+
+       ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2,
+                                       TUSB_ASYNC_CS, TUSB_SYNC_CS,
+                                       GPIO_TUSB_INT, 0x3f);
+       if (ret != 0)
+               goto err;
+
+       printk(announce);
+
+       return;
+
+err:
+       gpio_free(GPIO_TUSB_ENABLE);
+}
diff --git a/arch/arm/mach-omap2/board-n800.c b/arch/arm/mach-omap2/board-n800.c
new file mode 100644 (file)
index 0000000..f1552f0
--- /dev/null
@@ -0,0 +1,750 @@
+/*
+ * linux/arch/arm/mach-omap2/board-n800.c
+ *
+ * Copyright (C) 2005-2007 Nokia Corporation
+ * Author: Juha Yrjola <juha.yrjola@nokia.com>
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/tsc2301.h>
+#include <linux/spi/tsc2005.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/i2c.h>
+#include <linux/i2c/lm8323.h>
+#include <linux/i2c/menelaus.h>
+#include <linux/i2c/lp5521.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/gpio.h>
+#include <mach/usb.h>
+#include <mach/board.h>
+#include <mach/common.h>
+#include <mach/mcspi.h>
+#include <mach/lcd_mipid.h>
+#include <mach/clock.h>
+#include <mach/gpio-switch.h>
+#include <mach/omapfb.h>
+#include <mach/blizzard.h>
+#include <mach/board-nokia.h>
+
+#include <../drivers/cbus/tahvo.h>
+#include <../drivers/media/video/tcm825x.h>
+
+#define N800_BLIZZARD_POWERDOWN_GPIO   15
+#define N800_STI_GPIO                  62
+#define N800_KEYB_IRQ_GPIO             109
+#define N800_DAV_IRQ_GPIO              103
+#define N800_TSC2301_RESET_GPIO                118
+
+#ifdef CONFIG_MACH_NOKIA_N810
+static s16 rx44_keymap[LM8323_KEYMAP_SIZE] = {
+       [0x01] = KEY_Q,
+       [0x02] = KEY_K,
+       [0x03] = KEY_O,
+       [0x04] = KEY_P,
+       [0x05] = KEY_BACKSPACE,
+       [0x06] = KEY_A,
+       [0x07] = KEY_S,
+       [0x08] = KEY_D,
+       [0x09] = KEY_F,
+       [0x0a] = KEY_G,
+       [0x0b] = KEY_H,
+       [0x0c] = KEY_J,
+
+       [0x11] = KEY_W,
+       [0x12] = KEY_F4,
+       [0x13] = KEY_L,
+       [0x14] = KEY_APOSTROPHE,
+       [0x16] = KEY_Z,
+       [0x17] = KEY_X,
+       [0x18] = KEY_C,
+       [0x19] = KEY_V,
+       [0x1a] = KEY_B,
+       [0x1b] = KEY_N,
+       [0x1c] = KEY_LEFTSHIFT, /* Actually, this is both shift keys */
+       [0x1f] = KEY_F7,
+
+       [0x21] = KEY_E,
+       [0x22] = KEY_SEMICOLON,
+       [0x23] = KEY_MINUS,
+       [0x24] = KEY_EQUAL,
+       [0x2b] = KEY_FN,
+       [0x2c] = KEY_M,
+       [0x2f] = KEY_F8,
+
+       [0x31] = KEY_R,
+       [0x32] = KEY_RIGHTCTRL,
+       [0x34] = KEY_SPACE,
+       [0x35] = KEY_COMMA,
+       [0x37] = KEY_UP,
+       [0x3c] = KEY_COMPOSE,
+       [0x3f] = KEY_F6,
+
+       [0x41] = KEY_T,
+       [0x44] = KEY_DOT,
+       [0x46] = KEY_RIGHT,
+       [0x4f] = KEY_F5,
+       [0x51] = KEY_Y,
+       [0x53] = KEY_DOWN,
+       [0x55] = KEY_ENTER,
+       [0x5f] = KEY_ESC,
+
+       [0x61] = KEY_U,
+       [0x64] = KEY_LEFT,
+
+       [0x71] = KEY_I,
+       [0x75] = KEY_KPENTER,
+};
+
+static struct lm8323_platform_data lm8323_pdata = {
+       .repeat         = 0, /* Repeat is handled in userspace for now. */
+       .keymap         = rx44_keymap,
+       .size_x         = 8,
+       .size_y         = 8,
+       .debounce_time  = 12,
+       .active_time    = 500,
+
+       .name           = "Internal keyboard",
+       .pwm1_name      = "n810::keyboard",
+       .pwm2_name      = "n810::cover",
+};
+#endif
+
+void __init nokia_n800_init_irq(void)
+{
+       omap2_init_common_hw(NULL);
+       omap_init_irq();
+       omap_gpio_init();
+
+#ifdef CONFIG_OMAP_STI
+       if (gpio_request(N800_STI_GPIO, "STI") < 0) {
+               printk(KERN_ERR "Failed to request GPIO %d for STI\n",
+                      N800_STI_GPIO);
+               return;
+       }
+
+       gpio_direction_output(N800_STI_GPIO, 0);
+#endif
+}
+
+#if defined(CONFIG_MENELAUS) && defined(CONFIG_SENSORS_TMP105)
+
+static int n800_tmp105_set_power(int enable)
+{
+       return menelaus_set_vaux(enable ? 2800 : 0);
+}
+
+#else
+
+#define n800_tmp105_set_power NULL
+
+#endif
+
+static struct omap_uart_config n800_uart_config __initdata = {
+       .enabled_uarts = (1 << 0) | (1 << 2),
+};
+
+#include "../../../drivers/cbus/retu.h"
+
+static struct omap_fbmem_config n800_fbmem0_config __initdata = {
+       .size = 752 * 1024,
+};
+
+static struct omap_fbmem_config n800_fbmem1_config __initdata = {
+       .size = 752 * 1024,
+};
+
+static struct omap_fbmem_config n800_fbmem2_config __initdata = {
+       .size = 752 * 1024,
+};
+
+static struct omap_tmp105_config n800_tmp105_config __initdata = {
+       .tmp105_irq_pin = 125,
+       .set_power = n800_tmp105_set_power,
+};
+
+static void mipid_shutdown(struct mipid_platform_data *pdata)
+{
+       if (pdata->nreset_gpio != -1) {
+               pr_info("shutdown LCD\n");
+               gpio_set_value(pdata->nreset_gpio, 0);
+               msleep(120);
+       }
+}
+
+static struct mipid_platform_data n800_mipid_platform_data = {
+       .shutdown = mipid_shutdown,
+};
+
+static void __init mipid_dev_init(void)
+{
+       const struct omap_lcd_config *conf;
+
+       conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
+       if (conf != NULL) {
+               n800_mipid_platform_data.nreset_gpio = conf->nreset_gpio;
+               n800_mipid_platform_data.data_lines = conf->data_lines;
+       }
+}
+
+static struct {
+       struct clk *sys_ck;
+} blizzard;
+
+static int blizzard_get_clocks(void)
+{
+       blizzard.sys_ck = clk_get(0, "osc_ck");
+       if (IS_ERR(blizzard.sys_ck)) {
+               printk(KERN_ERR "can't get Blizzard clock\n");
+               return PTR_ERR(blizzard.sys_ck);
+       }
+       return 0;
+}
+
+static unsigned long blizzard_get_clock_rate(struct device *dev)
+{
+       return clk_get_rate(blizzard.sys_ck);
+}
+
+static void blizzard_enable_clocks(int enable)
+{
+       if (enable)
+               clk_enable(blizzard.sys_ck);
+       else
+               clk_disable(blizzard.sys_ck);
+}
+
+static void blizzard_power_up(struct device *dev)
+{
+       /* Vcore to 1.475V */
+       tahvo_set_clear_reg_bits(0x07, 0, 0xf);
+       msleep(10);
+
+       blizzard_enable_clocks(1);
+       gpio_set_value(N800_BLIZZARD_POWERDOWN_GPIO, 1);
+}
+
+static void blizzard_power_down(struct device *dev)
+{
+       gpio_set_value(N800_BLIZZARD_POWERDOWN_GPIO, 0);
+       blizzard_enable_clocks(0);
+
+       /* Vcore to 1.005V */
+       tahvo_set_clear_reg_bits(0x07, 0xf, 0);
+}
+
+static struct blizzard_platform_data n800_blizzard_data = {
+       .power_up       = blizzard_power_up,
+       .power_down     = blizzard_power_down,
+       .get_clock_rate = blizzard_get_clock_rate,
+       .te_connected   = 1,
+};
+
+static void __init blizzard_dev_init(void)
+{
+       int r;
+
+       r = gpio_request(N800_BLIZZARD_POWERDOWN_GPIO, "Blizzard pd");
+       if (r < 0)
+               return;
+       gpio_direction_output(N800_BLIZZARD_POWERDOWN_GPIO, 1);
+
+       blizzard_get_clocks();
+       omapfb_set_ctrl_platform_data(&n800_blizzard_data);
+}
+
+static struct omap_board_config_kernel n800_config[] __initdata = {
+       { OMAP_TAG_UART,                        &n800_uart_config },
+       { OMAP_TAG_FBMEM,                       &n800_fbmem0_config },
+       { OMAP_TAG_FBMEM,                       &n800_fbmem1_config },
+       { OMAP_TAG_FBMEM,                       &n800_fbmem2_config },
+       { OMAP_TAG_TMP105,                      &n800_tmp105_config },
+};
+
+static struct tsc2301_platform_data tsc2301_config = {
+       .reset_gpio     = N800_TSC2301_RESET_GPIO,
+       .keymap = {
+               -1,             /* Event for bit 0 */
+               KEY_UP,         /* Event for bit 1 (up) */
+               KEY_F5,         /* Event for bit 2 (home) */
+               -1,             /* Event for bit 3 */
+               KEY_LEFT,       /* Event for bit 4 (left) */
+               KEY_ENTER,      /* Event for bit 5 (enter) */
+               KEY_RIGHT,      /* Event for bit 6 (right) */
+               -1,             /* Event for bit 7 */
+               KEY_ESC,        /* Event for bit 8 (cycle) */
+               KEY_DOWN,       /* Event for bit 9 (down) */
+               KEY_F4,         /* Event for bit 10 (menu) */
+               -1,             /* Event for bit 11 */
+               KEY_F8,         /* Event for bit 12 (Zoom-) */
+               KEY_F6,         /* Event for bit 13 (FS) */
+               KEY_F7,         /* Event for bit 14 (Zoom+) */
+               -1,             /* Event for bit 15 */
+       },
+       .kp_rep         = 0,
+       .keyb_name      = "Internal keypad",
+};
+
+static void tsc2301_dev_init(void)
+{
+       int r;
+       int gpio = N800_KEYB_IRQ_GPIO;
+
+       r = gpio_request(gpio, "tsc2301 KBD IRQ");
+       if (r >= 0) {
+               gpio_direction_input(gpio);
+               tsc2301_config.keyb_int = gpio_to_irq(gpio);
+       } else {
+               printk(KERN_ERR "unable to get KBD GPIO");
+       }
+
+       gpio = N800_DAV_IRQ_GPIO;
+       r = gpio_request(gpio, "tsc2301 DAV IRQ");
+       if (r >= 0) {
+               gpio_direction_input(gpio);
+               tsc2301_config.dav_int = gpio_to_irq(gpio);
+       } else {
+               printk(KERN_ERR "unable to get DAV GPIO");
+       }
+}
+
+static int __init tea5761_dev_init(void)
+{
+       const struct omap_tea5761_config *info;
+       int enable_gpio = 0;
+
+       info = omap_get_config(OMAP_TAG_TEA5761, struct omap_tea5761_config);
+       if (info)
+               enable_gpio = info->enable_gpio;
+
+       if (enable_gpio) {
+               pr_debug("Enabling tea5761 at GPIO %d\n",
+                        enable_gpio);
+
+               if (gpio_request(enable_gpio, "TEA5761 enable") < 0) {
+                       printk(KERN_ERR "Can't request GPIO %d\n",
+                              enable_gpio);
+                       return -ENODEV;
+               }
+
+               gpio_direction_output(enable_gpio, 0);
+               udelay(50);
+               gpio_set_value(enable_gpio, 1);
+       }
+
+       return 0;
+}
+
+static struct omap2_mcspi_device_config tsc2301_mcspi_config = {
+       .turbo_mode     = 0,
+       .single_channel = 1,
+};
+
+static struct omap2_mcspi_device_config mipid_mcspi_config = {
+       .turbo_mode     = 0,
+       .single_channel = 1,
+};
+
+static struct omap2_mcspi_device_config cx3110x_mcspi_config = {
+       .turbo_mode     = 0,
+       .single_channel = 1,
+};
+
+#ifdef CONFIG_TOUCHSCREEN_TSC2005
+static struct tsc2005_platform_data tsc2005_config = {
+       .reset_gpio = 94,
+       .dav_gpio = 106
+};
+
+static struct omap2_mcspi_device_config tsc2005_mcspi_config = {
+       .turbo_mode     = 0,
+       .single_channel = 1,
+};
+#endif
+
+static struct spi_board_info n800_spi_board_info[] __initdata = {
+       {
+               .modalias       = "lcd_mipid",
+               .bus_num        = 1,
+               .chip_select    = 1,
+               .max_speed_hz   = 4000000,
+               .controller_data= &mipid_mcspi_config,
+               .platform_data  = &n800_mipid_platform_data,
+       }, {
+               .modalias       = "cx3110x",
+               .bus_num        = 2,
+               .chip_select    = 0,
+               .max_speed_hz   = 48000000,
+               .controller_data= &cx3110x_mcspi_config,
+       },
+       {
+               .modalias       = "tsc2301",
+               .bus_num        = 1,
+               .chip_select    = 0,
+               .max_speed_hz   = 6000000,
+               .controller_data= &tsc2301_mcspi_config,
+               .platform_data  = &tsc2301_config,
+       },
+};
+
+static struct spi_board_info n810_spi_board_info[] __initdata = {
+       {
+               .modalias        = "lcd_mipid",
+               .bus_num         = 1,
+               .chip_select     = 1,
+               .max_speed_hz    = 4000000,
+               .controller_data = &mipid_mcspi_config,
+               .platform_data   = &n800_mipid_platform_data,
+       },
+       {
+               .modalias        = "cx3110x",
+               .bus_num         = 2,
+               .chip_select     = 0,
+               .max_speed_hz    = 48000000,
+               .controller_data = &cx3110x_mcspi_config,
+       },
+       {
+               .modalias        = "tsc2005",
+               .bus_num         = 1,
+               .chip_select     = 0,
+               .max_speed_hz    = 6000000,
+               .controller_data = &tsc2005_mcspi_config,
+               .platform_data   = &tsc2005_config,
+       },
+};
+
+static void __init tsc2005_set_config(void)
+{
+       const struct omap_lcd_config *conf;
+
+       conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
+       if (conf != NULL) {
+#ifdef CONFIG_TOUCHSCREEN_TSC2005
+               if (strcmp(conf->panel_name, "lph8923") == 0) {
+                       tsc2005_config.ts_x_plate_ohm = 180;
+                       tsc2005_config.ts_hw_avg = 0;
+                       tsc2005_config.ts_ignore_last = 0;
+                       tsc2005_config.ts_touch_pressure = 1500;
+                       tsc2005_config.ts_stab_time = 100;
+                       tsc2005_config.ts_pressure_max = 2048;
+                       tsc2005_config.ts_pressure_fudge = 2;
+                       tsc2005_config.ts_x_max = 4096;
+                       tsc2005_config.ts_x_fudge = 4;
+                       tsc2005_config.ts_y_max = 4096;
+                       tsc2005_config.ts_y_fudge = 7;
+               } else if (strcmp(conf->panel_name, "ls041y3") == 0) {
+                       tsc2005_config.ts_x_plate_ohm = 280;
+                       tsc2005_config.ts_hw_avg = 0;
+                       tsc2005_config.ts_ignore_last = 0;
+                       tsc2005_config.ts_touch_pressure = 1500;
+                       tsc2005_config.ts_stab_time = 1000;
+                       tsc2005_config.ts_pressure_max = 2048;
+                       tsc2005_config.ts_pressure_fudge = 2;
+                       tsc2005_config.ts_x_max = 4096;
+                       tsc2005_config.ts_x_fudge = 4;
+                       tsc2005_config.ts_y_max = 4096;
+                       tsc2005_config.ts_y_fudge = 7;
+               } else {
+                       printk(KERN_ERR "Unknown panel type, set default "
+                              "touchscreen configuration\n");
+                       tsc2005_config.ts_x_plate_ohm = 200;
+                       tsc2005_config.ts_stab_time = 100;
+               }
+#endif
+       }
+}
+
+#if defined(CONFIG_CBUS_RETU) && defined(CONFIG_LEDS_OMAP_PWM)
+
+void retu_keypad_led_set_power(struct omap_pwm_led_platform_data *self,
+                              int on_off)
+{
+       if (on_off) {
+               retu_write_reg(RETU_REG_CTRL_SET, 1 << 6);
+               msleep(2);
+               retu_write_reg(RETU_REG_CTRL_SET, 1 << 3);
+       } else {
+               retu_write_reg(RETU_REG_CTRL_CLR, (1 << 6) | (1 << 3));
+       }
+}
+
+static struct omap_pwm_led_platform_data n800_keypad_led_data = {
+       .name = "keypad",
+       .intensity_timer = 10,
+       .blink_timer = 9,
+       .set_power = retu_keypad_led_set_power,
+};
+
+static struct platform_device n800_keypad_led_device = {
+       .name           = "omap_pwm_led",
+       .id             = -1,
+       .dev            = {
+               .platform_data = &n800_keypad_led_data,
+       },
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_TSC2301)
+static void __init n800_ts_set_config(void)
+{
+       const struct omap_lcd_config *conf;
+
+       conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
+       if (conf != NULL) {
+               if (strcmp(conf->panel_name, "lph8923") == 0) {
+                       tsc2301_config.ts_x_plate_ohm   = 180;
+                       tsc2301_config.ts_hw_avg        = 8;
+                       tsc2301_config.ts_max_pressure  = 2048;
+                       tsc2301_config.ts_touch_pressure = 400;
+                       tsc2301_config.ts_stab_time     = 100;
+                       tsc2301_config.ts_pressure_fudge = 2;
+                       tsc2301_config.ts_x_max         = 4096;
+                       tsc2301_config.ts_x_fudge       = 4;
+                       tsc2301_config.ts_y_max         = 4096;
+                       tsc2301_config.ts_y_fudge       = 7;
+               } else if (strcmp(conf->panel_name, "ls041y3") == 0) {
+                       tsc2301_config.ts_x_plate_ohm   = 280;
+                       tsc2301_config.ts_hw_avg        = 8;
+                       tsc2301_config.ts_touch_pressure = 400;
+                       tsc2301_config.ts_max_pressure  = 2048;
+                       tsc2301_config.ts_stab_time     = 1000;
+                       tsc2301_config.ts_pressure_fudge = 2;
+                       tsc2301_config.ts_x_max         = 4096;
+                       tsc2301_config.ts_x_fudge       = 4;
+                       tsc2301_config.ts_y_max         = 4096;
+                       tsc2301_config.ts_y_fudge       = 7;
+               } else {
+                       printk(KERN_ERR "Unknown panel type, set default "
+                              "touchscreen configuration\n");
+                       tsc2301_config.ts_x_plate_ohm   = 200;
+                       tsc2301_config.ts_stab_time     = 100;
+               }
+       }
+}
+#else
+static inline void n800_ts_set_config(void)
+{
+}
+#endif
+
+static struct omap_gpio_switch n800_gpio_switches[] __initdata = {
+       {
+               .name                   = "bat_cover",
+               .gpio                   = -1,
+               .debounce_rising        = 100,
+               .debounce_falling       = 0,
+               .notify                 = n800_mmc_slot1_cover_handler,
+               .notify_data            = NULL,
+       }, {
+               .name                   = "headphone",
+               .gpio                   = -1,
+               .debounce_rising        = 200,
+               .debounce_falling       = 200,
+       }, {
+               .name                   = "cam_act",
+               .gpio                   = -1,
+               .debounce_rising        = 200,
+               .debounce_falling       = 200,
+       }, {
+               .name                   = "cam_turn",
+               .gpio                   = -1,
+               .debounce_rising        = 100,
+               .debounce_falling       = 100,
+       },
+};
+
+#if defined(CONFIG_CBUS_RETU_HEADSET)
+static struct platform_device retu_headset_device = {
+       .name   = "retu-headset",
+       .id     = -1,
+};
+#endif
+
+static struct platform_device *n800_devices[] __initdata = {
+#if defined(CONFIG_CBUS_RETU) && defined(CONFIG_LEDS_OMAP_PWM)
+       &n800_keypad_led_device,
+#endif
+#if defined(CONFIG_CBUS_RETU_HEADSET)
+       &retu_headset_device,
+#endif
+};
+
+#ifdef CONFIG_MENELAUS
+static int n800_auto_sleep_regulators(void)
+{
+       u32 val;
+       int ret;
+
+       val = EN_VPLL_SLEEP | EN_VMMC_SLEEP    \
+               | EN_VAUX_SLEEP | EN_VIO_SLEEP \
+               | EN_VMEM_SLEEP | EN_DC3_SLEEP \
+               | EN_VC_SLEEP | EN_DC2_SLEEP;
+
+       ret = menelaus_set_regulator_sleep(1, val);
+       if (ret < 0) {
+               printk(KERN_ERR "Could not set regulators to sleep on "
+                       "menelaus: %u\n", ret);
+               return ret;
+       }
+       return 0;
+}
+
+static int n800_auto_voltage_scale(void)
+{
+       int ret;
+
+       ret = menelaus_set_vcore_hw(1400, 1050);
+       if (ret < 0) {
+               printk(KERN_ERR "Could not set VCORE voltage on "
+                       "menelaus: %u\n", ret);
+               return ret;
+       }
+       return 0;
+}
+
+static int n800_menelaus_init(struct device *dev)
+{
+       int ret;
+
+       ret = n800_auto_voltage_scale();
+       if (ret < 0)
+               return ret;
+       ret = n800_auto_sleep_regulators();
+       if (ret < 0)
+               return ret;
+       return 0;
+}
+
+static struct menelaus_platform_data n800_menelaus_platform_data = {
+       .late_init = n800_menelaus_init,
+};
+#endif
+
+static struct i2c_board_info __initdata n800_i2c_board_info_1[] = {
+       {
+               I2C_BOARD_INFO("menelaus", 0x72),
+               .irq = INT_24XX_SYS_NIRQ,
+               .platform_data = &n800_menelaus_platform_data,
+       },
+};
+
+static struct lp5521_platform_data n810_lp5521_platform_data = {
+       .mode           = LP5521_MODE_DIRECT_CONTROL,
+       .label          = "n810",
+       .red_present    = true,
+       .green_present  = true,
+       .blue_present   = true,
+};
+
+extern struct tcm825x_platform_data n800_tcm825x_platform_data;
+
+static struct i2c_board_info __initdata_or_module n8x0_i2c_board_info_2[] = {
+       {
+               I2C_BOARD_INFO(TCM825X_NAME, TCM825X_I2C_ADDR),
+#if defined (CONFIG_VIDEO_TCM825X) || defined (CONFIG_VIDEO_TCM825X_MODULE)
+               .platform_data = &n800_tcm825x_platform_data,
+#endif
+       },
+};
+
+
+static struct i2c_board_info __initdata_or_module n800_i2c_board_info_2[] = {
+       {
+               I2C_BOARD_INFO("tea5761", 0x10),
+       },
+};
+
+static struct i2c_board_info __initdata_or_module n810_i2c_board_info_2[] = {
+       {
+               I2C_BOARD_INFO("lm8323", 0x45),
+               .irq            = OMAP_GPIO_IRQ(109),
+               .platform_data  = &lm8323_pdata,
+       },
+       {
+               I2C_BOARD_INFO("tsl2563", 0x29),
+       },
+       {
+               I2C_BOARD_INFO("lp5521", 0x32),
+               .platform_data = &n810_lp5521_platform_data,
+       },
+};
+
+void __init nokia_n800_common_init(void)
+{
+       platform_add_devices(n800_devices, ARRAY_SIZE(n800_devices));
+
+       n800_flash_init();
+       n800_mmc_init();
+       n800_bt_init();
+       n800_dsp_init();
+       n800_usb_init();
+       n800_cam_init();
+       if (machine_is_nokia_n800())
+               spi_register_board_info(n800_spi_board_info,
+                               ARRAY_SIZE(n800_spi_board_info));
+       if (machine_is_nokia_n810()) {
+               tsc2005_set_config();
+               spi_register_board_info(n810_spi_board_info,
+                               ARRAY_SIZE(n810_spi_board_info));
+       }
+       omap_serial_init();
+       omap_register_i2c_bus(1, 400, n800_i2c_board_info_1,
+                             ARRAY_SIZE(n800_i2c_board_info_1));
+       omap_register_i2c_bus(2, 400, n8x0_i2c_board_info_2,
+                             ARRAY_SIZE(n8x0_i2c_board_info_2));
+       if (machine_is_nokia_n800())
+               i2c_register_board_info(2, n800_i2c_board_info_2,
+                       ARRAY_SIZE(n800_i2c_board_info_2));
+       if (machine_is_nokia_n810())
+               i2c_register_board_info(2, n810_i2c_board_info_2,
+                       ARRAY_SIZE(n810_i2c_board_info_2));
+               
+       mipid_dev_init();
+       blizzard_dev_init();
+}
+
+static void __init nokia_n800_init(void)
+{
+       nokia_n800_common_init();
+
+       n800_ts_set_config();
+       tsc2301_dev_init();
+       tea5761_dev_init();
+       omap_register_gpio_switches(n800_gpio_switches,
+                                   ARRAY_SIZE(n800_gpio_switches));
+}
+
+void __init nokia_n800_map_io(void)
+{
+       omap_board_config = n800_config;
+       omap_board_config_size = ARRAY_SIZE(n800_config);
+
+       omap2_set_globals_242x();
+       omap2_map_common_io();
+}
+
+MACHINE_START(NOKIA_N800, "Nokia N800")
+       .phys_io        = 0x48000000,
+       .io_pg_offst    = ((0xd8000000) >> 18) & 0xfffc,
+       .boot_params    = 0x80000100,
+       .map_io         = nokia_n800_map_io,
+       .init_irq       = nokia_n800_init_irq,
+       .init_machine   = nokia_n800_init,
+       .timer          = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-n800.h b/arch/arm/mach-omap2/board-n800.h
new file mode 100644 (file)
index 0000000..e71dae4
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-omap2/board-n800.h
+ *
+ * Copyright (C) 2005-2007 Nokia Corporation
+ * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
+ *
+ * Modified from mach-omap2/board-n800.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_BOARD_N800_H
+#define __ARCH_ARM_MACH_OMAP2_BOARD_N800_H
+
+void __init nokia_n800_common_init(void);
+void __init nokia_n800_map_io(void);
+void __init nokia_n800_init_irq(void);
+
+extern const struct tcm825x_platform_data n800_tcm825x_platform_data;
+
+#endif
diff --git a/arch/arm/mach-omap2/board-n810.c b/arch/arm/mach-omap2/board-n810.c
new file mode 100644 (file)
index 0000000..7984d43
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/arm/mach-omap2/board-n810.c
+ *
+ * Copyright (C) 2007 Nokia
+ * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/i2c/lm8323.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/board.h>
+#include <mach/common.h>
+
+#include "board-n800.h"
+
+static void __init nokia_n810_init(void)
+{
+       nokia_n800_common_init();
+}
+
+MACHINE_START(NOKIA_N810, "Nokia N810")
+       .phys_io        = 0x48000000,
+       .io_pg_offst    = ((0xd8000000) >> 18) & 0xfffc,
+       .boot_params    = 0x80000100,
+       .map_io         = nokia_n800_map_io,
+       .init_irq       = nokia_n800_init_irq,
+       .init_machine   = nokia_n810_init,
+       .timer          = &omap_timer,
+MACHINE_END
+
+MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
+       .phys_io        = 0x48000000,
+       .io_pg_offst    = ((0xd8000000) >> 18) & 0xfffc,
+       .boot_params    = 0x80000100,
+       .map_io         = nokia_n800_map_io,
+       .init_irq       = nokia_n800_init_irq,
+       .init_machine   = nokia_n810_init,
+       .timer          = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap2evm.c b/arch/arm/mach-omap2/board-omap2evm.c
new file mode 100644 (file)
index 0000000..86477cc
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap2evm.c
+ *
+ * Copyright (C) 2008 Mistral Solutions Pvt Ltd
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/input.h>
+#include <linux/i2c/twl4030.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/common.h>
+#include <mach/mmc.h>
+#include <mach/gpmc.h>
+#include <mach/nand.h>
+#include <mach/mcspi.h>
+#include <mach/mux.h>
+
+#include "mmc-twl4030.h"
+
+#define OMAP2EVM_ETHR_START            0x2c000000
+#define OMAP2EVM_ETHR_SIZE             1024
+#define OMAP2EVM_ETHR_GPIO_IRQ         149
+#define        OMAP2_EVM_TS_GPIO               85
+
+#define GPMC_OFF_CONFIG1_0             0x60
+
+static struct mtd_partition omap2evm_nand_partitions[] = {
+       {
+               .name           = "X-Loader",
+               .offset         = 0,
+               .size           = 1 * (64 * 2048),
+               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
+       },
+       {
+               .name           = "U-Boot",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 3 * (64 * 2048),
+               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
+       },
+       {
+               .name           = "U-Boot Environment",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 1 * (64 * 2048),
+        },
+       {
+               .name           = "Kernel",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 16 * (64 * 2048),     /* 2MB */
+       },
+       {
+               .name           = "Ramdisk",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 32 * (64 * 2048),     /* 4MB */
+       },
+       {
+               .name           = "Filesystem",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = MTDPART_SIZ_FULL,
+       }
+};
+
+static struct omap_nand_platform_data omap2evm_nand_data = {
+       .parts          = omap2evm_nand_partitions,
+       .nr_parts       = ARRAY_SIZE(omap2evm_nand_partitions),
+       .dma_channel    = -1,   /* disable DMA in OMAP NAND driver */
+};
+
+static struct resource omap2evm_nand_resource = {
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device omap2evm_nand_device = {
+       .name           = "omap2-nand",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &omap2evm_nand_data,
+       },
+       .num_resources  = 1,
+       .resource       = &omap2evm_nand_resource,
+};
+
+void __init omap2evm_flash_init(void)
+{
+       void __iomem *gpmc_base_add, *gpmc_cs_base_add;
+       unsigned char cs = 0;
+
+       gpmc_base_add = (__force void __iomem *)OMAP243X_GPMC_VIRT;
+       while (cs < GPMC_CS_NUM) {
+               int ret = 0;
+
+               /* Each GPMC set for a single CS is at offset 0x30 */
+               gpmc_cs_base_add = (gpmc_base_add + GPMC_OFF_CONFIG1_0 +
+                                   (cs * 0x30));
+
+               /* xloader/Uboot would have programmed the NAND
+                * base address for us This is a ugly hack. The proper
+                * way of doing this is to pass the setup of u-boot up
+                * to kernel using kernel params - something on the
+                * lines of machineID. Check if Nand is
+                * configured */
+               ret = __raw_readl(gpmc_cs_base_add + GPMC_CS_CONFIG1);
+               if ((ret & 0xC00) == (0x800)) {
+                       /* Found it!! */
+                       printk(KERN_INFO "NAND: Found NAND on CS %d \n", cs);
+                       break;
+               }
+               cs++;
+       }
+       if (cs >= GPMC_CS_NUM) {
+               printk(KERN_INFO "MTD: Unable to find MTD configuration in "
+                                "GPMC   - not registering.\n");
+               return;
+       }
+
+       omap2evm_nand_data.cs                   = cs;
+       omap2evm_nand_data.gpmc_cs_baseaddr     = gpmc_cs_base_add;
+       omap2evm_nand_data.gpmc_baseaddr        = gpmc_base_add;
+
+       if (platform_device_register(&omap2evm_nand_device) < 0) {
+               printk(KERN_ERR "Unable to register NAND device\n");
+               return;
+       }
+}
+
+static struct resource omap2evm_smc911x_resources[] = {
+       [0] =   {
+               .start  = OMAP2EVM_ETHR_START,
+               .end    = (OMAP2EVM_ETHR_START + OMAP2EVM_ETHR_SIZE - 1),
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] =   {
+               .start  = OMAP_GPIO_IRQ(OMAP2EVM_ETHR_GPIO_IRQ),
+               .end    = OMAP_GPIO_IRQ(OMAP2EVM_ETHR_GPIO_IRQ),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device omap2evm_smc911x_device = {
+       .name       = "smc911x",
+       .id     = -1,
+       .num_resources  = ARRAY_SIZE(omap2evm_smc911x_resources),
+       .resource   = &omap2evm_smc911x_resources [0],
+};
+
+static inline void __init omap2evm_init_smc911x(void)
+{
+       int gpio = OMAP2EVM_ETHR_GPIO_IRQ;
+       int ret;
+
+       ret = gpio_request(gpio, "smc911x IRQ");
+       if (ret < 0) {
+               printk(KERN_ERR "Failed to request GPIO %d for smc911x IRQ\n",
+                               gpio);
+               return;
+       }
+       gpio_direction_input(gpio);
+
+}
+
+static struct platform_device omap2_evm_lcd_device = {
+       .name           = "omap2evm_lcd",
+       .id             = -1,
+};
+
+static struct omap_lcd_config omap2_evm_lcd_config __initdata = {
+       .ctrl_name      = "internal",
+};
+
+static void ads7846_dev_init(void)
+{
+       int gpio = OMAP2_EVM_TS_GPIO;
+       int ret;
+
+       ret = gpio_request(gpio, "ads7846_pen_down");
+       if (ret < 0) {
+               printk(KERN_ERR "Failed to request GPIO %d for ads7846 pen down IRQ\n",
+                               gpio);
+               return;
+       }
+
+       gpio_direction_input(gpio);
+
+       /*Setting the MUX */
+       omap_cfg_reg(Y18_2430_MCSPI1_CLK);
+       omap_cfg_reg(AD15_2430_MCSPI1_SIMO);
+       omap_cfg_reg(AE17_2430_MCSPI1_SOMI);
+       omap_cfg_reg(U1_2430_MCSPI1_CS0);
+
+       omap_cfg_reg(AF19_2430_GPIO_85);
+
+}
+
+static int ads7846_get_pendown_state(void)
+{
+       return !gpio_get_value(OMAP2_EVM_TS_GPIO);
+}
+
+struct ads7846_platform_data ads7846_config = {
+       .x_max                  = 0x0fff,
+       .y_max                  = 0x0fff,
+       .x_plate_ohms           = 180,
+       .pressure_max           = 255,
+       .debounce_max           = 10,
+       .debounce_tol           = 3,
+       .debounce_rep           = 1,
+       .get_pendown_state      = ads7846_get_pendown_state,
+       .keep_vref_on           = 1,
+       .settle_delay_usecs     = 150,
+};
+
+static struct omap2_mcspi_device_config ads7846_mcspi_config = {
+       .turbo_mode     = 0,
+       .single_channel = 1,  /* 0: slave, 1: master */
+};
+
+struct spi_board_info omap2evm_spi_board_info[] = {
+       [0] = {
+               .modalias               = "ads7846",
+               .bus_num                = 1,
+               .chip_select            = 0,
+               .max_speed_hz           = 1500000,
+               .controller_data        = &ads7846_mcspi_config,
+               .irq                    = OMAP_GPIO_IRQ(OMAP2_EVM_TS_GPIO),
+               .platform_data          = &ads7846_config,
+       },
+};
+
+
+static int omap2evm_keymap[] = {
+       KEY(0, 0, KEY_LEFT),
+       KEY(0, 1, KEY_RIGHT),
+       KEY(0, 2, KEY_A),
+       KEY(0, 3, KEY_B),
+       KEY(1, 0, KEY_DOWN),
+       KEY(1, 1, KEY_UP),
+       KEY(1, 2, KEY_E),
+       KEY(1, 3, KEY_F),
+       KEY(2, 0, KEY_ENTER),
+       KEY(2, 1, KEY_I),
+       KEY(2, 2, KEY_J),
+       KEY(2, 3, KEY_K),
+       KEY(3, 0, KEY_M),
+       KEY(3, 1, KEY_N),
+       KEY(3, 2, KEY_O),
+       KEY(3, 3, KEY_P)
+};
+
+static struct twl4030_keypad_data omap2evm_kp_data = {
+       .rows           = 4,
+       .cols           = 4,
+       .keymap         = omap2evm_keymap,
+       .keymapsize     = ARRAY_SIZE(omap2evm_keymap),
+       .rep            = 1,
+};
+
+static void __init omap2_evm_init_irq(void)
+{
+       omap2_init_common_hw(NULL);
+       omap_init_irq();
+       omap_gpio_init();
+       omap2evm_init_smc911x();
+}
+
+static struct omap_uart_config omap2_evm_uart_config __initdata = {
+       .enabled_uarts  = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_board_config_kernel omap2_evm_config[] __initdata = {
+       { OMAP_TAG_UART,        &omap2_evm_uart_config },
+       { OMAP_TAG_LCD,         &omap2_evm_lcd_config },
+};
+
+static struct twl4030_gpio_platform_data omap2evm_gpio_data = {
+       .gpio_base      = OMAP_MAX_GPIO_LINES,
+       .irq_base       = TWL4030_GPIO_IRQ_BASE,
+       .irq_end        = TWL4030_GPIO_IRQ_END,
+};
+
+static struct twl4030_usb_data omap2evm_usb_data = {
+       .usb_mode       = T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_madc_platform_data omap2evm_madc_data = {
+       .irq_line       = 1,
+};
+
+static struct twl4030_platform_data omap2evm_twldata = {
+       .irq_base       = TWL4030_IRQ_BASE,
+       .irq_end        = TWL4030_IRQ_END,
+
+       /* platform_data for children goes here */
+       .keypad         = &omap2evm_kp_data,
+       .madc           = &omap2evm_madc_data,
+       .usb            = &omap2evm_usb_data,
+       .gpio           = &omap2evm_gpio_data,
+};
+
+static struct i2c_board_info __initdata omap2evm_i2c_boardinfo[] = {
+       {
+               I2C_BOARD_INFO("twl4030", 0x48),
+               .flags = I2C_CLIENT_WAKE,
+               .irq = INT_24XX_SYS_NIRQ,
+               .platform_data = &omap2evm_twldata,
+       },
+};
+
+static int __init omap2_evm_i2c_init(void)
+{
+       omap_register_i2c_bus(1, 400, NULL, 0);
+       omap_register_i2c_bus(2, 2600, omap2evm_i2c_boardinfo,
+                       ARRAY_SIZE(omap2evm_i2c_boardinfo));
+       return 0;
+}
+
+static struct platform_device *omap2_evm_devices[] __initdata = {
+       &omap2_evm_lcd_device,
+       &omap2evm_smc911x_device,
+};
+
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+       {
+               .mmc            = 1,
+               .wires          = 4,
+               .gpio_cd        = -EINVAL,
+               .gpio_wp        = -EINVAL,
+       },
+       {}      /* Terminator */
+};
+
+static void __init omap2_evm_init(void)
+{
+       omap2_evm_i2c_init();
+
+       platform_add_devices(omap2_evm_devices, ARRAY_SIZE(omap2_evm_devices));
+       omap_board_config = omap2_evm_config;
+       omap_board_config_size = ARRAY_SIZE(omap2_evm_config);
+       spi_register_board_info(omap2evm_spi_board_info,
+                               ARRAY_SIZE(omap2evm_spi_board_info));
+       omap_serial_init();
+       twl4030_mmc_init(mmc);
+       omap2evm_flash_init();
+       ads7846_dev_init();
+}
+
+static void __init omap2_evm_map_io(void)
+{
+       omap2_set_globals_243x();
+       omap2_map_common_io();
+}
+
+MACHINE_START(OMAP2EVM, "OMAP2EVM Board")
+       /* Maintainer:  Arun KS <arunks@mistralsolutions.com> */
+       .phys_io        = 0x48000000,
+       .io_pg_offst    = ((0xd8000000) >> 18) & 0xfffc,
+       .boot_params    = 0x80000100,
+       .map_io         = omap2_evm_map_io,
+       .init_irq       = omap2_evm_init_irq,
+       .init_machine   = omap2_evm_init,
+       .timer          = &omap_timer,
+MACHINE_END
index 744740ae1b9c0424c842afe2ebba88e20f3e1d61..346351e0fe8689fa79abb23fcb371a39605e6ef2 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
 
+#include <linux/regulator/machine.h>
 #include <linux/i2c/twl4030.h>
 
 #include <mach/hardware.h>
 #include <asm/mach/flash.h>
 
 #include <mach/board.h>
+#include <mach/usb.h>
 #include <mach/common.h>
 #include <mach/gpmc.h>
 #include <mach/nand.h>
 #include <mach/mux.h>
-#include <mach/usb.h>
 
+#include "twl4030-generic-scripts.h"
 #include "mmc-twl4030.h"
 
+
 #define GPMC_CS0_BASE  0x60
 #define GPMC_CS_SIZE   0x30
 
@@ -104,10 +107,16 @@ static struct platform_device omap3beagle_nand_device = {
        .resource       = &omap3beagle_nand_resource,
 };
 
+#include "sdram-micron-mt46h32m32lf-6.h"
+
 static struct omap_uart_config omap3_beagle_uart_config __initdata = {
        .enabled_uarts  = ((1 << 0) | (1 << 1) | (1 << 2)),
 };
 
+static struct twl4030_usb_data beagle_usb_data = {
+       .usb_mode       = T2_USB_MODE_ULPI,
+};
+
 static struct twl4030_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
@@ -117,6 +126,14 @@ static struct twl4030_hsmmc_info mmc[] = {
        {}      /* Terminator */
 };
 
+static struct regulator_consumer_supply beagle_vmmc1_supply = {
+       .supply                 = "vmmc",
+};
+
+static struct regulator_consumer_supply beagle_vsim_supply = {
+       .supply                 = "vmmc_aux",
+};
+
 static struct gpio_led gpio_leds[];
 
 static int beagle_twl_gpio_setup(struct device *dev,
@@ -127,6 +144,10 @@ static int beagle_twl_gpio_setup(struct device *dev,
        mmc[0].gpio_cd = gpio + 0;
        twl4030_mmc_init(mmc);
 
+       /* link regulators to MMC adapters */
+       beagle_vmmc1_supply.dev = mmc[0].dev;
+       beagle_vsim_supply.dev = mmc[0].dev;
+
        /* REVISIT: need ehci-omap hooks for external VBUS
         * power switch and overcurrent detect
         */
@@ -155,12 +176,114 @@ static struct twl4030_gpio_platform_data beagle_gpio_data = {
        .setup          = beagle_twl_gpio_setup,
 };
 
+static struct platform_device omap3_beagle_lcd_device = {
+       .name           = "omap3beagle_lcd",
+       .id             = -1,
+};
+
+static struct regulator_consumer_supply beagle_vdac_supply = {
+       .supply         = "vdac",
+       .dev            = &omap3_beagle_lcd_device.dev,
+};
+
+static struct regulator_consumer_supply beagle_vdvi_supply = {
+       .supply         = "vdvi",
+       .dev            = &omap3_beagle_lcd_device.dev,
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data beagle_vmmc1 = {
+       .constraints = {
+               .min_uV                 = 1850000,
+               .max_uV                 = 3150000,
+               .valid_modes_mask       = REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+               .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
+                                       | REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &beagle_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data beagle_vsim = {
+       .constraints = {
+               .min_uV                 = 1800000,
+               .max_uV                 = 3000000,
+               .valid_modes_mask       = REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+               .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
+                                       | REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &beagle_vsim_supply,
+};
+
+/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
+static struct regulator_init_data beagle_vdac = {
+       .constraints = {
+               .min_uV                 = 1800000,
+               .max_uV                 = 1800000,
+               .valid_modes_mask       = REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+               .valid_ops_mask         = REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &beagle_vdac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data beagle_vpll2 = {
+       .constraints = {
+               .name                   = "VDVI",
+               .min_uV                 = 1800000,
+               .max_uV                 = 1800000,
+               .valid_modes_mask       = REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+               .valid_ops_mask         = REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &beagle_vdvi_supply,
+};
+
+static const struct twl4030_resconfig beagle_resconfig[] = {
+       /* disable regulators that u-boot left enabled; the
+        * devices' drivers should be managing these.
+        */
+       { .resource = RES_VAUX3, },     /* not even connected! */
+       { .resource = RES_VMMC1, },
+       { .resource = RES_VSIM, },
+       { .resource = RES_VPLL2, },
+       { .resource = RES_VDAC, },
+       { .resource = RES_VUSB_1V5, },
+       { .resource = RES_VUSB_1V8, },
+       { .resource = RES_VUSB_3V1, },
+       { 0, },
+};
+
+static struct twl4030_power_data beagle_power_data = {
+       .resource_config        = beagle_resconfig,
+       /* REVISIT can't use GENERIC3430_T2SCRIPTS_DATA;
+        * among other things, it makes reboot fail.
+        */
+};
+
 static struct twl4030_platform_data beagle_twldata = {
        .irq_base       = TWL4030_IRQ_BASE,
        .irq_end        = TWL4030_IRQ_END,
 
        /* platform_data for children goes here */
+       .usb            = &beagle_usb_data,
        .gpio           = &beagle_gpio_data,
+       .power          = &beagle_power_data,
+       .vmmc1          = &beagle_vmmc1,
+       .vsim           = &beagle_vsim,
+       .vdac           = &beagle_vdac,
+       .vpll2          = &beagle_vpll2,
 };
 
 static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
@@ -184,16 +307,11 @@ static int __init omap3_beagle_i2c_init(void)
 
 static void __init omap3_beagle_init_irq(void)
 {
-       omap2_init_common_hw(NULL);
+       omap2_init_common_hw(mt46h32m32lf6_sdrc_params);
        omap_init_irq();
        omap_gpio_init();
 }
 
-static struct platform_device omap3_beagle_lcd_device = {
-       .name           = "omap3beagle_lcd",
-       .id             = -1,
-};
-
 static struct omap_lcd_config omap3_beagle_lcd_config __initdata = {
        .ctrl_name      = "internal",
 };
@@ -315,6 +433,7 @@ static void __init omap3_beagle_init(void)
        gpio_direction_output(170, true);
 
        usb_musb_init();
+       usb_ehci_init();
        omap3beagle_flash_init();
 }
 
diff --git a/arch/arm/mach-omap2/board-omap3evm-flash.c b/arch/arm/mach-omap2/board-omap3evm-flash.c
new file mode 100644 (file)
index 0000000..b58b7c6
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * board-omap3evm-flash.c
+ *
+ * Copyright (c) 2008 Texas Instruments,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/onenand_regs.h>
+#include <linux/types.h>
+#include <linux/io.h>
+
+#include <asm/mach/flash.h>
+#include <mach/onenand.h>
+#include <mach/board.h>
+#include <mach/gpmc.h>
+#include <mach/nand.h>
+
+#define ONENAND_MAP            0x20000000
+
+static int omap3evm_onenand_setup(void __iomem *, int freq);
+
+static struct mtd_partition omap3evm_onenand_partitions[] = {
+       {
+               .name           = "xloader-onenand",
+               .offset         = 0,
+               .size           = 4*(64*2048),
+               .mask_flags     = MTD_WRITEABLE
+       },
+       {
+               .name           = "uboot-onenand",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           =  15*(64*2048),
+               .mask_flags     = MTD_WRITEABLE
+       },
+       {
+               .name           = "params-onenand",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 1*(64*2048),
+       },
+       {
+               .name           = "linux-onenand",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 40*(64*2048),
+       },
+       {
+               .name           = "jffs2-onenand",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct omap_onenand_platform_data omap3evm_onenand_data = {
+       .parts = omap3evm_onenand_partitions,
+       .nr_parts = ARRAY_SIZE(omap3evm_onenand_partitions),
+       .onenand_setup = omap3evm_onenand_setup,
+       .dma_channel    = -1,   /* disable DMA in OMAP OneNAND driver */
+};
+
+static struct platform_device omap3evm_onenand_device = {
+       .name           = "omap2-onenand",
+       .id             = -1,
+       .dev = {
+               .platform_data = &omap3evm_onenand_data,
+       },
+};
+
+static struct mtd_partition omap3evm_nand_partitions[] = {
+       /* All the partition sizes are listed in terms of NAND block size */
+       {
+               .name           = "xloader-nand",
+               .offset         = 0,
+               .size           = 4*(128 * 1024),
+               .mask_flags     = MTD_WRITEABLE
+       },
+       {
+               .name           = "uboot-nand",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 14*(128 * 1024),
+               .mask_flags     = MTD_WRITEABLE
+       },
+       {
+               .name           = "params-nand",
+
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 2*(128 * 1024)
+       },
+       {
+               .name           = "linux-nand",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 40*(128 * 1024)
+       },
+       {
+               .name           = "jffs2-nand",
+               .size           = MTDPART_SIZ_FULL,
+               .offset         = MTDPART_OFS_APPEND,
+       },
+};
+
+static struct omap_nand_platform_data omap3evm_nand_data = {
+       .parts          = omap3evm_nand_partitions,
+       .nr_parts       = ARRAY_SIZE(omap3evm_nand_partitions),
+       .nand_setup     = NULL,
+       .dma_channel    = -1,           /* disable DMA in OMAP NAND driver */
+       .dev_ready      = NULL,
+};
+
+static struct resource omap3evm_nand_resource = {
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device omap3evm_nand_device = {
+       .name           = "omap2-nand",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &omap3evm_nand_data,
+       },
+       .num_resources  = 1,
+       .resource       = &omap3evm_nand_resource,
+};
+
+/*
+ *      omap3evm_onenand_setup - Set the onenand sync mode
+ *      @onenand_base:  The onenand base address in GPMC memory map
+ *
+ */
+
+static int omap3evm_onenand_setup(void __iomem *onenand_base, int freq)
+{
+       /* nothing is required to be setup for onenand as of now */
+       return 0;
+}
+
+void __init omap3evm_flash_init(void)
+{
+       u8              cs = 0;
+       u8              onenandcs = GPMC_CS_NUM + 1, nandcs = GPMC_CS_NUM + 1;
+       u32             gpmc_base_add = OMAP34XX_GPMC_VIRT;
+
+       while (cs < GPMC_CS_NUM) {
+               u32 ret = 0;
+               ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+               /*
+               * xloader/Uboot would have programmed the NAND/oneNAND
+               * base address for us This is a ugly hack. The proper
+               * way of doing this is to pass the setup of u-boot up
+               * to kernel using kernel params - something on the
+               * lines of machineID. Check if NAND/oneNAND is configured
+               */
+               if ((ret & 0xC00) == 0x800) {
+                       /* Found it!! */
+                       if (nandcs > GPMC_CS_NUM)
+                               nandcs = cs;
+               } else {
+                       ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+                       if ((ret & 0x3F) == (ONENAND_MAP >> 24))
+                               onenandcs = cs;
+               }
+               cs++;
+       }
+       if ((nandcs > GPMC_CS_NUM) && (onenandcs > GPMC_CS_NUM)) {
+               printk(KERN_INFO "NAND/OneNAND: Unable to find configuration "
+                               " in GPMC\n ");
+               return;
+       }
+
+       if (nandcs < GPMC_CS_NUM) {
+               omap3evm_nand_data.cs   = nandcs;
+               omap3evm_nand_data.gpmc_cs_baseaddr = (void *)(gpmc_base_add +
+                                       GPMC_CS0_BASE + nandcs*GPMC_CS_SIZE);
+               omap3evm_nand_data.gpmc_baseaddr   = (void *) (gpmc_base_add);
+
+               if (platform_device_register(&omap3evm_nand_device) < 0) {
+                       printk(KERN_ERR "Unable to register NAND device\n");
+               }
+       }
+
+       if (onenandcs < GPMC_CS_NUM) {
+               omap3evm_onenand_data.cs = onenandcs;
+               if (platform_device_register(&omap3evm_onenand_device) < 0)
+                       printk(KERN_ERR "Unable to register OneNAND device\n");
+       }
+}
+
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
new file mode 100644 (file)
index 0000000..6eb3c52
--- /dev/null
@@ -0,0 +1,333 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3evm.c
+ *
+ * Copyright (C) 2008 Texas Instruments
+ *
+ * Modified from mach-omap2/board-3430sdp.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/i2c/twl4030.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/mux.h>
+#include <mach/usb.h>
+#include <mach/common.h>
+#include <mach/mcspi.h>
+
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "twl4030-generic-scripts.h"
+#include "mmc-twl4030.h"
+
+#define OMAP3_EVM_TS_GPIO      175
+
+#define OMAP3EVM_ETHR_START    0x2c000000
+#define OMAP3EVM_ETHR_SIZE     1024
+#define OMAP3EVM_ETHR_GPIO_IRQ 176
+#define OMAP3EVM_SMC911X_CS    5
+
+extern void omap3evm_flash_init(void);
+
+static struct resource omap3evm_smc911x_resources[] = {
+       [0] =   {
+               .start  = OMAP3EVM_ETHR_START,
+               .end    = (OMAP3EVM_ETHR_START + OMAP3EVM_ETHR_SIZE - 1),
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] =   {
+               .start  = OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ),
+               .end    = OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device omap3evm_smc911x_device = {
+       .name           = "smc911x",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(omap3evm_smc911x_resources),
+       .resource       = &omap3evm_smc911x_resources [0],
+};
+
+static inline void __init omap3evm_init_smc911x(void)
+{
+       int eth_cs;
+       struct clk *l3ck;
+       unsigned int rate;
+
+       eth_cs = OMAP3EVM_SMC911X_CS;
+
+       l3ck = clk_get(NULL, "l3_ck");
+       if (IS_ERR(l3ck))
+               rate = 100000000;
+       else
+               rate = clk_get_rate(l3ck);
+
+       if (gpio_request(OMAP3EVM_ETHR_GPIO_IRQ, "SMC911x irq") < 0) {
+               printk(KERN_ERR "Failed to request GPIO%d for smc911x IRQ\n",
+                       OMAP3EVM_ETHR_GPIO_IRQ);
+               return;
+       }
+
+       gpio_direction_input(OMAP3EVM_ETHR_GPIO_IRQ);
+}
+
+static struct omap_uart_config omap3_evm_uart_config __initdata = {
+       .enabled_uarts  = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct twl4030_hsmmc_info mmc[] = {
+       {
+               .mmc            = 1,
+               .wires          = 4,
+               .gpio_cd        = -EINVAL,
+               .gpio_wp        = 63,
+       },
+       {}      /* Terminator */
+};
+
+static struct gpio_led gpio_leds[] = {
+       {
+               .name                   = "omap3evm::ledb",
+               /* normally not visible (board underside) */
+               .default_trigger        = "default-on",
+               .gpio                   = -EINVAL,      /* gets replaced */
+               .active_low             = true,
+       },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+       .leds           = gpio_leds,
+       .num_leds       = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &gpio_led_info,
+       },
+};
+
+
+static int omap3evm_twl_gpio_setup(struct device *dev,
+               unsigned gpio, unsigned ngpio)
+{
+       /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+       omap_cfg_reg(L8_34XX_GPIO63);
+       mmc[0].gpio_cd = gpio + 0;
+       twl4030_mmc_init(mmc);
+
+       /* Most GPIOs are for USB OTG.  Some are mostly sent to
+        * the P2 connector; notably LEDA for the LCD backlight.
+        */
+
+       /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
+       gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+       platform_device_register(&leds_gpio);
+
+       return 0;
+}
+
+static struct twl4030_gpio_platform_data omap3evm_gpio_data = {
+       .gpio_base      = OMAP_MAX_GPIO_LINES,
+       .irq_base       = TWL4030_GPIO_IRQ_BASE,
+       .irq_end        = TWL4030_GPIO_IRQ_END,
+       .use_leds       = true,
+       .setup          = omap3evm_twl_gpio_setup,
+};
+
+static struct twl4030_usb_data omap3evm_usb_data = {
+       .usb_mode       = T2_USB_MODE_ULPI,
+};
+
+static int omap3evm_keymap[] = {
+       KEY(0, 0, KEY_LEFT),
+       KEY(0, 1, KEY_RIGHT),
+       KEY(0, 2, KEY_A),
+       KEY(0, 3, KEY_B),
+       KEY(1, 0, KEY_DOWN),
+       KEY(1, 1, KEY_UP),
+       KEY(1, 2, KEY_E),
+       KEY(1, 3, KEY_F),
+       KEY(2, 0, KEY_ENTER),
+       KEY(2, 1, KEY_I),
+       KEY(2, 2, KEY_J),
+       KEY(2, 3, KEY_K),
+       KEY(3, 0, KEY_M),
+       KEY(3, 1, KEY_N),
+       KEY(3, 2, KEY_O),
+       KEY(3, 3, KEY_P)
+};
+
+static struct twl4030_keypad_data omap3evm_kp_data = {
+       .rows           = 4,
+       .cols           = 4,
+       .keymap         = omap3evm_keymap,
+       .keymapsize     = ARRAY_SIZE(omap3evm_keymap),
+       .rep            = 1,
+};
+
+static struct twl4030_madc_platform_data omap3evm_madc_data = {
+       .irq_line       = 1,
+};
+
+static struct twl4030_platform_data omap3evm_twldata = {
+       .irq_base       = TWL4030_IRQ_BASE,
+       .irq_end        = TWL4030_IRQ_END,
+
+       /* platform_data for children goes here */
+       .keypad         = &omap3evm_kp_data,
+       .madc           = &omap3evm_madc_data,
+       .usb            = &omap3evm_usb_data,
+       .power          = GENERIC3430_T2SCRIPTS_DATA,
+       .gpio           = &omap3evm_gpio_data,
+};
+
+static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = {
+       {
+               I2C_BOARD_INFO("twl4030", 0x48),
+               .flags = I2C_CLIENT_WAKE,
+               .irq = INT_34XX_SYS_NIRQ,
+               .platform_data = &omap3evm_twldata,
+       },
+};
+
+static int __init omap3_evm_i2c_init(void)
+{
+       omap_register_i2c_bus(1, 2600, omap3evm_i2c_boardinfo,
+                       ARRAY_SIZE(omap3evm_i2c_boardinfo));
+       omap_register_i2c_bus(2, 400, NULL, 0);
+       omap_register_i2c_bus(3, 400, NULL, 0);
+       return 0;
+}
+
+static struct platform_device omap3_evm_lcd_device = {
+       .name           = "omap3evm_lcd",
+       .id             = -1,
+};
+
+static struct omap_lcd_config omap3_evm_lcd_config __initdata = {
+       .ctrl_name      = "internal",
+};
+
+static void ads7846_dev_init(void)
+{
+       if (gpio_request(OMAP3_EVM_TS_GPIO, "ADS7846 pendown") < 0)
+               printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
+
+       gpio_direction_input(OMAP3_EVM_TS_GPIO);
+
+       omap_set_gpio_debounce(OMAP3_EVM_TS_GPIO, 1);
+       omap_set_gpio_debounce_time(OMAP3_EVM_TS_GPIO, 0xa);
+}
+
+static int ads7846_get_pendown_state(void)
+{
+       return !gpio_get_value(OMAP3_EVM_TS_GPIO);
+}
+
+struct ads7846_platform_data ads7846_config = {
+       .x_max                  = 0x0fff,
+       .y_max                  = 0x0fff,
+       .x_plate_ohms           = 180,
+       .pressure_max           = 255,
+       .debounce_max           = 10,
+       .debounce_tol           = 3,
+       .debounce_rep           = 1,
+       .get_pendown_state      = ads7846_get_pendown_state,
+       .keep_vref_on           = 1,
+       .settle_delay_usecs     = 150,
+};
+
+static struct omap2_mcspi_device_config ads7846_mcspi_config = {
+       .turbo_mode     = 0,
+       .single_channel = 1,  /* 0: slave, 1: master */
+};
+
+struct spi_board_info omap3evm_spi_board_info[] = {
+       [0] = {
+               .modalias               = "ads7846",
+               .bus_num                = 1,
+               .chip_select            = 0,
+               .max_speed_hz           = 1500000,
+               .controller_data        = &ads7846_mcspi_config,
+               .irq                    = OMAP_GPIO_IRQ(OMAP3_EVM_TS_GPIO),
+               .platform_data          = &ads7846_config,
+       },
+};
+
+static void __init omap3_evm_init_irq(void)
+{
+       omap2_init_common_hw(mt46h32m32lf6_sdrc_params);
+       omap_init_irq();
+       omap_gpio_init();
+       omap3evm_init_smc911x();
+}
+
+static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
+       { OMAP_TAG_UART,        &omap3_evm_uart_config },
+       { OMAP_TAG_LCD,         &omap3_evm_lcd_config },
+};
+
+static struct platform_device *omap3_evm_devices[] __initdata = {
+       &omap3_evm_lcd_device,
+       &omap3evm_smc911x_device,
+};
+
+static void __init omap3_evm_init(void)
+{
+       omap3_evm_i2c_init();
+
+       platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices));
+       omap_board_config = omap3_evm_config;
+       omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
+
+       spi_register_board_info(omap3evm_spi_board_info,
+                               ARRAY_SIZE(omap3evm_spi_board_info));
+
+       omap_serial_init();
+       usb_musb_init();
+       usb_ehci_init();
+       omap3evm_flash_init();
+       ads7846_dev_init();
+}
+
+static void __init omap3_evm_map_io(void)
+{
+       omap2_set_globals_343x();
+       omap2_map_common_io();
+}
+
+MACHINE_START(OMAP3EVM, "OMAP3 EVM")
+       /* Maintainer: Syed Mohammed Khasim - Texas Instruments */
+       .phys_io        = 0x48000000,
+       .io_pg_offst    = ((0xd8000000) >> 18) & 0xfffc,
+       .boot_params    = 0x80000100,
+       .map_io         = omap3_evm_map_io,
+       .init_irq       = omap3_evm_init_irq,
+       .init_machine   = omap3_evm_init,
+       .timer          = &omap_timer,
+MACHINE_END
index 402f09c6cf1011da8ccd291b62decf5606b6f402..c67f62ff8850976a9da45820f6ed19493323b0ae 100644 (file)
  *
  */
 
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 
 #include <linux/spi/ads7846.h>
 #include <linux/i2c/twl4030.h>
 
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
 #include <mach/board.h>
 #include <mach/common.h>
 #include <mach/gpio.h>
+#include <mach/gpmc.h>
 #include <mach/hardware.h>
-#include <mach/mcspi.h>
+#include <mach/nand.h>
 #include <mach/usb.h>
+#include <mach/mcspi.h>
 
+#include "sdram-micron-mt46h32m32lf-6.h"
 #include "mmc-twl4030.h"
 
+
+#define NAND_BLOCK_SIZE                        SZ_128K
+#define GPMC_CS0_BASE                  0x60
+#define GPMC_CS_SIZE                   0x30
+
 #define OMAP3_PANDORA_TS_GPIO          94
 
+static struct mtd_partition omap3pandora_nand_partitions[] = {
+       {
+               .name           = "xloader",
+               .offset         = 0,                    /* Offset = 0x00000 */
+               .size           = 4 * NAND_BLOCK_SIZE,
+               .mask_flags     = MTD_WRITEABLE
+       }, {
+               .name           = "uboot",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x80000 */
+               .size           = 14 * NAND_BLOCK_SIZE,
+       }, {
+               .name           = "uboot environment",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x240000 */
+               .size           = 2 * NAND_BLOCK_SIZE,
+       }, {
+               .name           = "linux",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x280000 */
+               .size           = 32 * NAND_BLOCK_SIZE,
+       }, {
+               .name           = "rootfs",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x680000 */
+               .size           = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct omap_nand_platform_data omap3pandora_nand_data = {
+       .parts          = omap3pandora_nand_partitions,
+       .nr_parts       = ARRAY_SIZE(omap3pandora_nand_partitions),
+       .dma_channel    = -1,   /* disable DMA in OMAP NAND driver */
+};
+
+static struct resource omap3pandora_nand_resource[] = {
+       {
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device omap3pandora_nand_device = {
+       .name           = "omap2-nand",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &omap3pandora_nand_data,
+       },
+       .num_resources  = ARRAY_SIZE(omap3pandora_nand_resource),
+       .resource       = omap3pandora_nand_resource,
+};
+
+static void __init omap3pandora_flash_init(void)
+{
+       u8 cs = 0;
+       u8 nandcs = GPMC_CS_NUM + 1;
+
+       u32 gpmc_base_add = OMAP34XX_GPMC_VIRT;
+
+       /* find out the chip-select on which NAND exists */
+       while (cs < GPMC_CS_NUM) {
+               u32 ret = 0;
+               ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+               if ((ret & 0xC00) == 0x800) {
+                       printk(KERN_INFO "Found NAND on CS%d\n", cs);
+                       if (nandcs > GPMC_CS_NUM)
+                               nandcs = cs;
+               }
+               cs++;
+       }
+
+       if (nandcs > GPMC_CS_NUM) {
+               printk(KERN_INFO "NAND: Unable to find configuration "
+                                "in GPMC\n ");
+               return;
+       }
+
+       if (nandcs < GPMC_CS_NUM) {
+               omap3pandora_nand_data.cs = nandcs;
+               omap3pandora_nand_data.gpmc_cs_baseaddr = (void *)
+                       (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE);
+               omap3pandora_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add);
+
+               printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
+               if (platform_device_register(&omap3pandora_nand_device) < 0)
+                       printk(KERN_ERR "Unable to register NAND device\n");
+       }
+}
+
 static struct twl4030_hsmmc_info omap3pandora_mmc[] = {
        {
                .mmc            = 1,
@@ -118,7 +220,7 @@ static int __init omap3pandora_i2c_init(void)
 
 static void __init omap3pandora_init_irq(void)
 {
-       omap2_init_common_hw(NULL);
+       omap2_init_common_hw(mt46h32m32lf6_sdrc_params);
        omap_init_irq();
        omap_gpio_init();
 }
@@ -200,8 +302,10 @@ static void __init omap3pandora_init(void)
        omap_serial_init();
        spi_register_board_info(omap3pandora_spi_board_info,
                        ARRAY_SIZE(omap3pandora_spi_board_info));
-       omap3pandora_ads7846_init();
        usb_musb_init();
+       usb_ehci_init();
+       omap3pandora_flash_init();
+       omap3pandora_ads7846_init();
 }
 
 static void __init omap3pandora_map_io(void)
index b3f6e9d81807c9197c4b9d63ef52891f82c90844..f9cc015d36d869b3c84f3a46a6cbeaaffff216dc 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/i2c/twl4030.h>
+#include <linux/regulator/machine.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
@@ -45,6 +46,8 @@
 #include <mach/nand.h>
 #include <mach/usb.h>
 
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "twl4030-generic-scripts.h"
 #include "mmc-twl4030.h"
 
 #define OVERO_GPIO_BT_XGATE    15
 #define GPMC_CS0_BASE  0x60
 #define GPMC_CS_SIZE   0x30
 
+#define OVERO_SMSC911X_CS      5
+#define OVERO_SMSC911X_GPIO    176
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+
+#include <linux/smsc911x.h>
+
+static struct resource overo_smsc911x_resources[] = {
+       {
+               .name   = "smsc911x-memory",
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+       },
+};
+
+static struct smsc911x_platform_config overo_smsc911x_config = {
+       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+       .irq_type       = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+       .flags          = SMSC911X_USE_32BIT ,
+       .phy_interface  = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device overo_smsc911x_device = {
+       .name           = "smsc911x",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(overo_smsc911x_resources),
+       .resource       = &overo_smsc911x_resources,
+       .dev            = {
+               .platform_data = &overo_smsc911x_config,
+       },
+};
+
+static inline void __init overo_init_smsc911x(void)
+{
+       unsigned long cs_mem_base;
+
+       if (gpmc_cs_request(OVERO_SMSC911X_CS, SZ_16M, &cs_mem_base) < 0) {
+               printk(KERN_ERR "Failed request for GPMC mem for smsc911x\n");
+               return;
+       }
+
+       overo_smsc911x_resources[0].start = cs_mem_base + 0x0;
+       overo_smsc911x_resources[0].end   = cs_mem_base + 0xff;
+
+       if ((gpio_request(OVERO_SMSC911X_GPIO, "SMSC911X IRQ") == 0) &&
+           (gpio_direction_input(OVERO_SMSC911X_GPIO) == 0)) {
+               gpio_export(OVERO_SMSC911X_GPIO, 0);
+       } else {
+               printk(KERN_ERR "could not obtain gpio for SMSC911X IRQ\n");
+               return;
+       }
+
+       overo_smsc911x_resources[1].start = OMAP_GPIO_IRQ(OVERO_SMSC911X_GPIO);
+       overo_smsc911x_resources[1].end   = 0;
+
+       platform_device_register(&overo_smsc911x_device);
+}
+
+#else
+static inline void __init overo_init_smsc911x(void) { return; }
+#endif
+
 #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
        defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
 
@@ -69,6 +136,7 @@ static struct omap2_mcspi_device_config ads7846_mcspi_config = {
        .single_channel = 1,    /* 0: slave, 1: master */
 };
 
+
 static int ads7846_get_pendown_state(void)
 {
        return !gpio_get_value(OVERO_GPIO_PENDOWN);
@@ -207,21 +275,77 @@ static struct omap_uart_config overo_uart_config __initdata = {
        .enabled_uarts  = ((1 << 0) | (1 << 1) | (1 << 2)),
 };
 
+static struct twl4030_hsmmc_info mmc[] = {
+       {
+               .mmc            = 1,
+               .wires          = 4,
+               .gpio_cd        = -EINVAL,
+               .gpio_wp        = -EINVAL,
+       },
+       {
+               .mmc            = 2,
+               .wires          = 4,
+               .gpio_cd        = -EINVAL,
+               .gpio_wp        = -EINVAL,
+               .transceiver    = true,
+               .ocr_mask       = 0x00100000,   /* 3.3V */
+       },
+       {}      /* Terminator */
+};
+
+static struct regulator_consumer_supply overo_vmmc1_supply = {
+       .supply                 = "vmmc",
+};
+
+static int overo_twl_gpio_setup(struct device *dev,
+               unsigned gpio, unsigned ngpio)
+{
+       twl4030_mmc_init(mmc);
+
+       overo_vmmc1_supply.dev = mmc[0].dev;
+
+       return 0;
+}
+
 static struct twl4030_gpio_platform_data overo_gpio_data = {
        .gpio_base      = OMAP_MAX_GPIO_LINES,
        .irq_base       = TWL4030_GPIO_IRQ_BASE,
        .irq_end        = TWL4030_GPIO_IRQ_END,
+       .setup          = overo_twl_gpio_setup,
+};
+
+static struct twl4030_usb_data overo_usb_data = {
+       .usb_mode       = T2_USB_MODE_ULPI,
+};
+
+static struct regulator_init_data overo_vmmc1 = {
+       .constraints = {
+               .min_uV                 = 1850000,
+               .max_uV                 = 3150000,
+               .valid_modes_mask       = REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+               .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
+                                       | REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &overo_vmmc1_supply,
 };
 
+/* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */
+
 static struct twl4030_platform_data overo_twldata = {
        .irq_base       = TWL4030_IRQ_BASE,
        .irq_end        = TWL4030_IRQ_END,
        .gpio           = &overo_gpio_data,
+       .usb            = &overo_usb_data,
+       .power          = GENERIC3430_T2SCRIPTS_DATA,
+       .vmmc1          = &overo_vmmc1,
 };
 
 static struct i2c_board_info __initdata overo_i2c_boardinfo[] = {
        {
-               I2C_BOARD_INFO("twl4030", 0x48),
+               I2C_BOARD_INFO("tps65950", 0x48),
                .flags = I2C_CLIENT_WAKE,
                .irq = INT_34XX_SYS_NIRQ,
                .platform_data = &overo_twldata,
@@ -239,7 +363,7 @@ static int __init overo_i2c_init(void)
 
 static void __init overo_init_irq(void)
 {
-       omap2_init_common_hw(NULL);
+       omap2_init_common_hw(mt46h32m32lf6_sdrc_params);
        omap_init_irq();
        omap_gpio_init();
 }
@@ -262,23 +386,6 @@ static struct platform_device *overo_devices[] __initdata = {
        &overo_lcd_device,
 };
 
-static struct twl4030_hsmmc_info mmc[] __initdata = {
-       {
-               .mmc            = 1,
-               .wires          = 4,
-               .gpio_cd        = -EINVAL,
-               .gpio_wp        = -EINVAL,
-       },
-       {
-               .mmc            = 2,
-               .wires          = 4,
-               .gpio_cd        = -EINVAL,
-               .gpio_wp        = -EINVAL,
-               .transceiver    = true,
-       },
-       {}      /* Terminator */
-};
-
 static void __init overo_init(void)
 {
        overo_i2c_init();
@@ -286,9 +393,10 @@ static void __init overo_init(void)
        omap_board_config = overo_config;
        omap_board_config_size = ARRAY_SIZE(overo_config);
        omap_serial_init();
-       twl4030_mmc_init(mmc);
-       overo_flash_init();
        usb_musb_init();
+       usb_ehci_init();
+       overo_flash_init();
+       overo_init_smsc911x();
        overo_ads7846_init();
 
        if ((gpio_request(OVERO_GPIO_W2W_NRESET,
diff --git a/arch/arm/mach-omap2/board-rx51-flash.c b/arch/arm/mach-omap2/board-rx51-flash.c
new file mode 100644 (file)
index 0000000..f3b7eaf
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * linux/arch/arm/mach-omap2/board-rx51-flash.c
+ *
+ * Copyright (C) 2008 Nokia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <mach/board-rx51.h>
+
+extern void __init n800_flash_init(void);
+
+void __init rx51_flash_init(void)
+{
+       n800_flash_init();
+}
+
index a7381729645cf5c4deeaf23e895c21ee1306b613..22183aff1669fafb32d5f6a0dd5da8c42c208997 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/input.h>
 #include <linux/spi/spi.h>
+#include <linux/spi/tsc2005.h>
 #include <linux/i2c.h>
 #include <linux/i2c/twl4030.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/regulator/machine.h>
-#include <linux/gpio.h>
 
 #include <mach/mcspi.h>
+#include <mach/gpio.h>
 #include <mach/mux.h>
 #include <mach/board.h>
 #include <mach/common.h>
 #include <mach/dma.h>
 #include <mach/gpmc.h>
-#include <mach/keypad.h>
 
 #include "mmc-twl4030.h"
 
+#define SYSTEM_REV_B_USES_VAUX3 0x1699
+#define SYSTEM_REV_S_USES_VAUX3 0x8
 
 #define SMC91X_CS                      1
 #define SMC91X_GPIO_IRQ                        54
 #define SMC91X_GPIO_RESET              164
 #define SMC91X_GPIO_PWRDWN             86
 
+#define RX51_TSC2005_RESET_GPIO                104
+#define RX51_TSC2005_IRQ_GPIO          100
+
 static struct resource rx51_smc91x_resources[] = {
        [0] = {
                .flags          = IORESOURCE_MEM,
@@ -52,6 +57,38 @@ static struct platform_device rx51_smc91x_device = {
        .resource       = rx51_smc91x_resources,
 };
 
+static struct tsc2005_platform_data tsc2005_config = {
+       .reset_gpio             = RX51_TSC2005_RESET_GPIO, /* not used */
+
+       .ts_x_plate_ohm         = 280,
+       .ts_hw_avg              = 0,
+       .ts_touch_pressure      = 1500,
+       .ts_stab_time           = 1000,
+       .ts_pressure_max        = 2048,
+       .ts_pressure_fudge      = 2,
+       .ts_x_max               = 4096,
+       .ts_x_fudge             = 4,
+       .ts_y_max               = 4096,
+       .ts_y_fudge             = 7,
+};
+
+static struct omap2_mcspi_device_config tsc2005_mcspi_config = {
+       .turbo_mode     = 0,
+       .single_channel = 1,
+};
+
+static struct spi_board_info rx51_peripherals_spi_board_info[] = {
+       [0] = {
+               .modalias               = "tsc2005",
+               .bus_num                = 1,
+               .chip_select            = 0,
+               .irq                    = OMAP_GPIO_IRQ(RX51_TSC2005_IRQ_GPIO),
+               .max_speed_hz           = 6000000,
+               .controller_data        = &tsc2005_mcspi_config,
+               .platform_data          = &tsc2005_config,
+       },
+};
+
 static int rx51_keymap[] = {
        KEY(0, 0, KEY_Q),
        KEY(0, 1, KEY_W),
@@ -199,6 +236,18 @@ free1:
        printk(KERN_ERR "Could not initialize smc91x\n");
 }
 
+static void __init rx51_init_tsc2005(void)
+{
+       int r;
+
+       r = gpio_request(RX51_TSC2005_IRQ_GPIO, "tsc2005 DAV IRQ");
+       if (r >= 0) {
+               gpio_direction_input(RX51_TSC2005_IRQ_GPIO);
+       } else {
+               printk(KERN_ERR "unable to get DAV GPIO");
+       }
+}
+
 static struct twl4030_madc_platform_data rx51_madc_data = {
        .irq_line               = 1,
 };
@@ -259,7 +308,7 @@ static struct regulator_init_data rx51_vaux2 = {
 };
 
 /* VAUX3 - adds more power to VIO_18 rail */
-static struct regulator_init_data rx51_vaux3 = {
+static struct regulator_init_data rx51_vaux3_cam = {
        .constraints = {
                .name                   = "VCAM_DIG_18",
                .min_uV                 = 1800000,
@@ -272,6 +321,22 @@ static struct regulator_init_data rx51_vaux3 = {
        },
 };
 
+static struct regulator_init_data rx51_vaux3_mmc = {
+       .constraints = {
+               .name                   = "VMMC2_30",
+               .min_uV                 = 2800000,
+               .max_uV                 = 3000000,
+               .apply_uV               = true,
+               .valid_modes_mask       = REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+               .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
+                                       | REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &rx51_vmmc2_supply,
+};
+
 static struct regulator_init_data rx51_vaux4 = {
        .constraints = {
                .name                   = "VCAM_ANA_28",
@@ -382,10 +447,8 @@ static struct twl4030_platform_data rx51_twldata = {
 
        .vaux1                  = &rx51_vaux1,
        .vaux2                  = &rx51_vaux2,
-       .vaux3                  = &rx51_vaux3,
        .vaux4                  = &rx51_vaux4,
        .vmmc1                  = &rx51_vmmc1,
-       .vmmc2                  = &rx51_vmmc2,
        .vsim                   = &rx51_vsim,
        .vdac                   = &rx51_vdac,
 };
@@ -401,6 +464,13 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = {
 
 static int __init rx51_i2c_init(void)
 {
+       if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) ||
+           system_rev >= SYSTEM_REV_B_USES_VAUX3)
+               rx51_twldata.vaux3 = &rx51_vaux3_mmc;
+       else {
+               rx51_twldata.vaux3 = &rx51_vaux3_cam;
+               rx51_twldata.vmmc2 = &rx51_vmmc2;
+       }
        omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1,
                        ARRAY_SIZE(rx51_peripherals_i2c_board_info_1));
        omap_register_i2c_bus(2, 100, NULL, 0);
@@ -413,7 +483,10 @@ void __init rx51_peripherals_init(void)
 {
        platform_add_devices(rx51_peripherals_devices,
                                ARRAY_SIZE(rx51_peripherals_devices));
+       spi_register_board_info(rx51_peripherals_spi_board_info,
+                               ARRAY_SIZE(rx51_peripherals_spi_board_info));
        rx51_i2c_init();
        rx51_init_smc91x();
+       rx51_init_tsc2005();
 }
 
diff --git a/arch/arm/mach-omap2/board-rx51-sdram.c b/arch/arm/mach-omap2/board-rx51-sdram.c
new file mode 100644 (file)
index 0000000..32b5da4
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * SDRC register values for the Samsung K4X1G323PC
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Lauri Leukkunen <lauri.leukkunen@nokia.com>
+ *
+ * Original code by Juha Yrjölä <juha.yrjola@solidboot.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/io.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+#include <mach/sdrc.h>
+
+
+/* In picoseconds, except for tREF */
+struct sdram_timings {
+       u32 casl;
+       u32 tDAL;
+       u32 tDPL;
+       u32 tRRD;
+       u32 tRCD;
+       u32 tRP;
+       u32 tRAS;
+       u32 tRC;
+       u32 tRFC;
+       u32 tXSR;
+
+       u32 tREF; /* in ms */
+};
+
+struct sdram_info {
+       u8 row_lines;
+};
+
+
+struct omap_sdrc_params rx51_sdrc_params[2];
+
+static const struct sdram_timings rx51_timings[] = {
+       {
+               .casl = 3,
+               .tDAL = 15000 + 18000,
+               .tDPL = 15000,
+               .tRRD = 12000,
+               .tRCD = 18000,
+               .tRP = 18000,
+               .tRAS = 42000,
+               .tRC = 66000,
+               .tRFC = 97500,
+               .tXSR = 120000,
+
+               .tREF = 64,
+       },
+};
+
+static const struct sdram_info rx51_info = {
+       .row_lines = 13,
+};
+
+#define CM_BASE                    0x48004000
+
+#define CM_CLKSEL_CORE      0x0a40
+#define CM_CLKSEL1_PLL      0x0d40
+
+#define PRM_CLKSEL          0x48306d40
+#define PRM_CLKSRC_CTRL     0x48307270
+
+static u32 cm_base = CM_BASE;
+
+static inline u32 cm_read_reg(int idx)
+{
+       return *(u32 *)OMAP2_IO_ADDRESS(cm_base + idx);
+}
+
+static const unsigned long sys_clk_rate_table[] = {
+       12000, 13000, 19200, 26000, 38400, 16800
+};
+
+static unsigned long get_sys_clk_rate(void)
+{
+       unsigned long rate;
+
+       rate = sys_clk_rate_table[*(u32 *)OMAP2_IO_ADDRESS(PRM_CLKSEL) & 0x07];
+       if (((*(u32 *)OMAP2_IO_ADDRESS(PRM_CLKSRC_CTRL) >> 6) & 0x03) == 0x02)
+               rate /= 2;
+       return rate;
+}
+
+static unsigned long get_core_rate(void)
+{
+       unsigned long rate;
+       u32 l;
+
+       l = cm_read_reg(CM_CLKSEL1_PLL);
+       rate = get_sys_clk_rate();
+       rate *= ((l >> 16) & 0x7ff);
+       rate /= ((l >> 8) & 0x7f) + 1;
+       rate /= (l >> 27) & 0x1f;
+
+       return rate;
+}
+
+static unsigned long get_l3_rate(void)
+{
+       u32 l;
+
+       l = cm_read_reg(CM_CLKSEL_CORE);
+       return get_core_rate() / (l & 0x03);
+}
+
+
+
+static unsigned long sdrc_get_fclk_period(void)
+{
+       /* In picoseconds */
+       return 1000000000 / get_l3_rate();
+}
+
+static unsigned int sdrc_ps_to_ticks(unsigned int time_ps)
+{
+       unsigned long tick_ps;
+
+       /* Calculate in picosecs to yield more exact results */
+       tick_ps = sdrc_get_fclk_period();
+
+       return (time_ps + tick_ps - 1) / tick_ps;
+}
+#undef DEBUG
+#ifdef DEBUG
+static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit,
+                              int time, const char *name)
+#else
+static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit,
+                              int time)
+#endif
+{
+       int ticks, mask, nr_bits;
+
+       if (time == 0)
+               ticks = 0;
+       else
+               ticks = sdrc_ps_to_ticks(time);
+       nr_bits = end_bit - st_bit + 1;
+       if (ticks >= 1 << nr_bits)
+               return -1;
+       mask = (1 << nr_bits) - 1;
+       *regval &= ~(mask << st_bit);
+       *regval |= ticks << st_bit;
+#ifdef DEBUG
+       printk("SDRC %s: %i ticks %i ns\n", name, ticks,
+                       (unsigned int)sdrc_get_fclk_period() * ticks / 1000);
+#endif
+
+       return 0;
+}
+
+#ifdef DEBUG
+#define SDRC_SET_ONE(reg, st, end, field) \
+       if (set_sdrc_timing_regval((reg), (st), (end), rx51_timings->field, #field) < 0) \
+               err = -1
+#else
+#define SDRC_SET_ONE(reg, st, end, field) \
+       if (set_sdrc_timing_regval((reg), (st), (end), rx51_timings->field) < 0) \
+               err = -1
+#endif
+
+struct omap_sdrc_params *rx51_get_sdram_timings(void)
+{
+       u32 ticks_per_ms;
+       u32 rfr, l;
+       u32 actim_ctrla, actim_ctrlb;
+       u32 rfr_ctrl;
+       int err = 0;
+
+       SDRC_SET_ONE(&actim_ctrla,  0,  4, tDAL);
+       SDRC_SET_ONE(&actim_ctrla,  6,  8, tDPL);
+       SDRC_SET_ONE(&actim_ctrla,  9, 11, tRRD);
+       SDRC_SET_ONE(&actim_ctrla, 12, 14, tRCD);
+       SDRC_SET_ONE(&actim_ctrla, 15, 17, tRP);
+       SDRC_SET_ONE(&actim_ctrla, 18, 21, tRAS);
+       SDRC_SET_ONE(&actim_ctrla, 22, 26, tRC);
+       SDRC_SET_ONE(&actim_ctrla, 27, 31, tRFC);
+
+       SDRC_SET_ONE(&actim_ctrlb,  0,  7, tXSR);
+
+       ticks_per_ms = sdrc_ps_to_ticks(1000000000);
+       rfr = rx51_timings[0].tREF * ticks_per_ms / (1 << rx51_info.row_lines);
+       if (rfr > 65535 + 50)
+               rfr = 65535;
+       else
+               rfr -= 50;
+
+       l = rfr << 8;
+       rfr_ctrl = l | 0x3; /* autorefresh, reload counter with 8xARCV */
+
+       rx51_sdrc_params[0].rate = 133333333;
+       rx51_sdrc_params[0].actim_ctrla = actim_ctrla;
+       rx51_sdrc_params[0].actim_ctrlb = actim_ctrlb;
+       rx51_sdrc_params[0].rfr_ctrl = rfr_ctrl;
+       rx51_sdrc_params[0].mr = 0x32;
+
+       rx51_sdrc_params[1].rate = 0;
+
+       if (err < 0)
+               return NULL;
+
+       return &rx51_sdrc_params[0];
+}
+
diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c
new file mode 100644 (file)
index 0000000..6ebdc82
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * linux/arch/arm/mach-omap2/board-rx51-video.c
+ *
+ * Copyright (C) 2008 Nokia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+
+#include <mach/lcd_mipid.h>
+#include <mach/mcspi.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+
+
+static struct omap2_mcspi_device_config mipid_mcspi_config = {
+       .turbo_mode     = 0,
+       .single_channel = 1,
+};
+
+static struct platform_device rx51_lcd_device = {
+       .name           = "lcd_mipid",
+       .id             = -1,
+};
+
+static void mipid_shutdown(struct mipid_platform_data *pdata)
+{
+       if (pdata->nreset_gpio != -1) {
+               pr_info("shutdown LCD\n");
+               gpio_direction_output(pdata->nreset_gpio, 0);
+               msleep(120);
+       }
+}
+
+static struct mipid_platform_data rx51_mipid_platform_data = {
+       .shutdown = mipid_shutdown,
+};
+
+static void __init mipid_dev_init(void)
+{
+       const struct omap_lcd_config *conf;
+
+       conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
+       if (conf != NULL) {
+               rx51_mipid_platform_data.nreset_gpio = conf->nreset_gpio;
+               rx51_mipid_platform_data.data_lines = conf->data_lines;
+       }
+}
+
+static struct spi_board_info rx51_video_spi_board_info[] = {
+       [0] = {
+               .modalias               = "lcd_mipid",
+               .bus_num                = 1,
+               .chip_select            = 2,
+               .max_speed_hz           = 6000000,
+               .controller_data        = &mipid_mcspi_config,
+               .platform_data          = &rx51_mipid_platform_data,
+       },
+};
+
+static struct platform_device *rx51_video_devices[] = {
+       &rx51_lcd_device,
+};
+
+void __init rx51_video_init(void)
+{
+       platform_add_devices(rx51_video_devices, ARRAY_SIZE(rx51_video_devices));
+       spi_register_board_info(rx51_video_spi_board_info,
+                       ARRAY_SIZE(rx51_video_spi_board_info));
+       mipid_dev_init();
+}
+
index 3a0daac6c8396740e10eca560514989c902596a6..768f507a569fb822e9d59cc7da6d43581d1eb298 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/delay.h>
-#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -24,6 +23,7 @@
 #include <asm/mach/map.h>
 
 #include <mach/mcspi.h>
+#include <mach/gpio.h>
 #include <mach/mux.h>
 #include <mach/board.h>
 #include <mach/common.h>
@@ -31,6 +31,7 @@
 #include <mach/dma.h>
 #include <mach/gpmc.h>
 #include <mach/usb.h>
+#include <mach/board-rx51.h>
 
 static struct omap_uart_config rx51_uart_config = {
        .enabled_uarts  = ((1 << 0) | (1 << 1) | (1 << 2)),
@@ -62,12 +63,14 @@ static struct omap_board_config_kernel rx51_config[] = {
 
 static void __init rx51_init_irq(void)
 {
-       omap2_init_common_hw(NULL);
+       omap2_init_common_hw(rx51_get_sdram_timings());
        omap_init_irq();
        omap_gpio_init();
 }
 
+extern void __init rx51_flash_init(void);
 extern void __init rx51_peripherals_init(void);
+extern void __init rx51_video_init(void);
 
 static void __init rx51_init(void)
 {
@@ -75,7 +78,9 @@ static void __init rx51_init(void)
        omap_board_config_size = ARRAY_SIZE(rx51_config);
        omap_serial_init();
        usb_musb_init();
+       rx51_flash_init();
        rx51_peripherals_init();
+       rx51_video_init();
 }
 
 static void __init rx51_map_io(void)
index d6b4b2f8722fac7cbafa7a01b6367f5862802bc0..cb697e115776a3fd6782234c9411bf4875ebf43d 100644 (file)
@@ -355,10 +355,12 @@ static void omap_init_mcspi(void)
        platform_device_register(&omap2_mcspi1);
        platform_device_register(&omap2_mcspi2);
 #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
-       platform_device_register(&omap2_mcspi3);
+       if (cpu_is_omap2430() || cpu_is_omap343x())
+               platform_device_register(&omap2_mcspi3);
 #endif
 #ifdef CONFIG_ARCH_OMAP3
-       platform_device_register(&omap2_mcspi4);
+       if (cpu_is_omap343x())
+               platform_device_register(&omap2_mcspi4);
 #endif
 }
 
index 34b5914e0f8b18d094d45a31e9ce166af215b410..32ceaa6582408e36e96ba968e0cbe116d15a220f 100644 (file)
@@ -45,6 +45,28 @@ int omap_chip_is(struct omap_chip_id oci)
 }
 EXPORT_SYMBOL(omap_chip_is);
 
+int omap_type(void)
+{
+       u32 val = 0;
+
+       if (cpu_is_omap24xx()) {
+               val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
+       } else if (cpu_is_omap34xx()) {
+               val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
+       } else {
+               pr_err("Cannot detect omap type!\n");
+               goto out;
+       }
+
+       val &= OMAP2_DEVICETYPE_MASK;
+       val >>= 8;
+
+out:
+       return val;
+}
+EXPORT_SYMBOL(omap_type);
+
+
 /*----------------------------------------------------------------------------*/
 
 #define OMAP_TAP_IDCODE                0x0204
index dc40b3e72206080164b1c1f5b17def1f4d211688..cb56fe270abd89710375ff77e51a92b24fa3c5d0 100644 (file)
@@ -16,8 +16,8 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
-#include <linux/i2c/twl4030.h>
-#include <linux/regulator/machine.h>
+#include <linux/mmc/host.h>
+#include <linux/regulator/consumer.h>
 
 #include <mach/hardware.h>
 #include <mach/control.h>
 
 #include "mmc-twl4030.h"
 
-#if defined(CONFIG_TWL4030_CORE) && \
-       (defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
 
-#define LDO_CLR                        0x00
-#define VSEL_S2_CLR            0x40
-
-#define VMMC1_DEV_GRP          0x27
-#define VMMC1_CLR              0x00
-#define VMMC1_315V             0x03
-#define VMMC1_300V             0x02
-#define VMMC1_285V             0x01
-#define VMMC1_185V             0x00
-#define VMMC1_DEDICATED                0x2A
-
-#define VMMC2_DEV_GRP          0x2B
-#define VMMC2_CLR              0x40
-#define VMMC2_315V             0x0c
-#define VMMC2_300V             0x0b
-#define VMMC2_285V             0x0a
-#define VMMC2_280V             0x09
-#define VMMC2_260V             0x08
-#define VMMC2_185V             0x06
-#define VMMC2_DEDICATED                0x2E
-
-#define VMMC_DEV_GRP_P1                0x20
+#if defined(CONFIG_REGULATOR) && \
+       (defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
 
 static u16 control_pbias_offset;
 static u16 control_devconf1_offset;
@@ -59,19 +37,16 @@ static u16 control_devconf1_offset;
 
 static struct twl_mmc_controller {
        struct omap_mmc_platform_data   *mmc;
-       u8              twl_vmmc_dev_grp;
-       u8              twl_mmc_dedicated;
-       char            name[HSMMC_NAME_LEN + 1];
-} hsmmc[OMAP34XX_NR_MMC] = {
-       {
-               .twl_vmmc_dev_grp               = VMMC1_DEV_GRP,
-               .twl_mmc_dedicated              = VMMC1_DEDICATED,
-       },
-       {
-               .twl_vmmc_dev_grp               = VMMC2_DEV_GRP,
-               .twl_mmc_dedicated              = VMMC2_DEDICATED,
-       },
-};
+       /* Vcc == configured supply
+        * Vcc_alt == optional
+        *   -  MMC1, supply for DAT4..DAT7
+        *   -  MMC2/MMC2, external level shifter voltage supply, for
+        *      chip (SDIO, eMMC, etc) or transceiver (MMC2 only)
+        */
+       struct regulator                *vcc;
+       struct regulator                *vcc_aux;
+       char                            name[HSMMC_NAME_LEN + 1];
+} hsmmc[OMAP34XX_NR_MMC];
 
 static int twl_mmc_card_detect(int irq)
 {
@@ -117,16 +92,63 @@ static int twl_mmc_late_init(struct device *dev)
        int ret = 0;
        int i;
 
-       ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd");
-       if (ret)
-               goto done;
-       ret = gpio_direction_input(mmc->slots[0].switch_pin);
-       if (ret)
-               goto err;
+       /* MMC/SD/SDIO doesn't require a card detect switch */
+       if (gpio_is_valid(mmc->slots[0].switch_pin)) {
+               ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd");
+               if (ret)
+                       goto done;
+               ret = gpio_direction_input(mmc->slots[0].switch_pin);
+               if (ret)
+                       goto err;
+       }
 
+       /* require at least main regulator */
        for (i = 0; i < ARRAY_SIZE(hsmmc); i++) {
                if (hsmmc[i].name == mmc->slots[0].name) {
+                       struct regulator *reg;
+
                        hsmmc[i].mmc = mmc;
+
+                       reg = regulator_get(dev, "vmmc");
+                       if (IS_ERR(reg)) {
+                               dev_dbg(dev, "vmmc regulator missing\n");
+                               /* HACK: until fixed.c regulator is usable,
+                                * we don't require a main regulator
+                                * for MMC2 or MMC3
+                                */
+                               if (i != 0)
+                                       break;
+                               ret = PTR_ERR(reg);
+                               goto err;
+                       }
+                       hsmmc[i].vcc = reg;
+                       mmc->slots[0].ocr_mask = mmc_regulator_get_ocrmask(reg);
+
+                       /* allow an aux regulator */
+                       reg = regulator_get(dev, "vmmc_aux");
+                       hsmmc[i].vcc_aux = IS_ERR(reg) ? NULL : reg;
+
+                       /* UGLY HACK:  workaround regulator framework bugs.
+                        * When the bootloader leaves a supply active, it's
+                        * initialized with zero usecount ... and we can't
+                        * disable it without first disabling it.  Until the
+                        * framework is fixed, we need a workaround like this
+                        * (which is safe for MMC, but not in general).
+                        */
+                       if (regulator_is_enabled(hsmmc[i].vcc) > 0) {
+                               dev_warn(dev, "APPLY REGULATOR HACK for vmmc\n");
+                               regulator_enable(hsmmc[i].vcc);
+                               regulator_disable(hsmmc[i].vcc);
+                       }
+                       if (hsmmc[i].vcc_aux) {
+                               if (regulator_is_enabled(reg) > 0) {
+                                       dev_warn(dev, "APPLY REGULATOR HACK "
+                                               "for vmmc_aux\n");
+                                       regulator_enable(reg);
+                                       regulator_disable(reg);
+                               }
+                       }
+
                        break;
                }
        }
@@ -173,96 +195,6 @@ static int twl_mmc_resume(struct device *dev, int slot)
 #define twl_mmc_resume NULL
 #endif
 
-/*
- * Sets the MMC voltage in twl4030
- */
-
-#define MMC1_OCR       (MMC_VDD_165_195 \
-               |MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32)
-#define MMC2_OCR       (MMC_VDD_165_195 \
-               |MMC_VDD_25_26|MMC_VDD_26_27|MMC_VDD_27_28 \
-               |MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32)
-
-static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd)
-{
-       int ret;
-       u8 vmmc = 0, dev_grp_val;
-
-       if (!vdd)
-               goto doit;
-
-       if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) {
-               /* VMMC1:  max 220 mA.  And for 8-bit mode,
-                * VSIM:  max 50 mA
-                */
-               switch (1 << vdd) {
-               case MMC_VDD_165_195:
-                       vmmc = VMMC1_185V;
-                       /* and VSIM_180V */
-                       break;
-               case MMC_VDD_28_29:
-                       vmmc = VMMC1_285V;
-                       /* and VSIM_280V */
-                       break;
-               case MMC_VDD_29_30:
-               case MMC_VDD_30_31:
-                       vmmc = VMMC1_300V;
-                       /* and VSIM_300V */
-                       break;
-               case MMC_VDD_31_32:
-                       vmmc = VMMC1_315V;
-                       /* error if VSIM needed */
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       } else if (c->twl_vmmc_dev_grp == VMMC2_DEV_GRP) {
-               /* VMMC2:  max 100 mA */
-               switch (1 << vdd) {
-               case MMC_VDD_165_195:
-                       vmmc = VMMC2_185V;
-                       break;
-               case MMC_VDD_25_26:
-               case MMC_VDD_26_27:
-                       vmmc = VMMC2_260V;
-                       break;
-               case MMC_VDD_27_28:
-                       vmmc = VMMC2_280V;
-                       break;
-               case MMC_VDD_28_29:
-                       vmmc = VMMC2_285V;
-                       break;
-               case MMC_VDD_29_30:
-               case MMC_VDD_30_31:
-                       vmmc = VMMC2_300V;
-                       break;
-               case MMC_VDD_31_32:
-                       vmmc = VMMC2_315V;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       } else {
-               return -EINVAL;
-       }
-
-doit:
-       if (vdd)
-               dev_grp_val = VMMC_DEV_GRP_P1;  /* Power up */
-       else
-               dev_grp_val = LDO_CLR;          /* Power down */
-
-       ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
-                                       dev_grp_val, c->twl_vmmc_dev_grp);
-       if (ret || !vdd)
-               return ret;
-
-       ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
-                                       vmmc, c->twl_mmc_dedicated);
-
-       return ret;
-}
-
 static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
                                int vdd)
 {
@@ -273,11 +205,13 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
 
        /*
         * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
-        * card using the same TWL VMMC1 supply (hsmmc[0]); OMAP has both
+        * card with Vcc regulator (from twl4030 or whatever).  OMAP has both
         * 1.8V and 3.0V modes, controlled by the PBIAS register.
         *
         * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
         * is most naturally TWL VSIM; those pins also use PBIAS.
+        *
+        * FIXME handle VMMC1A as needed ...
         */
        if (power_on) {
                if (cpu_is_omap2430()) {
@@ -300,7 +234,7 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
                reg &= ~OMAP2_PBIASLITEPWRDNZ0;
                omap_ctrl_writel(reg, control_pbias_offset);
 
-               ret = twl_mmc_set_voltage(c, vdd);
+               ret = mmc_regulator_set_ocr(c->vcc, vdd);
 
                /* 100ms delay required for PBIAS configuration */
                msleep(100);
@@ -316,7 +250,7 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
                reg &= ~OMAP2_PBIASLITEPWRDNZ0;
                omap_ctrl_writel(reg, control_pbias_offset);
 
-               ret = twl_mmc_set_voltage(c, 0);
+               ret = mmc_regulator_set_ocr(c->vcc, 0);
 
                /* 100ms delay required for PBIAS configuration */
                msleep(100);
@@ -329,19 +263,33 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
        return ret;
 }
 
-static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vdd)
+static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int vdd)
 {
-       int ret;
+       int ret = 0;
        struct twl_mmc_controller *c = &hsmmc[1];
        struct omap_mmc_platform_data *mmc = dev->platform_data;
 
+       /* If we don't see a Vcc regulator, assume it's a fixed
+        * voltage always-on regulator.
+        */
+       if (!c->vcc)
+               return 0;
+
        /*
-        * Assume TWL VMMC2 (hsmmc[1]) is used only to power the card ... OMAP
+        * Assume Vcc regulator is used only to power the card ... OMAP
         * VDDS is used to power the pins, optionally with a transceiver to
         * support cards using voltages other than VDDS (1.8V nominal).  When a
         * transceiver is used, DAT3..7 are muxed as transceiver control pins.
+        *
+        * In some cases this regulator won't support enable/disable;
+        * e.g. it's a fixed rail for a WLAN chip.
+        *
+        * In other cases vcc_aux switches interface power.  Example, for
+        * eMMC cards it represents VccQ.  Sometimes transceivers or SDIO
+        * chips/cards need an interface voltage rail too.
         */
        if (power_on) {
+               /* only MMC2 supports a CLKIN */
                if (mmc->slots[0].internal_clock) {
                        u32 reg;
 
@@ -349,24 +297,23 @@ static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vd
                        reg |= OMAP2_MMCSDIO2ADPCLKISEL;
                        omap_ctrl_writel(reg, control_devconf1_offset);
                }
-               ret = twl_mmc_set_voltage(c, vdd);
+               ret = mmc_regulator_set_ocr(c->vcc, vdd);
+               /* enable interface voltage rail, if needed */
+               if (ret == 0 && c->vcc_aux) {
+                       ret = regulator_enable(c->vcc_aux);
+                       if (ret < 0)
+                               ret = mmc_regulator_set_ocr(c->vcc, 0);
+               }
        } else {
-               ret = twl_mmc_set_voltage(c, 0);
+               if (c->vcc_aux && (ret = regulator_is_enabled(c->vcc_aux)) > 0)
+                       ret = regulator_disable(c->vcc_aux);
+               if (ret == 0)
+                       ret = mmc_regulator_set_ocr(c->vcc, 0);
        }
 
        return ret;
 }
 
-static int twl_mmc3_set_power(struct device *dev, int slot, int power_on,
-               int vdd)
-{
-       /*
-        * Assume MMC3 has self-powered device connected, for example on-board
-        * chip with external power source.
-        */
-       return 0;
-}
-
 static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
 
 void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
@@ -405,17 +352,16 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
                if (c->name)
                        strncpy(twl->name, c->name, HSMMC_NAME_LEN);
                else
-                       snprintf(twl->name, ARRAY_SIZE(twl->name),
-                               "mmc%islot%i", c->mmc, 1);
+                       sprintf(twl->name, "mmc%islot%i", c->mmc, 1);
                mmc->slots[0].name = twl->name;
                mmc->nr_slots = 1;
                mmc->slots[0].wires = c->wires;
                mmc->slots[0].internal_clock = !c->ext_clock;
                mmc->dma_mask = 0xffffffff;
+               mmc->init = twl_mmc_late_init;
 
-               /* note: twl4030 card detect GPIOs normally switch VMMCx ... */
+               /* note: twl4030 card detect GPIOs can disable VMMCx ... */
                if (gpio_is_valid(c->gpio_cd)) {
-                       mmc->init = twl_mmc_late_init;
                        mmc->cleanup = twl_mmc_cleanup;
                        mmc->suspend = twl_mmc_suspend;
                        mmc->resume = twl_mmc_resume;
@@ -439,26 +385,28 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
                } else
                        mmc->slots[0].gpio_wp = -EINVAL;
 
-               /* NOTE:  we assume OMAP's MMC1 and MMC2 use
-                * the TWL4030's VMMC1 and VMMC2, respectively;
-                * and that MMC3 device has it's own power source.
+               /* NOTE:  MMC slots should have a Vcc regulator set up.
+                * This may be from a TWL4030-family chip, another
+                * controllable regulator, or a fixed supply.
+                *
+                * temporary HACK: ocr_mask instead of fixed supply
                 */
+               mmc->slots[0].ocr_mask = c->ocr_mask;
 
                switch (c->mmc) {
                case 1:
+                       /* on-chip level shifting via PBIAS0/PBIAS1 */
                        mmc->slots[0].set_power = twl_mmc1_set_power;
-                       mmc->slots[0].ocr_mask = MMC1_OCR;
                        break;
                case 2:
-                       mmc->slots[0].set_power = twl_mmc2_set_power;
-                       if (c->transceiver)
-                               mmc->slots[0].ocr_mask = MMC2_OCR;
-                       else
-                               mmc->slots[0].ocr_mask = MMC_VDD_165_195;
-                       break;
+                       if (c->ext_clock)
+                               c->transceiver = 1;
+                       if (c->transceiver && c->wires > 4)
+                               c->wires = 4;
+                       /* FALLTHROUGH */
                case 3:
-                       mmc->slots[0].set_power = twl_mmc3_set_power;
-                       mmc->slots[0].ocr_mask = MMC_VDD_165_195;
+                       /* off-chip level shifting, or none */
+                       mmc->slots[0].set_power = twl_mmc23_set_power;
                        break;
                default:
                        pr_err("MMC%d configuration not supported!\n", c->mmc);
index ea59e8624290a1d8c1fb5b2f002a69beebd0cd2b..3807c45c9a6ca4d8dc0a4534da1276af8a069ce3 100644 (file)
@@ -16,9 +16,10 @@ struct twl4030_hsmmc_info {
        int     gpio_wp;        /* or -EINVAL */
        char    *name;          /* or NULL for default */
        struct device *dev;     /* returned: pointer to mmc adapter */
+       int     ocr_mask;       /* temporary HACK */
 };
 
-#if    defined(CONFIG_TWL4030_CORE) && \
+#if defined(CONFIG_REGULATOR) && \
        (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
         defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
 
diff --git a/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h b/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h
new file mode 100644 (file)
index 0000000..ef35415
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * SDRC register values for the Micron MT46H32M32LF-6
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef ARCH_ARM_MACH_OMAP2_SDRAM_MICRON_MT46H32M32LF
+#define ARCH_ARM_MACH_OMAP2_SDRAM_MICRON_MT46H32M32LF
+
+#include <mach/sdrc.h>
+
+/* Micron MT46H32M32LF-6 */
+/* XXX Using ARE = 0x1 (no autorefresh burst) -- can this be changed? */
+static struct omap_sdrc_params mt46h32m32lf6_sdrc_params[] = {
+       [0] = {
+               .rate        = 165941176,
+               .actim_ctrla = 0x9a9db4c6,
+               .actim_ctrlb = 0x00011217,
+               .rfr_ctrl    = 0x0004dc01,
+               .mr          = 0x00000032,
+       },
+       [1] = {
+               .rate        = 133333333,
+               .actim_ctrla = 0x7a19b485,
+               .actim_ctrlb = 0x00011213,
+               .rfr_ctrl    = 0x0003de01,
+               .mr          = 0x00000032,
+       },
+       [2] = {
+               .rate        = 82970588,
+               .actim_ctrla = 0x51512283,
+               .actim_ctrlb = 0x0001120c,
+               .rfr_ctrl    = 0x00025501,
+               .mr          = 0x00000032,
+       },
+       [3] = {
+               .rate        = 66666666,
+               .actim_ctrla = 0x410d2243,
+               .actim_ctrlb = 0x0001120a,
+               .rfr_ctrl    = 0x0001d601,
+               .mr          = 0x00000032,
+       },
+       [4] = {
+               .rate        = 0
+       },
+};
+
+#endif
diff --git a/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h b/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h
new file mode 100644 (file)
index 0000000..74a92c8
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * SDRC register values for the Qimonda HYB18M512160AF-6
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef ARCH_ARM_MACH_OMAP2_SDRAM_QIMONDA_HYB18M512160AF6
+#define ARCH_ARM_MACH_OMAP2_SDRAM_QIMONDA_HYB18M512160AF6
+
+#include <mach/sdrc.h>
+
+/* Qimonda HYB18M512160AF-6 */
+/* XXX Using ARE = 0x1 (no autorefresh burst) -- can this be changed? */
+static struct omap_sdrc_params hyb18m512160af6_sdrc_params[] = {
+       [0] = {
+               .rate        = 165941176,
+               .actim_ctrla = 0x629db4c6,
+               .actim_ctrlb = 0x00012214,
+               .rfr_ctrl    = 0x0004dc01,
+               .mr          = 0x00000032,
+       },
+       [1] = {
+               .rate        = 133333333,
+               .actim_ctrla = 0x5219b485,
+               .actim_ctrlb = 0x00012210,
+               .rfr_ctrl    = 0x0003de01,
+               .mr          = 0x00000032,
+       },
+       [2] = {
+               .rate        = 82970588,
+               .actim_ctrla = 0x31512283,
+               .actim_ctrlb = 0x0001220a,
+               .rfr_ctrl    = 0x00025501,
+               .mr          = 0x00000022,
+       },
+       [3] = {
+               .rate        = 66666666,
+               .actim_ctrla = 0x290d2243,
+               .actim_ctrlb = 0x00012208,
+               .rfr_ctrl    = 0x0001d601,
+               .mr          = 0x00000022,
+       },
+       [4] = {
+               .rate        = 0
+       },
+};
+
+#endif
diff --git a/arch/arm/mach-omap2/twl4030-generic-scripts.c b/arch/arm/mach-omap2/twl4030-generic-scripts.c
new file mode 100644 (file)
index 0000000..4293752
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * arch/arm/mach-omap2/twl4030-generic-scripts.c
+ *
+ * Generic power control scripts for TWL4030
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Copyright (C) 2006 Texas Instruments, Inc
+ *
+ * Written by  Kalle Jokiniemi
+ *             Peter De Schrijver <peter.de-schrijver@nokia.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file "COPYING" in the main directory of this
+ * archive for more details.
+ *
+ * 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
+ */
+
+#ifdef CONFIG_TWL4030_POWER
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/i2c/twl4030.h>
+
+/*
+ * This script instructs twl4030 to first put the Reset and Control (RC)
+ * resources to sleep and then all the other resources.
+ */
+
+static struct twl4030_ins sleep_on_seq[] __initdata = {
+       {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0,
+                       RES_STATE_SLEEP), 4},
+       {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_ALL, RES_TYPE2_R0,
+                       RES_STATE_SLEEP), 4},
+};
+
+static struct twl4030_script sleep_on_script __initdata = {
+       .script = sleep_on_seq,
+       .size   = ARRAY_SIZE(sleep_on_seq),
+       .flags  = TRITON_SLEEP_SCRIPT,
+};
+
+/*
+ * This script instructs twl4030 to first enable CLKEN, then wakeup the
+ * regulators and then all other resources.
+ */
+
+static struct twl4030_ins wakeup_seq[] __initdata = {
+       {MSG_SINGULAR(DEV_GRP_NULL, 0x17, RES_STATE_ACTIVE), 0x30},
+       {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP_PR, RES_TYPE_ALL, RES_TYPE2_R0,
+                       RES_STATE_ACTIVE), 0x37},
+       {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_ALL, RES_TYPE2_R0,
+                       RES_STATE_ACTIVE), 0x2},
+};
+
+static struct twl4030_script wakeup_script __initdata = {
+       .script = wakeup_seq,
+       .size   = ARRAY_SIZE(wakeup_seq),
+       .flags  = TRITON_WAKEUP12_SCRIPT | TRITON_WAKEUP3_SCRIPT,
+};
+
+static struct twl4030_script *twl4030_scripts[] __initdata = {
+       &sleep_on_script,
+       &wakeup_script,
+};
+
+struct twl4030_power_data generic3430_t2scripts_data __initdata = {
+       .scripts        = twl4030_scripts,
+       .size           = ARRAY_SIZE(twl4030_scripts),
+};
+
+
+#endif /* CONFIG_TWL4030_POWER */
diff --git a/arch/arm/mach-omap2/twl4030-generic-scripts.h b/arch/arm/mach-omap2/twl4030-generic-scripts.h
new file mode 100644 (file)
index 0000000..fb69c2e
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __TWL4030_GENERIC_SCRIPTS_H
+#define __TWL4030_GENERIC_SCRIPTS_H
+
+#include <linux/i2c/twl4030.h>
+
+#ifdef CONFIG_TWL4030_POWER
+extern struct twl4030_power_data generic3430_t2scripts_data;
+#define GENERIC3430_T2SCRIPTS_DATA &generic3430_t2scripts_data
+#else
+#define GENERIC3430_T2SCRIPTS_DATA NULL
+#endif /* CONFIG_TWL4030_POWER */
+
+#endif
diff --git a/arch/arm/mach-omap2/usb-ehci.c b/arch/arm/mach-omap2/usb-ehci.c
new file mode 100644 (file)
index 0000000..23fe857
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * linux/arch/arm/mach-omap2/usb-ehci.c
+ *
+ * This file will contain the board specific details for the
+ * Synopsys EHCI host controller on OMAP3430
+ *
+ * Copyright (C) 2007 Texas Instruments
+ * Author: Vikram Pandita <vikram.pandita@ti.com>
+ *
+ * Generalization by:
+ * Felipe Balbi <felipe.balbi@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <asm/io.h>
+#include <mach/mux.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/pm.h>
+#include <mach/usb.h>
+
+static struct resource ehci_resources[] = {
+       [0] = {
+               .start   = OMAP34XX_HSUSB_HOST_BASE + 0x800,
+               .end     = OMAP34XX_HSUSB_HOST_BASE + 0x800 + SZ_1K - 1,
+               .flags   = IORESOURCE_MEM,
+       },
+       [1] = {         /* general IRQ */
+               .start   = INT_34XX_EHCI_IRQ,
+               .flags   = IORESOURCE_IRQ,
+       }
+};
+
+static u64 ehci_dmamask = ~(u32)0;
+static struct platform_device ehci_device = {
+       .name           = "ehci-omap",
+       .id             = 0,
+       .dev = {
+               .dma_mask               = &ehci_dmamask,
+               .coherent_dma_mask      = 0xffffffff,
+               .platform_data          = NULL,
+       },
+       .num_resources  = ARRAY_SIZE(ehci_resources),
+       .resource       = ehci_resources,
+};
+
+/* MUX settings for EHCI pins */
+/*
+ * setup_ehci_io_mux - initialize IO pad mux for USBHOST
+ */
+static void setup_ehci_io_mux(void)
+{
+#ifdef CONFIG_OMAP_EHCI_PHY_MODE
+       /* PHY mode of operation for board: 750-2083-001
+        * ISP1504 connected to Port1 and Port2
+        * Do Func Mux setting for 12-pin ULPI PHY mode
+        */
+
+       /* Port1 */
+       omap_cfg_reg(Y9_3430_USB1HS_PHY_STP);
+       omap_cfg_reg(Y8_3430_USB1HS_PHY_CLK);
+       omap_cfg_reg(AA14_3430_USB1HS_PHY_DIR);
+       omap_cfg_reg(AA11_3430_USB1HS_PHY_NXT);
+       omap_cfg_reg(W13_3430_USB1HS_PHY_DATA0);
+       omap_cfg_reg(W12_3430_USB1HS_PHY_DATA1);
+       omap_cfg_reg(W11_3430_USB1HS_PHY_DATA2);
+       omap_cfg_reg(Y11_3430_USB1HS_PHY_DATA3);
+       omap_cfg_reg(W9_3430_USB1HS_PHY_DATA4);
+       omap_cfg_reg(Y12_3430_USB1HS_PHY_DATA5);
+       omap_cfg_reg(W8_3430_USB1HS_PHY_DATA6);
+       omap_cfg_reg(Y13_3430_USB1HS_PHY_DATA7);
+
+       /* Port2 */
+       omap_cfg_reg(AA10_3430_USB2HS_PHY_STP);
+       omap_cfg_reg(AA8_3430_USB2HS_PHY_CLK);
+       omap_cfg_reg(AA9_3430_USB2HS_PHY_DIR);
+       omap_cfg_reg(AB11_3430_USB2HS_PHY_NXT);
+       omap_cfg_reg(AB10_3430_USB2HS_PHY_DATA0);
+       omap_cfg_reg(AB9_3430_USB2HS_PHY_DATA1);
+       omap_cfg_reg(W3_3430_USB2HS_PHY_DATA2);
+       omap_cfg_reg(T4_3430_USB2HS_PHY_DATA3);
+       omap_cfg_reg(T3_3430_USB2HS_PHY_DATA4);
+       omap_cfg_reg(R3_3430_USB2HS_PHY_DATA5);
+       omap_cfg_reg(R4_3430_USB2HS_PHY_DATA6);
+       omap_cfg_reg(T2_3430_USB2HS_PHY_DATA7);
+
+#else
+       /* Set Func mux for :
+        * TLL mode of operation
+        * 12-pin ULPI SDR TLL mode for Port1/2/3
+        */
+
+       /* Port1 */
+       omap_cfg_reg(Y9_3430_USB1HS_TLL_STP);
+       omap_cfg_reg(Y8_3430_USB1HS_TLL_CLK);
+       omap_cfg_reg(AA14_3430_USB1HS_TLL_DIR);
+       omap_cfg_reg(AA11_3430_USB1HS_TLL_NXT);
+       omap_cfg_reg(W13_3430_USB1HS_TLL_DATA0);
+       omap_cfg_reg(W12_3430_USB1HS_TLL_DATA1);
+       omap_cfg_reg(W11_3430_USB1HS_TLL_DATA2);
+       omap_cfg_reg(Y11_3430_USB1HS_TLL_DATA3);
+       omap_cfg_reg(W9_3430_USB1HS_TLL_DATA4);
+       omap_cfg_reg(Y12_3430_USB1HS_TLL_DATA5);
+       omap_cfg_reg(W8_3430_USB1HS_TLL_DATA6);
+       omap_cfg_reg(Y13_3430_USB1HS_TLL_DATA7);
+
+       /* Port2 */
+       omap_cfg_reg(AA10_3430_USB2HS_TLL_STP);
+       omap_cfg_reg(AA8_3430_USB2HS_TLL_CLK);
+       omap_cfg_reg(AA9_3430_USB2HS_TLL_DIR);
+       omap_cfg_reg(AB11_3430_USB2HS_TLL_NXT);
+       omap_cfg_reg(AB10_3430_USB2HS_TLL_DATA0);
+       omap_cfg_reg(AB9_3430_USB2HS_TLL_DATA1);
+       omap_cfg_reg(W3_3430_USB2HS_TLL_DATA2);
+       omap_cfg_reg(T4_3430_USB2HS_TLL_DATA3);
+       omap_cfg_reg(T3_3430_USB2HS_TLL_DATA4);
+       omap_cfg_reg(R3_3430_USB2HS_TLL_DATA5);
+       omap_cfg_reg(R4_3430_USB2HS_TLL_DATA6);
+       omap_cfg_reg(T2_3430_USB2HS_TLL_DATA7);
+
+       /* Port3 */
+       omap_cfg_reg(AB3_3430_USB3HS_TLL_STP);
+       omap_cfg_reg(AA6_3430_USB3HS_TLL_CLK);
+       omap_cfg_reg(AA3_3430_USB3HS_TLL_DIR);
+       omap_cfg_reg(Y3_3430_USB3HS_TLL_NXT);
+       omap_cfg_reg(AA5_3430_USB3HS_TLL_DATA0);
+       omap_cfg_reg(Y4_3430_USB3HS_TLL_DATA1);
+       omap_cfg_reg(Y5_3430_USB3HS_TLL_DATA2);
+       omap_cfg_reg(W5_3430_USB3HS_TLL_DATA3);
+       omap_cfg_reg(AB12_3430_USB3HS_TLL_DATA4);
+       omap_cfg_reg(AB13_3430_USB3HS_TLL_DATA5);
+       omap_cfg_reg(AA13_3430_USB3HS_TLL_DATA6);
+       omap_cfg_reg(AA12_3430_USB3HS_TLL_DATA7);
+#endif /* CONFIG_OMAP_EHCI_PHY_MODE */
+
+       return;
+}
+
+void __init usb_ehci_init(void)
+{
+       /* Setup Pin IO MUX for EHCI */
+       if (cpu_is_omap34xx())
+               setup_ehci_io_mux();
+
+       if (platform_device_register(&ehci_device) < 0) {
+               printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n");
+               return;
+       }
+}
+
+
index fc74e913c415523dcf3965468b6b374b98c9654f..927c2d91a036c15ec7d741bb1d822bc1be8f770b 100644 (file)
@@ -161,17 +161,15 @@ static struct platform_device nop_xceiv_device = {
 
 void __init usb_musb_init(void)
 {
-       if (cpu_is_omap243x())
+       if (cpu_is_omap243x()) {
                musb_resources[0].start = OMAP243X_HS_BASE;
-       else
+               musb_plat.clock = "usbhs_ick";
+       } else {
                musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;
-       musb_resources[0].end = musb_resources[0].start + SZ_8K - 1;
+               musb_plat.clock = "hsotgusb_ick";
+       }
 
-       /*
-        * REVISIT: This line can be removed once all the platforms using
-        * musb_core.c have been converted to use use clkdev.
-        */
-       musb_plat.clock = "ick";
+       musb_resources[0].end = musb_resources[0].start + SZ_8K - 1;
 
 #ifdef CONFIG_NOP_USB_XCEIV
        if (platform_device_register(&nop_xceiv_device) < 0) {
index 15e509013def69cda9cf2ff4d431e70868d676c0..59c1d57e507f1c96ef9e451c863937a6cc670d2f 100644 (file)
@@ -175,8 +175,6 @@ static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)
        return gpmc_cs_set_timings(sync_cs, &t);
 }
 
-extern unsigned long gpmc_get_fclk_period(void);
-
 /* tusb driver calls this when it changes the chip's clocking */
 int tusb6010_platform_retime(unsigned is_refclk)
 {
@@ -187,7 +185,7 @@ int tusb6010_platform_retime(unsigned is_refclk)
        unsigned        sysclk_ps;
        int             status;
 
-       if (!refclk_psec)
+       if (!refclk_psec || sysclk_ps == 0)
                return -ENODEV;
 
        sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
index 9dd68fafb374b54c273ebe2e7034be042e993563..b37fc101e9f581bed9ea5feff8b1e4dd0009e76a 100644 (file)
@@ -73,6 +73,39 @@ config OMAP_RESET_CLOCKS
          probably do not want this option enabled until your
          device drivers work properly.
 
+config OMAP_BOOT_TAG
+       bool "OMAP bootloader information passing"
+        depends on ARCH_OMAP
+        default n
+        help
+          Say Y, if you have a bootloader which passes information
+          about your board and its peripheral configuration.
+
+config OMAP_BOOT_REASON
+       bool "Support for boot reason"
+        depends on OMAP_BOOT_TAG
+        default n
+        help
+          Say Y, if you want to have a procfs entry for reading the boot
+          reason in user-space.
+
+config OMAP_COMPONENT_VERSION
+       bool "Support for component version display"
+       depends on OMAP_BOOT_TAG && PROC_FS
+       default n
+       help
+         Say Y, if you want to have a procfs entry for reading component
+         versions (supplied by the bootloader) in user-space.
+
+config OMAP_GPIO_SWITCH
+       bool "GPIO switch support"
+        default n
+        help
+          Say Y, if you want to have support for reporting of GPIO
+          switches (e.g. cover switches) via sysfs. Your bootloader has
+          to provide information about the switches to the kernel via the
+          ATAG_BOARD mechanism if they're not defined by the board config.
+
 config OMAP_MUX
        bool "OMAP multiplexing support"
         depends on ARCH_OMAP
index 04a100cfb8e5fcfe67057938f7472114150c04b1..3ebc09ed0f6c8ea466796026b2c3a757586e49f0 100644 (file)
@@ -16,6 +16,9 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
 obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
 obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
+obj-$(CONFIG_OMAP_BOOT_REASON) += bootreason.o
+obj-$(CONFIG_OMAP_COMPONENT_VERSION) += component-version.o
+obj-$(CONFIG_OMAP_GPIO_SWITCH) += gpio-switch.o
 obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
 obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
 i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
diff --git a/arch/arm/plat-omap/bootreason.c b/arch/arm/plat-omap/bootreason.c
new file mode 100644 (file)
index 0000000..d527b1b
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * linux/arch/arm/plat-omap/bootreason.c
+ *
+ * OMAP Bootreason passing
+ *
+ * Copyright (c) 2004 Nokia
+ *
+ * Written by David Weinehall <david.weinehall@nokia.com>
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/proc_fs.h>
+#include <linux/errno.h>
+#include <mach/board.h>
+
+static char boot_reason[16];
+
+static int omap_bootreason_read_proc(char *page, char **start, off_t off,
+                                        int count, int *eof, void *data)
+{
+       int len = 0;
+
+       len += sprintf(page + len, "%s\n", boot_reason);
+
+       *start = page + off;
+
+       if (len > off)
+               len -= off;
+       else
+               len = 0;
+
+       return len < count ? len  : count;
+}
+
+static int __init bootreason_init(void)
+{
+       const struct omap_boot_reason_config *cfg;
+       int reason_valid = 0;
+
+       cfg = omap_get_config(OMAP_TAG_BOOT_REASON, struct omap_boot_reason_config);
+       if (cfg != NULL) {
+               strncpy(boot_reason, cfg->reason_str, sizeof(cfg->reason_str));
+               boot_reason[sizeof(cfg->reason_str)] = 0;
+               reason_valid = 1;
+       } else {
+               /* Read the boot reason from the OMAP registers */
+       }
+
+       if (!reason_valid)
+               return -ENOENT;
+
+       printk(KERN_INFO "Bootup reason: %s\n", boot_reason);
+
+       if (!create_proc_read_entry("bootreason", S_IRUGO, NULL,
+                                       omap_bootreason_read_proc, NULL))
+               return -ENOMEM;
+
+       return 0;
+}
+
+late_initcall(bootreason_init);
index d1797147732f217ce4906f5388e55956b7f4f62c..28666126fd3b9c661fdf611068e5b37e9a074625 100644 (file)
 
 #define NO_LENGTH_CHECK 0xffffffff
 
-unsigned char omap_bootloader_tag[512];
+unsigned char omap_bootloader_tag[1024];
 int omap_bootloader_tag_len;
 
 struct omap_board_config_kernel *omap_board_config;
 int omap_board_config_size;
 
+#ifdef CONFIG_OMAP_BOOT_TAG
+
+static int __init parse_tag_omap(const struct tag *tag)
+{
+       u32 size = tag->hdr.size - (sizeof(tag->hdr) >> 2);
+
+        size <<= 2;
+       if (size > sizeof(omap_bootloader_tag))
+               return -1;
+
+       memcpy(omap_bootloader_tag, tag->u.omap.data, size);
+       omap_bootloader_tag_len = size;
+
+        return 0;
+}
+
+__tagtable(ATAG_BOARD, parse_tag_omap);
+
+#endif
+
 static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
 {
        struct omap_board_config_kernel *kinfo = NULL;
diff --git a/arch/arm/plat-omap/component-version.c b/arch/arm/plat-omap/component-version.c
new file mode 100644 (file)
index 0000000..3c9d523
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  linux/arch/arm/plat-omap/component-version.c
+ *
+ *  Copyright (C) 2005 Nokia Corporation
+ *  Written by Juha Yrjölä <juha.yrjola@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/proc_fs.h>
+#include <mach/board.h>
+#include <mach/board-nokia.h>
+
+static int component_version_read_proc(char *page, char **start, off_t off,
+                                      int count, int *eof, void *data)
+{
+       int len, i;
+       const struct omap_version_config *ver;
+       char *p;
+
+       i = 0;
+       p = page;
+       while ((ver = omap_get_nr_config(OMAP_TAG_VERSION_STR,
+                                        struct omap_version_config, i)) != NULL) {
+               p += sprintf(p, "%-12s%s\n", ver->component, ver->version);
+               i++;
+       }
+
+       len = (p - page) - off;
+       if (len < 0)
+               len = 0;
+
+       *eof = (len <= count) ? 1 : 0;
+       *start = page + off;
+
+       return len;
+}
+
+static int __init component_version_init(void)
+{
+       if (omap_get_config(OMAP_TAG_VERSION_STR, struct omap_version_config) == NULL)
+               return -ENODEV;
+       if (!create_proc_read_entry("component_version", S_IRUGO, NULL,
+                                   component_version_read_proc, NULL))
+               return -ENOMEM;
+
+       return 0;
+}
+
+static void __exit component_version_exit(void)
+{
+       remove_proc_entry("component_version", NULL);
+}
+
+late_initcall(component_version_init);
+module_exit(component_version_exit);
+
+MODULE_AUTHOR("Juha Yrjölä <juha.yrjola@nokia.com>");
+MODULE_DESCRIPTION("Component version driver");
+MODULE_LICENSE("GPL");
old mode 100644 (file)
new mode 100755 (executable)
index 21cc014..3fd0e77
@@ -738,7 +738,7 @@ int omap_request_dma(int dev_id, const char *dev_name,
                 * id.
                 */
                dma_write(dev_id | (1 << 10), CCR(free_ch));
-       } else if (cpu_is_omap7xx() || cpu_is_omap15xx()) {
+       } else if (cpu_is_omap730() || cpu_is_omap15xx()) {
                dma_write(dev_id, CCR(free_ch));
        }
 
@@ -2346,7 +2346,7 @@ static int __init omap_init_dma(void)
                printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
                dma_chan_count = 9;
                enable_1510_mode = 1;
-       } else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
+       } else if (cpu_is_omap16xx() || cpu_is_omap730()) {
                printk(KERN_INFO "OMAP DMA hardware version %d\n",
                       dma_read(HW_ID));
                printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
@@ -2424,6 +2424,19 @@ static int __init omap_init_dma(void)
        if (cpu_class_is_omap2())
                setup_irq(INT_24XX_SDMA_IRQ0, &omap24xx_dma_irq);
 
+       /* Enable smartidle idlemodes and autoidle */
+       if (cpu_is_omap34xx()) {
+               u32 v = dma_read(OCP_SYSCONFIG);
+               v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK |
+                               DMA_SYSCONFIG_SIDLEMODE_MASK |
+                               DMA_SYSCONFIG_AUTOIDLE);
+               v |= (DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
+                       DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
+                       DMA_SYSCONFIG_AUTOIDLE);
+               dma_write(v , OCP_SYSCONFIG);
+       }
+
+
        /* FIXME: Update LCD DMA to work on 24xx */
        if (cpu_class_is_omap1()) {
                r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0,
index bfd47570cc9142e2d0d2b2d0e471233f4a925979..a05205c12f7b3d39c58f5eba6561107558f34a09 100644 (file)
@@ -238,7 +238,7 @@ static struct omap_dm_timer omap3_dm_timers[] = {
        { .phys_base = 0x49040000, .irq = INT_24XX_GPTIMER9 },
        { .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
        { .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
-       { .phys_base = 0x48304000, .irq = INT_24XX_GPTIMER12 },
+       { .phys_base = 0x48304000, .irq = INT_34XX_GPT12_IRQ },
 };
 
 static const char *omap3_dm_source_names[] __initdata = {
@@ -321,11 +321,9 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
        l |= 0x2 << 8;   /* Set clock activity to perserve f-clock on idle */
 
        /*
-        * Enable wake-up only for GPT1 on OMAP2 CPUs.
-        * FIXME: All timers should have wake-up enabled and clear
-        * PRCM status.
+        * Enable wake-up on OMAP2 CPUs.
         */
-       if (cpu_class_is_omap2() && (timer == &dm_timers[0]))
+       if (cpu_class_is_omap2())
                l |= 1 << 2;
        omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
 
index ce6b4baeedec416aa48d64f17872e799079cd328..3746222bed10ff52f6002556c21cfca486e2babf 100644 (file)
@@ -206,9 +206,10 @@ void __init omapfb_reserve_sdram(void)
                        config_invalid = 1;
                        return;
                }
-               if (rg.paddr)
+               if (rg.paddr) {
                        reserve_bootmem(rg.paddr, rg.size, BOOTMEM_DEFAULT);
-               reserved += rg.size;
+                       reserved += rg.size;
+               }
                omapfb_config.mem_desc.region[i] = rg;
                configured_regions++;
        }
diff --git a/arch/arm/plat-omap/gpio-switch.c b/arch/arm/plat-omap/gpio-switch.c
new file mode 100644 (file)
index 0000000..9053ea0
--- /dev/null
@@ -0,0 +1,558 @@
+/*
+ *  linux/arch/arm/plat-omap/gpio-switch.c
+ *
+ *  Copyright (C) 2004-2006 Nokia Corporation
+ *  Written by Juha Yrjölä <juha.yrjola@nokia.com>
+ *         and Paul Mundt <paul.mundt@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/timer.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/mux.h>
+#include <mach/board.h>
+#include <mach/gpio-switch.h>
+
+struct gpio_switch {
+       char            name[14];
+       u16             gpio;
+       unsigned        flags:4;
+       unsigned        type:4;
+       unsigned        state:1;
+       unsigned        both_edges:1;
+
+       u16             debounce_rising;
+       u16             debounce_falling;
+
+       void (* notify)(void *data, int state);
+       void *notify_data;
+
+       struct work_struct      work;
+       struct timer_list       timer;
+       struct platform_device  pdev;
+
+       struct list_head        node;
+};
+
+static LIST_HEAD(gpio_switches);
+static struct platform_device *gpio_sw_platform_dev;
+static struct platform_driver gpio_sw_driver;
+
+static const struct omap_gpio_switch *board_gpio_sw_table;
+static int board_gpio_sw_count;
+
+static const char *cover_str[2] = { "open", "closed" };
+static const char *connection_str[2] = { "disconnected", "connected" };
+static const char *activity_str[2] = { "inactive", "active" };
+
+/*
+ * GPIO switch state default debounce delay in ms
+ */
+#define OMAP_GPIO_SW_DEFAULT_DEBOUNCE          10
+
+static const char **get_sw_str(struct gpio_switch *sw)
+{
+       switch (sw->type) {
+       case OMAP_GPIO_SWITCH_TYPE_COVER:
+               return cover_str;
+       case OMAP_GPIO_SWITCH_TYPE_CONNECTION:
+               return connection_str;
+       case OMAP_GPIO_SWITCH_TYPE_ACTIVITY:
+               return activity_str;
+       default:
+               BUG();
+               return NULL;
+       }
+}
+
+static const char *get_sw_type(struct gpio_switch *sw)
+{
+       switch (sw->type) {
+       case OMAP_GPIO_SWITCH_TYPE_COVER:
+               return "cover";
+       case OMAP_GPIO_SWITCH_TYPE_CONNECTION:
+               return "connection";
+       case OMAP_GPIO_SWITCH_TYPE_ACTIVITY:
+               return "activity";
+       default:
+               BUG();
+               return NULL;
+       }
+}
+
+static void print_sw_state(struct gpio_switch *sw, int state)
+{
+       const char **str;
+
+       str = get_sw_str(sw);
+       if (str != NULL)
+               printk(KERN_INFO "%s (GPIO %d) is now %s\n", sw->name, sw->gpio, str[state]);
+}
+
+static int gpio_sw_get_state(struct gpio_switch *sw)
+{
+       int state;
+
+       state = gpio_get_value(sw->gpio);
+       if (sw->flags & OMAP_GPIO_SWITCH_FLAG_INVERTED)
+               state = !state;
+
+       return state;
+}
+
+static ssize_t gpio_sw_state_store(struct device *dev,
+                                  struct device_attribute *attr,
+                                  const char *buf,
+                                  size_t count)
+{
+       struct gpio_switch *sw = dev_get_drvdata(dev);
+       const char **str;
+       char state[16];
+       int enable;
+
+       if (!(sw->flags & OMAP_GPIO_SWITCH_FLAG_OUTPUT))
+               return -EPERM;
+
+       if (sscanf(buf, "%15s", state) != 1)
+               return -EINVAL;
+
+       str = get_sw_str(sw);
+       if (strcmp(state, str[0]) == 0)
+               sw->state = enable = 0;
+       else if (strcmp(state, str[1]) == 0)
+               sw->state = enable = 1;
+       else
+               return -EINVAL;
+
+       if (sw->flags & OMAP_GPIO_SWITCH_FLAG_INVERTED)
+               enable = !enable;
+       gpio_set_value(sw->gpio, enable);
+
+       return count;
+}
+
+static ssize_t gpio_sw_state_show(struct device *dev,
+                                 struct device_attribute *attr,
+                                 char *buf)
+{
+       struct gpio_switch *sw = dev_get_drvdata(dev);
+       const char **str;
+
+       str = get_sw_str(sw);
+       return sprintf(buf, "%s\n", str[sw->state]);
+}
+
+static DEVICE_ATTR(state, S_IRUGO | S_IWUSR, gpio_sw_state_show,
+                  gpio_sw_state_store);
+
+static ssize_t gpio_sw_type_show(struct device *dev,
+                                struct device_attribute *attr,
+                                char *buf)
+{
+       struct gpio_switch *sw = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%s\n", get_sw_type(sw));
+}
+
+static DEVICE_ATTR(type, S_IRUGO, gpio_sw_type_show, NULL);
+
+static ssize_t gpio_sw_direction_show(struct device *dev,
+                                     struct device_attribute *attr,
+                                     char *buf)
+{
+       struct gpio_switch *sw = dev_get_drvdata(dev);
+       int is_output;
+
+       is_output = sw->flags & OMAP_GPIO_SWITCH_FLAG_OUTPUT;
+       return sprintf(buf, "%s\n", is_output ? "output" : "input");
+}
+
+static DEVICE_ATTR(direction, S_IRUGO, gpio_sw_direction_show, NULL);
+
+
+static irqreturn_t gpio_sw_irq_handler(int irq, void *arg)
+{
+       struct gpio_switch *sw = arg;
+       unsigned long timeout;
+       int state;
+
+       if (!sw->both_edges) {
+               if (gpio_get_value(sw->gpio))
+                       set_irq_type(gpio_to_irq(sw->gpio), IRQ_TYPE_EDGE_FALLING);
+               else
+                       set_irq_type(gpio_to_irq(sw->gpio), IRQ_TYPE_EDGE_RISING);
+       }
+
+       state = gpio_sw_get_state(sw);
+       if (sw->state == state)
+               return IRQ_HANDLED;
+
+       if (state)
+               timeout = sw->debounce_rising;
+       else
+               timeout = sw->debounce_falling;
+       if (!timeout)
+               schedule_work(&sw->work);
+       else
+               mod_timer(&sw->timer, jiffies + msecs_to_jiffies(timeout));
+
+       return IRQ_HANDLED;
+}
+
+static void gpio_sw_timer(unsigned long arg)
+{
+       struct gpio_switch *sw = (struct gpio_switch *) arg;
+
+       schedule_work(&sw->work);
+}
+
+static void gpio_sw_handler(struct work_struct *work)
+{
+       struct gpio_switch *sw = container_of(work, struct gpio_switch, work);
+       int state;
+
+       state = gpio_sw_get_state(sw);
+       if (sw->state == state)
+               return;
+
+       sw->state = state;
+       if (sw->notify != NULL)
+               sw->notify(sw->notify_data, state);
+       sysfs_notify(&sw->pdev.dev.kobj, NULL, "state");
+       print_sw_state(sw, state);
+}
+
+static int __init can_do_both_edges(struct gpio_switch *sw)
+{
+       if (!cpu_class_is_omap1())
+               return 1;
+       if (OMAP_GPIO_IS_MPUIO(sw->gpio))
+               return 0;
+       else
+               return 1;
+}
+
+static void gpio_sw_release(struct device *dev)
+{
+}
+
+static int __init new_switch(struct gpio_switch *sw)
+{
+       int r, direction, trigger;
+
+       switch (sw->type) {
+       case OMAP_GPIO_SWITCH_TYPE_COVER:
+       case OMAP_GPIO_SWITCH_TYPE_CONNECTION:
+       case OMAP_GPIO_SWITCH_TYPE_ACTIVITY:
+               break;
+       default:
+               printk(KERN_ERR "invalid GPIO switch type: %d\n", sw->type);
+               return -EINVAL;
+       }
+
+       sw->pdev.name   = sw->name;
+       sw->pdev.id     = -1;
+
+       sw->pdev.dev.parent = &gpio_sw_platform_dev->dev;
+       sw->pdev.dev.driver = &gpio_sw_driver.driver;
+       sw->pdev.dev.release = gpio_sw_release;
+
+       r = platform_device_register(&sw->pdev);
+       if (r) {
+               printk(KERN_ERR "gpio-switch: platform device registration "
+                      "failed for %s", sw->name);
+               return r;
+       }
+       dev_set_drvdata(&sw->pdev.dev, sw);
+
+       r = gpio_request(sw->gpio, sw->name);
+       if (r < 0) {
+               platform_device_unregister(&sw->pdev);
+               return r;
+       }
+
+       /* input: 1, output: 0 */
+       direction = !(sw->flags & OMAP_GPIO_SWITCH_FLAG_OUTPUT);
+       if (direction) {
+               gpio_direction_input(sw->gpio);
+               sw->state = gpio_sw_get_state(sw);
+       } else {
+               int state = sw->state = !!(sw->flags &
+                       OMAP_GPIO_SWITCH_FLAG_OUTPUT_INIT_ACTIVE);
+
+               if (sw->flags & OMAP_GPIO_SWITCH_FLAG_INVERTED)
+                       state = !state;
+               gpio_direction_output(sw->gpio, state);
+       }
+
+       r = 0;
+       r |= device_create_file(&sw->pdev.dev, &dev_attr_state);
+       r |= device_create_file(&sw->pdev.dev, &dev_attr_type);
+       r |= device_create_file(&sw->pdev.dev, &dev_attr_direction);
+       if (r)
+               printk(KERN_ERR "gpio-switch: attribute file creation "
+                      "failed for %s\n", sw->name);
+
+       if (!direction)
+               return 0;
+
+       if (can_do_both_edges(sw)) {
+               trigger = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING;
+               sw->both_edges = 1;
+       } else {
+               if (gpio_get_value(sw->gpio))
+                       trigger = IRQF_TRIGGER_FALLING;
+               else
+                       trigger = IRQF_TRIGGER_RISING;
+       }
+       r = request_irq(gpio_to_irq(sw->gpio), gpio_sw_irq_handler,
+                       IRQF_SHARED | trigger, sw->name, sw);
+       if (r < 0) {
+               printk(KERN_ERR "gpio-switch: request_irq() failed "
+                      "for GPIO %d\n", sw->gpio);
+               platform_device_unregister(&sw->pdev);
+               gpio_free(sw->gpio);
+               return r;
+       }
+
+       INIT_WORK(&sw->work, gpio_sw_handler);
+       init_timer(&sw->timer);
+
+       sw->timer.function = gpio_sw_timer;
+       sw->timer.data = (unsigned long)sw;
+
+       list_add(&sw->node, &gpio_switches);
+
+       return 0;
+}
+
+static int __init add_atag_switches(void)
+{
+       const struct omap_gpio_switch_config *cfg;
+       struct gpio_switch *sw;
+       int i, r;
+
+       for (i = 0; ; i++) {
+               cfg = omap_get_nr_config(OMAP_TAG_GPIO_SWITCH,
+                                        struct omap_gpio_switch_config, i);
+               if (cfg == NULL)
+                       break;
+               sw = kzalloc(sizeof(*sw), GFP_KERNEL);
+               if (sw == NULL) {
+                       printk(KERN_ERR "gpio-switch: kmalloc failed\n");
+                       return -ENOMEM;
+               }
+               strncpy(sw->name, cfg->name, sizeof(cfg->name));
+               sw->gpio = cfg->gpio;
+               sw->flags = cfg->flags;
+               sw->type = cfg->type;
+               sw->debounce_rising = OMAP_GPIO_SW_DEFAULT_DEBOUNCE;
+               sw->debounce_falling = OMAP_GPIO_SW_DEFAULT_DEBOUNCE;
+               if ((r = new_switch(sw)) < 0) {
+                       kfree(sw);
+                       return r;
+               }
+       }
+       return 0;
+}
+
+static struct gpio_switch * __init find_switch(int gpio, const char *name)
+{
+       struct gpio_switch *sw;
+
+       list_for_each_entry(sw, &gpio_switches, node) {
+               if ((gpio < 0 || sw->gpio != gpio) &&
+                   (name == NULL || strcmp(sw->name, name) != 0))
+                       continue;
+
+               if (gpio < 0 || name == NULL)
+                       goto no_check;
+
+               if (strcmp(sw->name, name) != 0)
+                       printk("gpio-switch: name mismatch for %d (%s, %s)\n",
+                              gpio, name, sw->name);
+               else if (sw->gpio != gpio)
+                       printk("gpio-switch: GPIO mismatch for %s (%d, %d)\n",
+                              name, gpio, sw->gpio);
+no_check:
+               return sw;
+       }
+       return NULL;
+}
+
+static int __init add_board_switches(void)
+{
+       int i;
+
+       for (i = 0; i < board_gpio_sw_count; i++) {
+               const struct omap_gpio_switch *cfg;
+               struct gpio_switch *sw;
+               int r;
+
+               cfg = board_gpio_sw_table + i;
+               if (strlen(cfg->name) > sizeof(sw->name) - 1)
+                       return -EINVAL;
+               /* Check whether we only update an existing switch
+                * or add a new switch. */
+               sw = find_switch(cfg->gpio, cfg->name);
+               if (sw != NULL) {
+                       sw->debounce_rising = cfg->debounce_rising;
+                       sw->debounce_falling = cfg->debounce_falling;
+                       sw->notify = cfg->notify;
+                       sw->notify_data = cfg->notify_data;
+                       continue;
+               } else {
+                       if (cfg->gpio < 0 || cfg->name == NULL) {
+                               printk("gpio-switch: required switch not "
+                                      "found (%d, %s)\n", cfg->gpio,
+                                      cfg->name);
+                               continue;
+                       }
+               }
+               sw = kzalloc(sizeof(*sw), GFP_KERNEL);
+               if (sw == NULL) {
+                       printk(KERN_ERR "gpio-switch: kmalloc failed\n");
+                       return -ENOMEM;
+               }
+               strlcpy(sw->name, cfg->name, sizeof(sw->name));
+               sw->gpio = cfg->gpio;
+               sw->flags = cfg->flags;
+               sw->type = cfg->type;
+               sw->debounce_rising = cfg->debounce_rising;
+               sw->debounce_falling = cfg->debounce_falling;
+               sw->notify = cfg->notify;
+               sw->notify_data = cfg->notify_data;
+               if ((r = new_switch(sw)) < 0) {
+                       kfree(sw);
+                       return r;
+               }
+       }
+       return 0;
+}
+
+static void gpio_sw_cleanup(void)
+{
+       struct gpio_switch *sw = NULL, *old = NULL;
+
+       list_for_each_entry(sw, &gpio_switches, node) {
+               if (old != NULL)
+                       kfree(old);
+               flush_scheduled_work();
+               del_timer_sync(&sw->timer);
+
+               free_irq(gpio_to_irq(sw->gpio), sw);
+
+               device_remove_file(&sw->pdev.dev, &dev_attr_state);
+               device_remove_file(&sw->pdev.dev, &dev_attr_type);
+               device_remove_file(&sw->pdev.dev, &dev_attr_direction);
+
+               platform_device_unregister(&sw->pdev);
+               gpio_free(sw->gpio);
+               old = sw;
+       }
+       kfree(old);
+}
+
+static void __init report_initial_state(void)
+{
+       struct gpio_switch *sw;
+
+       list_for_each_entry(sw, &gpio_switches, node) {
+               int state;
+
+               state = gpio_get_value(sw->gpio);
+               if (sw->flags & OMAP_GPIO_SWITCH_FLAG_INVERTED)
+                       state = !state;
+               if (sw->notify != NULL)
+                       sw->notify(sw->notify_data, state);
+               print_sw_state(sw, state);
+       }
+}
+
+static int gpio_sw_remove(struct platform_device *dev)
+{
+       return 0;
+}
+
+static struct platform_driver gpio_sw_driver = {
+       .remove         = gpio_sw_remove,
+       .driver         = {
+               .name   = "gpio-switch",
+       },
+};
+
+void __init omap_register_gpio_switches(const struct omap_gpio_switch *tbl,
+                                       int count)
+{
+       BUG_ON(board_gpio_sw_table != NULL);
+
+       board_gpio_sw_table = tbl;
+       board_gpio_sw_count = count;
+}
+
+static int __init gpio_sw_init(void)
+{
+       int r;
+
+       printk(KERN_INFO "OMAP GPIO switch handler initializing\n");
+
+       r = platform_driver_register(&gpio_sw_driver);
+       if (r)
+               return r;
+
+       gpio_sw_platform_dev = platform_device_register_simple("gpio-switch",
+                                                              -1, NULL, 0);
+       if (IS_ERR(gpio_sw_platform_dev)) {
+               r = PTR_ERR(gpio_sw_platform_dev);
+               goto err1;
+       }
+
+       r = add_atag_switches();
+       if (r < 0)
+               goto err2;
+
+       r = add_board_switches();
+       if (r < 0)
+               goto err2;
+
+       report_initial_state();
+
+       return 0;
+err2:
+       gpio_sw_cleanup();
+       platform_device_unregister(gpio_sw_platform_dev);
+err1:
+       platform_driver_unregister(&gpio_sw_driver);
+       return r;
+}
+
+static void __exit gpio_sw_exit(void)
+{
+       gpio_sw_cleanup();
+       platform_device_unregister(gpio_sw_platform_dev);
+       platform_driver_unregister(&gpio_sw_driver);
+}
+
+#ifndef MODULE
+late_initcall(gpio_sw_init);
+#else
+module_init(gpio_sw_init);
+#endif
+module_exit(gpio_sw_exit);
+
+MODULE_AUTHOR("Juha Yrjölä <juha.yrjola@nokia.com>, Paul Mundt <paul.mundt@nokia.com");
+MODULE_DESCRIPTION("GPIO switch driver");
+MODULE_LICENSE("GPL");
index d3fa41e3d8c5a79235eb687dc4dc9ae92f330b77..210a1c04555488cf9d4d39856557b9caac029b53 100644 (file)
@@ -921,13 +921,10 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
        case METHOD_MPUIO:
        case METHOD_GPIO_1610:
                spin_lock_irqsave(&bank->lock, flags);
-               if (enable) {
+               if (enable)
                        bank->suspend_wakeup |= (1 << gpio);
-                       enable_irq_wake(bank->irq);
-               } else {
-                       disable_irq_wake(bank->irq);
+               else
                        bank->suspend_wakeup &= ~(1 << gpio);
-               }
                spin_unlock_irqrestore(&bank->lock, flags);
                return 0;
 #endif
@@ -940,13 +937,10 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
                        return -EINVAL;
                }
                spin_lock_irqsave(&bank->lock, flags);
-               if (enable) {
+               if (enable)
                        bank->suspend_wakeup |= (1 << gpio);
-                       enable_irq_wake(bank->irq);
-               } else {
-                       disable_irq_wake(bank->irq);
+               else
                        bank->suspend_wakeup &= ~(1 << gpio);
-               }
                spin_unlock_irqrestore(&bank->lock, flags);
                return 0;
 #endif
diff --git a/arch/arm/plat-omap/include/mach/board-nokia.h b/arch/arm/plat-omap/include/mach/board-nokia.h
new file mode 100644 (file)
index 0000000..198d761
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  arch/arm/plat-omap/include/mach/board-nokia.h
+ *
+ *  Information structures for Nokia-specific board config data
+ *
+ *  Copyright (C) 2005 Nokia Corporation
+ */
+
+#ifndef __ASM_ARCH_OMAP_NOKIA_H
+#define __ASM_ARCH_OMAP_NOKIA_H
+
+#include <linux/types.h>
+
+struct tsc2301_platform_data;
+struct dsp_kfunc_device;
+extern void n800_bt_init(void);
+extern void n800_dsp_init(void);
+extern void n800_flash_init(void);
+extern void n800_mmc_init(void);
+extern void n800_pm_init(void);
+extern void n800_usb_init(void);
+extern void n800_cam_init(void);
+extern void n800_audio_init(struct tsc2301_platform_data *);
+extern int n800_audio_enable(struct dsp_kfunc_device *kdev, int stage);
+extern int n800_audio_disable(struct dsp_kfunc_device *kdev, int stage);
+extern void n800_mmc_slot1_cover_handler(void *arg, int state);
+
+#define OMAP_TAG_NOKIA_BT      0x4e01
+#define OMAP_TAG_WLAN_CX3110X  0x4e02
+#define OMAP_TAG_CBUS          0x4e03
+#define OMAP_TAG_EM_ASIC_BB5   0x4e04
+
+#define BT_CHIP_CSR            1
+#define BT_CHIP_TI             2
+
+#define BT_SYSCLK_12           1
+#define BT_SYSCLK_38_4         2
+
+struct omap_bluetooth_config {
+       u8    chip_type;
+       u8    bt_wakeup_gpio;
+       u8    host_wakeup_gpio;
+       u8    reset_gpio;
+       u8    bt_uart;
+       u8    bd_addr[6];
+       u8    bt_sysclk;
+};
+
+struct omap_wlan_cx3110x_config {
+       u8  chip_type;
+       s16 power_gpio;
+       s16 irq_gpio;
+       s16 spi_cs_gpio;
+};
+
+struct omap_cbus_config {
+       s16 clk_gpio;
+       s16 dat_gpio;
+       s16 sel_gpio;
+};
+
+struct omap_em_asic_bb5_config {
+       s16 retu_irq_gpio;
+       s16 tahvo_irq_gpio;
+};
+
+#endif
diff --git a/arch/arm/plat-omap/include/mach/board-rx51.h b/arch/arm/plat-omap/include/mach/board-rx51.h
new file mode 100644 (file)
index 0000000..7b32872
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * linux/include/asm-arm/arch-omap/board-rx51.h
+ *
+ * Copyright (C) 2007 Nokia
+ *
+ * Hardware definitions for Nokia RX-51
+ * based on board-3430sdp.h
+ *
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OMAP_BOARD_RX51_H
+#define __ASM_ARCH_OMAP_BOARD_RX51_H
+
+#include <mach/board-nokia.h>
+
+#ifdef CONFIG_USB_MUSB_SOC
+extern void rx51_usb_init(void);
+#else
+static inline void rx51_usb_init(void) { }
+#endif
+
+extern void n800_bt_init(void);
+
+struct omap_sdrc_params *rx51_get_sdram_timings(void);
+
+#endif /*  __ASM_ARCH_OMAP_BOARD_RX51_H */
+
index 50ea79a0efa258b807b793c6cf58733fcb1b236c..ae8c2db22eb51786222be2a93ff2e31eb39c5b33 100644 (file)
 #define OMAP_TAG_FBMEM         0x4f08
 #define OMAP_TAG_STI_CONSOLE   0x4f09
 #define OMAP_TAG_CAMERA_SENSOR 0x4f0a
+#define OMAP_TAG_PARTITION      0x4f0b
+#define OMAP_TAG_TEA5761       0x4f10
+#define OMAP_TAG_TMP105                0x4f11
 
 #define OMAP_TAG_BOOT_REASON    0x4f80
-#define OMAP_TAG_FLASH_PART    0x4f81
+#define OMAP_TAG_FLASH_PART_STR        0x4f81
 #define OMAP_TAG_VERSION_STR   0x4f82
 
 struct omap_clock_config {
@@ -43,12 +46,6 @@ struct omap_sti_console_config {
        u8 channel;
 };
 
-struct omap_camera_sensor_config {
-       u16 reset_gpio;
-       int (*power_on)(void * data);
-       int (*power_off)(void * data);
-};
-
 struct omap_usb_config {
        /* Configure drivers according to the connectors on your board:
         *  - "A" connector (rectagular)
@@ -108,9 +105,9 @@ struct omap_pwm_led_platform_data {
 struct omap_gpio_switch_config {
        char name[12];
        u16 gpio;
-       int flags:4;
-       int type:4;
-       int key_code:24; /* Linux key code */
+       u8 flags:4;
+       u8 type:4;
+       unsigned int key_code:24; /* Linux key code */
 };
 
 struct omap_uart_config {
@@ -118,8 +115,25 @@ struct omap_uart_config {
        unsigned int enabled_uarts;
 };
 
+struct omap_tea5761_config {
+       u16 enable_gpio;
+};
+
+/* This cannot be passed from the bootloader */
+struct omap_tmp105_config {
+       u16 tmp105_irq_pin;
+       int (* set_power)(int enable);
+};
+
+struct omap_partition_config {
+       char name[16];
+       unsigned int size;
+       unsigned int offset;
+       /* same as in include/linux/mtd/partitions.h */
+       unsigned int mask_flags;
+};
 
-struct omap_flash_part_config {
+struct omap_flash_part_str_config {
        char part_table[0];
 };
 
index 54fe9665b1826f674b761685d443f54c48567864..224b0770ec2dcd41e461aadf49df797731153f30 100644 (file)
 #define DMA_THREAD_FIFO_25             (0x02 << 14)
 #define DMA_THREAD_FIFO_50             (0x03 << 14)
 
+/* DMA4_OCP_SYSCONFIG bits */
+#define DMA_SYSCONFIG_MIDLEMODE_MASK           (3 << 12)
+#define DMA_SYSCONFIG_CLOCKACTIVITY_MASK       (3 << 8)
+#define DMA_SYSCONFIG_EMUFREE                  (1 << 5)
+#define DMA_SYSCONFIG_SIDLEMODE_MASK           (3 << 3)
+#define DMA_SYSCONFIG_SOFTRESET                        (1 << 2)
+#define DMA_SYSCONFIG_AUTOIDLE                 (1 << 0)
+
+#define DMA_SYSCONFIG_MIDLEMODE(n)             ((n) << 12)
+#define DMA_SYSCONFIG_SIDLEMODE(n)             ((n) << 3)
+
+#define DMA_IDLEMODE_SMARTIDLE                 0x2
+#define DMA_IDLEMODE_NO_IDLE                   0x1
+#define DMA_IDLEMODE_FORCE_IDLE                        0x0
+
 /* Chaining modes*/
 #ifndef CONFIG_ARCH_OMAP1
 #define OMAP_DMA_STATIC_CHAIN          0x1
index 10da0e07c0cf8998b926a3680b042936e77e5129..2096780660937ceef27eb24e0b437ab32af88bc1 100644 (file)
  *     low  -> inactive
  *
  */
-#define OMAP_GPIO_SWITCH_TYPE_COVER            0x0000
-#define OMAP_GPIO_SWITCH_TYPE_CONNECTION       0x0001
-#define OMAP_GPIO_SWITCH_TYPE_ACTIVITY         0x0002
-#define OMAP_GPIO_SWITCH_FLAG_INVERTED         0x0001
-#define OMAP_GPIO_SWITCH_FLAG_OUTPUT           0x0002
+#define OMAP_GPIO_SWITCH_TYPE_COVER                    0x0000
+#define OMAP_GPIO_SWITCH_TYPE_CONNECTION               0x0001
+#define OMAP_GPIO_SWITCH_TYPE_ACTIVITY                 0x0002
+#define OMAP_GPIO_SWITCH_FLAG_INVERTED                 0x0001
+#define OMAP_GPIO_SWITCH_FLAG_OUTPUT                   0x0002
+#define OMAP_GPIO_SWITCH_FLAG_OUTPUT_INIT_ACTIVE       0x0004
 
 struct omap_gpio_switch {
        const char *name;
@@ -48,7 +49,11 @@ struct omap_gpio_switch {
 };
 
 /* Call at init time only */
+#ifdef CONFIG_OMAP_GPIO_SWITCH
 extern void omap_register_gpio_switches(const struct omap_gpio_switch *tbl,
                                        int count);
+#else
+#define omap_register_gpio_switches(tbl, count)        do { } while (0)
+#endif
 
 #endif
diff --git a/arch/arm/plat-omap/include/mach/gpioexpander.h b/arch/arm/plat-omap/include/mach/gpioexpander.h
deleted file mode 100644 (file)
index 90444a0..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/gpioexpander.h
- *
- *
- * Copyright (C) 2004 Texas Instruments, Inc.
- *
- * This package is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef __ASM_ARCH_OMAP_GPIOEXPANDER_H
-#define __ASM_ARCH_OMAP_GPIOEXPANDER_H
-
-/* Function Prototypes for GPIO Expander functions */
-
-#ifdef CONFIG_GPIOEXPANDER_OMAP
-int read_gpio_expa(u8 *, int);
-int write_gpio_expa(u8 , int);
-#else
-static inline int read_gpio_expa(u8 *val, int addr)
-{
-       return 0;
-}
-static inline int write_gpio_expa(u8 val, int addr)
-{
-       return 0;
-}
-#endif
-
-#endif /* __ASM_ARCH_OMAP_GPIOEXPANDER_H */
index 921b16532ff55c4e28301cb5bcce975de546a70b..b0b2edf8c550615372c50f538da9aaf3c49a26a3 100644 (file)
 #define GPMC_CS_NAND_ADDRESS   0x20
 #define GPMC_CS_NAND_DATA      0x24
 
+/*
+ * The following gpmc registers are being used by
+ * nand driver and hence is defined here.
+ * TBD: Move them to gpmc.c by providing appropriate
+ *  methods to read and write into these registers
+ */
+#define GPMC_IRQSTATUS         0x18
 #define GPMC_CONFIG            0x50
 #define GPMC_STATUS            0x54
+#define GPMC_CS0_BASE           0x60
+#define GPMC_CS_SIZE            0x30
+
 
 #define GPMC_CONFIG1_WRAPBURST_SUPP     (1 << 31)
 #define GPMC_CONFIG1_READMULTIPLE_SUPP  (1 << 30)
index 7f57ee66f364dd0ad65092f58d62066c95a3604d..9499a0520e0f5554de292d4cef2e757fd0b4d22e 100644 (file)
 #define INT_34XX_MMC3_IRQ      94
 #define INT_34XX_GPT12_IRQ     95
 
-#define        INT_34XX_BENCH_MPU_EMUL 3
-
 /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and
  * 16 MPUIO lines */
 #define OMAP_MAX_GPIO_LINES    192
 
 #ifndef __ASSEMBLY__
 extern void omap_init_irq(void);
+extern int omap_irq_pending(void);
 #endif
 
 #include <mach/hardware.h>
index 232923aaf61d34ed0f66daf5af54d1fad7c73a13..b7f270a6782188a471469a366c7ea86eac45ccbb 100644 (file)
@@ -14,6 +14,7 @@ struct omap_kp_platform_data {
        int rows;
        int cols;
        int *keymap;
+       int irq;
        unsigned int keymapsize;
        unsigned int rep:1;
        unsigned long delay;
@@ -33,7 +34,12 @@ struct omap_kp_platform_data {
 #define GROUP_3                (3 << 16)
 #define GROUP_MASK     GROUP_3
 
+#define ROWCOL_MASK            0xFF000000
+#define KEY_PERSISTENT         0x00800000
+#define KEYNUM_MASK            0x00EFFFFF
 #define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
+#define PERSISTENT_KEY(col, row) (((col) << 28) | ((row) << 24) | \
+                                               KEY_PERSISTENT)
 
 #endif
 
index 4435bd434e179b995adfbec2944ac24436aa6119..81d5b36534b340680ffc36fde156e9cafbb70e2d 100644 (file)
@@ -79,7 +79,6 @@ struct omap_mmc_platform_data {
 
                /* use the internal clock */
                unsigned internal_clock:1;
-               s16 power_pin;
 
                int switch_pin;                 /* gpio (card detect) */
                int gpio_wp;                    /* gpio (write protect) */
diff --git a/arch/arm/plat-omap/include/mach/sti.h b/arch/arm/plat-omap/include/mach/sti.h
new file mode 100644 (file)
index 0000000..af43917
--- /dev/null
@@ -0,0 +1,172 @@
+#ifndef __ASM_ARCH_OMAP_STI_H
+#define __ASM_ARCH_OMAP_STI_H
+
+#include <asm/io.h>
+
+/*
+ * STI/SDTI
+ */
+#define STI_REVISION           0x00
+#define STI_SYSCONFIG          0x10
+#define STI_SYSSTATUS          0x14
+#define STI_IRQSTATUS          0x18
+#define STI_IRQSETEN           0x1c
+
+#if defined(CONFIG_ARCH_OMAP1)
+#define STI_IRQCLREN           0x20
+#define STI_ER                 0x24
+#define STI_DR                 0x28
+#define STI_RX_DR              0x2c
+#define STI_RX_STATUS          0x30
+#define STI_CLK_CTRL           0x34
+#define STI_IOBOTT0            0x4c
+#define STI_IOTOP0             0x50
+#define STI_IOBOTT1            0x54
+#define STI_IOTOP1             0x58
+#define STI_SERIAL_CFG         0x60
+
+#define STI_OCPT2_MATCH_INT    0
+#define STI_OCPT1_MATCH_INT    1
+#define STI_EMIFS_MATCH_INT    2
+#define STI_EMIFF_MATCH_INT    3
+#define STI_IO_MATCH_INT       4
+#define STI_RX_INT             5
+#define STI_DUMP_REQUEST_INT   6
+#define STI_DUMP_UNDERRUN_INT  7
+#define STI_WAKEUP_INT         9
+
+#define STI_NR_IRQS    10
+
+#define STI_IRQSTATUS_MASK     0x2ff
+
+#define STI_RXFIFO_EMPTY       (1 << 0)
+
+/*
+ * We use the following enums to retain consistency with the STI "functional"
+ * specification.
+ */
+
+/* STI_ER */
+enum {
+       UnlockStatMatch = (1 <<  2), /* Unlock status match event regs */
+       IOMPUStr1En1    = (1 <<  3), /* MPU IO match, strobe 1, window 1 */
+       IOMPUStr0En1    = (1 <<  4), /* MPU IO match, strobe 0, window 1 */
+       IOMPUStr1En0    = (1 <<  5), /* MPU IO match, strobe 1, window 0 */
+       IOMPUStr0En0    = (1 <<  6), /* MPU IO match, strobe 0, window 0 */
+       IODSPStr1En1    = (1 <<  7), /* DSP IO match, strobe 1, window 1 */
+       IODSPStr0En1    = (1 <<  8), /* DSP IO match, strobe 0, window 1 */
+       IODSPStr1En0    = (1 <<  9), /* DSP IO match, strobe 1, window 0 */
+       IODSPStr0En0    = (1 << 10), /* DSP IO match, strobe 0, window 0 */
+       MemMatchEn      = (1 << 11), /* Memory matched event */
+       DSPCmdEn        = (1 << 12), /* DSP command write */
+       MPUCmdEn        = (1 << 13), /* MPU command write */
+       MemDumpEn       = (1 << 14), /* System memory dump */
+       STIEn           = (1 << 15), /* Global trace enable */
+};
+
+#define STI_PERCHANNEL_SIZE    4
+
+#define to_channel_address(channel) \
+       (sti_channel_base + STI_PERCHANNEL_SIZE * (channel))
+
+#elif defined(CONFIG_ARCH_OMAP2)
+
+/* XTI interrupt bits */
+enum {
+       STI_WAKEUP_INT  = 0,
+       STI_ETB_THRESHOLD_INT,
+       STI_RX_INT,
+       STI_DUMP_REQUEST_INT,
+       STI_NR_IRQS,
+};
+
+/* XTI_TRACESELECT */
+enum {
+       CmdTimeStampEn  = (1 << 0),     /* Command write timestamps */
+       WinTimeStampEn  = (1 << 1),     /* Window match timestamps */
+       WinMatchEn      = (1 << 2),     /* Window match trace */
+       DSPCmdEn        = (1 << 3),     /* DSP command write */
+       MPUCmdEn        = (1 << 4),     /* MPU command write */
+       MemDumpEn0      = (1 << 5),     /* System memory dump */
+       MemDumpEn1      = (1 << 6),
+       MemDumpEn2      = (1 << 7),
+       ExtTriggerEn    = (1 << 8),     /* External trace trigger */
+       STIEn           = (1 << 9),     /* System trace enable */
+};
+
+#define STI_IRQSTATUS_MASK     0x0f
+#define STI_PERCHANNEL_SIZE    64
+
+/* XTI registers */
+#define XTI_SYSSTATUS          0x14
+#define XTI_TRACESELECT                0x24
+#define XTI_RXDATA             0x28
+#define XTI_SCLKCRTL           0x2c
+#define XTI_SCONFIG            0x30
+
+/* STI Compatability */
+#define STI_RX_STATUS          XTI_SYSSTATUS
+#define STI_IRQCLREN           STI_IRQSETEN
+#define STI_ER                 XTI_TRACESELECT
+#define STI_DR                 XTI_TRACESELECT
+#define STI_RX_DR              XTI_RXDATA
+#define STI_CLK_CTRL           XTI_SCLKCRTL
+#define STI_SERIAL_CFG         XTI_SCONFIG
+
+#define STI_RXFIFO_EMPTY       (1 << 8)
+
+#define to_channel_address(channel) \
+       (sti_channel_base + STI_PERCHANNEL_SIZE * (channel))
+
+#elif defined(CONFIG_ARCH_OMAP3)
+
+#define STI_PERCHANNEL_SIZE    0x1000
+#define to_channel_address(channel) \
+       (sti_channel_base + STI_PERCHANNEL_SIZE * (channel) + 0x800)
+
+#endif
+
+/* arch/arm/plat-omap/sti/sti.c */
+extern void __iomem *sti_base, *sti_channel_base;
+
+int sti_request_irq(unsigned int irq, void *handler, unsigned long arg);
+void sti_free_irq(unsigned int irq);
+void sti_enable_irq(unsigned int irq);
+void sti_disable_irq(unsigned int irq);
+void sti_ack_irq(unsigned int irq);
+
+int sti_trace_enable(int event);
+void sti_trace_disable(int event);
+
+void sti_channel_write_trace(int len, int id, void *data, unsigned int channel);
+
+/* arch/arm/plat-omap/sti/sti-fifo.c */
+int sti_read_packet(unsigned char *buf, int maxsize);
+
+static inline unsigned long sti_readl(unsigned long reg)
+{
+       return __raw_readl(sti_base + reg);
+}
+
+static inline void sti_writel(unsigned long data, unsigned long reg)
+{
+       __raw_writel(data, sti_base + reg);
+}
+
+static inline void sti_channel_writeb(unsigned char data, unsigned int channel)
+{
+       __raw_writeb(data, to_channel_address(channel));
+}
+
+static inline void sti_channel_writel(unsigned long data, unsigned int channel)
+{
+       __raw_writel(data, to_channel_address(channel));
+}
+
+#define STI_TRACE_CONTROL_CHANNEL      253
+
+static inline void sti_channel_flush(unsigned int channel)
+{
+       sti_channel_writeb(channel, STI_TRACE_CONTROL_CHANNEL);
+}
+#endif /* __ASM_ARCH_OMAP_STI_H */
index 69f0ceed500bd174467e3b1cd7e579d160c9cc9e..f6d334ffaae85987e6e74b9576463a89a1bde821 100644 (file)
@@ -33,9 +33,17 @@ extern void usb_musb_init(void);
 static inline void usb_musb_init(void)
 {
 }
-#endif
+#endif /* !OMAP1 && !MUSB */
 
-#endif
+#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
+extern void usb_ehci_init(void);
+#else
+static inline void usb_ehci_init(void)
+{
+}
+#endif /* !OMAP1 && !EHCI */
+
+#endif /* !OMAP1 */
 
 void omap_usb_init(struct omap_usb_config *pdata);
 
index dc104cd96197ce63e983cbd4139830bbe36ce29b..b97dfafeebda6179a5ef652fb0e8070a2ef4b3ae 100644 (file)
@@ -17,5 +17,5 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
-#define VMALLOC_END      (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END      (PAGE_OFFSET + 0x18000000)
 
index fa5297d643d3f545d181551bdee853a2a0938251..e1e637f222c6673fb102c588eb0ef6616ba36462 100644 (file)
@@ -38,8 +38,8 @@
 #define OMAP1_SRAM_VA          VMALLOC_END
 #define OMAP2_SRAM_PA          0x40200000
 #define OMAP2_SRAM_PUB_PA      0x4020f800
-#define OMAP2_SRAM_VA          VMALLOC_END
-#define OMAP2_SRAM_PUB_VA      (VMALLOC_END + 0x800)
+#define OMAP2_SRAM_VA          0xe3000000
+#define OMAP2_SRAM_PUB_VA      (OMAP2_SRAM_VA + 0x800)
 #define OMAP3_SRAM_PA           0x40200000
 #define OMAP3_SRAM_VA           0xd7000000
 #define OMAP3_SRAM_PUB_PA       0x40208000
@@ -359,14 +359,14 @@ static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl,
                                              u32 m2);
 u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
                              u32 sdrc_actim_ctrlb, u32 m2)
-{
+ {
        if (!_omap3_sram_configure_core_dpll)
                omap_sram_error();
 
        return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl,
                                               sdrc_actim_ctrla,
                                               sdrc_actim_ctrlb, m2);
-}
+ }
 
 /* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */
 void restore_sram_functions(void)
@@ -378,7 +378,7 @@ void restore_sram_functions(void)
                               omap3_sram_configure_core_dpll_sz);
 }
 
-int __init omap34xx_sram_init(void)
+int __init omap3_sram_init(void)
 {
        _omap3_sram_configure_core_dpll =
                omap_sram_push(omap3_sram_configure_core_dpll,
@@ -387,7 +387,7 @@ int __init omap34xx_sram_init(void)
        return 0;
 }
 #else
-static inline int omap34xx_sram_init(void)
+static inline int omap3_sram_init(void)
 {
        return 0;
 }
@@ -405,7 +405,7 @@ int __init omap_sram_init(void)
        else if (cpu_is_omap2430())
                omap243x_sram_init();
        else if (cpu_is_omap34xx())
-               omap34xx_sram_init();
+               omap3_sram_init();
 
        return 0;
 }