cmd_i2c.c 36.6 KB
Newer Older
W
wdenk 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
/*
 * (C) Copyright 2001
 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/*
 * I2C Functions similar to the standard memory functions.
 *
 * There are several parameters in many of the commands that bear further
 * explanations:
 *
 * {i2c_chip} is the I2C chip address (the first byte sent on the bus).
 *   Each I2C chip on the bus has a unique address.  On the I2C data bus,
 *   the address is the upper seven bits and the LSB is the "read/write"
 *   bit.  Note that the {i2c_chip} address specified on the command
 *   line is not shifted up: e.g. a typical EEPROM memory chip may have
 *   an I2C address of 0x50, but the data put on the bus will be 0xA0
 *   for write and 0xA1 for read.  This "non shifted" address notation
 *   matches at least half of the data sheets :-/.
 *
 * {addr} is the address (or offset) within the chip.  Small memory
 *   chips have 8 bit addresses.  Large memory chips have 16 bit
 *   addresses.  Other memory chips have 9, 10, or 11 bit addresses.
 *   Many non-memory chips have multiple registers and {addr} is used
 *   as the register index.  Some non-memory chips have only one register
 *   and therefore don't need any {addr} parameter.
 *
 *   The default {addr} parameter is one byte (.1) which works well for
 *   memories and registers with 8 bits of address space.
 *
 *   You can specify the length of the {addr} field with the optional .0,
 *   .1, or .2 modifier (similar to the .b, .w, .l modifier).  If you are
 *   manipulating a single register device which doesn't use an address
 *   field, use "0.0" for the address and the ".0" length field will
 *   suppress the address in the I2C data stream.  This also works for
 *   successive reads using the I2C auto-incrementing memory pointer.
 *
 *   If you are manipulating a large memory with 2-byte addresses, use
 *   the .2 address modifier, e.g. 210.2 addresses location 528 (decimal).
 *
 *   Then there are the unfortunate memory chips that spill the most
 *   significant 1, 2, or 3 bits of address into the chip address byte.
 *   This effectively makes one chip (logically) look like 2, 4, or
 *   8 chips.  This is handled (awkwardly) by #defining
63
 *   CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW and using the .1 modifier on the
W
wdenk 已提交
64 65 66
 *   {addr} field (since .1 is the default, it doesn't actually have to
 *   be specified).  Examples: given a memory chip at I2C chip address
 *   0x50, the following would happen...
67
 *     i2c md 50 0 10   display 16 bytes starting at 0x000
W
wdenk 已提交
68
 *                      On the bus: <S> A0 00 <E> <S> A1 <rd> ... <rd>
69
 *     i2c md 50 100 10 display 16 bytes starting at 0x100
W
wdenk 已提交
70
 *                      On the bus: <S> A2 00 <E> <S> A3 <rd> ... <rd>
71
 *     i2c md 50 210 10 display 16 bytes starting at 0x210
W
wdenk 已提交
72 73 74 75 76 77 78 79 80
 *                      On the bus: <S> A4 10 <E> <S> A5 <rd> ... <rd>
 *   This is awfully ugly.  It would be nice if someone would think up
 *   a better way of handling this.
 *
 * Adapted from cmd_mem.c which is copyright Wolfgang Denk (wd@denx.de).
 */

#include <common.h>
#include <command.h>
81
#include <environment.h>
W
wdenk 已提交
82
#include <i2c.h>
83
#include <malloc.h>
W
wdenk 已提交
84 85 86 87 88 89 90 91 92 93 94 95 96 97
#include <asm/byteorder.h>

/* Display values from last command.
 * Memory modify remembered values are different from display memory.
 */
static uchar	i2c_dp_last_chip;
static uint	i2c_dp_last_addr;
static uint	i2c_dp_last_alen;
static uint	i2c_dp_last_length = 0x10;

static uchar	i2c_mm_last_chip;
static uint	i2c_mm_last_addr;
static uint	i2c_mm_last_alen;

B
Ben Warren 已提交
98 99 100 101 102
/* If only one I2C bus is present, the list of devices to ignore when
 * the probe command is issued is represented by a 1D array of addresses.
 * When multiple buses are present, the list is an array of bus-address
 * pairs.  The following macros take care of this */

103
#if defined(CONFIG_SYS_I2C_NOPROBES)
B
Ben Warren 已提交
104 105 106 107 108
#if defined(CONFIG_I2C_MULTI_BUS)
static struct
{
	uchar	bus;
	uchar	addr;
109
} i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES;
B
Ben Warren 已提交
110 111 112 113 114
#define GET_BUS_NUM	i2c_get_bus_num()
#define COMPARE_BUS(b,i)	(i2c_no_probes[(i)].bus == (b))
#define COMPARE_ADDR(a,i)	(i2c_no_probes[(i)].addr == (a))
#define NO_PROBE_ADDR(i)	i2c_no_probes[(i)].addr
#else		/* single bus */
115
static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES;
B
Ben Warren 已提交
116 117 118 119 120 121 122
#define GET_BUS_NUM	0
#define COMPARE_BUS(b,i)	((b) == 0)	/* Make compiler happy */
#define COMPARE_ADDR(a,i)	(i2c_no_probes[(i)] == (a))
#define NO_PROBE_ADDR(i)	i2c_no_probes[(i)]
#endif	/* CONFIG_MULTI_BUS */

#define NUM_ELEMENTS_NOPROBE (sizeof(i2c_no_probes)/sizeof(i2c_no_probes[0]))
W
wdenk 已提交
123 124
#endif

125 126
#if defined(CONFIG_I2C_MUX)
static I2C_MUX_DEVICE	*i2c_mux_devices = NULL;
127
static	int	i2c_mux_busid = CONFIG_SYS_MAX_I2C_BUS;
128 129 130 131 132

DECLARE_GLOBAL_DATA_PTR;

#endif

133 134
#define DISP_LINE_LEN	16

135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
/* TODO: Implement architecture-specific get/set functions */
unsigned int __def_i2c_get_bus_speed(void)
{
	return CONFIG_SYS_I2C_SPEED;
}
unsigned int i2c_get_bus_speed(void)
	__attribute__((weak, alias("__def_i2c_get_bus_speed")));

int __def_i2c_set_bus_speed(unsigned int speed)
{
	if (speed != CONFIG_SYS_I2C_SPEED)
		return -1;

	return 0;
}
int i2c_set_bus_speed(unsigned int)
	__attribute__((weak, alias("__def_i2c_set_bus_speed")));

153 154
/*
 * get_alen: small parser helper function to get address length
R
Reinhard Meyer 已提交
155
 * returns the address length
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
 */
static uint get_alen(char *arg)
{
	int	j;
	int	alen;

	alen = 1;
	for (j = 0; j < 8; j++) {
		if (arg[j] == '.') {
			alen = arg[j+1] - '0';
			break;
		} else if (arg[j] == '\0')
			break;
	}
	return alen;
}

