Merge tag 'imx-eukrea' of git://git.pengutronix.de/git/imx/linux-2.6 into next/boards
authorOlof Johansson <olof@lixom.net>
Wed, 9 May 2012 09:57:26 +0000 (02:57 -0700)
committerOlof Johansson <olof@lixom.net>
Wed, 9 May 2012 09:57:26 +0000 (02:57 -0700)
ARM i.MX Eukrea Patches for 3.5

By Eric BĂ©nard (11) and Denis Carikli (1)
via Sascha Hauer
* tag 'imx-eukrea' of git://git.pengutronix.de/git/imx/linux-2.6:
  ARM: imx: eukrea_mbimxsd rename to eukrea_mbimxsd51
  ARM: imx: eukrea_mbimxsd25: use IMX_GPIO_NR
  ARM: imx: eukrea_mbimxsd25: don't free twice GPIO_SWITCH1
  ARM: imx: eukrea_mbimxsd: add backlight and lcd support
  ARM: imx: eukrea_cpuimx51sd: support rev2 PCB
  ARM: imx: eukrea_mbimxsd: add audio support
  ARM: imx: eukrea_cpuimx51sd: add watchdog support
  ARM: imx: eukrea-cpuimx51: remove board
  ARM: imx: eukrea_mbimxsd35: add spi controler and spidev support
  ARM: imx: eukrea_cpuimx25: add watchdog support
  ARM: imx: eukrea_mbimxsd25: add spi controler and spidev support
  ARM: imx: eukrea_cpuimx25: enable workaround ENGcm09152

22 files changed:
arch/arm/configs/imx_v4_v5_defconfig
arch/arm/mach-imx/mach-imx27_visstrim_m10.c
arch/arm/mach-imx/mach-mx35_3ds.c
arch/arm/mach-mmp/Kconfig
arch/arm/mach-mmp/aspenite.c
arch/arm/mach-mmp/devices.c
arch/arm/mach-mmp/include/mach/devices.h
arch/arm/mach-mmp/include/mach/pxa168.h
arch/arm/mach-mmp/include/mach/pxa910.h
arch/arm/mach-mmp/include/mach/regs-usb.h [new file with mode: 0644]
arch/arm/mach-mmp/pxa168.c
arch/arm/mach-mmp/pxa910.c
arch/arm/mach-mmp/ttc_dkb.c
arch/arm/mach-pxa/hx4700.c
arch/arm/mach-pxa/include/mach/mioa701.h
arch/arm/mach-pxa/include/mach/pcm990_baseboard.h
arch/arm/mach-pxa/mioa701.c
arch/arm/mach-pxa/pcm990-baseboard.c
drivers/pcmcia/Kconfig
drivers/pcmcia/Makefile
drivers/pcmcia/pxa2xx_hx4700.c [new file with mode: 0644]
include/linux/mfd/asic3.h

index 6b31cb60daabd516579d55f1cb2b5a7198cb3776..09a02963cf58ab9fadbc6fc5d9ecfffdf2ba35c2 100644 (file)
@@ -92,6 +92,7 @@ CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ADS7846=m
+CONFIG_TOUCHSCREEN_MC13783=m
 # CONFIG_SERIO is not set
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_8250=m
@@ -107,7 +108,8 @@ CONFIG_SPI_SPIDEV=y
 CONFIG_W1=y
 CONFIG_W1_MASTER_MXC=y
 CONFIG_W1_SLAVE_THERM=y
-# CONFIG_HWMON is not set
+CONFIG_HWMON=m
+CONFIG_SENSORS_MC13783_ADC=m
 CONFIG_WATCHDOG=y
 CONFIG_IMX2_WDT=y
 CONFIG_MFD_MC13XXX=y
index f7b074f496f070b5654a6ab99407f4281dfe04d7..748ba2e311b56710ed195e27b3e5b3d26684364d 100644 (file)
@@ -38,6 +38,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
+#include <asm/system.h>
 #include <mach/common.h>
 #include <mach/iomux-mx27.h>
 
 #define OTG_PHY_CS_GPIO (GPIO_PORTF + 17)
 #define SDHC1_IRQ IRQ_GPIOB(25)
 
