summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJuergen Borleis <jbe@pengutronix.de>2015-07-31 11:03:52 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2015-08-03 08:52:50 +0200
commit8e04a039a9625f75cdc9274ad06c4b8084565848 (patch)
treeb2a47ac98094558474c0bc6790f02c37b81e1ef3 /arch
parent90c52fe07a1073826d009d2b5f1d4e5d8350580f (diff)
downloadbarebox-8e04a039a9625f75cdc9274ad06c4b8084565848.tar.gz
barebox-8e04a039a9625f75cdc9274ad06c4b8084565848.tar.xz
PPC/PCM030: provide EEPROM support to read factory settings
Above the 0x800 offset the manufacturer provides the board type, a serial number and the MAC as three simple strings. Extract these strings, provide their value as global variables and set the MAC into the ethernet unit. Signed-off-by: Juergen Borleis <jbe@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/ppc/boards/pcm030/Makefile2
-rw-r--r--arch/ppc/boards/pcm030/eeprom.c118
-rw-r--r--arch/ppc/boards/pcm030/pcm030.c13
-rw-r--r--arch/ppc/configs/pcm030_defconfig3
4 files changed, 135 insertions, 1 deletions
diff --git a/arch/ppc/boards/pcm030/Makefile b/arch/ppc/boards/pcm030/Makefile
index e7d744bfb4..4e5dc4f57b 100644
--- a/arch/ppc/boards/pcm030/Makefile
+++ b/arch/ppc/boards/pcm030/Makefile
@@ -1,2 +1,2 @@
-obj-y += pcm030.o
+obj-y += pcm030.o eeprom.o
extra-y += barebox.lds
diff --git a/arch/ppc/boards/pcm030/eeprom.c b/arch/ppc/boards/pcm030/eeprom.c
new file mode 100644
index 0000000000..aa00f361cd
--- /dev/null
+++ b/arch/ppc/boards/pcm030/eeprom.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2015 Juergen Borleis <kernel@pengutronix.de>
+ *
+ * Based on code from:
+ * Copyright (C) 2013 Jan Luebbe <j.luebbe@pengutronix.de>
+ *
+ * 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.
+ */
+#include <common.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fs.h>
+#include <globalvar.h>
+#include <xfuncs.h>
+#include <init.h>
+#include <net.h>
+
+#define PCM030_EEPROM_DEVICE "/dev/eeprom0"
+
+/*
+ * The first 2048 bytes contain the U-Boot environment shipped with the boards.
+ * After that an area begins where some board specific and partially unique data
+ * is stored. All of this data is plain test, string delimiter is the semicolon.
+ * the last string terminates with a '\0'.
+ * One example found in the 'product' area: PCM-030-02REI;017822;0050C2875974\0
+ * The first string seems to be the product type, the second string some kind
+ * of serial number and the last string the boards unique MAC.
+ */
+struct pcm030_eeprom {
+ char env[0x800]; /* u-boot environment */
+ char product[0x80]; /* <product>;<serno>;<mac>\0 */
+} __attribute__((packed));
+
+static void pcm030_read_factory_data(const struct pcm030_eeprom *buf)
+{
+ unsigned u, l;
+ char *board, *serial;
+ char *full_mac = "xx:xx:xx:xx:xx:xx";
+ u8 enetaddr[6];
+
+ u = 0;
+
+ for (l = 0; (l + u) < sizeof(buf->product); l++) {
+ if (buf->product[u + l] != ';')
+ continue;
+ board = xstrndup(&buf->product[u], l);
+ u += l + 1;
+ globalvar_add_simple("model.type", board);
+ free(board);
+ }
+
+ for (l = 0; (l + u) < sizeof(buf->product); l++) {
+ if (buf->product[u + l] != ';')
+ continue;
+ serial = xstrndup(&buf->product[u], l);
+ u += l + 1;
+ globalvar_add_simple("model.serial", serial);
+ free(serial);
+ }
+
+ /* for the MAC do a simple duck test */
+ if (buf->product[u] != ';' && buf->product[u + 12] == '\0') {
+ full_mac[0] = buf->product[u + 0];
+ full_mac[1] = buf->product[u + 1];
+ full_mac[3] = buf->product[u + 2];
+ full_mac[4] = buf->product[u + 3];
+ full_mac[6] = buf->product[u + 4];
+ full_mac[7] = buf->product[u + 5];
+ full_mac[9] = buf->product[u + 6];
+ full_mac[10] = buf->product[u + 7];
+ full_mac[12] = buf->product[u + 8];
+ full_mac[13] = buf->product[u + 9];
+ full_mac[15] = buf->product[u + 10];
+ full_mac[16] = buf->product[u + 11];
+ string_to_ethaddr(full_mac, enetaddr);
+ eth_register_ethaddr(0, enetaddr);
+ return;
+ }
+
+ printf("EEPROM contains no ethernet MAC\n");
+}
+
+static int pcm030_eeprom_read(void)
+{
+ int fd, ret;
+ struct pcm030_eeprom *buf;
+
+ fd = open(PCM030_EEPROM_DEVICE, O_RDONLY);
+ if (fd < 0) {
+ perror("failed to open " PCM030_EEPROM_DEVICE);
+ return fd;
+ }
+
+ buf = xmalloc(sizeof(struct pcm030_eeprom));
+
+ ret = pread(fd, buf, sizeof(struct pcm030_eeprom), 0);
+ if (ret < sizeof(struct pcm030_eeprom)) {
+ perror("failed to read " PCM030_EEPROM_DEVICE);
+ goto out;
+ }
+
+ pcm030_read_factory_data(buf);
+ ret = 0;
+out:
+ free(buf);
+ close(fd);
+
+ return ret;
+}
+late_initcall(pcm030_eeprom_read);
diff --git a/arch/ppc/boards/pcm030/pcm030.c b/arch/ppc/boards/pcm030/pcm030.c
index fe0f046f4e..11b3beb20f 100644
--- a/arch/ppc/boards/pcm030/pcm030.c
+++ b/arch/ppc/boards/pcm030/pcm030.c
@@ -34,11 +34,21 @@
#include <linux/stat.h>
#include <asm/io.h>
#include <fs.h>
+#include <i2c/i2c.h>
static struct fec_platform_data fec_info = {
.xcv_type = PHY_INTERFACE_MODE_MII,
};
+static struct i2c_board_info pcm030_i2c_devices[] = {
+ { I2C_BOARD_INFO("pcf8563", 0x51), },
+ { I2C_BOARD_INFO("24c32", 0x52), },
+};
+
+struct i2c_platform_data pcm030_i2c_plat = {
+ .bitrate = 100000,
+};
+
static int devices_init (void)
{
struct stat s;
@@ -53,6 +63,9 @@ static int devices_init (void)
add_generic_device("fec_mpc5xxx", DEVICE_ID_DYNAMIC, NULL, MPC5XXX_FEC, 0x200,
IORESOURCE_MEM, &fec_info);
+ i2c_register_board_info(0, pcm030_i2c_devices, ARRAY_SIZE(pcm030_i2c_devices));
+ add_generic_device("i2c-fsl", DEVICE_ID_DYNAMIC, NULL, MPC5XXX_I2C2, 0x100,
+ IORESOURCE_MEM, &pcm030_i2c_plat);
ret = stat("/dev/nor0", &s);
if (ret)
diff --git a/arch/ppc/configs/pcm030_defconfig b/arch/ppc/configs/pcm030_defconfig
index 7b84e2f3b6..61380ac294 100644
--- a/arch/ppc/configs/pcm030_defconfig
+++ b/arch/ppc/configs/pcm030_defconfig
@@ -35,8 +35,11 @@ CONFIG_CMD_OFTREE=y
CONFIG_CMD_TIME=y
CONFIG_NET=y
CONFIG_DRIVER_NET_MPC5200=y
+CONFIG_I2C=y
+CONFIG_I2C_IMX=y
CONFIG_MTD=y
CONFIG_DRIVER_CFI=y
CONFIG_CFI_BUFFER_WRITE=y
+CONFIG_EEPROM_AT24=y
CONFIG_FS_TFTP=y
CONFIG_ZLIB=y