173 174 175 176 177
/*
 * Syntax:
 *	i2c read {i2c_chip} {devaddr}{.0, .1, .2} {len} {memaddr}
 */

178
static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
179 180 181 182 183
{
	u_char	chip;
	uint	devaddr, alen, length;
	u_char  *memaddr;

184 185
	if (argc != 5)
		return cmd_usage(cmdtp);
186 187 188 189 190 191 192 193 194 195 196

	/*
	 * I2C chip address
	 */
	chip = simple_strtoul(argv[1], 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[2], NULL, 16);
197
	alen = get_alen(argv[2]);
R
Reinhard Meyer 已提交
198
	if (alen > 3)
199
		return cmd_usage(cmdtp);
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217

	/*
	 * Length is the number of objects, not number of bytes.
	 */
	length = simple_strtoul(argv[3], NULL, 16);

	/*
	 * memaddr is the address where to store things in memory
	 */
	memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16);

	if (i2c_read(chip, devaddr, alen, memaddr, length) != 0) {
		puts ("Error reading the chip.\n");
		return 1;
	}
	return 0;
}

218 219 220 221
/*
 * Syntax:
 *	i2c md {i2c_chip} {addr}{.0, .1, .2} {len}
 */
222
static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
W
wdenk 已提交
223 224 225 226 227 228 229 230 231 232 233 234 235
{
	u_char	chip;
	uint	addr, alen, length;
	int	j, nbytes, linebytes;

	/* We use the last specified parameters, unless new ones are
	 * entered.
	 */
	chip   = i2c_dp_last_chip;
	addr   = i2c_dp_last_addr;
	alen   = i2c_dp_last_alen;
	length = i2c_dp_last_length;

236 237
	if (argc < 3)
		return cmd_usage(cmdtp);
W
wdenk 已提交
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253

	if ((flag & CMD_FLAG_REPEAT) == 0) {
		/*
		 * New command specified.
		 */

		/*
		 * I2C chip address
		 */
		chip = simple_strtoul(argv[1], NULL, 16);

		/*
		 * I2C data address within the chip.  This can be 1 or
		 * 2 bytes long.  Some day it might be 3 bytes long :-).
		 */
		addr = simple_strtoul(argv[2], NULL, 16);
254
		alen = get_alen(argv[2]);
R
Reinhard Meyer 已提交
255
		if (alen > 3)
256
			return cmd_usage(cmdtp);
W
wdenk 已提交
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278

		/*
		 * If another parameter, it is the length to display.
		 * Length is the number of objects, not number of bytes.
		 */
		if (argc > 3)
			length = simple_strtoul(argv[3], NULL, 16);
	}

	/*
	 * Print the lines.
	 *
	 * We buffer all read data, so we can make sure data is read only
	 * once.
	 */
	nbytes = length;
	do {
		unsigned char	linebuf[DISP_LINE_LEN];
		unsigned char	*cp;

		linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;

279
		if (i2c_read(chip, addr, alen, linebuf, linebytes) != 0)
280
			puts ("Error reading the chip.\n");
281
		else {
W
wdenk 已提交
282 283 284 285 286 287
			printf("%04x:", addr);
			cp = linebuf;
			for (j=0; j<linebytes; j++) {
				printf(" %02x", *cp++);
				addr++;
			}
288
			puts ("    ");
W
wdenk 已提交
289 290 291
			cp = linebuf;
			for (j=0; j<linebytes; j++) {
				if ((*cp < 0x20) || (*cp > 0x7e))
292
					puts (".");
W
wdenk 已提交
293 294 295 296
				else
					printf("%c", *cp);
				cp++;
			}
297
			putc ('\n');
W
wdenk 已提交
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
		}
		nbytes -= linebytes;
	} while (nbytes > 0);

	i2c_dp_last_chip   = chip;
	i2c_dp_last_addr   = addr;
	i2c_dp_last_alen   = alen;
	i2c_dp_last_length = length;

	return 0;
}


/* Write (fill) memory
 *
 * Syntax:
314
 *	i2c mw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}]
W
wdenk 已提交
315
 */
316
static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
W
wdenk 已提交
317 318 319 320 321 322 323
{
	uchar	chip;
	ulong	addr;
	uint	alen;
	uchar	byte;
	int	count;

324 325
	if ((argc < 4) || (argc > 5))
		return cmd_usage(cmdtp);
W
wdenk 已提交
326 327

	/*
W
Wolfgang Denk 已提交
328 329
	 * Chip is always specified.
	 */
W
wdenk 已提交
330 331 332 333 334 335
	chip = simple_strtoul(argv[1], NULL, 16);

	/*
	 * Address is always specified.
	 */
	addr = simple_strtoul(argv[2], NULL, 16);
336
	alen = get_alen(argv[2]);
R
Reinhard Meyer 已提交
337
	if (alen > 3)
338
		return cmd_usage(cmdtp);
W
wdenk 已提交
339 340 341 342 343 344 345 346 347

	/*
	 * Value to write is always specified.
	 */
	byte = simple_strtoul(argv[3], NULL, 16);

	/*
	 * Optional count
	 */
348
	if (argc == 5)
W
wdenk 已提交
349
		count = simple_strtoul(argv[4], NULL, 16);
350
	else
W
wdenk 已提交
351 352 353
		count = 1;

	while (count-- > 0) {
354
		if (i2c_write(chip, addr++, alen, &byte, 1) != 0)
355
			puts ("Error writing the chip.\n");
W
wdenk 已提交
356 357 358 359
		/*
		 * Wait for the write to complete.  The write can take
		 * up to 10mSec (we allow a little more time).
		 */
已提交
360 361 362
/*
 * No write delay with FRAM devices.
 */
363
#if !defined(CONFIG_SYS_I2C_FRAM)
W
wdenk 已提交
364
		udelay(11000);
已提交
365
#endif
W
wdenk 已提交
366 367 368 369 370 371 372 373
	}

	return (0);
}

/* Calculate a CRC on memory
 *
 * Syntax:
374
 *	i2c crc32 {i2c_chip} {addr}{.0, .1, .2} {count}
W
wdenk 已提交
375
 */