+#define MOTHERBOARD_BIT2       (GPIO_PORTD + 31)
+#define MOTHERBOARD_BIT1       (GPIO_PORTD + 30)
+#define MOTHERBOARD_BIT0       (GPIO_PORTD + 29)
+
+#define EXPBOARD_BIT2          (GPIO_PORTD + 25)
+#define EXPBOARD_BIT1          (GPIO_PORTD + 27)
+#define EXPBOARD_BIT0          (GPIO_PORTD + 28)
+
 static const int visstrim_m10_pins[] __initconst = {
        /* UART1 (console) */
        PE12_PF_UART1_TXD,
@@ -119,6 +128,23 @@ static const int visstrim_m10_pins[] __initconst = {
        PB19_PF_CSI_D7,
        PB20_PF_CSI_VSYNC,
        PB21_PF_CSI_HSYNC,
+       /* mother board version */
+       MOTHERBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+       MOTHERBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+       MOTHERBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+       /* expansion board version */
+       EXPBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+       EXPBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+       EXPBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+};
+
+static struct gpio visstrim_m10_version_gpios[] = {
+       { EXPBOARD_BIT0, GPIOF_IN, "exp-version-0" },
+       { EXPBOARD_BIT1, GPIOF_IN, "exp-version-1" },
+       { EXPBOARD_BIT2, GPIOF_IN, "exp-version-2" },
+       { MOTHERBOARD_BIT0, GPIOF_IN, "mother-version-0" },
+       { MOTHERBOARD_BIT1, GPIOF_IN, "mother-version-1" },
+       { MOTHERBOARD_BIT2, GPIOF_IN, "mother-version-2" },
 };
 
 /* Camera */
@@ -369,11 +395,40 @@ static const struct imx_ssi_platform_data visstrim_m10_ssi_pdata __initconst = {
        .flags                  = IMX_SSI_DMA | IMX_SSI_SYN,
 };
 
+static void __init visstrim_m10_revision(void)
+{
+       int exp_version = 0;
+       int mo_version = 0;
+       int ret;
+
+       ret = gpio_request_array(visstrim_m10_version_gpios,
+                                ARRAY_SIZE(visstrim_m10_version_gpios));
+       if (ret) {
+               pr_err("Failed to request version gpios");
+               return;
+       }
+
+       /* Get expansion board version (negative logic) */
+       exp_version |= !gpio_get_value(EXPBOARD_BIT2) << 2;
+       exp_version |= !gpio_get_value(EXPBOARD_BIT1) << 1;
+       exp_version |= !gpio_get_value(EXPBOARD_BIT0);
+
+       /* Get mother board version (negative logic) */
+       mo_version |= !gpio_get_value(MOTHERBOARD_BIT2) << 2;
+       mo_version |= !gpio_get_value(MOTHERBOARD_BIT1) << 1;
+       mo_version |= !gpio_get_value(MOTHERBOARD_BIT0);
+
+       system_rev = 0x27000;
+       system_rev |= (mo_version << 4);
+       system_rev |= exp_version;
+}
+
 static void __init visstrim_m10_board_init(void)
 {
        int ret;
 
        imx27_soc_init();
+       visstrim_m10_revision();
 
        ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins,
                        ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10");
index 6ae51c6b95b7c02992d27d6f053b9fb289a92b36..e99b016bbbb6724197a0831927fbe85e24a6f8a9 100644 (file)
@@ -34,6 +34,8 @@
 #include <linux/usb/otg.h>
 
 #include <linux/mtd/physmap.h>
+#include <linux/mfd/mc13892.h>
+#include <linux/regulator/machine.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -253,6 +255,8 @@ static iomux_v3_cfg_t mx35pdk_pads[] = {
        MX35_PAD_CSI_MCLK__IPU_CSI_MCLK,
        MX35_PAD_CSI_PIXCLK__IPU_CSI_PIXCLK,
        MX35_PAD_CSI_VSYNC__IPU_CSI_VSYNC,
+       /*PMIC IRQ*/
+       MX35_PAD_GPIO2_0__GPIO2_0,
 };
 
 /*
@@ -317,6 +321,193 @@ static struct platform_device mx35_3ds_ov2640 = {
        },
 };
 
+static struct regulator_consumer_supply sw1_consumers[] = {
+       {
+               .supply = "cpu_vcc",
+       }
+};
+
+static struct regulator_consumer_supply vcam_consumers[] = {
+       /* sgtl5000 */
+       REGULATOR_SUPPLY("VDDA", "0-000a"),
+};
+
+static struct regulator_consumer_supply vaudio_consumers[] = {
+       REGULATOR_SUPPLY("cmos_vio", "soc-camera-pdrv.0"),
+};
+
+static struct regulator_init_data sw1_init = {
+       .constraints = {
+               .name = "SW1",
+               .min_uV = 600000,
+               .max_uV = 1375000,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+               .valid_modes_mask = 0,
+               .always_on = 1,
+               .boot_on = 1,
+       },
+       .num_consumer_supplies = ARRAY_SIZE(sw1_consumers),
+       .consumer_supplies = sw1_consumers,
+};
+
+static struct regulator_init_data sw2_init = {
+       .constraints = {
+               .name = "SW2",
+               .always_on = 1,
+               .boot_on = 1,
+       }
+};
+
+static struct regulator_init_data sw3_init = {
+       .constraints = {
+               .name = "SW3",
+               .always_on = 1,
+               .boot_on = 1,
+       }
+};
+
+static struct regulator_init_data sw4_init = {
+       .constraints = {
+               .name = "SW4",
+               .always_on = 1,
+               .boot_on = 1,
+       }
+};
+
+static struct regulator_init_data viohi_init = {
+       .constraints = {
+               .name = "VIOHI",
+               .boot_on = 1,
+       }
+};
+
+static struct regulator_init_data vusb_init = {
+       .constraints = {
+               .name = "VUSB",
+               .boot_on = 1,
+       }
+};
+
+static struct regulator_init_data vdig_init = {
+       .constraints = {
+               .name = "VDIG",
+               .boot_on = 1,
+       }
+};
+
+static struct regulator_init_data vpll_init = {
+       .constraints = {
+               .name = "VPLL",
+               .boot_on = 1,
+       }
+};
+
+static struct regulator_init_data vusb2_init = {
+       .constraints = {
+               .name = "VUSB2",
+               .boot_on = 1,
+       }
+};
+
+static struct regulator_init_data vvideo_init = {
+       .constraints = {
+               .name = "VVIDEO",
+               .boot_on = 1
+       }
+};
+
+static struct regulator_init_data vaudio_init = {
+       .constraints = {
+               .name = "VAUDIO",
+               .min_uV = 2300000,
+               .max_uV = 3000000,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+               .boot_on = 1
+       },
+       .num_consumer_supplies = ARRAY_SIZE(vaudio_consumers),
+       .consumer_supplies = vaudio_consumers,
+};
+
+static struct regulator_init_data vcam_init = {
+       .constraints = {
+               .name = "VCAM",
+               .min_uV = 2500000,
+               .max_uV = 3000000,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+                                       REGULATOR_CHANGE_MODE,
+               .valid_modes_mask = REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL,
+               .boot_on = 1
+       },
+       .num_consumer_supplies = ARRAY_SIZE(vcam_consumers),
+       .consumer_supplies = vcam_consumers,
+};
+
+static struct regulator_init_data vgen1_init = {
+       .constraints = {
+               .name = "VGEN1",
+       }
+};
+
+static struct regulator_init_data vgen2_init = {
+       .constraints = {
+               .name = "VGEN2",
+               .boot_on = 1,
+       }
+};
+
+static struct regulator_init_data vgen3_init = {
+       .constraints = {
+               .name = "VGEN3",
+       }
+};
+
+static struct mc13xxx_regulator_init_data mx35_3ds_regulators[] = {
+       { .id = MC13892_SW1, .init_data = &sw1_init },
+       { .id = MC13892_SW2, .init_data = &sw2_init },
+       { .id = MC13892_SW3, .init_data = &sw3_init },
+       { .id = MC13892_SW4, .init_data = &sw4_init },
+       { .id = MC13892_VIOHI, .init_data = &viohi_init },
+       { .id = MC13892_VPLL, .init_data = &vpll_init },
+       { .id = MC13892_VDIG, .init_data = &vdig_init },
+       { .id = MC13892_VUSB2, .init_data = &vusb2_init },
+       { .id = MC13892_VVIDEO, .init_data = &vvideo_init },
+       { .id = MC13892_VAUDIO, .init_data = &vaudio_init },
+       { .id = MC13892_VCAM, .init_data = &vcam_init },
+       { .id = MC13892_VGEN1, .init_data = &vgen1_init },
+       { .id = MC13892_VGEN2, .init_data = &vgen2_init },
+       { .id = MC13892_VGEN3, .init_data = &vgen3_init },
+       { .id = MC13892_VUSB, .init_data = &vusb_init },
+};
+
+static struct mc13xxx_platform_data mx35_3ds_mc13892_data = {
+       .flags = MC13XXX_USE_RTC | MC13XXX_USE_TOUCHSCREEN,
+       .regulators = {
+               .num_regulators = ARRAY_SIZE(mx35_3ds_regulators),
+               .regulators = mx35_3ds_regulators,
+       },
+};
+
+#define GPIO_PMIC_INT IMX_GPIO_NR(2, 0)
+
+static struct i2c_board_info mx35_3ds_i2c_mc13892 = {
+
+       I2C_BOARD_INFO("mc13892", 0x08),
+       .platform_data = &mx35_3ds_mc13892_data,
+       .irq = IMX_GPIO_TO_IRQ(GPIO_PMIC_INT),
+};
+
+static void __init imx35_3ds_init_mc13892(void)
+{
+       int ret = gpio_request_one(GPIO_PMIC_INT, GPIOF_DIR_IN, "pmic irq");
+
+       if (ret) {
+               pr_err("failed to get pmic irq: %d\n", ret);
+               return;
+       }
+
+       i2c_register_board_info(0, &mx35_3ds_i2c_mc13892, 1);
+}
+
 static int mx35_3ds_otg_init(struct platform_device *pdev)
 {
        return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERNAL_PHY);
@@ -412,6 +603,8 @@ static void __init mx35_3ds_init(void)
        imx35_fb_pdev = imx35_add_mx3_sdc_fb(&mx3fb_pdata);
        mx35_3ds_lcd.dev.parent = &imx35_fb_pdev->dev;
        platform_device_register(&mx35_3ds_lcd);
+
+       imx35_3ds_init_mc13892();
 }
 
 static void __init mx35pdk_timer_init(void)
index 5a90b9a3ab6efa753ef830171f8f5b6f97df9b5d..fa03974fd8385a7c02f3e41412b6619ed15cd577 100644 (file)
@@ -113,4 +113,11 @@ config CPU_MMP2
        select CPU_PJ4
        help
          Select code specific to MMP2. MMP2 is ARMv7 compatible.
+
+config USB_EHCI_MV_U2O
+        bool "EHCI support for PXA USB OTG controller"
+       depends on USB_EHCI_MV
+       help
+         Enables support for OTG controller which can be switched to host mode.
+
 endif
index bf5d8e195c3efb03849660ffac3d923897e88b33..223090b1444d099e01f6c5d96799d06a6b589e35 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
 #include <linux/interrupt.h>
+#include <linux/platform_data/mv_usb.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -221,6 +222,21 @@ static struct pxa27x_keypad_platform_data aspenite_keypad_info __initdata = {
        .debounce_interval      = 30,
 };
 
+#if defined(CONFIG_USB_EHCI_MV)
+static char *pxa168_sph_clock_name[] = {
+       [0] = "PXA168-USBCLK",
+};
+
+static struct mv_usb_platform_data pxa168_sph_pdata = {
+       .clknum         = 1,
+       .clkname        = pxa168_sph_clock_name,
+       .mode           = MV_USB_MODE_HOST,
+       .phy_init       = pxa_usb_phy_init,
+       .phy_deinit     = pxa_usb_phy_deinit,
+       .set_vbus       = NULL,
+};
+#endif
+
 static void __init common_init(void)
 {
        mfp_config(ARRAY_AND_SIZE(common_pin_config));
@@ -236,6 +252,10 @@ static void __init common_init(void)
 
        /* off-chip devices */
        platform_device_register(&smc91x_device);
+
+#if defined(CONFIG_USB_EHCI_MV)
+       pxa168_add_usb_host(&pxa168_sph_pdata);
+#endif
 }
 
 MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform")
index 191d9dea87316f173777737b54ccdbbc2e10fe90..dd2d8b103cc8e4416f3e6575524898548d104d4b 100644 (file)
@@ -9,9 +9,13 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/delay.h>
 
 #include <asm/irq.h>
+#include <mach/irqs.h>
 #include <mach/devices.h>
+#include <mach/cputype.h>
+#include <mach/regs-usb.h>
 
 int __init pxa_register_device(struct pxa_device_desc *desc,
                                void *data, size_t size)
@@ -67,3 +71,281 @@ int __init pxa_register_device(struct pxa_device_desc *desc,
 
        return platform_device_add(pdev);
 }
