summaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/board-igep0020.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-25 20:46:56 (GMT)
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-25 20:46:56 (GMT)
commit7b6181e06841f5ad15c4ff708b967b4db65a64de (patch)
treebdfcf5b74b692f76581156e452d268b64c795200 /arch/arm/mach-omap2/board-igep0020.c
parent72e58063d63c5f0a7bf65312f1e3a5ed9bb5c2ff (diff)
parentbc487fb341af05120bccb9f59ce76302391dcc77 (diff)
downloadlinux-7b6181e06841f5ad15c4ff708b967b4db65a64de.tar.xz
Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6
* 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6: (163 commits) omap: complete removal of machine_desc.io_pg_offst and .phys_io omap: UART: fix wakeup registers for OMAP24xx UART2 omap: Fix spotty MMC voltages ASoC: OMAP4: MCPDM: Remove unnecessary include of plat/control.h serial: omap-serial: fix signess error OMAP3: DMA: Errata i541: sDMA FIFO draining does not finish omap: dma: Fix buffering disable bit setting for omap24xx omap: serial: Fix the boot-up crash/reboot without CONFIG_PM OMAP3: PM: fix scratchpad memory accesses for off-mode omap4: pandaboard: enable the ehci port on pandaboard omap4: pandaboard: Fix the init if CONFIG_MMC_OMAP_HS is not set omap4: pandaboard: remove unused hsmmc definition OMAP: McBSP: Remove null omap44xx ops comment OMAP: McBSP: Swap CLKS source definition OMAP: McBSP: Fix CLKR and FSR signal muxing OMAP2+: clock: reduce the amount of standard debugging while disabling unused clocks OMAP: control: move plat-omap/control.h to mach-omap2/control.h OMAP: split plat-omap/common.c OMAP: McBSP: implement functional clock switching via clock framework OMAP: McBSP: implement McBSP CLKR and FSR signal muxing via mach-omap2/mcbsp.c ... Fixed up trivial conflicts in arch/arm/mach-omap2/ {board-zoom-peripherals.c,devices.c} as per Tony
Diffstat (limited to 'arch/arm/mach-omap2/board-igep0020.c')
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c369
1 files changed, 244 insertions, 125 deletions
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index b62a68b..5e035a5 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -20,6 +20,7 @@
#include <linux/regulator/machine.h>
#include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -38,12 +39,61 @@
#define IGEP2_SMSC911X_CS 5
#define IGEP2_SMSC911X_GPIO 176
#define IGEP2_GPIO_USBH_NRESET 24
-#define IGEP2_GPIO_LED0_GREEN 26
-#define IGEP2_GPIO_LED0_RED 27
-#define IGEP2_GPIO_LED1_RED 28
-#define IGEP2_GPIO_DVI_PUP 170
-#define IGEP2_GPIO_WIFI_NPD 94
-#define IGEP2_GPIO_WIFI_NRESET 95
+#define IGEP2_GPIO_LED0_GREEN 26
+#define IGEP2_GPIO_LED0_RED 27
+#define IGEP2_GPIO_LED1_RED 28
+#define IGEP2_GPIO_DVI_PUP 170
+
+#define IGEP2_RB_GPIO_WIFI_NPD 94
+#define IGEP2_RB_GPIO_WIFI_NRESET 95
+#define IGEP2_RB_GPIO_BT_NRESET 137
+#define IGEP2_RC_GPIO_WIFI_NPD 138
+#define IGEP2_RC_GPIO_WIFI_NRESET 139
+#define IGEP2_RC_GPIO_BT_NRESET 137
+
+/*
+ * IGEP2 Hardware Revision Table
+ *
+ * --------------------------------------------------------------------------
+ * | Id. | Hw Rev. | HW0 (28) | WIFI_NPD | WIFI_NRESET | BT_NRESET |
+ * --------------------------------------------------------------------------
+ * | 0 | B | high | gpio94 | gpio95 | - |
+ * | 0 | B/C (B-compatible) | high | gpio94 | gpio95 | gpio137 |
+ * | 1 | C | low | gpio138 | gpio139 | gpio137 |
+ * --------------------------------------------------------------------------
+ */
+
+#define IGEP2_BOARD_HWREV_B 0
+#define IGEP2_BOARD_HWREV_C 1
+
+static u8 hwrev;
+
+static void __init igep2_get_revision(void)
+{
+ u8 ret;
+
+ omap_mux_init_gpio(IGEP2_GPIO_LED1_RED, OMAP_PIN_INPUT);
+
+ if ((gpio_request(IGEP2_GPIO_LED1_RED, "GPIO_HW0_REV") == 0) &&
+ (gpio_direction_input(IGEP2_GPIO_LED1_RED) == 0)) {
+ ret = gpio_get_value(IGEP2_GPIO_LED1_RED);
+ if (ret == 0) {
+ pr_info("IGEP2: Hardware Revision C (B-NON compatible)\n");
+ hwrev = IGEP2_BOARD_HWREV_C;
+ } else if (ret == 1) {
+ pr_info("IGEP2: Hardware Revision B/C (B compatible)\n");
+ hwrev = IGEP2_BOARD_HWREV_B;
+ } else {
+ pr_err("IGEP2: Unknown Hardware Revision\n");
+ hwrev = -1;
+ }
+ } else {
+ pr_warning("IGEP2: Could not obtain gpio GPIO_HW0_REV\n");
+ pr_err("IGEP2: Unknown Hardware Revision\n");
+ }
+
+ gpio_free(IGEP2_GPIO_LED1_RED);
+}
#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
@@ -107,7 +157,7 @@ static struct platform_device igep2_onenand_device = {
},
};
-void __init igep2_flash_init(void)
+static void __init igep2_flash_init(void)
{
u8 cs = 0;
u8 onenandcs = GPMC_CS_NUM + 1;
@@ -141,7 +191,7 @@ void __init igep2_flash_init(void)
}
#else
-void __init igep2_flash_init(void) {}
+static void __init igep2_flash_init(void) {}
#endif
#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
@@ -211,10 +261,6 @@ static struct regulator_consumer_supply igep2_vmmc1_supply = {
.supply = "vmmc",
};
-static struct regulator_consumer_supply igep2_vmmc2_supply = {
- .supply = "vmmc",
-};
-
/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
static struct regulator_init_data igep2_vmmc1 = {
.constraints = {
@@ -230,37 +276,95 @@ static struct regulator_init_data igep2_vmmc1 = {
.consumer_supplies = &igep2_vmmc1_supply,
};
-/* VMMC2 for OMAP VDD_MMC2 (i/o) and MMC2 WIFI */
-static struct regulator_init_data igep2_vmmc2 = {
- .constraints = {
- .min_uV = 1850000,
- .max_uV = 3150000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &igep2_vmmc2_supply,
-};
-
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
},
+#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
{
.mmc = 2,
- .wires = 4,
+ .caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
},
+#endif
{} /* Terminator */
};
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led igep2_gpio_leds[] = {
+ [0] = {
+ .name = "gpio-led:red:d0",
+ .gpio = IGEP2_GPIO_LED0_RED,
+ .default_trigger = "default-off"
+ },
+ [1] = {
+ .name = "gpio-led:green:d0",
+ .gpio = IGEP2_GPIO_LED0_GREEN,
+ .default_trigger = "default-off",
+ },
+ [2] = {
+ .name = "gpio-led:red:d1",
+ .gpio = IGEP2_GPIO_LED1_RED,
+ .default_trigger = "default-off",
+ },
+ [3] = {
+ .name = "gpio-led:green:d1",
+ .default_trigger = "heartbeat",
+ .gpio = -EINVAL, /* gets replaced */
+ },
+};
+
+static struct gpio_led_platform_data igep2_led_pdata = {
+ .leds = igep2_gpio_leds,
+ .num_leds = ARRAY_SIZE(igep2_gpio_leds),
+};
+
+static struct platform_device igep2_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &igep2_led_pdata,
+ },
+};
+
+static void __init igep2_leds_init(void)
+{
+ platform_device_register(&igep2_led_device);
+}
+
+#else
+static inline void igep2_leds_init(void)
+{
+ if ((gpio_request(IGEP2_GPIO_LED0_RED, "gpio-led:red:d0") == 0) &&
+ (gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) {
+ gpio_export(IGEP2_GPIO_LED0_RED, 0);
+ gpio_set_value(IGEP2_GPIO_LED0_RED, 0);
+ } else
+ pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
+
+ if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "gpio-led:green:d0") == 0) &&
+ (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) {
+ gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
+ gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0);
+ } else
+ pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
+
+ if ((gpio_request(IGEP2_GPIO_LED1_RED, "gpio-led:red:d1") == 0) &&
+ (gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) {
+ gpio_export(IGEP2_GPIO_LED1_RED, 0);
+ gpio_set_value(IGEP2_GPIO_LED1_RED, 0);
+ } else
+ pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
+
+}
+#endif
+
static int igep2_twl_gpio_setup(struct device *dev,
unsigned gpio, unsigned ngpio)
{
@@ -268,20 +372,48 @@ static int igep2_twl_gpio_setup(struct device *dev,
mmc[0].gpio_cd = gpio + 0;
omap2_hsmmc_init(mmc);
- /* link regulators to MMC adapters ... we "know" the
+ /*
+ * link regulators to MMC adapters ... we "know" the
* regulators will be set up only *after* we return.
- */
+ */
igep2_vmmc1_supply.dev = mmc[0].dev;
- igep2_vmmc2_supply.dev = mmc[1].dev;
+
+ /*
+ * REVISIT: need ehci-omap hooks for external VBUS
+ * power switch and overcurrent detect
+ */
+ if ((gpio_request(gpio + 1, "GPIO_EHCI_NOC") < 0) ||
+ (gpio_direction_input(gpio + 1) < 0))
+ pr_err("IGEP2: Could not obtain gpio for EHCI NOC");
+
+ /*
+ * TWL4030_GPIO_MAX + 0 == ledA, GPIO_USBH_CPEN
+ * (out, active low)
+ */
+ if ((gpio_request(gpio + TWL4030_GPIO_MAX, "GPIO_USBH_CPEN") < 0) ||
+ (gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0) < 0))
+ pr_err("IGEP2: Could not obtain gpio for USBH_CPEN");
+
+ /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
+#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
+ if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0)
+ && (gpio_direction_output(gpio + TWL4030_GPIO_MAX + 1, 1) == 0)) {
+ gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0);
+ gpio_set_value(gpio + TWL4030_GPIO_MAX + 1, 0);
+ } else
+ pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_GREEN\n");
+#else
+ igep2_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1;
+#endif
return 0;
};
-static struct twl4030_gpio_platform_data igep2_gpio_data = {
+static struct twl4030_gpio_platform_data igep2_twl4030_gpio_pdata = {
.gpio_base = OMAP_MAX_GPIO_LINES,
.irq_base = TWL4030_GPIO_IRQ_BASE,
.irq_end = TWL4030_GPIO_IRQ_END,
- .use_leds = false,
+ .use_leds = true,
.setup = igep2_twl_gpio_setup,
};
@@ -355,47 +487,6 @@ static void __init igep2_display_init(void)
pr_err("IGEP v2: Could not obtain gpio GPIO_DVI_PUP\n");
}
-#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
-#include <linux/leds.h>
-
-static struct gpio_led igep2_gpio_leds[] = {
- {
- .name = "led0:red",
- .gpio = IGEP2_GPIO_LED0_RED,
- },
- {
- .name = "led0:green",
- .default_trigger = "heartbeat",
- .gpio = IGEP2_GPIO_LED0_GREEN,
- },
- {
- .name = "led1:red",
- .gpio = IGEP2_GPIO_LED1_RED,
- },
-};
-
-static struct gpio_led_platform_data igep2_led_pdata = {
- .leds = igep2_gpio_leds,
- .num_leds = ARRAY_SIZE(igep2_gpio_leds),
-};
-
-static struct platform_device igep2_led_device = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
- .platform_data = &igep2_led_pdata,
- },
-};
-
-static void __init igep2_init_led(void)
-{
- platform_device_register(&igep2_led_device);
-}
-
-#else
-static inline void igep2_init_led(void) {}
-#endif
-
static struct platform_device *igep2_devices[] __initdata = {
&igep2_dss_device,
};
@@ -425,14 +516,13 @@ static struct twl4030_platform_data igep2_twldata = {
/* platform_data for children goes here */
.usb = &igep2_usb_data,
.codec = &igep2_codec_data,
- .gpio = &igep2_gpio_data,
+ .gpio = &igep2_twl4030_gpio_pdata,
.vmmc1 = &igep2_vmmc1,
- .vmmc2 = &igep2_vmmc2,
.vpll2 = &igep2_vpll2,
};
-static struct i2c_board_info __initdata igep2_i2c_boardinfo[] = {
+static struct i2c_board_info __initdata igep2_i2c1_boardinfo[] = {
{
I2C_BOARD_INFO("twl4030", 0x48),
.flags = I2C_CLIENT_WAKE,
@@ -441,14 +531,29 @@ static struct i2c_board_info __initdata igep2_i2c_boardinfo[] = {
},
};
-static int __init igep2_i2c_init(void)
+static struct i2c_board_info __initdata igep2_i2c3_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("eeprom", 0x50),
+ },
+};
+
+static void __init igep2_i2c_init(void)
{
- omap_register_i2c_bus(1, 2600, igep2_i2c_boardinfo,
- ARRAY_SIZE(igep2_i2c_boardinfo));
- /* 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, NULL, 0);
- return 0;
+ int ret;
+
+ ret = omap_register_i2c_bus(1, 2600, igep2_i2c1_boardinfo,
+ ARRAY_SIZE(igep2_i2c1_boardinfo));
+ if (ret)
+ pr_warning("IGEP2: Could not register I2C1 bus (%d)\n", ret);
+
+ /*
+ * Bus 3 is attached to the DVI port where devices like the pico DLP
+ * projector don't work reliably with 400kHz
+ */
+ ret = omap_register_i2c_bus(3, 100, igep2_i2c3_boardinfo,
+ ARRAY_SIZE(igep2_i2c3_boardinfo));
+ if (ret)
+ pr_warning("IGEP2: Could not register I2C3 bus (%d)\n", ret);
}
static struct omap_musb_board_data musb_board_data = {
@@ -476,9 +581,57 @@ static struct omap_board_mux board_mux[] __initdata = {
#define board_mux NULL
#endif
+#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
+
+static void __init igep2_wlan_bt_init(void)
+{
+ unsigned npd, wreset, btreset;
+
+ /* GPIO's for WLAN-BT combo depends on hardware revision */
+ if (hwrev == IGEP2_BOARD_HWREV_B) {
+ npd = IGEP2_RB_GPIO_WIFI_NPD;
+ wreset = IGEP2_RB_GPIO_WIFI_NRESET;
+ btreset = IGEP2_RB_GPIO_BT_NRESET;
+ } else if (hwrev == IGEP2_BOARD_HWREV_C) {
+ npd = IGEP2_RC_GPIO_WIFI_NPD;
+ wreset = IGEP2_RC_GPIO_WIFI_NRESET;
+ btreset = IGEP2_RC_GPIO_BT_NRESET;
+ } else
+ return;
+
+ /* Set GPIO's for WLAN-BT combo module */
+ if ((gpio_request(npd, "GPIO_WIFI_NPD") == 0) &&
+ (gpio_direction_output(npd, 1) == 0)) {
+ gpio_export(npd, 0);
+ } else
+ pr_warning("IGEP2: Could not obtain gpio GPIO_WIFI_NPD\n");
+
+ if ((gpio_request(wreset, "GPIO_WIFI_NRESET") == 0) &&
+ (gpio_direction_output(wreset, 1) == 0)) {
+ gpio_export(wreset, 0);
+ gpio_set_value(wreset, 0);
+ udelay(10);
+ gpio_set_value(wreset, 1);
+ } else
+ pr_warning("IGEP2: Could not obtain gpio GPIO_WIFI_NRESET\n");
+
+ if ((gpio_request(btreset, "GPIO_BT_NRESET") == 0) &&
+ (gpio_direction_output(btreset, 1) == 0)) {
+ gpio_export(btreset, 0);
+ } else
+ pr_warning("IGEP2: Could not obtain gpio GPIO_BT_NRESET\n");
+}
+#else
+static inline void __init igep2_wlan_bt_init(void) { }
+#endif
+
static void __init igep2_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
+ /* Get IGEP2 hardware revision */
+ igep2_get_revision();
+ /* Register I2C busses and drivers */
igep2_i2c_init();
platform_add_devices(igep2_devices, ARRAY_SIZE(igep2_devices));
omap_serial_init();
@@ -486,50 +639,16 @@ static void __init igep2_init(void)
usb_ehci_init(&ehci_pdata);
igep2_flash_init();
- igep2_init_led();
+ igep2_leds_init();
igep2_display_init();
igep2_init_smsc911x();
- /* GPIO userspace leds */
-#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
- if ((gpio_request(IGEP2_GPIO_LED0_RED, "led0:red") == 0) &&
- (gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) {
- gpio_export(IGEP2_GPIO_LED0_RED, 0);
- gpio_set_value(IGEP2_GPIO_LED0_RED, 0);
- } else
- pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
-
- if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "led0:green") == 0) &&
- (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) {
- gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
- gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0);
- } else
- pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
-
- if ((gpio_request(IGEP2_GPIO_LED1_RED, "led1:red") == 0) &&
- (gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) {
- gpio_export(IGEP2_GPIO_LED1_RED, 0);
- gpio_set_value(IGEP2_GPIO_LED1_RED, 0);
- } else
- pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
-#endif
-
- /* GPIO W-LAN + Bluetooth combo module */
- if ((gpio_request(IGEP2_GPIO_WIFI_NPD, "GPIO_WIFI_NPD") == 0) &&
- (gpio_direction_output(IGEP2_GPIO_WIFI_NPD, 1) == 0)) {
- gpio_export(IGEP2_GPIO_WIFI_NPD, 0);
-/* gpio_set_value(IGEP2_GPIO_WIFI_NPD, 0); */
- } else
- pr_warning("IGEP v2: Could not obtain gpio GPIO_WIFI_NPD\n");
+ /*
+ * WLAN-BT combo module from MuRata wich has a Marvell WLAN
+ * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface.
+ */
+ igep2_wlan_bt_init();
- if ((gpio_request(IGEP2_GPIO_WIFI_NRESET, "GPIO_WIFI_NRESET") == 0) &&
- (gpio_direction_output(IGEP2_GPIO_WIFI_NRESET, 1) == 0)) {
- gpio_export(IGEP2_GPIO_WIFI_NRESET, 0);
- gpio_set_value(IGEP2_GPIO_WIFI_NRESET, 0);
- udelay(10);
- gpio_set_value(IGEP2_GPIO_WIFI_NRESET, 1);
- } else
- pr_warning("IGEP v2: Could not obtain gpio GPIO_WIFI_NRESET\n");
}
MACHINE_START(IGEP0020, "IGEP v2 board")