376
static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
W
wdenk 已提交
377 378 379 380 381 382 383 384 385
{
	uchar	chip;
	ulong	addr;
	uint	alen;
	int	count;
	uchar	byte;
	ulong	crc;
	ulong	err;

386 387
	if (argc < 4)
		return cmd_usage(cmdtp);
W
wdenk 已提交
388 389

	/*
W
Wolfgang Denk 已提交
390 391
	 * Chip is always specified.
	 */
W
wdenk 已提交
392 393 394 395 396 397
	chip = simple_strtoul(argv[1], NULL, 16);

	/*
	 * Address is always specified.
	 */
	addr = simple_strtoul(argv[2], NULL, 16);
398
	alen = get_alen(argv[2]);
R
Reinhard Meyer 已提交
399
	if (alen > 3)
400
		return cmd_usage(cmdtp);
W
wdenk 已提交
401 402 403 404 405 406 407 408 409 410 411 412 413

	/*
	 * Count is always specified
	 */
	count = simple_strtoul(argv[3], NULL, 16);

	printf ("CRC32 for %08lx ... %08lx ==> ", addr, addr + count - 1);
	/*
	 * CRC a byte at a time.  This is going to be slooow, but hey, the
	 * memories are small and slow too so hopefully nobody notices.
	 */
	crc = 0;
	err = 0;
414 415
	while (count-- > 0) {
		if (i2c_read(chip, addr, alen, &byte, 1) != 0)
W
wdenk 已提交
416 417 418 419
			err++;
		crc = crc32 (crc, &byte, 1);
		addr++;
	}
420
	if (err > 0)
421
		puts ("Error reading the chip,\n");
422
	else
W
wdenk 已提交
423 424 425 426 427 428 429 430
		printf ("%08lx\n", crc);

	return 0;
}

/* Modify memory.
 *
 * Syntax:
431 432
 *	i2c mm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}
 *	i2c nm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}
W
wdenk 已提交
433 434 435
 */

static int
436
mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
W
wdenk 已提交
437 438 439 440 441 442 443 444 445
{
	uchar	chip;
	ulong	addr;
	uint	alen;
	ulong	data;
	int	size = 1;
	int	nbytes;
	extern char console_buffer[];

446 447
	if (argc != 3)
		return cmd_usage(cmdtp);
W
wdenk 已提交
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467

#ifdef CONFIG_BOOT_RETRY_TIME
	reset_cmd_timeout();	/* got a good command to get here */
#endif
	/*
	 * We use the last specified parameters, unless new ones are
	 * entered.
	 */
	chip = i2c_mm_last_chip;
	addr = i2c_mm_last_addr;
	alen = i2c_mm_last_alen;

	if ((flag & CMD_FLAG_REPEAT) == 0) {
		/*
		 * New command specified.  Check for a size specification.
		 * Defaults to byte if no or incorrect specification.
		 */
		size = cmd_get_data_size(argv[0], 1);

		/*
W
Wolfgang Denk 已提交
468 469
		 * Chip is always specified.
		 */
W
wdenk 已提交
470 471 472 473 474 475
		chip = simple_strtoul(argv[1], NULL, 16);

		/*
		 * Address is always specified.
		 */
		addr = simple_strtoul(argv[2], NULL, 16);
476
		alen = get_alen(argv[2]);
R
Reinhard Meyer 已提交
477
		if (alen > 3)
478
			return cmd_usage(cmdtp);
W
wdenk 已提交
479 480 481 482 483 484 485 486
	}

	/*
	 * Print the address, followed by value.  Then accept input for
	 * the next value.  A non-converted value exits.
	 */
	do {
		printf("%08lx:", addr);
487
		if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0)
488
			puts ("\nError reading the chip,\n");
489
		else {
W
wdenk 已提交
490
			data = cpu_to_be32(data);
491
			if (size == 1)
W
wdenk 已提交
492
				printf(" %02lx", (data >> 24) & 0x000000FF);
493
			else if (size == 2)
W
wdenk 已提交
494
				printf(" %04lx", (data >> 16) & 0x0000FFFF);
495
			else
W
wdenk 已提交
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
				printf(" %08lx", data);
		}

		nbytes = readline (" ? ");
		if (nbytes == 0) {
			/*
			 * <CR> pressed as only input, don't modify current
			 * location and move to next.
			 */
			if (incrflag)
				addr += size;
			nbytes = size;
#ifdef CONFIG_BOOT_RETRY_TIME
			reset_cmd_timeout(); /* good enough to not time out */
#endif
		}
#ifdef CONFIG_BOOT_RETRY_TIME
513
		else if (nbytes == -2)
W
wdenk 已提交
514 515 516 517 518 519
			break;	/* timed out, exit the command	*/
#endif
		else {
			char *endp;

			data = simple_strtoul(console_buffer, &endp, 16);
520
			if (size == 1)
W
wdenk 已提交
521
				data = data << 24;
522
			else if (size == 2)
W
wdenk 已提交
523 524 525 526 527 528 529 530 531 532
				data = data << 16;
			data = be32_to_cpu(data);
			nbytes = endp - console_buffer;
			if (nbytes) {
#ifdef CONFIG_BOOT_RETRY_TIME
				/*
				 * good enough to not time out
				 */
				reset_cmd_timeout();
#endif
533
				if (i2c_write(chip, addr, alen, (uchar *)&data, size) != 0)
534
					puts ("Error writing the chip.\n");
535 536
#ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS
				udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
W
wdenk 已提交
537
#endif
W
wdenk 已提交
538 539 540 541 542 543
				if (incrflag)
					addr += size;
			}
		}
	} while (nbytes);

P
Peter Tyser 已提交
544 545 546
	i2c_mm_last_chip = chip;
	i2c_mm_last_addr = addr;
	i2c_mm_last_alen = alen;
W
wdenk 已提交
547 548 549 550 551 552

	return 0;
}

/*
 * Syntax:
553
 *	i2c probe {addr}{.0, .1, .2}
W
wdenk 已提交
554
 */
555
static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
W
wdenk 已提交
556 557
{
	int j;
558
#if defined(CONFIG_SYS_I2C_NOPROBES)
W
wdenk 已提交
559
	int k, skip;
B
Ben Warren 已提交
560 561
	uchar bus = GET_BUS_NUM;
#endif	/* NOPROBES */
W
wdenk 已提交
562

563
	puts ("Valid chip addresses:");
564
	for (j = 0; j < 128; j++) {
565
#if defined(CONFIG_SYS_I2C_NOPROBES)
W
wdenk 已提交
566
		skip = 0;
567 568
		for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) {
			if (COMPARE_BUS(bus, k) && COMPARE_ADDR(j, k)) {
W
wdenk 已提交
569 570 571 572 573 574 575
				skip = 1;
				break;
			}
		}
		if (skip)
			continue;
#endif
576
		if (i2c_probe(j) == 0)
W
wdenk 已提交
577 578
			printf(" %02X", j);
	}
579
	putc ('\n');
W
wdenk 已提交
580

581
#if defined(CONFIG_SYS_I2C_NOPROBES)
W
wdenk 已提交
582
	puts ("Excluded chip addresses:");
583 584
	for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) {
		if (COMPARE_BUS(bus,k))
B
Ben Warren 已提交
585 586
			printf(" %02X", NO_PROBE_ADDR(k));
	}
587
	putc ('\n');
