#define DISP_LINE_LEN 16
+/* implement possible board specific board init */
+void __def_i2c_init_board(void)
+{
+ return;
+}
+void i2c_init_board(void)
+ __attribute__((weak, alias("__def_i2c_init_board")));
+
/* TODO: Implement architecture-specific get/set functions */
unsigned int __def_i2c_get_bus_speed(void)
{
/*
* get_alen: small parser helper function to get address length
- * returns the address length,or 0 on error
+ * returns the address length
*/
static uint get_alen(char *arg)
{
for (j = 0; j < 8; j++) {
if (arg[j] == '.') {
alen = arg[j+1] - '0';
- if (alen > 3) {
- return 0;
- }
break;
} else if (arg[j] == '\0')
break;
* i2c read {i2c_chip} {devaddr}{.0, .1, .2} {len} {memaddr}
*/
-static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
u_char chip;
uint devaddr, alen, length;
u_char *memaddr;
- if (argc != 5) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (argc != 5)
+ return CMD_RET_USAGE;
/*
* I2C chip address
*/
devaddr = simple_strtoul(argv[2], NULL, 16);
alen = get_alen(argv[2]);
- if (alen == 0) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (alen > 3)
+ return CMD_RET_USAGE;
/*
* Length is the number of objects, not number of bytes.
return 0;
}
+static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ u_char chip;
+ uint devaddr, alen, length;
+ u_char *memaddr;
+
+ if (argc != 5)
+ return cmd_usage(cmdtp);
+
+ /*
+ * memaddr is the address where to store things in memory
+ */
+ memaddr = (u_char *)simple_strtoul(argv[1], NULL, 16);
+
+ /*
+ * I2C chip address
+ */
+ chip = simple_strtoul(argv[2], NULL, 16);
+
+ /*
+ * I2C data address within the chip. This can be 1 or
+ * 2 bytes long. Some day it might be 3 bytes long :-).
+ */
+ devaddr = simple_strtoul(argv[3], NULL, 16);
+ alen = get_alen(argv[3]);
+ if (alen > 3)
+ return cmd_usage(cmdtp);
+
+ /*
+ * Length is the number of objects, not number of bytes.
+ */
+ length = simple_strtoul(argv[4], NULL, 16);
+
+ while (length-- > 0) {
+ if (i2c_write(chip, devaddr++, alen, memaddr++, 1) != 0) {
+ puts("Error writing to the chip.\n");
+ return 1;
+ }
+/*
+ * No write delay with FRAM devices.
+ */
+#if !defined(CONFIG_SYS_I2C_FRAM)
+ udelay(11000);
+#endif
+ }
+ return 0;
+}
+
/*
* Syntax:
* i2c md {i2c_chip} {addr}{.0, .1, .2} {len}
*/
-static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
u_char chip;
uint addr, alen, length;
alen = i2c_dp_last_alen;
length = i2c_dp_last_length;
- if (argc < 3) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (argc < 3)
+ return CMD_RET_USAGE;
if ((flag & CMD_FLAG_REPEAT) == 0) {
/*
*/
addr = simple_strtoul(argv[2], NULL, 16);
alen = get_alen(argv[2]);
- if (alen == 0) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (alen > 3)
+ return CMD_RET_USAGE;
/*
* If another parameter, it is the length to display.
* Syntax:
* i2c mw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}]
*/
-static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
uchar chip;
ulong addr;
uchar byte;
int count;
- if ((argc < 4) || (argc > 5)) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if ((argc < 4) || (argc > 5))
+ return CMD_RET_USAGE;
/*
* Chip is always specified.
*/
addr = simple_strtoul(argv[2], NULL, 16);
alen = get_alen(argv[2]);
- if (alen == 0) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (alen > 3)
+ return CMD_RET_USAGE;
/*
* Value to write is always specified.
* Syntax:
* i2c crc32 {i2c_chip} {addr}{.0, .1, .2} {count}
*/
-static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
uchar chip;
ulong addr;
ulong crc;
ulong err;
- if (argc < 4) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (argc < 4)
+ return CMD_RET_USAGE;
/*
* Chip is always specified.
*/
addr = simple_strtoul(argv[2], NULL, 16);
alen = get_alen(argv[2]);
- if (alen == 0) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (alen > 3)
+ return CMD_RET_USAGE;
/*
* Count is always specified
*/
static int
-mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
+mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
{
uchar chip;
ulong addr;
ulong data;
int size = 1;
int nbytes;
- extern char console_buffer[];
- if (argc != 3) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (argc != 3)
+ return CMD_RET_USAGE;
#ifdef CONFIG_BOOT_RETRY_TIME
reset_cmd_timeout(); /* got a good command to get here */
*/
addr = simple_strtoul(argv[2], NULL, 16);
alen = get_alen(argv[2]);
- if (alen == 0) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (alen > 3)
+ return CMD_RET_USAGE;
}
/*
/*
* Syntax:
- * i2c probe {addr}{.0, .1, .2}
+ * i2c probe {addr}
+ *
+ * Returns zero (success) if one or more I2C devices was found
*/
-static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int j;
+ int addr = -1;
+ int found = 0;
#if defined(CONFIG_SYS_I2C_NOPROBES)
int k, skip;
uchar bus = GET_BUS_NUM;
#endif /* NOPROBES */
+ if (argc == 2)
+ addr = simple_strtol(argv[1], 0, 16);
+
puts ("Valid chip addresses:");
for (j = 0; j < 128; j++) {
+ if ((0 <= addr) && (j != addr))
+ continue;
+
#if defined(CONFIG_SYS_I2C_NOPROBES)
skip = 0;
for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) {
if (skip)
continue;
#endif
- if (i2c_probe(j) == 0)
+ if (i2c_probe(j) == 0) {
printf(" %02X", j);
+ found++;
+ }
}
putc ('\n');
putc ('\n');
#endif
- return 0;
+ return (0 == found);
}
/*
* {length} - Number of bytes to read
* {delay} - A DECIMAL number and defaults to 1000 uSec
*/
-static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
u_char chip;
ulong alen;
u_char bytes[16];
int delay;
- if (argc < 3) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (argc < 3)
+ return CMD_RET_USAGE;
/*
* Chip is always specified.
*/
addr = simple_strtoul(argv[2], NULL, 16);
alen = get_alen(argv[2]);
- if (alen == 0) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (alen > 3)
+ return CMD_RET_USAGE;
/*
* Length is the number of objects, not number of bytes.
* Syntax:
* i2c sdram {i2c_chip}
*/
-static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
enum { unknown, EDO, SDRAM, DDR2 } type;
"32 MiB", "16 MiB", "8 MiB", "4 MiB"
};
- if (argc < 2) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
/*
* Chip is always specified.
*/
#endif
#if defined(CONFIG_I2C_MUX)
-static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
int ret=0;
device = device->next;
}
} else {
- I2C_MUX_DEVICE *dev;
-
- dev = i2c_mux_ident_muxstring ((uchar *)argv[1]);
+ (void)i2c_mux_ident_muxstring ((uchar *)argv[1]);
ret = 0;
}
return ret;
#endif /* CONFIG_I2C_MUX */
#if defined(CONFIG_I2C_MULTI_BUS)
-static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
int bus_idx, ret=0;
}
#endif /* CONFIG_I2C_MULTI_BUS */
-static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
int speed, ret=0;
return ret;
}
-static int do_i2c_mm(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+static int do_i2c_mm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
return mod_i2c_mem (cmdtp, 1, flag, argc, argv);
}
-static int do_i2c_nm(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+static int do_i2c_nm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
return mod_i2c_mem (cmdtp, 0, flag, argc, argv);
}
-static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
return 0;
U_BOOT_CMD_MKENT(nm, 2, 1, do_i2c_nm, "", ""),
U_BOOT_CMD_MKENT(probe, 0, 1, do_i2c_probe, "", ""),
U_BOOT_CMD_MKENT(read, 5, 1, do_i2c_read, "", ""),
+ U_BOOT_CMD_MKENT(write, 5, 0, do_i2c_write, "", ""),
U_BOOT_CMD_MKENT(reset, 0, 1, do_i2c_reset, "", ""),
#if defined(CONFIG_CMD_SDRAM)
U_BOOT_CMD_MKENT(sdram, 1, 1, do_sdram, "", ""),
U_BOOT_CMD_MKENT(speed, 1, 1, do_i2c_bus_speed, "", ""),
};
-static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+#ifdef CONFIG_NEEDS_MANUAL_RELOC
+void i2c_reloc(void) {
+ fixup_cmdtable(cmd_i2c_sub, ARRAY_SIZE(cmd_i2c_sub));
+}
+#endif
+
+static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
cmd_tbl_t *c;
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
/* Strip off leading 'i2c' command argument */
argc--;
argv++;
c = find_cmd_tbl(argv[0], &cmd_i2c_sub[0], ARRAY_SIZE(cmd_i2c_sub));
- if (c) {
- return c->cmd(cmdtp, flag, argc, argv);
- } else {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (c)
+ return c->cmd(cmdtp, flag, argc, argv);
+ else
+ return CMD_RET_USAGE;
}
/***************************************************/
"i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n"
"i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n"
"i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)\n"
- "i2c probe - show devices on the I2C bus\n"
+ "i2c probe [address] - test for and show device(s) on the I2C bus\n"
"i2c read chip address[.0, .1, .2] length memaddress - read to memory \n"
+ "i2c write memaddress chip address[.0, .1, .2] length - write memory to i2c\n"
"i2c reset - re-init the I2C Controller\n"
#if defined(CONFIG_CMD_SDRAM)
"i2c sdram chip - print SDRAM configuration information\n"
);
#if defined(CONFIG_I2C_MUX)
-int i2c_mux_add_device(I2C_MUX_DEVICE *dev)
+static int i2c_mux_add_device(I2C_MUX_DEVICE *dev)
{
I2C_MUX_DEVICE *devtmp = i2c_mux_devices;
return tmp;
}
-/* Analyses a Muxstring and sends immediately the
- Commands to the Muxes. Runs from Flash.
+/* Analyses a Muxstring and immediately sends the
+ commands to the muxes. Runs from flash.
*/
int i2c_mux_ident_muxstring_f (uchar *buf)
{
oldpos = pos;
}
+ i2c_init_board();
return 0;
}
mux = dev->mux;
while (mux != NULL) {
+ /* do deblocking on each level of mux, before mux config */
+ i2c_init_board();
if (i2c_write(mux->chip, 0, 0, &mux->channel, 1) != 0) {
printf ("Error setting Mux: chip:%x channel: \
%x\n", mux->chip, mux->channel);
}
mux = mux->next;
}
+ /* do deblocking on each level of mux and after mux config */
+ i2c_init_board();
return 0;
}
#endif /* CONFIG_I2C_MUX */