Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind...
[pandora-kernel.git] / arch / arm / mach-omap2 / board-omap3beagle.c
index 9d9f5b8..14f4224 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
 
 #include <linux/regulator/machine.h>
 #include <linux/i2c/twl.h>
 #include <plat/gpmc.h>
 #include <plat/nand.h>
 #include <plat/usb.h>
-#include <plat/timer-gp.h>
 
 #include "mux.h"
 #include "hsmmc.h"
+#include "timer-gp.h"
 
 #define NAND_BLOCK_SIZE                SZ_128K
 
+/*
+ * OMAP3 Beagle revision
+ * Run time detection of Beagle revision is done by reading GPIO.
+ * GPIO ID -
+ *     AXBX    = GPIO173, GPIO172, GPIO171: 1 1 1
+ *     C1_3    = GPIO173, GPIO172, GPIO171: 1 1 0
+ *     C4      = GPIO173, GPIO172, GPIO171: 1 0 1
+ *     XM      = GPIO173, GPIO172, GPIO171: 0 0 0
+ */
+enum {
+       OMAP3BEAGLE_BOARD_UNKN = 0,
+       OMAP3BEAGLE_BOARD_AXBX,
+       OMAP3BEAGLE_BOARD_C1_3,
+       OMAP3BEAGLE_BOARD_C4,
+       OMAP3BEAGLE_BOARD_XM,
+};
+
+static u8 omap3_beagle_version;
+
+static u8 omap3_beagle_get_rev(void)
+{
+       return omap3_beagle_version;
+}
+
+static void __init omap3_beagle_init_rev(void)
+{
+       int ret;
+       u16 beagle_rev = 0;
+
+       omap_mux_init_gpio(171, OMAP_PIN_INPUT_PULLUP);
+       omap_mux_init_gpio(172, OMAP_PIN_INPUT_PULLUP);
+       omap_mux_init_gpio(173, OMAP_PIN_INPUT_PULLUP);
+
+       ret = gpio_request(171, "rev_id_0");
+       if (ret < 0)
+               goto fail0;
+
+       ret = gpio_request(172, "rev_id_1");
+       if (ret < 0)
+               goto fail1;
+
+       ret = gpio_request(173, "rev_id_2");
+       if (ret < 0)
+               goto fail2;
+
+       gpio_direction_input(171);
+       gpio_direction_input(172);
+       gpio_direction_input(173);
+
+       beagle_rev = gpio_get_value(171) | (gpio_get_value(172) << 1)
+                       | (gpio_get_value(173) << 2);
+
+       switch (beagle_rev) {
+       case 7:
+               printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n");
+               omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX;
+               break;
+       case 6:
+               printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n");
+               omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3;
+               break;
+       case 5:
+               printk(KERN_INFO "OMAP3 Beagle Rev: C4\n");
+               omap3_beagle_version = OMAP3BEAGLE_BOARD_C4;
+               break;
+       case 0:
+               printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
+               omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
+               break;
+       default:
+               printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
+               omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+       }
+
+       return;
+
+fail2:
+       gpio_free(172);
+fail1:
+       gpio_free(171);
+fail0:
+       printk(KERN_ERR "Unable to get revision detection GPIO pins\n");
+       omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+
+       return;
+}
+
 static struct mtd_partition omap3beagle_nand_partitions[] = {
        /* All the partition sizes are listed in terms of NAND block size */
        {
@@ -166,7 +254,7 @@ static void __init beagle_display_init(void)
 static struct omap2_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
-               .wires          = 8,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = 29,
        },
        {}      /* Terminator */
@@ -185,7 +273,10 @@ static struct gpio_led gpio_leds[];
 static int beagle_twl_gpio_setup(struct device *dev,
                unsigned gpio, unsigned ngpio)
 {
-       if (system_rev >= 0x20 && system_rev <= 0x34301000) {
+       if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+               mmc[0].gpio_wp = -EINVAL;
+       } else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
+               (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
                omap_mux_init_gpio(23, OMAP_PIN_INPUT);
                mmc[0].gpio_wp = 23;
        } else {
@@ -322,13 +413,19 @@ static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
        },
 };
 
+static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
+       {
+               I2C_BOARD_INFO("eeprom", 0x50),
+       },
+};
+
 static int __init omap3_beagle_i2c_init(void)
 {
        omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
                        ARRAY_SIZE(beagle_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);
+       omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom));
        return 0;
 }
 
@@ -464,6 +561,7 @@ static struct omap_musb_board_data musb_board_data = {
 static void __init omap3_beagle_init(void)
 {
        omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+       omap3_beagle_init_rev();
        omap3_beagle_i2c_init();
        platform_add_devices(omap3_beagle_devices,
                        ARRAY_SIZE(omap3_beagle_devices));