W
wdenk 已提交
588 589 590 591 592 593 594
#endif

	return 0;
}

/*
 * Syntax:
595
 *	i2c loop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}]
W
wdenk 已提交
596 597 598
 *	{length} - Number of bytes to read
 *	{delay}  - A DECIMAL number and defaults to 1000 uSec
 */
599
static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
W
wdenk 已提交
600 601 602 603 604 605 606 607
{
	u_char	chip;
	ulong	alen;
	uint	addr;
	uint	length;
	u_char	bytes[16];
	int	delay;

608 609
	if (argc < 3)
		return cmd_usage(cmdtp);
W
wdenk 已提交
610 611 612 613 614 615 616 617 618 619

	/*
	 * Chip is always specified.
	 */
	chip = simple_strtoul(argv[1], NULL, 16);

	/*
	 * Address is always specified.
	 */
	addr = simple_strtoul(argv[2], NULL, 16);
620
	alen = get_alen(argv[2]);
R
Reinhard Meyer 已提交
621
	if (alen > 3)
622
		return cmd_usage(cmdtp);
W
wdenk 已提交
623 624 625 626 627 628

	/*
	 * Length is the number of objects, not number of bytes.
	 */
	length = 1;
	length = simple_strtoul(argv[3], NULL, 16);
629
	if (length > sizeof(bytes))
W
wdenk 已提交
630 631 632 633 634 635
		length = sizeof(bytes);

	/*
	 * The delay time (uSec) is optional.
	 */
	delay = 1000;
636
	if (argc > 3)
W
wdenk 已提交
637 638 639 640
		delay = simple_strtoul(argv[4], NULL, 10);
	/*
	 * Run the loop...
	 */
641 642
	while (1) {
		if (i2c_read(chip, addr, alen, bytes, length) != 0)
643
			puts ("Error reading the chip.\n");
W
wdenk 已提交
644 645 646 647 648 649 650 651 652 653 654
		udelay(delay);
	}

	/* NOTREACHED */
	return 0;
}

/*
 * The SDRAM command is separately configured because many
 * (most?) embedded boards don't use SDRAM DIMMs.
 */
655
#if defined(CONFIG_CMD_SDRAM)
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701
static void print_ddr2_tcyc (u_char const b)
{
	printf ("%d.", (b >> 4) & 0x0F);
	switch (b & 0x0F) {
	case 0x0:
	case 0x1:
	case 0x2:
	case 0x3:
	case 0x4:
	case 0x5:
	case 0x6:
	case 0x7:
	case 0x8:
	case 0x9:
		printf ("%d ns\n", b & 0x0F);
		break;
	case 0xA:
		puts ("25 ns\n");
		break;
	case 0xB:
		puts ("33 ns\n");
		break;
	case 0xC:
		puts ("66 ns\n");
		break;
	case 0xD:
		puts ("75 ns\n");
		break;
	default:
		puts ("?? ns\n");
		break;
	}
}

static void decode_bits (u_char const b, char const *str[], int const do_once)
{
	u_char mask;

	for (mask = 0x80; mask != 0x00; mask >>= 1, ++str) {
		if (b & mask) {
			puts (*str);
			if (do_once)
				return;
		}
	}
}
W
wdenk 已提交
702 703 704

/*
 * Syntax:
705
 *	i2c sdram {i2c_chip}
W
wdenk 已提交
706
 */
