ARMV7: OMAP3: Add expansion board detection for Beagle

Beagle expansion boards contain an i2c eeprom to identify themselves.
This patch adds code to read and parse the eeprom contents.  It prints
the expansion board name and revision and modifies environment variables
as appropriate. This patch is based on the Overo expansion board code.

Signed-off-by: Koen Kooi <k-kooi@ti.com>
Signed-off-by: Steve Sakoman <steve.sakoman@linaro.org>
Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
diff --git a/board/ti/beagle/beagle.c b/board/ti/beagle/beagle.c
index c5d6679..d9b6f01 100644
--- a/board/ti/beagle/beagle.c
+++ b/board/ti/beagle/beagle.c
@@ -39,6 +39,27 @@
 #include <asm/mach-types.h>
 #include "beagle.h"
 
+#define TWL4030_I2C_BUS			0
+#define EXPANSION_EEPROM_I2C_BUS	1
+#define EXPANSION_EEPROM_I2C_ADDRESS	0x50
+
+#define TINCANTOOLS_ZIPPY		0x01000100
+#define TINCANTOOLS_ZIPPY2		0x02000100
+#define TINCANTOOLS_TRAINER		0x04000100
+#define TINCANTOOLS_SHOWDOG		0x03000100
+#define KBADC_BEAGLEFPGA		0x01000600
+
+#define BEAGLE_NO_EEPROM		0xffffffff
+
+static struct {
+	unsigned int device_vendor;
+	unsigned char revision;
+	unsigned char content;
+	char fab_revision[8];
+	char env_var[16];
+	char env_setting[64];
+} expansion_config;
+
 /*
  * Routine: board_init
  * Description: Early hardware init.
@@ -95,6 +116,31 @@
 }
 
 /*
+ * Routine: get_expansion_id
+ * Description: This function checks for expansion board by checking I2C
+ *		bus 1 for the availability of an AT24C01B serial EEPROM.
+ *		returns the device_vendor field from the EEPROM
+ */
+unsigned int get_expansion_id(void)
+{
+	i2c_set_bus_num(EXPANSION_EEPROM_I2C_BUS);
+
+	/* return BEAGLE_NO_EEPROM if eeprom doesn't respond */
+	if (i2c_probe(EXPANSION_EEPROM_I2C_ADDRESS) == 1) {
+		i2c_set_bus_num(TWL4030_I2C_BUS);
+		return BEAGLE_NO_EEPROM;
+	}
+
+	/* read configuration data */
+	i2c_read(EXPANSION_EEPROM_I2C_ADDRESS, 0, 1, (u8 *)&expansion_config,
+		 sizeof(expansion_config));
+
+	i2c_set_bus_num(TWL4030_I2C_BUS);
+
+	return expansion_config.device_vendor;
+}
+
+/*
  * Routine: misc_init_r
  * Description: Configure board specific parts
  */
@@ -141,6 +187,55 @@
 		printf("Beagle unknown 0x%02x\n", get_board_revision());
 	}
 
+	switch (get_expansion_id()) {
+	case TINCANTOOLS_ZIPPY:
+		printf("Recognized Tincantools Zippy board (rev %d %s)\n",
+			expansion_config.revision,
+			expansion_config.fab_revision);
+		MUX_TINCANTOOLS_ZIPPY();
+		setenv("buddy", "zippy");
+		break;
+	case TINCANTOOLS_ZIPPY2:
+		printf("Recognized Tincantools Zippy2 board (rev %d %s)\n",
+			expansion_config.revision,
+			expansion_config.fab_revision);
+		MUX_TINCANTOOLS_ZIPPY();
+		setenv("buddy", "zippy2");
+		break;
+	case TINCANTOOLS_TRAINER:
+		printf("Recognized Tincantools Trainer board (rev %d %s)\n",
+			expansion_config.revision,
+			expansion_config.fab_revision);
+		MUX_TINCANTOOLS_ZIPPY();
+		MUX_TINCANTOOLS_TRAINER();
+		setenv("buddy", "trainer");
+		break;
+	case TINCANTOOLS_SHOWDOG:
+		printf("Recognized Tincantools Showdow board (rev %d %s)\n",
+			expansion_config.revision,
+			expansion_config.fab_revision);
+		/* Place holder for DSS2 definition for showdog lcd */
+		setenv("defaultdisplay", "showdoglcd");
+		setenv("buddy", "showdog");
+		break;
+	case KBADC_BEAGLEFPGA:
+		printf("Recognized KBADC Beagle FPGA board\n");
+		MUX_KBADC_BEAGLEFPGA();
+		setenv("buddy", "beaglefpga");
+		break;
+	case BEAGLE_NO_EEPROM:
+		printf("No EEPROM on expansion board\n");
+		setenv("buddy", "none");
+		break;
+	default:
+		printf("Unrecognized expansion board: %x\n",
+			expansion_config.device_vendor);
+		setenv("buddy", "unknown");
+	}
+
+	if (expansion_config.content == 1)
+		setenv(expansion_config.env_var, expansion_config.env_setting);
+
 	twl4030_power_init();
 	twl4030_led_init(TWL4030_LED_LEDEN_LEDAON | TWL4030_LED_LEDEN_LEDBON);
 
