Commit 9166b776350d16460c7330bfb0a50154ea0a1903
Committed by
Wolfgang Denk
1 parent
0a45a6357b
Exists in
master
and in
55 other branches
cmd_i2c: Fix i2c help command output when CONFIG_I2C_MUX
When CONFIG_I2C_MUX was defined the output of 'help i2c' was not correct, eg: => help i2c i2c bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes. speed [speed] - show or set I2C bus speed i2c dev [dev] - show or set current I2C bus ... It has been changed to: i2c speed [speed] - show or set I2C bus speed i2c bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes i2c dev [dev] - show or set current I2C bus ... Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
Showing 1 changed file with 2 additions and 2 deletions Inline Diff
common/cmd_i2c.c
1 | /* | 1 | /* |
2 | * (C) Copyright 2001 | 2 | * (C) Copyright 2001 |
3 | * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. | 3 | * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. |
4 | * | 4 | * |
5 | * See file CREDITS for list of people who contributed to this | 5 | * See file CREDITS for list of people who contributed to this |
6 | * project. | 6 | * project. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or | 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 | 9 | * modify it under the terms of the GNU General Public License as |
10 | * published by the Free Software Foundation; either version 2 of | 10 | * published by the Free Software Foundation; either version 2 of |
11 | * the License, or (at your option) any later version. | 11 | * the License, or (at your option) any later version. |
12 | * | 12 | * |
13 | * This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | * | 17 | * |
18 | * You should have received a copy of the GNU General Public License | 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 | 19 | * along with this program; if not, write to the Free Software |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
21 | * MA 02111-1307 USA | 21 | * MA 02111-1307 USA |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* | 24 | /* |
25 | * I2C Functions similar to the standard memory functions. | 25 | * I2C Functions similar to the standard memory functions. |
26 | * | 26 | * |
27 | * There are several parameters in many of the commands that bear further | 27 | * There are several parameters in many of the commands that bear further |
28 | * explanations: | 28 | * explanations: |
29 | * | 29 | * |
30 | * {i2c_chip} is the I2C chip address (the first byte sent on the bus). | 30 | * {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, | 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" | 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 | 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 | 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 | 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 | 36 | * for write and 0xA1 for read. This "non shifted" address notation |
37 | * matches at least half of the data sheets :-/. | 37 | * matches at least half of the data sheets :-/. |
38 | * | 38 | * |
39 | * {addr} is the address (or offset) within the chip. Small memory | 39 | * {addr} is the address (or offset) within the chip. Small memory |
40 | * chips have 8 bit addresses. Large memory chips have 16 bit | 40 | * chips have 8 bit addresses. Large memory chips have 16 bit |
41 | * addresses. Other memory chips have 9, 10, or 11 bit addresses. | 41 | * addresses. Other memory chips have 9, 10, or 11 bit addresses. |
42 | * Many non-memory chips have multiple registers and {addr} is used | 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 | 43 | * as the register index. Some non-memory chips have only one register |
44 | * and therefore don't need any {addr} parameter. | 44 | * and therefore don't need any {addr} parameter. |
45 | * | 45 | * |
46 | * The default {addr} parameter is one byte (.1) which works well for | 46 | * The default {addr} parameter is one byte (.1) which works well for |
47 | * memories and registers with 8 bits of address space. | 47 | * memories and registers with 8 bits of address space. |
48 | * | 48 | * |
49 | * You can specify the length of the {addr} field with the optional .0, | 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 | 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 | 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 | 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 | 53 | * suppress the address in the I2C data stream. This also works for |
54 | * successive reads using the I2C auto-incrementing memory pointer. | 54 | * successive reads using the I2C auto-incrementing memory pointer. |
55 | * | 55 | * |
56 | * If you are manipulating a large memory with 2-byte addresses, use | 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). | 57 | * the .2 address modifier, e.g. 210.2 addresses location 528 (decimal). |
58 | * | 58 | * |
59 | * Then there are the unfortunate memory chips that spill the most | 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. | 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 | 61 | * This effectively makes one chip (logically) look like 2, 4, or |
62 | * 8 chips. This is handled (awkwardly) by #defining | 62 | * 8 chips. This is handled (awkwardly) by #defining |
63 | * CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW and using the .1 modifier on the | 63 | * CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW and using the .1 modifier on the |
64 | * {addr} field (since .1 is the default, it doesn't actually have to | 64 | * {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 | 65 | * be specified). Examples: given a memory chip at I2C chip address |
66 | * 0x50, the following would happen... | 66 | * 0x50, the following would happen... |
67 | * i2c md 50 0 10 display 16 bytes starting at 0x000 | 67 | * i2c md 50 0 10 display 16 bytes starting at 0x000 |
68 | * On the bus: <S> A0 00 <E> <S> A1 <rd> ... <rd> | 68 | * On the bus: <S> A0 00 <E> <S> A1 <rd> ... <rd> |
69 | * i2c md 50 100 10 display 16 bytes starting at 0x100 | 69 | * i2c md 50 100 10 display 16 bytes starting at 0x100 |
70 | * On the bus: <S> A2 00 <E> <S> A3 <rd> ... <rd> | 70 | * On the bus: <S> A2 00 <E> <S> A3 <rd> ... <rd> |
71 | * i2c md 50 210 10 display 16 bytes starting at 0x210 | 71 | * i2c md 50 210 10 display 16 bytes starting at 0x210 |
72 | * On the bus: <S> A4 10 <E> <S> A5 <rd> ... <rd> | 72 | * 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 | 73 | * This is awfully ugly. It would be nice if someone would think up |
74 | * a better way of handling this. | 74 | * a better way of handling this. |
75 | * | 75 | * |
76 | * Adapted from cmd_mem.c which is copyright Wolfgang Denk (wd@denx.de). | 76 | * Adapted from cmd_mem.c which is copyright Wolfgang Denk (wd@denx.de). |
77 | */ | 77 | */ |
78 | 78 | ||
79 | #include <common.h> | 79 | #include <common.h> |
80 | #include <command.h> | 80 | #include <command.h> |
81 | #include <environment.h> | 81 | #include <environment.h> |
82 | #include <i2c.h> | 82 | #include <i2c.h> |
83 | #include <malloc.h> | 83 | #include <malloc.h> |
84 | #include <asm/byteorder.h> | 84 | #include <asm/byteorder.h> |
85 | 85 | ||
86 | /* Display values from last command. | 86 | /* Display values from last command. |
87 | * Memory modify remembered values are different from display memory. | 87 | * Memory modify remembered values are different from display memory. |
88 | */ | 88 | */ |
89 | static uchar i2c_dp_last_chip; | 89 | static uchar i2c_dp_last_chip; |
90 | static uint i2c_dp_last_addr; | 90 | static uint i2c_dp_last_addr; |
91 | static uint i2c_dp_last_alen; | 91 | static uint i2c_dp_last_alen; |
92 | static uint i2c_dp_last_length = 0x10; | 92 | static uint i2c_dp_last_length = 0x10; |
93 | 93 | ||
94 | static uchar i2c_mm_last_chip; | 94 | static uchar i2c_mm_last_chip; |
95 | static uint i2c_mm_last_addr; | 95 | static uint i2c_mm_last_addr; |
96 | static uint i2c_mm_last_alen; | 96 | static uint i2c_mm_last_alen; |
97 | 97 | ||
98 | /* If only one I2C bus is present, the list of devices to ignore when | 98 | /* 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. | 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 | 100 | * When multiple buses are present, the list is an array of bus-address |
101 | * pairs. The following macros take care of this */ | 101 | * pairs. The following macros take care of this */ |
102 | 102 | ||
103 | #if defined(CONFIG_SYS_I2C_NOPROBES) | 103 | #if defined(CONFIG_SYS_I2C_NOPROBES) |
104 | #if defined(CONFIG_I2C_MULTI_BUS) | 104 | #if defined(CONFIG_I2C_MULTI_BUS) |
105 | static struct | 105 | static struct |
106 | { | 106 | { |
107 | uchar bus; | 107 | uchar bus; |
108 | uchar addr; | 108 | uchar addr; |
109 | } i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES; | 109 | } i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES; |
110 | #define GET_BUS_NUM i2c_get_bus_num() | 110 | #define GET_BUS_NUM i2c_get_bus_num() |
111 | #define COMPARE_BUS(b,i) (i2c_no_probes[(i)].bus == (b)) | 111 | #define COMPARE_BUS(b,i) (i2c_no_probes[(i)].bus == (b)) |
112 | #define COMPARE_ADDR(a,i) (i2c_no_probes[(i)].addr == (a)) | 112 | #define COMPARE_ADDR(a,i) (i2c_no_probes[(i)].addr == (a)) |
113 | #define NO_PROBE_ADDR(i) i2c_no_probes[(i)].addr | 113 | #define NO_PROBE_ADDR(i) i2c_no_probes[(i)].addr |
114 | #else /* single bus */ | 114 | #else /* single bus */ |
115 | static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES; | 115 | static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES; |
116 | #define GET_BUS_NUM 0 | 116 | #define GET_BUS_NUM 0 |
117 | #define COMPARE_BUS(b,i) ((b) == 0) /* Make compiler happy */ | 117 | #define COMPARE_BUS(b,i) ((b) == 0) /* Make compiler happy */ |
118 | #define COMPARE_ADDR(a,i) (i2c_no_probes[(i)] == (a)) | 118 | #define COMPARE_ADDR(a,i) (i2c_no_probes[(i)] == (a)) |
119 | #define NO_PROBE_ADDR(i) i2c_no_probes[(i)] | 119 | #define NO_PROBE_ADDR(i) i2c_no_probes[(i)] |
120 | #endif /* CONFIG_MULTI_BUS */ | 120 | #endif /* CONFIG_MULTI_BUS */ |
121 | 121 | ||
122 | #define NUM_ELEMENTS_NOPROBE (sizeof(i2c_no_probes)/sizeof(i2c_no_probes[0])) | 122 | #define NUM_ELEMENTS_NOPROBE (sizeof(i2c_no_probes)/sizeof(i2c_no_probes[0])) |
123 | #endif | 123 | #endif |
124 | 124 | ||
125 | #if defined(CONFIG_I2C_MUX) | 125 | #if defined(CONFIG_I2C_MUX) |
126 | static I2C_MUX_DEVICE *i2c_mux_devices = NULL; | 126 | static I2C_MUX_DEVICE *i2c_mux_devices = NULL; |
127 | static int i2c_mux_busid = CONFIG_SYS_MAX_I2C_BUS; | 127 | static int i2c_mux_busid = CONFIG_SYS_MAX_I2C_BUS; |
128 | 128 | ||
129 | DECLARE_GLOBAL_DATA_PTR; | 129 | DECLARE_GLOBAL_DATA_PTR; |
130 | 130 | ||
131 | #endif | 131 | #endif |
132 | 132 | ||
133 | /* TODO: Implement architecture-specific get/set functions */ | 133 | /* TODO: Implement architecture-specific get/set functions */ |
134 | unsigned int __def_i2c_get_bus_speed(void) | 134 | unsigned int __def_i2c_get_bus_speed(void) |
135 | { | 135 | { |
136 | return CONFIG_SYS_I2C_SPEED; | 136 | return CONFIG_SYS_I2C_SPEED; |
137 | } | 137 | } |
138 | unsigned int i2c_get_bus_speed(void) | 138 | unsigned int i2c_get_bus_speed(void) |
139 | __attribute__((weak, alias("__def_i2c_get_bus_speed"))); | 139 | __attribute__((weak, alias("__def_i2c_get_bus_speed"))); |
140 | 140 | ||
141 | int __def_i2c_set_bus_speed(unsigned int speed) | 141 | int __def_i2c_set_bus_speed(unsigned int speed) |
142 | { | 142 | { |
143 | if (speed != CONFIG_SYS_I2C_SPEED) | 143 | if (speed != CONFIG_SYS_I2C_SPEED) |
144 | return -1; | 144 | return -1; |
145 | 145 | ||
146 | return 0; | 146 | return 0; |
147 | } | 147 | } |
148 | int i2c_set_bus_speed(unsigned int) | 148 | int i2c_set_bus_speed(unsigned int) |
149 | __attribute__((weak, alias("__def_i2c_set_bus_speed"))); | 149 | __attribute__((weak, alias("__def_i2c_set_bus_speed"))); |
150 | 150 | ||
151 | /* | 151 | /* |
152 | * Syntax: | 152 | * Syntax: |
153 | * i2c md {i2c_chip} {addr}{.0, .1, .2} {len} | 153 | * i2c md {i2c_chip} {addr}{.0, .1, .2} {len} |
154 | */ | 154 | */ |
155 | #define DISP_LINE_LEN 16 | 155 | #define DISP_LINE_LEN 16 |
156 | 156 | ||
157 | int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 157 | int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
158 | { | 158 | { |
159 | u_char chip; | 159 | u_char chip; |
160 | uint addr, alen, length; | 160 | uint addr, alen, length; |
161 | int j, nbytes, linebytes; | 161 | int j, nbytes, linebytes; |
162 | 162 | ||
163 | /* We use the last specified parameters, unless new ones are | 163 | /* We use the last specified parameters, unless new ones are |
164 | * entered. | 164 | * entered. |
165 | */ | 165 | */ |
166 | chip = i2c_dp_last_chip; | 166 | chip = i2c_dp_last_chip; |
167 | addr = i2c_dp_last_addr; | 167 | addr = i2c_dp_last_addr; |
168 | alen = i2c_dp_last_alen; | 168 | alen = i2c_dp_last_alen; |
169 | length = i2c_dp_last_length; | 169 | length = i2c_dp_last_length; |
170 | 170 | ||
171 | if (argc < 3) { | 171 | if (argc < 3) { |
172 | cmd_usage(cmdtp); | 172 | cmd_usage(cmdtp); |
173 | return 1; | 173 | return 1; |
174 | } | 174 | } |
175 | 175 | ||
176 | if ((flag & CMD_FLAG_REPEAT) == 0) { | 176 | if ((flag & CMD_FLAG_REPEAT) == 0) { |
177 | /* | 177 | /* |
178 | * New command specified. | 178 | * New command specified. |
179 | */ | 179 | */ |
180 | alen = 1; | 180 | alen = 1; |
181 | 181 | ||
182 | /* | 182 | /* |
183 | * I2C chip address | 183 | * I2C chip address |
184 | */ | 184 | */ |
185 | chip = simple_strtoul(argv[1], NULL, 16); | 185 | chip = simple_strtoul(argv[1], NULL, 16); |
186 | 186 | ||
187 | /* | 187 | /* |
188 | * I2C data address within the chip. This can be 1 or | 188 | * I2C data address within the chip. This can be 1 or |
189 | * 2 bytes long. Some day it might be 3 bytes long :-). | 189 | * 2 bytes long. Some day it might be 3 bytes long :-). |
190 | */ | 190 | */ |
191 | addr = simple_strtoul(argv[2], NULL, 16); | 191 | addr = simple_strtoul(argv[2], NULL, 16); |
192 | alen = 1; | 192 | alen = 1; |
193 | for (j = 0; j < 8; j++) { | 193 | for (j = 0; j < 8; j++) { |
194 | if (argv[2][j] == '.') { | 194 | if (argv[2][j] == '.') { |
195 | alen = argv[2][j+1] - '0'; | 195 | alen = argv[2][j+1] - '0'; |
196 | if (alen > 4) { | 196 | if (alen > 4) { |
197 | cmd_usage(cmdtp); | 197 | cmd_usage(cmdtp); |
198 | return 1; | 198 | return 1; |
199 | } | 199 | } |
200 | break; | 200 | break; |
201 | } else if (argv[2][j] == '\0') | 201 | } else if (argv[2][j] == '\0') |
202 | break; | 202 | break; |
203 | } | 203 | } |
204 | 204 | ||
205 | /* | 205 | /* |
206 | * If another parameter, it is the length to display. | 206 | * If another parameter, it is the length to display. |
207 | * Length is the number of objects, not number of bytes. | 207 | * Length is the number of objects, not number of bytes. |
208 | */ | 208 | */ |
209 | if (argc > 3) | 209 | if (argc > 3) |
210 | length = simple_strtoul(argv[3], NULL, 16); | 210 | length = simple_strtoul(argv[3], NULL, 16); |
211 | } | 211 | } |
212 | 212 | ||
213 | /* | 213 | /* |
214 | * Print the lines. | 214 | * Print the lines. |
215 | * | 215 | * |
216 | * We buffer all read data, so we can make sure data is read only | 216 | * We buffer all read data, so we can make sure data is read only |
217 | * once. | 217 | * once. |
218 | */ | 218 | */ |
219 | nbytes = length; | 219 | nbytes = length; |
220 | do { | 220 | do { |
221 | unsigned char linebuf[DISP_LINE_LEN]; | 221 | unsigned char linebuf[DISP_LINE_LEN]; |
222 | unsigned char *cp; | 222 | unsigned char *cp; |
223 | 223 | ||
224 | linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; | 224 | linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; |
225 | 225 | ||
226 | if (i2c_read(chip, addr, alen, linebuf, linebytes) != 0) | 226 | if (i2c_read(chip, addr, alen, linebuf, linebytes) != 0) |
227 | puts ("Error reading the chip.\n"); | 227 | puts ("Error reading the chip.\n"); |
228 | else { | 228 | else { |
229 | printf("%04x:", addr); | 229 | printf("%04x:", addr); |
230 | cp = linebuf; | 230 | cp = linebuf; |
231 | for (j=0; j<linebytes; j++) { | 231 | for (j=0; j<linebytes; j++) { |
232 | printf(" %02x", *cp++); | 232 | printf(" %02x", *cp++); |
233 | addr++; | 233 | addr++; |
234 | } | 234 | } |
235 | puts (" "); | 235 | puts (" "); |
236 | cp = linebuf; | 236 | cp = linebuf; |
237 | for (j=0; j<linebytes; j++) { | 237 | for (j=0; j<linebytes; j++) { |
238 | if ((*cp < 0x20) || (*cp > 0x7e)) | 238 | if ((*cp < 0x20) || (*cp > 0x7e)) |
239 | puts ("."); | 239 | puts ("."); |
240 | else | 240 | else |
241 | printf("%c", *cp); | 241 | printf("%c", *cp); |
242 | cp++; | 242 | cp++; |
243 | } | 243 | } |
244 | putc ('\n'); | 244 | putc ('\n'); |
245 | } | 245 | } |
246 | nbytes -= linebytes; | 246 | nbytes -= linebytes; |
247 | } while (nbytes > 0); | 247 | } while (nbytes > 0); |
248 | 248 | ||
249 | i2c_dp_last_chip = chip; | 249 | i2c_dp_last_chip = chip; |
250 | i2c_dp_last_addr = addr; | 250 | i2c_dp_last_addr = addr; |
251 | i2c_dp_last_alen = alen; | 251 | i2c_dp_last_alen = alen; |
252 | i2c_dp_last_length = length; | 252 | i2c_dp_last_length = length; |
253 | 253 | ||
254 | return 0; | 254 | return 0; |
255 | } | 255 | } |
256 | 256 | ||
257 | 257 | ||
258 | /* Write (fill) memory | 258 | /* Write (fill) memory |
259 | * | 259 | * |
260 | * Syntax: | 260 | * Syntax: |
261 | * i2c mw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}] | 261 | * i2c mw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}] |
262 | */ | 262 | */ |
263 | int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 263 | int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
264 | { | 264 | { |
265 | uchar chip; | 265 | uchar chip; |
266 | ulong addr; | 266 | ulong addr; |
267 | uint alen; | 267 | uint alen; |
268 | uchar byte; | 268 | uchar byte; |
269 | int count; | 269 | int count; |
270 | int j; | 270 | int j; |
271 | 271 | ||
272 | if ((argc < 4) || (argc > 5)) { | 272 | if ((argc < 4) || (argc > 5)) { |
273 | cmd_usage(cmdtp); | 273 | cmd_usage(cmdtp); |
274 | return 1; | 274 | return 1; |
275 | } | 275 | } |
276 | 276 | ||
277 | /* | 277 | /* |
278 | * Chip is always specified. | 278 | * Chip is always specified. |
279 | */ | 279 | */ |
280 | chip = simple_strtoul(argv[1], NULL, 16); | 280 | chip = simple_strtoul(argv[1], NULL, 16); |
281 | 281 | ||
282 | /* | 282 | /* |
283 | * Address is always specified. | 283 | * Address is always specified. |
284 | */ | 284 | */ |
285 | addr = simple_strtoul(argv[2], NULL, 16); | 285 | addr = simple_strtoul(argv[2], NULL, 16); |
286 | alen = 1; | 286 | alen = 1; |
287 | for (j = 0; j < 8; j++) { | 287 | for (j = 0; j < 8; j++) { |
288 | if (argv[2][j] == '.') { | 288 | if (argv[2][j] == '.') { |
289 | alen = argv[2][j+1] - '0'; | 289 | alen = argv[2][j+1] - '0'; |
290 | if (alen > 4) { | 290 | if (alen > 4) { |
291 | cmd_usage(cmdtp); | 291 | cmd_usage(cmdtp); |
292 | return 1; | 292 | return 1; |
293 | } | 293 | } |
294 | break; | 294 | break; |
295 | } else if (argv[2][j] == '\0') | 295 | } else if (argv[2][j] == '\0') |
296 | break; | 296 | break; |
297 | } | 297 | } |
298 | 298 | ||
299 | /* | 299 | /* |
300 | * Value to write is always specified. | 300 | * Value to write is always specified. |
301 | */ | 301 | */ |
302 | byte = simple_strtoul(argv[3], NULL, 16); | 302 | byte = simple_strtoul(argv[3], NULL, 16); |
303 | 303 | ||
304 | /* | 304 | /* |
305 | * Optional count | 305 | * Optional count |
306 | */ | 306 | */ |
307 | if (argc == 5) | 307 | if (argc == 5) |
308 | count = simple_strtoul(argv[4], NULL, 16); | 308 | count = simple_strtoul(argv[4], NULL, 16); |
309 | else | 309 | else |
310 | count = 1; | 310 | count = 1; |
311 | 311 | ||
312 | while (count-- > 0) { | 312 | while (count-- > 0) { |
313 | if (i2c_write(chip, addr++, alen, &byte, 1) != 0) | 313 | if (i2c_write(chip, addr++, alen, &byte, 1) != 0) |
314 | puts ("Error writing the chip.\n"); | 314 | puts ("Error writing the chip.\n"); |
315 | /* | 315 | /* |
316 | * Wait for the write to complete. The write can take | 316 | * Wait for the write to complete. The write can take |
317 | * up to 10mSec (we allow a little more time). | 317 | * up to 10mSec (we allow a little more time). |
318 | * | 318 | * |
319 | * On some chips, while the write is in progress, the | 319 | * On some chips, while the write is in progress, the |
320 | * chip doesn't respond. This apparently isn't a | 320 | * chip doesn't respond. This apparently isn't a |
321 | * universal feature so we don't take advantage of it. | 321 | * universal feature so we don't take advantage of it. |
322 | */ | 322 | */ |
323 | /* | 323 | /* |
324 | * No write delay with FRAM devices. | 324 | * No write delay with FRAM devices. |
325 | */ | 325 | */ |
326 | #if !defined(CONFIG_SYS_I2C_FRAM) | 326 | #if !defined(CONFIG_SYS_I2C_FRAM) |
327 | udelay(11000); | 327 | udelay(11000); |
328 | #endif | 328 | #endif |
329 | 329 | ||
330 | #if 0 | 330 | #if 0 |
331 | for (timeout = 0; timeout < 10; timeout++) { | 331 | for (timeout = 0; timeout < 10; timeout++) { |
332 | udelay(2000); | 332 | udelay(2000); |
333 | if (i2c_probe(chip) == 0) | 333 | if (i2c_probe(chip) == 0) |
334 | break; | 334 | break; |
335 | } | 335 | } |
336 | #endif | 336 | #endif |
337 | } | 337 | } |
338 | 338 | ||
339 | return (0); | 339 | return (0); |
340 | } | 340 | } |
341 | 341 | ||
342 | /* Calculate a CRC on memory | 342 | /* Calculate a CRC on memory |
343 | * | 343 | * |
344 | * Syntax: | 344 | * Syntax: |
345 | * i2c crc32 {i2c_chip} {addr}{.0, .1, .2} {count} | 345 | * i2c crc32 {i2c_chip} {addr}{.0, .1, .2} {count} |
346 | */ | 346 | */ |
347 | int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 347 | int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
348 | { | 348 | { |
349 | uchar chip; | 349 | uchar chip; |
350 | ulong addr; | 350 | ulong addr; |
351 | uint alen; | 351 | uint alen; |
352 | int count; | 352 | int count; |
353 | uchar byte; | 353 | uchar byte; |
354 | ulong crc; | 354 | ulong crc; |
355 | ulong err; | 355 | ulong err; |
356 | int j; | 356 | int j; |
357 | 357 | ||
358 | if (argc < 4) { | 358 | if (argc < 4) { |
359 | cmd_usage(cmdtp); | 359 | cmd_usage(cmdtp); |
360 | return 1; | 360 | return 1; |
361 | } | 361 | } |
362 | 362 | ||
363 | /* | 363 | /* |
364 | * Chip is always specified. | 364 | * Chip is always specified. |
365 | */ | 365 | */ |
366 | chip = simple_strtoul(argv[1], NULL, 16); | 366 | chip = simple_strtoul(argv[1], NULL, 16); |
367 | 367 | ||
368 | /* | 368 | /* |
369 | * Address is always specified. | 369 | * Address is always specified. |
370 | */ | 370 | */ |
371 | addr = simple_strtoul(argv[2], NULL, 16); | 371 | addr = simple_strtoul(argv[2], NULL, 16); |
372 | alen = 1; | 372 | alen = 1; |
373 | for (j = 0; j < 8; j++) { | 373 | for (j = 0; j < 8; j++) { |
374 | if (argv[2][j] == '.') { | 374 | if (argv[2][j] == '.') { |
375 | alen = argv[2][j+1] - '0'; | 375 | alen = argv[2][j+1] - '0'; |
376 | if (alen > 4) { | 376 | if (alen > 4) { |
377 | cmd_usage(cmdtp); | 377 | cmd_usage(cmdtp); |
378 | return 1; | 378 | return 1; |
379 | } | 379 | } |
380 | break; | 380 | break; |
381 | } else if (argv[2][j] == '\0') | 381 | } else if (argv[2][j] == '\0') |
382 | break; | 382 | break; |
383 | } | 383 | } |
384 | 384 | ||
385 | /* | 385 | /* |
386 | * Count is always specified | 386 | * Count is always specified |
387 | */ | 387 | */ |
388 | count = simple_strtoul(argv[3], NULL, 16); | 388 | count = simple_strtoul(argv[3], NULL, 16); |
389 | 389 | ||
390 | printf ("CRC32 for %08lx ... %08lx ==> ", addr, addr + count - 1); | 390 | printf ("CRC32 for %08lx ... %08lx ==> ", addr, addr + count - 1); |
391 | /* | 391 | /* |
392 | * CRC a byte at a time. This is going to be slooow, but hey, the | 392 | * CRC a byte at a time. This is going to be slooow, but hey, the |
393 | * memories are small and slow too so hopefully nobody notices. | 393 | * memories are small and slow too so hopefully nobody notices. |
394 | */ | 394 | */ |
395 | crc = 0; | 395 | crc = 0; |
396 | err = 0; | 396 | err = 0; |
397 | while (count-- > 0) { | 397 | while (count-- > 0) { |
398 | if (i2c_read(chip, addr, alen, &byte, 1) != 0) | 398 | if (i2c_read(chip, addr, alen, &byte, 1) != 0) |
399 | err++; | 399 | err++; |
400 | crc = crc32 (crc, &byte, 1); | 400 | crc = crc32 (crc, &byte, 1); |
401 | addr++; | 401 | addr++; |
402 | } | 402 | } |
403 | if (err > 0) | 403 | if (err > 0) |
404 | puts ("Error reading the chip,\n"); | 404 | puts ("Error reading the chip,\n"); |
405 | else | 405 | else |
406 | printf ("%08lx\n", crc); | 406 | printf ("%08lx\n", crc); |
407 | 407 | ||
408 | return 0; | 408 | return 0; |
409 | } | 409 | } |
410 | 410 | ||
411 | /* Modify memory. | 411 | /* Modify memory. |
412 | * | 412 | * |
413 | * Syntax: | 413 | * Syntax: |
414 | * i2c mm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} | 414 | * i2c mm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} |
415 | * i2c nm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} | 415 | * i2c nm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} |
416 | */ | 416 | */ |
417 | 417 | ||
418 | static int | 418 | static int |
419 | mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) | 419 | mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) |
420 | { | 420 | { |
421 | uchar chip; | 421 | uchar chip; |
422 | ulong addr; | 422 | ulong addr; |
423 | uint alen; | 423 | uint alen; |
424 | ulong data; | 424 | ulong data; |
425 | int size = 1; | 425 | int size = 1; |
426 | int nbytes; | 426 | int nbytes; |
427 | int j; | 427 | int j; |
428 | extern char console_buffer[]; | 428 | extern char console_buffer[]; |
429 | 429 | ||
430 | if (argc != 3) { | 430 | if (argc != 3) { |
431 | cmd_usage(cmdtp); | 431 | cmd_usage(cmdtp); |
432 | return 1; | 432 | return 1; |
433 | } | 433 | } |
434 | 434 | ||
435 | #ifdef CONFIG_BOOT_RETRY_TIME | 435 | #ifdef CONFIG_BOOT_RETRY_TIME |
436 | reset_cmd_timeout(); /* got a good command to get here */ | 436 | reset_cmd_timeout(); /* got a good command to get here */ |
437 | #endif | 437 | #endif |
438 | /* | 438 | /* |
439 | * We use the last specified parameters, unless new ones are | 439 | * We use the last specified parameters, unless new ones are |
440 | * entered. | 440 | * entered. |
441 | */ | 441 | */ |
442 | chip = i2c_mm_last_chip; | 442 | chip = i2c_mm_last_chip; |
443 | addr = i2c_mm_last_addr; | 443 | addr = i2c_mm_last_addr; |
444 | alen = i2c_mm_last_alen; | 444 | alen = i2c_mm_last_alen; |
445 | 445 | ||
446 | if ((flag & CMD_FLAG_REPEAT) == 0) { | 446 | if ((flag & CMD_FLAG_REPEAT) == 0) { |
447 | /* | 447 | /* |
448 | * New command specified. Check for a size specification. | 448 | * New command specified. Check for a size specification. |
449 | * Defaults to byte if no or incorrect specification. | 449 | * Defaults to byte if no or incorrect specification. |
450 | */ | 450 | */ |
451 | size = cmd_get_data_size(argv[0], 1); | 451 | size = cmd_get_data_size(argv[0], 1); |
452 | 452 | ||
453 | /* | 453 | /* |
454 | * Chip is always specified. | 454 | * Chip is always specified. |
455 | */ | 455 | */ |
456 | chip = simple_strtoul(argv[1], NULL, 16); | 456 | chip = simple_strtoul(argv[1], NULL, 16); |
457 | 457 | ||
458 | /* | 458 | /* |
459 | * Address is always specified. | 459 | * Address is always specified. |
460 | */ | 460 | */ |
461 | addr = simple_strtoul(argv[2], NULL, 16); | 461 | addr = simple_strtoul(argv[2], NULL, 16); |
462 | alen = 1; | 462 | alen = 1; |
463 | for (j = 0; j < 8; j++) { | 463 | for (j = 0; j < 8; j++) { |
464 | if (argv[2][j] == '.') { | 464 | if (argv[2][j] == '.') { |
465 | alen = argv[2][j+1] - '0'; | 465 | alen = argv[2][j+1] - '0'; |
466 | if (alen > 4) { | 466 | if (alen > 4) { |
467 | cmd_usage(cmdtp); | 467 | cmd_usage(cmdtp); |
468 | return 1; | 468 | return 1; |
469 | } | 469 | } |
470 | break; | 470 | break; |
471 | } else if (argv[2][j] == '\0') | 471 | } else if (argv[2][j] == '\0') |
472 | break; | 472 | break; |
473 | } | 473 | } |
474 | } | 474 | } |
475 | 475 | ||
476 | /* | 476 | /* |
477 | * Print the address, followed by value. Then accept input for | 477 | * Print the address, followed by value. Then accept input for |
478 | * the next value. A non-converted value exits. | 478 | * the next value. A non-converted value exits. |
479 | */ | 479 | */ |
480 | do { | 480 | do { |
481 | printf("%08lx:", addr); | 481 | printf("%08lx:", addr); |
482 | if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0) | 482 | if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0) |
483 | puts ("\nError reading the chip,\n"); | 483 | puts ("\nError reading the chip,\n"); |
484 | else { | 484 | else { |
485 | data = cpu_to_be32(data); | 485 | data = cpu_to_be32(data); |
486 | if (size == 1) | 486 | if (size == 1) |
487 | printf(" %02lx", (data >> 24) & 0x000000FF); | 487 | printf(" %02lx", (data >> 24) & 0x000000FF); |
488 | else if (size == 2) | 488 | else if (size == 2) |
489 | printf(" %04lx", (data >> 16) & 0x0000FFFF); | 489 | printf(" %04lx", (data >> 16) & 0x0000FFFF); |
490 | else | 490 | else |
491 | printf(" %08lx", data); | 491 | printf(" %08lx", data); |
492 | } | 492 | } |
493 | 493 | ||
494 | nbytes = readline (" ? "); | 494 | nbytes = readline (" ? "); |
495 | if (nbytes == 0) { | 495 | if (nbytes == 0) { |
496 | /* | 496 | /* |
497 | * <CR> pressed as only input, don't modify current | 497 | * <CR> pressed as only input, don't modify current |
498 | * location and move to next. | 498 | * location and move to next. |
499 | */ | 499 | */ |
500 | if (incrflag) | 500 | if (incrflag) |
501 | addr += size; | 501 | addr += size; |
502 | nbytes = size; | 502 | nbytes = size; |
503 | #ifdef CONFIG_BOOT_RETRY_TIME | 503 | #ifdef CONFIG_BOOT_RETRY_TIME |
504 | reset_cmd_timeout(); /* good enough to not time out */ | 504 | reset_cmd_timeout(); /* good enough to not time out */ |
505 | #endif | 505 | #endif |
506 | } | 506 | } |
507 | #ifdef CONFIG_BOOT_RETRY_TIME | 507 | #ifdef CONFIG_BOOT_RETRY_TIME |
508 | else if (nbytes == -2) | 508 | else if (nbytes == -2) |
509 | break; /* timed out, exit the command */ | 509 | break; /* timed out, exit the command */ |
510 | #endif | 510 | #endif |
511 | else { | 511 | else { |
512 | char *endp; | 512 | char *endp; |
513 | 513 | ||
514 | data = simple_strtoul(console_buffer, &endp, 16); | 514 | data = simple_strtoul(console_buffer, &endp, 16); |
515 | if (size == 1) | 515 | if (size == 1) |
516 | data = data << 24; | 516 | data = data << 24; |
517 | else if (size == 2) | 517 | else if (size == 2) |
518 | data = data << 16; | 518 | data = data << 16; |
519 | data = be32_to_cpu(data); | 519 | data = be32_to_cpu(data); |
520 | nbytes = endp - console_buffer; | 520 | nbytes = endp - console_buffer; |
521 | if (nbytes) { | 521 | if (nbytes) { |
522 | #ifdef CONFIG_BOOT_RETRY_TIME | 522 | #ifdef CONFIG_BOOT_RETRY_TIME |
523 | /* | 523 | /* |
524 | * good enough to not time out | 524 | * good enough to not time out |
525 | */ | 525 | */ |
526 | reset_cmd_timeout(); | 526 | reset_cmd_timeout(); |
527 | #endif | 527 | #endif |
528 | if (i2c_write(chip, addr, alen, (uchar *)&data, size) != 0) | 528 | if (i2c_write(chip, addr, alen, (uchar *)&data, size) != 0) |
529 | puts ("Error writing the chip.\n"); | 529 | puts ("Error writing the chip.\n"); |
530 | #ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS | 530 | #ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS |
531 | udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); | 531 | udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); |
532 | #endif | 532 | #endif |
533 | if (incrflag) | 533 | if (incrflag) |
534 | addr += size; | 534 | addr += size; |
535 | } | 535 | } |
536 | } | 536 | } |
537 | } while (nbytes); | 537 | } while (nbytes); |
538 | 538 | ||
539 | i2c_mm_last_chip = chip; | 539 | i2c_mm_last_chip = chip; |
540 | i2c_mm_last_addr = addr; | 540 | i2c_mm_last_addr = addr; |
541 | i2c_mm_last_alen = alen; | 541 | i2c_mm_last_alen = alen; |
542 | 542 | ||
543 | return 0; | 543 | return 0; |
544 | } | 544 | } |
545 | 545 | ||
546 | /* | 546 | /* |
547 | * Syntax: | 547 | * Syntax: |
548 | * i2c probe {addr}{.0, .1, .2} | 548 | * i2c probe {addr}{.0, .1, .2} |
549 | */ | 549 | */ |
550 | int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 550 | int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
551 | { | 551 | { |
552 | int j; | 552 | int j; |
553 | #if defined(CONFIG_SYS_I2C_NOPROBES) | 553 | #if defined(CONFIG_SYS_I2C_NOPROBES) |
554 | int k, skip; | 554 | int k, skip; |
555 | uchar bus = GET_BUS_NUM; | 555 | uchar bus = GET_BUS_NUM; |
556 | #endif /* NOPROBES */ | 556 | #endif /* NOPROBES */ |
557 | 557 | ||
558 | puts ("Valid chip addresses:"); | 558 | puts ("Valid chip addresses:"); |
559 | for (j = 0; j < 128; j++) { | 559 | for (j = 0; j < 128; j++) { |
560 | #if defined(CONFIG_SYS_I2C_NOPROBES) | 560 | #if defined(CONFIG_SYS_I2C_NOPROBES) |
561 | skip = 0; | 561 | skip = 0; |
562 | for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) { | 562 | for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) { |
563 | if (COMPARE_BUS(bus, k) && COMPARE_ADDR(j, k)) { | 563 | if (COMPARE_BUS(bus, k) && COMPARE_ADDR(j, k)) { |
564 | skip = 1; | 564 | skip = 1; |
565 | break; | 565 | break; |
566 | } | 566 | } |
567 | } | 567 | } |
568 | if (skip) | 568 | if (skip) |
569 | continue; | 569 | continue; |
570 | #endif | 570 | #endif |
571 | if (i2c_probe(j) == 0) | 571 | if (i2c_probe(j) == 0) |
572 | printf(" %02X", j); | 572 | printf(" %02X", j); |
573 | } | 573 | } |
574 | putc ('\n'); | 574 | putc ('\n'); |
575 | 575 | ||
576 | #if defined(CONFIG_SYS_I2C_NOPROBES) | 576 | #if defined(CONFIG_SYS_I2C_NOPROBES) |
577 | puts ("Excluded chip addresses:"); | 577 | puts ("Excluded chip addresses:"); |
578 | for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) { | 578 | for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) { |
579 | if (COMPARE_BUS(bus,k)) | 579 | if (COMPARE_BUS(bus,k)) |
580 | printf(" %02X", NO_PROBE_ADDR(k)); | 580 | printf(" %02X", NO_PROBE_ADDR(k)); |
581 | } | 581 | } |
582 | putc ('\n'); | 582 | putc ('\n'); |
583 | #endif | 583 | #endif |
584 | 584 | ||
585 | return 0; | 585 | return 0; |
586 | } | 586 | } |
587 | 587 | ||
588 | /* | 588 | /* |
589 | * Syntax: | 589 | * Syntax: |
590 | * i2c loop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}] | 590 | * i2c loop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}] |
591 | * {length} - Number of bytes to read | 591 | * {length} - Number of bytes to read |
592 | * {delay} - A DECIMAL number and defaults to 1000 uSec | 592 | * {delay} - A DECIMAL number and defaults to 1000 uSec |
593 | */ | 593 | */ |
594 | int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 594 | int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
595 | { | 595 | { |
596 | u_char chip; | 596 | u_char chip; |
597 | ulong alen; | 597 | ulong alen; |
598 | uint addr; | 598 | uint addr; |
599 | uint length; | 599 | uint length; |
600 | u_char bytes[16]; | 600 | u_char bytes[16]; |
601 | int delay; | 601 | int delay; |
602 | int j; | 602 | int j; |
603 | 603 | ||
604 | if (argc < 3) { | 604 | if (argc < 3) { |
605 | cmd_usage(cmdtp); | 605 | cmd_usage(cmdtp); |
606 | return 1; | 606 | return 1; |
607 | } | 607 | } |
608 | 608 | ||
609 | /* | 609 | /* |
610 | * Chip is always specified. | 610 | * Chip is always specified. |
611 | */ | 611 | */ |
612 | chip = simple_strtoul(argv[1], NULL, 16); | 612 | chip = simple_strtoul(argv[1], NULL, 16); |
613 | 613 | ||
614 | /* | 614 | /* |
615 | * Address is always specified. | 615 | * Address is always specified. |
616 | */ | 616 | */ |
617 | addr = simple_strtoul(argv[2], NULL, 16); | 617 | addr = simple_strtoul(argv[2], NULL, 16); |
618 | alen = 1; | 618 | alen = 1; |
619 | for (j = 0; j < 8; j++) { | 619 | for (j = 0; j < 8; j++) { |
620 | if (argv[2][j] == '.') { | 620 | if (argv[2][j] == '.') { |
621 | alen = argv[2][j+1] - '0'; | 621 | alen = argv[2][j+1] - '0'; |
622 | if (alen > 4) { | 622 | if (alen > 4) { |
623 | cmd_usage(cmdtp); | 623 | cmd_usage(cmdtp); |
624 | return 1; | 624 | return 1; |
625 | } | 625 | } |
626 | break; | 626 | break; |
627 | } else if (argv[2][j] == '\0') | 627 | } else if (argv[2][j] == '\0') |
628 | break; | 628 | break; |
629 | } | 629 | } |
630 | 630 | ||
631 | /* | 631 | /* |
632 | * Length is the number of objects, not number of bytes. | 632 | * Length is the number of objects, not number of bytes. |
633 | */ | 633 | */ |
634 | length = 1; | 634 | length = 1; |
635 | length = simple_strtoul(argv[3], NULL, 16); | 635 | length = simple_strtoul(argv[3], NULL, 16); |
636 | if (length > sizeof(bytes)) | 636 | if (length > sizeof(bytes)) |
637 | length = sizeof(bytes); | 637 | length = sizeof(bytes); |
638 | 638 | ||
639 | /* | 639 | /* |
640 | * The delay time (uSec) is optional. | 640 | * The delay time (uSec) is optional. |
641 | */ | 641 | */ |
642 | delay = 1000; | 642 | delay = 1000; |
643 | if (argc > 3) | 643 | if (argc > 3) |
644 | delay = simple_strtoul(argv[4], NULL, 10); | 644 | delay = simple_strtoul(argv[4], NULL, 10); |
645 | /* | 645 | /* |
646 | * Run the loop... | 646 | * Run the loop... |
647 | */ | 647 | */ |
648 | while (1) { | 648 | while (1) { |
649 | if (i2c_read(chip, addr, alen, bytes, length) != 0) | 649 | if (i2c_read(chip, addr, alen, bytes, length) != 0) |
650 | puts ("Error reading the chip.\n"); | 650 | puts ("Error reading the chip.\n"); |
651 | udelay(delay); | 651 | udelay(delay); |
652 | } | 652 | } |
653 | 653 | ||
654 | /* NOTREACHED */ | 654 | /* NOTREACHED */ |
655 | return 0; | 655 | return 0; |
656 | } | 656 | } |
657 | 657 | ||
658 | /* | 658 | /* |
659 | * The SDRAM command is separately configured because many | 659 | * The SDRAM command is separately configured because many |
660 | * (most?) embedded boards don't use SDRAM DIMMs. | 660 | * (most?) embedded boards don't use SDRAM DIMMs. |
661 | */ | 661 | */ |
662 | #if defined(CONFIG_CMD_SDRAM) | 662 | #if defined(CONFIG_CMD_SDRAM) |
663 | static void print_ddr2_tcyc (u_char const b) | 663 | static void print_ddr2_tcyc (u_char const b) |
664 | { | 664 | { |
665 | printf ("%d.", (b >> 4) & 0x0F); | 665 | printf ("%d.", (b >> 4) & 0x0F); |
666 | switch (b & 0x0F) { | 666 | switch (b & 0x0F) { |
667 | case 0x0: | 667 | case 0x0: |
668 | case 0x1: | 668 | case 0x1: |
669 | case 0x2: | 669 | case 0x2: |
670 | case 0x3: | 670 | case 0x3: |
671 | case 0x4: | 671 | case 0x4: |
672 | case 0x5: | 672 | case 0x5: |
673 | case 0x6: | 673 | case 0x6: |
674 | case 0x7: | 674 | case 0x7: |
675 | case 0x8: | 675 | case 0x8: |
676 | case 0x9: | 676 | case 0x9: |
677 | printf ("%d ns\n", b & 0x0F); | 677 | printf ("%d ns\n", b & 0x0F); |
678 | break; | 678 | break; |
679 | case 0xA: | 679 | case 0xA: |
680 | puts ("25 ns\n"); | 680 | puts ("25 ns\n"); |
681 | break; | 681 | break; |
682 | case 0xB: | 682 | case 0xB: |
683 | puts ("33 ns\n"); | 683 | puts ("33 ns\n"); |
684 | break; | 684 | break; |
685 | case 0xC: | 685 | case 0xC: |
686 | puts ("66 ns\n"); | 686 | puts ("66 ns\n"); |
687 | break; | 687 | break; |
688 | case 0xD: | 688 | case 0xD: |
689 | puts ("75 ns\n"); | 689 | puts ("75 ns\n"); |
690 | break; | 690 | break; |
691 | default: | 691 | default: |
692 | puts ("?? ns\n"); | 692 | puts ("?? ns\n"); |
693 | break; | 693 | break; |
694 | } | 694 | } |
695 | } | 695 | } |
696 | 696 | ||
697 | static void decode_bits (u_char const b, char const *str[], int const do_once) | 697 | static void decode_bits (u_char const b, char const *str[], int const do_once) |
698 | { | 698 | { |
699 | u_char mask; | 699 | u_char mask; |
700 | 700 | ||
701 | for (mask = 0x80; mask != 0x00; mask >>= 1, ++str) { | 701 | for (mask = 0x80; mask != 0x00; mask >>= 1, ++str) { |
702 | if (b & mask) { | 702 | if (b & mask) { |
703 | puts (*str); | 703 | puts (*str); |
704 | if (do_once) | 704 | if (do_once) |
705 | return; | 705 | return; |
706 | } | 706 | } |
707 | } | 707 | } |
708 | } | 708 | } |
709 | 709 | ||
710 | /* | 710 | /* |
711 | * Syntax: | 711 | * Syntax: |
712 | * i2c sdram {i2c_chip} | 712 | * i2c sdram {i2c_chip} |
713 | */ | 713 | */ |
714 | int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 714 | int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
715 | { | 715 | { |
716 | enum { unknown, EDO, SDRAM, DDR2 } type; | 716 | enum { unknown, EDO, SDRAM, DDR2 } type; |
717 | 717 | ||
718 | u_char chip; | 718 | u_char chip; |
719 | u_char data[128]; | 719 | u_char data[128]; |
720 | u_char cksum; | 720 | u_char cksum; |
721 | int j; | 721 | int j; |
722 | 722 | ||
723 | static const char *decode_CAS_DDR2[] = { | 723 | static const char *decode_CAS_DDR2[] = { |
724 | " TBD", " 6", " 5", " 4", " 3", " 2", " TBD", " TBD" | 724 | " TBD", " 6", " 5", " 4", " 3", " 2", " TBD", " TBD" |
725 | }; | 725 | }; |
726 | 726 | ||
727 | static const char *decode_CAS_default[] = { | 727 | static const char *decode_CAS_default[] = { |
728 | " TBD", " 7", " 6", " 5", " 4", " 3", " 2", " 1" | 728 | " TBD", " 7", " 6", " 5", " 4", " 3", " 2", " 1" |
729 | }; | 729 | }; |
730 | 730 | ||
731 | static const char *decode_CS_WE_default[] = { | 731 | static const char *decode_CS_WE_default[] = { |
732 | " TBD", " 6", " 5", " 4", " 3", " 2", " 1", " 0" | 732 | " TBD", " 6", " 5", " 4", " 3", " 2", " 1", " 0" |
733 | }; | 733 | }; |
734 | 734 | ||
735 | static const char *decode_byte21_default[] = { | 735 | static const char *decode_byte21_default[] = { |
736 | " TBD (bit 7)\n", | 736 | " TBD (bit 7)\n", |
737 | " Redundant row address\n", | 737 | " Redundant row address\n", |
738 | " Differential clock input\n", | 738 | " Differential clock input\n", |
739 | " Registerd DQMB inputs\n", | 739 | " Registerd DQMB inputs\n", |
740 | " Buffered DQMB inputs\n", | 740 | " Buffered DQMB inputs\n", |
741 | " On-card PLL\n", | 741 | " On-card PLL\n", |
742 | " Registered address/control lines\n", | 742 | " Registered address/control lines\n", |
743 | " Buffered address/control lines\n" | 743 | " Buffered address/control lines\n" |
744 | }; | 744 | }; |
745 | 745 | ||
746 | static const char *decode_byte22_DDR2[] = { | 746 | static const char *decode_byte22_DDR2[] = { |
747 | " TBD (bit 7)\n", | 747 | " TBD (bit 7)\n", |
748 | " TBD (bit 6)\n", | 748 | " TBD (bit 6)\n", |
749 | " TBD (bit 5)\n", | 749 | " TBD (bit 5)\n", |
750 | " TBD (bit 4)\n", | 750 | " TBD (bit 4)\n", |
751 | " TBD (bit 3)\n", | 751 | " TBD (bit 3)\n", |
752 | " Supports partial array self refresh\n", | 752 | " Supports partial array self refresh\n", |
753 | " Supports 50 ohm ODT\n", | 753 | " Supports 50 ohm ODT\n", |
754 | " Supports weak driver\n" | 754 | " Supports weak driver\n" |
755 | }; | 755 | }; |
756 | 756 | ||
757 | static const char *decode_row_density_DDR2[] = { | 757 | static const char *decode_row_density_DDR2[] = { |
758 | "512 MiB", "256 MiB", "128 MiB", "16 GiB", | 758 | "512 MiB", "256 MiB", "128 MiB", "16 GiB", |
759 | "8 GiB", "4 GiB", "2 GiB", "1 GiB" | 759 | "8 GiB", "4 GiB", "2 GiB", "1 GiB" |
760 | }; | 760 | }; |
761 | 761 | ||
762 | static const char *decode_row_density_default[] = { | 762 | static const char *decode_row_density_default[] = { |
763 | "512 MiB", "256 MiB", "128 MiB", "64 MiB", | 763 | "512 MiB", "256 MiB", "128 MiB", "64 MiB", |
764 | "32 MiB", "16 MiB", "8 MiB", "4 MiB" | 764 | "32 MiB", "16 MiB", "8 MiB", "4 MiB" |
765 | }; | 765 | }; |
766 | 766 | ||
767 | if (argc < 2) { | 767 | if (argc < 2) { |
768 | cmd_usage(cmdtp); | 768 | cmd_usage(cmdtp); |
769 | return 1; | 769 | return 1; |
770 | } | 770 | } |
771 | /* | 771 | /* |
772 | * Chip is always specified. | 772 | * Chip is always specified. |
773 | */ | 773 | */ |
774 | chip = simple_strtoul (argv[1], NULL, 16); | 774 | chip = simple_strtoul (argv[1], NULL, 16); |
775 | 775 | ||
776 | if (i2c_read (chip, 0, 1, data, sizeof (data)) != 0) { | 776 | if (i2c_read (chip, 0, 1, data, sizeof (data)) != 0) { |
777 | puts ("No SDRAM Serial Presence Detect found.\n"); | 777 | puts ("No SDRAM Serial Presence Detect found.\n"); |
778 | return 1; | 778 | return 1; |
779 | } | 779 | } |
780 | 780 | ||
781 | cksum = 0; | 781 | cksum = 0; |
782 | for (j = 0; j < 63; j++) { | 782 | for (j = 0; j < 63; j++) { |
783 | cksum += data[j]; | 783 | cksum += data[j]; |
784 | } | 784 | } |
785 | if (cksum != data[63]) { | 785 | if (cksum != data[63]) { |
786 | printf ("WARNING: Configuration data checksum failure:\n" | 786 | printf ("WARNING: Configuration data checksum failure:\n" |
787 | " is 0x%02x, calculated 0x%02x\n", data[63], cksum); | 787 | " is 0x%02x, calculated 0x%02x\n", data[63], cksum); |
788 | } | 788 | } |
789 | printf ("SPD data revision %d.%d\n", | 789 | printf ("SPD data revision %d.%d\n", |
790 | (data[62] >> 4) & 0x0F, data[62] & 0x0F); | 790 | (data[62] >> 4) & 0x0F, data[62] & 0x0F); |
791 | printf ("Bytes used 0x%02X\n", data[0]); | 791 | printf ("Bytes used 0x%02X\n", data[0]); |
792 | printf ("Serial memory size 0x%02X\n", 1 << data[1]); | 792 | printf ("Serial memory size 0x%02X\n", 1 << data[1]); |
793 | 793 | ||
794 | puts ("Memory type "); | 794 | puts ("Memory type "); |
795 | switch (data[2]) { | 795 | switch (data[2]) { |
796 | case 2: | 796 | case 2: |
797 | type = EDO; | 797 | type = EDO; |
798 | puts ("EDO\n"); | 798 | puts ("EDO\n"); |
799 | break; | 799 | break; |
800 | case 4: | 800 | case 4: |
801 | type = SDRAM; | 801 | type = SDRAM; |
802 | puts ("SDRAM\n"); | 802 | puts ("SDRAM\n"); |
803 | break; | 803 | break; |
804 | case 8: | 804 | case 8: |
805 | type = DDR2; | 805 | type = DDR2; |
806 | puts ("DDR2\n"); | 806 | puts ("DDR2\n"); |
807 | break; | 807 | break; |
808 | default: | 808 | default: |
809 | type = unknown; | 809 | type = unknown; |
810 | puts ("unknown\n"); | 810 | puts ("unknown\n"); |
811 | break; | 811 | break; |
812 | } | 812 | } |
813 | 813 | ||
814 | puts ("Row address bits "); | 814 | puts ("Row address bits "); |
815 | if ((data[3] & 0x00F0) == 0) | 815 | if ((data[3] & 0x00F0) == 0) |
816 | printf ("%d\n", data[3] & 0x0F); | 816 | printf ("%d\n", data[3] & 0x0F); |
817 | else | 817 | else |
818 | printf ("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F); | 818 | printf ("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F); |
819 | 819 | ||
820 | puts ("Column address bits "); | 820 | puts ("Column address bits "); |
821 | if ((data[4] & 0x00F0) == 0) | 821 | if ((data[4] & 0x00F0) == 0) |
822 | printf ("%d\n", data[4] & 0x0F); | 822 | printf ("%d\n", data[4] & 0x0F); |
823 | else | 823 | else |
824 | printf ("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F); | 824 | printf ("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F); |
825 | 825 | ||
826 | switch (type) { | 826 | switch (type) { |
827 | case DDR2: | 827 | case DDR2: |
828 | printf ("Number of ranks %d\n", | 828 | printf ("Number of ranks %d\n", |
829 | (data[5] & 0x07) + 1); | 829 | (data[5] & 0x07) + 1); |
830 | break; | 830 | break; |
831 | default: | 831 | default: |
832 | printf ("Module rows %d\n", data[5]); | 832 | printf ("Module rows %d\n", data[5]); |
833 | break; | 833 | break; |
834 | } | 834 | } |
835 | 835 | ||
836 | switch (type) { | 836 | switch (type) { |
837 | case DDR2: | 837 | case DDR2: |
838 | printf ("Module data width %d bits\n", data[6]); | 838 | printf ("Module data width %d bits\n", data[6]); |
839 | break; | 839 | break; |
840 | default: | 840 | default: |
841 | printf ("Module data width %d bits\n", | 841 | printf ("Module data width %d bits\n", |
842 | (data[7] << 8) | data[6]); | 842 | (data[7] << 8) | data[6]); |
843 | break; | 843 | break; |
844 | } | 844 | } |
845 | 845 | ||
846 | puts ("Interface signal levels "); | 846 | puts ("Interface signal levels "); |
847 | switch(data[8]) { | 847 | switch(data[8]) { |
848 | case 0: puts ("TTL 5.0 V\n"); break; | 848 | case 0: puts ("TTL 5.0 V\n"); break; |
849 | case 1: puts ("LVTTL\n"); break; | 849 | case 1: puts ("LVTTL\n"); break; |
850 | case 2: puts ("HSTL 1.5 V\n"); break; | 850 | case 2: puts ("HSTL 1.5 V\n"); break; |
851 | case 3: puts ("SSTL 3.3 V\n"); break; | 851 | case 3: puts ("SSTL 3.3 V\n"); break; |
852 | case 4: puts ("SSTL 2.5 V\n"); break; | 852 | case 4: puts ("SSTL 2.5 V\n"); break; |
853 | case 5: puts ("SSTL 1.8 V\n"); break; | 853 | case 5: puts ("SSTL 1.8 V\n"); break; |
854 | default: puts ("unknown\n"); break; | 854 | default: puts ("unknown\n"); break; |
855 | } | 855 | } |
856 | 856 | ||
857 | switch (type) { | 857 | switch (type) { |
858 | case DDR2: | 858 | case DDR2: |
859 | printf ("SDRAM cycle time "); | 859 | printf ("SDRAM cycle time "); |
860 | print_ddr2_tcyc (data[9]); | 860 | print_ddr2_tcyc (data[9]); |
861 | break; | 861 | break; |
862 | default: | 862 | default: |
863 | printf ("SDRAM cycle time %d.%d ns\n", | 863 | printf ("SDRAM cycle time %d.%d ns\n", |
864 | (data[9] >> 4) & 0x0F, data[9] & 0x0F); | 864 | (data[9] >> 4) & 0x0F, data[9] & 0x0F); |
865 | break; | 865 | break; |
866 | } | 866 | } |
867 | 867 | ||
868 | switch (type) { | 868 | switch (type) { |
869 | case DDR2: | 869 | case DDR2: |
870 | printf ("SDRAM access time 0.%d%d ns\n", | 870 | printf ("SDRAM access time 0.%d%d ns\n", |
871 | (data[10] >> 4) & 0x0F, data[10] & 0x0F); | 871 | (data[10] >> 4) & 0x0F, data[10] & 0x0F); |
872 | break; | 872 | break; |
873 | default: | 873 | default: |
874 | printf ("SDRAM access time %d.%d ns\n", | 874 | printf ("SDRAM access time %d.%d ns\n", |
875 | (data[10] >> 4) & 0x0F, data[10] & 0x0F); | 875 | (data[10] >> 4) & 0x0F, data[10] & 0x0F); |
876 | break; | 876 | break; |
877 | } | 877 | } |
878 | 878 | ||
879 | puts ("EDC configuration "); | 879 | puts ("EDC configuration "); |
880 | switch (data[11]) { | 880 | switch (data[11]) { |
881 | case 0: puts ("None\n"); break; | 881 | case 0: puts ("None\n"); break; |
882 | case 1: puts ("Parity\n"); break; | 882 | case 1: puts ("Parity\n"); break; |
883 | case 2: puts ("ECC\n"); break; | 883 | case 2: puts ("ECC\n"); break; |
884 | default: puts ("unknown\n"); break; | 884 | default: puts ("unknown\n"); break; |
885 | } | 885 | } |
886 | 886 | ||
887 | if ((data[12] & 0x80) == 0) | 887 | if ((data[12] & 0x80) == 0) |
888 | puts ("No self refresh, rate "); | 888 | puts ("No self refresh, rate "); |
889 | else | 889 | else |
890 | puts ("Self refresh, rate "); | 890 | puts ("Self refresh, rate "); |
891 | 891 | ||
892 | switch(data[12] & 0x7F) { | 892 | switch(data[12] & 0x7F) { |
893 | case 0: puts ("15.625 us\n"); break; | 893 | case 0: puts ("15.625 us\n"); break; |
894 | case 1: puts ("3.9 us\n"); break; | 894 | case 1: puts ("3.9 us\n"); break; |
895 | case 2: puts ("7.8 us\n"); break; | 895 | case 2: puts ("7.8 us\n"); break; |
896 | case 3: puts ("31.3 us\n"); break; | 896 | case 3: puts ("31.3 us\n"); break; |
897 | case 4: puts ("62.5 us\n"); break; | 897 | case 4: puts ("62.5 us\n"); break; |
898 | case 5: puts ("125 us\n"); break; | 898 | case 5: puts ("125 us\n"); break; |
899 | default: puts ("unknown\n"); break; | 899 | default: puts ("unknown\n"); break; |
900 | } | 900 | } |
901 | 901 | ||
902 | switch (type) { | 902 | switch (type) { |
903 | case DDR2: | 903 | case DDR2: |
904 | printf ("SDRAM width (primary) %d\n", data[13]); | 904 | printf ("SDRAM width (primary) %d\n", data[13]); |
905 | break; | 905 | break; |
906 | default: | 906 | default: |
907 | printf ("SDRAM width (primary) %d\n", data[13] & 0x7F); | 907 | printf ("SDRAM width (primary) %d\n", data[13] & 0x7F); |
908 | if ((data[13] & 0x80) != 0) { | 908 | if ((data[13] & 0x80) != 0) { |
909 | printf (" (second bank) %d\n", | 909 | printf (" (second bank) %d\n", |
910 | 2 * (data[13] & 0x7F)); | 910 | 2 * (data[13] & 0x7F)); |
911 | } | 911 | } |
912 | break; | 912 | break; |
913 | } | 913 | } |
914 | 914 | ||
915 | switch (type) { | 915 | switch (type) { |
916 | case DDR2: | 916 | case DDR2: |
917 | if (data[14] != 0) | 917 | if (data[14] != 0) |
918 | printf ("EDC width %d\n", data[14]); | 918 | printf ("EDC width %d\n", data[14]); |
919 | break; | 919 | break; |
920 | default: | 920 | default: |
921 | if (data[14] != 0) { | 921 | if (data[14] != 0) { |
922 | printf ("EDC width %d\n", | 922 | printf ("EDC width %d\n", |
923 | data[14] & 0x7F); | 923 | data[14] & 0x7F); |
924 | 924 | ||
925 | if ((data[14] & 0x80) != 0) { | 925 | if ((data[14] & 0x80) != 0) { |
926 | printf (" (second bank) %d\n", | 926 | printf (" (second bank) %d\n", |
927 | 2 * (data[14] & 0x7F)); | 927 | 2 * (data[14] & 0x7F)); |
928 | } | 928 | } |
929 | } | 929 | } |
930 | break; | 930 | break; |
931 | } | 931 | } |
932 | 932 | ||
933 | if (DDR2 != type) { | 933 | if (DDR2 != type) { |
934 | printf ("Min clock delay, back-to-back random column addresses " | 934 | printf ("Min clock delay, back-to-back random column addresses " |
935 | "%d\n", data[15]); | 935 | "%d\n", data[15]); |
936 | } | 936 | } |
937 | 937 | ||
938 | puts ("Burst length(s) "); | 938 | puts ("Burst length(s) "); |
939 | if (data[16] & 0x80) puts (" Page"); | 939 | if (data[16] & 0x80) puts (" Page"); |
940 | if (data[16] & 0x08) puts (" 8"); | 940 | if (data[16] & 0x08) puts (" 8"); |
941 | if (data[16] & 0x04) puts (" 4"); | 941 | if (data[16] & 0x04) puts (" 4"); |
942 | if (data[16] & 0x02) puts (" 2"); | 942 | if (data[16] & 0x02) puts (" 2"); |
943 | if (data[16] & 0x01) puts (" 1"); | 943 | if (data[16] & 0x01) puts (" 1"); |
944 | putc ('\n'); | 944 | putc ('\n'); |
945 | printf ("Number of banks %d\n", data[17]); | 945 | printf ("Number of banks %d\n", data[17]); |
946 | 946 | ||
947 | switch (type) { | 947 | switch (type) { |
948 | case DDR2: | 948 | case DDR2: |
949 | puts ("CAS latency(s) "); | 949 | puts ("CAS latency(s) "); |
950 | decode_bits (data[18], decode_CAS_DDR2, 0); | 950 | decode_bits (data[18], decode_CAS_DDR2, 0); |
951 | putc ('\n'); | 951 | putc ('\n'); |
952 | break; | 952 | break; |
953 | default: | 953 | default: |
954 | puts ("CAS latency(s) "); | 954 | puts ("CAS latency(s) "); |
955 | decode_bits (data[18], decode_CAS_default, 0); | 955 | decode_bits (data[18], decode_CAS_default, 0); |
956 | putc ('\n'); | 956 | putc ('\n'); |
957 | break; | 957 | break; |
958 | } | 958 | } |
959 | 959 | ||
960 | if (DDR2 != type) { | 960 | if (DDR2 != type) { |
961 | puts ("CS latency(s) "); | 961 | puts ("CS latency(s) "); |
962 | decode_bits (data[19], decode_CS_WE_default, 0); | 962 | decode_bits (data[19], decode_CS_WE_default, 0); |
963 | putc ('\n'); | 963 | putc ('\n'); |
964 | } | 964 | } |
965 | 965 | ||
966 | if (DDR2 != type) { | 966 | if (DDR2 != type) { |
967 | puts ("WE latency(s) "); | 967 | puts ("WE latency(s) "); |
968 | decode_bits (data[20], decode_CS_WE_default, 0); | 968 | decode_bits (data[20], decode_CS_WE_default, 0); |
969 | putc ('\n'); | 969 | putc ('\n'); |
970 | } | 970 | } |
971 | 971 | ||
972 | switch (type) { | 972 | switch (type) { |
973 | case DDR2: | 973 | case DDR2: |
974 | puts ("Module attributes:\n"); | 974 | puts ("Module attributes:\n"); |
975 | if (data[21] & 0x80) | 975 | if (data[21] & 0x80) |
976 | puts (" TBD (bit 7)\n"); | 976 | puts (" TBD (bit 7)\n"); |
977 | if (data[21] & 0x40) | 977 | if (data[21] & 0x40) |
978 | puts (" Analysis probe installed\n"); | 978 | puts (" Analysis probe installed\n"); |
979 | if (data[21] & 0x20) | 979 | if (data[21] & 0x20) |
980 | puts (" TBD (bit 5)\n"); | 980 | puts (" TBD (bit 5)\n"); |
981 | if (data[21] & 0x10) | 981 | if (data[21] & 0x10) |
982 | puts (" FET switch external enable\n"); | 982 | puts (" FET switch external enable\n"); |
983 | printf (" %d PLLs on DIMM\n", (data[21] >> 2) & 0x03); | 983 | printf (" %d PLLs on DIMM\n", (data[21] >> 2) & 0x03); |
984 | if (data[20] & 0x11) { | 984 | if (data[20] & 0x11) { |
985 | printf (" %d active registers on DIMM\n", | 985 | printf (" %d active registers on DIMM\n", |
986 | (data[21] & 0x03) + 1); | 986 | (data[21] & 0x03) + 1); |
987 | } | 987 | } |
988 | break; | 988 | break; |
989 | default: | 989 | default: |
990 | puts ("Module attributes:\n"); | 990 | puts ("Module attributes:\n"); |
991 | if (!data[21]) | 991 | if (!data[21]) |
992 | puts (" (none)\n"); | 992 | puts (" (none)\n"); |
993 | else | 993 | else |
994 | decode_bits (data[21], decode_byte21_default, 0); | 994 | decode_bits (data[21], decode_byte21_default, 0); |
995 | break; | 995 | break; |
996 | } | 996 | } |
997 | 997 | ||
998 | switch (type) { | 998 | switch (type) { |
999 | case DDR2: | 999 | case DDR2: |
1000 | decode_bits (data[22], decode_byte22_DDR2, 0); | 1000 | decode_bits (data[22], decode_byte22_DDR2, 0); |
1001 | break; | 1001 | break; |
1002 | default: | 1002 | default: |
1003 | puts ("Device attributes:\n"); | 1003 | puts ("Device attributes:\n"); |
1004 | if (data[22] & 0x80) puts (" TBD (bit 7)\n"); | 1004 | if (data[22] & 0x80) puts (" TBD (bit 7)\n"); |
1005 | if (data[22] & 0x40) puts (" TBD (bit 6)\n"); | 1005 | if (data[22] & 0x40) puts (" TBD (bit 6)\n"); |
1006 | if (data[22] & 0x20) puts (" Upper Vcc tolerance 5%\n"); | 1006 | if (data[22] & 0x20) puts (" Upper Vcc tolerance 5%\n"); |
1007 | else puts (" Upper Vcc tolerance 10%\n"); | 1007 | else puts (" Upper Vcc tolerance 10%\n"); |
1008 | if (data[22] & 0x10) puts (" Lower Vcc tolerance 5%\n"); | 1008 | if (data[22] & 0x10) puts (" Lower Vcc tolerance 5%\n"); |
1009 | else puts (" Lower Vcc tolerance 10%\n"); | 1009 | else puts (" Lower Vcc tolerance 10%\n"); |
1010 | if (data[22] & 0x08) puts (" Supports write1/read burst\n"); | 1010 | if (data[22] & 0x08) puts (" Supports write1/read burst\n"); |
1011 | if (data[22] & 0x04) puts (" Supports precharge all\n"); | 1011 | if (data[22] & 0x04) puts (" Supports precharge all\n"); |
1012 | if (data[22] & 0x02) puts (" Supports auto precharge\n"); | 1012 | if (data[22] & 0x02) puts (" Supports auto precharge\n"); |
1013 | if (data[22] & 0x01) puts (" Supports early RAS# precharge\n"); | 1013 | if (data[22] & 0x01) puts (" Supports early RAS# precharge\n"); |
1014 | break; | 1014 | break; |
1015 | } | 1015 | } |
1016 | 1016 | ||
1017 | switch (type) { | 1017 | switch (type) { |
1018 | case DDR2: | 1018 | case DDR2: |
1019 | printf ("SDRAM cycle time (2nd highest CAS latency) "); | 1019 | printf ("SDRAM cycle time (2nd highest CAS latency) "); |
1020 | print_ddr2_tcyc (data[23]); | 1020 | print_ddr2_tcyc (data[23]); |
1021 | break; | 1021 | break; |
1022 | default: | 1022 | default: |
1023 | printf ("SDRAM cycle time (2nd highest CAS latency) %d." | 1023 | printf ("SDRAM cycle time (2nd highest CAS latency) %d." |
1024 | "%d ns\n", (data[23] >> 4) & 0x0F, data[23] & 0x0F); | 1024 | "%d ns\n", (data[23] >> 4) & 0x0F, data[23] & 0x0F); |
1025 | break; | 1025 | break; |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | switch (type) { | 1028 | switch (type) { |
1029 | case DDR2: | 1029 | case DDR2: |
1030 | printf ("SDRAM access from clock (2nd highest CAS latency) 0." | 1030 | printf ("SDRAM access from clock (2nd highest CAS latency) 0." |
1031 | "%d%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F); | 1031 | "%d%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F); |
1032 | break; | 1032 | break; |
1033 | default: | 1033 | default: |
1034 | printf ("SDRAM access from clock (2nd highest CAS latency) %d." | 1034 | printf ("SDRAM access from clock (2nd highest CAS latency) %d." |
1035 | "%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F); | 1035 | "%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F); |
1036 | break; | 1036 | break; |
1037 | } | 1037 | } |
1038 | 1038 | ||
1039 | switch (type) { | 1039 | switch (type) { |
1040 | case DDR2: | 1040 | case DDR2: |
1041 | printf ("SDRAM cycle time (3rd highest CAS latency) "); | 1041 | printf ("SDRAM cycle time (3rd highest CAS latency) "); |
1042 | print_ddr2_tcyc (data[25]); | 1042 | print_ddr2_tcyc (data[25]); |
1043 | break; | 1043 | break; |
1044 | default: | 1044 | default: |
1045 | printf ("SDRAM cycle time (3rd highest CAS latency) %d." | 1045 | printf ("SDRAM cycle time (3rd highest CAS latency) %d." |
1046 | "%d ns\n", (data[25] >> 4) & 0x0F, data[25] & 0x0F); | 1046 | "%d ns\n", (data[25] >> 4) & 0x0F, data[25] & 0x0F); |
1047 | break; | 1047 | break; |
1048 | } | 1048 | } |
1049 | 1049 | ||
1050 | switch (type) { | 1050 | switch (type) { |
1051 | case DDR2: | 1051 | case DDR2: |
1052 | printf ("SDRAM access from clock (3rd highest CAS latency) 0." | 1052 | printf ("SDRAM access from clock (3rd highest CAS latency) 0." |
1053 | "%d%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F); | 1053 | "%d%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F); |
1054 | break; | 1054 | break; |
1055 | default: | 1055 | default: |
1056 | printf ("SDRAM access from clock (3rd highest CAS latency) %d." | 1056 | printf ("SDRAM access from clock (3rd highest CAS latency) %d." |
1057 | "%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F); | 1057 | "%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F); |
1058 | break; | 1058 | break; |
1059 | } | 1059 | } |
1060 | 1060 | ||
1061 | switch (type) { | 1061 | switch (type) { |
1062 | case DDR2: | 1062 | case DDR2: |
1063 | printf ("Minimum row precharge %d.%02d ns\n", | 1063 | printf ("Minimum row precharge %d.%02d ns\n", |
1064 | (data[27] >> 2) & 0x3F, 25 * (data[27] & 0x03)); | 1064 | (data[27] >> 2) & 0x3F, 25 * (data[27] & 0x03)); |
1065 | break; | 1065 | break; |
1066 | default: | 1066 | default: |
1067 | printf ("Minimum row precharge %d ns\n", data[27]); | 1067 | printf ("Minimum row precharge %d ns\n", data[27]); |
1068 | break; | 1068 | break; |
1069 | } | 1069 | } |
1070 | 1070 | ||
1071 | switch (type) { | 1071 | switch (type) { |
1072 | case DDR2: | 1072 | case DDR2: |
1073 | printf ("Row active to row active min %d.%02d ns\n", | 1073 | printf ("Row active to row active min %d.%02d ns\n", |
1074 | (data[28] >> 2) & 0x3F, 25 * (data[28] & 0x03)); | 1074 | (data[28] >> 2) & 0x3F, 25 * (data[28] & 0x03)); |
1075 | break; | 1075 | break; |
1076 | default: | 1076 | default: |
1077 | printf ("Row active to row active min %d ns\n", data[28]); | 1077 | printf ("Row active to row active min %d ns\n", data[28]); |
1078 | break; | 1078 | break; |
1079 | } | 1079 | } |
1080 | 1080 | ||
1081 | switch (type) { | 1081 | switch (type) { |
1082 | case DDR2: | 1082 | case DDR2: |
1083 | printf ("RAS to CAS delay min %d.%02d ns\n", | 1083 | printf ("RAS to CAS delay min %d.%02d ns\n", |
1084 | (data[29] >> 2) & 0x3F, 25 * (data[29] & 0x03)); | 1084 | (data[29] >> 2) & 0x3F, 25 * (data[29] & 0x03)); |
1085 | break; | 1085 | break; |
1086 | default: | 1086 | default: |
1087 | printf ("RAS to CAS delay min %d ns\n", data[29]); | 1087 | printf ("RAS to CAS delay min %d ns\n", data[29]); |
1088 | break; | 1088 | break; |
1089 | } | 1089 | } |
1090 | 1090 | ||
1091 | printf ("Minimum RAS pulse width %d ns\n", data[30]); | 1091 | printf ("Minimum RAS pulse width %d ns\n", data[30]); |
1092 | 1092 | ||
1093 | switch (type) { | 1093 | switch (type) { |
1094 | case DDR2: | 1094 | case DDR2: |
1095 | puts ("Density of each row "); | 1095 | puts ("Density of each row "); |
1096 | decode_bits (data[31], decode_row_density_DDR2, 1); | 1096 | decode_bits (data[31], decode_row_density_DDR2, 1); |
1097 | putc ('\n'); | 1097 | putc ('\n'); |
1098 | break; | 1098 | break; |
1099 | default: | 1099 | default: |
1100 | puts ("Density of each row "); | 1100 | puts ("Density of each row "); |
1101 | decode_bits (data[31], decode_row_density_default, 1); | 1101 | decode_bits (data[31], decode_row_density_default, 1); |
1102 | putc ('\n'); | 1102 | putc ('\n'); |
1103 | break; | 1103 | break; |
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | switch (type) { | 1106 | switch (type) { |
1107 | case DDR2: | 1107 | case DDR2: |
1108 | puts ("Command and Address setup "); | 1108 | puts ("Command and Address setup "); |
1109 | if (data[32] >= 0xA0) { | 1109 | if (data[32] >= 0xA0) { |
1110 | printf ("1.%d%d ns\n", | 1110 | printf ("1.%d%d ns\n", |
1111 | ((data[32] >> 4) & 0x0F) - 10, data[32] & 0x0F); | 1111 | ((data[32] >> 4) & 0x0F) - 10, data[32] & 0x0F); |
1112 | } else { | 1112 | } else { |
1113 | printf ("0.%d%d ns\n", | 1113 | printf ("0.%d%d ns\n", |
1114 | ((data[32] >> 4) & 0x0F), data[32] & 0x0F); | 1114 | ((data[32] >> 4) & 0x0F), data[32] & 0x0F); |
1115 | } | 1115 | } |
1116 | break; | 1116 | break; |
1117 | default: | 1117 | default: |
1118 | printf ("Command and Address setup %c%d.%d ns\n", | 1118 | printf ("Command and Address setup %c%d.%d ns\n", |
1119 | (data[32] & 0x80) ? '-' : '+', | 1119 | (data[32] & 0x80) ? '-' : '+', |
1120 | (data[32] >> 4) & 0x07, data[32] & 0x0F); | 1120 | (data[32] >> 4) & 0x07, data[32] & 0x0F); |
1121 | break; | 1121 | break; |
1122 | } | 1122 | } |
1123 | 1123 | ||
1124 | switch (type) { | 1124 | switch (type) { |
1125 | case DDR2: | 1125 | case DDR2: |
1126 | puts ("Command and Address hold "); | 1126 | puts ("Command and Address hold "); |
1127 | if (data[33] >= 0xA0) { | 1127 | if (data[33] >= 0xA0) { |
1128 | printf ("1.%d%d ns\n", | 1128 | printf ("1.%d%d ns\n", |
1129 | ((data[33] >> 4) & 0x0F) - 10, data[33] & 0x0F); | 1129 | ((data[33] >> 4) & 0x0F) - 10, data[33] & 0x0F); |
1130 | } else { | 1130 | } else { |
1131 | printf ("0.%d%d ns\n", | 1131 | printf ("0.%d%d ns\n", |
1132 | ((data[33] >> 4) & 0x0F), data[33] & 0x0F); | 1132 | ((data[33] >> 4) & 0x0F), data[33] & 0x0F); |
1133 | } | 1133 | } |
1134 | break; | 1134 | break; |
1135 | default: | 1135 | default: |
1136 | printf ("Command and Address hold %c%d.%d ns\n", | 1136 | printf ("Command and Address hold %c%d.%d ns\n", |
1137 | (data[33] & 0x80) ? '-' : '+', | 1137 | (data[33] & 0x80) ? '-' : '+', |
1138 | (data[33] >> 4) & 0x07, data[33] & 0x0F); | 1138 | (data[33] >> 4) & 0x07, data[33] & 0x0F); |
1139 | break; | 1139 | break; |
1140 | } | 1140 | } |
1141 | 1141 | ||
1142 | switch (type) { | 1142 | switch (type) { |
1143 | case DDR2: | 1143 | case DDR2: |
1144 | printf ("Data signal input setup 0.%d%d ns\n", | 1144 | printf ("Data signal input setup 0.%d%d ns\n", |
1145 | (data[34] >> 4) & 0x0F, data[34] & 0x0F); | 1145 | (data[34] >> 4) & 0x0F, data[34] & 0x0F); |
1146 | break; | 1146 | break; |
1147 | default: | 1147 | default: |
1148 | printf ("Data signal input setup %c%d.%d ns\n", | 1148 | printf ("Data signal input setup %c%d.%d ns\n", |
1149 | (data[34] & 0x80) ? '-' : '+', | 1149 | (data[34] & 0x80) ? '-' : '+', |
1150 | (data[34] >> 4) & 0x07, data[34] & 0x0F); | 1150 | (data[34] >> 4) & 0x07, data[34] & 0x0F); |
1151 | break; | 1151 | break; |
1152 | } | 1152 | } |
1153 | 1153 | ||
1154 | switch (type) { | 1154 | switch (type) { |
1155 | case DDR2: | 1155 | case DDR2: |
1156 | printf ("Data signal input hold 0.%d%d ns\n", | 1156 | printf ("Data signal input hold 0.%d%d ns\n", |
1157 | (data[35] >> 4) & 0x0F, data[35] & 0x0F); | 1157 | (data[35] >> 4) & 0x0F, data[35] & 0x0F); |
1158 | break; | 1158 | break; |
1159 | default: | 1159 | default: |
1160 | printf ("Data signal input hold %c%d.%d ns\n", | 1160 | printf ("Data signal input hold %c%d.%d ns\n", |
1161 | (data[35] & 0x80) ? '-' : '+', | 1161 | (data[35] & 0x80) ? '-' : '+', |
1162 | (data[35] >> 4) & 0x07, data[35] & 0x0F); | 1162 | (data[35] >> 4) & 0x07, data[35] & 0x0F); |
1163 | break; | 1163 | break; |
1164 | } | 1164 | } |
1165 | 1165 | ||
1166 | puts ("Manufacturer's JEDEC ID "); | 1166 | puts ("Manufacturer's JEDEC ID "); |
1167 | for (j = 64; j <= 71; j++) | 1167 | for (j = 64; j <= 71; j++) |
1168 | printf ("%02X ", data[j]); | 1168 | printf ("%02X ", data[j]); |
1169 | putc ('\n'); | 1169 | putc ('\n'); |
1170 | printf ("Manufacturing Location %02X\n", data[72]); | 1170 | printf ("Manufacturing Location %02X\n", data[72]); |
1171 | puts ("Manufacturer's Part Number "); | 1171 | puts ("Manufacturer's Part Number "); |
1172 | for (j = 73; j <= 90; j++) | 1172 | for (j = 73; j <= 90; j++) |
1173 | printf ("%02X ", data[j]); | 1173 | printf ("%02X ", data[j]); |
1174 | putc ('\n'); | 1174 | putc ('\n'); |
1175 | printf ("Revision Code %02X %02X\n", data[91], data[92]); | 1175 | printf ("Revision Code %02X %02X\n", data[91], data[92]); |
1176 | printf ("Manufacturing Date %02X %02X\n", data[93], data[94]); | 1176 | printf ("Manufacturing Date %02X %02X\n", data[93], data[94]); |
1177 | puts ("Assembly Serial Number "); | 1177 | puts ("Assembly Serial Number "); |
1178 | for (j = 95; j <= 98; j++) | 1178 | for (j = 95; j <= 98; j++) |
1179 | printf ("%02X ", data[j]); | 1179 | printf ("%02X ", data[j]); |
1180 | putc ('\n'); | 1180 | putc ('\n'); |
1181 | 1181 | ||
1182 | if (DDR2 != type) { | 1182 | if (DDR2 != type) { |
1183 | printf ("Speed rating PC%d\n", | 1183 | printf ("Speed rating PC%d\n", |
1184 | data[126] == 0x66 ? 66 : data[126]); | 1184 | data[126] == 0x66 ? 66 : data[126]); |
1185 | } | 1185 | } |
1186 | return 0; | 1186 | return 0; |
1187 | } | 1187 | } |
1188 | #endif | 1188 | #endif |
1189 | 1189 | ||
1190 | #if defined(CONFIG_I2C_MUX) | 1190 | #if defined(CONFIG_I2C_MUX) |
1191 | int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 1191 | int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
1192 | { | 1192 | { |
1193 | int ret=0; | 1193 | int ret=0; |
1194 | 1194 | ||
1195 | if (argc == 1) { | 1195 | if (argc == 1) { |
1196 | /* show all busses */ | 1196 | /* show all busses */ |
1197 | I2C_MUX *mux; | 1197 | I2C_MUX *mux; |
1198 | I2C_MUX_DEVICE *device = i2c_mux_devices; | 1198 | I2C_MUX_DEVICE *device = i2c_mux_devices; |
1199 | 1199 | ||
1200 | printf ("Busses reached over muxes:\n"); | 1200 | printf ("Busses reached over muxes:\n"); |
1201 | while (device != NULL) { | 1201 | while (device != NULL) { |
1202 | printf ("Bus ID: %x\n", device->busid); | 1202 | printf ("Bus ID: %x\n", device->busid); |
1203 | printf (" reached over Mux(es):\n"); | 1203 | printf (" reached over Mux(es):\n"); |
1204 | mux = device->mux; | 1204 | mux = device->mux; |
1205 | while (mux != NULL) { | 1205 | while (mux != NULL) { |
1206 | printf (" %s@%x ch: %x\n", mux->name, mux->chip, mux->channel); | 1206 | printf (" %s@%x ch: %x\n", mux->name, mux->chip, mux->channel); |
1207 | mux = mux->next; | 1207 | mux = mux->next; |
1208 | } | 1208 | } |
1209 | device = device->next; | 1209 | device = device->next; |
1210 | } | 1210 | } |
1211 | } else { | 1211 | } else { |
1212 | I2C_MUX_DEVICE *dev; | 1212 | I2C_MUX_DEVICE *dev; |
1213 | 1213 | ||
1214 | dev = i2c_mux_ident_muxstring ((uchar *)argv[1]); | 1214 | dev = i2c_mux_ident_muxstring ((uchar *)argv[1]); |
1215 | ret = 0; | 1215 | ret = 0; |
1216 | } | 1216 | } |
1217 | return ret; | 1217 | return ret; |
1218 | } | 1218 | } |
1219 | #endif /* CONFIG_I2C_MUX */ | 1219 | #endif /* CONFIG_I2C_MUX */ |
1220 | 1220 | ||
1221 | #if defined(CONFIG_I2C_MULTI_BUS) | 1221 | #if defined(CONFIG_I2C_MULTI_BUS) |
1222 | int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 1222 | int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
1223 | { | 1223 | { |
1224 | int bus_idx, ret=0; | 1224 | int bus_idx, ret=0; |
1225 | 1225 | ||
1226 | if (argc == 1) | 1226 | if (argc == 1) |
1227 | /* querying current setting */ | 1227 | /* querying current setting */ |
1228 | printf("Current bus is %d\n", i2c_get_bus_num()); | 1228 | printf("Current bus is %d\n", i2c_get_bus_num()); |
1229 | else { | 1229 | else { |
1230 | bus_idx = simple_strtoul(argv[1], NULL, 10); | 1230 | bus_idx = simple_strtoul(argv[1], NULL, 10); |
1231 | printf("Setting bus to %d\n", bus_idx); | 1231 | printf("Setting bus to %d\n", bus_idx); |
1232 | ret = i2c_set_bus_num(bus_idx); | 1232 | ret = i2c_set_bus_num(bus_idx); |
1233 | if (ret) | 1233 | if (ret) |
1234 | printf("Failure changing bus number (%d)\n", ret); | 1234 | printf("Failure changing bus number (%d)\n", ret); |
1235 | } | 1235 | } |
1236 | return ret; | 1236 | return ret; |
1237 | } | 1237 | } |
1238 | #endif /* CONFIG_I2C_MULTI_BUS */ | 1238 | #endif /* CONFIG_I2C_MULTI_BUS */ |
1239 | 1239 | ||
1240 | int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 1240 | int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
1241 | { | 1241 | { |
1242 | int speed, ret=0; | 1242 | int speed, ret=0; |
1243 | 1243 | ||
1244 | if (argc == 1) | 1244 | if (argc == 1) |
1245 | /* querying current speed */ | 1245 | /* querying current speed */ |
1246 | printf("Current bus speed=%d\n", i2c_get_bus_speed()); | 1246 | printf("Current bus speed=%d\n", i2c_get_bus_speed()); |
1247 | else { | 1247 | else { |
1248 | speed = simple_strtoul(argv[1], NULL, 10); | 1248 | speed = simple_strtoul(argv[1], NULL, 10); |
1249 | printf("Setting bus speed to %d Hz\n", speed); | 1249 | printf("Setting bus speed to %d Hz\n", speed); |
1250 | ret = i2c_set_bus_speed(speed); | 1250 | ret = i2c_set_bus_speed(speed); |
1251 | if (ret) | 1251 | if (ret) |
1252 | printf("Failure changing bus speed (%d)\n", ret); | 1252 | printf("Failure changing bus speed (%d)\n", ret); |
1253 | } | 1253 | } |
1254 | return ret; | 1254 | return ret; |
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 1257 | int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
1258 | { | 1258 | { |
1259 | /* Strip off leading 'i2c' command argument */ | 1259 | /* Strip off leading 'i2c' command argument */ |
1260 | argc--; | 1260 | argc--; |
1261 | argv++; | 1261 | argv++; |
1262 | 1262 | ||
1263 | #if defined(CONFIG_I2C_MUX) | 1263 | #if defined(CONFIG_I2C_MUX) |
1264 | if (!strncmp(argv[0], "bu", 2)) | 1264 | if (!strncmp(argv[0], "bu", 2)) |
1265 | return do_i2c_add_bus(cmdtp, flag, argc, argv); | 1265 | return do_i2c_add_bus(cmdtp, flag, argc, argv); |
1266 | #endif /* CONFIG_I2C_MUX */ | 1266 | #endif /* CONFIG_I2C_MUX */ |
1267 | if (!strncmp(argv[0], "sp", 2)) | 1267 | if (!strncmp(argv[0], "sp", 2)) |
1268 | return do_i2c_bus_speed(cmdtp, flag, argc, argv); | 1268 | return do_i2c_bus_speed(cmdtp, flag, argc, argv); |
1269 | #if defined(CONFIG_I2C_MULTI_BUS) | 1269 | #if defined(CONFIG_I2C_MULTI_BUS) |
1270 | if (!strncmp(argv[0], "de", 2)) | 1270 | if (!strncmp(argv[0], "de", 2)) |
1271 | return do_i2c_bus_num(cmdtp, flag, argc, argv); | 1271 | return do_i2c_bus_num(cmdtp, flag, argc, argv); |
1272 | #endif /* CONFIG_I2C_MULTI_BUS */ | 1272 | #endif /* CONFIG_I2C_MULTI_BUS */ |
1273 | if (!strncmp(argv[0], "md", 2)) | 1273 | if (!strncmp(argv[0], "md", 2)) |
1274 | return do_i2c_md(cmdtp, flag, argc, argv); | 1274 | return do_i2c_md(cmdtp, flag, argc, argv); |
1275 | if (!strncmp(argv[0], "mm", 2)) | 1275 | if (!strncmp(argv[0], "mm", 2)) |
1276 | return mod_i2c_mem (cmdtp, 1, flag, argc, argv); | 1276 | return mod_i2c_mem (cmdtp, 1, flag, argc, argv); |
1277 | if (!strncmp(argv[0], "mw", 2)) | 1277 | if (!strncmp(argv[0], "mw", 2)) |
1278 | return do_i2c_mw(cmdtp, flag, argc, argv); | 1278 | return do_i2c_mw(cmdtp, flag, argc, argv); |
1279 | if (!strncmp(argv[0], "nm", 2)) | 1279 | if (!strncmp(argv[0], "nm", 2)) |
1280 | return mod_i2c_mem (cmdtp, 0, flag, argc, argv); | 1280 | return mod_i2c_mem (cmdtp, 0, flag, argc, argv); |
1281 | if (!strncmp(argv[0], "cr", 2)) | 1281 | if (!strncmp(argv[0], "cr", 2)) |
1282 | return do_i2c_crc(cmdtp, flag, argc, argv); | 1282 | return do_i2c_crc(cmdtp, flag, argc, argv); |
1283 | if (!strncmp(argv[0], "pr", 2)) | 1283 | if (!strncmp(argv[0], "pr", 2)) |
1284 | return do_i2c_probe(cmdtp, flag, argc, argv); | 1284 | return do_i2c_probe(cmdtp, flag, argc, argv); |
1285 | if (!strncmp(argv[0], "re", 2)) | 1285 | if (!strncmp(argv[0], "re", 2)) |
1286 | i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); | 1286 | i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); |
1287 | return 0; | 1287 | return 0; |
1288 | if (!strncmp(argv[0], "lo", 2)) | 1288 | if (!strncmp(argv[0], "lo", 2)) |
1289 | return do_i2c_loop(cmdtp, flag, argc, argv); | 1289 | return do_i2c_loop(cmdtp, flag, argc, argv); |
1290 | #if defined(CONFIG_CMD_SDRAM) | 1290 | #if defined(CONFIG_CMD_SDRAM) |
1291 | if (!strncmp(argv[0], "sd", 2)) | 1291 | if (!strncmp(argv[0], "sd", 2)) |
1292 | return do_sdram(cmdtp, flag, argc, argv); | 1292 | return do_sdram(cmdtp, flag, argc, argv); |
1293 | #endif | 1293 | #endif |
1294 | else | 1294 | else |
1295 | cmd_usage(cmdtp); | 1295 | cmd_usage(cmdtp); |
1296 | return 0; | 1296 | return 0; |
1297 | } | 1297 | } |
1298 | 1298 | ||
1299 | /***************************************************/ | 1299 | /***************************************************/ |
1300 | 1300 | ||
1301 | U_BOOT_CMD( | 1301 | U_BOOT_CMD( |
1302 | i2c, 6, 1, do_i2c, | 1302 | i2c, 6, 1, do_i2c, |
1303 | "I2C sub-system", | 1303 | "I2C sub-system", |
1304 | "speed [speed] - show or set I2C bus speed\n" | ||
1304 | #if defined(CONFIG_I2C_MUX) | 1305 | #if defined(CONFIG_I2C_MUX) |
1305 | "bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes.\n" | 1306 | "i2c bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes\n" |
1306 | #endif /* CONFIG_I2C_MUX */ | 1307 | #endif /* CONFIG_I2C_MUX */ |
1307 | "speed [speed] - show or set I2C bus speed\n" | ||
1308 | #if defined(CONFIG_I2C_MULTI_BUS) | 1308 | #if defined(CONFIG_I2C_MULTI_BUS) |
1309 | "i2c dev [dev] - show or set current I2C bus\n" | 1309 | "i2c dev [dev] - show or set current I2C bus\n" |
1310 | #endif /* CONFIG_I2C_MULTI_BUS */ | 1310 | #endif /* CONFIG_I2C_MULTI_BUS */ |
1311 | "i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n" | 1311 | "i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n" |
1312 | "i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n" | 1312 | "i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n" |
1313 | "i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n" | 1313 | "i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n" |
1314 | "i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)\n" | 1314 | "i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)\n" |
1315 | "i2c crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n" | 1315 | "i2c crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n" |
1316 | "i2c probe - show devices on the I2C bus\n" | 1316 | "i2c probe - show devices on the I2C bus\n" |
1317 | "i2c reset - re-init the I2C Controller\n" | 1317 | "i2c reset - re-init the I2C Controller\n" |
1318 | "i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device\n" | 1318 | "i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device\n" |
1319 | #if defined(CONFIG_CMD_SDRAM) | 1319 | #if defined(CONFIG_CMD_SDRAM) |
1320 | "i2c sdram chip - print SDRAM configuration information\n" | 1320 | "i2c sdram chip - print SDRAM configuration information\n" |
1321 | #endif | 1321 | #endif |
1322 | ); | 1322 | ); |
1323 | 1323 | ||
1324 | #if defined(CONFIG_I2C_MUX) | 1324 | #if defined(CONFIG_I2C_MUX) |
1325 | 1325 | ||
1326 | int i2c_mux_add_device(I2C_MUX_DEVICE *dev) | 1326 | int i2c_mux_add_device(I2C_MUX_DEVICE *dev) |
1327 | { | 1327 | { |
1328 | I2C_MUX_DEVICE *devtmp = i2c_mux_devices; | 1328 | I2C_MUX_DEVICE *devtmp = i2c_mux_devices; |
1329 | 1329 | ||
1330 | if (i2c_mux_devices == NULL) { | 1330 | if (i2c_mux_devices == NULL) { |
1331 | i2c_mux_devices = dev; | 1331 | i2c_mux_devices = dev; |
1332 | return 0; | 1332 | return 0; |
1333 | } | 1333 | } |
1334 | while (devtmp->next != NULL) | 1334 | while (devtmp->next != NULL) |
1335 | devtmp = devtmp->next; | 1335 | devtmp = devtmp->next; |
1336 | 1336 | ||
1337 | devtmp->next = dev; | 1337 | devtmp->next = dev; |
1338 | return 0; | 1338 | return 0; |
1339 | } | 1339 | } |
1340 | 1340 | ||
1341 | I2C_MUX_DEVICE *i2c_mux_search_device(int id) | 1341 | I2C_MUX_DEVICE *i2c_mux_search_device(int id) |
1342 | { | 1342 | { |
1343 | I2C_MUX_DEVICE *device = i2c_mux_devices; | 1343 | I2C_MUX_DEVICE *device = i2c_mux_devices; |
1344 | 1344 | ||
1345 | while (device != NULL) { | 1345 | while (device != NULL) { |
1346 | if (device->busid == id) | 1346 | if (device->busid == id) |
1347 | return device; | 1347 | return device; |
1348 | device = device->next; | 1348 | device = device->next; |
1349 | } | 1349 | } |
1350 | return NULL; | 1350 | return NULL; |
1351 | } | 1351 | } |
1352 | 1352 | ||
1353 | /* searches in the buf from *pos the next ':'. | 1353 | /* searches in the buf from *pos the next ':'. |
1354 | * returns: | 1354 | * returns: |
1355 | * 0 if found (with *pos = where) | 1355 | * 0 if found (with *pos = where) |
1356 | * < 0 if an error occured | 1356 | * < 0 if an error occured |
1357 | * > 0 if the end of buf is reached | 1357 | * > 0 if the end of buf is reached |
1358 | */ | 1358 | */ |
1359 | static int i2c_mux_search_next (int *pos, uchar *buf, int len) | 1359 | static int i2c_mux_search_next (int *pos, uchar *buf, int len) |
1360 | { | 1360 | { |
1361 | while ((buf[*pos] != ':') && (*pos < len)) { | 1361 | while ((buf[*pos] != ':') && (*pos < len)) { |
1362 | *pos += 1; | 1362 | *pos += 1; |
1363 | } | 1363 | } |
1364 | if (*pos >= len) | 1364 | if (*pos >= len) |
1365 | return 1; | 1365 | return 1; |
1366 | if (buf[*pos] != ':') | 1366 | if (buf[*pos] != ':') |
1367 | return -1; | 1367 | return -1; |
1368 | return 0; | 1368 | return 0; |
1369 | } | 1369 | } |
1370 | 1370 | ||
1371 | static int i2c_mux_get_busid (void) | 1371 | static int i2c_mux_get_busid (void) |
1372 | { | 1372 | { |
1373 | int tmp = i2c_mux_busid; | 1373 | int tmp = i2c_mux_busid; |
1374 | 1374 | ||
1375 | i2c_mux_busid ++; | 1375 | i2c_mux_busid ++; |
1376 | return tmp; | 1376 | return tmp; |
1377 | } | 1377 | } |
1378 | 1378 | ||
1379 | /* Analyses a Muxstring and sends immediately the | 1379 | /* Analyses a Muxstring and sends immediately the |
1380 | Commands to the Muxes. Runs from Flash. | 1380 | Commands to the Muxes. Runs from Flash. |
1381 | */ | 1381 | */ |
1382 | int i2c_mux_ident_muxstring_f (uchar *buf) | 1382 | int i2c_mux_ident_muxstring_f (uchar *buf) |
1383 | { | 1383 | { |
1384 | int pos = 0; | 1384 | int pos = 0; |
1385 | int oldpos; | 1385 | int oldpos; |
1386 | int ret = 0; | 1386 | int ret = 0; |
1387 | int len = strlen((char *)buf); | 1387 | int len = strlen((char *)buf); |
1388 | int chip; | 1388 | int chip; |
1389 | uchar channel; | 1389 | uchar channel; |
1390 | int was = 0; | 1390 | int was = 0; |
1391 | 1391 | ||
1392 | while (ret == 0) { | 1392 | while (ret == 0) { |
1393 | oldpos = pos; | 1393 | oldpos = pos; |
1394 | /* search name */ | 1394 | /* search name */ |
1395 | ret = i2c_mux_search_next(&pos, buf, len); | 1395 | ret = i2c_mux_search_next(&pos, buf, len); |
1396 | if (ret != 0) | 1396 | if (ret != 0) |
1397 | printf ("ERROR\n"); | 1397 | printf ("ERROR\n"); |
1398 | /* search address */ | 1398 | /* search address */ |
1399 | pos ++; | 1399 | pos ++; |
1400 | oldpos = pos; | 1400 | oldpos = pos; |
1401 | ret = i2c_mux_search_next(&pos, buf, len); | 1401 | ret = i2c_mux_search_next(&pos, buf, len); |
1402 | if (ret != 0) | 1402 | if (ret != 0) |
1403 | printf ("ERROR\n"); | 1403 | printf ("ERROR\n"); |
1404 | buf[pos] = 0; | 1404 | buf[pos] = 0; |
1405 | chip = simple_strtoul((char *)&buf[oldpos], NULL, 16); | 1405 | chip = simple_strtoul((char *)&buf[oldpos], NULL, 16); |
1406 | buf[pos] = ':'; | 1406 | buf[pos] = ':'; |
1407 | /* search channel */ | 1407 | /* search channel */ |
1408 | pos ++; | 1408 | pos ++; |
1409 | oldpos = pos; | 1409 | oldpos = pos; |
1410 | ret = i2c_mux_search_next(&pos, buf, len); | 1410 | ret = i2c_mux_search_next(&pos, buf, len); |
1411 | if (ret < 0) | 1411 | if (ret < 0) |
1412 | printf ("ERROR\n"); | 1412 | printf ("ERROR\n"); |
1413 | was = 0; | 1413 | was = 0; |
1414 | if (buf[pos] != 0) { | 1414 | if (buf[pos] != 0) { |
1415 | buf[pos] = 0; | 1415 | buf[pos] = 0; |
1416 | was = 1; | 1416 | was = 1; |
1417 | } | 1417 | } |
1418 | channel = simple_strtoul((char *)&buf[oldpos], NULL, 16); | 1418 | channel = simple_strtoul((char *)&buf[oldpos], NULL, 16); |
1419 | if (was) | 1419 | if (was) |
1420 | buf[pos] = ':'; | 1420 | buf[pos] = ':'; |
1421 | if (i2c_write(chip, 0, 0, &channel, 1) != 0) { | 1421 | if (i2c_write(chip, 0, 0, &channel, 1) != 0) { |
1422 | printf ("Error setting Mux: chip:%x channel: \ | 1422 | printf ("Error setting Mux: chip:%x channel: \ |
1423 | %x\n", chip, channel); | 1423 | %x\n", chip, channel); |
1424 | return -1; | 1424 | return -1; |
1425 | } | 1425 | } |
1426 | pos ++; | 1426 | pos ++; |
1427 | oldpos = pos; | 1427 | oldpos = pos; |
1428 | 1428 | ||
1429 | } | 1429 | } |
1430 | 1430 | ||
1431 | return 0; | 1431 | return 0; |
1432 | } | 1432 | } |
1433 | 1433 | ||
1434 | /* Analyses a Muxstring and if this String is correct | 1434 | /* Analyses a Muxstring and if this String is correct |
1435 | * adds a new I2C Bus. | 1435 | * adds a new I2C Bus. |
1436 | */ | 1436 | */ |
1437 | I2C_MUX_DEVICE *i2c_mux_ident_muxstring (uchar *buf) | 1437 | I2C_MUX_DEVICE *i2c_mux_ident_muxstring (uchar *buf) |
1438 | { | 1438 | { |
1439 | I2C_MUX_DEVICE *device; | 1439 | I2C_MUX_DEVICE *device; |
1440 | I2C_MUX *mux; | 1440 | I2C_MUX *mux; |
1441 | int pos = 0; | 1441 | int pos = 0; |
1442 | int oldpos; | 1442 | int oldpos; |
1443 | int ret = 0; | 1443 | int ret = 0; |
1444 | int len = strlen((char *)buf); | 1444 | int len = strlen((char *)buf); |
1445 | int was = 0; | 1445 | int was = 0; |
1446 | 1446 | ||
1447 | device = (I2C_MUX_DEVICE *)malloc (sizeof(I2C_MUX_DEVICE)); | 1447 | device = (I2C_MUX_DEVICE *)malloc (sizeof(I2C_MUX_DEVICE)); |
1448 | device->mux = NULL; | 1448 | device->mux = NULL; |
1449 | device->busid = i2c_mux_get_busid (); | 1449 | device->busid = i2c_mux_get_busid (); |
1450 | device->next = NULL; | 1450 | device->next = NULL; |
1451 | while (ret == 0) { | 1451 | while (ret == 0) { |
1452 | mux = (I2C_MUX *)malloc (sizeof(I2C_MUX)); | 1452 | mux = (I2C_MUX *)malloc (sizeof(I2C_MUX)); |
1453 | mux->next = NULL; | 1453 | mux->next = NULL; |
1454 | /* search name of mux */ | 1454 | /* search name of mux */ |
1455 | oldpos = pos; | 1455 | oldpos = pos; |
1456 | ret = i2c_mux_search_next(&pos, buf, len); | 1456 | ret = i2c_mux_search_next(&pos, buf, len); |
1457 | if (ret != 0) | 1457 | if (ret != 0) |
1458 | printf ("%s no name.\n", __FUNCTION__); | 1458 | printf ("%s no name.\n", __FUNCTION__); |
1459 | mux->name = (char *)malloc (pos - oldpos + 1); | 1459 | mux->name = (char *)malloc (pos - oldpos + 1); |
1460 | memcpy (mux->name, &buf[oldpos], pos - oldpos); | 1460 | memcpy (mux->name, &buf[oldpos], pos - oldpos); |
1461 | mux->name[pos - oldpos] = 0; | 1461 | mux->name[pos - oldpos] = 0; |
1462 | /* search address */ | 1462 | /* search address */ |
1463 | pos ++; | 1463 | pos ++; |
1464 | oldpos = pos; | 1464 | oldpos = pos; |
1465 | ret = i2c_mux_search_next(&pos, buf, len); | 1465 | ret = i2c_mux_search_next(&pos, buf, len); |
1466 | if (ret != 0) | 1466 | if (ret != 0) |
1467 | printf ("%s no mux address.\n", __FUNCTION__); | 1467 | printf ("%s no mux address.\n", __FUNCTION__); |
1468 | buf[pos] = 0; | 1468 | buf[pos] = 0; |
1469 | mux->chip = simple_strtoul((char *)&buf[oldpos], NULL, 16); | 1469 | mux->chip = simple_strtoul((char *)&buf[oldpos], NULL, 16); |
1470 | buf[pos] = ':'; | 1470 | buf[pos] = ':'; |
1471 | /* search channel */ | 1471 | /* search channel */ |
1472 | pos ++; | 1472 | pos ++; |
1473 | oldpos = pos; | 1473 | oldpos = pos; |
1474 | ret = i2c_mux_search_next(&pos, buf, len); | 1474 | ret = i2c_mux_search_next(&pos, buf, len); |
1475 | if (ret < 0) | 1475 | if (ret < 0) |
1476 | printf ("%s no mux channel.\n", __FUNCTION__); | 1476 | printf ("%s no mux channel.\n", __FUNCTION__); |
1477 | was = 0; | 1477 | was = 0; |
1478 | if (buf[pos] != 0) { | 1478 | if (buf[pos] != 0) { |
1479 | buf[pos] = 0; | 1479 | buf[pos] = 0; |
1480 | was = 1; | 1480 | was = 1; |
1481 | } | 1481 | } |
1482 | mux->channel = simple_strtoul((char *)&buf[oldpos], NULL, 16); | 1482 | mux->channel = simple_strtoul((char *)&buf[oldpos], NULL, 16); |
1483 | if (was) | 1483 | if (was) |
1484 | buf[pos] = ':'; | 1484 | buf[pos] = ':'; |
1485 | if (device->mux == NULL) | 1485 | if (device->mux == NULL) |
1486 | device->mux = mux; | 1486 | device->mux = mux; |
1487 | else { | 1487 | else { |
1488 | I2C_MUX *muxtmp = device->mux; | 1488 | I2C_MUX *muxtmp = device->mux; |
1489 | while (muxtmp->next != NULL) { | 1489 | while (muxtmp->next != NULL) { |
1490 | muxtmp = muxtmp->next; | 1490 | muxtmp = muxtmp->next; |
1491 | } | 1491 | } |
1492 | muxtmp->next = mux; | 1492 | muxtmp->next = mux; |
1493 | } | 1493 | } |
1494 | pos ++; | 1494 | pos ++; |
1495 | oldpos = pos; | 1495 | oldpos = pos; |
1496 | } | 1496 | } |
1497 | if (ret > 0) { | 1497 | if (ret > 0) { |
1498 | /* Add Device */ | 1498 | /* Add Device */ |
1499 | i2c_mux_add_device (device); | 1499 | i2c_mux_add_device (device); |
1500 | return device; | 1500 | return device; |
1501 | } | 1501 | } |
1502 | 1502 | ||
1503 | return NULL; | 1503 | return NULL; |
1504 | } | 1504 | } |
1505 | 1505 | ||
1506 | int i2x_mux_select_mux(int bus) | 1506 | int i2x_mux_select_mux(int bus) |
1507 | { | 1507 | { |
1508 | I2C_MUX_DEVICE *dev; | 1508 | I2C_MUX_DEVICE *dev; |
1509 | I2C_MUX *mux; | 1509 | I2C_MUX *mux; |
1510 | 1510 | ||
1511 | if ((gd->flags & GD_FLG_RELOC) != GD_FLG_RELOC) { | 1511 | if ((gd->flags & GD_FLG_RELOC) != GD_FLG_RELOC) { |
1512 | /* select Default Mux Bus */ | 1512 | /* select Default Mux Bus */ |
1513 | #if defined(CONFIG_SYS_I2C_IVM_BUS) | 1513 | #if defined(CONFIG_SYS_I2C_IVM_BUS) |
1514 | i2c_mux_ident_muxstring_f ((uchar *)CONFIG_SYS_I2C_IVM_BUS); | 1514 | i2c_mux_ident_muxstring_f ((uchar *)CONFIG_SYS_I2C_IVM_BUS); |
1515 | #else | 1515 | #else |
1516 | { | 1516 | { |
1517 | unsigned char *buf; | 1517 | unsigned char *buf; |
1518 | buf = (unsigned char *) getenv("EEprom_ivm"); | 1518 | buf = (unsigned char *) getenv("EEprom_ivm"); |
1519 | if (buf != NULL) | 1519 | if (buf != NULL) |
1520 | i2c_mux_ident_muxstring_f (buf); | 1520 | i2c_mux_ident_muxstring_f (buf); |
1521 | } | 1521 | } |
1522 | #endif | 1522 | #endif |
1523 | return 0; | 1523 | return 0; |
1524 | } | 1524 | } |
1525 | dev = i2c_mux_search_device(bus); | 1525 | dev = i2c_mux_search_device(bus); |
1526 | if (dev == NULL) | 1526 | if (dev == NULL) |
1527 | return -1; | 1527 | return -1; |
1528 | 1528 | ||
1529 | mux = dev->mux; | 1529 | mux = dev->mux; |
1530 | while (mux != NULL) { | 1530 | while (mux != NULL) { |
1531 | if (i2c_write(mux->chip, 0, 0, &mux->channel, 1) != 0) { | 1531 | if (i2c_write(mux->chip, 0, 0, &mux->channel, 1) != 0) { |
1532 | printf ("Error setting Mux: chip:%x channel: \ | 1532 | printf ("Error setting Mux: chip:%x channel: \ |
1533 | %x\n", mux->chip, mux->channel); | 1533 | %x\n", mux->chip, mux->channel); |
1534 | return -1; | 1534 | return -1; |
1535 | } | 1535 | } |
1536 | mux = mux->next; | 1536 | mux = mux->next; |
1537 | } | 1537 | } |
1538 | return 0; | 1538 | return 0; |
1539 | } | 1539 | } |
1540 | #endif /* CONFIG_I2C_MUX */ | 1540 | #endif /* CONFIG_I2C_MUX */ |