+
+#if defined(CONFIG_USB) || defined(CONFIG_USB_GADGET)
+
+/*****************************************************************************
+ * The registers read/write routines
+ *****************************************************************************/
+
+static unsigned int u2o_get(void __iomem *base, unsigned int offset)
+{
+       return readl_relaxed(base + offset);
+}
+
+static void u2o_set(void __iomem *base, unsigned int offset,
+               unsigned int value)
+{
+       u32 reg;
+
+       reg = readl_relaxed(base + offset);
+       reg |= value;
+       writel_relaxed(reg, base + offset);
+       readl_relaxed(base + offset);
+}
+
+static void u2o_clear(void __iomem *base, unsigned int offset,
+               unsigned int value)
+{
+       u32 reg;
+
+       reg = readl_relaxed(base + offset);
+       reg &= ~value;
+       writel_relaxed(reg, base + offset);
+       readl_relaxed(base + offset);
+}
+
+static void u2o_write(void __iomem *base, unsigned int offset,
+               unsigned int value)
+{
+       writel_relaxed(value, base + offset);
+       readl_relaxed(base + offset);
+}
+
+#if defined(CONFIG_USB_MV_UDC) || defined(CONFIG_USB_EHCI_MV)
+
+#if defined(CONFIG_CPU_PXA910) || defined(CONFIG_CPU_PXA168)
+
+static DEFINE_MUTEX(phy_lock);
+static int phy_init_cnt;
+
+static int usb_phy_init_internal(void __iomem *base)
+{
+       int loops;
+
+       pr_info("Init usb phy!!!\n");
+
+       /* Initialize the USB PHY power */
+       if (cpu_is_pxa910()) {
+               u2o_set(base, UTMI_CTRL, (1<<UTMI_CTRL_INPKT_DELAY_SOF_SHIFT)
+                       | (1<<UTMI_CTRL_PU_REF_SHIFT));
+       }
+
+       u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT);
+       u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT);
+
+       /* UTMI_PLL settings */
+       u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK
+               | UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK
+               | UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK
+               | UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK);
+
+       u2o_set(base, UTMI_PLL, 0xee<<UTMI_PLL_FBDIV_SHIFT
+               | 0xb<<UTMI_PLL_REFDIV_SHIFT | 3<<UTMI_PLL_PLLVDD18_SHIFT
+               | 3<<UTMI_PLL_PLLVDD12_SHIFT | 3<<UTMI_PLL_PLLCALI12_SHIFT
+               | 1<<UTMI_PLL_ICP_SHIFT | 3<<UTMI_PLL_KVCO_SHIFT);
+
+       /* UTMI_TX */
+       u2o_clear(base, UTMI_TX, UTMI_TX_REG_EXT_FS_RCAL_EN_MASK
+               | UTMI_TX_TXVDD12_MASK | UTMI_TX_CK60_PHSEL_MASK
+               | UTMI_TX_IMPCAL_VTH_MASK | UTMI_TX_REG_EXT_FS_RCAL_MASK
+               | UTMI_TX_AMP_MASK);
+       u2o_set(base, UTMI_TX, 3<<UTMI_TX_TXVDD12_SHIFT
+               | 4<<UTMI_TX_CK60_PHSEL_SHIFT | 4<<UTMI_TX_IMPCAL_VTH_SHIFT
+               | 8<<UTMI_TX_REG_EXT_FS_RCAL_SHIFT | 3<<UTMI_TX_AMP_SHIFT);
+
+       /* UTMI_RX */
+       u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK
+               | UTMI_REG_SQ_LENGTH_MASK);
+       u2o_set(base, UTMI_RX, 7<<UTMI_RX_SQ_THRESH_SHIFT
+               | 2<<UTMI_REG_SQ_LENGTH_SHIFT);
+
+       /* UTMI_IVREF */
+       if (cpu_is_pxa168())
+               /* fixing Microsoft Altair board interface with NEC hub issue -
+                * Set UTMI_IVREF from 0x4a3 to 0x4bf */
+               u2o_write(base, UTMI_IVREF, 0x4bf);
+
+       /* toggle VCOCAL_START bit of UTMI_PLL */
+       udelay(200);
+       u2o_set(base, UTMI_PLL, VCOCAL_START);
+       udelay(40);
+       u2o_clear(base, UTMI_PLL, VCOCAL_START);
+
+       /* toggle REG_RCAL_START bit of UTMI_TX */
+       udelay(400);
+       u2o_set(base, UTMI_TX, REG_RCAL_START);
+       udelay(40);
+       u2o_clear(base, UTMI_TX, REG_RCAL_START);
+       udelay(400);
+
+       /* Make sure PHY PLL is ready */
+       loops = 0;
+       while ((u2o_get(base, UTMI_PLL) & PLL_READY) == 0) {
+               mdelay(1);
+               loops++;
+               if (loops > 100) {
+                       printk(KERN_WARNING "calibrate timeout, UTMI_PLL %x\n",
+                               u2o_get(base, UTMI_PLL));
+                       break;
+               }
+       }
+
+       if (cpu_is_pxa168()) {
+               u2o_set(base, UTMI_RESERVE, 1 << 5);
+               /* Turn on UTMI PHY OTG extension */
+               u2o_write(base, UTMI_OTG_ADDON, 1);
+       }
+
+       return 0;
+}
+
+static int usb_phy_deinit_internal(void __iomem *base)
+{
+       pr_info("Deinit usb phy!!!\n");
+
+       if (cpu_is_pxa168())
+               u2o_clear(base, UTMI_OTG_ADDON, UTMI_OTG_ADDON_OTG_ON);
+
+       u2o_clear(base, UTMI_CTRL, UTMI_CTRL_RXBUF_PDWN);
+       u2o_clear(base, UTMI_CTRL, UTMI_CTRL_TXBUF_PDWN);
+       u2o_clear(base, UTMI_CTRL, UTMI_CTRL_USB_CLK_EN);
+       u2o_clear(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT);
+       u2o_clear(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT);
+
+       return 0;
+}
+
+int pxa_usb_phy_init(void __iomem *phy_reg)
+{
+       mutex_lock(&phy_lock);
+       if (phy_init_cnt++ == 0)
+               usb_phy_init_internal(phy_reg);
+       mutex_unlock(&phy_lock);
+       return 0;
+}
+
+void pxa_usb_phy_deinit(void __iomem *phy_reg)
+{
+       WARN_ON(phy_init_cnt == 0);
+
+       mutex_lock(&phy_lock);
+       if (--phy_init_cnt == 0)
+               usb_phy_deinit_internal(phy_reg);
+       mutex_unlock(&phy_lock);
+}
+#endif
+#endif
+#endif
+
+#ifdef CONFIG_USB_SUPPORT
+static u64 usb_dma_mask = ~(u32)0;
+
+#ifdef CONFIG_USB_MV_UDC
+struct resource pxa168_u2o_resources[] = {
+       /* regbase */
+       [0] = {
+               .start  = PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET,
+               .end    = PXA168_U2O_REGBASE + USB_REG_RANGE,
+               .flags  = IORESOURCE_MEM,
+               .name   = "capregs",
+       },
+       /* phybase */
+       [1] = {
+               .start  = PXA168_U2O_PHYBASE,
+               .end    = PXA168_U2O_PHYBASE + USB_PHY_RANGE,
+               .flags  = IORESOURCE_MEM,
+               .name   = "phyregs",
+       },
+       [2] = {
+               .start  = IRQ_PXA168_USB1,
+               .end    = IRQ_PXA168_USB1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device pxa168_device_u2o = {
+       .name           = "mv-udc",
+       .id             = -1,
+       .resource       = pxa168_u2o_resources,
+       .num_resources  = ARRAY_SIZE(pxa168_u2o_resources),
+       .dev            =  {
+               .dma_mask       = &usb_dma_mask,
+               .coherent_dma_mask = 0xffffffff,
+       }
+};
+#endif /* CONFIG_USB_MV_UDC */
+
+#ifdef CONFIG_USB_EHCI_MV_U2O
+struct resource pxa168_u2oehci_resources[] = {
+       /* regbase */
+       [0] = {
+               .start  = PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET,
+               .end    = PXA168_U2O_REGBASE + USB_REG_RANGE,
+               .flags  = IORESOURCE_MEM,
+               .name   = "capregs",
+       },
+       /* phybase */
+       [1] = {
+               .start  = PXA168_U2O_PHYBASE,
+               .end    = PXA168_U2O_PHYBASE + USB_PHY_RANGE,
+               .flags  = IORESOURCE_MEM,
+               .name   = "phyregs",
+       },
+       [2] = {
+               .start  = IRQ_PXA168_USB1,
+               .end    = IRQ_PXA168_USB1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device pxa168_device_u2oehci = {
+       .name           = "pxa-u2oehci",
+       .id             = -1,
+       .dev            = {
+               .dma_mask               = &usb_dma_mask,
+               .coherent_dma_mask      = 0xffffffff,
+       },
+
+       .num_resources  = ARRAY_SIZE(pxa168_u2oehci_resources),
+       .resource       = pxa168_u2oehci_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_MV_OTG)
+struct resource pxa168_u2ootg_resources[] = {
+       /* regbase */
+       [0] = {
+               .start  = PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET,
+               .end    = PXA168_U2O_REGBASE + USB_REG_RANGE,
+               .flags  = IORESOURCE_MEM,
+               .name   = "capregs",
+       },
+       /* phybase */
+       [1] = {
+               .start  = PXA168_U2O_PHYBASE,
+               .end    = PXA168_U2O_PHYBASE + USB_PHY_RANGE,
+               .flags  = IORESOURCE_MEM,
+               .name   = "phyregs",
+       },
+       [2] = {
+               .start  = IRQ_PXA168_USB1,
+               .end    = IRQ_PXA168_USB1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device pxa168_device_u2ootg = {
+       .name           = "mv-otg",
+       .id             = -1,
+       .dev  = {
+               .dma_mask          = &usb_dma_mask,
+               .coherent_dma_mask = 0xffffffff,
+       },
+
+       .num_resources  = ARRAY_SIZE(pxa168_u2ootg_resources),
+       .resource      = pxa168_u2ootg_resources,
+};
+#endif /* CONFIG_USB_MV_OTG */
+
+#endif
index d0ec7dae88e4c06f9050f4bf3b2223121109c8c0..21217ef11b64f38639221e2717fbcf20cd63d487 100644 (file)
@@ -50,4 +50,7 @@ struct pxa_device_desc mmp2_device_##_name __initdata = {             \
 }
 
 extern int pxa_register_device(struct pxa_device_desc *, void *, size_t);
+extern int pxa_usb_phy_init(void __iomem *phy_reg);
+extern void pxa_usb_phy_deinit(void __iomem *phy_reg);
+
 #endif /* __MACH_DEVICE_H */
index dc03d580a06d64737dab0962bcab81ffa296eddd..09dcd6e2b6a8431a5f64528631fd0c92a809cdbe 100644 (file)
@@ -16,6 +16,7 @@ extern void pxa168_clear_keypad_wakeup(void);
 #include <plat/pxa27x_keypad.h>
 #include <mach/cputype.h>
 #include <linux/pxa168_eth.h>
+#include <linux/platform_data/mv_usb.h>
 
 extern struct pxa_device_desc pxa168_device_uart1;
 extern struct pxa_device_desc pxa168_device_uart2;
@@ -36,12 +37,9 @@ extern struct pxa_device_desc pxa168_device_fb;
 extern struct pxa_device_desc pxa168_device_keypad;
 extern struct pxa_device_desc pxa168_device_eth;
 
-struct pxa168_usb_pdata {
-       /* If NULL, default phy init routine for PXA168 would be called */
-       int (*phy_init)(void __iomem *usb_phy_reg_base);
-};
 /* pdata can be NULL */
-int __init pxa168_add_usb_host(struct pxa168_usb_pdata *pdata);
+extern int __init pxa168_add_usb_host(struct mv_usb_platform_data *pdata);
+
 
 extern struct platform_device pxa168_device_gpio;
 
index e2e1f1e5e1249f908f7a8b531862d921abb00359..793634c837ef337e2da881c5a4e42db2df98a323 100644 (file)
@@ -20,6 +20,9 @@ extern struct pxa_device_desc pxa910_device_pwm2;
 extern struct pxa_device_desc pxa910_device_pwm3;
 extern struct pxa_device_desc pxa910_device_pwm4;
 extern struct pxa_device_desc pxa910_device_nand;
+extern struct platform_device pxa168_device_u2o;
+extern struct platform_device pxa168_device_u2ootg;
+extern struct platform_device pxa168_device_u2oehci;
 
 extern struct platform_device pxa910_device_gpio;
 extern struct platform_device pxa910_device_rtc;
diff --git a/arch/arm/mach-mmp/include/mach/regs-usb.h b/arch/arm/mach-mmp/include/mach/regs-usb.h
new file mode 100644 (file)
index 0000000..b047bf4
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_REGS_USB_H
+#define __ASM_ARCH_REGS_USB_H
+
+#define PXA168_U2O_REGBASE     (0xd4208000)
+#define PXA168_U2O_PHYBASE     (0xd4207000)
+
+#define PXA168_U2H_REGBASE      (0xd4209000)
+#define PXA168_U2H_PHYBASE      (0xd4206000)
+
+#define MMP3_HSIC1_REGBASE     (0xf0001000)
+#define MMP3_HSIC1_PHYBASE     (0xf0001800)
+
+#define MMP3_HSIC2_REGBASE     (0xf0002000)
+#define MMP3_HSIC2_PHYBASE     (0xf0002800)
+
+#define MMP3_FSIC_REGBASE      (0xf0003000)
+#define MMP3_FSIC_PHYBASE      (0xf0003800)
+
+
+#define USB_REG_RANGE          (0x1ff)
+#define USB_PHY_RANGE          (0xff)
+
+/* registers */
+#define U2x_CAPREGS_OFFSET       0x100
+
+/* phy regs */
+#define UTMI_REVISION          0x0
+#define UTMI_CTRL              0x4
+#define UTMI_PLL               0x8
+#define UTMI_TX                        0xc
+#define UTMI_RX                        0x10
+#define UTMI_IVREF             0x14
+#define UTMI_T0                        0x18
+#define UTMI_T1                        0x1c
+#define UTMI_T2                        0x20
+#define UTMI_T3                        0x24
+#define UTMI_T4                        0x28
+#define UTMI_T5                        0x2c
+#define UTMI_RESERVE           0x30
+#define UTMI_USB_INT           0x34
+#define UTMI_DBG_CTL           0x38
+#define UTMI_OTG_ADDON         0x3c
+
+/* For UTMICTRL Register */
+#define UTMI_CTRL_USB_CLK_EN                    (1 << 31)
+/* pxa168 */
+#define UTMI_CTRL_SUSPEND_SET1                  (1 << 30)
+#define UTMI_CTRL_SUSPEND_SET2                  (1 << 29)
+#define UTMI_CTRL_RXBUF_PDWN                    (1 << 24)
+#define UTMI_CTRL_TXBUF_PDWN                    (1 << 11)
+
+#define UTMI_CTRL_INPKT_DELAY_SHIFT             30
+#define UTMI_CTRL_INPKT_DELAY_SOF_SHIFT                28
+#define UTMI_CTRL_PU_REF_SHIFT                 20
+#define UTMI_CTRL_ARC_PULLDN_SHIFT              12
+#define UTMI_CTRL_PLL_PWR_UP_SHIFT              1
+#define UTMI_CTRL_PWR_UP_SHIFT                  0
+
+/* For UTMI_PLL Register */
+#define UTMI_PLL_PLLCALI12_SHIFT               29
+#define UTMI_PLL_PLLCALI12_MASK                        (0x3 << 29)
+
+#define UTMI_PLL_PLLVDD18_SHIFT                        27
+#define UTMI_PLL_PLLVDD18_MASK                 (0x3 << 27)
+
+#define UTMI_PLL_PLLVDD12_SHIFT                        25
+#define UTMI_PLL_PLLVDD12_MASK                 (0x3 << 25)
+
+#define UTMI_PLL_CLK_BLK_EN_SHIFT               24
+#define CLK_BLK_EN                              (0x1 << 24)
+#define PLL_READY                               (0x1 << 23)
+#define KVCO_EXT                                (0x1 << 22)
+#define VCOCAL_START                            (0x1 << 21)
+
+#define UTMI_PLL_KVCO_SHIFT                    15
+#define UTMI_PLL_KVCO_MASK                      (0x7 << 15)
+
+#define UTMI_PLL_ICP_SHIFT                     12
+#define UTMI_PLL_ICP_MASK                       (0x7 << 12)
+
+#define UTMI_PLL_FBDIV_SHIFT                    4
+#define UTMI_PLL_FBDIV_MASK                     (0xFF << 4)
+
+#define UTMI_PLL_REFDIV_SHIFT                   0
+#define UTMI_PLL_REFDIV_MASK                    (0xF << 0)
+
+/* For UTMI_TX Register */
+#define UTMI_TX_REG_EXT_FS_RCAL_SHIFT          27
+#define UTMI_TX_REG_EXT_FS_RCAL_MASK           (0xf << 27)
+
+#define UTMI_TX_REG_EXT_FS_RCAL_EN_SHIFT       26
+#define UTMI_TX_REG_EXT_FS_RCAL_EN_MASK                (0x1 << 26)
+
+#define UTMI_TX_TXVDD12_SHIFT                   22
+#define UTMI_TX_TXVDD12_MASK                    (0x3 << 22)
+
+#define UTMI_TX_CK60_PHSEL_SHIFT                17
+#define UTMI_TX_CK60_PHSEL_MASK                 (0xf << 17)
+
+#define UTMI_TX_IMPCAL_VTH_SHIFT                14
+#define UTMI_TX_IMPCAL_VTH_MASK                 (0x7 << 14)
+
+#define REG_RCAL_START                          (0x1 << 12)
+
+#define UTMI_TX_LOW_VDD_EN_SHIFT                11
+
+#define UTMI_TX_AMP_SHIFT                      0
+#define UTMI_TX_AMP_MASK                       (0x7 << 0)
+
+/* For UTMI_RX Register */
+#define UTMI_REG_SQ_LENGTH_SHIFT                15
+#define UTMI_REG_SQ_LENGTH_MASK                 (0x3 << 15)
+
+#define UTMI_RX_SQ_THRESH_SHIFT                 4
+#define UTMI_RX_SQ_THRESH_MASK                  (0xf << 4)
+
+#define UTMI_OTG_ADDON_OTG_ON                  (1 << 0)
+
+/* For MMP3 USB Phy */
+#define USB2_PLL_REG0          0x4
+#define USB2_PLL_REG1          0x8
+#define USB2_TX_REG0           0x10
+#define USB2_TX_REG1           0x14
+#define USB2_TX_REG2           0x18
+#define USB2_RX_REG0           0x20
+#define USB2_RX_REG1           0x24
+#define USB2_RX_REG2           0x28
+#define USB2_ANA_REG0          0x30
+#define USB2_ANA_REG1          0x34
+#define USB2_ANA_REG2          0x38
+#define USB2_DIG_REG0          0x3C
+#define USB2_DIG_REG1          0x40
+#define USB2_DIG_REG2          0x44
+#define USB2_DIG_REG3          0x48
+#define USB2_TEST_REG0         0x4C
+#define USB2_TEST_REG1         0x50
+#define USB2_TEST_REG2         0x54
+#define USB2_CHARGER_REG0      0x58
+#define USB2_OTG_REG0          0x5C
+#define USB2_PHY_MON0          0x60
+#define USB2_RESETVE_REG0      0x64
+#define USB2_ICID_REG0         0x78
+#define USB2_ICID_REG1         0x7C
+
+/* USB2_PLL_REG0 */
+/* This is for Ax stepping */
+#define USB2_PLL_FBDIV_SHIFT_MMP3              0
+#define USB2_PLL_FBDIV_MASK_MMP3               (0xFF << 0)
+
+#define USB2_PLL_REFDIV_SHIFT_MMP3             8
+#define USB2_PLL_REFDIV_MASK_MMP3              (0xF << 8)
+
+#define USB2_PLL_VDD12_SHIFT_MMP3              12
+#define USB2_PLL_VDD18_SHIFT_MMP3              14
+
+/* This is for B0 stepping */
+#define USB2_PLL_FBDIV_SHIFT_MMP3_B0           0
+#define USB2_PLL_REFDIV_SHIFT_MMP3_B0          9
+#define USB2_PLL_VDD18_SHIFT_MMP3_B0           14
+#define USB2_PLL_FBDIV_MASK_MMP3_B0            0x01FF
+#define USB2_PLL_REFDIV_MASK_MMP3_B0           0x3E00
+
+#define USB2_PLL_CAL12_SHIFT_MMP3              0
+#define USB2_PLL_CALI12_MASK_MMP3              (0x3 << 0)
+
+#define USB2_PLL_VCOCAL_START_SHIFT_MMP3       2
+
+#define USB2_PLL_KVCO_SHIFT_MMP3               4
+#define USB2_PLL_KVCO_MASK_MMP3                        (0x7<<4)
+
+#define USB2_PLL_ICP_SHIFT_MMP3                        8
+#define USB2_PLL_ICP_MASK_MMP3                 (0x7<<8)
+
+#define USB2_PLL_LOCK_BYPASS_SHIFT_MMP3                12
+
+#define USB2_PLL_PU_PLL_SHIFT_MMP3             13
+#define USB2_PLL_PU_PLL_MASK                   (0x1 << 13)
+
+#define USB2_PLL_READY_MASK_MMP3               (0x1 << 15)
+
+/* USB2_TX_REG0 */
+#define USB2_TX_IMPCAL_VTH_SHIFT_MMP3          8
+#define USB2_TX_IMPCAL_VTH_MASK_MMP3           (0x7 << 8)
+
+#define USB2_TX_RCAL_START_SHIFT_MMP3          13
+
+/* USB2_TX_REG1 */
+#define USB2_TX_CK60_PHSEL_SHIFT_MMP3          0
+#define USB2_TX_CK60_PHSEL_MASK_MMP3           (0xf << 0)
+
+#define USB2_TX_AMP_SHIFT_MMP3                 4
+#define USB2_TX_AMP_MASK_MMP3                  (0x7 << 4)
+
+#define USB2_TX_VDD12_SHIFT_MMP3               8
+#define USB2_TX_VDD12_MASK_MMP3                        (0x3 << 8)
+
+/* USB2_TX_REG2 */
+#define USB2_TX_DRV_SLEWRATE_SHIFT             10
+
+/* USB2_RX_REG0 */
+#define USB2_RX_SQ_THRESH_SHIFT_MMP3           4
+#define USB2_RX_SQ_THRESH_MASK_MMP3            (0xf << 4)
+
+#define USB2_RX_SQ_LENGTH_SHIFT_MMP3           10
+#define USB2_RX_SQ_LENGTH_MASK_MMP3            (0x3 << 10)
+
+/* USB2_ANA_REG1*/
+#define USB2_ANA_PU_ANA_SHIFT_MMP3             14
+
+/* USB2_OTG_REG0 */
+#define USB2_OTG_PU_OTG_SHIFT_MMP3             3
+
+/* fsic registers */
+#define FSIC_MISC                      0x4
+#define FSIC_INT                       0x28
+#define FSIC_CTRL                      0x30
+
+/* HSIC registers */
+#define HSIC_PAD_CTRL                  0x4
+
+#define HSIC_CTRL                      0x8
+#define HSIC_CTRL_HSIC_ENABLE          (1<<7)
+#define HSIC_CTRL_PLL_BYPASS           (1<<4)
+
+#define TEST_GRP_0                     0xc
+#define TEST_GRP_1                     0x10
+
+#define HSIC_INT                       0x14
+#define HSIC_INT_READY_INT_EN          (1<<10)
+#define HSIC_INT_CONNECT_INT_EN                (1<<9)
+#define HSIC_INT_CORE_INT_EN           (1<<8)
+#define HSIC_INT_HS_READY              (1<<2)
+#define HSIC_INT_CONNECT               (1<<1)
+#define HSIC_INT_CORE                  (1<<0)
+
+#define HSIC_CONFIG                    0x18
+#define USBHSIC_CTRL                   0x20
+
+#define HSIC_USB_CTRL                  0x28
+#define HSIC_USB_CTRL_CLKEN            1
+#define        HSIC_USB_CLK_PHY                0x0
+#define HSIC_USB_CLK_PMU               0x1
+
+#endif /* __ASM_ARCH_PXA_U2O_H */
index b24d2c32cba984c1b72a3b2f20761c944d24ced5..62d787c3447569da2815025accced28a6379b17c 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/platform_data/mv_usb.h>
 
 #include <asm/mach/time.h>
 #include <asm/system_misc.h>
@@ -27,6 +28,7 @@
 #include <mach/mfp.h>
 #include <linux/dma-mapping.h>
 #include <mach/pxa168.h>
+#include <mach/regs-usb.h>
 
 #include "common.h"
 #include "clock.h"
@@ -93,7 +95,7 @@ static struct clk_lookup pxa168_clkregs[] = {
        INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL),
        INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
        INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"),
-       INIT_CLKREG(&clk_usb, "pxa168-ehci", "PXA168-USBCLK"),
+       INIT_CLKREG(&clk_usb, NULL, "PXA168-USBCLK"),
        INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
 };
 
@@ -184,17 +186,17 @@ struct platform_device pxa168_device_gpio = {
 struct resource pxa168_usb_host_resources[] = {
        /* USB Host conroller register base */
        [0] = {
-               .start  = 0xd4209000,
-               .end    = 0xd4209000 + 0x200,
+               .start  = PXA168_U2H_REGBASE + U2x_CAPREGS_OFFSET,
+               .end    = PXA168_U2H_REGBASE + USB_REG_RANGE,
                .flags  = IORESOURCE_MEM,
-               .name   = "pxa168-usb-host",
+               .name   = "capregs",
        },
        /* USB PHY register base */
        [1] = {
-               .start  = 0xd4206000,
-               .end    = 0xd4206000 + 0xff,
+               .start  = PXA168_U2H_PHYBASE,
+               .end    = PXA168_U2H_PHYBASE + USB_PHY_RANGE,
                .flags  = IORESOURCE_MEM,
-               .name   = "pxa168-usb-phy",
+               .name   = "phyregs",
        },
        [2] = {
                .start  = IRQ_PXA168_USB2,
@@ -205,7 +207,7 @@ struct resource pxa168_usb_host_resources[] = {
 
 static u64 pxa168_usb_host_dmamask = DMA_BIT_MASK(32);
 struct platform_device pxa168_device_usb_host = {
-       .name = "pxa168-ehci",
+       .name = "pxa-sph",
        .id   = -1,
        .dev  = {
                .dma_mask = &pxa168_usb_host_dmamask,
@@ -216,7 +218,7 @@ struct platform_device pxa168_device_usb_host = {
        .resource      = pxa168_usb_host_resources,
 };
 
-int __init pxa168_add_usb_host(struct pxa168_usb_pdata *pdata)
+int __init pxa168_add_usb_host(struct mv_usb_platform_data *pdata)
 {
        pxa168_device_usb_host.dev.platform_data = pdata;
        return platform_device_register(&pxa168_device_usb_host);
index 43f8bcc29b67734a733260381f256db6b1ce19e7..6da52e9f2bdcf7dc353687d71093887af9deb3f4 100644 (file)
@@ -109,7 +109,7 @@ static struct clk_lookup pxa910_clkregs[] = {
        INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL),
        INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
        INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL),
-       INIT_CLKREG(&clk_u2o, "pxa-u2o", "U2OCLK"),
+       INIT_CLKREG(&clk_u2o, NULL, "U2OCLK"),
        INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
 };
 
index 3fc9ed21f97d20d8c5a63a79b5dce8f0be05c1a9..266215393f44c9d3a84335d34804074211c5f74a 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/i2c/pca953x.h>
 #include <linux/gpio.h>
+#include <linux/platform_data/mv_usb.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -25,6 +26,7 @@
 #include <mach/mfp-pxa910.h>
 #include <mach/pxa910.h>
 #include <mach/irqs.h>
+#include <mach/regs-usb.h>
 
 #include "common.h"
 
@@ -144,6 +146,26 @@ static struct i2c_board_info ttc_dkb_i2c_info[] = {
        },
 };
 
+#ifdef CONFIG_USB_SUPPORT
+#if defined(CONFIG_USB_MV_UDC) || defined(CONFIG_USB_EHCI_MV_U2O)
+
+static char *pxa910_usb_clock_name[] = {
+       [0] = "U2OCLK",
+};
+
+static struct mv_usb_platform_data ttc_usb_pdata = {
+       .clknum         = 1,
+       .clkname        = pxa910_usb_clock_name,
+       .vbus           = NULL,
+       .mode           = MV_USB_MODE_OTG,
+       .otg_force_a_bus_req = 1,
+       .phy_init       = pxa_usb_phy_init,
+       .phy_deinit     = pxa_usb_phy_deinit,
+       .set_vbus       = NULL,
+};
+#endif
+#endif
+
 static void __init ttc_dkb_init(void)
 {
        mfp_config(ARRAY_AND_SIZE(ttc_dkb_pin_config));
@@ -154,6 +176,21 @@ static void __init ttc_dkb_init(void)
        /* off-chip devices */
        pxa910_add_twsi(0, NULL, ARRAY_AND_SIZE(ttc_dkb_i2c_info));
        platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices));
+
+#ifdef CONFIG_USB_MV_UDC
+       pxa168_device_u2o.dev.platform_data = &ttc_usb_pdata;
+       platform_device_register(&pxa168_device_u2o);
+#endif
+
+#ifdef CONFIG_USB_EHCI_MV_U2O
+       pxa168_device_u2oehci.dev.platform_data = &ttc_usb_pdata;
+       platform_device_register(&pxa168_device_u2oehci);
+#endif
+
+#ifdef CONFIG_USB_MV_OTG
+       pxa168_device_u2ootg.dev.platform_data = &ttc_usb_pdata;
+       platform_device_register(&pxa168_device_u2ootg);
+#endif
 }
 
 MACHINE_START(TTC_DKB, "PXA910-based TTC_DKB Development Platform")
index b83b95a2950342b298a8693b753217feacb4b5ab..6bd692d271c1ae3e1fca9f6b6dbf4cda667df7f3 100644 (file)
@@ -102,6 +102,10 @@ static unsigned long hx4700_pin_config[] __initdata = {
        GPIO44_BTUART_CTS,
        GPIO45_BTUART_RTS_LPM_LOW,
 
+       /* STUART (IRDA) */
+       GPIO46_STUART_RXD,
+       GPIO47_STUART_TXD,
+
        /* PWM 1 (Backlight) */
        GPIO17_PWM1_OUT,
 
@@ -125,7 +129,7 @@ static unsigned long hx4700_pin_config[] __initdata = {
        GPIO88_GPIO,
 
        /* HX4700 specific input GPIOs */
-       GPIO12_GPIO,    /* ASIC3_IRQ */
+       GPIO12_GPIO | WAKEUP_ON_EDGE_RISE,      /* ASIC3_IRQ */
        GPIO13_GPIO,    /* W3220_IRQ */
        GPIO14_GPIO,    /* nWLAN_IRQ */
 
@@ -227,7 +231,6 @@ static u16 asic3_gpio_config[] = {
        ASIC3_GPIOC0_LED0,              /* red */
        ASIC3_GPIOC1_LED1,              /* green */
        ASIC3_GPIOC2_LED2,              /* blue */
-       ASIC3_GPIOC4_CF_nCD,
        ASIC3_GPIOC5_nCIOW,
        ASIC3_GPIOC6_nCIOR,
        ASIC3_GPIOC7_nPCE_1,
@@ -241,6 +244,7 @@ static u16 asic3_gpio_config[] = {
        ASIC3_GPIOC15_nPIOR,
 
        /* GPIOD: input GPIOs, CF */
+       ASIC3_GPIOD4_CF_nCD,
        ASIC3_GPIOD11_nCIOIS16,
        ASIC3_GPIOD12_nCWAIT,
        ASIC3_GPIOD15_nPIOW,
@@ -291,6 +295,7 @@ static struct asic3_platform_data asic3_platform_data = {
        .gpio_config_num = ARRAY_SIZE(asic3_gpio_config),
        .irq_base        = IRQ_BOARD_START,
        .gpio_base       = HX4700_ASIC3_GPIO_BASE,
+       .clock_rate      = 4000000,
        .leds            = asic3_leds,
 };
 
@@ -859,6 +864,7 @@ static void __init hx4700_init(void)
        int ret;
 
        pxa2xx_mfp_config(ARRAY_AND_SIZE(hx4700_pin_config));
+       gpio_set_wake(GPIO12_HX4700_ASIC3_IRQ, 1);
        ret = gpio_request_array(ARRAY_AND_SIZE(global_gpios));
        if (ret)
                pr_err ("hx4700: Failed to request GPIOs.\n");
index 02868447b0b135d56b4e9c687233358280da77b3..e57f5c724e8a1e18ded7302bb6c7a29bd288c0ab 100644 (file)
@@ -61,6 +61,9 @@
 #define GPIO93_KEY_VOLUME_UP                   93
 #define GPIO94_KEY_VOLUME_DOWN                 94
 
+/* Camera */
+#define GPIO56_MT9M111_nOE                     56
+
 extern struct input_dev *mioa701_evdev;
 extern void mioa701_gpio_lpm_set(unsigned long mfp_pin);
 
index d72791695b2611ba3e55aeeab43623641d7baacf..0260aaa2fc178670e597014eff70f358a16c5ad1 100644 (file)
@@ -31,7 +31,6 @@
 #define PCM990_CTRL_INT_IRQ            PXA_GPIO_TO_IRQ(PCM990_CTRL_INT_IRQ_GPIO)
 #define PCM990_CTRL_INT_IRQ_EDGE       IRQ_TYPE_EDGE_RISING
 #define PCM990_CTRL_PHYS               PXA_CS1_PHYS    /* 16-Bit */
-#define PCM990_CTRL_BASE               0xea000000
 #define PCM990_CTRL_SIZE               (1*1024*1024)
 
 #define PCM990_CTRL_PWR_IRQ_GPIO       14
 #define PCM990_CTRL_MMC2DE     0x0004  /* R MMC2 Card detect */
 #define PCM990_CTRL_MMC2WP     0x0008  /* R MMC2 Card write protect */
 
-#define PCM990_CTRL_REG6       0x000C  /* Interrupt Clear REGISTER */
+#define PCM990_CTRL_INTSETCLR  0x000C  /* Interrupt Clear REGISTER */
 #define PCM990_CTRL_INTC0      0x0001  /* Clear Reg BT Detect */
 #define PCM990_CTRL_INTC1      0x0002  /* Clear Reg FR RI */
 #define PCM990_CTRL_INTC2      0x0004  /* Clear Reg MMC1 Detect */
 #define PCM990_CTRL_INTC3      0x0008  /* Clear Reg PM_5V off */
 
-#define PCM990_CTRL_REG7       0x000E  /* Interrupt Enable REGISTER */
+#define PCM990_CTRL_INTMSKENA  0x000E  /* Interrupt Enable REGISTER */
 #define PCM990_CTRL_ENAINT0    0x0001  /* Enable Int BT Detect */
 #define PCM990_CTRL_ENAINT1    0x0002  /* Enable Int FR RI */
 #define PCM990_CTRL_ENAINT2    0x0004  /* Enable Int MMC1 Detect */
 #define PCM990_CTRL_ACPRES     0x0004  /* DC Present */
 #define PCM990_CTRL_ACALARM    0x0008  /* Error Akku */
 
-#define PCM990_CTRL_P2V(x)     ((x) - PCM990_CTRL_PHYS + PCM990_CTRL_BASE)
-#define PCM990_CTRL_V2P(x)     ((x) - PCM990_CTRL_BASE + PCM990_CTRL_PHYS)
-
-#ifndef __ASSEMBLY__
-#  define __PCM990_CTRL_REG(x) \
-               (*((volatile unsigned char *)PCM990_CTRL_P2V(x)))
-#else
-#  define __PCM990_CTRL_REG(x) PCM990_CTRL_P2V(x)
-#endif
-
-#define PCM990_INTMSKENA __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG7)
-#define PCM990_INTSETCLR __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG6)
-#define PCM990_CTRL0   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG0)
-#define PCM990_CTRL1   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG1)
-#define PCM990_CTRL2   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG2)
-#define PCM990_CTRL3   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3)
-#define PCM990_CTRL4   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG4)
-#define PCM990_CTRL5   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5)
-#define PCM990_CTRL6   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG6)
-#define PCM990_CTRL7   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG7)
-#define PCM990_CTRL8   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG8)
-#define PCM990_CTRL9   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG9)
-#define PCM990_CTRL10  __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG10)
-#define PCM990_CTRL11  __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG11)
-
-
 /*
  * IDE
  */
 #define PCM990_IDE_PLD_P2V(x) ((x) - PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_BASE)
 #define PCM990_IDE_PLD_V2P(x) ((x) - PCM990_IDE_PLD_BASE + PCM990_IDE_PLD_PHYS)
 
-#ifndef __ASSEMBLY__
-# define  __PCM990_IDE_PLD_REG(x) \
-       (*((volatile unsigned char *)PCM990_IDE_PLD_P2V(x)))
-#else
-# define  __PCM990_IDE_PLD_REG(x)      PCM990_IDE_PLD_P2V(x)
-#endif
-
-#define PCM990_IDE0 \
-       __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG0)
-#define PCM990_IDE1 \
-       __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG1)
-#define PCM990_IDE2 \
-       __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG2)
-#define PCM990_IDE3 \
-       __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG3)
-#define PCM990_IDE4 \
-       __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG4)
-
 /*
  * Compact Flash
  */
 #define PCM990_CF_CD_EDGE      IRQ_TYPE_EDGE_RISING
 
 #define PCM990_CF_PLD_PHYS     0x30000000      /* 16 bit wide */
-#define PCM990_CF_PLD_BASE     0xef000000
-#define PCM990_CF_PLD_SIZE     (1*1024*1024)
-#define PCM990_CF_PLD_P2V(x)   ((x) - PCM990_CF_PLD_PHYS + PCM990_CF_PLD_BASE)
-#define PCM990_CF_PLD_V2P(x)   ((x) - PCM990_CF_PLD_BASE + PCM990_CF_PLD_PHYS)
 
 /* visible CPLD (U6) registers */
 #define PCM990_CF_PLD_REG0     0x1000  /* OFFSET CF REGISTER 0 */
 #define PCM990_CF_REG6_CD1     0x0001  /* R CF Card_Detect1 */
 #define PCM990_CF_REG6_CD2     0x0002  /* R CF Card_Detect2 */
 
-#ifndef __ASSEMBLY__
-#  define  __PCM990_CF_PLD_REG(x) \
-       (*((volatile unsigned char *)PCM990_CF_PLD_P2V(x)))
-#else
-#  define  __PCM990_CF_PLD_REG(x)      PCM990_CF_PLD_P2V(x)
-#endif
-
-#define PCM990_CF0 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG0)
-#define PCM990_CF1 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG1)
-#define PCM990_CF2 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG2)
-#define PCM990_CF3 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG3)
-#define PCM990_CF4 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG4)
-#define PCM990_CF5 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG5)
-#define PCM990_CF6 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG6)
-
 /*
  * Wolfson AC97 Touch
  */
index 061d57009cee98aec4335c745d3a7a51cfd975ea..929c62b47b761b9fab85dd6ffc78e7089dbb6a3e 100644 (file)
@@ -103,6 +103,7 @@ static unsigned long mioa701_pin_config[] = {
        GPIO82_CIF_DD_5,
        GPIO84_CIF_FV,
        GPIO85_CIF_LV,
+       MIO_CFG_OUT(GPIO56_MT9M111_nOE, AF0, DRIVE_LOW),
 
        /* Bluetooth */
        MIO_CFG_IN(GPIO14_BT_nACTIVITY, AF0),
@@ -705,6 +706,7 @@ static struct gpio global_gpios[] = {
        { GPIO9_CHARGE_EN, GPIOF_OUT_INIT_HIGH, "Charger enable" },
        { GPIO18_POWEROFF, GPIOF_OUT_INIT_LOW, "Power Off" },
        { GPIO87_LCD_POWER, GPIOF_OUT_INIT_LOW, "LCD Power" },
+       { GPIO56_MT9M111_nOE, GPIOF_OUT_INIT_LOW, "Camera nOE" },
 };
 
 static void __init mioa701_machine_init(void)
index abab4e2b122c088195f9fcbdc8708976c68da90a..cb723e84bc2710f7cd7a7955edabca98275e901d 100644 (file)
@@ -65,6 +65,18 @@ static unsigned long pcm990_pin_config[] __initdata = {
        GPIO31_AC97_SYNC,
 };
 
+static void __iomem *pcm990_cpld_base;
+
+static u8 pcm990_cpld_readb(unsigned int reg)
+{
+       return readb(pcm990_cpld_base + reg);
+}
+
+static void pcm990_cpld_writeb(u8 value, unsigned int reg)
+{
+       writeb(value, pcm990_cpld_base + reg);
+}
+
 /*
  * pcm990_lcd_power - control power supply to the LCD
  * @on: 0 = switch off, 1 = switch on
@@ -78,13 +90,13 @@ static void pcm990_lcd_power(int on, struct fb_var_screeninfo *var)
                /* enable LCD-Latches
                 * power on LCD
                 */
-               __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3) =
-                       PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON;
+               pcm990_cpld_writeb(PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON,
+                               PCM990_CTRL_REG3);
        } else {
                /* disable LCD-Latches
                 * power off LCD
                 */
-               __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3) = 0x00;
+               pcm990_cpld_writeb(0, PCM990_CTRL_REG3);
        }
 }
 #endif
@@ -243,15 +255,26 @@ static unsigned long pcm990_irq_enabled;
 static void pcm990_mask_ack_irq(struct irq_data *d)
 {
        int pcm990_irq = (d->irq - PCM027_IRQ(0));
-       PCM990_INTMSKENA = (pcm990_irq_enabled &= ~(1 << pcm990_irq));
+
+       pcm990_irq_enabled &= ~(1 << pcm990_irq);
+
+       pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA);
 }
 
 static void pcm990_unmask_irq(struct irq_data *d)
 {
        int pcm990_irq = (d->irq - PCM027_IRQ(0));
+       u8 val;
+
        /* the irq can be acknowledged only if deasserted, so it's done here */
-       PCM990_INTSETCLR |= 1 << pcm990_irq;
-       PCM990_INTMSKENA  = (pcm990_irq_enabled |= (1 << pcm990_irq));
+
+       pcm990_irq_enabled |= (1 << pcm990_irq);
+
+       val = pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
+       val |= 1 << pcm990_irq;
+       pcm990_cpld_writeb(val, PCM990_CTRL_INTSETCLR);
+
+       pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA);
 }
 
 static struct irq_chip pcm990_irq_chip = {
@@ -261,7 +284,10 @@ static struct irq_chip pcm990_irq_chip = {
 
 static void pcm990_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
-       unsigned long pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
+       unsigned long pending;
+
+       pending = ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
+       pending &= pcm990_irq_enabled;
 
        do {
                /* clear our parent IRQ */
@@ -270,7 +296,8 @@ static void pcm990_irq_handler(unsigned int irq, struct irq_desc *desc)
                        irq = PCM027_IRQ(0) + __ffs(pending);
                        generic_handle_irq(irq);
                }
-               pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
+               pending = ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
+               pending &= pcm990_irq_enabled;
        } while (pending);
 }
 
