OSDN Git Service

ux500: mop500: add TC35892 and MicroSD slot support
authorRabin Vincent <rabin.vincent@stericsson.com>
Mon, 9 Aug 2010 13:48:17 +0000 (19:18 +0530)
committerLinus Walleij <linus.walleij@stericsson.com>
Wed, 8 Dec 2010 12:13:51 +0000 (13:13 +0100)
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
arch/arm/mach-ux500/board-mop500-sdi.c
arch/arm/mach-ux500/board-mop500.c
arch/arm/mach-ux500/board-mop500.h
arch/arm/mach-ux500/include/mach/irqs-board-mop500.h

index bac9956..f0095ff 100644 (file)
 #include "board-mop500.h"
 
 static pin_cfg_t mop500_sdi_pins[] = {
+       /* SDI0 (MicroSD slot) */
+       GPIO18_MC0_CMDDIR,
+       GPIO19_MC0_DAT0DIR,
+       GPIO20_MC0_DAT2DIR,
+       GPIO21_MC0_DAT31DIR,
+       GPIO22_MC0_FBCLK,
+       GPIO23_MC0_CLK,
+       GPIO24_MC0_CMD,
+       GPIO25_MC0_DAT0,
+       GPIO26_MC0_DAT1,
+       GPIO27_MC0_DAT2,
+       GPIO28_MC0_DAT3,
+
        /* SDI4 (on-board eMMC) */
        GPIO197_MC4_DAT3,
        GPIO198_MC4_DAT2,
@@ -50,6 +63,55 @@ static pin_cfg_t mop500_sdi2_pins[] = {
 };
 
 /*
+ * SDI 0 (MicroSD slot)
+ */
+
+/* MMCIPOWER bits */
+#define MCI_DATA2DIREN         (1 << 2)
+#define MCI_CMDDIREN           (1 << 3)
+#define MCI_DATA0DIREN         (1 << 4)
+#define MCI_DATA31DIREN                (1 << 5)
+#define MCI_FBCLKEN            (1 << 7)
+
+static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd,
+                                  unsigned char power_mode)
+{
+       if (power_mode == MMC_POWER_UP)
+               gpio_set_value(GPIO_SDMMC_EN, 1);
+       else if (power_mode == MMC_POWER_OFF)
+               gpio_set_value(GPIO_SDMMC_EN, 0);
+
+       return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN |
+              MCI_DATA2DIREN | MCI_DATA31DIREN;
+}
+
+static struct mmci_platform_data mop500_sdi0_data = {
+       .vdd_handler    = mop500_sdi0_vdd_handler,
+       .ocr_mask       = MMC_VDD_29_30,
+       .f_max          = 100000000,
+       .capabilities   = MMC_CAP_4_BIT_DATA,
+       .gpio_cd        = GPIO_SDMMC_CD,
+       .gpio_wp        = -1,
+};
+
+void mop500_sdi_tc35892_init(void)
+{
+       int ret;
+
+       ret = gpio_request(GPIO_SDMMC_EN, "SDMMC_EN");
+       if (!ret)
+               ret = gpio_request(GPIO_SDMMC_1V8_3V_SEL,
+                                  "GPIO_SDMMC_1V8_3V_SEL");
+       if (ret)
+               return;
+
+       gpio_direction_output(GPIO_SDMMC_1V8_3V_SEL, 1);
+       gpio_direction_output(GPIO_SDMMC_EN, 0);
+
+       amba_device_register(&u8500_sdi0_device, &iomem_resource);
+}
+
+/*
  * SDI 2 (POP eMMC, not on DB8500ed)
  */
 