diff --git a/board/ti/beagle/beagle.h b/board/ti/beagle/beagle.h
index ec0da6d..b22b653 100644
--- a/board/ti/beagle/beagle.h
+++ b/board/ti/beagle/beagle.h
@@ -259,8 +259,8 @@
 	MUX_VAL(CP(HSUSB0_DATA7),	(IEN  | PTD | DIS | M0)) /*HSUSB0_DATA7*/\
 	MUX_VAL(CP(I2C1_SCL),		(IEN  | PTU | EN  | M0)) /*I2C1_SCL*/\
 	MUX_VAL(CP(I2C1_SDA),		(IEN  | PTU | EN  | M0)) /*I2C1_SDA*/\
-	MUX_VAL(CP(I2C2_SCL),		(IEN  | PTU | EN  | M4)) /*GPIO_168*/\
-	MUX_VAL(CP(I2C2_SDA),		(IEN  | PTU | EN  | M4)) /*GPIO_183*/\
+	MUX_VAL(CP(I2C2_SCL),		(IEN  | PTU | EN  | M0)) /*I2C2_SCL*/\
+	MUX_VAL(CP(I2C2_SDA),		(IEN  | PTU | EN  | M0)) /*I2C2_SDA*/\
 	MUX_VAL(CP(I2C3_SCL),		(IEN  | PTU | EN  | M0)) /*I2C3_SCL*/\
 	MUX_VAL(CP(I2C3_SDA),		(IEN  | PTU | EN  | M0)) /*I2C3_SDA*/\
 	MUX_VAL(CP(I2C4_SCL),		(IEN  | PTU | EN  | M0)) /*I2C4_SCL*/\
@@ -415,4 +415,46 @@
 	MUX_VAL(CP(SYS_BOOT5),		(IDIS | PTD | DIS | M3)) /*DSS_DATA22*/\
 	MUX_VAL(CP(SYS_BOOT6),		(IDIS | PTD | DIS | M3)) /*DSS_DATA23*/
 