@@ -285,8 +312,9 @@ static void __init pcm990_init_irq(void)
                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
        }
 
-       PCM990_INTMSKENA = 0x00;        /* disable all Interrupts */
-       PCM990_INTSETCLR = 0xFF;
+       /* disable all Interrupts */
+       pcm990_cpld_writeb(0x0, PCM990_CTRL_INTMSKENA);
+       pcm990_cpld_writeb(0xff, PCM990_CTRL_INTSETCLR);
 
        irq_set_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler);
        irq_set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE);
@@ -309,13 +337,16 @@ static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
 static void pcm990_mci_setpower(struct device *dev, unsigned int vdd)
 {
        struct pxamci_platform_data *p_d = dev->platform_data;
+       u8 val;
+
+       val = pcm990_cpld_readb(PCM990_CTRL_REG5);
 
        if ((1 << vdd) & p_d->ocr_mask)
-               __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) =
-                                               PCM990_CTRL_MMC2PWR;
+               val |= PCM990_CTRL_MMC2PWR;
        else
-               __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) =
-                                               ~PCM990_CTRL_MMC2PWR;
+               val &= ~PCM990_CTRL_MMC2PWR;
+
+       pcm990_cpld_writeb(PCM990_CTRL_MMC2PWR, PCM990_CTRL_REG5);
 }
 
 static void pcm990_mci_exit(struct device *dev, void *data)