@@ -78,6 +140,7 @@ void mop500_sdi_init(void)
 {
        nmk_config_pins(mop500_sdi_pins, ARRAY_SIZE(mop500_sdi_pins));
 
+       u8500_sdi0_device.dev.platform_data = &mop500_sdi0_data;
        u8500_sdi2_device.dev.platform_data = &mop500_sdi2_data;
        u8500_sdi4_device.dev.platform_data = &mop500_sdi4_data;
 
index cac83a6..9aeefc4 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/i2c.h>
 #include <linux/gpio.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/pl022.h>
 #include <linux/spi/spi.h>
 #include <linux/mfd/ab8500.h>
+#include <linux/mfd/tc35892.h>
 #include <linux/input/matrix_keypad.h>
 
 #include <asm/mach-types.h>
@@ -69,6 +71,8 @@ static pin_cfg_t mop500_pins[] = {
        GPIO166_KP_O2,
        GPIO167_KP_O1,
        GPIO168_KP_O0,
+
+       GPIO217_GPIO,           /* GPIO_EXP_INT */
 };
 
 static void ab4500_spi_cs_control(u32 command)
@@ -132,6 +136,33 @@ static struct pl022_ssp_controller ssp0_platform_data = {
        .num_chipselect = 5,
 };
 
+/*
+ * TC35892
+ */
+
+static void mop500_tc35892_init(struct tc35892 *tc35892, unsigned int base)
+{
+       mop500_sdi_tc35892_init();
+}
+
+static struct tc35892_gpio_platform_data mop500_tc35892_gpio_data = {
+       .gpio_base      = MOP500_EGPIO(0),
+       .setup          = mop500_tc35892_init,
+};
+
+static struct tc35892_platform_data mop500_tc35892_data = {
+       .gpio           = &mop500_tc35892_gpio_data,
+       .irq_base       = MOP500_EGPIO_IRQ_BASE,
+};
+
+static struct i2c_board_info mop500_i2c0_devices[] = {
+       {
+               I2C_BOARD_INFO("tc35892", 0x42),
+               .irq            = NOMADIK_GPIO_TO_IRQ(217),
+               .platform_data  = &mop500_tc35892_data,
+       },
+};
+
 #define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \
 static struct nmk_i2c_controller u8500_i2c##id##_data = { \
        /*                              \
@@ -314,6 +345,9 @@ static void __init u8500_init_machine(void)
                        ARRAY_SIZE(ab8500_spi_devices));
        else /* If HW is v.1.1 or later use I2C to access AB8500 */
                platform_device_register(&ab8500_device);
+
+       i2c_register_board_info(0, mop500_i2c0_devices,
+                               ARRAY_SIZE(mop500_i2c0_devices));
 }
 
 MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
index 2d24032..3a338e6 100644 (file)
@@ -7,6 +7,14 @@
 #ifndef __BOARD_MOP500_H
 #define __BOARD_MOP500_H
 
+#define MOP500_EGPIO(x)                        (NOMADIK_NR_GPIO + (x))
+
+/* GPIOs on the TC35892 expander */
+#define GPIO_SDMMC_CD                  MOP500_EGPIO(3)
+#define GPIO_SDMMC_EN                  MOP500_EGPIO(17)
+#define GPIO_SDMMC_1V8_3V_SEL          MOP500_EGPIO(18)
+
 extern void mop500_sdi_init(void);
+extern void mop500_sdi_tc35892_init(void);
 
 #endif
index cca4f70..7ee8aaa 100644 (file)
 #define MOP500_AB8500_IRQ_BASE         IRQ_BOARD_START
 #define MOP500_AB8500_IRQ_END          (MOP500_AB8500_IRQ_BASE \
                                         + AB8500_NR_IRQS)
-#define MOP500_IRQ_END                 MOP500_AB8500_IRQ_END
+
+#define TC35892_NR_INTERNAL_IRQS       8
+#define TC35892_INT_GPIO(x)            (TC35892_NR_INTERNAL_IRQS + (x))
+#define TC35892_NR_GPIOS               24
+#define TC35892_NR_IRQS                        TC35892_INT_GPIO(TC35892_NR_GPIOS)
+
+#define MOP500_EGPIO_NR_IRQS           TC35892_NR_IRQS
+
+#define MOP500_EGPIO_IRQ_BASE          MOP500_AB8500_IRQ_END
+#define MOP500_EGPIO_IRQ_END           (MOP500_EGPIO_IRQ_BASE \
+                                        + MOP500_EGPIO_NR_IRQS)
+
+#define MOP500_IRQ_END                 MOP500_EGPIO_IRQ_END
 
 #if MOP500_IRQ_END > IRQ_BOARD_END
 #undef IRQ_BOARD_END