blob: b59470e7f68947e4a5071c261a4a1baec05b16bf [file] [log] [blame]
wdenk81a88242002-10-26 15:22:42 +00001/*
2 * (C) Copyright 2001
3 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/*
25 * I2C Functions similar to the standard memory functions.
26 *
27 * There are several parameters in many of the commands that bear further
28 * explanations:
29 *
wdenk81a88242002-10-26 15:22:42 +000030 * {i2c_chip} is the I2C chip address (the first byte sent on the bus).
31 * Each I2C chip on the bus has a unique address. On the I2C data bus,
32 * the address is the upper seven bits and the LSB is the "read/write"
33 * bit. Note that the {i2c_chip} address specified on the command
34 * line is not shifted up: e.g. a typical EEPROM memory chip may have
35 * an I2C address of 0x50, but the data put on the bus will be 0xA0
36 * for write and 0xA1 for read. This "non shifted" address notation
37 * matches at least half of the data sheets :-/.
38 *
39 * {addr} is the address (or offset) within the chip. Small memory
40 * chips have 8 bit addresses. Large memory chips have 16 bit
41 * addresses. Other memory chips have 9, 10, or 11 bit addresses.
42 * Many non-memory chips have multiple registers and {addr} is used
43 * as the register index. Some non-memory chips have only one register
44 * and therefore don't need any {addr} parameter.
45 *
46 * The default {addr} parameter is one byte (.1) which works well for
47 * memories and registers with 8 bits of address space.
48 *
49 * You can specify the length of the {addr} field with the optional .0,
50 * .1, or .2 modifier (similar to the .b, .w, .l modifier). If you are
51 * manipulating a single register device which doesn't use an address
52 * field, use "0.0" for the address and the ".0" length field will
53 * suppress the address in the I2C data stream. This also works for
54 * successive reads using the I2C auto-incrementing memory pointer.
55 *
56 * If you are manipulating a large memory with 2-byte addresses, use
57 * the .2 address modifier, e.g. 210.2 addresses location 528 (decimal).
58 *
59 * Then there are the unfortunate memory chips that spill the most
60 * significant 1, 2, or 3 bits of address into the chip address byte.
61 * This effectively makes one chip (logically) look like 2, 4, or
62 * 8 chips. This is handled (awkwardly) by #defining
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020063 * CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW and using the .1 modifier on the
wdenk81a88242002-10-26 15:22:42 +000064 * {addr} field (since .1 is the default, it doesn't actually have to
65 * be specified). Examples: given a memory chip at I2C chip address
66 * 0x50, the following would happen...
Peter Tyser0f89c542009-04-18 22:34:03 -050067 * i2c md 50 0 10 display 16 bytes starting at 0x000
wdenk81a88242002-10-26 15:22:42 +000068 * On the bus: <S> A0 00 <E> <S> A1 <rd> ... <rd>
Peter Tyser0f89c542009-04-18 22:34:03 -050069 * i2c md 50 100 10 display 16 bytes starting at 0x100
wdenk81a88242002-10-26 15:22:42 +000070 * On the bus: <S> A2 00 <E> <S> A3 <rd> ... <rd>
Peter Tyser0f89c542009-04-18 22:34:03 -050071 * i2c md 50 210 10 display 16 bytes starting at 0x210
wdenk81a88242002-10-26 15:22:42 +000072 * On the bus: <S> A4 10 <E> <S> A5 <rd> ... <rd>
73 * This is awfully ugly. It would be nice if someone would think up
74 * a better way of handling this.
75 *
76 * Adapted from cmd_mem.c which is copyright Wolfgang Denk (wd@denx.de).
77 */
78
79#include <common.h>
80#include <command.h>
Heiko Schocher67b23a32008-10-15 09:39:47 +020081#include <environment.h>
wdenk81a88242002-10-26 15:22:42 +000082#include <i2c.h>
Heiko Schocher67b23a32008-10-15 09:39:47 +020083#include <malloc.h>
wdenk81a88242002-10-26 15:22:42 +000084#include <asm/byteorder.h>
85
wdenk81a88242002-10-26 15:22:42 +000086/* Display values from last command.
87 * Memory modify remembered values are different from display memory.
88 */
89static uchar i2c_dp_last_chip;
90static uint i2c_dp_last_addr;
91static uint i2c_dp_last_alen;
92static uint i2c_dp_last_length = 0x10;
93
94static uchar i2c_mm_last_chip;
95static uint i2c_mm_last_addr;
96static uint i2c_mm_last_alen;
97
Ben Warrenbb99ad62006-09-07 16:50:54 -040098/* If only one I2C bus is present, the list of devices to ignore when
99 * the probe command is issued is represented by a 1D array of addresses.
100 * When multiple buses are present, the list is an array of bus-address
101 * pairs. The following macros take care of this */
102
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200103#if defined(CONFIG_SYS_I2C_NOPROBES)
Ben Warrenbb99ad62006-09-07 16:50:54 -0400104#if defined(CONFIG_I2C_MULTI_BUS)
105static struct
106{
107 uchar bus;
108 uchar addr;
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200109} i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES;
Ben Warrenbb99ad62006-09-07 16:50:54 -0400110#define GET_BUS_NUM i2c_get_bus_num()
111#define COMPARE_BUS(b,i) (i2c_no_probes[(i)].bus == (b))
112#define COMPARE_ADDR(a,i) (i2c_no_probes[(i)].addr == (a))
113#define NO_PROBE_ADDR(i) i2c_no_probes[(i)].addr
114#else /* single bus */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200115static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES;
Ben Warrenbb99ad62006-09-07 16:50:54 -0400116#define GET_BUS_NUM 0
117#define COMPARE_BUS(b,i) ((b) == 0) /* Make compiler happy */
118#define COMPARE_ADDR(a,i) (i2c_no_probes[(i)] == (a))
119#define NO_PROBE_ADDR(i) i2c_no_probes[(i)]
120#endif /* CONFIG_MULTI_BUS */
121
122#define NUM_ELEMENTS_NOPROBE (sizeof(i2c_no_probes)/sizeof(i2c_no_probes[0]))
wdenk81a88242002-10-26 15:22:42 +0000123#endif
124
Heiko Schocher67b23a32008-10-15 09:39:47 +0200125#if defined(CONFIG_I2C_MUX)
126static I2C_MUX_DEVICE *i2c_mux_devices = NULL;
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200127static int i2c_mux_busid = CONFIG_SYS_MAX_I2C_BUS;
Heiko Schocher67b23a32008-10-15 09:39:47 +0200128
129DECLARE_GLOBAL_DATA_PTR;
130
131#endif
132
Frans Meulenbroeksa266fe92010-03-26 09:46:40 +0100133#define DISP_LINE_LEN 16
134
Stefan Biglerc649dda2011-04-08 16:24:08 +0200135/* implement possible board specific board init */
136void __def_i2c_init_board(void)
137{
138 return;
139}
140void i2c_init_board(void)
141 __attribute__((weak, alias("__def_i2c_init_board")));
142
Peter Tyser655b34a2009-04-18 22:34:01 -0500143/* TODO: Implement architecture-specific get/set functions */
144unsigned int __def_i2c_get_bus_speed(void)
145{
146 return CONFIG_SYS_I2C_SPEED;
147}
148unsigned int i2c_get_bus_speed(void)
149 __attribute__((weak, alias("__def_i2c_get_bus_speed")));
150
151int __def_i2c_set_bus_speed(unsigned int speed)
152{
153 if (speed != CONFIG_SYS_I2C_SPEED)
154 return -1;
155
156 return 0;
157}
158int i2c_set_bus_speed(unsigned int)
159 __attribute__((weak, alias("__def_i2c_set_bus_speed")));
160
Frans Meulenbroeks652e5352010-02-25 10:12:16 +0100161/*
Frans Meulenbroeks2c0dc992010-03-26 09:46:41 +0100162 * get_alen: small parser helper function to get address length
Reinhard Meyer7a92e532010-08-25 14:41:16 +0200163 * returns the address length
Frans Meulenbroeks2c0dc992010-03-26 09:46:41 +0100164 */
165static uint get_alen(char *arg)
166{
167 int j;
168 int alen;
169
170 alen = 1;
171 for (j = 0; j < 8; j++) {
172 if (arg[j] == '.') {
173 alen = arg[j+1] - '0';
Frans Meulenbroeks2c0dc992010-03-26 09:46:41 +0100174 break;
175 } else if (arg[j] == '\0')
176 break;
177 }
178 return alen;
179}
180
181/*
Frans Meulenbroeks652e5352010-02-25 10:12:16 +0100182 * Syntax:
183 * i2c read {i2c_chip} {devaddr}{.0, .1, .2} {len} {memaddr}
184 */
185
Wolfgang Denk54841ab2010-06-28 22:00:46 +0200186static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
Frans Meulenbroeks652e5352010-02-25 10:12:16 +0100187{
188 u_char chip;
189 uint devaddr, alen, length;
190 u_char *memaddr;
Frans Meulenbroeks652e5352010-02-25 10:12:16 +0100191
Wolfgang Denk47e26b12010-07-17 01:06:04 +0200192 if (argc != 5)
Simon Glass4c12eeb2011-12-10 08:44:01 +0000193 return CMD_RET_USAGE;
Frans Meulenbroeks652e5352010-02-25 10:12:16 +0100194
195 /*
196 * I2C chip address
197 */
198 chip = simple_strtoul(argv[1], NULL, 16);
199
200 /*
201 * I2C data address within the chip. This can be 1 or
202 * 2 bytes long. Some day it might be 3 bytes long :-).
203 */
204 devaddr = simple_strtoul(argv[2], NULL, 16);
Frans Meulenbroeks2c0dc992010-03-26 09:46:41 +0100205 alen = get_alen(argv[2]);
Reinhard Meyer7a92e532010-08-25 14:41:16 +0200206 if (alen > 3)
Simon Glass4c12eeb2011-12-10 08:44:01 +0000207 return CMD_RET_USAGE;
Frans Meulenbroeks652e5352010-02-25 10:12:16 +0100208
209 /*
210 * Length is the number of objects, not number of bytes.
211 */
212 length = simple_strtoul(argv[3], NULL, 16);
213
214 /*
215 * memaddr is the address where to store things in memory
216 */
217 memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16);
218
219 if (i2c_read(chip, devaddr, alen, memaddr, length) != 0) {
220 puts ("Error reading the chip.\n");
221 return 1;
222 }
223 return 0;
224}
225
York Sunff5d2dc2012-09-16 08:02:30 +0000226static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
227{
228 u_char chip;
229 uint devaddr, alen, length;
230 u_char *memaddr;
231
232 if (argc != 5)
233 return cmd_usage(cmdtp);
234
235 /*
236 * memaddr is the address where to store things in memory
237 */
238 memaddr = (u_char *)simple_strtoul(argv[1], NULL, 16);
239
240 /*
241 * I2C chip address
242 */
243 chip = simple_strtoul(argv[2], NULL, 16);
244
245 /*
246 * I2C data address within the chip. This can be 1 or
247 * 2 bytes long. Some day it might be 3 bytes long :-).
248 */
249 devaddr = simple_strtoul(argv[3], NULL, 16);
250 alen = get_alen(argv[3]);
251 if (alen > 3)
252 return cmd_usage(cmdtp);
253
254 /*
255 * Length is the number of objects, not number of bytes.
256 */
257 length = simple_strtoul(argv[4], NULL, 16);
258
259 while (length-- > 0) {
260 if (i2c_write(chip, devaddr++, alen, memaddr++, 1) != 0) {
261 puts("Error writing to the chip.\n");
262 return 1;
263 }
264/*
265 * No write delay with FRAM devices.
266 */
267#if !defined(CONFIG_SYS_I2C_FRAM)
268 udelay(11000);
269#endif
270 }
271 return 0;
272}
273
Frans Meulenbroeks4a8cf332010-03-26 09:46:39 +0100274/*
275 * Syntax:
276 * i2c md {i2c_chip} {addr}{.0, .1, .2} {len}
277 */
Wolfgang Denk54841ab2010-06-28 22:00:46 +0200278static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
wdenk81a88242002-10-26 15:22:42 +0000279{
280 u_char chip;
281 uint addr, alen, length;
282 int j, nbytes, linebytes;
283
284 /* We use the last specified parameters, unless new ones are
285 * entered.
286 */
287 chip = i2c_dp_last_chip;
288 addr = i2c_dp_last_addr;
289 alen = i2c_dp_last_alen;
290 length = i2c_dp_last_length;
291
Wolfgang Denk47e26b12010-07-17 01:06:04 +0200292 if (argc < 3)
Simon Glass4c12eeb2011-12-10 08:44:01 +0000293 return CMD_RET_USAGE;
wdenk81a88242002-10-26 15:22:42 +0000294
295 if ((flag & CMD_FLAG_REPEAT) == 0) {
296 /*
297 * New command specified.
298 */
wdenk81a88242002-10-26 15:22:42 +0000299
300 /*
301 * I2C chip address
302 */
303 chip = simple_strtoul(argv[1], NULL, 16);
304
305 /*
306 * I2C data address within the chip. This can be 1 or
307 * 2 bytes long. Some day it might be 3 bytes long :-).
308 */
309 addr = simple_strtoul(argv[2], NULL, 16);
Frans Meulenbroeks2c0dc992010-03-26 09:46:41 +0100310 alen = get_alen(argv[2]);
Reinhard Meyer7a92e532010-08-25 14:41:16 +0200311 if (alen > 3)
Simon Glass4c12eeb2011-12-10 08:44:01 +0000312 return CMD_RET_USAGE;
wdenk81a88242002-10-26 15:22:42 +0000313
314 /*
315 * If another parameter, it is the length to display.
316 * Length is the number of objects, not number of bytes.
317 */
318 if (argc > 3)
319 length = simple_strtoul(argv[3], NULL, 16);
320 }
321
322 /*
323 * Print the lines.
324 *
325 * We buffer all read data, so we can make sure data is read only
326 * once.
327 */
328 nbytes = length;
329 do {
330 unsigned char linebuf[DISP_LINE_LEN];
331 unsigned char *cp;
332
333 linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
334
Timur Tabie857a5b2006-11-28 12:09:35 -0600335 if (i2c_read(chip, addr, alen, linebuf, linebytes) != 0)
wdenk4b9206e2004-03-23 22:14:11 +0000336 puts ("Error reading the chip.\n");
Timur Tabie857a5b2006-11-28 12:09:35 -0600337 else {
wdenk81a88242002-10-26 15:22:42 +0000338 printf("%04x:", addr);
339 cp = linebuf;
340 for (j=0; j<linebytes; j++) {
341 printf(" %02x", *cp++);
342 addr++;
343 }
wdenk4b9206e2004-03-23 22:14:11 +0000344 puts (" ");
wdenk81a88242002-10-26 15:22:42 +0000345 cp = linebuf;
346 for (j=0; j<linebytes; j++) {
347 if ((*cp < 0x20) || (*cp > 0x7e))
wdenk4b9206e2004-03-23 22:14:11 +0000348 puts (".");
wdenk81a88242002-10-26 15:22:42 +0000349 else
350 printf("%c", *cp);
351 cp++;
352 }
wdenk4b9206e2004-03-23 22:14:11 +0000353 putc ('\n');
wdenk81a88242002-10-26 15:22:42 +0000354 }
355 nbytes -= linebytes;
356 } while (nbytes > 0);
357
358 i2c_dp_last_chip = chip;
359 i2c_dp_last_addr = addr;
360 i2c_dp_last_alen = alen;
361 i2c_dp_last_length = length;
362
363 return 0;
364}
365
wdenk81a88242002-10-26 15:22:42 +0000366
367/* Write (fill) memory
368 *
369 * Syntax:
Peter Tyser0f89c542009-04-18 22:34:03 -0500370 * i2c mw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}]
wdenk81a88242002-10-26 15:22:42 +0000371 */
Wolfgang Denk54841ab2010-06-28 22:00:46 +0200372static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
wdenk81a88242002-10-26 15:22:42 +0000373{
374 uchar chip;
375 ulong addr;
376 uint alen;
377 uchar byte;
378 int count;
wdenk81a88242002-10-26 15:22:42 +0000379
Wolfgang Denk47e26b12010-07-17 01:06:04 +0200380 if ((argc < 4) || (argc > 5))
Simon Glass4c12eeb2011-12-10 08:44:01 +0000381 return CMD_RET_USAGE;
wdenk81a88242002-10-26 15:22:42 +0000382
383 /*
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200384 * Chip is always specified.
385 */
wdenk81a88242002-10-26 15:22:42 +0000386 chip = simple_strtoul(argv[1], NULL, 16);
387
388 /*
389 * Address is always specified.
390 */
391 addr = simple_strtoul(argv[2], NULL, 16);
Frans Meulenbroeks2c0dc992010-03-26 09:46:41 +0100392 alen = get_alen(argv[2]);
Reinhard Meyer7a92e532010-08-25 14:41:16 +0200393 if (alen > 3)
Simon Glass4c12eeb2011-12-10 08:44:01 +0000394 return CMD_RET_USAGE;
wdenk81a88242002-10-26 15:22:42 +0000395
396 /*
397 * Value to write is always specified.
398 */
399 byte = simple_strtoul(argv[3], NULL, 16);
400
401 /*
402 * Optional count
403 */
Timur Tabie857a5b2006-11-28 12:09:35 -0600404 if (argc == 5)
wdenk81a88242002-10-26 15:22:42 +0000405 count = simple_strtoul(argv[4], NULL, 16);
Timur Tabie857a5b2006-11-28 12:09:35 -0600406 else
wdenk81a88242002-10-26 15:22:42 +0000407 count = 1;
wdenk81a88242002-10-26 15:22:42 +0000408
409 while (count-- > 0) {
Timur Tabie857a5b2006-11-28 12:09:35 -0600410 if (i2c_write(chip, addr++, alen, &byte, 1) != 0)
wdenk4b9206e2004-03-23 22:14:11 +0000411 puts ("Error writing the chip.\n");
wdenk81a88242002-10-26 15:22:42 +0000412 /*
413 * Wait for the write to complete. The write can take
414 * up to 10mSec (we allow a little more time).
wdenk81a88242002-10-26 15:22:42 +0000415 */
d4f5c722005-08-12 21:16:13 +0200416/*
417 * No write delay with FRAM devices.
418 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200419#if !defined(CONFIG_SYS_I2C_FRAM)
wdenk81a88242002-10-26 15:22:42 +0000420 udelay(11000);
d4f5c722005-08-12 21:16:13 +0200421#endif
wdenk81a88242002-10-26 15:22:42 +0000422 }
423
424 return (0);
425}
426
wdenk81a88242002-10-26 15:22:42 +0000427/* Calculate a CRC on memory
428 *
429 * Syntax:
Peter Tyser0f89c542009-04-18 22:34:03 -0500430 * i2c crc32 {i2c_chip} {addr}{.0, .1, .2} {count}
wdenk81a88242002-10-26 15:22:42 +0000431 */
Wolfgang Denk54841ab2010-06-28 22:00:46 +0200432static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
wdenk81a88242002-10-26 15:22:42 +0000433{
434 uchar chip;
435 ulong addr;
436 uint alen;
437 int count;
438 uchar byte;
439 ulong crc;
440 ulong err;
wdenk81a88242002-10-26 15:22:42 +0000441
Wolfgang Denk47e26b12010-07-17 01:06:04 +0200442 if (argc < 4)
Simon Glass4c12eeb2011-12-10 08:44:01 +0000443 return CMD_RET_USAGE;
wdenk81a88242002-10-26 15:22:42 +0000444
445 /*
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200446 * Chip is always specified.
447 */
wdenk81a88242002-10-26 15:22:42 +0000448 chip = simple_strtoul(argv[1], NULL, 16);
449
450 /*
451 * Address is always specified.
452 */
453 addr = simple_strtoul(argv[2], NULL, 16);
Frans Meulenbroeks2c0dc992010-03-26 09:46:41 +0100454 alen = get_alen(argv[2]);
Reinhard Meyer7a92e532010-08-25 14:41:16 +0200455 if (alen > 3)
Simon Glass4c12eeb2011-12-10 08:44:01 +0000456 return CMD_RET_USAGE;
wdenk81a88242002-10-26 15:22:42 +0000457
458 /*
459 * Count is always specified
460 */
461 count = simple_strtoul(argv[3], NULL, 16);
462
463 printf ("CRC32 for %08lx ... %08lx ==> ", addr, addr + count - 1);
464 /*
465 * CRC a byte at a time. This is going to be slooow, but hey, the
466 * memories are small and slow too so hopefully nobody notices.
467 */
468 crc = 0;
469 err = 0;
Timur Tabie857a5b2006-11-28 12:09:35 -0600470 while (count-- > 0) {
471 if (i2c_read(chip, addr, alen, &byte, 1) != 0)
wdenk81a88242002-10-26 15:22:42 +0000472 err++;
wdenk81a88242002-10-26 15:22:42 +0000473 crc = crc32 (crc, &byte, 1);
474 addr++;
475 }
Timur Tabie857a5b2006-11-28 12:09:35 -0600476 if (err > 0)
wdenk4b9206e2004-03-23 22:14:11 +0000477 puts ("Error reading the chip,\n");
Timur Tabie857a5b2006-11-28 12:09:35 -0600478 else
wdenk81a88242002-10-26 15:22:42 +0000479 printf ("%08lx\n", crc);
wdenk81a88242002-10-26 15:22:42 +0000480
481 return 0;
482}
483
wdenk81a88242002-10-26 15:22:42 +0000484/* Modify memory.
485 *
486 * Syntax:
Peter Tyser0f89c542009-04-18 22:34:03 -0500487 * i2c mm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}
488 * i2c nm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}
wdenk81a88242002-10-26 15:22:42 +0000489 */
490
491static int
Wolfgang Denk54841ab2010-06-28 22:00:46 +0200492mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
wdenk81a88242002-10-26 15:22:42 +0000493{
494 uchar chip;
495 ulong addr;
496 uint alen;
497 ulong data;
498 int size = 1;
499 int nbytes;
wdenk81a88242002-10-26 15:22:42 +0000500
Wolfgang Denk47e26b12010-07-17 01:06:04 +0200501 if (argc != 3)
Simon Glass4c12eeb2011-12-10 08:44:01 +0000502 return CMD_RET_USAGE;
wdenk81a88242002-10-26 15:22:42 +0000503
504#ifdef CONFIG_BOOT_RETRY_TIME
505 reset_cmd_timeout(); /* got a good command to get here */
506#endif
507 /*
508 * We use the last specified parameters, unless new ones are
509 * entered.
510 */
511 chip = i2c_mm_last_chip;
512 addr = i2c_mm_last_addr;
513 alen = i2c_mm_last_alen;
514
515 if ((flag & CMD_FLAG_REPEAT) == 0) {
516 /*
517 * New command specified. Check for a size specification.
518 * Defaults to byte if no or incorrect specification.
519 */
520 size = cmd_get_data_size(argv[0], 1);
521
522 /*
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200523 * Chip is always specified.
524 */
wdenk81a88242002-10-26 15:22:42 +0000525 chip = simple_strtoul(argv[1], NULL, 16);
526
527 /*
528 * Address is always specified.
529 */
530 addr = simple_strtoul(argv[2], NULL, 16);
Frans Meulenbroeks2c0dc992010-03-26 09:46:41 +0100531 alen = get_alen(argv[2]);
Reinhard Meyer7a92e532010-08-25 14:41:16 +0200532 if (alen > 3)
Simon Glass4c12eeb2011-12-10 08:44:01 +0000533 return CMD_RET_USAGE;
wdenk81a88242002-10-26 15:22:42 +0000534 }
535
536 /*
537 * Print the address, followed by value. Then accept input for
538 * the next value. A non-converted value exits.
539 */
540 do {
541 printf("%08lx:", addr);
Timur Tabie857a5b2006-11-28 12:09:35 -0600542 if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0)
wdenk4b9206e2004-03-23 22:14:11 +0000543 puts ("\nError reading the chip,\n");
Timur Tabie857a5b2006-11-28 12:09:35 -0600544 else {
wdenk81a88242002-10-26 15:22:42 +0000545 data = cpu_to_be32(data);
Timur Tabie857a5b2006-11-28 12:09:35 -0600546 if (size == 1)
wdenk81a88242002-10-26 15:22:42 +0000547 printf(" %02lx", (data >> 24) & 0x000000FF);
Timur Tabie857a5b2006-11-28 12:09:35 -0600548 else if (size == 2)
wdenk81a88242002-10-26 15:22:42 +0000549 printf(" %04lx", (data >> 16) & 0x0000FFFF);
Timur Tabie857a5b2006-11-28 12:09:35 -0600550 else
wdenk81a88242002-10-26 15:22:42 +0000551 printf(" %08lx", data);
wdenk81a88242002-10-26 15:22:42 +0000552 }
553
554 nbytes = readline (" ? ");
555 if (nbytes == 0) {
556 /*
557 * <CR> pressed as only input, don't modify current
558 * location and move to next.
559 */
560 if (incrflag)
561 addr += size;
562 nbytes = size;
563#ifdef CONFIG_BOOT_RETRY_TIME
564 reset_cmd_timeout(); /* good enough to not time out */
565#endif
566 }
567#ifdef CONFIG_BOOT_RETRY_TIME
Timur Tabie857a5b2006-11-28 12:09:35 -0600568 else if (nbytes == -2)
wdenk81a88242002-10-26 15:22:42 +0000569 break; /* timed out, exit the command */
wdenk81a88242002-10-26 15:22:42 +0000570#endif
571 else {
572 char *endp;
573
574 data = simple_strtoul(console_buffer, &endp, 16);
Timur Tabie857a5b2006-11-28 12:09:35 -0600575 if (size == 1)
wdenk81a88242002-10-26 15:22:42 +0000576 data = data << 24;
Timur Tabie857a5b2006-11-28 12:09:35 -0600577 else if (size == 2)
wdenk81a88242002-10-26 15:22:42 +0000578 data = data << 16;
wdenk81a88242002-10-26 15:22:42 +0000579 data = be32_to_cpu(data);
580 nbytes = endp - console_buffer;
581 if (nbytes) {
582#ifdef CONFIG_BOOT_RETRY_TIME
583 /*
584 * good enough to not time out
585 */
586 reset_cmd_timeout();
587#endif
Timur Tabie857a5b2006-11-28 12:09:35 -0600588 if (i2c_write(chip, addr, alen, (uchar *)&data, size) != 0)
wdenk4b9206e2004-03-23 22:14:11 +0000589 puts ("Error writing the chip.\n");
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200590#ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS
591 udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
wdenk2535d602003-07-17 23:16:40 +0000592#endif
wdenk81a88242002-10-26 15:22:42 +0000593 if (incrflag)
594 addr += size;
595 }
596 }
597 } while (nbytes);
598
Peter Tyser08007072008-08-15 14:36:32 -0500599 i2c_mm_last_chip = chip;
600 i2c_mm_last_addr = addr;
601 i2c_mm_last_alen = alen;
wdenk81a88242002-10-26 15:22:42 +0000602
603 return 0;
604}
605
606/*
607 * Syntax:
Peter Tyser0f89c542009-04-18 22:34:03 -0500608 * i2c probe {addr}{.0, .1, .2}
wdenk81a88242002-10-26 15:22:42 +0000609 */
Wolfgang Denk54841ab2010-06-28 22:00:46 +0200610static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
wdenk81a88242002-10-26 15:22:42 +0000611{
612 int j;
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200613#if defined(CONFIG_SYS_I2C_NOPROBES)
wdenk81a88242002-10-26 15:22:42 +0000614 int k, skip;
Ben Warrenbb99ad62006-09-07 16:50:54 -0400615 uchar bus = GET_BUS_NUM;
616#endif /* NOPROBES */
wdenk81a88242002-10-26 15:22:42 +0000617
wdenk4b9206e2004-03-23 22:14:11 +0000618 puts ("Valid chip addresses:");
Timur Tabie857a5b2006-11-28 12:09:35 -0600619 for (j = 0; j < 128; j++) {
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200620#if defined(CONFIG_SYS_I2C_NOPROBES)
wdenk81a88242002-10-26 15:22:42 +0000621 skip = 0;
Timur Tabie857a5b2006-11-28 12:09:35 -0600622 for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) {
623 if (COMPARE_BUS(bus, k) && COMPARE_ADDR(j, k)) {
wdenk81a88242002-10-26 15:22:42 +0000624 skip = 1;
625 break;
626 }
627 }
628 if (skip)
629 continue;
630#endif
Timur Tabie857a5b2006-11-28 12:09:35 -0600631 if (i2c_probe(j) == 0)
wdenk81a88242002-10-26 15:22:42 +0000632 printf(" %02X", j);
wdenk81a88242002-10-26 15:22:42 +0000633 }
wdenk4b9206e2004-03-23 22:14:11 +0000634 putc ('\n');
wdenk81a88242002-10-26 15:22:42 +0000635
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200636#if defined(CONFIG_SYS_I2C_NOPROBES)
wdenk81a88242002-10-26 15:22:42 +0000637 puts ("Excluded chip addresses:");
Timur Tabie857a5b2006-11-28 12:09:35 -0600638 for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) {
639 if (COMPARE_BUS(bus,k))
Ben Warrenbb99ad62006-09-07 16:50:54 -0400640 printf(" %02X", NO_PROBE_ADDR(k));
641 }
wdenk4b9206e2004-03-23 22:14:11 +0000642 putc ('\n');
wdenk81a88242002-10-26 15:22:42 +0000643#endif
644
645 return 0;
646}
647
wdenk81a88242002-10-26 15:22:42 +0000648/*
649 * Syntax:
Peter Tyser0f89c542009-04-18 22:34:03 -0500650 * i2c loop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}]
wdenk81a88242002-10-26 15:22:42 +0000651 * {length} - Number of bytes to read
652 * {delay} - A DECIMAL number and defaults to 1000 uSec
653 */
Wolfgang Denk54841ab2010-06-28 22:00:46 +0200654static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
wdenk81a88242002-10-26 15:22:42 +0000655{
656 u_char chip;
657 ulong alen;
658 uint addr;
659 uint length;
660 u_char bytes[16];
661 int delay;
wdenk81a88242002-10-26 15:22:42 +0000662
Wolfgang Denk47e26b12010-07-17 01:06:04 +0200663 if (argc < 3)
Simon Glass4c12eeb2011-12-10 08:44:01 +0000664 return CMD_RET_USAGE;
wdenk81a88242002-10-26 15:22:42 +0000665
666 /*
667 * Chip is always specified.
668 */
669 chip = simple_strtoul(argv[1], NULL, 16);
670
671 /*
672 * Address is always specified.
673 */
674 addr = simple_strtoul(argv[2], NULL, 16);
Frans Meulenbroeks2c0dc992010-03-26 09:46:41 +0100675 alen = get_alen(argv[2]);
Reinhard Meyer7a92e532010-08-25 14:41:16 +0200676 if (alen > 3)
Simon Glass4c12eeb2011-12-10 08:44:01 +0000677 return CMD_RET_USAGE;
wdenk81a88242002-10-26 15:22:42 +0000678
679 /*
680 * Length is the number of objects, not number of bytes.
681 */
682 length = 1;
683 length = simple_strtoul(argv[3], NULL, 16);
Timur Tabie857a5b2006-11-28 12:09:35 -0600684 if (length > sizeof(bytes))
wdenk81a88242002-10-26 15:22:42 +0000685 length = sizeof(bytes);
wdenk81a88242002-10-26 15:22:42 +0000686
687 /*
688 * The delay time (uSec) is optional.
689 */
690 delay = 1000;
Timur Tabie857a5b2006-11-28 12:09:35 -0600691 if (argc > 3)
wdenk81a88242002-10-26 15:22:42 +0000692 delay = simple_strtoul(argv[4], NULL, 10);
wdenk81a88242002-10-26 15:22:42 +0000693 /*
694 * Run the loop...
695 */
Timur Tabie857a5b2006-11-28 12:09:35 -0600696 while (1) {
697 if (i2c_read(chip, addr, alen, bytes, length) != 0)
wdenk4b9206e2004-03-23 22:14:11 +0000698 puts ("Error reading the chip.\n");
wdenk81a88242002-10-26 15:22:42 +0000699 udelay(delay);
700 }
701
702 /* NOTREACHED */
703 return 0;
704}
705
wdenk81a88242002-10-26 15:22:42 +0000706/*
707 * The SDRAM command is separately configured because many
708 * (most?) embedded boards don't use SDRAM DIMMs.
709 */
Jon Loeligerc76fe472007-07-08 18:02:23 -0500710#if defined(CONFIG_CMD_SDRAM)
Larry Johnson632de062008-01-11 23:26:18 -0500711static void print_ddr2_tcyc (u_char const b)
712{
713 printf ("%d.", (b >> 4) & 0x0F);
714 switch (b & 0x0F) {
715 case 0x0:
716 case 0x1:
717 case 0x2:
718 case 0x3:
719 case 0x4:
720 case 0x5:
721 case 0x6:
722 case 0x7:
723 case 0x8:
724 case 0x9:
725 printf ("%d ns\n", b & 0x0F);
726 break;
727 case 0xA:
728 puts ("25 ns\n");
729 break;
730 case 0xB:
731 puts ("33 ns\n");
732 break;
733 case 0xC:
734 puts ("66 ns\n");
735 break;
736 case 0xD:
737 puts ("75 ns\n");
738 break;
739 default:
740 puts ("?? ns\n");
741 break;
742 }
743}
744
745static void decode_bits (u_char const b, char const *str[], int const do_once)
746{
747 u_char mask;
748
749 for (mask = 0x80; mask != 0x00; mask >>= 1, ++str) {
750 if (b & mask) {
751 puts (*str);
752 if (do_once)
753 return;
754 }
755 }
756}
wdenk81a88242002-10-26 15:22:42 +0000757
758/*
759 * Syntax:
Peter Tyser0f89c542009-04-18 22:34:03 -0500760 * i2c sdram {i2c_chip}
wdenk81a88242002-10-26 15:22:42 +0000761 */
Wolfgang Denk54841ab2010-06-28 22:00:46 +0200762static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
wdenk81a88242002-10-26 15:22:42 +0000763{
Larry Johnson632de062008-01-11 23:26:18 -0500764 enum { unknown, EDO, SDRAM, DDR2 } type;
765
wdenk81a88242002-10-26 15:22:42 +0000766 u_char chip;
767 u_char data[128];
768 u_char cksum;
769 int j;
770
Larry Johnson632de062008-01-11 23:26:18 -0500771 static const char *decode_CAS_DDR2[] = {
772 " TBD", " 6", " 5", " 4", " 3", " 2", " TBD", " TBD"
773 };
774
775 static const char *decode_CAS_default[] = {
776 " TBD", " 7", " 6", " 5", " 4", " 3", " 2", " 1"
777 };
778
779 static const char *decode_CS_WE_default[] = {
780 " TBD", " 6", " 5", " 4", " 3", " 2", " 1", " 0"
781 };
782
783 static const char *decode_byte21_default[] = {
784 " TBD (bit 7)\n",
785 " Redundant row address\n",
786 " Differential clock input\n",
787 " Registerd DQMB inputs\n",
788 " Buffered DQMB inputs\n",
789 " On-card PLL\n",
790 " Registered address/control lines\n",
791 " Buffered address/control lines\n"
792 };
793
794 static const char *decode_byte22_DDR2[] = {
795 " TBD (bit 7)\n",
796 " TBD (bit 6)\n",
797 " TBD (bit 5)\n",
798 " TBD (bit 4)\n",
799 " TBD (bit 3)\n",
800 " Supports partial array self refresh\n",
801 " Supports 50 ohm ODT\n",
802 " Supports weak driver\n"
803 };
804
805 static const char *decode_row_density_DDR2[] = {
806 "512 MiB", "256 MiB", "128 MiB", "16 GiB",
807 "8 GiB", "4 GiB", "2 GiB", "1 GiB"
808 };
809
810 static const char *decode_row_density_default[] = {
811 "512 MiB", "256 MiB", "128 MiB", "64 MiB",
812 "32 MiB", "16 MiB", "8 MiB", "4 MiB"
813 };
814
Wolfgang Denk47e26b12010-07-17 01:06:04 +0200815 if (argc < 2)
Simon Glass4c12eeb2011-12-10 08:44:01 +0000816 return CMD_RET_USAGE;
Wolfgang Denk47e26b12010-07-17 01:06:04 +0200817
wdenk81a88242002-10-26 15:22:42 +0000818 /*
819 * Chip is always specified.
Larry Johnson632de062008-01-11 23:26:18 -0500820 */
821 chip = simple_strtoul (argv[1], NULL, 16);
wdenk81a88242002-10-26 15:22:42 +0000822
Larry Johnson632de062008-01-11 23:26:18 -0500823 if (i2c_read (chip, 0, 1, data, sizeof (data)) != 0) {
wdenk4b9206e2004-03-23 22:14:11 +0000824 puts ("No SDRAM Serial Presence Detect found.\n");
wdenk81a88242002-10-26 15:22:42 +0000825 return 1;
826 }
827
828 cksum = 0;
829 for (j = 0; j < 63; j++) {
830 cksum += data[j];
831 }
Timur Tabie857a5b2006-11-28 12:09:35 -0600832 if (cksum != data[63]) {
wdenk81a88242002-10-26 15:22:42 +0000833 printf ("WARNING: Configuration data checksum failure:\n"
Larry Johnson632de062008-01-11 23:26:18 -0500834 " is 0x%02x, calculated 0x%02x\n", data[63], cksum);
wdenk81a88242002-10-26 15:22:42 +0000835 }
Larry Johnson632de062008-01-11 23:26:18 -0500836 printf ("SPD data revision %d.%d\n",
wdenk81a88242002-10-26 15:22:42 +0000837 (data[62] >> 4) & 0x0F, data[62] & 0x0F);
Larry Johnson632de062008-01-11 23:26:18 -0500838 printf ("Bytes used 0x%02X\n", data[0]);
839 printf ("Serial memory size 0x%02X\n", 1 << data[1]);
840
wdenk4b9206e2004-03-23 22:14:11 +0000841 puts ("Memory type ");
Larry Johnson632de062008-01-11 23:26:18 -0500842 switch (data[2]) {
Larry Johnson0df6b842008-01-10 22:23:39 -0500843 case 2:
844 type = EDO;
845 puts ("EDO\n");
846 break;
847 case 4:
848 type = SDRAM;
849 puts ("SDRAM\n");
850 break;
851 case 8:
852 type = DDR2;
853 puts ("DDR2\n");
854 break;
855 default:
856 type = unknown;
857 puts ("unknown\n");
858 break;
wdenk81a88242002-10-26 15:22:42 +0000859 }
Larry Johnson632de062008-01-11 23:26:18 -0500860
wdenk4b9206e2004-03-23 22:14:11 +0000861 puts ("Row address bits ");
Timur Tabie857a5b2006-11-28 12:09:35 -0600862 if ((data[3] & 0x00F0) == 0)
Larry Johnson632de062008-01-11 23:26:18 -0500863 printf ("%d\n", data[3] & 0x0F);
Timur Tabie857a5b2006-11-28 12:09:35 -0600864 else
Larry Johnson632de062008-01-11 23:26:18 -0500865 printf ("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F);
866
wdenk4b9206e2004-03-23 22:14:11 +0000867 puts ("Column address bits ");
Timur Tabie857a5b2006-11-28 12:09:35 -0600868 if ((data[4] & 0x00F0) == 0)
Larry Johnson632de062008-01-11 23:26:18 -0500869 printf ("%d\n", data[4] & 0x0F);
Timur Tabie857a5b2006-11-28 12:09:35 -0600870 else
Larry Johnson632de062008-01-11 23:26:18 -0500871 printf ("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -0500872
873 switch (type) {
874 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -0500875 printf ("Number of ranks %d\n",
876 (data[5] & 0x07) + 1);
Larry Johnson0df6b842008-01-10 22:23:39 -0500877 break;
878 default:
Larry Johnson632de062008-01-11 23:26:18 -0500879 printf ("Module rows %d\n", data[5]);
Larry Johnson0df6b842008-01-10 22:23:39 -0500880 break;
881 }
882
883 switch (type) {
884 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -0500885 printf ("Module data width %d bits\n", data[6]);
Larry Johnson0df6b842008-01-10 22:23:39 -0500886 break;
887 default:
Larry Johnson632de062008-01-11 23:26:18 -0500888 printf ("Module data width %d bits\n",
889 (data[7] << 8) | data[6]);
Larry Johnson0df6b842008-01-10 22:23:39 -0500890 break;
891 }
892
wdenk4b9206e2004-03-23 22:14:11 +0000893 puts ("Interface signal levels ");
wdenk81a88242002-10-26 15:22:42 +0000894 switch(data[8]) {
Larry Johnson0df6b842008-01-10 22:23:39 -0500895 case 0: puts ("TTL 5.0 V\n"); break;
wdenk4b9206e2004-03-23 22:14:11 +0000896 case 1: puts ("LVTTL\n"); break;
Larry Johnson0df6b842008-01-10 22:23:39 -0500897 case 2: puts ("HSTL 1.5 V\n"); break;
898 case 3: puts ("SSTL 3.3 V\n"); break;
899 case 4: puts ("SSTL 2.5 V\n"); break;
900 case 5: puts ("SSTL 1.8 V\n"); break;
wdenk4b9206e2004-03-23 22:14:11 +0000901 default: puts ("unknown\n"); break;
wdenk81a88242002-10-26 15:22:42 +0000902 }
Larry Johnson0df6b842008-01-10 22:23:39 -0500903
904 switch (type) {
905 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -0500906 printf ("SDRAM cycle time ");
907 print_ddr2_tcyc (data[9]);
Larry Johnson0df6b842008-01-10 22:23:39 -0500908 break;
909 default:
Larry Johnson632de062008-01-11 23:26:18 -0500910 printf ("SDRAM cycle time %d.%d ns\n",
911 (data[9] >> 4) & 0x0F, data[9] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -0500912 break;
913 }
914
915 switch (type) {
916 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -0500917 printf ("SDRAM access time 0.%d%d ns\n",
918 (data[10] >> 4) & 0x0F, data[10] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -0500919 break;
920 default:
Larry Johnson632de062008-01-11 23:26:18 -0500921 printf ("SDRAM access time %d.%d ns\n",
922 (data[10] >> 4) & 0x0F, data[10] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -0500923 break;
924 }
925
wdenk4b9206e2004-03-23 22:14:11 +0000926 puts ("EDC configuration ");
Larry Johnson632de062008-01-11 23:26:18 -0500927 switch (data[11]) {
wdenk4b9206e2004-03-23 22:14:11 +0000928 case 0: puts ("None\n"); break;
929 case 1: puts ("Parity\n"); break;
930 case 2: puts ("ECC\n"); break;
931 default: puts ("unknown\n"); break;
wdenk81a88242002-10-26 15:22:42 +0000932 }
Larry Johnson632de062008-01-11 23:26:18 -0500933
Timur Tabie857a5b2006-11-28 12:09:35 -0600934 if ((data[12] & 0x80) == 0)
wdenk4b9206e2004-03-23 22:14:11 +0000935 puts ("No self refresh, rate ");
Timur Tabie857a5b2006-11-28 12:09:35 -0600936 else
wdenk4b9206e2004-03-23 22:14:11 +0000937 puts ("Self refresh, rate ");
Larry Johnson632de062008-01-11 23:26:18 -0500938
wdenk81a88242002-10-26 15:22:42 +0000939 switch(data[12] & 0x7F) {
Larry Johnson632de062008-01-11 23:26:18 -0500940 case 0: puts ("15.625 us\n"); break;
941 case 1: puts ("3.9 us\n"); break;
942 case 2: puts ("7.8 us\n"); break;
943 case 3: puts ("31.3 us\n"); break;
944 case 4: puts ("62.5 us\n"); break;
945 case 5: puts ("125 us\n"); break;
wdenk4b9206e2004-03-23 22:14:11 +0000946 default: puts ("unknown\n"); break;
wdenk81a88242002-10-26 15:22:42 +0000947 }
Larry Johnson0df6b842008-01-10 22:23:39 -0500948
949 switch (type) {
950 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -0500951 printf ("SDRAM width (primary) %d\n", data[13]);
Larry Johnson0df6b842008-01-10 22:23:39 -0500952 break;
953 default:
Larry Johnson632de062008-01-11 23:26:18 -0500954 printf ("SDRAM width (primary) %d\n", data[13] & 0x7F);
Larry Johnson0df6b842008-01-10 22:23:39 -0500955 if ((data[13] & 0x80) != 0) {
Larry Johnson632de062008-01-11 23:26:18 -0500956 printf (" (second bank) %d\n",
957 2 * (data[13] & 0x7F));
Larry Johnson0df6b842008-01-10 22:23:39 -0500958 }
959 break;
wdenk81a88242002-10-26 15:22:42 +0000960 }
Larry Johnson0df6b842008-01-10 22:23:39 -0500961
962 switch (type) {
963 case DDR2:
964 if (data[14] != 0)
Larry Johnson632de062008-01-11 23:26:18 -0500965 printf ("EDC width %d\n", data[14]);
Larry Johnson0df6b842008-01-10 22:23:39 -0500966 break;
967 default:
968 if (data[14] != 0) {
Larry Johnson632de062008-01-11 23:26:18 -0500969 printf ("EDC width %d\n",
970 data[14] & 0x7F);
Larry Johnson0df6b842008-01-10 22:23:39 -0500971
972 if ((data[14] & 0x80) != 0) {
Larry Johnson632de062008-01-11 23:26:18 -0500973 printf (" (second bank) %d\n",
974 2 * (data[14] & 0x7F));
Larry Johnson0df6b842008-01-10 22:23:39 -0500975 }
976 }
977 break;
978 }
979
Larry Johnson632de062008-01-11 23:26:18 -0500980 if (DDR2 != type) {
981 printf ("Min clock delay, back-to-back random column addresses "
982 "%d\n", data[15]);
Larry Johnson0df6b842008-01-10 22:23:39 -0500983 }
984
wdenk4b9206e2004-03-23 22:14:11 +0000985 puts ("Burst length(s) ");
986 if (data[16] & 0x80) puts (" Page");
987 if (data[16] & 0x08) puts (" 8");
988 if (data[16] & 0x04) puts (" 4");
989 if (data[16] & 0x02) puts (" 2");
990 if (data[16] & 0x01) puts (" 1");
991 putc ('\n');
Larry Johnson632de062008-01-11 23:26:18 -0500992 printf ("Number of banks %d\n", data[17]);
Larry Johnson0df6b842008-01-10 22:23:39 -0500993
994 switch (type) {
995 case DDR2:
996 puts ("CAS latency(s) ");
Larry Johnson632de062008-01-11 23:26:18 -0500997 decode_bits (data[18], decode_CAS_DDR2, 0);
Larry Johnson0df6b842008-01-10 22:23:39 -0500998 putc ('\n');
999 break;
1000 default:
1001 puts ("CAS latency(s) ");
Larry Johnson632de062008-01-11 23:26:18 -05001002 decode_bits (data[18], decode_CAS_default, 0);
Larry Johnson0df6b842008-01-10 22:23:39 -05001003 putc ('\n');
1004 break;
1005 }
1006
1007 if (DDR2 != type) {
1008 puts ("CS latency(s) ");
Larry Johnson632de062008-01-11 23:26:18 -05001009 decode_bits (data[19], decode_CS_WE_default, 0);
Larry Johnson0df6b842008-01-10 22:23:39 -05001010 putc ('\n');
1011 }
1012
1013 if (DDR2 != type) {
1014 puts ("WE latency(s) ");
Larry Johnson632de062008-01-11 23:26:18 -05001015 decode_bits (data[20], decode_CS_WE_default, 0);
Larry Johnson0df6b842008-01-10 22:23:39 -05001016 putc ('\n');
1017 }
1018
1019 switch (type) {
1020 case DDR2:
1021 puts ("Module attributes:\n");
1022 if (data[21] & 0x80)
1023 puts (" TBD (bit 7)\n");
1024 if (data[21] & 0x40)
1025 puts (" Analysis probe installed\n");
1026 if (data[21] & 0x20)
1027 puts (" TBD (bit 5)\n");
1028 if (data[21] & 0x10)
1029 puts (" FET switch external enable\n");
Larry Johnson632de062008-01-11 23:26:18 -05001030 printf (" %d PLLs on DIMM\n", (data[21] >> 2) & 0x03);
Larry Johnson0df6b842008-01-10 22:23:39 -05001031 if (data[20] & 0x11) {
Larry Johnson632de062008-01-11 23:26:18 -05001032 printf (" %d active registers on DIMM\n",
1033 (data[21] & 0x03) + 1);
Larry Johnson0df6b842008-01-10 22:23:39 -05001034 }
1035 break;
1036 default:
1037 puts ("Module attributes:\n");
1038 if (!data[21])
1039 puts (" (none)\n");
Larry Johnson632de062008-01-11 23:26:18 -05001040 else
1041 decode_bits (data[21], decode_byte21_default, 0);
Larry Johnson0df6b842008-01-10 22:23:39 -05001042 break;
1043 }
1044
1045 switch (type) {
1046 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -05001047 decode_bits (data[22], decode_byte22_DDR2, 0);
Larry Johnson0df6b842008-01-10 22:23:39 -05001048 break;
1049 default:
1050 puts ("Device attributes:\n");
1051 if (data[22] & 0x80) puts (" TBD (bit 7)\n");
1052 if (data[22] & 0x40) puts (" TBD (bit 6)\n");
1053 if (data[22] & 0x20) puts (" Upper Vcc tolerance 5%\n");
1054 else puts (" Upper Vcc tolerance 10%\n");
1055 if (data[22] & 0x10) puts (" Lower Vcc tolerance 5%\n");
1056 else puts (" Lower Vcc tolerance 10%\n");
1057 if (data[22] & 0x08) puts (" Supports write1/read burst\n");
1058 if (data[22] & 0x04) puts (" Supports precharge all\n");
1059 if (data[22] & 0x02) puts (" Supports auto precharge\n");
1060 if (data[22] & 0x01) puts (" Supports early RAS# precharge\n");
1061 break;
1062 }
1063
1064 switch (type) {
1065 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -05001066 printf ("SDRAM cycle time (2nd highest CAS latency) ");
1067 print_ddr2_tcyc (data[23]);
Larry Johnson0df6b842008-01-10 22:23:39 -05001068 break;
1069 default:
Larry Johnson632de062008-01-11 23:26:18 -05001070 printf ("SDRAM cycle time (2nd highest CAS latency) %d."
1071 "%d ns\n", (data[23] >> 4) & 0x0F, data[23] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001072 break;
1073 }
1074
1075 switch (type) {
1076 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -05001077 printf ("SDRAM access from clock (2nd highest CAS latency) 0."
1078 "%d%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001079 break;
1080 default:
Larry Johnson632de062008-01-11 23:26:18 -05001081 printf ("SDRAM access from clock (2nd highest CAS latency) %d."
1082 "%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001083 break;
1084 }
1085
1086 switch (type) {
1087 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -05001088 printf ("SDRAM cycle time (3rd highest CAS latency) ");
1089 print_ddr2_tcyc (data[25]);
Larry Johnson0df6b842008-01-10 22:23:39 -05001090 break;
1091 default:
Larry Johnson632de062008-01-11 23:26:18 -05001092 printf ("SDRAM cycle time (3rd highest CAS latency) %d."
1093 "%d ns\n", (data[25] >> 4) & 0x0F, data[25] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001094 break;
1095 }
1096
1097 switch (type) {
1098 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -05001099 printf ("SDRAM access from clock (3rd highest CAS latency) 0."
1100 "%d%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001101 break;
1102 default:
Larry Johnson632de062008-01-11 23:26:18 -05001103 printf ("SDRAM access from clock (3rd highest CAS latency) %d."
1104 "%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001105 break;
1106 }
1107
1108 switch (type) {
1109 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -05001110 printf ("Minimum row precharge %d.%02d ns\n",
1111 (data[27] >> 2) & 0x3F, 25 * (data[27] & 0x03));
Larry Johnson0df6b842008-01-10 22:23:39 -05001112 break;
1113 default:
Larry Johnson632de062008-01-11 23:26:18 -05001114 printf ("Minimum row precharge %d ns\n", data[27]);
Larry Johnson0df6b842008-01-10 22:23:39 -05001115 break;
1116 }
1117
1118 switch (type) {
1119 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -05001120 printf ("Row active to row active min %d.%02d ns\n",
1121 (data[28] >> 2) & 0x3F, 25 * (data[28] & 0x03));
Larry Johnson0df6b842008-01-10 22:23:39 -05001122 break;
1123 default:
Larry Johnson632de062008-01-11 23:26:18 -05001124 printf ("Row active to row active min %d ns\n", data[28]);
Larry Johnson0df6b842008-01-10 22:23:39 -05001125 break;
1126 }
1127
1128 switch (type) {
1129 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -05001130 printf ("RAS to CAS delay min %d.%02d ns\n",
1131 (data[29] >> 2) & 0x3F, 25 * (data[29] & 0x03));
Larry Johnson0df6b842008-01-10 22:23:39 -05001132 break;
1133 default:
Larry Johnson632de062008-01-11 23:26:18 -05001134 printf ("RAS to CAS delay min %d ns\n", data[29]);
Larry Johnson0df6b842008-01-10 22:23:39 -05001135 break;
1136 }
1137
Larry Johnson632de062008-01-11 23:26:18 -05001138 printf ("Minimum RAS pulse width %d ns\n", data[30]);
Larry Johnson0df6b842008-01-10 22:23:39 -05001139
1140 switch (type) {
1141 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -05001142 puts ("Density of each row ");
1143 decode_bits (data[31], decode_row_density_DDR2, 1);
1144 putc ('\n');
Larry Johnson0df6b842008-01-10 22:23:39 -05001145 break;
1146 default:
Larry Johnson632de062008-01-11 23:26:18 -05001147 puts ("Density of each row ");
1148 decode_bits (data[31], decode_row_density_default, 1);
1149 putc ('\n');
Larry Johnson0df6b842008-01-10 22:23:39 -05001150 break;
1151 }
1152
1153 switch (type) {
1154 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -05001155 puts ("Command and Address setup ");
Larry Johnson0df6b842008-01-10 22:23:39 -05001156 if (data[32] >= 0xA0) {
Larry Johnson632de062008-01-11 23:26:18 -05001157 printf ("1.%d%d ns\n",
1158 ((data[32] >> 4) & 0x0F) - 10, data[32] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001159 } else {
Larry Johnson632de062008-01-11 23:26:18 -05001160 printf ("0.%d%d ns\n",
1161 ((data[32] >> 4) & 0x0F), data[32] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001162 }
1163 break;
1164 default:
Larry Johnson632de062008-01-11 23:26:18 -05001165 printf ("Command and Address setup %c%d.%d ns\n",
1166 (data[32] & 0x80) ? '-' : '+',
1167 (data[32] >> 4) & 0x07, data[32] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001168 break;
1169 }
1170
1171 switch (type) {
1172 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -05001173 puts ("Command and Address hold ");
Larry Johnson0df6b842008-01-10 22:23:39 -05001174 if (data[33] >= 0xA0) {
Larry Johnson632de062008-01-11 23:26:18 -05001175 printf ("1.%d%d ns\n",
1176 ((data[33] >> 4) & 0x0F) - 10, data[33] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001177 } else {
Larry Johnson632de062008-01-11 23:26:18 -05001178 printf ("0.%d%d ns\n",
1179 ((data[33] >> 4) & 0x0F), data[33] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001180 }
1181 break;
1182 default:
Larry Johnson632de062008-01-11 23:26:18 -05001183 printf ("Command and Address hold %c%d.%d ns\n",
1184 (data[33] & 0x80) ? '-' : '+',
1185 (data[33] >> 4) & 0x07, data[33] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001186 break;
1187 }
1188
1189 switch (type) {
1190 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -05001191 printf ("Data signal input setup 0.%d%d ns\n",
1192 (data[34] >> 4) & 0x0F, data[34] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001193 break;
1194 default:
Larry Johnson632de062008-01-11 23:26:18 -05001195 printf ("Data signal input setup %c%d.%d ns\n",
1196 (data[34] & 0x80) ? '-' : '+',
1197 (data[34] >> 4) & 0x07, data[34] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001198 break;
1199 }
1200
1201 switch (type) {
1202 case DDR2:
Larry Johnson632de062008-01-11 23:26:18 -05001203 printf ("Data signal input hold 0.%d%d ns\n",
1204 (data[35] >> 4) & 0x0F, data[35] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001205 break;
1206 default:
Larry Johnson632de062008-01-11 23:26:18 -05001207 printf ("Data signal input hold %c%d.%d ns\n",
1208 (data[35] & 0x80) ? '-' : '+',
1209 (data[35] >> 4) & 0x07, data[35] & 0x0F);
Larry Johnson0df6b842008-01-10 22:23:39 -05001210 break;
1211 }
1212
wdenk4b9206e2004-03-23 22:14:11 +00001213 puts ("Manufacturer's JEDEC ID ");
Timur Tabie857a5b2006-11-28 12:09:35 -06001214 for (j = 64; j <= 71; j++)
Larry Johnson632de062008-01-11 23:26:18 -05001215 printf ("%02X ", data[j]);
wdenk4b9206e2004-03-23 22:14:11 +00001216 putc ('\n');
Larry Johnson632de062008-01-11 23:26:18 -05001217 printf ("Manufacturing Location %02X\n", data[72]);
wdenk4b9206e2004-03-23 22:14:11 +00001218 puts ("Manufacturer's Part Number ");
Timur Tabie857a5b2006-11-28 12:09:35 -06001219 for (j = 73; j <= 90; j++)
Larry Johnson632de062008-01-11 23:26:18 -05001220 printf ("%02X ", data[j]);
wdenk4b9206e2004-03-23 22:14:11 +00001221 putc ('\n');
Larry Johnson632de062008-01-11 23:26:18 -05001222 printf ("Revision Code %02X %02X\n", data[91], data[92]);
1223 printf ("Manufacturing Date %02X %02X\n", data[93], data[94]);
wdenk4b9206e2004-03-23 22:14:11 +00001224 puts ("Assembly Serial Number ");
Timur Tabie857a5b2006-11-28 12:09:35 -06001225 for (j = 95; j <= 98; j++)
Larry Johnson632de062008-01-11 23:26:18 -05001226 printf ("%02X ", data[j]);
wdenk4b9206e2004-03-23 22:14:11 +00001227 putc ('\n');
wdenk81a88242002-10-26 15:22:42 +00001228
Larry Johnson0df6b842008-01-10 22:23:39 -05001229 if (DDR2 != type) {
Larry Johnson632de062008-01-11 23:26:18 -05001230 printf ("Speed rating PC%d\n",
1231 data[126] == 0x66 ? 66 : data[126]);
Larry Johnson0df6b842008-01-10 22:23:39 -05001232 }
wdenk81a88242002-10-26 15:22:42 +00001233 return 0;
1234}
Jon Loeliger90253172007-07-10 11:02:44 -05001235#endif
wdenk81a88242002-10-26 15:22:42 +00001236
Heiko Schocher67b23a32008-10-15 09:39:47 +02001237#if defined(CONFIG_I2C_MUX)
Wolfgang Denk54841ab2010-06-28 22:00:46 +02001238static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
Heiko Schocher67b23a32008-10-15 09:39:47 +02001239{
1240 int ret=0;
1241
1242 if (argc == 1) {
1243 /* show all busses */
1244 I2C_MUX *mux;
1245 I2C_MUX_DEVICE *device = i2c_mux_devices;
1246
1247 printf ("Busses reached over muxes:\n");
1248 while (device != NULL) {
1249 printf ("Bus ID: %x\n", device->busid);
1250 printf (" reached over Mux(es):\n");
1251 mux = device->mux;
1252 while (mux != NULL) {
1253 printf (" %s@%x ch: %x\n", mux->name, mux->chip, mux->channel);
1254 mux = mux->next;
1255 }
1256 device = device->next;
1257 }
1258 } else {
Wolfgang Denke8260cb2011-11-04 15:55:54 +00001259 (void)i2c_mux_ident_muxstring ((uchar *)argv[1]);
Heiko Schocher67b23a32008-10-15 09:39:47 +02001260 ret = 0;
1261 }
1262 return ret;
1263}
1264#endif /* CONFIG_I2C_MUX */
1265
Ben Warrenbb99ad62006-09-07 16:50:54 -04001266#if defined(CONFIG_I2C_MULTI_BUS)
Wolfgang Denk54841ab2010-06-28 22:00:46 +02001267static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
Ben Warrenbb99ad62006-09-07 16:50:54 -04001268{
1269 int bus_idx, ret=0;
1270
Timur Tabie857a5b2006-11-28 12:09:35 -06001271 if (argc == 1)
1272 /* querying current setting */
Ben Warrenbb99ad62006-09-07 16:50:54 -04001273 printf("Current bus is %d\n", i2c_get_bus_num());
Timur Tabie857a5b2006-11-28 12:09:35 -06001274 else {
Ben Warrenbb99ad62006-09-07 16:50:54 -04001275 bus_idx = simple_strtoul(argv[1], NULL, 10);
1276 printf("Setting bus to %d\n", bus_idx);
1277 ret = i2c_set_bus_num(bus_idx);
Timur Tabie857a5b2006-11-28 12:09:35 -06001278 if (ret)
Ben Warrenbb99ad62006-09-07 16:50:54 -04001279 printf("Failure changing bus number (%d)\n", ret);
Ben Warrenbb99ad62006-09-07 16:50:54 -04001280 }
1281 return ret;
1282}
1283#endif /* CONFIG_I2C_MULTI_BUS */
1284
Wolfgang Denk54841ab2010-06-28 22:00:46 +02001285static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
Ben Warrenbb99ad62006-09-07 16:50:54 -04001286{
1287 int speed, ret=0;
1288
Timur Tabie857a5b2006-11-28 12:09:35 -06001289 if (argc == 1)
1290 /* querying current speed */
Ben Warrenbb99ad62006-09-07 16:50:54 -04001291 printf("Current bus speed=%d\n", i2c_get_bus_speed());
Timur Tabie857a5b2006-11-28 12:09:35 -06001292 else {
Ben Warrenbb99ad62006-09-07 16:50:54 -04001293 speed = simple_strtoul(argv[1], NULL, 10);
1294 printf("Setting bus speed to %d Hz\n", speed);
1295 ret = i2c_set_bus_speed(speed);
Timur Tabie857a5b2006-11-28 12:09:35 -06001296 if (ret)
Ben Warrenbb99ad62006-09-07 16:50:54 -04001297 printf("Failure changing bus speed (%d)\n", ret);
Ben Warrenbb99ad62006-09-07 16:50:54 -04001298 }
1299 return ret;
1300}
1301
Wolfgang Denk54841ab2010-06-28 22:00:46 +02001302static int do_i2c_mm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
Frans Meulenbroeksbfc3b772010-02-25 10:12:14 +01001303{
1304 return mod_i2c_mem (cmdtp, 1, flag, argc, argv);
1305}
1306
Wolfgang Denk54841ab2010-06-28 22:00:46 +02001307static int do_i2c_nm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
Frans Meulenbroeksbfc3b772010-02-25 10:12:14 +01001308{
1309 return mod_i2c_mem (cmdtp, 0, flag, argc, argv);
1310}
1311
Wolfgang Denk54841ab2010-06-28 22:00:46 +02001312static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
Frans Meulenbroeksbfc3b772010-02-25 10:12:14 +01001313{
1314 i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
1315 return 0;
1316}
1317
1318static cmd_tbl_t cmd_i2c_sub[] = {
1319#if defined(CONFIG_I2C_MUX)
1320 U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_add_bus, "", ""),
1321#endif /* CONFIG_I2C_MUX */
1322 U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""),
1323#if defined(CONFIG_I2C_MULTI_BUS)
1324 U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""),
1325#endif /* CONFIG_I2C_MULTI_BUS */
1326 U_BOOT_CMD_MKENT(loop, 3, 1, do_i2c_loop, "", ""),
1327 U_BOOT_CMD_MKENT(md, 3, 1, do_i2c_md, "", ""),
1328 U_BOOT_CMD_MKENT(mm, 2, 1, do_i2c_mm, "", ""),
1329 U_BOOT_CMD_MKENT(mw, 3, 1, do_i2c_mw, "", ""),
1330 U_BOOT_CMD_MKENT(nm, 2, 1, do_i2c_nm, "", ""),
1331 U_BOOT_CMD_MKENT(probe, 0, 1, do_i2c_probe, "", ""),
Frans Meulenbroeks652e5352010-02-25 10:12:16 +01001332 U_BOOT_CMD_MKENT(read, 5, 1, do_i2c_read, "", ""),
York Sunff5d2dc2012-09-16 08:02:30 +00001333 U_BOOT_CMD_MKENT(write, 5, 0, do_i2c_write, "", ""),
Frans Meulenbroeksbfc3b772010-02-25 10:12:14 +01001334 U_BOOT_CMD_MKENT(reset, 0, 1, do_i2c_reset, "", ""),
1335#if defined(CONFIG_CMD_SDRAM)
1336 U_BOOT_CMD_MKENT(sdram, 1, 1, do_sdram, "", ""),
1337#endif
1338 U_BOOT_CMD_MKENT(speed, 1, 1, do_i2c_bus_speed, "", ""),
1339};
1340
Wolfgang Denk2e5167c2010-10-28 20:00:11 +02001341#ifdef CONFIG_NEEDS_MANUAL_RELOC
Heiko Schocherf1d2b312010-09-17 13:10:39 +02001342void i2c_reloc(void) {
1343 fixup_cmdtable(cmd_i2c_sub, ARRAY_SIZE(cmd_i2c_sub));
1344}
1345#endif
1346
Wolfgang Denk54841ab2010-06-28 22:00:46 +02001347static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
Ben Warrenbb99ad62006-09-07 16:50:54 -04001348{
Frans Meulenbroeksbfc3b772010-02-25 10:12:14 +01001349 cmd_tbl_t *c;
1350
Heiko Schocher4444b222010-09-17 13:10:35 +02001351 if (argc < 2)
Simon Glass4c12eeb2011-12-10 08:44:01 +00001352 return CMD_RET_USAGE;
Heiko Schocher4444b222010-09-17 13:10:35 +02001353
Peter Tysere96ad5d2009-04-18 22:34:04 -05001354 /* Strip off leading 'i2c' command argument */
1355 argc--;
1356 argv++;
1357
Frans Meulenbroeksbfc3b772010-02-25 10:12:14 +01001358 c = find_cmd_tbl(argv[0], &cmd_i2c_sub[0], ARRAY_SIZE(cmd_i2c_sub));
1359
Wolfgang Denk47e26b12010-07-17 01:06:04 +02001360 if (c)
Simon Glass4c12eeb2011-12-10 08:44:01 +00001361 return c->cmd(cmdtp, flag, argc, argv);
Wolfgang Denk47e26b12010-07-17 01:06:04 +02001362 else
Simon Glass4c12eeb2011-12-10 08:44:01 +00001363 return CMD_RET_USAGE;
Ben Warrenbb99ad62006-09-07 16:50:54 -04001364}
wdenk8bde7f72003-06-27 21:31:46 +00001365
1366/***************************************************/
1367
Matthias Fuchsd9fc7032007-03-08 16:25:47 +01001368U_BOOT_CMD(
1369 i2c, 6, 1, do_i2c,
Peter Tyser2fb26042009-01-27 18:03:12 -06001370 "I2C sub-system",
Peter Tyser9166b772009-04-18 22:34:06 -05001371#if defined(CONFIG_I2C_MUX)
Frans Meulenbroeksfb0070e2010-02-25 10:12:15 +01001372 "bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes\ni2c "
Peter Tyser9166b772009-04-18 22:34:06 -05001373#endif /* CONFIG_I2C_MUX */
Frans Meulenbroeksfb0070e2010-02-25 10:12:15 +01001374 "crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n"
Matthias Fuchsd9fc7032007-03-08 16:25:47 +01001375#if defined(CONFIG_I2C_MULTI_BUS)
Peter Tyser9bc2e4e2008-10-01 12:25:04 -05001376 "i2c dev [dev] - show or set current I2C bus\n"
Matthias Fuchsd9fc7032007-03-08 16:25:47 +01001377#endif /* CONFIG_I2C_MULTI_BUS */
Frans Meulenbroeksfb0070e2010-02-25 10:12:15 +01001378 "i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device\n"
Matthias Fuchsd9fc7032007-03-08 16:25:47 +01001379 "i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n"
1380 "i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n"
1381 "i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n"
1382 "i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)\n"
Matthias Fuchsd9fc7032007-03-08 16:25:47 +01001383 "i2c probe - show devices on the I2C bus\n"
Frans Meulenbroeks652e5352010-02-25 10:12:16 +01001384 "i2c read chip address[.0, .1, .2] length memaddress - read to memory \n"
York Sunff5d2dc2012-09-16 08:02:30 +00001385 "i2c write memaddress chip address[.0, .1, .2] length - write memory to i2c\n"
Heiko Schochere43a27c2008-10-15 09:33:30 +02001386 "i2c reset - re-init the I2C Controller\n"
Jon Loeligerc76fe472007-07-08 18:02:23 -05001387#if defined(CONFIG_CMD_SDRAM)
Frans Meulenbroeksfb0070e2010-02-25 10:12:15 +01001388 "i2c sdram chip - print SDRAM configuration information\n"
Jon Loeliger90253172007-07-10 11:02:44 -05001389#endif
Frans Meulenbroeksfb0070e2010-02-25 10:12:15 +01001390 "i2c speed [speed] - show or set I2C bus speed"
Matthias Fuchsd9fc7032007-03-08 16:25:47 +01001391);
Heiko Schocher67b23a32008-10-15 09:39:47 +02001392
1393#if defined(CONFIG_I2C_MUX)
Frans Meulenbroeksfd03ea82010-03-26 09:46:42 +01001394static int i2c_mux_add_device(I2C_MUX_DEVICE *dev)
Heiko Schocher67b23a32008-10-15 09:39:47 +02001395{
1396 I2C_MUX_DEVICE *devtmp = i2c_mux_devices;
1397
1398 if (i2c_mux_devices == NULL) {
1399 i2c_mux_devices = dev;
1400 return 0;
1401 }
1402 while (devtmp->next != NULL)
1403 devtmp = devtmp->next;
1404
1405 devtmp->next = dev;
1406 return 0;
1407}
1408
1409I2C_MUX_DEVICE *i2c_mux_search_device(int id)
1410{
1411 I2C_MUX_DEVICE *device = i2c_mux_devices;
1412
1413 while (device != NULL) {
1414 if (device->busid == id)
1415 return device;
1416 device = device->next;
1417 }
1418 return NULL;
1419}
1420
1421/* searches in the buf from *pos the next ':'.
1422 * returns:
1423 * 0 if found (with *pos = where)
1424 * < 0 if an error occured
1425 * > 0 if the end of buf is reached
1426 */
1427static int i2c_mux_search_next (int *pos, uchar *buf, int len)
1428{
1429 while ((buf[*pos] != ':') && (*pos < len)) {
1430 *pos += 1;
1431 }
1432 if (*pos >= len)
1433 return 1;
1434 if (buf[*pos] != ':')
1435 return -1;
1436 return 0;
1437}
1438
1439static int i2c_mux_get_busid (void)
1440{
1441 int tmp = i2c_mux_busid;
1442
1443 i2c_mux_busid ++;
1444 return tmp;
1445}
1446
Michael Jonesf9a78b82011-07-14 22:09:28 +00001447/* Analyses a Muxstring and immediately sends the
1448 commands to the muxes. Runs from flash.
Heiko Schocher67b23a32008-10-15 09:39:47 +02001449 */
1450int i2c_mux_ident_muxstring_f (uchar *buf)
1451{
1452 int pos = 0;
1453 int oldpos;
1454 int ret = 0;
1455 int len = strlen((char *)buf);
1456 int chip;
1457 uchar channel;
1458 int was = 0;
1459
1460 while (ret == 0) {
1461 oldpos = pos;
1462 /* search name */
1463 ret = i2c_mux_search_next(&pos, buf, len);
1464 if (ret != 0)
1465 printf ("ERROR\n");
1466 /* search address */
1467 pos ++;
1468 oldpos = pos;
1469 ret = i2c_mux_search_next(&pos, buf, len);
1470 if (ret != 0)
1471 printf ("ERROR\n");
1472 buf[pos] = 0;
1473 chip = simple_strtoul((char *)&buf[oldpos], NULL, 16);
1474 buf[pos] = ':';
1475 /* search channel */
1476 pos ++;
1477 oldpos = pos;
1478 ret = i2c_mux_search_next(&pos, buf, len);
1479 if (ret < 0)
1480 printf ("ERROR\n");
1481 was = 0;
1482 if (buf[pos] != 0) {
1483 buf[pos] = 0;
1484 was = 1;
1485 }
1486 channel = simple_strtoul((char *)&buf[oldpos], NULL, 16);
1487 if (was)
1488 buf[pos] = ':';
1489 if (i2c_write(chip, 0, 0, &channel, 1) != 0) {
1490 printf ("Error setting Mux: chip:%x channel: \
1491 %x\n", chip, channel);
1492 return -1;
1493 }
1494 pos ++;
1495 oldpos = pos;
1496
1497 }
Holger Brunck8ec038a2012-06-28 04:30:22 +00001498 i2c_init_board();
Heiko Schocher67b23a32008-10-15 09:39:47 +02001499
1500 return 0;
1501}
1502
1503/* Analyses a Muxstring and if this String is correct
1504 * adds a new I2C Bus.
1505 */
1506I2C_MUX_DEVICE *i2c_mux_ident_muxstring (uchar *buf)
1507{
1508 I2C_MUX_DEVICE *device;
1509 I2C_MUX *mux;
1510 int pos = 0;
1511 int oldpos;
1512 int ret = 0;
1513 int len = strlen((char *)buf);
1514 int was = 0;
1515
1516 device = (I2C_MUX_DEVICE *)malloc (sizeof(I2C_MUX_DEVICE));
1517 device->mux = NULL;
1518 device->busid = i2c_mux_get_busid ();
1519 device->next = NULL;
1520 while (ret == 0) {
1521 mux = (I2C_MUX *)malloc (sizeof(I2C_MUX));
1522 mux->next = NULL;
1523 /* search name of mux */
1524 oldpos = pos;
1525 ret = i2c_mux_search_next(&pos, buf, len);
1526 if (ret != 0)
1527 printf ("%s no name.\n", __FUNCTION__);
1528 mux->name = (char *)malloc (pos - oldpos + 1);
1529 memcpy (mux->name, &buf[oldpos], pos - oldpos);
1530 mux->name[pos - oldpos] = 0;
1531 /* search address */
1532 pos ++;
1533 oldpos = pos;
1534 ret = i2c_mux_search_next(&pos, buf, len);
1535 if (ret != 0)
1536 printf ("%s no mux address.\n", __FUNCTION__);
1537 buf[pos] = 0;
1538 mux->chip = simple_strtoul((char *)&buf[oldpos], NULL, 16);
1539 buf[pos] = ':';
1540 /* search channel */
1541 pos ++;
1542 oldpos = pos;
1543 ret = i2c_mux_search_next(&pos, buf, len);
1544 if (ret < 0)
1545 printf ("%s no mux channel.\n", __FUNCTION__);
1546 was = 0;
1547 if (buf[pos] != 0) {
1548 buf[pos] = 0;
1549 was = 1;
1550 }
1551 mux->channel = simple_strtoul((char *)&buf[oldpos], NULL, 16);
1552 if (was)
1553 buf[pos] = ':';
1554 if (device->mux == NULL)
1555 device->mux = mux;
1556 else {
1557 I2C_MUX *muxtmp = device->mux;
1558 while (muxtmp->next != NULL) {
1559 muxtmp = muxtmp->next;
1560 }
1561 muxtmp->next = mux;
1562 }
1563 pos ++;
1564 oldpos = pos;
1565 }
1566 if (ret > 0) {
1567 /* Add Device */
1568 i2c_mux_add_device (device);
1569 return device;
1570 }
1571
1572 return NULL;
1573}
1574
1575int i2x_mux_select_mux(int bus)
1576{
1577 I2C_MUX_DEVICE *dev;
1578 I2C_MUX *mux;
1579
1580 if ((gd->flags & GD_FLG_RELOC) != GD_FLG_RELOC) {
1581 /* select Default Mux Bus */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +02001582#if defined(CONFIG_SYS_I2C_IVM_BUS)
1583 i2c_mux_ident_muxstring_f ((uchar *)CONFIG_SYS_I2C_IVM_BUS);
Heiko Schocher67b23a32008-10-15 09:39:47 +02001584#else
1585 {
1586 unsigned char *buf;
1587 buf = (unsigned char *) getenv("EEprom_ivm");
1588 if (buf != NULL)
1589 i2c_mux_ident_muxstring_f (buf);
1590 }
1591#endif
1592 return 0;
1593 }
1594 dev = i2c_mux_search_device(bus);
1595 if (dev == NULL)
1596 return -1;
1597
1598 mux = dev->mux;
1599 while (mux != NULL) {
Stefan Biglerc649dda2011-04-08 16:24:08 +02001600 /* do deblocking on each level of mux, before mux config */
1601 i2c_init_board();
Heiko Schocher67b23a32008-10-15 09:39:47 +02001602 if (i2c_write(mux->chip, 0, 0, &mux->channel, 1) != 0) {
1603 printf ("Error setting Mux: chip:%x channel: \
1604 %x\n", mux->chip, mux->channel);
1605 return -1;
1606 }
1607 mux = mux->next;
1608 }
Stefan Biglerc649dda2011-04-08 16:24:08 +02001609 /* do deblocking on each level of mux and after mux config */
1610 i2c_init_board();
Heiko Schocher67b23a32008-10-15 09:39:47 +02001611 return 0;
1612}
1613#endif /* CONFIG_I2C_MUX */