@@ -480,23 +511,6 @@ static struct platform_device pcm990_camera[] = {
 };
 #endif /* CONFIG_VIDEO_PXA27x ||CONFIG_VIDEO_PXA27x_MODULE */
 
-/*
- * enable generic access to the base board control CPLDs U6 and U7
- */
-static struct map_desc pcm990_io_desc[] __initdata = {
-       {
-               .virtual        = PCM990_CTRL_BASE,
-               .pfn            = __phys_to_pfn(PCM990_CTRL_PHYS),
-               .length         = PCM990_CTRL_SIZE,
-               .type           = MT_DEVICE     /* CPLD */
-       }, {
-               .virtual        = PCM990_CF_PLD_BASE,
-               .pfn            = __phys_to_pfn(PCM990_CF_PLD_PHYS),
-               .length         = PCM990_CF_PLD_SIZE,
-               .type           = MT_DEVICE     /* CPLD */
-       }
-};
-
 /*
  * system init for baseboard usage. Will be called by pcm027 init.
  *
@@ -507,8 +521,11 @@ void __init pcm990_baseboard_init(void)
 {
        pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_pin_config));
 
-       /* register CPLD access */
-       iotable_init(ARRAY_AND_SIZE(pcm990_io_desc));
+       pcm990_cpld_base = ioremap(PCM990_CTRL_PHYS, PCM990_CTRL_SIZE);
+       if (!pcm990_cpld_base) {
+               pr_err("pcm990: failed to ioremap cpld\n");
+               return;
+       }
 
        /* register CPLD's IRQ controller */
        pcm990_init_irq();
