summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Ungar <david.ungar@timesys.com>2010-10-11 14:23:54 -0400
committerDavid Ungar <david.ungar@timesys.com>2010-10-11 14:39:18 -0400
commit5ecaddd0ed2e7c7a65ccd5eb63b94df1a116e50e (patch)
treeb8945dfe304252c32daa1a322344d8b7e5539c42
parente652fd7cf6150d7df26e990a828e4f4a68452da4 (diff)
Product id fix
-rw-r--r--board/omap3/logic/logic-data.c728
-rw-r--r--board/omap3/logic/logic.c38
-rw-r--r--board/omap3/logic/product_id.h2
3 files changed, 476 insertions, 292 deletions
diff --git a/board/omap3/logic/logic-data.c b/board/omap3/logic/logic-data.c
index cb68eba861..b6720ce1fc 100644
--- a/board/omap3/logic/logic-data.c
+++ b/board/omap3/logic/logic-data.c
@@ -23,10 +23,8 @@
#include <command.h>
#include <asm/arch/cpu.h>
#include <asm/io.h>
-// #include <asm/arch/bits.h>
#include <asm/arch/mux.h>
#include <asm/arch/sys_proto.h>
-// #include <asm/arch/sys_info.h>
#include <asm/arch/clocks.h>
#include <asm/arch/mem.h>
#include <i2c.h>
@@ -45,19 +43,19 @@ enum {
} I2C_RX_MODE;
typedef enum {
- GPIO_I2C_SDATA,
- GPIO_I2C_SCLK,
+ GPIO_I2C_SDATA,
+ GPIO_I2C_SCLK,
} GPIO_I2C_PIN;
static enum {
- GPIO_I2C_UNINIT,
- GPIO_I2C_STOPPED,
- GPIO_I2C_STARTED,
+ GPIO_I2C_UNINIT,
+ GPIO_I2C_STOPPED,
+ GPIO_I2C_STARTED,
} gpio_i2c_bus_state;
typedef enum {
- GPIO_I2C_INPUT,
- GPIO_I2C_OUTPUT,
+ GPIO_I2C_INPUT,
+ GPIO_I2C_OUTPUT,
} GPIO_I2C_DIRECTION;
static int gpio_i2c_clock_high_width, gpio_i2c_clock_low_width;
@@ -65,13 +63,6 @@ static int gpio_i2c_coarse_delay;
#define DEBUG_PRODUCTION_DATA 0
#define DEBUG_PRODUCTION_DATA_BUF 0
-#define STATIC static
-
-#if 0
-#define MUX_VAL(OFFSET,VALUE) \
- __raw_writew((VALUE), OMAP34XX_CTRL_BASE + (OFFSET))
-#define CP(x) (CONTROL_PADCONF_##x)
-#endif
/*
* IEN - Input Enable
@@ -84,16 +75,16 @@ static int gpio_i2c_coarse_delay;
* The commented string gives the final mux configuration for that pin
*/
-// Put SCLK/SDA pins connected to the product ID into GPIO mode
-STATIC void gpio_i2c_config_pins(void)
+/* Put SCLK/SDA pins connected to the product ID into GPIO mode */
+static void gpio_i2c_config_pins(void)
{
MUX_VAL(CP(I2C3_SCL), (IEN | PTU | EN | M4)); /*I2C3_SCL*/
MUX_VAL(CP(I2C3_SDA), (IEN | PTU | EN | M4)); /*I2C3_SDA*/
}
-// Restore SCLK/SDA pins connected to the product ID back to I2C mode
+/* Restore SCLK/SDA pins connected to the product ID back to I2C mode */
-STATIC void gpio_i2c_restore_pins(void)
+static void gpio_i2c_restore_pins(void)
{
MUX_VAL(CP(I2C3_SCL), (IEN | PTU | EN | M0)); /*I2C3_SCL*/
MUX_VAL(CP(I2C3_SDA), (IEN | PTU | EN | M0)); /*I2C3_SDA*/
@@ -102,176 +93,176 @@ STATIC void gpio_i2c_restore_pins(void)
#define GPIO_I2C_GPIO_SCLK 184
#define GPIO_I2C_GPIO_SDATA 185
-STATIC void gpio_i2c_config_pin(GPIO_I2C_PIN pin, GPIO_I2C_DIRECTION dir)
+static void gpio_i2c_config_pin(GPIO_I2C_PIN pin, GPIO_I2C_DIRECTION dir)
{
- if (dir == GPIO_I2C_INPUT) {
- if (pin == GPIO_I2C_SCLK)
- pin_init_gpio(GPIO_I2C_GPIO_SCLK, 1);
- else
- pin_init_gpio(GPIO_I2C_GPIO_SDATA, 1);
- } else if (dir == GPIO_I2C_OUTPUT) {
- if (pin == GPIO_I2C_SCLK)
- pin_init_gpio(GPIO_I2C_GPIO_SCLK, 0);
- else
- pin_init_gpio(GPIO_I2C_GPIO_SDATA, 0);
- }
+ if (dir == GPIO_I2C_INPUT) {
+ if (pin == GPIO_I2C_SCLK)
+ pin_init_gpio(GPIO_I2C_GPIO_SCLK, 1);
+ else
+ pin_init_gpio(GPIO_I2C_GPIO_SDATA, 1);
+ } else if (dir == GPIO_I2C_OUTPUT) {
+ if (pin == GPIO_I2C_SCLK)
+ pin_init_gpio(GPIO_I2C_GPIO_SCLK, 0);
+ else
+ pin_init_gpio(GPIO_I2C_GPIO_SDATA, 0);
+ }
}
-STATIC int gpio_i2c_read_pin(GPIO_I2C_PIN pin)
+static int gpio_i2c_read_pin(GPIO_I2C_PIN pin)
{
- if (pin == GPIO_I2C_SCLK)
- return pin_get_gpio_input(GPIO_I2C_GPIO_SCLK);
- else
- return pin_get_gpio_input(GPIO_I2C_GPIO_SDATA);
- return 0;
+ if (pin == GPIO_I2C_SCLK)
+ return pin_get_gpio_input(GPIO_I2C_GPIO_SCLK);
+ else
+ return pin_get_gpio_input(GPIO_I2C_GPIO_SDATA);
+ return 0;
}
-STATIC void gpio_i2c_set_pin_level(GPIO_I2C_PIN pin, int level)
+static void gpio_i2c_set_pin_level(GPIO_I2C_PIN pin, int level)
{
- uint8_t pin_level;
-
- if (pin == GPIO_I2C_SCLK) {
- pin_level = pin_get_gpio_input(GPIO_I2C_GPIO_SCLK);
- if (((level == 1) && (pin_level == 0)) ||
- ((level == 0) && (pin_level == 1)))
- pin_set_gpio_dataout(GPIO_I2C_GPIO_SCLK, level);
- } else if (pin == GPIO_I2C_SDATA) {
- if (level == 0) {
- gpio_i2c_config_pin(pin, GPIO_I2C_OUTPUT);
- pin_set_gpio_dataout(GPIO_I2C_GPIO_SDATA, 0);
- } else {
- gpio_i2c_config_pin(pin, GPIO_I2C_INPUT);
- }
- }
+ uint8_t pin_level;
+
+ if (pin == GPIO_I2C_SCLK) {
+ pin_level = pin_get_gpio_input(GPIO_I2C_GPIO_SCLK);
+ if (((level == 1) && (pin_level == 0)) ||
+ ((level == 0) && (pin_level == 1)))
+ pin_set_gpio_dataout(GPIO_I2C_GPIO_SCLK, level);
+ } else if (pin == GPIO_I2C_SDATA) {
+ if (level == 0) {
+ gpio_i2c_config_pin(pin, GPIO_I2C_OUTPUT);
+ pin_set_gpio_dataout(GPIO_I2C_GPIO_SDATA, 0);
+ } else {
+ gpio_i2c_config_pin(pin, GPIO_I2C_INPUT);
+ }
+ }
}
-STATIC void gpio_i2c_init(int bps)
+static void gpio_i2c_init(int bps)
{
- gpio_i2c_bus_state = GPIO_I2C_UNINIT;
+ gpio_i2c_bus_state = GPIO_I2C_UNINIT;
- // Config SCLK, SDATA pins
- gpio_i2c_config_pin(GPIO_I2C_SCLK, GPIO_I2C_OUTPUT);
- gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
+ // Config SCLK, SDATA pins
+ gpio_i2c_config_pin(GPIO_I2C_SCLK, GPIO_I2C_OUTPUT);
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
- gpio_i2c_config_pin(GPIO_I2C_SDATA, GPIO_I2C_INPUT);
+ gpio_i2c_config_pin(GPIO_I2C_SDATA, GPIO_I2C_INPUT);
- gpio_i2c_config_pins();
+ gpio_i2c_config_pins();
- // Assume 1:1 clock duty cycle
- gpio_i2c_clock_high_width = gpio_i2c_clock_low_width
- = 1000000 / bps / 2;
+ // Assume 1:1 clock duty cycle
+ gpio_i2c_clock_high_width = gpio_i2c_clock_low_width
+ = 1000000 / bps / 2;
- gpio_i2c_coarse_delay = gpio_i2c_clock_high_width;
+ gpio_i2c_coarse_delay = gpio_i2c_clock_high_width;
}
-STATIC int gpio_i2c_busy(void)
+static int gpio_i2c_busy(void)
{
- return (gpio_i2c_bus_state == GPIO_I2C_STARTED);
+ return (gpio_i2c_bus_state == GPIO_I2C_STARTED);
}
-STATIC void gpio_i2c_tx_stop(void)
+static void gpio_i2c_tx_stop(void)
{
- if (gpio_i2c_bus_state == GPIO_I2C_STARTED) {
- udelay(gpio_i2c_coarse_delay);
-
- // Pull SDATA low
- gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0);
- udelay(gpio_i2c_coarse_delay);
-
- // Push SCLK high
- gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
- udelay(gpio_i2c_coarse_delay);
-
- // Now drive SDATA high - thats a STOP.
- gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1);
- udelay(gpio_i2c_coarse_delay);
- gpio_i2c_bus_state = GPIO_I2C_STOPPED;
- }
-
+ if (gpio_i2c_bus_state == GPIO_I2C_STARTED) {
+ udelay(gpio_i2c_coarse_delay);
+
+ // Pull SDATA low
+ gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0);
+ udelay(gpio_i2c_coarse_delay);
+
+ // Push SCLK high
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
+ udelay(gpio_i2c_coarse_delay);
+
+ // Now drive SDATA high - thats a STOP.
+ gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1);
+ udelay(gpio_i2c_coarse_delay);
+ gpio_i2c_bus_state = GPIO_I2C_STOPPED;
+ }
}
-STATIC void gpio_i2c_tx_start(void)
+static void gpio_i2c_tx_start(void)
{
- if (gpio_i2c_bus_state == GPIO_I2C_UNINIT || gpio_i2c_bus_state == GPIO_I2C_STOPPED) {
- udelay(gpio_i2c_coarse_delay);
- gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1);
- udelay(gpio_i2c_coarse_delay);
- gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
- udelay(gpio_i2c_coarse_delay);
- gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0);
- udelay(gpio_i2c_coarse_delay);
- gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0);
- udelay(gpio_i2c_coarse_delay);
- gpio_i2c_bus_state = GPIO_I2C_STARTED;
- }
+ if (gpio_i2c_bus_state == GPIO_I2C_UNINIT
+ || gpio_i2c_bus_state == GPIO_I2C_STOPPED) {
+ udelay(gpio_i2c_coarse_delay);
+ gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1);
+ udelay(gpio_i2c_coarse_delay);
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
+ udelay(gpio_i2c_coarse_delay);
+ gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0);
+ udelay(gpio_i2c_coarse_delay);
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0);
+ udelay(gpio_i2c_coarse_delay);
+ gpio_i2c_bus_state = GPIO_I2C_STARTED;
+ }
}
// Return !0 if NACK
-STATIC int gpio_i2c_tx_byte(uint8_t data)
+static int gpio_i2c_tx_byte(uint8_t data)
{
- uint8_t clock, tx_bit_mask=0x80, nack;
-
- if (gpio_i2c_bus_state != GPIO_I2C_STARTED)
- printf("%s: Unexpected I2C bus state!\n", __FUNCTION__);
-
- udelay(gpio_i2c_coarse_delay);
-
- for (clock=0; clock <= 7; ++clock) {
- if (data & tx_bit_mask)
- gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1);
- else
- gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0);
- udelay(gpio_i2c_clock_low_width);
- gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
- udelay(gpio_i2c_clock_high_width);
- gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0);
- tx_bit_mask >>= 1;
- }
- gpio_i2c_config_pin(GPIO_I2C_SDATA, GPIO_I2C_INPUT);
- udelay(gpio_i2c_clock_low_width);
- gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
- udelay(gpio_i2c_clock_high_width);
- nack = gpio_i2c_read_pin(GPIO_I2C_SDATA);
- gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0);
- return (nack != 0);
+ uint8_t clock, tx_bit_mask=0x80, nack;
+
+ if (gpio_i2c_bus_state != GPIO_I2C_STARTED)
+ printf("%s: Unexpected I2C bus state!\n", __FUNCTION__);
+
+ udelay(gpio_i2c_coarse_delay);
+
+ for (clock=0; clock <= 7; ++clock) {
+ if (data & tx_bit_mask)
+ gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1);
+ else
+ gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0);
+ udelay(gpio_i2c_clock_low_width);
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
+ udelay(gpio_i2c_clock_high_width);
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0);
+ tx_bit_mask >>= 1;
+ }
+ gpio_i2c_config_pin(GPIO_I2C_SDATA, GPIO_I2C_INPUT);
+ udelay(gpio_i2c_clock_low_width);
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
+ udelay(gpio_i2c_clock_high_width);
+ nack = gpio_i2c_read_pin(GPIO_I2C_SDATA);
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0);
+ return (nack != 0);
}
-STATIC int gpio_i2c_rx_byte(uint8_t *data, int rx_mode)
+static int gpio_i2c_rx_byte(uint8_t *data, int rx_mode)
{
- uint8_t clock, data_bit;
-
- *data = 0;
-
- gpio_i2c_config_pin(GPIO_I2C_SDATA, GPIO_I2C_INPUT);
-
- udelay(gpio_i2c_coarse_delay);
-
- for (clock=0; clock<=8; ++clock) {
- if (clock < 8) {
- gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
- udelay(gpio_i2c_clock_high_width);
- data_bit = gpio_i2c_read_pin(GPIO_I2C_SDATA);
- gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0);
- *data = (*data << 1) | data_bit;
- } else {
- if ((rx_mode == RX_MODE_LAST_BYTE) || (rx_mode == RX_MODE_ONE_BYTE))
- gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1);
- else
- gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0);
-
- gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
- udelay(gpio_i2c_clock_high_width);
- gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0);
- }
- udelay(gpio_i2c_clock_low_width);
- }
-
- return 0;
+ uint8_t clock, data_bit;
+
+ *data = 0;
+
+ gpio_i2c_config_pin(GPIO_I2C_SDATA, GPIO_I2C_INPUT);
+
+ udelay(gpio_i2c_coarse_delay);
+
+ for (clock=0; clock<=8; ++clock) {
+ if (clock < 8) {
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
+ udelay(gpio_i2c_clock_high_width);
+ data_bit = gpio_i2c_read_pin(GPIO_I2C_SDATA);
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0);
+ *data = (*data << 1) | data_bit;
+ } else {
+ if ((rx_mode == RX_MODE_LAST_BYTE) || (rx_mode == RX_MODE_ONE_BYTE))
+ gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1);
+ else
+ gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0);
+
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
+ udelay(gpio_i2c_clock_high_width);
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0);
+ }
+ udelay(gpio_i2c_clock_low_width);
+ }
+
+ return 0;
}
-STATIC int send_packet(uint8_t *data, int len, uint8_t *rxbuf, int rxlen)
+static int send_packet(uint8_t *data, int len, uint8_t *rxbuf, int rxlen)
{
int timeout = 1000;
int retry;
@@ -279,15 +270,15 @@ STATIC int send_packet(uint8_t *data, int len, uint8_t *rxbuf, int rxlen)
int tick, err, idx;
if (DEBUG_PRODUCTION_DATA) {
- char buf[128];
- int i, offset;
- for (offset = 0, i=0; i<len; ++i) {
- if (!i)
- offset = sprintf(buf, "%02x", data[i]);
- else
- offset += sprintf(&buf[offset], " %02x", data[i]);
- }
- printf("%s: %s\n", __FUNCTION__, buf);
+ char buf[3 * len + 2];
+ int i, offset;
+ for (offset = 0, i=0; i<len; ++i) {
+ if (!i)
+ offset = sprintf(buf, "%02x", data[i]);
+ else
+ offset += sprintf(&buf[offset], " %02x", data[i]);
+ }
+ printf("%s: %s\n", __FUNCTION__, buf);
}
// Wait for bus
@@ -295,7 +286,7 @@ STATIC int send_packet(uint8_t *data, int len, uint8_t *rxbuf, int rxlen)
udelay(100);
if (!timeout)
- printf("%s:%d i2c_busy never return zero!\n", __FUNCTION__, __LINE__);
+ printf("%s:%d i2c_busy never return zero!\n", __FUNCTION__, __LINE__);
retry = 0;
do {
@@ -321,71 +312,201 @@ STATIC int send_packet(uint8_t *data, int len, uint8_t *rxbuf, int rxlen)
} while (err && (retry++ < 5));
if (err)
- return err;
+ return err;
// Are we expecting a response?
if (rxbuf) {
- for (idx = 0; idx < rxlen; ++idx) {
- if (rxlen == 1)
- rx_mode = RX_MODE_ONE_BYTE;
- else if (idx == (rxlen - 1))
- rx_mode = RX_MODE_LAST_BYTE;
- else if (idx == (rxlen - 2))
- rx_mode = RX_MODE_NEXT_TO_LAST_BYTE;
- else if (idx == 0)
- rx_mode = RX_MODE_FIRST_BYTE;
- else
- rx_mode = RX_MODE_MIDDLE_BYTE;
-
- err = gpio_i2c_rx_byte(&rxbuf[idx], rx_mode);
- if (DEBUG_PRODUCTION_DATA) {
- if (err)
- printf("%s:%d err idx %d\n", __FUNCTION__, __LINE__, idx);
- }
- // tx_ack();
- }
+ for (idx = 0; idx < rxlen; ++idx) {
+ if (rxlen == 1)
+ rx_mode = RX_MODE_ONE_BYTE;
+ else if (idx == (rxlen - 1))
+ rx_mode = RX_MODE_LAST_BYTE;
+ else if (idx == (rxlen - 2))
+ rx_mode = RX_MODE_NEXT_TO_LAST_BYTE;
+ else if (idx == 0)
+ rx_mode = RX_MODE_FIRST_BYTE;
+ else
+ rx_mode = RX_MODE_MIDDLE_BYTE;
+
+ err = gpio_i2c_rx_byte(&rxbuf[idx], rx_mode);
+ if (DEBUG_PRODUCTION_DATA) {
+ if (err)
+ printf("%s:%d err idx %d\n", __FUNCTION__, __LINE__, idx);
+ }
+ }
}
gpio_i2c_tx_stop();
return err;
}
+/*
+ * Identify the device
+ */
+struct device_param {
+ char *name;
+ unsigned char reset[8]; // ATR for part
+ unsigned int zones; // number of zones
+ unsigned int zonesize; // bytes per zone
+};
+
+static const struct device_param answers[] = {
+
+ {
+ .name = "AT88SC0104C",
+ .reset = {0x3B, 0xB2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x01},
+ .zones = 4,
+ .zonesize = 32
+ },
+ {
+ .name = "AT88SC0204C",
+ .reset = {0x3B, 0xB2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x02},
+ .zones = 4,
+ .zonesize = 64
+ },
+ {
+ .name = "AT88SC0404C",
+ .reset = {0x3B, 0xB2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x04},
+ .zones = 4,
+ .zonesize = 128
+ },
+ {
+ .name = "AT88SC0808C",
+ .reset = {0x3B, 0xB2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x08},
+ .zones = 8,
+ .zonesize = 128
+ },
+ {
+ .name = "AT88SC1616C",
+ .reset = {0x3B, 0xB2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x16},
+ .zones = 16,
+ .zonesize = 128
+ },
+ {
+ .name = "AT88SC3216C",
+ .reset = {0x3B, 0xB3, 0x11, 0x00, 0x00, 0x00, 0x00, 0x32},
+ .zones = 16,
+ .zonesize = 256
+ },
+ {
+ .name = "AT88SC6416C",
+ .reset = {0x3B, 0xB3, 0x11, 0x00, 0x00, 0x00, 0x00, 0x64},
+ .zones = 16,
+ .zonesize = 512
+ },
+ {
+ .name = "AT88SC12816C",
+ .reset = {0x3B, 0xB3, 0x11, 0x00, 0x00, 0x00, 0x01, 0x28},
+ .zones = 16,
+ .zonesize = 1024
+ },
+ {
+ .name = "AT88SC25616C",
+ .reset = {0x3B, 0xB3, 0x11, 0x00, 0x00, 0x00, 0x02, 0x56},
+ .zones = 16,
+ .zonesize = 2048
+ },
+};
+
+static const struct device_param *devptr; /* pointer to ID'd device */
+
+#define CMD_SYSTEM_READ 0xB6
+
+static int
+identify_device(void)
+{
+ const struct device_param *p;
+ unsigned char cmd[] = { CMD_SYSTEM_READ, 0x00, 0x00, 0x00 };
+ unsigned char buf[8];
+ int err;
+ int i,j;
+
+ err = send_packet(cmd, sizeof(cmd), buf, sizeof(buf));
+ if (err)
+ return err;
+
+ if (DEBUG_PRODUCTION_DATA)
+ printf("%s: ident %02x %02x %02x %02x %02x %02x %02x %02x\n", __FUNCTION__,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+
+ for (p=answers,i=0; i<sizeof(answers)/sizeof(answers[0]); ++i,++p) {
+ for (j=0; j<8 && (p->reset[j] == buf[j]); ++j)
+ ;
+ if (j==8) {
+ devptr = p;
+
+ if (DEBUG_PRODUCTION_DATA)
+ printf("%s: device %s zones %u zonesize %u\n", __FUNCTION__,
+ devptr->name, devptr->zones, devptr->zonesize);
+
+ return 0;
+ }
+ }
+
+ printf("%s: ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x unknown!\n", __FUNCTION__,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+
+ return -1;
+}
+
#define CMD_SYSTEM_WRITE 0xB4
-STATIC int
+static int
set_user_zone(int zone)
{
- unsigned char cmd[] = { CMD_SYSTEM_WRITE, 0x03, 0x00, 0x00 };
- if (DEBUG_PRODUCTION_DATA)
- printf("%s: zone %d\n", __FUNCTION__, zone);
- cmd[2] = zone;
- return send_packet(cmd, sizeof(cmd), NULL, 0);
+ unsigned char cmd[] = { CMD_SYSTEM_WRITE, 0x03, 0x00, 0x00 };
+
+ if (DEBUG_PRODUCTION_DATA)
+ printf("%s: zone %d\n", __FUNCTION__, zone);
+ cmd[2] = zone;
+ return send_packet(cmd, sizeof(cmd), NULL, 0);
}
#define CMD_READ_USER_ZONE 0xB2
-STATIC int
-read_user_zone(unsigned char *buf, int len, int startoff)
+static int
+read_user_zone(unsigned int offset, unsigned char *buf, int len)
{
- unsigned char cmd[] = { CMD_READ_USER_ZONE, 0x00, 0x00, 0x00 };
- int ret;
- cmd[2] = startoff;
- cmd[3] = len;
- ret = send_packet(cmd, sizeof(cmd), buf, len);
-
- if (DEBUG_PRODUCTION_DATA_BUF) {
- char obuf[128];
- int i,j,offset;
- for (i = 0, offset=0; i<len; i+=16) {
- for (j = 0; j<16 && i+j<len; ++j)
- if (!j)
- offset = sprintf(obuf, "%02x", buf[i+j]);
- else
- offset += sprintf(&obuf[offset], " %02x", buf[i+j]);
- printf("%s\n", obuf);
- }
- }
- return ret;
+ unsigned char cmd[] = { CMD_READ_USER_ZONE, 0x00, 0x00, 0x00 };
+ int ret;
+ unsigned int startzone, endzone;
+
+ if (DEBUG_PRODUCTION_DATA)
+ printf("%s: offset %u len %d\n", __FUNCTION__, offset, len);
+
+ // abort if we're not in one zone, or past the end of the device
+ startzone = offset / devptr->zonesize;
+ endzone = (offset + (len - 1)) / devptr->zonesize;
+ if (startzone != endzone) {
+ printf("%s: startzone %d != endzone %d (len %d, offset %d)\n", __FUNCTION__, startzone, endzone, offset, len);
+ return -1;
+ }
+ if (endzone > devptr->zones) {
+ printf("%s: endzone %d > numzones\n", __FUNCTION__, endzone);
+ return -1;
+ }
+
+ // Set the zone
+ if (set_user_zone(startzone))
+ return -1;
+
+ cmd[2] = offset % devptr->zonesize;
+ cmd[3] = len;
+ ret = send_packet(cmd, sizeof(cmd), buf, len);
+
+ if (DEBUG_PRODUCTION_DATA_BUF) {
+ char obuf[128];
+ int i,j,offset;
+ for (i = 0, offset=0; i<len; i+=16) {
+ for (j = 0; j<16 && i+j<len; ++j)
+ if (!j)
+ offset = sprintf(obuf, "%02x", buf[i+j]);
+ else
+ offset += sprintf(&obuf[offset], " %02x", buf[i+j]);
+ printf("%s\n", obuf);
+ }
+ }
+ return ret;
}
#define XMK_STR(x) #x
@@ -394,23 +515,26 @@ int production_data_valid;
struct product_id_data product_id_data;
-void board_get_nth_enetaddr (unsigned char *enetaddr, int which)
+/*
+ * Extract/set an ethernet address.
+ * Which is the address in the environment, position is which MAC address
+ * in the product ID data
+ */
+void board_get_nth_enetaddr (unsigned char *enetaddr, int which, int position)
{
- unsigned char *mac = &product_id_data.d.zone2.mac[which][0];
+ unsigned char *mac = &product_id_data.d.zone2.mac[position][0];
char *s = NULL, *e;
int i;
char ethbuf[18];
- // If the data is bogus, or the MAC address is 00:00:00 or ff:ff:ff
- // then blow zeros into the address.
// We only handle the first two interfaces (LAN/WiFi)...
if (which >= 2)
return;
-#if 0
- printf("%s:%d valid %d which %d %02x:%02x:%02x\n", __FUNCTION__, __LINE__, production_data_valid, which,
- mac[0], mac[1], mac[2]);
-#endif
+ if (DEBUG_PRODUCTION_DATA)
+ printf("%s: valid %d which %d %02x:%02x:%02x\n", __FUNCTION__,
+ production_data_valid, which,
+ mac[0], mac[1], mac[2]);
memset(enetaddr, '\0', 6);
if (!production_data_valid ||
@@ -418,17 +542,11 @@ void board_get_nth_enetaddr (unsigned char *enetaddr, int which)
|| (mac[0] == 0x00 && mac[1] == 0x00 && mac[2] == 0x00)) {
s = getenv("ethaddr");
- // Skip the WiFi for rev 1 boards (no WiFi address)
- if (which == 1)
- return;
-
#ifdef CONFIG_ETHADDR
if (!s)
s = MK_STR(CONFIG_ETHADDR);
#endif
-#if 1
- printf("%s:%d %s\n", __FUNCTION__, __LINE__, s);
-#endif
+ printf("%s which %d %s\n", __FUNCTION__, which, s);
for (i = 0; i < 6; ++i) {
enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0;
if (s)
@@ -526,7 +644,7 @@ static void extract_model_number_revision(struct product_id_data *p, char *buf,
strncpy(buf, product_id_data.d.zone1.model_number, buflen);
buf[buflen-1] = '\0';
i = strlen(buf);
- if (i + 3 < buflen) {
+ if (i && (i + 3 < buflen)) {
buf[i] = '-';
buf[i+1] = product_id_data.d.zone1.model_revision;
buf[i+2] = '\0';
@@ -535,66 +653,98 @@ static void extract_model_number_revision(struct product_id_data *p, char *buf,
int fetch_production_data(void)
{
- int err = 0;
- char buf[36];
- int header_version;
- int checksum;
-
- gpio_i2c_init(50000);
-
- printf("Read production data: ");
- if (set_user_zone(0) || read_user_zone((unsigned char *)&product_id_data.d.u_zone0, sizeof(product_id_data.d.u_zone0), 0)) {
- printf("failed!\n");
- err = -1;
- goto out;
- }
-
- // If the header doesn't match, we can't map any of the data
- if (extract_header_version(&product_id_data, &header_version)) {
- err = -2;
- printf("failed - invalid header version %d!\n", header_version);
- goto out;
- }
-
- if (set_user_zone(1) || read_user_zone((unsigned char *)&product_id_data.d.zone1, sizeof(product_id_data.d.zone1), 0)) {
- printf("failed!\n");
- err = -3;
- goto out;
- }
-
- if (set_user_zone(2) || read_user_zone((unsigned char *)&product_id_data.d.zone2, sizeof(product_id_data.d.zone2), 0)) {
- printf("failed!\n");
- err = -4;
- goto out;
- }
-
- printf("done\n");
-
- // Correct endianess issues
- product_id_data.d.zone2.processor_type = le16_to_cpu(product_id_data.d.zone2.processor_type);
- product_id_data.d.zone2.features = le32_to_cpu(product_id_data.d.zone2.features);
- product_id_data.d.zone2.platform_bits = le32_to_cpu(product_id_data.d.zone2.platform_bits);
-
- // Print out the name, model number, and set MAC addresses
- extract_product_id_part_number(&product_id_data, buf, sizeof(buf));
-
- printf("Part Number : %s\n", buf);
- extract_model_number_revision(&product_id_data, buf, sizeof(buf));
- printf("Model Name : %s\n", buf);
- extract_serial_number(&product_id_data, buf, sizeof(buf));
- printf("Serial Number: %s\n", buf);
-
- out:
- production_data_valid = !err;
-
- // Restore pins back to their intended use
- gpio_i2c_restore_pins();
-
- // Clone the production data into SRAM
- checksum = calculate_checksum(&product_id_data.d, sizeof(product_id_data.d));
- product_id_data.checksum = checksum;
- *(struct product_id_data *)(SRAM_BASE) = product_id_data;
-
- return err;
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int err = 0;
+ char buf[36];
+ int header_version;
+ int checksum;
+ int i;
+
+ // Make sure voltage is to productID chip!
+ gpio_i2c_init(50000);
+
+ /* The productID chip wants at least 5 clocks to wake it up... */
+ gpio_i2c_config_pin(GPIO_I2C_SCLK, GPIO_I2C_OUTPUT);
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
+ for (i=0; i<10; ++i) {
+ udelay(100);
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0);
+ udelay(100);
+ gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1);
+ }
+
+ printf("Read production data: ");
+
+ if (identify_device()) {
+ printf("failed to identify device!\n");
+ err = -1;
+ goto out;
+ }
+
+ if (read_user_zone(0, (unsigned char *)&product_id_data.d.u_zone0, sizeof(product_id_data.d.u_zone0))) {
+ printf("failed!\n");
+ err = -1;
+ goto out;
+ }
+
+ // If the header doesn't match, we can't map any of the data
+ if (extract_header_version(&product_id_data, &header_version)) {
+ printf("failed - invalid header version %d!\n", header_version);
+ err = -2;
+ goto out;
+ }
+
+ if (read_user_zone(32, (unsigned char *)&product_id_data.d.zone1, sizeof(product_id_data.d.zone1))) {
+ printf("failed!\n");
+ err = -3;
+ goto out;
+ }
+
+ if (read_user_zone(64, (unsigned char *)&product_id_data.d.zone2, sizeof(product_id_data.d.zone2))) {
+ printf("failed!\n");
+ err = -4;
+ goto out;
+ }
+
+ printf("done\n");
+
+ // Correct endianess issues
+ product_id_data.d.zone2.processor_type = le16_to_cpu(product_id_data.d.zone2.processor_type);
+ product_id_data.d.zone2.features = le32_to_cpu(product_id_data.d.zone2.features);
+ product_id_data.d.zone2.platform_bits = le32_to_cpu(product_id_data.d.zone2.platform_bits);
+
+ // Print out the name, model number, and set MAC addresses
+ extract_product_id_part_number(&product_id_data, buf, sizeof(buf));
+
+ printf("Part Number : %s\n", buf);
+ extract_model_number_revision(&product_id_data, buf, sizeof(buf));
+ if (strlen(buf))
+ printf("Model Name : %s\n", buf);
+ extract_serial_number(&product_id_data, buf, sizeof(buf));
+ printf("Serial Number: %s\n", buf);
+ printf("Wired Lan MAC: 00:08:ee:%02x:%02x:%02x\n",
+ product_id_data.d.zone2.mac[0][0],
+ product_id_data.d.zone2.mac[0][1],
+ product_id_data.d.zone2.mac[0][2]);
+
+ if (gd->bd->bi_arch_number == MACH_TYPE_OMAP3530_LV_SOM)
+ printf("Wirless MAC: 00:08:ee:%02x:%02x:%02x\n",
+ product_id_data.d.zone2.mac[1][0],
+ product_id_data.d.zone2.mac[1][1],
+ product_id_data.d.zone2.mac[1][2]);
+
+ out:
+ production_data_valid = !err;
+
+ // Restore pins back to their intended use
+ gpio_i2c_restore_pins();
+
+ // Clone the production data into SRAM
+ checksum = calculate_checksum(&product_id_data.d, sizeof(product_id_data.d));
+ product_id_data.checksum = checksum;
+ *(struct product_id_data *)(SRAM_BASE) = product_id_data;
+
+ return err;
}
diff --git a/board/omap3/logic/logic.c b/board/omap3/logic/logic.c
index 807f91b33f..e0bcbc4bf3 100644
--- a/board/omap3/logic/logic.c
+++ b/board/omap3/logic/logic.c
@@ -145,6 +145,37 @@ int misc_init_r(void)
return 0;
}
+// Turn on VAUX1 voltage to 3.0 volts to drive level shifters and
+// power 3.0v parts (tsc2004 and Product ID chip)
+#define I2C_TRITON2 0x4b /* Address of Triton power group */
+
+void init_vaux1_voltage(void)
+{
+#ifdef CONFIG_DRIVER_OMAP34XX_I2C
+ unsigned char data;
+ unsigned short msg;
+
+ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+ // Select the output voltage
+ data = 0x04;
+ i2c_write(I2C_TRITON2, 0x72, 1, &data, 1);
+ // Select the Processor resource group
+ data = 0x20;
+ i2c_write(I2C_TRITON2, 0x72, 1, &data, 1);
+ // Enable I2C access to the Power bus
+ data = 0x02;
+ i2c_write(I2C_TRITON2, 0x4a, 1, &data, 1);
+ // Send message MSB
+ msg = (1<<13) | (1<<4) | (0xd<<0); // group(process_grp1):resource(vaux1):res_active;
+ data = msg >> 8;
+ i2c_write(I2C_TRITON2, 0x4b, 1, &data, 1);
+ // Send message LSB
+ data = msg & 0xff;
+ i2c_write(I2C_TRITON2, 0x4c, 1, &data, 1);
+#endif
+}
+
/******************************************************************************
* Routine: late_board_init
* Description: Late hardware init.
@@ -155,12 +186,15 @@ int board_late_init(void)
// DECLARE_GLOBAL_DATA_PTR;
+ // Turn on vaux1 to make sure voltage is to the product ID chip
+ init_vaux1_voltage();
fetch_production_data(); // Extract production data
+
// Fetch the ethaddr of the LAN
- board_get_nth_enetaddr(enetaddr, 0);
+ board_get_nth_enetaddr(enetaddr, 0, 0);
#ifdef CONFIG_HAS_ETH1
// Fetch the ethaddr of the WiFi
- board_get_nth_enetaddr(enetaddr, 1);
+ board_get_nth_enetaddr(enetaddr, 1, 1);
#endif
return 0;
}
diff --git a/board/omap3/logic/product_id.h b/board/omap3/logic/product_id.h
index 0980f481ea..77ee9d7d0e 100644
--- a/board/omap3/logic/product_id.h
+++ b/board/omap3/logic/product_id.h
@@ -87,4 +87,4 @@ static inline int calculate_checksum(void *p, int len)
}
extern int fetch_production_data(void);
-extern void board_get_nth_enetaddr (unsigned char *enetaddr, int which);
+extern void board_get_nth_enetaddr (unsigned char *enetaddr, int which, int position);