Merge branch 'for-linus' of git://android.git.kernel.org/kernel/tegra
[pandora-kernel.git] / arch / arm / mach-omap2 / board-omap4panda.c
index ed61c1f..c936c6d 100644 (file)
 #include <linux/usb/otg.h>
 #include <linux/i2c/twl.h>
 #include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/wl12xx.h>
 
 #include <mach/hardware.h>
 #include <mach/omap4-common.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <plat/display.h>
 
 #include <plat/board.h>
 #include <plat/common.h>
 #include <plat/usb.h>
 #include <plat/mmc.h>
+#include <plat/panel-generic-dpi.h>
 #include "timer-gp.h"
 
 #include "hsmmc.h"
 
 #define GPIO_HUB_POWER         1
 #define GPIO_HUB_NRESET                62
+#define GPIO_WIFI_PMENA                43
+#define GPIO_WIFI_IRQ          53
+#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
+#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
+
+/* wl127x BT, FM, GPS connectivity chip */
+static int wl1271_gpios[] = {46, -1, -1};
+static struct platform_device wl1271_device = {
+       .name   = "kim",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &wl1271_gpios,
+       },
+};
 
 static struct gpio_led gpio_leds[] = {
        {
@@ -74,13 +92,13 @@ static struct platform_device leds_gpio = {
 
 static struct platform_device *panda_devices[] __initdata = {
        &leds_gpio,
+       &wl1271_device,
 };
 
-static void __init omap4_panda_init_irq(void)
+static void __init omap4_panda_init_early(void)
 {
        omap2_init_common_infrastructure();
        omap2_init_common_devices(NULL, NULL);
-       gic_init_irq();
 }
 
 static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
@@ -163,14 +181,60 @@ static struct omap2_hsmmc_info mmc[] = {
                .gpio_wp        = -EINVAL,
                .gpio_cd        = -EINVAL,
        },
+       {
+               .name           = "wl1271",
+               .mmc            = 5,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+               .gpio_wp        = -EINVAL,
+               .gpio_cd        = -EINVAL,
+               .ocr_mask       = MMC_VDD_165_195,
+               .nonremovable   = true,
+       },
        {}      /* Terminator */
 };
 
 static struct regulator_consumer_supply omap4_panda_vmmc_supply[] = {
        {
                .supply = "vmmc",
-               .dev_name = "mmci-omap-hs.0",
+               .dev_name = "omap_hsmmc.0",
+       },
+};
+
+static struct regulator_consumer_supply omap4_panda_vmmc5_supply = {
+       .supply = "vmmc",
+       .dev_name = "omap_hsmmc.4",
+};
+
+static struct regulator_init_data panda_vmmc5 = {
+       .constraints = {
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
        },
+       .num_consumer_supplies = 1,
+       .consumer_supplies = &omap4_panda_vmmc5_supply,
+};
+
+static struct fixed_voltage_config panda_vwlan = {
+       .supply_name = "vwl1271",
+       .microvolts = 1800000, /* 1.8V */
+       .gpio = GPIO_WIFI_PMENA,
+       .startup_delay = 70000, /* 70msec */
+       .enable_high = 1,
+       .enabled_at_boot = 0,
+       .init_data = &panda_vmmc5,
+};
+
+static struct platform_device omap_vwlan_device = {
+       .name           = "reg-fixed-voltage",
+       .id             = 1,
+       .dev = {
+               .platform_data = &panda_vwlan,
+       },
+};
+
+struct wl12xx_platform_data omap_panda_wlan_data  __initdata = {
+       .irq = OMAP_GPIO_IRQ(GPIO_WIFI_IRQ),
+       /* PANDA ref clock is 38.4 MHz */
+       .board_ref_clock = 2,
 };
 
 static int omap4_twl6030_hsmmc_late_init(struct device *dev)
@@ -306,7 +370,6 @@ static struct regulator_init_data omap4_panda_vana = {
        .constraints = {
                .min_uV                 = 2100000,
                .max_uV                 = 2100000,
-               .apply_uV               = true,
                .valid_modes_mask       = REGULATOR_MODE_NORMAL
                                        | REGULATOR_MODE_STANDBY,
                .valid_ops_mask  = REGULATOR_CHANGE_MODE
@@ -318,7 +381,6 @@ static struct regulator_init_data omap4_panda_vcxio = {
        .constraints = {
                .min_uV                 = 1800000,
                .max_uV                 = 1800000,
-               .apply_uV               = true,
                .valid_modes_mask       = REGULATOR_MODE_NORMAL
                                        | REGULATOR_MODE_STANDBY,
                .valid_ops_mask  = REGULATOR_CHANGE_MODE
@@ -330,7 +392,6 @@ static struct regulator_init_data omap4_panda_vdac = {
        .constraints = {
                .min_uV                 = 1800000,
                .max_uV                 = 1800000,
-               .apply_uV               = true,
                .valid_modes_mask       = REGULATOR_MODE_NORMAL
                                        | REGULATOR_MODE_STANDBY,
                .valid_ops_mask  = REGULATOR_CHANGE_MODE
@@ -350,6 +411,12 @@ static struct regulator_init_data omap4_panda_vusb = {
        },
 };
 
+static struct regulator_init_data omap4_panda_clk32kg = {
+       .constraints = {
+               .valid_ops_mask         = REGULATOR_CHANGE_STATUS,
+       },
+};
+
 static struct twl4030_platform_data omap4_panda_twldata = {
        .irq_base       = TWL6030_IRQ_BASE,
        .irq_end        = TWL6030_IRQ_END,
@@ -365,6 +432,7 @@ static struct twl4030_platform_data omap4_panda_twldata = {
        .vaux1          = &omap4_panda_vaux1,
        .vaux2          = &omap4_panda_vaux2,
        .vaux3          = &omap4_panda_vaux3,
+       .clk32kg        = &omap4_panda_clk32kg,
        .usb            = &omap4_usbphy_data,
 };
 
@@ -376,6 +444,17 @@ static struct i2c_board_info __initdata omap4_panda_i2c_boardinfo[] = {
                .platform_data = &omap4_panda_twldata,
        },
 };
+
+/*
+ * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
+ * is connected as I2C slave device, and can be accessed at address 0x50
+ */
+static struct i2c_board_info __initdata panda_i2c_eeprom[] = {
+       {
+               I2C_BOARD_INFO("eeprom", 0x50),
+       },
+};
+
 static int __init omap4_panda_i2c_init(void)
 {
        /*
@@ -385,19 +464,284 @@ static int __init omap4_panda_i2c_init(void)
        omap_register_i2c_bus(1, 400, omap4_panda_i2c_boardinfo,
                        ARRAY_SIZE(omap4_panda_i2c_boardinfo));
        omap_register_i2c_bus(2, 400, NULL, 0);
-       omap_register_i2c_bus(3, 400, NULL, 0);
+       /*
+        * Bus 3 is attached to the DVI port where devices like the pico DLP
+        * projector don't work reliably with 400kHz
+        */
+       omap_register_i2c_bus(3, 100, panda_i2c_eeprom,
+                                       ARRAY_SIZE(panda_i2c_eeprom));
        omap_register_i2c_bus(4, 400, NULL, 0);
        return 0;
 }
 
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
+       /* WLAN IRQ - GPIO 53 */
+       OMAP4_MUX(GPMC_NCS3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+       /* WLAN POWER ENABLE - GPIO 43 */
+       OMAP4_MUX(GPMC_A19, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
+       /* WLAN SDIO: MMC5 CMD */
+       OMAP4_MUX(SDMMC5_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+       /* WLAN SDIO: MMC5 CLK */
+       OMAP4_MUX(SDMMC5_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+       /* WLAN SDIO: MMC5 DAT[0-3] */
+       OMAP4_MUX(SDMMC5_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+       OMAP4_MUX(SDMMC5_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+       OMAP4_MUX(SDMMC5_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+       OMAP4_MUX(SDMMC5_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+       /* gpio 0 - TFP410 PD */
+       OMAP4_MUX(KPD_COL1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE3),
+       /* dispc2_data23 */
+       OMAP4_MUX(USBB2_ULPITLL_STP, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data22 */
+       OMAP4_MUX(USBB2_ULPITLL_DIR, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data21 */
+       OMAP4_MUX(USBB2_ULPITLL_NXT, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data20 */
+       OMAP4_MUX(USBB2_ULPITLL_DAT0, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data19 */
+       OMAP4_MUX(USBB2_ULPITLL_DAT1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data18 */
+       OMAP4_MUX(USBB2_ULPITLL_DAT2, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data15 */
+       OMAP4_MUX(USBB2_ULPITLL_DAT3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data14 */
+       OMAP4_MUX(USBB2_ULPITLL_DAT4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data13 */
+       OMAP4_MUX(USBB2_ULPITLL_DAT5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data12 */
+       OMAP4_MUX(USBB2_ULPITLL_DAT6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data11 */
+       OMAP4_MUX(USBB2_ULPITLL_DAT7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data10 */
+       OMAP4_MUX(DPM_EMU3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data9 */
+       OMAP4_MUX(DPM_EMU4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data16 */
+       OMAP4_MUX(DPM_EMU5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data17 */
+       OMAP4_MUX(DPM_EMU6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_hsync */
+       OMAP4_MUX(DPM_EMU7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_pclk */
+       OMAP4_MUX(DPM_EMU8, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_vsync */
+       OMAP4_MUX(DPM_EMU9, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_de */
+       OMAP4_MUX(DPM_EMU10, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data8 */
+       OMAP4_MUX(DPM_EMU11, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data7 */
+       OMAP4_MUX(DPM_EMU12, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data6 */
+       OMAP4_MUX(DPM_EMU13, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data5 */
+       OMAP4_MUX(DPM_EMU14, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data4 */
+       OMAP4_MUX(DPM_EMU15, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data3 */
+       OMAP4_MUX(DPM_EMU16, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data2 */
+       OMAP4_MUX(DPM_EMU17, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data1 */
+       OMAP4_MUX(DPM_EMU18, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+       /* dispc2_data0 */
+       OMAP4_MUX(DPM_EMU19, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
        { .reg_offset = OMAP_MUX_TERMINATOR },
 };
+
+static struct omap_device_pad serial2_pads[] __initdata = {
+       OMAP_MUX_STATIC("uart2_cts.uart2_cts",
+                        OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+       OMAP_MUX_STATIC("uart2_rts.uart2_rts",
+                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+       OMAP_MUX_STATIC("uart2_rx.uart2_rx",
+                        OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+       OMAP_MUX_STATIC("uart2_tx.uart2_tx",
+                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+};
+
+static struct omap_device_pad serial3_pads[] __initdata = {
+       OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
+                        OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+       OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
+                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+       OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
+                        OMAP_PIN_INPUT | OMAP_MUX_MODE0),
+       OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
+                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+};
+
+static struct omap_device_pad serial4_pads[] __initdata = {
+       OMAP_MUX_STATIC("uart4_rx.uart4_rx",
+                        OMAP_PIN_INPUT | OMAP_MUX_MODE0),
+       OMAP_MUX_STATIC("uart4_tx.uart4_tx",
+                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+};
+
+static struct omap_board_data serial2_data = {
+       .id             = 1,
+       .pads           = serial2_pads,
+       .pads_cnt       = ARRAY_SIZE(serial2_pads),
+};
+
+static struct omap_board_data serial3_data = {
+       .id             = 2,
+       .pads           = serial3_pads,
+       .pads_cnt       = ARRAY_SIZE(serial3_pads),
+};
+
+static struct omap_board_data serial4_data = {
+       .id             = 3,
+       .pads           = serial4_pads,
+       .pads_cnt       = ARRAY_SIZE(serial4_pads),
+};
+
+static inline void board_serial_init(void)
+{
+       struct omap_board_data bdata;
+       bdata.flags     = 0;
+       bdata.pads      = NULL;
+       bdata.pads_cnt  = 0;
+       bdata.id        = 0;
+       /* pass dummy data for UART1 */
+       omap_serial_init_port(&bdata);
+
+       omap_serial_init_port(&serial2_data);
+       omap_serial_init_port(&serial3_data);
+       omap_serial_init_port(&serial4_data);
+}
 #else
 #define board_mux      NULL
+
+static inline void board_serial_init(void)
+{
+       omap_serial_init();
+}
 #endif
 
+/* Display DVI */
+#define PANDA_DVI_TFP410_POWER_DOWN_GPIO       0
+
+static int omap4_panda_enable_dvi(struct omap_dss_device *dssdev)
+{
+       gpio_set_value(dssdev->reset_gpio, 1);
+       return 0;
+}
+
+static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
+{
+       gpio_set_value(dssdev->reset_gpio, 0);
+}
+
+/* Using generic display panel */
+static struct panel_generic_dpi_data omap4_dvi_panel = {
+       .name                   = "generic",
+       .platform_enable        = omap4_panda_enable_dvi,
+       .platform_disable       = omap4_panda_disable_dvi,
+};
+
+struct omap_dss_device omap4_panda_dvi_device = {
+       .type                   = OMAP_DISPLAY_TYPE_DPI,
+       .name                   = "dvi",
+       .driver_name            = "generic_dpi_panel",
+       .data                   = &omap4_dvi_panel,
+       .phy.dpi.data_lines     = 24,
+       .reset_gpio             = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
+       .channel                = OMAP_DSS_CHANNEL_LCD2,
+};
+
+int __init omap4_panda_dvi_init(void)
+{
+       int r;
+
+       /* Requesting TFP410 DVI GPIO and disabling it, at bootup */
+       r = gpio_request_one(omap4_panda_dvi_device.reset_gpio,
+                               GPIOF_OUT_INIT_LOW, "DVI PD");
+       if (r)
+               pr_err("Failed to get DVI powerdown GPIO\n");
+
+       return r;
+}
+
+
+static void omap4_panda_hdmi_mux_init(void)
+{
+       /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
+       omap_mux_init_signal("hdmi_hpd",
+                       OMAP_PIN_INPUT_PULLUP);
+       omap_mux_init_signal("hdmi_cec",
+                       OMAP_PIN_INPUT_PULLUP);
+       /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
+       omap_mux_init_signal("hdmi_ddc_scl",
+                       OMAP_PIN_INPUT_PULLUP);
+       omap_mux_init_signal("hdmi_ddc_sda",
+                       OMAP_PIN_INPUT_PULLUP);
+}
+
+static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
+{
+       int status;
+
+       status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH,
+                                                       "hdmi_gpio_hpd");
+       if (status) {
+               pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD);
+               return status;
+       }
+       status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH,
+                                                       "hdmi_gpio_ls_oe");
+       if (status) {
+               pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE);
+               goto error1;
+       }
+
+       return 0;
+
+error1:
+       gpio_free(HDMI_GPIO_HPD);
+
+       return status;
+}
+
+static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
+{
+       gpio_free(HDMI_GPIO_LS_OE);
+       gpio_free(HDMI_GPIO_HPD);
+}
+
+static struct omap_dss_device  omap4_panda_hdmi_device = {
+       .name = "hdmi",
+       .driver_name = "hdmi_panel",
+       .type = OMAP_DISPLAY_TYPE_HDMI,
+       .platform_enable = omap4_panda_panel_enable_hdmi,
+       .platform_disable = omap4_panda_panel_disable_hdmi,
+       .channel = OMAP_DSS_CHANNEL_DIGIT,
+};
+
+static struct omap_dss_device *omap4_panda_dss_devices[] = {
+       &omap4_panda_dvi_device,
+       &omap4_panda_hdmi_device,
+};
+
+static struct omap_dss_board_info omap4_panda_dss_data = {
+       .num_devices    = ARRAY_SIZE(omap4_panda_dss_devices),
+       .devices        = omap4_panda_dss_devices,
+       .default_device = &omap4_panda_dvi_device,
+};
+
+void omap4_panda_display_init(void)
+{
+       int r;
+
+       r = omap4_panda_dvi_init();
+       if (r)
+               pr_err("error initializing panda DVI\n");
+
+       omap4_panda_hdmi_mux_init();
+       omap_display_init(&omap4_panda_dss_data);
+}
+
 static void __init omap4_panda_init(void)
 {
        int package = OMAP_PACKAGE_CBS;
@@ -406,12 +750,17 @@ static void __init omap4_panda_init(void)
                package = OMAP_PACKAGE_CBL;
        omap4_mux_init(board_mux, package);
 
+       if (wl12xx_set_platform_data(&omap_panda_wlan_data))
+               pr_err("error setting wl12xx data\n");
+
        omap4_panda_i2c_init();
        platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
-       omap_serial_init();
+       platform_device_register(&omap_vwlan_device);
+       board_serial_init();
        omap4_twl6030_hsmmc_init(mmc);
        omap4_ehci_init();
        usb_musb_init(&musb_board_data);
+       omap4_panda_display_init();
 }
 
 static void __init omap4_panda_map_io(void)
@@ -425,7 +774,8 @@ MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
        .boot_params    = 0x80000100,
        .reserve        = omap_reserve,
        .map_io         = omap4_panda_map_io,
-       .init_irq       = omap4_panda_init_irq,
+       .init_early     = omap4_panda_init_early,
+       .init_irq       = gic_init_irq,
        .init_machine   = omap4_panda_init,
        .timer          = &omap_timer,
 MACHINE_END