index bba3ab2066eefafbc580630f17beda79717d915a..8fd255f7ee40e9f64ea04f606f7157ac28f7c808 100644 (file)
@@ -217,7 +217,7 @@ config PCMCIA_PXA2XX
                    || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
                    || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \
                    || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \
-                   || MACH_COLIBRI320)
+                   || MACH_COLIBRI320 || MACH_H4700)
        select PCMCIA_SA1111 if ARCH_LUBBOCK && SA1111
        select PCMCIA_SOC_COMMON
        help
index 47525de6a631f13fd36ffdaf06413258bb51c64d..7745b512a87c7c2ebb71c7be1d07435e4960118a 100644 (file)
@@ -69,6 +69,7 @@ pxa2xx-obj-$(CONFIG_MACH_VPAC270)             += pxa2xx_vpac270.o
 pxa2xx-obj-$(CONFIG_MACH_BALLOON3)             += pxa2xx_balloon3.o
 pxa2xx-obj-$(CONFIG_MACH_COLIBRI)              += pxa2xx_colibri.o
 pxa2xx-obj-$(CONFIG_MACH_COLIBRI320)           += pxa2xx_colibri.o
+pxa2xx-obj-$(CONFIG_MACH_H4700)                        += pxa2xx_hx4700.o
 
 obj-$(CONFIG_PCMCIA_PXA2XX)                    += pxa2xx_base.o $(pxa2xx-obj-y)
 
