[U-Boot] [PATCH v3 3/6] cm-t35: add EEPROM module and pass Linux a serial number

Igor Grinberg grinberg at compulab.co.il
Thu Jan 12 14:26:30 CET 2012


From: Nikita Kiryanov <nikita at compulab.co.il>

Add board specific EEPROM handling module,
read the serial number from the EEPROM and pass it to Linux.

Signed-off-by: Nikita Kiryanov <nikita at compulab.co.il>
Signed-off-by: Igor Grinberg <grinberg at compulab.co.il>
---
Changes in v2:
 * Use CONFIG_SYS_I2C_EEPROM_ADDR instead of a custom define
 * Fix strange linker warning: ".bss section overlaps previous sections"
   by changing the type of the eeprom_layout static global variable to int
   (probably this is a compiler bug).

Changes in v3:
 * Move the default implementation of get_board_serial out of eeprom.h and into
   cm_t35.c
 * Make get_board_serial default implementation weak.

 board/cm_t35/Makefile    |    4 ++-
 board/cm_t35/cm_t35.c    |   11 ++++++
 board/cm_t35/eeprom.c    |   78 ++++++++++++++++++++++++++++++++++++++++++++++
 include/configs/cm_t35.h |    3 ++
 4 files changed, 95 insertions(+), 1 deletions(-)
 create mode 100644 board/cm_t35/eeprom.c

diff --git a/board/cm_t35/Makefile b/board/cm_t35/Makefile
index 27693f0..894fa09 100644
--- a/board/cm_t35/Makefile
+++ b/board/cm_t35/Makefile
@@ -25,7 +25,9 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)lib$(BOARD).o
 
-COBJS	:= cm_t35.o leds.o
+COBJS-$(CONFIG_DRIVER_OMAP34XX_I2C) += eeprom.o
+
+COBJS	:= cm_t35.o leds.o $(COBJS-y)
 
 SRCS	:= $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
diff --git a/board/cm_t35/cm_t35.c b/board/cm_t35/cm_t35.c
index ff372d8..0d5a401 100644
--- a/board/cm_t35/cm_t35.c
+++ b/board/cm_t35/cm_t35.c
@@ -33,6 +33,7 @@
 #include <net.h>
 #include <i2c.h>
 #include <twl4030.h>
+#include <linux/compiler.h>
 
 #include <asm/io.h>
 #include <asm/arch/mem.h>
@@ -421,3 +422,13 @@ int board_eth_init(bd_t *bis)
 	return rc;
 }
 #endif
+
+void __weak get_board_serial(struct tag_serialnr *serialnr)
+{
+	/*
+	 * This corresponds to what happens when we can communicate with the
+	 * eeprom but don't get a valid board serial value.
+	 */
+	serialnr->low = 0;
+	serialnr->high = 0;
+};
diff --git a/board/cm_t35/eeprom.c b/board/cm_t35/eeprom.c
new file mode 100644
index 0000000..93ed6cb
--- /dev/null
+++ b/board/cm_t35/eeprom.c
@@ -0,0 +1,78 @@
+/*
+ * (C) Copyright 2011 CompuLab, Ltd. <www.compulab.co.il>
+ *
+ * Authors: Nikita Kiryanov <nikita at compulab.co.il>
+ *	    Igor Grinberg <grinberg at compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#include <common.h>
+#include <i2c.h>
+
+#define EEPROM_LAYOUT_VER_OFFSET	44
+#define BOARD_SERIAL_OFFSET		20
+#define BOARD_SERIAL_OFFSET_LEGACY	8
+
+#define LAYOUT_INVALID	0
+#define LAYOUT_LEGACY	0xff
+
+static int eeprom_layout; /* Implicitly LAYOUT_INVALID */
+
+static int cm_t3x_eeprom_read(uint offset, uchar *buf, int len)
+{
+	return i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, offset,
+			CONFIG_SYS_I2C_EEPROM_ADDR_LEN, buf, len);
+}
+
+static int eeprom_setup_layout(void)
+{
+	int res;
+
+	if (eeprom_layout != LAYOUT_INVALID)
+		return 0;
+
+	res = cm_t3x_eeprom_read(EEPROM_LAYOUT_VER_OFFSET,
+						(uchar *)&eeprom_layout, 1);
+	if (res) {
+		eeprom_layout = LAYOUT_INVALID;
+		return res;
+	}
+
+	if (eeprom_layout == 0 || eeprom_layout >= 0x20)
+		eeprom_layout = LAYOUT_LEGACY;
+
+	return 0;
+}
+
+void get_board_serial(struct tag_serialnr *serialnr)
+{
+	u32 serial[2];
+	uint offset;
+
+	memset(serialnr, 0, sizeof(*serialnr));
+	if (eeprom_setup_layout())
+		return;
+
+	offset = (eeprom_layout != LAYOUT_LEGACY) ?
+			BOARD_SERIAL_OFFSET : BOARD_SERIAL_OFFSET_LEGACY;
+	if (cm_t3x_eeprom_read(offset, (uchar *)serial, 8))
+		return;
+
+	if (serial[0] != 0xffffffff && serial[1] != 0xffffffff) {
+		serialnr->low = serial[0];
+		serialnr->high = serial[1];
+	}
+}
diff --git a/include/configs/cm_t35.h b/include/configs/cm_t35.h
index 61226d5..fe91c10 100644
--- a/include/configs/cm_t35.h
+++ b/include/configs/cm_t35.h
@@ -72,6 +72,7 @@
 #define CONFIG_SETUP_MEMORY_TAGS
 #define CONFIG_INITRD_TAG
 #define CONFIG_REVISION_TAG
+#define CONFIG_SERIAL_TAG
 
 /*
  * Size of malloc() pool
@@ -153,6 +154,8 @@
 #define CONFIG_SYS_I2C_BUS		0
 #define CONFIG_SYS_I2C_BUS_SELECT	1
 #define CONFIG_DRIVER_OMAP34XX_I2C
+#define CONFIG_SYS_I2C_EEPROM_ADDR	0x50
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	1
 
 /*
  * TWL4030
-- 
1.7.3.4



More information about the U-Boot mailing list