diff options
Diffstat (limited to 'ANDROID_3.4.5/arch/arm/mach-omap2/board-omap4panda.c')
-rw-r--r-- | ANDROID_3.4.5/arch/arm/mach-omap2/board-omap4panda.c | 587 |
1 files changed, 587 insertions, 0 deletions
diff --git a/ANDROID_3.4.5/arch/arm/mach-omap2/board-omap4panda.c b/ANDROID_3.4.5/arch/arm/mach-omap2/board-omap4panda.c new file mode 100644 index 00000000..1b782ba5 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-omap2/board-omap4panda.c @@ -0,0 +1,587 @@ +/* + * Board support file for OMAP4430 based PandaBoard. + * + * Copyright (C) 2010 Texas Instruments + * + * Author: David Anders <x0132446@ti.com> + * + * Based on mach-omap2/board-4430sdp.c + * + * Author: Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * Based on mach-omap2/board-3430sdp.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/clk.h> +#include <linux/io.h> +#include <linux/leds.h> +#include <linux/gpio.h> +#include <linux/usb/otg.h> +#include <linux/i2c/twl.h> +#include <linux/mfd/twl6040.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> +#include <linux/wl12xx.h> +#include <linux/platform_data/omap-abe-twl6040.h> + +#include <mach/hardware.h> +#include <asm/hardware/gic.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <video/omapdss.h> + +#include <plat/board.h> +#include "common.h" +#include <plat/usb.h> +#include <plat/mmc.h> +#include <video/omap-panel-dvi.h> + +#include "hsmmc.h" +#include "control.h" +#include "mux.h" +#include "common-board-devices.h" + +#define GPIO_HUB_POWER 1 +#define GPIO_HUB_NRESET 62 +#define GPIO_WIFI_PMENA 43 +#define GPIO_WIFI_IRQ 53 +#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */ +#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ +#define HDMI_GPIO_HPD 63 /* Hotplug detect */ + +/* 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[] = { + { + .name = "pandaboard::status1", + .default_trigger = "heartbeat", + .gpio = 7, + }, + { + .name = "pandaboard::status2", + .default_trigger = "mmc0", + .gpio = 8, + }, +}; + +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 struct omap_abe_twl6040_data panda_abe_audio_data = { + /* Audio out */ + .has_hs = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT, + /* HandsFree through expasion connector */ + .has_hf = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT, + /* PandaBoard: FM TX, PandaBoardES: can be connected to audio out */ + .has_aux = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT, + /* PandaBoard: FM RX, PandaBoardES: audio in */ + .has_afm = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT, + /* No jack detection. */ + .jack_detection = 0, + /* MCLK input is 38.4MHz */ + .mclk_freq = 38400000, + +}; + +static struct platform_device panda_abe_audio = { + .name = "omap-abe-twl6040", + .id = -1, + .dev = { + .platform_data = &panda_abe_audio_data, + }, +}; + +static struct platform_device btwilink_device = { + .name = "btwilink", + .id = -1, +}; + +static struct platform_device *panda_devices[] __initdata = { + &leds_gpio, + &wl1271_device, + &panda_abe_audio, + &btwilink_device, +}; + +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, + .phy_reset = false, + .reset_gpio_port[0] = -EINVAL, + .reset_gpio_port[1] = -EINVAL, + .reset_gpio_port[2] = -EINVAL +}; + +static struct gpio panda_ehci_gpios[] __initdata = { + { GPIO_HUB_POWER, GPIOF_OUT_INIT_LOW, "hub_power" }, + { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, "hub_nreset" }, +}; + +static void __init omap4_ehci_init(void) +{ + int ret; + struct clk *phy_ref_clk; + + /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */ + phy_ref_clk = clk_get(NULL, "auxclk3_ck"); + if (IS_ERR(phy_ref_clk)) { + pr_err("Cannot request auxclk3\n"); + return; + } + clk_set_rate(phy_ref_clk, 19200000); + clk_enable(phy_ref_clk); + + /* disable the power to the usb hub prior to init and reset phy+hub */ + ret = gpio_request_array(panda_ehci_gpios, + ARRAY_SIZE(panda_ehci_gpios)); + if (ret) { + pr_err("Unable to initialize EHCI power/reset\n"); + return; + } + + gpio_export(GPIO_HUB_POWER, 0); + gpio_export(GPIO_HUB_NRESET, 0); + gpio_set_value(GPIO_HUB_NRESET, 1); + + usbhs_init(&usbhs_bdata); + + /* enable power to hub */ + gpio_set_value(GPIO_HUB_POWER, 1); +} + +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_UTMI, + .mode = MUSB_OTG, + .power = 100, +}; + +static struct omap2_hsmmc_info mmc[] = { + { + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + .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_vmmc5_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.4"), +}; + +static struct regulator_init_data panda_vmmc5 = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(omap4_panda_vmmc5_supply), + .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 = { + /* PANDA ref clock is 38.4 MHz */ + .board_ref_clock = 2, +}; + +static int omap4_twl6030_hsmmc_late_init(struct device *dev) +{ + int irq = 0; + struct platform_device *pdev = container_of(dev, + struct platform_device, dev); + struct omap_mmc_platform_data *pdata = dev->platform_data; + + if (!pdata) { + dev_err(dev, "%s: NULL platform data\n", __func__); + return -EINVAL; + } + /* Setting MMC1 Card detect Irq */ + if (pdev->id == 0) { + irq = twl6030_mmc_card_detect_config(); + if (irq < 0) { + dev_err(dev, "%s: Error card detect config(%d)\n", + __func__, irq); + return irq; + } + pdata->slots[0].card_detect = twl6030_mmc_card_detect; + } + return 0; +} + +static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev) +{ + struct omap_mmc_platform_data *pdata; + + /* dev can be null if CONFIG_MMC_OMAP_HS is not set */ + if (!dev) { + pr_err("Failed omap4_twl6030_hsmmc_set_late_init\n"); + return; + } + pdata = dev->platform_data; + + pdata->init = omap4_twl6030_hsmmc_late_init; +} + +static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) +{ + struct omap2_hsmmc_info *c; + + omap_hsmmc_init(controllers); + for (c = controllers; c->mmc; c++) + omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev); + + return 0; +} + +static struct twl6040_codec_data twl6040_codec = { + /* single-step ramp for headset and handsfree */ + .hs_left_step = 0x0f, + .hs_right_step = 0x0f, + .hf_left_step = 0x1d, + .hf_right_step = 0x1d, +}; + +static struct twl6040_platform_data twl6040_data = { + .codec = &twl6040_codec, + .audpwron_gpio = 127, + .irq_base = TWL6040_CODEC_IRQ_BASE, +}; + +/* Panda board uses the common PMIC configuration */ +static struct twl4030_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) +{ + omap4_pmic_get_config(&omap4_panda_twldata, TWL_COMMON_PDATA_USB, + TWL_COMMON_REGULATOR_VDAC | + TWL_COMMON_REGULATOR_VAUX2 | + TWL_COMMON_REGULATOR_VAUX3 | + TWL_COMMON_REGULATOR_VMMC | + TWL_COMMON_REGULATOR_VPP | + TWL_COMMON_REGULATOR_VANA | + TWL_COMMON_REGULATOR_VCXIO | + TWL_COMMON_REGULATOR_VUSB | + TWL_COMMON_REGULATOR_CLK32KG); + omap4_pmic_init("twl6030", &omap4_panda_twldata, + &twl6040_data, OMAP44XX_IRQ_SYS_2N); + omap_register_i2c_bus(2, 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 }, +}; + +#else +#define board_mux NULL +#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_dvi_platform_data omap4_dvi_panel = { + .platform_enable = omap4_panda_enable_dvi, + .platform_disable = omap4_panda_disable_dvi, + .i2c_bus_num = 3, +}; + +struct omap_dss_device omap4_panda_dvi_device = { + .type = OMAP_DISPLAY_TYPE_DPI, + .name = "dvi", + .driver_name = "dvi", + .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 struct gpio panda_hdmi_gpios[] = { + { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" }, + { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" }, + { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" }, +}; + +static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev) +{ + int status; + + status = gpio_request_array(panda_hdmi_gpios, + ARRAY_SIZE(panda_hdmi_gpios)); + if (status) + pr_err("Cannot request HDMI GPIOs\n"); + + return status; +} + +static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev) +{ + gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios)); +} + +static struct omap_dss_hdmi_data omap4_panda_hdmi_data = { + .hpd_gpio = 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, + .data = &omap4_panda_hdmi_data, +}; + +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 __init omap4_panda_display_init(void) +{ + int r; + + r = omap4_panda_dvi_init(); + if (r) + pr_err("error initializing panda DVI\n"); + + omap_display_init(&omap4_panda_dss_data); + + /* + * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and + * later have external pull up on the HDMI I2C lines + */ + if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2) + omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP); + else + omap_hdmi_init(0); + + omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN); +} + +static void omap4_panda_init_rev(void) +{ + if (cpu_is_omap443x()) { + /* PandaBoard 4430 */ + /* ASoC audio configuration */ + panda_abe_audio_data.card_name = "PandaBoard"; + panda_abe_audio_data.has_hsmic = 1; + } else { + /* PandaBoard ES */ + /* ASoC audio configuration */ + panda_abe_audio_data.card_name = "PandaBoardES"; + } +} + +static void __init omap4_panda_init(void) +{ + int package = OMAP_PACKAGE_CBS; + int ret; + + if (omap_rev() == OMAP4430_REV_ES1_0) + package = OMAP_PACKAGE_CBL; + omap4_mux_init(board_mux, NULL, package); + + omap_panda_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ); + ret = wl12xx_set_platform_data(&omap_panda_wlan_data); + if (ret) + pr_err("error setting wl12xx data: %d\n", ret); + + omap4_panda_init_rev(); + omap4_panda_i2c_init(); + platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices)); + platform_device_register(&omap_vwlan_device); + omap_serial_init(); + omap_sdrc_init(NULL, NULL); + omap4_twl6030_hsmmc_init(mmc); + omap4_ehci_init(); + usb_musb_init(&musb_board_data); + omap4_panda_display_init(); +} + +MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board") + /* Maintainer: David Anders - Texas Instruments Inc */ + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap4_map_io, + .init_early = omap4430_init_early, + .init_irq = gic_init_irq, + .handle_irq = gic_handle_irq, + .init_machine = omap4_panda_init, + .timer = &omap4_timer, + .restart = omap_prcm_restart, +MACHINE_END |