diff --git a/drivers/pcmcia/pxa2xx_hx4700.c b/drivers/pcmcia/pxa2xx_hx4700.c
new file mode 100644 (file)
index 0000000..7dfef3e
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ *  Copyright (C) 2012 Paul Parsons <lost.distance@yahoo.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/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <mach/hx4700.h>
+
+#include "soc_common.h"
+
+static struct gpio gpios[] = {
+       { GPIO114_HX4700_CF_RESET,    GPIOF_OUT_INIT_LOW,   "CF reset"        },
+       { EGPIO4_CF_3V3_ON,           GPIOF_OUT_INIT_LOW,   "CF 3.3V enable"  },
+};
+
+static int hx4700_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+       int ret;
+
+       ret = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+       if (ret)
+               goto out;
+
+       /*
+        * IRQ type must be set before soc_pcmcia_hw_init() calls request_irq().
+        * The asic3 default IRQ type is level trigger low level detect, exactly
+        * the the signal present on GPIOD4_CF_nCD when a CF card is inserted.
+        * If the IRQ type is not changed, the asic3 interrupt handler will loop
+        * repeatedly because it is unable to clear the level trigger interrupt.
+        */
+       irq_set_irq_type(gpio_to_irq(GPIOD4_CF_nCD), IRQ_TYPE_EDGE_BOTH);
+
+       skt->stat[SOC_STAT_CD].gpio = GPIOD4_CF_nCD;
+       skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
+       skt->stat[SOC_STAT_RDY].gpio = GPIO60_HX4700_CF_RNB;
+       skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
+
+out:
+       return ret;
+}
+
+static void hx4700_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+       gpio_free_array(gpios, ARRAY_SIZE(gpios));
+}
+
+static void hx4700_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+       struct pcmcia_state *state)
+{
+       state->vs_3v = 1;
+       state->vs_Xv = 0;
+}
+
+static int hx4700_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+       const socket_state_t *state)
+{
+       switch (state->Vcc) {
+       case 0:
+               gpio_set_value(EGPIO4_CF_3V3_ON, 0);
+               break;
+       case 33:
+               gpio_set_value(EGPIO4_CF_3V3_ON, 1);
+               break;
+       default:
+               printk(KERN_ERR "pcmcia: Unsupported Vcc: %d\n", state->Vcc);
+               return -EINVAL;
+       }
+
+       gpio_set_value(GPIO114_HX4700_CF_RESET, (state->flags & SS_RESET) != 0);
+
+       return 0;
+}
+
+static struct pcmcia_low_level hx4700_pcmcia_ops = {
+       .owner          = THIS_MODULE,
+       .nr             = 1,
+       .hw_init        = hx4700_pcmcia_hw_init,
+       .hw_shutdown    = hx4700_pcmcia_hw_shutdown,
+       .socket_state   = hx4700_pcmcia_socket_state,
+       .configure_socket = hx4700_pcmcia_configure_socket,
+};
+
+static struct platform_device *hx4700_pcmcia_device;
+
+static int __init hx4700_pcmcia_init(void)
+{
+       struct platform_device *pdev;
+
+       if (!machine_is_h4700())
+               return -ENODEV;
+
+       pdev = platform_device_register_data(NULL, "pxa2xx-pcmcia", -1,
+               &hx4700_pcmcia_ops, sizeof(hx4700_pcmcia_ops));
+       if (IS_ERR(pdev))
+               return PTR_ERR(pdev);
+
+       hx4700_pcmcia_device = pdev;
+
+       return 0;
+}
+
+static void __exit hx4700_pcmcia_exit(void)
+{
+       platform_device_unregister(hx4700_pcmcia_device);
+}
+
+module_init(hx4700_pcmcia_init);
+module_exit(hx4700_pcmcia_exit);
+
+MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>");
+MODULE_DESCRIPTION("HP iPAQ hx4700 PCMCIA driver");
+MODULE_LICENSE("GPL");
index ed793b77a1c5e2a77301964fc8822f18c4239e1c..ef6faa5cee46d49a3df43f0567146e777dc8c07c 100644 (file)
@@ -138,6 +138,7 @@ struct asic3_platform_data {
 #define ASIC3_GPIOC13_nPWAIT           ASIC3_CONFIG_GPIO(45, 1, 1, 0)
 #define ASIC3_GPIOC14_nPIOIS16         ASIC3_CONFIG_GPIO(46, 1, 1, 0)
 #define ASIC3_GPIOC15_nPIOR            ASIC3_CONFIG_GPIO(47, 1, 0, 0)
+#define ASIC3_GPIOD4_CF_nCD            ASIC3_CONFIG_GPIO(52, 1, 0, 0)
 #define ASIC3_GPIOD11_nCIOIS16         ASIC3_CONFIG_GPIO(59, 1, 0, 0)
 #define ASIC3_GPIOD12_nCWAIT           ASIC3_CONFIG_GPIO(60, 1, 0, 0)
 #define ASIC3_GPIOD15_nPIOW            ASIC3_CONFIG_GPIO(63, 1, 0, 0)