707
static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
W
wdenk 已提交
708
{
709 710
	enum { unknown, EDO, SDRAM, DDR2 } type;

W
wdenk 已提交
711 712 713 714 715
	u_char	chip;
	u_char	data[128];
	u_char	cksum;
	int	j;

716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759
	static const char *decode_CAS_DDR2[] = {
		" TBD", " 6", " 5", " 4", " 3", " 2", " TBD", " TBD"
	};

	static const char *decode_CAS_default[] = {
		" TBD", " 7", " 6", " 5", " 4", " 3", " 2", " 1"
	};

	static const char *decode_CS_WE_default[] = {
		" TBD", " 6", " 5", " 4", " 3", " 2", " 1", " 0"
	};

	static const char *decode_byte21_default[] = {
		"  TBD (bit 7)\n",
		"  Redundant row address\n",
		"  Differential clock input\n",
		"  Registerd DQMB inputs\n",
		"  Buffered DQMB inputs\n",
		"  On-card PLL\n",
		"  Registered address/control lines\n",
		"  Buffered address/control lines\n"
	};

	static const char *decode_byte22_DDR2[] = {
		"  TBD (bit 7)\n",
		"  TBD (bit 6)\n",
		"  TBD (bit 5)\n",
		"  TBD (bit 4)\n",
		"  TBD (bit 3)\n",
		"  Supports partial array self refresh\n",
		"  Supports 50 ohm ODT\n",
		"  Supports weak driver\n"
	};

	static const char *decode_row_density_DDR2[] = {
		"512 MiB", "256 MiB", "128 MiB", "16 GiB",
		"8 GiB", "4 GiB", "2 GiB", "1 GiB"
	};

	static const char *decode_row_density_default[] = {
		"512 MiB", "256 MiB", "128 MiB", "64 MiB",
		"32 MiB", "16 MiB", "8 MiB", "4 MiB"
	};

760 761 762
	if (argc < 2)
		return cmd_usage(cmdtp);

W
wdenk 已提交
763 764
	/*
	 * Chip is always specified.
765 766
	 */
	chip = simple_strtoul (argv[1], NULL, 16);
W
wdenk 已提交
767

768
	if (i2c_read (chip, 0, 1, data, sizeof (data)) != 0) {
769
		puts ("No SDRAM Serial Presence Detect found.\n");
W
wdenk 已提交
770 771 772 773 774 775 776
		return 1;
	}

	cksum = 0;
	for (j = 0; j < 63; j++) {
		cksum += data[j];
	}
777
	if (cksum != data[63]) {
W
wdenk 已提交
778
		printf ("WARNING: Configuration data checksum failure:\n"
779
			"  is 0x%02x, calculated 0x%02x\n", data[63], cksum);
W
wdenk 已提交
780
	}
781
	printf ("SPD data revision            %d.%d\n",
W
wdenk 已提交
782
		(data[62] >> 4) & 0x0F, data[62] & 0x0F);
783 784 785
	printf ("Bytes used                   0x%02X\n", data[0]);
	printf ("Serial memory size           0x%02X\n", 1 << data[1]);

786
	puts ("Memory type                  ");
787
	switch (data[2]) {
788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803
	case 2:
		type = EDO;
		puts ("EDO\n");
		break;
	case 4:
		type = SDRAM;
		puts ("SDRAM\n");
		break;
	case 8:
		type = DDR2;
		puts ("DDR2\n");
		break;
	default:
		type = unknown;
		puts ("unknown\n");
		break;
W
wdenk 已提交
804
	}
805

806
	puts ("Row address bits             ");
807
	if ((data[3] & 0x00F0) == 0)
808
		printf ("%d\n", data[3] & 0x0F);
809
	else
810 811
		printf ("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F);

812
	puts ("Column address bits          ");
813
	if ((data[4] & 0x00F0) == 0)
814
		printf ("%d\n", data[4] & 0x0F);
815
	else
816
		printf ("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F);
817 818 819

	switch (type) {
	case DDR2:
820 821
		printf ("Number of ranks              %d\n",
			(data[5] & 0x07) + 1);
822 823
		break;
	default:
824
		printf ("Module rows                  %d\n", data[5]);
825 826 827 828 829
		break;
	}

	switch (type) {
	case DDR2:
830
		printf ("Module data width            %d bits\n", data[6]);
831 832
		break;
	default:
833 834
		printf ("Module data width            %d bits\n",
			(data[7] << 8) | data[6]);
835 836 837
		break;
	}

838
	puts ("Interface signal levels      ");
W
wdenk 已提交
839
	switch(data[8]) {
840
		case 0:  puts ("TTL 5.0 V\n");	break;
841
		case 1:  puts ("LVTTL\n");	break;
842 843 844 845
		case 2:  puts ("HSTL 1.5 V\n");	break;
		case 3:  puts ("SSTL 3.3 V\n");	break;
		case 4:  puts ("SSTL 2.5 V\n");	break;
		case 5:  puts ("SSTL 1.8 V\n");	break;
846
		default: puts ("unknown\n");	break;
W
wdenk 已提交
847
	}
848 849 850

	switch (type) {
	case DDR2:
851 852
		printf ("SDRAM cycle time             ");
		print_ddr2_tcyc (data[9]);
853 854
		break;
	default:
855 856
		printf ("SDRAM cycle time             %d.%d ns\n",
			(data[9] >> 4) & 0x0F, data[9] & 0x0F);
857 858 859 860 861
		break;
	}

	switch (type) {
	case DDR2:
862 863
		printf ("SDRAM access time            0.%d%d ns\n",
			(data[10] >> 4) & 0x0F, data[10] & 0x0F);
864 865
		break;
	default:
866 867
		printf ("SDRAM access time            %d.%d ns\n",
			(data[10] >> 4) & 0x0F, data[10] & 0x0F);
868 869 870
		break;
	}

871
	puts ("EDC configuration            ");
872
	switch (data[11]) {
873 874 875 876
		case 0:  puts ("None\n");	break;
		case 1:  puts ("Parity\n");	break;
		case 2:  puts ("ECC\n");	break;
		default: puts ("unknown\n");	break;
W
wdenk 已提交
877
	}
878

879
	if ((data[12] & 0x80) == 0)
880
		puts ("No self refresh, rate        ");
881
	else
882
		puts ("Self refresh, rate           ");
883

W
wdenk 已提交
884
	switch(data[12] & 0x7F) {
885 886 887 888 889 890
		case 0:  puts ("15.625 us\n");	break;
		case 1:  puts ("3.9 us\n");	break;
		case 2:  puts ("7.8 us\n");	break;
		case 3:  puts ("31.3 us\n");	break;
		case 4:  puts ("62.5 us\n");	break;
		case 5:  puts ("125 us\n");	break;
891
		default: puts ("unknown\n");	break;
W
wdenk 已提交
892
	}
893 894 895

	switch (type) {
	case DDR2:
896
		printf ("SDRAM width (primary)        %d\n", data[13]);
897 898
		break;
	default:
899
		printf ("SDRAM width (primary)        %d\n", data[13] & 0x7F);
900
		if ((data[13] & 0x80) != 0) {
901 902
			printf ("  (second bank)              %d\n",
				2 * (data[13] & 0x7F));
903 904 905 906 907 908 909
		}
		break;
	}

	switch (type) {
	case DDR2:
		if (data[14] != 0)
910
			printf ("EDC width                    %d\n", data[14]);
911 912 913
		break;
	default:
		if (data[14] != 0) {
914 915
			printf ("EDC width                    %d\n",
				data[14] & 0x7F);
916 917

			if ((data[14] & 0x80) != 0) {
918 919
				printf ("  (second bank)              %d\n",
					2 * (data[14] & 0x7F));
920 921 922
			}
		}
		break;
W
wdenk 已提交
923
	}
924

925 926 927
	if (DDR2 != type) {
		printf ("Min clock delay, back-to-back random column addresses "
			"%d\n", data[15]);
928 929
	}

930 931 932 933 934 935 936
	puts ("Burst length(s)             ");
	if (data[16] & 0x80) puts (" Page");
	if (data[16] & 0x08) puts (" 8");
	if (data[16] & 0x04) puts (" 4");
	if (data[16] & 0x02) puts (" 2");
	if (data[16] & 0x01) puts (" 1");
	putc ('\n');
937
	printf ("Number of banks              %d\n", data[17]);
938 939 940 941

	switch (type) {
	case DDR2:
		puts ("CAS latency(s)              ");
942
		decode_bits (data[18], decode_CAS_DDR2, 0);
943 944 945 946
		putc ('\n');
		break;
	default:
		puts ("CAS latency(s)              ");
947
		decode_bits (data[18], decode_CAS_default, 0);
948 949 950 951 952 953
		putc ('\n');
		break;
	}

	if (DDR2 != type) {
		puts ("CS latency(s)               ");
954
		decode_bits (data[19], decode_CS_WE_default, 0);
955 956 957 958 959
		putc ('\n');
	}

	if (DDR2 != type) {
		puts ("WE latency(s)               ");
960
		decode_bits (data[20], decode_CS_WE_default, 0);
961 962 963 964 965 966 967 968 969 970 971 972 973 974
		putc ('\n');
	}

	switch (type) {
	case DDR2:
		puts ("Module attributes:\n");
		if (data[21] & 0x80)
			puts ("  TBD (bit 7)\n");
		if (data[21] & 0x40)
			puts ("  Analysis probe installed\n");
		if (data[21] & 0x20)
			puts ("  TBD (bit 5)\n");
		if (data[21] & 0x10)
			puts ("  FET switch external enable\n");
975
		printf ("  %d PLLs on DIMM\n", (data[21] >> 2) & 0x03);
976
		if (data[20] & 0x11) {
977 978
			printf ("  %d active registers on DIMM\n",
				(data[21] & 0x03) + 1);
979 980 981 982 983 984
		}
		break;
	default:
		puts ("Module attributes:\n");
		if (!data[21])
			puts ("  (none)\n");
985 986
		else
			decode_bits (data[21], decode_byte21_default, 0);
987 988 989 990 991
		break;
	}

	switch (type) {
	case DDR2:
992
		decode_bits (data[22], decode_byte22_DDR2, 0);
993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
		break;
	default:
		puts ("Device attributes:\n");
		if (data[22] & 0x80) puts ("  TBD (bit 7)\n");
		if (data[22] & 0x40) puts ("  TBD (bit 6)\n");
		if (data[22] & 0x20) puts ("  Upper Vcc tolerance 5%\n");
		else                 puts ("  Upper Vcc tolerance 10%\n");
		if (data[22] & 0x10) puts ("  Lower Vcc tolerance 5%\n");
		else                 puts ("  Lower Vcc tolerance 10%\n");
		if (data[22] & 0x08) puts ("  Supports write1/read burst\n");
		if (data[22] & 0x04) puts ("  Supports precharge all\n");
		if (data[22] & 0x02) puts ("  Supports auto precharge\n");
		if (data[22] & 0x01) puts ("  Supports early RAS# precharge\n");
		break;
	}

	switch (type) {
	case DDR2:
1011 1012
		printf ("SDRAM cycle time (2nd highest CAS latency)        ");
		print_ddr2_tcyc (data[23]);
1013 1014
		break;
	default:
1015 1016
		printf ("SDRAM cycle time (2nd highest CAS latency)        %d."
			"%d ns\n", (data[23] >> 4) & 0x0F, data[23] & 0x0F);
1017 1018 1019 1020 1021
		break;
	}

	switch (type) {
	case DDR2:
1022 1023
		printf ("SDRAM access from clock (2nd highest CAS latency) 0."
			"%d%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F);
1024 1025
		break;
	default:
1026 1027
		printf ("SDRAM access from clock (2nd highest CAS latency) %d."
			"%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F);
1028 1029 1030 1031 1032
		break;
	}

	switch (type) {
	case DDR2:
1033 1034
		printf ("SDRAM cycle time (3rd highest CAS latency)        ");
		print_ddr2_tcyc (data[25]);
1035 1036
		break;
	default:
1037 1038
		printf ("SDRAM cycle time (3rd highest CAS latency)        %d."
			"%d ns\n", (data[25] >> 4) & 0x0F, data[25] & 0x0F);
1039 1040 1041 1042 1043
		break;
	}

	switch (type) {
	case DDR2:
1044 1045
		printf ("SDRAM access from clock (3rd highest CAS latency) 0."
			"%d%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F);
1046 1047
		break;
	default:
1048 1049
		printf ("SDRAM access from clock (3rd highest CAS latency) %d."
			"%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F);
1050 1051 1052 1053 1054
		break;
	}

	switch (type) {
	case DDR2:
1055 1056
		printf ("Minimum row precharge        %d.%02d ns\n",
			(data[27] >> 2) & 0x3F, 25 * (data[27] & 0x03));
1057 1058
		break;
	default:
1059
		printf ("Minimum row precharge        %d ns\n", data[27]);
1060 1061 1062 1063 1064
		break;
	}

	switch (type) {
	case DDR2:
1065 1066
		printf ("Row active to row active min %d.%02d ns\n",
			(data[28] >> 2) & 0x3F, 25 * (data[28] & 0x03));
1067 1068
		break;
	default:
1069
		printf ("Row active to row active min %d ns\n", data[28]);
1070 1071 1072 1073 1074
		break;
	}

	switch (type) {
	case DDR2:
1075 1076
		printf ("RAS to CAS delay min         %d.%02d ns\n",
			(data[29] >> 2) & 0x3F, 25 * (data[29] & 0x03));
1077 1078
		break;
	default:
1079
		printf ("RAS to CAS delay min         %d ns\n", data[29]);
1080 1081 1082
		break;
	}

1083
	printf ("Minimum RAS pulse width      %d ns\n", data[30]);
1084 1085 1086

	switch (type) {
	case DDR2:
1087 1088 1089
		puts ("Density of each row          ");
		decode_bits (data[31], decode_row_density_DDR2, 1);
		putc ('\n');
1090 1091
		break;
	default:
1092 1093 1094
		puts ("Density of each row          ");
		decode_bits (data[31], decode_row_density_default, 1);
		putc ('\n');
1095 1096 1097 1098 1099
		break;
	}

	switch (type) {
	case DDR2:
1100
		puts ("Command and Address setup    ");
1101
		if (data[32] >= 0xA0) {
1102 1103
			printf ("1.%d%d ns\n",
				((data[32] >> 4) & 0x0F) - 10, data[32] & 0x0F);
1104
		} else {
1105 1106
			printf ("0.%d%d ns\n",
				((data[32] >> 4) & 0x0F), data[32] & 0x0F);
1107 1108 1109
		}
		break;
	default:
1110 1111 1112
		printf ("Command and Address setup    %c%d.%d ns\n",
			(data[32] & 0x80) ? '-' : '+',
			(data[32] >> 4) & 0x07, data[32] & 0x0F);
1113 1114 1115 1116 1117
		break;
	}

	switch (type) {
	case DDR2:
1118
		puts ("Command and Address hold     ");
1119
		if (data[33] >= 0xA0) {
1120 1121
			printf ("1.%d%d ns\n",
				((data[33] >> 4) & 0x0F) - 10, data[33] & 0x0F);
1122
		} else {
1123 1124
			printf ("0.%d%d ns\n",
				((data[33] >> 4) & 0x0F), data[33] & 0x0F);
1125 1126 1127
		}
		break;
	default:
1128 1129 1130
		printf ("Command and Address hold     %c%d.%d ns\n",
			(data[33] & 0x80) ? '-' : '+',
			(data[33] >> 4) & 0x07, data[33] & 0x0F);
1131 1132 1133 1134 1135
		break;
	}

	switch (type) {
	case DDR2:
1136 1137
		printf ("Data signal input setup      0.%d%d ns\n",
			(data[34] >> 4) & 0x0F, data[34] & 0x0F);
1138 1139
		break;
	default:
1140 1141 1142
		printf ("Data signal input setup      %c%d.%d ns\n",
			(data[34] & 0x80) ? '-' : '+',
			(data[34] >> 4) & 0x07, data[34] & 0x0F);
1143 1144 1145 1146 1147
		break;
	}

	switch (type) {
	case DDR2:
1148 1149
		printf ("Data signal input hold       0.%d%d ns\n",
			(data[35] >> 4) & 0x0F, data[35] & 0x0F);
1150 1151
		break;
	default:
1152 1153 1154
		printf ("Data signal input hold       %c%d.%d ns\n",
			(data[35] & 0x80) ? '-' : '+',
			(data[35] >> 4) & 0x07, data[35] & 0x0F);
1155 1156 1157
		break;
	}

1158
	puts ("Manufacturer's JEDEC ID      ");
1159
	for (j = 64; j <= 71; j++)
1160
		printf ("%02X ", data[j]);
1161
	putc ('\n');
1162
	printf ("Manufacturing Location       %02X\n", data[72]);
1163
	puts ("Manufacturer's Part Number   ");
1164
	for (j = 73; j <= 90; j++)
1165
		printf ("%02X ", data[j]);
1166
	putc ('\n');
1167 1168
	printf ("Revision Code                %02X %02X\n", data[91], data[92]);
	printf ("Manufacturing Date           %02X %02X\n", data[93], data[94]);
1169
	puts ("Assembly Serial Number       ");
1170
	for (j = 95; j <= 98; j++)
1171
		printf ("%02X ", data[j]);
1172
	putc ('\n');
W
wdenk 已提交
1173

1174
	if (DDR2 != type) {
1175 1176
		printf ("Speed rating                 PC%d\n",
			data[126] == 0x66 ? 66 : data[126]);
1177
	}
W
wdenk 已提交
1178 1179
	return 0;
}
1180
#endif
W
wdenk 已提交
1181

1182
#if defined(CONFIG_I2C_MUX)
1183
static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212
{
	int ret=0;

	if (argc == 1) {
		/* show all busses */
		I2C_MUX		*mux;
		I2C_MUX_DEVICE	*device = i2c_mux_devices;

		printf ("Busses reached over muxes:\n");
		while (device != NULL) {
			printf ("Bus ID: %x\n", device->busid);
			printf ("  reached over Mux(es):\n");
			mux = device->mux;
			while (mux != NULL) {
				printf ("    %s@%x ch: %x\n", mux->name, mux->chip, mux->channel);
				mux = mux->next;
			}
			device = device->next;
		}
	} else {
		I2C_MUX_DEVICE *dev;

		dev = i2c_mux_ident_muxstring ((uchar *)argv[1]);
		ret = 0;
	}
	return ret;
}
#endif  /* CONFIG_I2C_MUX */

B
Ben Warren 已提交
1213
#if defined(CONFIG_I2C_MULTI_BUS)
1214
static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
B
Ben Warren 已提交
1215 1216 1217
{
	int bus_idx, ret=0;

1218 1219
	if (argc == 1)
		/* querying current setting */
B
Ben Warren 已提交
1220
		printf("Current bus is %d\n", i2c_get_bus_num());
1221
	else {
B
Ben Warren 已提交
1222 1223 1224
		bus_idx = simple_strtoul(argv[1], NULL, 10);
		printf("Setting bus to %d\n", bus_idx);
		ret = i2c_set_bus_num(bus_idx);
1225
		if (ret)
B
Ben Warren 已提交
1226 1227 1228 1229 1230 1231
			printf("Failure changing bus number (%d)\n", ret);
	}
	return ret;
}
#endif  /* CONFIG_I2C_MULTI_BUS */

1232
static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
B
Ben Warren 已提交
1233 1234 1235
{
	int speed, ret=0;

1236 1237
	if (argc == 1)
		/* querying current speed */
B
Ben Warren 已提交
1238
		printf("Current bus speed=%d\n", i2c_get_bus_speed());
1239
	else {
B
Ben Warren 已提交
1240 1241 1242
		speed = simple_strtoul(argv[1], NULL, 10);
		printf("Setting bus speed to %d Hz\n", speed);
		ret = i2c_set_bus_speed(speed);
1243
		if (ret)
B
Ben Warren 已提交
1244 1245 1246 1247 1248
			printf("Failure changing bus speed (%d)\n", ret);
	}
	return ret;
}

1249
static int do_i2c_mm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
B
Ben Warren 已提交
1250
{
1251 1252 1253
	return mod_i2c_mem (cmdtp, 1, flag, argc, argv);
}

1254
static int do_i2c_nm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
1255 1256 1257
{
	return mod_i2c_mem (cmdtp, 0, flag, argc, argv);
}
1258

1259
static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
1260 1261 1262 1263 1264 1265
{
	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
	return 0;
}

static cmd_tbl_t cmd_i2c_sub[] = {
1266
#if defined(CONFIG_I2C_MUX)
1267
	U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_add_bus, "", ""),
1268
#endif  /* CONFIG_I2C_MUX */
1269
	U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""),
B
Ben Warren 已提交
1270
#if defined(CONFIG_I2C_MULTI_BUS)
1271
	U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""),
B
Ben Warren 已提交
1272
#endif  /* CONFIG_I2C_MULTI_BUS */
1273 1274 1275 1276 1277 1278
	U_BOOT_CMD_MKENT(loop, 3, 1, do_i2c_loop, "", ""),
	U_BOOT_CMD_MKENT(md, 3, 1, do_i2c_md, "", ""),
	U_BOOT_CMD_MKENT(mm, 2, 1, do_i2c_mm, "", ""),
	U_BOOT_CMD_MKENT(mw, 3, 1, do_i2c_mw, "", ""),
	U_BOOT_CMD_MKENT(nm, 2, 1, do_i2c_nm, "", ""),
	U_BOOT_CMD_MKENT(probe, 0, 1, do_i2c_probe, "", ""),
1279
	U_BOOT_CMD_MKENT(read, 5, 1, do_i2c_read, "", ""),
1280
	U_BOOT_CMD_MKENT(reset, 0, 1, do_i2c_reset, "", ""),
1281
#if defined(CONFIG_CMD_SDRAM)
1282
	U_BOOT_CMD_MKENT(sdram, 1, 1, do_sdram, "", ""),
1283
#endif
1284 1285 1286
	U_BOOT_CMD_MKENT(speed, 1, 1, do_i2c_bus_speed, "", ""),
};

1287
static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
1288 1289 1290
{
	cmd_tbl_t *c;

H
Heiko Schocher 已提交
1291 1292 1293
	if (argc < 2)
		return cmd_usage(cmdtp);

1294 1295 1296 1297 1298 1299
	/* Strip off leading 'i2c' command argument */
	argc--;
	argv++;

	c = find_cmd_tbl(argv[0], &cmd_i2c_sub[0], ARRAY_SIZE(cmd_i2c_sub));

1300
	if (c)
1301
		return  c->cmd(cmdtp, flag, argc, argv);
1302 1303
	else
		return cmd_usage(cmdtp);
B
Ben Warren 已提交
1304
}
W
wdenk 已提交
1305 1306 1307

/***************************************************/

1308 1309
U_BOOT_CMD(
	i2c, 6, 1, do_i2c,
P
Peter Tyser 已提交
1310
	"I2C sub-system",
1311
#if defined(CONFIG_I2C_MUX)
1312
	"bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes\ni2c "
1313
#endif  /* CONFIG_I2C_MUX */
1314
	"crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n"
1315
#if defined(CONFIG_I2C_MULTI_BUS)
1316
	"i2c dev [dev] - show or set current I2C bus\n"
1317
#endif  /* CONFIG_I2C_MULTI_BUS */
1318
	"i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device\n"
1319 1320 1321 1322 1323
	"i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n"
	"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"
1324
	"i2c read chip address[.0, .1, .2] length memaddress - read to memory \n"
H
Heiko Schocher 已提交
1325
	"i2c reset - re-init the I2C Controller\n"
1326
#if defined(CONFIG_CMD_SDRAM)
1327
	"i2c sdram chip - print SDRAM configuration information\n"
1328
#endif
1329
	"i2c speed [speed] - show or set I2C bus speed"
1330
);
1331 1332

#if defined(CONFIG_I2C_MUX)
1333
static int i2c_mux_add_device(I2C_MUX_DEVICE *dev)
1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519
{
	I2C_MUX_DEVICE	*devtmp = i2c_mux_devices;

	if (i2c_mux_devices == NULL) {
		i2c_mux_devices = dev;
		return 0;
	}
	while (devtmp->next != NULL)
		devtmp = devtmp->next;

	devtmp->next = dev;
	return 0;
}

I2C_MUX_DEVICE	*i2c_mux_search_device(int id)
{
	I2C_MUX_DEVICE	*device = i2c_mux_devices;

	while (device != NULL) {
		if (device->busid == id)
			return device;
		device = device->next;
	}
	return NULL;
}

/* searches in the buf from *pos the next ':'.
 * returns:
 *     0 if found (with *pos = where)
 *   < 0 if an error occured
 *   > 0 if the end of buf is reached
 */
static int i2c_mux_search_next (int *pos, uchar	*buf, int len)
{
	while ((buf[*pos] != ':') && (*pos < len)) {
		*pos += 1;
	}
	if (*pos >= len)
		return 1;
	if (buf[*pos] != ':')
		return -1;
	return 0;
}

static int i2c_mux_get_busid (void)
{
	int	tmp = i2c_mux_busid;

	i2c_mux_busid ++;
	return tmp;
}

/* Analyses a Muxstring and sends immediately the
   Commands to the Muxes. Runs from Flash.
 */
int i2c_mux_ident_muxstring_f (uchar *buf)
{
	int	pos = 0;
	int	oldpos;
	int	ret = 0;
	int	len = strlen((char *)buf);
	int	chip;
	uchar	channel;
	int	was = 0;

	while (ret == 0) {
		oldpos = pos;
		/* search name */
		ret = i2c_mux_search_next(&pos, buf, len);
		if (ret != 0)
			printf ("ERROR\n");
		/* search address */
		pos ++;
		oldpos = pos;
		ret = i2c_mux_search_next(&pos, buf, len);
		if (ret != 0)
			printf ("ERROR\n");
		buf[pos] = 0;
		chip = simple_strtoul((char *)&buf[oldpos], NULL, 16);
		buf[pos] = ':';
		/* search channel */
		pos ++;
		oldpos = pos;
		ret = i2c_mux_search_next(&pos, buf, len);
		if (ret < 0)
			printf ("ERROR\n");
		was = 0;
		if (buf[pos] != 0) {
			buf[pos] = 0;
			was = 1;
		}
		channel = simple_strtoul((char *)&buf[oldpos], NULL, 16);
		if (was)
			buf[pos] = ':';
		if (i2c_write(chip, 0, 0, &channel, 1) != 0) {
			printf ("Error setting Mux: chip:%x channel: \
				%x\n", chip, channel);
			return -1;
		}
		pos ++;
		oldpos = pos;

	}

	return 0;
}

/* Analyses a Muxstring and if this String is correct
 * adds a new I2C Bus.
 */
I2C_MUX_DEVICE *i2c_mux_ident_muxstring (uchar *buf)
{
	I2C_MUX_DEVICE	*device;
	I2C_MUX		*mux;
	int	pos = 0;
	int	oldpos;
	int	ret = 0;
	int	len = strlen((char *)buf);
	int	was = 0;

	device = (I2C_MUX_DEVICE *)malloc (sizeof(I2C_MUX_DEVICE));
	device->mux = NULL;
	device->busid = i2c_mux_get_busid ();
	device->next = NULL;
	while (ret == 0) {
		mux = (I2C_MUX *)malloc (sizeof(I2C_MUX));
		mux->next = NULL;
		/* search name of mux */
		oldpos = pos;
		ret = i2c_mux_search_next(&pos, buf, len);
		if (ret != 0)
			printf ("%s no name.\n", __FUNCTION__);
		mux->name = (char *)malloc (pos - oldpos + 1);
		memcpy (mux->name, &buf[oldpos], pos - oldpos);
		mux->name[pos - oldpos] = 0;
		/* search address */
		pos ++;
		oldpos = pos;
		ret = i2c_mux_search_next(&pos, buf, len);
		if (ret != 0)
			printf ("%s no mux address.\n", __FUNCTION__);
		buf[pos] = 0;
		mux->chip = simple_strtoul((char *)&buf[oldpos], NULL, 16);
		buf[pos] = ':';
		/* search channel */
		pos ++;
		oldpos = pos;
		ret = i2c_mux_search_next(&pos, buf, len);
		if (ret < 0)
			printf ("%s no mux channel.\n", __FUNCTION__);
		was = 0;
		if (buf[pos] != 0) {
			buf[pos] = 0;
			was = 1;
		}
		mux->channel = simple_strtoul((char *)&buf[oldpos], NULL, 16);
		if (was)
			buf[pos] = ':';
		if (device->mux == NULL)
			device->mux = mux;
		else {
			I2C_MUX		*muxtmp = device->mux;
			while (muxtmp->next != NULL) {
				muxtmp = muxtmp->next;
			}
			muxtmp->next = mux;
		}
		pos ++;
		oldpos = pos;
	}
	if (ret > 0) {
		/* Add Device */
		i2c_mux_add_device (device);
		return device;
	}

	return NULL;
}

int i2x_mux_select_mux(int bus)
{
	I2C_MUX_DEVICE  *dev;
	I2C_MUX		*mux;

	if ((gd->flags & GD_FLG_RELOC) != GD_FLG_RELOC) {
		/* select Default Mux Bus */
1520 1521
#if defined(CONFIG_SYS_I2C_IVM_BUS)
		i2c_mux_ident_muxstring_f ((uchar *)CONFIG_SYS_I2C_IVM_BUS);
1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547
#else
		{
		unsigned char *buf;
		buf = (unsigned char *) getenv("EEprom_ivm");
		if (buf != NULL)
			i2c_mux_ident_muxstring_f (buf);
		}
#endif
		return 0;
	}
	dev = i2c_mux_search_device(bus);
	if (dev == NULL)
		return -1;

	mux = dev->mux;
	while (mux != NULL) {
		if (i2c_write(mux->chip, 0, 0, &mux->channel, 1) != 0) {
			printf ("Error setting Mux: chip:%x channel: \
				%x\n", mux->chip, mux->channel);
			return -1;
		}
		mux = mux->next;
	}
	return 0;
}
#endif /* CONFIG_I2C_MUX */