+#define MUX_TINCANTOOLS_ZIPPY() \
+	MUX_VAL(CP(MMC2_CLK),       (IEN  | PTU | EN  | M0)) /*MMC2_CLK*/\
+	MUX_VAL(CP(MMC2_CMD),       (IEN  | PTU | EN  | M0)) /*MMC2_CMD*/\
+	MUX_VAL(CP(MMC2_DAT0),      (IEN  | PTU | EN  | M0)) /*MMC2_DAT0*/\
+	MUX_VAL(CP(MMC2_DAT1),      (IEN  | PTU | EN  | M0)) /*MMC2_DAT1*/\
+	MUX_VAL(CP(MMC2_DAT2),      (IEN  | PTU | EN  | M0)) /*MMC2_DAT2*/\
+	MUX_VAL(CP(MMC2_DAT3),      (IEN  | PTU | EN  | M0)) /*MMC2_DAT3*/\
+	MUX_VAL(CP(MMC2_DAT4),      (IEN  | PTU | EN  | M1)) /*MMC2_DIR_DAT0*/\
+	MUX_VAL(CP(MMC2_DAT5),      (IEN  | PTU | EN  | M1)) /*MMC2_DIR_DAT1*/\
+	MUX_VAL(CP(MMC2_DAT6),      (IEN  | PTU | EN  | M1)) /*MMC2_DIR_CMD*/\
+	MUX_VAL(CP(MMC2_DAT7),      (IEN  | PTU | EN  | M1)) /*MMC2_CLKIN*/\
+	MUX_VAL(CP(MCBSP1_CLKR),    (IEN  | PTU | EN  | M1)) /*MCSPI4_CLK*/\
+	MUX_VAL(CP(MCBSP1_FSR),     (IEN  | PTU | EN  | M4)) /*GPIO_157*/\
+	MUX_VAL(CP(MCBSP1_DX),      (IEN  | PTD | EN  | M1)) /*MCSPI4_SIMO*/\
+	MUX_VAL(CP(MCBSP1_DR),      (IEN  | PTD | DIS | M1)) /*MCSPI4_SOMI*/\
+	MUX_VAL(CP(MCBSP1_FSX),     (IEN  | PTD | EN  | M1)) /*MCSPI4_CS0*/\
+	MUX_VAL(CP(MCBSP1_CLKX),    (IEN  | PTD | DIS | M4)) /*GPIO_162*/\
+	MUX_VAL(CP(MCBSP3_DX),      (IEN  | PTD | DIS | M4)) /*GPIO_140*/\
+	MUX_VAL(CP(MCBSP3_DR),      (IEN  | PTD | DIS | M4)) /*GPIO_142*/\
+	MUX_VAL(CP(MCBSP3_CLKX),    (IEN  | PTD | DIS | M4)) /*GPIO_141*/
+
+#define MUX_TINCANTOOLS_TRAINER() \
+	MUX_VAL(CP(MMC2_CLK),       (IEN  | PTU | EN  | M4)) /*GPIO_130*/\
+	MUX_VAL(CP(MMC2_CMD),       (IEN  | PTU | EN  | M4)) /*GPIO_131*/\
+	MUX_VAL(CP(MMC2_DAT0),      (IEN  | PTU | EN  | M4)) /*GPIO_132*/\
+	MUX_VAL(CP(MMC2_DAT1),      (IEN  | PTU | EN  | M4)) /*GPIO_133*/\
+	MUX_VAL(CP(MMC2_DAT2),      (IEN  | PTU | EN  | M4)) /*GPIO_134*/\
+	MUX_VAL(CP(MMC2_DAT3),      (IEN  | PTU | EN  | M4)) /*GPIO_135*/\
+	MUX_VAL(CP(MMC2_DAT4),      (IEN  | PTU | EN  | M4)) /*GPIO_136*/\
+	MUX_VAL(CP(MMC2_DAT5),      (IEN  | PTU | EN  | M4)) /*GPIO_137*/\
+	MUX_VAL(CP(MMC2_DAT6),      (IEN  | PTU | EN  | M4)) /*GPIO_138*/\
+	MUX_VAL(CP(MMC2_DAT7),      (IEN  | PTU | EN  | M4)) /*GPIO_139*/\
+	MUX_VAL(CP(MCBSP3_DX),      (IEN  | PTU | EN  | M4)) /*GPIO_140*/\
+	MUX_VAL(CP(MCBSP3_CLKX),    (IEN  | PTU | EN  | M4)) /*GPIO_141*/\
+	MUX_VAL(CP(MCBSP1_CLKX),    (IEN  | PTU | EN  | M4)) /*GPIO_162*/
+
+#define MUX_KBADC_BEAGLEFPGA() \
+	MUX_VAL(CP(MCBSP1_CLKR),    (IEN  | PTU | DIS | M1)) /*MCSPI4_CLK*/\
+	MUX_VAL(CP(MCBSP1_DX),      (IDIS | PTU | DIS | M1)) /*MCSPI4_SIMO*/\
+	MUX_VAL(CP(MCBSP1_DR),      (IEN  | PTU | EN  | M1)) /*MCSPI4_SOMI*/\
+	MUX_VAL(CP(MCBSP1_FSX),     (IDIS | PTU | DIS | M1)) /*MCSPI4_CS0*/
+
 #endif