Commit faffe14f016db10f33836b018c4b304d939cf586
Committed by
Wolfgang Denk
1 parent
a6a04967bc
Exists in
master
and in
55 other branches
cmd_i2c.c: reduced subaddress length to 3 bytes
according to some of the comments the subaddress length is 1 or 2, but we are being prepared for the case it becomes 3. However the code also accepted 4. This repairs this by changing the constand 4 to 3. Signed-off-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Showing 1 changed file with 5 additions and 5 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 > 3) { |
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 > 3) { |
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 | /* | 319 | /* |
320 | * No write delay with FRAM devices. | 320 | * No write delay with FRAM devices. |
321 | */ | 321 | */ |
322 | #if !defined(CONFIG_SYS_I2C_FRAM) | 322 | #if !defined(CONFIG_SYS_I2C_FRAM) |
323 | udelay(11000); | 323 | udelay(11000); |
324 | #endif | 324 | #endif |
325 | } | 325 | } |
326 | 326 | ||
327 | return (0); | 327 | return (0); |
328 | } | 328 | } |
329 | 329 | ||
330 | /* Calculate a CRC on memory | 330 | /* Calculate a CRC on memory |
331 | * | 331 | * |
332 | * Syntax: | 332 | * Syntax: |
333 | * i2c crc32 {i2c_chip} {addr}{.0, .1, .2} {count} | 333 | * i2c crc32 {i2c_chip} {addr}{.0, .1, .2} {count} |
334 | */ | 334 | */ |
335 | int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 335 | int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
336 | { | 336 | { |
337 | uchar chip; | 337 | uchar chip; |
338 | ulong addr; | 338 | ulong addr; |
339 | uint alen; | 339 | uint alen; |
340 | int count; | 340 | int count; |
341 | uchar byte; | 341 | uchar byte; |
342 | ulong crc; | 342 | ulong crc; |
343 | ulong err; | 343 | ulong err; |
344 | int j; | 344 | int j; |
345 | 345 | ||
346 | if (argc < 4) { | 346 | if (argc < 4) { |
347 | cmd_usage(cmdtp); | 347 | cmd_usage(cmdtp); |
348 | return 1; | 348 | return 1; |
349 | } | 349 | } |
350 | 350 | ||
351 | /* | 351 | /* |
352 | * Chip is always specified. | 352 | * Chip is always specified. |
353 | */ | 353 | */ |
354 | chip = simple_strtoul(argv[1], NULL, 16); | 354 | chip = simple_strtoul(argv[1], NULL, 16); |
355 | 355 | ||
356 | /* | 356 | /* |
357 | * Address is always specified. | 357 | * Address is always specified. |
358 | */ | 358 | */ |
359 | addr = simple_strtoul(argv[2], NULL, 16); | 359 | addr = simple_strtoul(argv[2], NULL, 16); |
360 | alen = 1; | 360 | alen = 1; |
361 | for (j = 0; j < 8; j++) { | 361 | for (j = 0; j < 8; j++) { |
362 | if (argv[2][j] == '.') { | 362 | if (argv[2][j] == '.') { |
363 | alen = argv[2][j+1] - '0'; | 363 | alen = argv[2][j+1] - '0'; |
364 | if (alen > 4) { | 364 | if (alen > 3) { |
365 | cmd_usage(cmdtp); | 365 | cmd_usage(cmdtp); |
366 | return 1; | 366 | return 1; |
367 | } | 367 | } |
368 | break; | 368 | break; |
369 | } else if (argv[2][j] == '\0') | 369 | } else if (argv[2][j] == '\0') |
370 | break; | 370 | break; |
371 | } | 371 | } |
372 | 372 | ||
373 | /* | 373 | /* |
374 | * Count is always specified | 374 | * Count is always specified |
375 | */ | 375 | */ |
376 | count = simple_strtoul(argv[3], NULL, 16); | 376 | count = simple_strtoul(argv[3], NULL, 16); |
377 | 377 | ||
378 | printf ("CRC32 for %08lx ... %08lx ==> ", addr, addr + count - 1); | 378 | printf ("CRC32 for %08lx ... %08lx ==> ", addr, addr + count - 1); |
379 | /* | 379 | /* |
380 | * CRC a byte at a time. This is going to be slooow, but hey, the | 380 | * CRC a byte at a time. This is going to be slooow, but hey, the |
381 | * memories are small and slow too so hopefully nobody notices. | 381 | * memories are small and slow too so hopefully nobody notices. |
382 | */ | 382 | */ |
383 | crc = 0; | 383 | crc = 0; |
384 | err = 0; | 384 | err = 0; |
385 | while (count-- > 0) { | 385 | while (count-- > 0) { |
386 | if (i2c_read(chip, addr, alen, &byte, 1) != 0) | 386 | if (i2c_read(chip, addr, alen, &byte, 1) != 0) |
387 | err++; | 387 | err++; |
388 | crc = crc32 (crc, &byte, 1); | 388 | crc = crc32 (crc, &byte, 1); |
389 | addr++; | 389 | addr++; |
390 | } | 390 | } |
391 | if (err > 0) | 391 | if (err > 0) |
392 | puts ("Error reading the chip,\n"); | 392 | puts ("Error reading the chip,\n"); |
393 | else | 393 | else |
394 | printf ("%08lx\n", crc); | 394 | printf ("%08lx\n", crc); |
395 | 395 | ||
396 | return 0; | 396 | return 0; |
397 | } | 397 | } |
398 | 398 | ||
399 | /* Modify memory. | 399 | /* Modify memory. |
400 | * | 400 | * |
401 | * Syntax: | 401 | * Syntax: |
402 | * i2c mm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} | 402 | * i2c mm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} |
403 | * i2c nm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} | 403 | * i2c nm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} |
404 | */ | 404 | */ |
405 | 405 | ||
406 | static int | 406 | static int |
407 | mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) | 407 | mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) |
408 | { | 408 | { |
409 | uchar chip; | 409 | uchar chip; |
410 | ulong addr; | 410 | ulong addr; |
411 | uint alen; | 411 | uint alen; |
412 | ulong data; | 412 | ulong data; |
413 | int size = 1; | 413 | int size = 1; |
414 | int nbytes; | 414 | int nbytes; |
415 | int j; | 415 | int j; |
416 | extern char console_buffer[]; | 416 | extern char console_buffer[]; |
417 | 417 | ||
418 | if (argc != 3) { | 418 | if (argc != 3) { |
419 | cmd_usage(cmdtp); | 419 | cmd_usage(cmdtp); |
420 | return 1; | 420 | return 1; |
421 | } | 421 | } |
422 | 422 | ||
423 | #ifdef CONFIG_BOOT_RETRY_TIME | 423 | #ifdef CONFIG_BOOT_RETRY_TIME |
424 | reset_cmd_timeout(); /* got a good command to get here */ | 424 | reset_cmd_timeout(); /* got a good command to get here */ |
425 | #endif | 425 | #endif |
426 | /* | 426 | /* |
427 | * We use the last specified parameters, unless new ones are | 427 | * We use the last specified parameters, unless new ones are |
428 | * entered. | 428 | * entered. |
429 | */ | 429 | */ |
430 | chip = i2c_mm_last_chip; | 430 | chip = i2c_mm_last_chip; |
431 | addr = i2c_mm_last_addr; | 431 | addr = i2c_mm_last_addr; |
432 | alen = i2c_mm_last_alen; | 432 | alen = i2c_mm_last_alen; |
433 | 433 | ||
434 | if ((flag & CMD_FLAG_REPEAT) == 0) { | 434 | if ((flag & CMD_FLAG_REPEAT) == 0) { |
435 | /* | 435 | /* |
436 | * New command specified. Check for a size specification. | 436 | * New command specified. Check for a size specification. |
437 | * Defaults to byte if no or incorrect specification. | 437 | * Defaults to byte if no or incorrect specification. |
438 | */ | 438 | */ |
439 | size = cmd_get_data_size(argv[0], 1); | 439 | size = cmd_get_data_size(argv[0], 1); |
440 | 440 | ||
441 | /* | 441 | /* |
442 | * Chip is always specified. | 442 | * Chip is always specified. |
443 | */ | 443 | */ |
444 | chip = simple_strtoul(argv[1], NULL, 16); | 444 | chip = simple_strtoul(argv[1], NULL, 16); |
445 | 445 | ||
446 | /* | 446 | /* |
447 | * Address is always specified. | 447 | * Address is always specified. |
448 | */ | 448 | */ |
449 | addr = simple_strtoul(argv[2], NULL, 16); | 449 | addr = simple_strtoul(argv[2], NULL, 16); |
450 | alen = 1; | 450 | alen = 1; |
451 | for (j = 0; j < 8; j++) { | 451 | for (j = 0; j < 8; j++) { |
452 | if (argv[2][j] == '.') { | 452 | if (argv[2][j] == '.') { |
453 | alen = argv[2][j+1] - '0'; | 453 | alen = argv[2][j+1] - '0'; |
454 | if (alen > 4) { | 454 | if (alen > 3) { |
455 | cmd_usage(cmdtp); | 455 | cmd_usage(cmdtp); |
456 | return 1; | 456 | return 1; |
457 | } | 457 | } |
458 | break; | 458 | break; |
459 | } else if (argv[2][j] == '\0') | 459 | } else if (argv[2][j] == '\0') |
460 | break; | 460 | break; |
461 | } | 461 | } |
462 | } | 462 | } |
463 | 463 | ||
464 | /* | 464 | /* |
465 | * Print the address, followed by value. Then accept input for | 465 | * Print the address, followed by value. Then accept input for |
466 | * the next value. A non-converted value exits. | 466 | * the next value. A non-converted value exits. |
467 | */ | 467 | */ |
468 | do { | 468 | do { |
469 | printf("%08lx:", addr); | 469 | printf("%08lx:", addr); |
470 | if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0) | 470 | if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0) |
471 | puts ("\nError reading the chip,\n"); | 471 | puts ("\nError reading the chip,\n"); |
472 | else { | 472 | else { |
473 | data = cpu_to_be32(data); | 473 | data = cpu_to_be32(data); |
474 | if (size == 1) | 474 | if (size == 1) |
475 | printf(" %02lx", (data >> 24) & 0x000000FF); | 475 | printf(" %02lx", (data >> 24) & 0x000000FF); |
476 | else if (size == 2) | 476 | else if (size == 2) |
477 | printf(" %04lx", (data >> 16) & 0x0000FFFF); | 477 | printf(" %04lx", (data >> 16) & 0x0000FFFF); |
478 | else | 478 | else |
479 | printf(" %08lx", data); | 479 | printf(" %08lx", data); |
480 | } | 480 | } |
481 | 481 | ||
482 | nbytes = readline (" ? "); | 482 | nbytes = readline (" ? "); |
483 | if (nbytes == 0) { | 483 | if (nbytes == 0) { |
484 | /* | 484 | /* |
485 | * <CR> pressed as only input, don't modify current | 485 | * <CR> pressed as only input, don't modify current |
486 | * location and move to next. | 486 | * location and move to next. |
487 | */ | 487 | */ |
488 | if (incrflag) | 488 | if (incrflag) |
489 | addr += size; | 489 | addr += size; |
490 | nbytes = size; | 490 | nbytes = size; |
491 | #ifdef CONFIG_BOOT_RETRY_TIME | 491 | #ifdef CONFIG_BOOT_RETRY_TIME |
492 | reset_cmd_timeout(); /* good enough to not time out */ | 492 | reset_cmd_timeout(); /* good enough to not time out */ |
493 | #endif | 493 | #endif |
494 | } | 494 | } |
495 | #ifdef CONFIG_BOOT_RETRY_TIME | 495 | #ifdef CONFIG_BOOT_RETRY_TIME |
496 | else if (nbytes == -2) | 496 | else if (nbytes == -2) |
497 | break; /* timed out, exit the command */ | 497 | break; /* timed out, exit the command */ |
498 | #endif | 498 | #endif |
499 | else { | 499 | else { |
500 | char *endp; | 500 | char *endp; |
501 | 501 | ||
502 | data = simple_strtoul(console_buffer, &endp, 16); | 502 | data = simple_strtoul(console_buffer, &endp, 16); |
503 | if (size == 1) | 503 | if (size == 1) |
504 | data = data << 24; | 504 | data = data << 24; |
505 | else if (size == 2) | 505 | else if (size == 2) |
506 | data = data << 16; | 506 | data = data << 16; |
507 | data = be32_to_cpu(data); | 507 | data = be32_to_cpu(data); |
508 | nbytes = endp - console_buffer; | 508 | nbytes = endp - console_buffer; |
509 | if (nbytes) { | 509 | if (nbytes) { |
510 | #ifdef CONFIG_BOOT_RETRY_TIME | 510 | #ifdef CONFIG_BOOT_RETRY_TIME |
511 | /* | 511 | /* |
512 | * good enough to not time out | 512 | * good enough to not time out |
513 | */ | 513 | */ |
514 | reset_cmd_timeout(); | 514 | reset_cmd_timeout(); |
515 | #endif | 515 | #endif |
516 | if (i2c_write(chip, addr, alen, (uchar *)&data, size) != 0) | 516 | if (i2c_write(chip, addr, alen, (uchar *)&data, size) != 0) |
517 | puts ("Error writing the chip.\n"); | 517 | puts ("Error writing the chip.\n"); |
518 | #ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS | 518 | #ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS |
519 | udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); | 519 | udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); |
520 | #endif | 520 | #endif |
521 | if (incrflag) | 521 | if (incrflag) |
522 | addr += size; | 522 | addr += size; |
523 | } | 523 | } |
524 | } | 524 | } |
525 | } while (nbytes); | 525 | } while (nbytes); |
526 | 526 | ||
527 | i2c_mm_last_chip = chip; | 527 | i2c_mm_last_chip = chip; |
528 | i2c_mm_last_addr = addr; | 528 | i2c_mm_last_addr = addr; |
529 | i2c_mm_last_alen = alen; | 529 | i2c_mm_last_alen = alen; |
530 | 530 | ||
531 | return 0; | 531 | return 0; |
532 | } | 532 | } |
533 | 533 | ||
534 | /* | 534 | /* |
535 | * Syntax: | 535 | * Syntax: |
536 | * i2c probe {addr}{.0, .1, .2} | 536 | * i2c probe {addr}{.0, .1, .2} |
537 | */ | 537 | */ |
538 | int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 538 | int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
539 | { | 539 | { |
540 | int j; | 540 | int j; |
541 | #if defined(CONFIG_SYS_I2C_NOPROBES) | 541 | #if defined(CONFIG_SYS_I2C_NOPROBES) |
542 | int k, skip; | 542 | int k, skip; |
543 | uchar bus = GET_BUS_NUM; | 543 | uchar bus = GET_BUS_NUM; |
544 | #endif /* NOPROBES */ | 544 | #endif /* NOPROBES */ |
545 | 545 | ||
546 | puts ("Valid chip addresses:"); | 546 | puts ("Valid chip addresses:"); |
547 | for (j = 0; j < 128; j++) { | 547 | for (j = 0; j < 128; j++) { |
548 | #if defined(CONFIG_SYS_I2C_NOPROBES) | 548 | #if defined(CONFIG_SYS_I2C_NOPROBES) |
549 | skip = 0; | 549 | skip = 0; |
550 | for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) { | 550 | for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) { |
551 | if (COMPARE_BUS(bus, k) && COMPARE_ADDR(j, k)) { | 551 | if (COMPARE_BUS(bus, k) && COMPARE_ADDR(j, k)) { |
552 | skip = 1; | 552 | skip = 1; |
553 | break; | 553 | break; |
554 | } | 554 | } |
555 | } | 555 | } |
556 | if (skip) | 556 | if (skip) |
557 | continue; | 557 | continue; |
558 | #endif | 558 | #endif |
559 | if (i2c_probe(j) == 0) | 559 | if (i2c_probe(j) == 0) |
560 | printf(" %02X", j); | 560 | printf(" %02X", j); |
561 | } | 561 | } |
562 | putc ('\n'); | 562 | putc ('\n'); |
563 | 563 | ||
564 | #if defined(CONFIG_SYS_I2C_NOPROBES) | 564 | #if defined(CONFIG_SYS_I2C_NOPROBES) |
565 | puts ("Excluded chip addresses:"); | 565 | puts ("Excluded chip addresses:"); |
566 | for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) { | 566 | for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) { |
567 | if (COMPARE_BUS(bus,k)) | 567 | if (COMPARE_BUS(bus,k)) |
568 | printf(" %02X", NO_PROBE_ADDR(k)); | 568 | printf(" %02X", NO_PROBE_ADDR(k)); |
569 | } | 569 | } |
570 | putc ('\n'); | 570 | putc ('\n'); |
571 | #endif | 571 | #endif |
572 | 572 | ||
573 | return 0; | 573 | return 0; |
574 | } | 574 | } |
575 | 575 | ||
576 | /* | 576 | /* |
577 | * Syntax: | 577 | * Syntax: |
578 | * i2c loop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}] | 578 | * i2c loop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}] |
579 | * {length} - Number of bytes to read | 579 | * {length} - Number of bytes to read |
580 | * {delay} - A DECIMAL number and defaults to 1000 uSec | 580 | * {delay} - A DECIMAL number and defaults to 1000 uSec |
581 | */ | 581 | */ |
582 | int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 582 | int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
583 | { | 583 | { |
584 | u_char chip; | 584 | u_char chip; |
585 | ulong alen; | 585 | ulong alen; |
586 | uint addr; | 586 | uint addr; |
587 | uint length; | 587 | uint length; |
588 | u_char bytes[16]; | 588 | u_char bytes[16]; |
589 | int delay; | 589 | int delay; |
590 | int j; | 590 | int j; |
591 | 591 | ||
592 | if (argc < 3) { | 592 | if (argc < 3) { |
593 | cmd_usage(cmdtp); | 593 | cmd_usage(cmdtp); |
594 | return 1; | 594 | return 1; |
595 | } | 595 | } |
596 | 596 | ||
597 | /* | 597 | /* |
598 | * Chip is always specified. | 598 | * Chip is always specified. |
599 | */ | 599 | */ |
600 | chip = simple_strtoul(argv[1], NULL, 16); | 600 | chip = simple_strtoul(argv[1], NULL, 16); |
601 | 601 | ||
602 | /* | 602 | /* |
603 | * Address is always specified. | 603 | * Address is always specified. |
604 | */ | 604 | */ |
605 | addr = simple_strtoul(argv[2], NULL, 16); | 605 | addr = simple_strtoul(argv[2], NULL, 16); |
606 | alen = 1; | 606 | alen = 1; |
607 | for (j = 0; j < 8; j++) { | 607 | for (j = 0; j < 8; j++) { |
608 | if (argv[2][j] == '.') { | 608 | if (argv[2][j] == '.') { |
609 | alen = argv[2][j+1] - '0'; | 609 | alen = argv[2][j+1] - '0'; |
610 | if (alen > 4) { | 610 | if (alen > 3) { |
611 | cmd_usage(cmdtp); | 611 | cmd_usage(cmdtp); |
612 | return 1; | 612 | return 1; |
613 | } | 613 | } |
614 | break; | 614 | break; |
615 | } else if (argv[2][j] == '\0') | 615 | } else if (argv[2][j] == '\0') |
616 | break; | 616 | break; |
617 | } | 617 | } |
618 | 618 | ||
619 | /* | 619 | /* |
620 | * Length is the number of objects, not number of bytes. | 620 | * Length is the number of objects, not number of bytes. |
621 | */ | 621 | */ |
622 | length = 1; | 622 | length = 1; |
623 | length = simple_strtoul(argv[3], NULL, 16); | 623 | length = simple_strtoul(argv[3], NULL, 16); |
624 | if (length > sizeof(bytes)) | 624 | if (length > sizeof(bytes)) |
625 | length = sizeof(bytes); | 625 | length = sizeof(bytes); |
626 | 626 | ||
627 | /* | 627 | /* |
628 | * The delay time (uSec) is optional. | 628 | * The delay time (uSec) is optional. |
629 | */ | 629 | */ |
630 | delay = 1000; | 630 | delay = 1000; |
631 | if (argc > 3) | 631 | if (argc > 3) |
632 | delay = simple_strtoul(argv[4], NULL, 10); | 632 | delay = simple_strtoul(argv[4], NULL, 10); |
633 | /* | 633 | /* |
634 | * Run the loop... | 634 | * Run the loop... |
635 | */ | 635 | */ |
636 | while (1) { | 636 | while (1) { |
637 | if (i2c_read(chip, addr, alen, bytes, length) != 0) | 637 | if (i2c_read(chip, addr, alen, bytes, length) != 0) |
638 | puts ("Error reading the chip.\n"); | 638 | puts ("Error reading the chip.\n"); |
639 | udelay(delay); | 639 | udelay(delay); |
640 | } | 640 | } |
641 | 641 | ||
642 | /* NOTREACHED */ | 642 | /* NOTREACHED */ |
643 | return 0; | 643 | return 0; |
644 | } | 644 | } |
645 | 645 | ||
646 | /* | 646 | /* |
647 | * The SDRAM command is separately configured because many | 647 | * The SDRAM command is separately configured because many |
648 | * (most?) embedded boards don't use SDRAM DIMMs. | 648 | * (most?) embedded boards don't use SDRAM DIMMs. |
649 | */ | 649 | */ |
650 | #if defined(CONFIG_CMD_SDRAM) | 650 | #if defined(CONFIG_CMD_SDRAM) |
651 | static void print_ddr2_tcyc (u_char const b) | 651 | static void print_ddr2_tcyc (u_char const b) |
652 | { | 652 | { |
653 | printf ("%d.", (b >> 4) & 0x0F); | 653 | printf ("%d.", (b >> 4) & 0x0F); |
654 | switch (b & 0x0F) { | 654 | switch (b & 0x0F) { |
655 | case 0x0: | 655 | case 0x0: |
656 | case 0x1: | 656 | case 0x1: |
657 | case 0x2: | 657 | case 0x2: |
658 | case 0x3: | 658 | case 0x3: |
659 | case 0x4: | 659 | case 0x4: |
660 | case 0x5: | 660 | case 0x5: |
661 | case 0x6: | 661 | case 0x6: |
662 | case 0x7: | 662 | case 0x7: |
663 | case 0x8: | 663 | case 0x8: |
664 | case 0x9: | 664 | case 0x9: |
665 | printf ("%d ns\n", b & 0x0F); | 665 | printf ("%d ns\n", b & 0x0F); |
666 | break; | 666 | break; |
667 | case 0xA: | 667 | case 0xA: |
668 | puts ("25 ns\n"); | 668 | puts ("25 ns\n"); |
669 | break; | 669 | break; |
670 | case 0xB: | 670 | case 0xB: |
671 | puts ("33 ns\n"); | 671 | puts ("33 ns\n"); |
672 | break; | 672 | break; |
673 | case 0xC: | 673 | case 0xC: |
674 | puts ("66 ns\n"); | 674 | puts ("66 ns\n"); |
675 | break; | 675 | break; |
676 | case 0xD: | 676 | case 0xD: |
677 | puts ("75 ns\n"); | 677 | puts ("75 ns\n"); |
678 | break; | 678 | break; |
679 | default: | 679 | default: |
680 | puts ("?? ns\n"); | 680 | puts ("?? ns\n"); |
681 | break; | 681 | break; |
682 | } | 682 | } |
683 | } | 683 | } |
684 | 684 | ||
685 | static void decode_bits (u_char const b, char const *str[], int const do_once) | 685 | static void decode_bits (u_char const b, char const *str[], int const do_once) |
686 | { | 686 | { |
687 | u_char mask; | 687 | u_char mask; |
688 | 688 | ||
689 | for (mask = 0x80; mask != 0x00; mask >>= 1, ++str) { | 689 | for (mask = 0x80; mask != 0x00; mask >>= 1, ++str) { |
690 | if (b & mask) { | 690 | if (b & mask) { |
691 | puts (*str); | 691 | puts (*str); |
692 | if (do_once) | 692 | if (do_once) |
693 | return; | 693 | return; |
694 | } | 694 | } |
695 | } | 695 | } |
696 | } | 696 | } |
697 | 697 | ||
698 | /* | 698 | /* |
699 | * Syntax: | 699 | * Syntax: |
700 | * i2c sdram {i2c_chip} | 700 | * i2c sdram {i2c_chip} |
701 | */ | 701 | */ |
702 | int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 702 | int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
703 | { | 703 | { |
704 | enum { unknown, EDO, SDRAM, DDR2 } type; | 704 | enum { unknown, EDO, SDRAM, DDR2 } type; |
705 | 705 | ||
706 | u_char chip; | 706 | u_char chip; |
707 | u_char data[128]; | 707 | u_char data[128]; |
708 | u_char cksum; | 708 | u_char cksum; |
709 | int j; | 709 | int j; |
710 | 710 | ||
711 | static const char *decode_CAS_DDR2[] = { | 711 | static const char *decode_CAS_DDR2[] = { |
712 | " TBD", " 6", " 5", " 4", " 3", " 2", " TBD", " TBD" | 712 | " TBD", " 6", " 5", " 4", " 3", " 2", " TBD", " TBD" |
713 | }; | 713 | }; |
714 | 714 | ||
715 | static const char *decode_CAS_default[] = { | 715 | static const char *decode_CAS_default[] = { |
716 | " TBD", " 7", " 6", " 5", " 4", " 3", " 2", " 1" | 716 | " TBD", " 7", " 6", " 5", " 4", " 3", " 2", " 1" |
717 | }; | 717 | }; |
718 | 718 | ||
719 | static const char *decode_CS_WE_default[] = { | 719 | static const char *decode_CS_WE_default[] = { |
720 | " TBD", " 6", " 5", " 4", " 3", " 2", " 1", " 0" | 720 | " TBD", " 6", " 5", " 4", " 3", " 2", " 1", " 0" |
721 | }; | 721 | }; |
722 | 722 | ||
723 | static const char *decode_byte21_default[] = { | 723 | static const char *decode_byte21_default[] = { |
724 | " TBD (bit 7)\n", | 724 | " TBD (bit 7)\n", |
725 | " Redundant row address\n", | 725 | " Redundant row address\n", |
726 | " Differential clock input\n", | 726 | " Differential clock input\n", |
727 | " Registerd DQMB inputs\n", | 727 | " Registerd DQMB inputs\n", |
728 | " Buffered DQMB inputs\n", | 728 | " Buffered DQMB inputs\n", |
729 | " On-card PLL\n", | 729 | " On-card PLL\n", |
730 | " Registered address/control lines\n", | 730 | " Registered address/control lines\n", |
731 | " Buffered address/control lines\n" | 731 | " Buffered address/control lines\n" |
732 | }; | 732 | }; |
733 | 733 | ||
734 | static const char *decode_byte22_DDR2[] = { | 734 | static const char *decode_byte22_DDR2[] = { |
735 | " TBD (bit 7)\n", | 735 | " TBD (bit 7)\n", |
736 | " TBD (bit 6)\n", | 736 | " TBD (bit 6)\n", |
737 | " TBD (bit 5)\n", | 737 | " TBD (bit 5)\n", |
738 | " TBD (bit 4)\n", | 738 | " TBD (bit 4)\n", |
739 | " TBD (bit 3)\n", | 739 | " TBD (bit 3)\n", |
740 | " Supports partial array self refresh\n", | 740 | " Supports partial array self refresh\n", |
741 | " Supports 50 ohm ODT\n", | 741 | " Supports 50 ohm ODT\n", |
742 | " Supports weak driver\n" | 742 | " Supports weak driver\n" |
743 | }; | 743 | }; |
744 | 744 | ||
745 | static const char *decode_row_density_DDR2[] = { | 745 | static const char *decode_row_density_DDR2[] = { |
746 | "512 MiB", "256 MiB", "128 MiB", "16 GiB", | 746 | "512 MiB", "256 MiB", "128 MiB", "16 GiB", |
747 | "8 GiB", "4 GiB", "2 GiB", "1 GiB" | 747 | "8 GiB", "4 GiB", "2 GiB", "1 GiB" |
748 | }; | 748 | }; |
749 | 749 | ||
750 | static const char *decode_row_density_default[] = { | 750 | static const char *decode_row_density_default[] = { |
751 | "512 MiB", "256 MiB", "128 MiB", "64 MiB", | 751 | "512 MiB", "256 MiB", "128 MiB", "64 MiB", |
752 | "32 MiB", "16 MiB", "8 MiB", "4 MiB" | 752 | "32 MiB", "16 MiB", "8 MiB", "4 MiB" |
753 | }; | 753 | }; |
754 | 754 | ||
755 | if (argc < 2) { | 755 | if (argc < 2) { |
756 | cmd_usage(cmdtp); | 756 | cmd_usage(cmdtp); |
757 | return 1; | 757 | return 1; |
758 | } | 758 | } |
759 | /* | 759 | /* |
760 | * Chip is always specified. | 760 | * Chip is always specified. |
761 | */ | 761 | */ |
762 | chip = simple_strtoul (argv[1], NULL, 16); | 762 | chip = simple_strtoul (argv[1], NULL, 16); |
763 | 763 | ||
764 | if (i2c_read (chip, 0, 1, data, sizeof (data)) != 0) { | 764 | if (i2c_read (chip, 0, 1, data, sizeof (data)) != 0) { |
765 | puts ("No SDRAM Serial Presence Detect found.\n"); | 765 | puts ("No SDRAM Serial Presence Detect found.\n"); |
766 | return 1; | 766 | return 1; |
767 | } | 767 | } |
768 | 768 | ||
769 | cksum = 0; | 769 | cksum = 0; |
770 | for (j = 0; j < 63; j++) { | 770 | for (j = 0; j < 63; j++) { |
771 | cksum += data[j]; | 771 | cksum += data[j]; |
772 | } | 772 | } |
773 | if (cksum != data[63]) { | 773 | if (cksum != data[63]) { |
774 | printf ("WARNING: Configuration data checksum failure:\n" | 774 | printf ("WARNING: Configuration data checksum failure:\n" |
775 | " is 0x%02x, calculated 0x%02x\n", data[63], cksum); | 775 | " is 0x%02x, calculated 0x%02x\n", data[63], cksum); |
776 | } | 776 | } |
777 | printf ("SPD data revision %d.%d\n", | 777 | printf ("SPD data revision %d.%d\n", |
778 | (data[62] >> 4) & 0x0F, data[62] & 0x0F); | 778 | (data[62] >> 4) & 0x0F, data[62] & 0x0F); |
779 | printf ("Bytes used 0x%02X\n", data[0]); | 779 | printf ("Bytes used 0x%02X\n", data[0]); |
780 | printf ("Serial memory size 0x%02X\n", 1 << data[1]); | 780 | printf ("Serial memory size 0x%02X\n", 1 << data[1]); |
781 | 781 | ||
782 | puts ("Memory type "); | 782 | puts ("Memory type "); |
783 | switch (data[2]) { | 783 | switch (data[2]) { |
784 | case 2: | 784 | case 2: |
785 | type = EDO; | 785 | type = EDO; |
786 | puts ("EDO\n"); | 786 | puts ("EDO\n"); |
787 | break; | 787 | break; |
788 | case 4: | 788 | case 4: |
789 | type = SDRAM; | 789 | type = SDRAM; |
790 | puts ("SDRAM\n"); | 790 | puts ("SDRAM\n"); |
791 | break; | 791 | break; |
792 | case 8: | 792 | case 8: |
793 | type = DDR2; | 793 | type = DDR2; |
794 | puts ("DDR2\n"); | 794 | puts ("DDR2\n"); |
795 | break; | 795 | break; |
796 | default: | 796 | default: |
797 | type = unknown; | 797 | type = unknown; |
798 | puts ("unknown\n"); | 798 | puts ("unknown\n"); |
799 | break; | 799 | break; |
800 | } | 800 | } |
801 | 801 | ||
802 | puts ("Row address bits "); | 802 | puts ("Row address bits "); |
803 | if ((data[3] & 0x00F0) == 0) | 803 | if ((data[3] & 0x00F0) == 0) |
804 | printf ("%d\n", data[3] & 0x0F); | 804 | printf ("%d\n", data[3] & 0x0F); |
805 | else | 805 | else |
806 | printf ("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F); | 806 | printf ("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F); |
807 | 807 | ||
808 | puts ("Column address bits "); | 808 | puts ("Column address bits "); |
809 | if ((data[4] & 0x00F0) == 0) | 809 | if ((data[4] & 0x00F0) == 0) |
810 | printf ("%d\n", data[4] & 0x0F); | 810 | printf ("%d\n", data[4] & 0x0F); |
811 | else | 811 | else |
812 | printf ("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F); | 812 | printf ("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F); |
813 | 813 | ||
814 | switch (type) { | 814 | switch (type) { |
815 | case DDR2: | 815 | case DDR2: |
816 | printf ("Number of ranks %d\n", | 816 | printf ("Number of ranks %d\n", |
817 | (data[5] & 0x07) + 1); | 817 | (data[5] & 0x07) + 1); |
818 | break; | 818 | break; |
819 | default: | 819 | default: |
820 | printf ("Module rows %d\n", data[5]); | 820 | printf ("Module rows %d\n", data[5]); |
821 | break; | 821 | break; |
822 | } | 822 | } |
823 | 823 | ||
824 | switch (type) { | 824 | switch (type) { |
825 | case DDR2: | 825 | case DDR2: |
826 | printf ("Module data width %d bits\n", data[6]); | 826 | printf ("Module data width %d bits\n", data[6]); |
827 | break; | 827 | break; |
828 | default: | 828 | default: |
829 | printf ("Module data width %d bits\n", | 829 | printf ("Module data width %d bits\n", |
830 | (data[7] << 8) | data[6]); | 830 | (data[7] << 8) | data[6]); |
831 | break; | 831 | break; |
832 | } | 832 | } |
833 | 833 | ||
834 | puts ("Interface signal levels "); | 834 | puts ("Interface signal levels "); |
835 | switch(data[8]) { | 835 | switch(data[8]) { |
836 | case 0: puts ("TTL 5.0 V\n"); break; | 836 | case 0: puts ("TTL 5.0 V\n"); break; |
837 | case 1: puts ("LVTTL\n"); break; | 837 | case 1: puts ("LVTTL\n"); break; |
838 | case 2: puts ("HSTL 1.5 V\n"); break; | 838 | case 2: puts ("HSTL 1.5 V\n"); break; |
839 | case 3: puts ("SSTL 3.3 V\n"); break; | 839 | case 3: puts ("SSTL 3.3 V\n"); break; |
840 | case 4: puts ("SSTL 2.5 V\n"); break; | 840 | case 4: puts ("SSTL 2.5 V\n"); break; |
841 | case 5: puts ("SSTL 1.8 V\n"); break; | 841 | case 5: puts ("SSTL 1.8 V\n"); break; |
842 | default: puts ("unknown\n"); break; | 842 | default: puts ("unknown\n"); break; |
843 | } | 843 | } |
844 | 844 | ||
845 | switch (type) { | 845 | switch (type) { |
846 | case DDR2: | 846 | case DDR2: |
847 | printf ("SDRAM cycle time "); | 847 | printf ("SDRAM cycle time "); |
848 | print_ddr2_tcyc (data[9]); | 848 | print_ddr2_tcyc (data[9]); |
849 | break; | 849 | break; |
850 | default: | 850 | default: |
851 | printf ("SDRAM cycle time %d.%d ns\n", | 851 | printf ("SDRAM cycle time %d.%d ns\n", |
852 | (data[9] >> 4) & 0x0F, data[9] & 0x0F); | 852 | (data[9] >> 4) & 0x0F, data[9] & 0x0F); |
853 | break; | 853 | break; |
854 | } | 854 | } |
855 | 855 | ||
856 | switch (type) { | 856 | switch (type) { |
857 | case DDR2: | 857 | case DDR2: |
858 | printf ("SDRAM access time 0.%d%d ns\n", | 858 | printf ("SDRAM access time 0.%d%d ns\n", |
859 | (data[10] >> 4) & 0x0F, data[10] & 0x0F); | 859 | (data[10] >> 4) & 0x0F, data[10] & 0x0F); |
860 | break; | 860 | break; |
861 | default: | 861 | default: |
862 | printf ("SDRAM access time %d.%d ns\n", | 862 | printf ("SDRAM access time %d.%d ns\n", |
863 | (data[10] >> 4) & 0x0F, data[10] & 0x0F); | 863 | (data[10] >> 4) & 0x0F, data[10] & 0x0F); |
864 | break; | 864 | break; |
865 | } | 865 | } |
866 | 866 | ||
867 | puts ("EDC configuration "); | 867 | puts ("EDC configuration "); |
868 | switch (data[11]) { | 868 | switch (data[11]) { |
869 | case 0: puts ("None\n"); break; | 869 | case 0: puts ("None\n"); break; |
870 | case 1: puts ("Parity\n"); break; | 870 | case 1: puts ("Parity\n"); break; |
871 | case 2: puts ("ECC\n"); break; | 871 | case 2: puts ("ECC\n"); break; |
872 | default: puts ("unknown\n"); break; | 872 | default: puts ("unknown\n"); break; |
873 | } | 873 | } |
874 | 874 | ||
875 | if ((data[12] & 0x80) == 0) | 875 | if ((data[12] & 0x80) == 0) |
876 | puts ("No self refresh, rate "); | 876 | puts ("No self refresh, rate "); |
877 | else | 877 | else |
878 | puts ("Self refresh, rate "); | 878 | puts ("Self refresh, rate "); |
879 | 879 | ||
880 | switch(data[12] & 0x7F) { | 880 | switch(data[12] & 0x7F) { |
881 | case 0: puts ("15.625 us\n"); break; | 881 | case 0: puts ("15.625 us\n"); break; |
882 | case 1: puts ("3.9 us\n"); break; | 882 | case 1: puts ("3.9 us\n"); break; |
883 | case 2: puts ("7.8 us\n"); break; | 883 | case 2: puts ("7.8 us\n"); break; |
884 | case 3: puts ("31.3 us\n"); break; | 884 | case 3: puts ("31.3 us\n"); break; |
885 | case 4: puts ("62.5 us\n"); break; | 885 | case 4: puts ("62.5 us\n"); break; |
886 | case 5: puts ("125 us\n"); break; | 886 | case 5: puts ("125 us\n"); break; |
887 | default: puts ("unknown\n"); break; | 887 | default: puts ("unknown\n"); break; |
888 | } | 888 | } |
889 | 889 | ||
890 | switch (type) { | 890 | switch (type) { |
891 | case DDR2: | 891 | case DDR2: |
892 | printf ("SDRAM width (primary) %d\n", data[13]); | 892 | printf ("SDRAM width (primary) %d\n", data[13]); |
893 | break; | 893 | break; |
894 | default: | 894 | default: |
895 | printf ("SDRAM width (primary) %d\n", data[13] & 0x7F); | 895 | printf ("SDRAM width (primary) %d\n", data[13] & 0x7F); |
896 | if ((data[13] & 0x80) != 0) { | 896 | if ((data[13] & 0x80) != 0) { |
897 | printf (" (second bank) %d\n", | 897 | printf (" (second bank) %d\n", |
898 | 2 * (data[13] & 0x7F)); | 898 | 2 * (data[13] & 0x7F)); |
899 | } | 899 | } |
900 | break; | 900 | break; |
901 | } | 901 | } |
902 | 902 | ||
903 | switch (type) { | 903 | switch (type) { |
904 | case DDR2: | 904 | case DDR2: |
905 | if (data[14] != 0) | 905 | if (data[14] != 0) |
906 | printf ("EDC width %d\n", data[14]); | 906 | printf ("EDC width %d\n", data[14]); |
907 | break; | 907 | break; |
908 | default: | 908 | default: |
909 | if (data[14] != 0) { | 909 | if (data[14] != 0) { |
910 | printf ("EDC width %d\n", | 910 | printf ("EDC width %d\n", |
911 | data[14] & 0x7F); | 911 | data[14] & 0x7F); |
912 | 912 | ||
913 | if ((data[14] & 0x80) != 0) { | 913 | if ((data[14] & 0x80) != 0) { |
914 | printf (" (second bank) %d\n", | 914 | printf (" (second bank) %d\n", |
915 | 2 * (data[14] & 0x7F)); | 915 | 2 * (data[14] & 0x7F)); |
916 | } | 916 | } |
917 | } | 917 | } |
918 | break; | 918 | break; |
919 | } | 919 | } |
920 | 920 | ||
921 | if (DDR2 != type) { | 921 | if (DDR2 != type) { |
922 | printf ("Min clock delay, back-to-back random column addresses " | 922 | printf ("Min clock delay, back-to-back random column addresses " |
923 | "%d\n", data[15]); | 923 | "%d\n", data[15]); |
924 | } | 924 | } |
925 | 925 | ||
926 | puts ("Burst length(s) "); | 926 | puts ("Burst length(s) "); |
927 | if (data[16] & 0x80) puts (" Page"); | 927 | if (data[16] & 0x80) puts (" Page"); |
928 | if (data[16] & 0x08) puts (" 8"); | 928 | if (data[16] & 0x08) puts (" 8"); |
929 | if (data[16] & 0x04) puts (" 4"); | 929 | if (data[16] & 0x04) puts (" 4"); |
930 | if (data[16] & 0x02) puts (" 2"); | 930 | if (data[16] & 0x02) puts (" 2"); |
931 | if (data[16] & 0x01) puts (" 1"); | 931 | if (data[16] & 0x01) puts (" 1"); |
932 | putc ('\n'); | 932 | putc ('\n'); |
933 | printf ("Number of banks %d\n", data[17]); | 933 | printf ("Number of banks %d\n", data[17]); |
934 | 934 | ||
935 | switch (type) { | 935 | switch (type) { |
936 | case DDR2: | 936 | case DDR2: |
937 | puts ("CAS latency(s) "); | 937 | puts ("CAS latency(s) "); |
938 | decode_bits (data[18], decode_CAS_DDR2, 0); | 938 | decode_bits (data[18], decode_CAS_DDR2, 0); |
939 | putc ('\n'); | 939 | putc ('\n'); |
940 | break; | 940 | break; |
941 | default: | 941 | default: |
942 | puts ("CAS latency(s) "); | 942 | puts ("CAS latency(s) "); |
943 | decode_bits (data[18], decode_CAS_default, 0); | 943 | decode_bits (data[18], decode_CAS_default, 0); |
944 | putc ('\n'); | 944 | putc ('\n'); |
945 | break; | 945 | break; |
946 | } | 946 | } |
947 | 947 | ||
948 | if (DDR2 != type) { | 948 | if (DDR2 != type) { |
949 | puts ("CS latency(s) "); | 949 | puts ("CS latency(s) "); |
950 | decode_bits (data[19], decode_CS_WE_default, 0); | 950 | decode_bits (data[19], decode_CS_WE_default, 0); |
951 | putc ('\n'); | 951 | putc ('\n'); |
952 | } | 952 | } |
953 | 953 | ||
954 | if (DDR2 != type) { | 954 | if (DDR2 != type) { |
955 | puts ("WE latency(s) "); | 955 | puts ("WE latency(s) "); |
956 | decode_bits (data[20], decode_CS_WE_default, 0); | 956 | decode_bits (data[20], decode_CS_WE_default, 0); |
957 | putc ('\n'); | 957 | putc ('\n'); |
958 | } | 958 | } |
959 | 959 | ||
960 | switch (type) { | 960 | switch (type) { |
961 | case DDR2: | 961 | case DDR2: |
962 | puts ("Module attributes:\n"); | 962 | puts ("Module attributes:\n"); |
963 | if (data[21] & 0x80) | 963 | if (data[21] & 0x80) |
964 | puts (" TBD (bit 7)\n"); | 964 | puts (" TBD (bit 7)\n"); |
965 | if (data[21] & 0x40) | 965 | if (data[21] & 0x40) |
966 | puts (" Analysis probe installed\n"); | 966 | puts (" Analysis probe installed\n"); |
967 | if (data[21] & 0x20) | 967 | if (data[21] & 0x20) |
968 | puts (" TBD (bit 5)\n"); | 968 | puts (" TBD (bit 5)\n"); |
969 | if (data[21] & 0x10) | 969 | if (data[21] & 0x10) |
970 | puts (" FET switch external enable\n"); | 970 | puts (" FET switch external enable\n"); |
971 | printf (" %d PLLs on DIMM\n", (data[21] >> 2) & 0x03); | 971 | printf (" %d PLLs on DIMM\n", (data[21] >> 2) & 0x03); |
972 | if (data[20] & 0x11) { | 972 | if (data[20] & 0x11) { |
973 | printf (" %d active registers on DIMM\n", | 973 | printf (" %d active registers on DIMM\n", |
974 | (data[21] & 0x03) + 1); | 974 | (data[21] & 0x03) + 1); |
975 | } | 975 | } |
976 | break; | 976 | break; |
977 | default: | 977 | default: |
978 | puts ("Module attributes:\n"); | 978 | puts ("Module attributes:\n"); |
979 | if (!data[21]) | 979 | if (!data[21]) |
980 | puts (" (none)\n"); | 980 | puts (" (none)\n"); |
981 | else | 981 | else |
982 | decode_bits (data[21], decode_byte21_default, 0); | 982 | decode_bits (data[21], decode_byte21_default, 0); |
983 | break; | 983 | break; |
984 | } | 984 | } |
985 | 985 | ||
986 | switch (type) { | 986 | switch (type) { |
987 | case DDR2: | 987 | case DDR2: |
988 | decode_bits (data[22], decode_byte22_DDR2, 0); | 988 | decode_bits (data[22], decode_byte22_DDR2, 0); |
989 | break; | 989 | break; |
990 | default: | 990 | default: |
991 | puts ("Device attributes:\n"); | 991 | puts ("Device attributes:\n"); |
992 | if (data[22] & 0x80) puts (" TBD (bit 7)\n"); | 992 | if (data[22] & 0x80) puts (" TBD (bit 7)\n"); |
993 | if (data[22] & 0x40) puts (" TBD (bit 6)\n"); | 993 | if (data[22] & 0x40) puts (" TBD (bit 6)\n"); |
994 | if (data[22] & 0x20) puts (" Upper Vcc tolerance 5%\n"); | 994 | if (data[22] & 0x20) puts (" Upper Vcc tolerance 5%\n"); |
995 | else puts (" Upper Vcc tolerance 10%\n"); | 995 | else puts (" Upper Vcc tolerance 10%\n"); |
996 | if (data[22] & 0x10) puts (" Lower Vcc tolerance 5%\n"); | 996 | if (data[22] & 0x10) puts (" Lower Vcc tolerance 5%\n"); |
997 | else puts (" Lower Vcc tolerance 10%\n"); | 997 | else puts (" Lower Vcc tolerance 10%\n"); |
998 | if (data[22] & 0x08) puts (" Supports write1/read burst\n"); | 998 | if (data[22] & 0x08) puts (" Supports write1/read burst\n"); |
999 | if (data[22] & 0x04) puts (" Supports precharge all\n"); | 999 | if (data[22] & 0x04) puts (" Supports precharge all\n"); |
1000 | if (data[22] & 0x02) puts (" Supports auto precharge\n"); | 1000 | if (data[22] & 0x02) puts (" Supports auto precharge\n"); |
1001 | if (data[22] & 0x01) puts (" Supports early RAS# precharge\n"); | 1001 | if (data[22] & 0x01) puts (" Supports early RAS# precharge\n"); |
1002 | break; | 1002 | break; |
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | switch (type) { | 1005 | switch (type) { |
1006 | case DDR2: | 1006 | case DDR2: |
1007 | printf ("SDRAM cycle time (2nd highest CAS latency) "); | 1007 | printf ("SDRAM cycle time (2nd highest CAS latency) "); |
1008 | print_ddr2_tcyc (data[23]); | 1008 | print_ddr2_tcyc (data[23]); |
1009 | break; | 1009 | break; |
1010 | default: | 1010 | default: |
1011 | printf ("SDRAM cycle time (2nd highest CAS latency) %d." | 1011 | printf ("SDRAM cycle time (2nd highest CAS latency) %d." |
1012 | "%d ns\n", (data[23] >> 4) & 0x0F, data[23] & 0x0F); | 1012 | "%d ns\n", (data[23] >> 4) & 0x0F, data[23] & 0x0F); |
1013 | break; | 1013 | break; |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | switch (type) { | 1016 | switch (type) { |
1017 | case DDR2: | 1017 | case DDR2: |
1018 | printf ("SDRAM access from clock (2nd highest CAS latency) 0." | 1018 | printf ("SDRAM access from clock (2nd highest CAS latency) 0." |
1019 | "%d%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F); | 1019 | "%d%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F); |
1020 | break; | 1020 | break; |
1021 | default: | 1021 | default: |
1022 | printf ("SDRAM access from clock (2nd highest CAS latency) %d." | 1022 | printf ("SDRAM access from clock (2nd highest CAS latency) %d." |
1023 | "%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F); | 1023 | "%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F); |
1024 | break; | 1024 | break; |
1025 | } | 1025 | } |
1026 | 1026 | ||
1027 | switch (type) { | 1027 | switch (type) { |
1028 | case DDR2: | 1028 | case DDR2: |
1029 | printf ("SDRAM cycle time (3rd highest CAS latency) "); | 1029 | printf ("SDRAM cycle time (3rd highest CAS latency) "); |
1030 | print_ddr2_tcyc (data[25]); | 1030 | print_ddr2_tcyc (data[25]); |
1031 | break; | 1031 | break; |
1032 | default: | 1032 | default: |
1033 | printf ("SDRAM cycle time (3rd highest CAS latency) %d." | 1033 | printf ("SDRAM cycle time (3rd highest CAS latency) %d." |
1034 | "%d ns\n", (data[25] >> 4) & 0x0F, data[25] & 0x0F); | 1034 | "%d ns\n", (data[25] >> 4) & 0x0F, data[25] & 0x0F); |
1035 | break; | 1035 | break; |
1036 | } | 1036 | } |
1037 | 1037 | ||
1038 | switch (type) { | 1038 | switch (type) { |
1039 | case DDR2: | 1039 | case DDR2: |
1040 | printf ("SDRAM access from clock (3rd highest CAS latency) 0." | 1040 | printf ("SDRAM access from clock (3rd highest CAS latency) 0." |
1041 | "%d%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F); | 1041 | "%d%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F); |
1042 | break; | 1042 | break; |
1043 | default: | 1043 | default: |
1044 | printf ("SDRAM access from clock (3rd highest CAS latency) %d." | 1044 | printf ("SDRAM access from clock (3rd highest CAS latency) %d." |
1045 | "%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F); | 1045 | "%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F); |
1046 | break; | 1046 | break; |
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | switch (type) { | 1049 | switch (type) { |
1050 | case DDR2: | 1050 | case DDR2: |
1051 | printf ("Minimum row precharge %d.%02d ns\n", | 1051 | printf ("Minimum row precharge %d.%02d ns\n", |
1052 | (data[27] >> 2) & 0x3F, 25 * (data[27] & 0x03)); | 1052 | (data[27] >> 2) & 0x3F, 25 * (data[27] & 0x03)); |
1053 | break; | 1053 | break; |
1054 | default: | 1054 | default: |
1055 | printf ("Minimum row precharge %d ns\n", data[27]); | 1055 | printf ("Minimum row precharge %d ns\n", data[27]); |
1056 | break; | 1056 | break; |
1057 | } | 1057 | } |
1058 | 1058 | ||
1059 | switch (type) { | 1059 | switch (type) { |
1060 | case DDR2: | 1060 | case DDR2: |
1061 | printf ("Row active to row active min %d.%02d ns\n", | 1061 | printf ("Row active to row active min %d.%02d ns\n", |
1062 | (data[28] >> 2) & 0x3F, 25 * (data[28] & 0x03)); | 1062 | (data[28] >> 2) & 0x3F, 25 * (data[28] & 0x03)); |
1063 | break; | 1063 | break; |
1064 | default: | 1064 | default: |
1065 | printf ("Row active to row active min %d ns\n", data[28]); | 1065 | printf ("Row active to row active min %d ns\n", data[28]); |
1066 | break; | 1066 | break; |
1067 | } | 1067 | } |
1068 | 1068 | ||
1069 | switch (type) { | 1069 | switch (type) { |
1070 | case DDR2: | 1070 | case DDR2: |
1071 | printf ("RAS to CAS delay min %d.%02d ns\n", | 1071 | printf ("RAS to CAS delay min %d.%02d ns\n", |
1072 | (data[29] >> 2) & 0x3F, 25 * (data[29] & 0x03)); | 1072 | (data[29] >> 2) & 0x3F, 25 * (data[29] & 0x03)); |
1073 | break; | 1073 | break; |
1074 | default: | 1074 | default: |
1075 | printf ("RAS to CAS delay min %d ns\n", data[29]); | 1075 | printf ("RAS to CAS delay min %d ns\n", data[29]); |
1076 | break; | 1076 | break; |
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | printf ("Minimum RAS pulse width %d ns\n", data[30]); | 1079 | printf ("Minimum RAS pulse width %d ns\n", data[30]); |
1080 | 1080 | ||
1081 | switch (type) { | 1081 | switch (type) { |
1082 | case DDR2: | 1082 | case DDR2: |
1083 | puts ("Density of each row "); | 1083 | puts ("Density of each row "); |
1084 | decode_bits (data[31], decode_row_density_DDR2, 1); | 1084 | decode_bits (data[31], decode_row_density_DDR2, 1); |
1085 | putc ('\n'); | 1085 | putc ('\n'); |
1086 | break; | 1086 | break; |
1087 | default: | 1087 | default: |
1088 | puts ("Density of each row "); | 1088 | puts ("Density of each row "); |
1089 | decode_bits (data[31], decode_row_density_default, 1); | 1089 | decode_bits (data[31], decode_row_density_default, 1); |
1090 | putc ('\n'); | 1090 | putc ('\n'); |
1091 | break; | 1091 | break; |
1092 | } | 1092 | } |
1093 | 1093 | ||
1094 | switch (type) { | 1094 | switch (type) { |
1095 | case DDR2: | 1095 | case DDR2: |
1096 | puts ("Command and Address setup "); | 1096 | puts ("Command and Address setup "); |
1097 | if (data[32] >= 0xA0) { | 1097 | if (data[32] >= 0xA0) { |
1098 | printf ("1.%d%d ns\n", | 1098 | printf ("1.%d%d ns\n", |
1099 | ((data[32] >> 4) & 0x0F) - 10, data[32] & 0x0F); | 1099 | ((data[32] >> 4) & 0x0F) - 10, data[32] & 0x0F); |
1100 | } else { | 1100 | } else { |
1101 | printf ("0.%d%d ns\n", | 1101 | printf ("0.%d%d ns\n", |
1102 | ((data[32] >> 4) & 0x0F), data[32] & 0x0F); | 1102 | ((data[32] >> 4) & 0x0F), data[32] & 0x0F); |
1103 | } | 1103 | } |
1104 | break; | 1104 | break; |
1105 | default: | 1105 | default: |
1106 | printf ("Command and Address setup %c%d.%d ns\n", | 1106 | printf ("Command and Address setup %c%d.%d ns\n", |
1107 | (data[32] & 0x80) ? '-' : '+', | 1107 | (data[32] & 0x80) ? '-' : '+', |
1108 | (data[32] >> 4) & 0x07, data[32] & 0x0F); | 1108 | (data[32] >> 4) & 0x07, data[32] & 0x0F); |
1109 | break; | 1109 | break; |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | switch (type) { | 1112 | switch (type) { |
1113 | case DDR2: | 1113 | case DDR2: |
1114 | puts ("Command and Address hold "); | 1114 | puts ("Command and Address hold "); |
1115 | if (data[33] >= 0xA0) { | 1115 | if (data[33] >= 0xA0) { |
1116 | printf ("1.%d%d ns\n", | 1116 | printf ("1.%d%d ns\n", |
1117 | ((data[33] >> 4) & 0x0F) - 10, data[33] & 0x0F); | 1117 | ((data[33] >> 4) & 0x0F) - 10, data[33] & 0x0F); |
1118 | } else { | 1118 | } else { |
1119 | printf ("0.%d%d ns\n", | 1119 | printf ("0.%d%d ns\n", |
1120 | ((data[33] >> 4) & 0x0F), data[33] & 0x0F); | 1120 | ((data[33] >> 4) & 0x0F), data[33] & 0x0F); |
1121 | } | 1121 | } |
1122 | break; | 1122 | break; |
1123 | default: | 1123 | default: |
1124 | printf ("Command and Address hold %c%d.%d ns\n", | 1124 | printf ("Command and Address hold %c%d.%d ns\n", |
1125 | (data[33] & 0x80) ? '-' : '+', | 1125 | (data[33] & 0x80) ? '-' : '+', |
1126 | (data[33] >> 4) & 0x07, data[33] & 0x0F); | 1126 | (data[33] >> 4) & 0x07, data[33] & 0x0F); |
1127 | break; | 1127 | break; |
1128 | } | 1128 | } |
1129 | 1129 | ||
1130 | switch (type) { | 1130 | switch (type) { |
1131 | case DDR2: | 1131 | case DDR2: |
1132 | printf ("Data signal input setup 0.%d%d ns\n", | 1132 | printf ("Data signal input setup 0.%d%d ns\n", |
1133 | (data[34] >> 4) & 0x0F, data[34] & 0x0F); | 1133 | (data[34] >> 4) & 0x0F, data[34] & 0x0F); |
1134 | break; | 1134 | break; |
1135 | default: | 1135 | default: |
1136 | printf ("Data signal input setup %c%d.%d ns\n", | 1136 | printf ("Data signal input setup %c%d.%d ns\n", |
1137 | (data[34] & 0x80) ? '-' : '+', | 1137 | (data[34] & 0x80) ? '-' : '+', |
1138 | (data[34] >> 4) & 0x07, data[34] & 0x0F); | 1138 | (data[34] >> 4) & 0x07, data[34] & 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 hold 0.%d%d ns\n", | 1144 | printf ("Data signal input hold 0.%d%d ns\n", |
1145 | (data[35] >> 4) & 0x0F, data[35] & 0x0F); | 1145 | (data[35] >> 4) & 0x0F, data[35] & 0x0F); |
1146 | break; | 1146 | break; |
1147 | default: | 1147 | default: |
1148 | printf ("Data signal input hold %c%d.%d ns\n", | 1148 | printf ("Data signal input hold %c%d.%d ns\n", |
1149 | (data[35] & 0x80) ? '-' : '+', | 1149 | (data[35] & 0x80) ? '-' : '+', |
1150 | (data[35] >> 4) & 0x07, data[35] & 0x0F); | 1150 | (data[35] >> 4) & 0x07, data[35] & 0x0F); |
1151 | break; | 1151 | break; |
1152 | } | 1152 | } |
1153 | 1153 | ||
1154 | puts ("Manufacturer's JEDEC ID "); | 1154 | puts ("Manufacturer's JEDEC ID "); |
1155 | for (j = 64; j <= 71; j++) | 1155 | for (j = 64; j <= 71; j++) |
1156 | printf ("%02X ", data[j]); | 1156 | printf ("%02X ", data[j]); |
1157 | putc ('\n'); | 1157 | putc ('\n'); |
1158 | printf ("Manufacturing Location %02X\n", data[72]); | 1158 | printf ("Manufacturing Location %02X\n", data[72]); |
1159 | puts ("Manufacturer's Part Number "); | 1159 | puts ("Manufacturer's Part Number "); |
1160 | for (j = 73; j <= 90; j++) | 1160 | for (j = 73; j <= 90; j++) |
1161 | printf ("%02X ", data[j]); | 1161 | printf ("%02X ", data[j]); |
1162 | putc ('\n'); | 1162 | putc ('\n'); |
1163 | printf ("Revision Code %02X %02X\n", data[91], data[92]); | 1163 | printf ("Revision Code %02X %02X\n", data[91], data[92]); |
1164 | printf ("Manufacturing Date %02X %02X\n", data[93], data[94]); | 1164 | printf ("Manufacturing Date %02X %02X\n", data[93], data[94]); |
1165 | puts ("Assembly Serial Number "); | 1165 | puts ("Assembly Serial Number "); |
1166 | for (j = 95; j <= 98; j++) | 1166 | for (j = 95; j <= 98; j++) |
1167 | printf ("%02X ", data[j]); | 1167 | printf ("%02X ", data[j]); |
1168 | putc ('\n'); | 1168 | putc ('\n'); |
1169 | 1169 | ||
1170 | if (DDR2 != type) { | 1170 | if (DDR2 != type) { |
1171 | printf ("Speed rating PC%d\n", | 1171 | printf ("Speed rating PC%d\n", |
1172 | data[126] == 0x66 ? 66 : data[126]); | 1172 | data[126] == 0x66 ? 66 : data[126]); |
1173 | } | 1173 | } |
1174 | return 0; | 1174 | return 0; |
1175 | } | 1175 | } |
1176 | #endif | 1176 | #endif |
1177 | 1177 | ||
1178 | #if defined(CONFIG_I2C_MUX) | 1178 | #if defined(CONFIG_I2C_MUX) |
1179 | int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 1179 | int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
1180 | { | 1180 | { |
1181 | int ret=0; | 1181 | int ret=0; |
1182 | 1182 | ||
1183 | if (argc == 1) { | 1183 | if (argc == 1) { |
1184 | /* show all busses */ | 1184 | /* show all busses */ |
1185 | I2C_MUX *mux; | 1185 | I2C_MUX *mux; |
1186 | I2C_MUX_DEVICE *device = i2c_mux_devices; | 1186 | I2C_MUX_DEVICE *device = i2c_mux_devices; |
1187 | 1187 | ||
1188 | printf ("Busses reached over muxes:\n"); | 1188 | printf ("Busses reached over muxes:\n"); |
1189 | while (device != NULL) { | 1189 | while (device != NULL) { |
1190 | printf ("Bus ID: %x\n", device->busid); | 1190 | printf ("Bus ID: %x\n", device->busid); |
1191 | printf (" reached over Mux(es):\n"); | 1191 | printf (" reached over Mux(es):\n"); |
1192 | mux = device->mux; | 1192 | mux = device->mux; |
1193 | while (mux != NULL) { | 1193 | while (mux != NULL) { |
1194 | printf (" %s@%x ch: %x\n", mux->name, mux->chip, mux->channel); | 1194 | printf (" %s@%x ch: %x\n", mux->name, mux->chip, mux->channel); |
1195 | mux = mux->next; | 1195 | mux = mux->next; |
1196 | } | 1196 | } |
1197 | device = device->next; | 1197 | device = device->next; |
1198 | } | 1198 | } |
1199 | } else { | 1199 | } else { |
1200 | I2C_MUX_DEVICE *dev; | 1200 | I2C_MUX_DEVICE *dev; |
1201 | 1201 | ||
1202 | dev = i2c_mux_ident_muxstring ((uchar *)argv[1]); | 1202 | dev = i2c_mux_ident_muxstring ((uchar *)argv[1]); |
1203 | ret = 0; | 1203 | ret = 0; |
1204 | } | 1204 | } |
1205 | return ret; | 1205 | return ret; |
1206 | } | 1206 | } |
1207 | #endif /* CONFIG_I2C_MUX */ | 1207 | #endif /* CONFIG_I2C_MUX */ |
1208 | 1208 | ||
1209 | #if defined(CONFIG_I2C_MULTI_BUS) | 1209 | #if defined(CONFIG_I2C_MULTI_BUS) |
1210 | int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 1210 | int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
1211 | { | 1211 | { |
1212 | int bus_idx, ret=0; | 1212 | int bus_idx, ret=0; |
1213 | 1213 | ||
1214 | if (argc == 1) | 1214 | if (argc == 1) |
1215 | /* querying current setting */ | 1215 | /* querying current setting */ |
1216 | printf("Current bus is %d\n", i2c_get_bus_num()); | 1216 | printf("Current bus is %d\n", i2c_get_bus_num()); |
1217 | else { | 1217 | else { |
1218 | bus_idx = simple_strtoul(argv[1], NULL, 10); | 1218 | bus_idx = simple_strtoul(argv[1], NULL, 10); |
1219 | printf("Setting bus to %d\n", bus_idx); | 1219 | printf("Setting bus to %d\n", bus_idx); |
1220 | ret = i2c_set_bus_num(bus_idx); | 1220 | ret = i2c_set_bus_num(bus_idx); |
1221 | if (ret) | 1221 | if (ret) |
1222 | printf("Failure changing bus number (%d)\n", ret); | 1222 | printf("Failure changing bus number (%d)\n", ret); |
1223 | } | 1223 | } |
1224 | return ret; | 1224 | return ret; |
1225 | } | 1225 | } |
1226 | #endif /* CONFIG_I2C_MULTI_BUS */ | 1226 | #endif /* CONFIG_I2C_MULTI_BUS */ |
1227 | 1227 | ||
1228 | int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 1228 | int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
1229 | { | 1229 | { |
1230 | int speed, ret=0; | 1230 | int speed, ret=0; |
1231 | 1231 | ||
1232 | if (argc == 1) | 1232 | if (argc == 1) |
1233 | /* querying current speed */ | 1233 | /* querying current speed */ |
1234 | printf("Current bus speed=%d\n", i2c_get_bus_speed()); | 1234 | printf("Current bus speed=%d\n", i2c_get_bus_speed()); |
1235 | else { | 1235 | else { |
1236 | speed = simple_strtoul(argv[1], NULL, 10); | 1236 | speed = simple_strtoul(argv[1], NULL, 10); |
1237 | printf("Setting bus speed to %d Hz\n", speed); | 1237 | printf("Setting bus speed to %d Hz\n", speed); |
1238 | ret = i2c_set_bus_speed(speed); | 1238 | ret = i2c_set_bus_speed(speed); |
1239 | if (ret) | 1239 | if (ret) |
1240 | printf("Failure changing bus speed (%d)\n", ret); | 1240 | printf("Failure changing bus speed (%d)\n", ret); |
1241 | } | 1241 | } |
1242 | return ret; | 1242 | return ret; |
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 1245 | int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
1246 | { | 1246 | { |
1247 | /* Strip off leading 'i2c' command argument */ | 1247 | /* Strip off leading 'i2c' command argument */ |
1248 | argc--; | 1248 | argc--; |
1249 | argv++; | 1249 | argv++; |
1250 | 1250 | ||
1251 | #if defined(CONFIG_I2C_MUX) | 1251 | #if defined(CONFIG_I2C_MUX) |
1252 | if (!strncmp(argv[0], "bu", 2)) | 1252 | if (!strncmp(argv[0], "bu", 2)) |
1253 | return do_i2c_add_bus(cmdtp, flag, argc, argv); | 1253 | return do_i2c_add_bus(cmdtp, flag, argc, argv); |
1254 | #endif /* CONFIG_I2C_MUX */ | 1254 | #endif /* CONFIG_I2C_MUX */ |
1255 | if (!strncmp(argv[0], "sp", 2)) | 1255 | if (!strncmp(argv[0], "sp", 2)) |
1256 | return do_i2c_bus_speed(cmdtp, flag, argc, argv); | 1256 | return do_i2c_bus_speed(cmdtp, flag, argc, argv); |
1257 | #if defined(CONFIG_I2C_MULTI_BUS) | 1257 | #if defined(CONFIG_I2C_MULTI_BUS) |
1258 | if (!strncmp(argv[0], "de", 2)) | 1258 | if (!strncmp(argv[0], "de", 2)) |
1259 | return do_i2c_bus_num(cmdtp, flag, argc, argv); | 1259 | return do_i2c_bus_num(cmdtp, flag, argc, argv); |
1260 | #endif /* CONFIG_I2C_MULTI_BUS */ | 1260 | #endif /* CONFIG_I2C_MULTI_BUS */ |
1261 | if (!strncmp(argv[0], "md", 2)) | 1261 | if (!strncmp(argv[0], "md", 2)) |
1262 | return do_i2c_md(cmdtp, flag, argc, argv); | 1262 | return do_i2c_md(cmdtp, flag, argc, argv); |
1263 | if (!strncmp(argv[0], "mm", 2)) | 1263 | if (!strncmp(argv[0], "mm", 2)) |
1264 | return mod_i2c_mem (cmdtp, 1, flag, argc, argv); | 1264 | return mod_i2c_mem (cmdtp, 1, flag, argc, argv); |
1265 | if (!strncmp(argv[0], "mw", 2)) | 1265 | if (!strncmp(argv[0], "mw", 2)) |
1266 | return do_i2c_mw(cmdtp, flag, argc, argv); | 1266 | return do_i2c_mw(cmdtp, flag, argc, argv); |
1267 | if (!strncmp(argv[0], "nm", 2)) | 1267 | if (!strncmp(argv[0], "nm", 2)) |
1268 | return mod_i2c_mem (cmdtp, 0, flag, argc, argv); | 1268 | return mod_i2c_mem (cmdtp, 0, flag, argc, argv); |
1269 | if (!strncmp(argv[0], "cr", 2)) | 1269 | if (!strncmp(argv[0], "cr", 2)) |
1270 | return do_i2c_crc(cmdtp, flag, argc, argv); | 1270 | return do_i2c_crc(cmdtp, flag, argc, argv); |
1271 | if (!strncmp(argv[0], "pr", 2)) | 1271 | if (!strncmp(argv[0], "pr", 2)) |
1272 | return do_i2c_probe(cmdtp, flag, argc, argv); | 1272 | return do_i2c_probe(cmdtp, flag, argc, argv); |
1273 | if (!strncmp(argv[0], "re", 2)) { | 1273 | if (!strncmp(argv[0], "re", 2)) { |
1274 | i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); | 1274 | i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); |
1275 | return 0; | 1275 | return 0; |
1276 | } | 1276 | } |
1277 | if (!strncmp(argv[0], "lo", 2)) | 1277 | if (!strncmp(argv[0], "lo", 2)) |
1278 | return do_i2c_loop(cmdtp, flag, argc, argv); | 1278 | return do_i2c_loop(cmdtp, flag, argc, argv); |
1279 | #if defined(CONFIG_CMD_SDRAM) | 1279 | #if defined(CONFIG_CMD_SDRAM) |
1280 | if (!strncmp(argv[0], "sd", 2)) | 1280 | if (!strncmp(argv[0], "sd", 2)) |
1281 | return do_sdram(cmdtp, flag, argc, argv); | 1281 | return do_sdram(cmdtp, flag, argc, argv); |
1282 | #endif | 1282 | #endif |
1283 | cmd_usage(cmdtp); | 1283 | cmd_usage(cmdtp); |
1284 | return 0; | 1284 | return 0; |
1285 | } | 1285 | } |
1286 | 1286 | ||
1287 | /***************************************************/ | 1287 | /***************************************************/ |
1288 | 1288 | ||
1289 | U_BOOT_CMD( | 1289 | U_BOOT_CMD( |
1290 | i2c, 6, 1, do_i2c, | 1290 | i2c, 6, 1, do_i2c, |
1291 | "I2C sub-system", | 1291 | "I2C sub-system", |
1292 | "speed [speed] - show or set I2C bus speed\n" | 1292 | "speed [speed] - show or set I2C bus speed\n" |
1293 | #if defined(CONFIG_I2C_MUX) | 1293 | #if defined(CONFIG_I2C_MUX) |
1294 | "i2c bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes\n" | 1294 | "i2c bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes\n" |
1295 | #endif /* CONFIG_I2C_MUX */ | 1295 | #endif /* CONFIG_I2C_MUX */ |
1296 | #if defined(CONFIG_I2C_MULTI_BUS) | 1296 | #if defined(CONFIG_I2C_MULTI_BUS) |
1297 | "i2c dev [dev] - show or set current I2C bus\n" | 1297 | "i2c dev [dev] - show or set current I2C bus\n" |
1298 | #endif /* CONFIG_I2C_MULTI_BUS */ | 1298 | #endif /* CONFIG_I2C_MULTI_BUS */ |
1299 | "i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n" | 1299 | "i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n" |
1300 | "i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n" | 1300 | "i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n" |
1301 | "i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n" | 1301 | "i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n" |
1302 | "i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)\n" | 1302 | "i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)\n" |
1303 | "i2c crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n" | 1303 | "i2c crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n" |
1304 | "i2c probe - show devices on the I2C bus\n" | 1304 | "i2c probe - show devices on the I2C bus\n" |
1305 | "i2c reset - re-init the I2C Controller\n" | 1305 | "i2c reset - re-init the I2C Controller\n" |
1306 | "i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device" | 1306 | "i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device" |
1307 | #if defined(CONFIG_CMD_SDRAM) | 1307 | #if defined(CONFIG_CMD_SDRAM) |
1308 | "\n" | 1308 | "\n" |
1309 | "i2c sdram chip - print SDRAM configuration information" | 1309 | "i2c sdram chip - print SDRAM configuration information" |
1310 | #endif | 1310 | #endif |
1311 | ); | 1311 | ); |
1312 | 1312 | ||
1313 | #if defined(CONFIG_I2C_MUX) | 1313 | #if defined(CONFIG_I2C_MUX) |
1314 | 1314 | ||
1315 | int i2c_mux_add_device(I2C_MUX_DEVICE *dev) | 1315 | int i2c_mux_add_device(I2C_MUX_DEVICE *dev) |
1316 | { | 1316 | { |
1317 | I2C_MUX_DEVICE *devtmp = i2c_mux_devices; | 1317 | I2C_MUX_DEVICE *devtmp = i2c_mux_devices; |
1318 | 1318 | ||
1319 | if (i2c_mux_devices == NULL) { | 1319 | if (i2c_mux_devices == NULL) { |
1320 | i2c_mux_devices = dev; | 1320 | i2c_mux_devices = dev; |
1321 | return 0; | 1321 | return 0; |
1322 | } | 1322 | } |
1323 | while (devtmp->next != NULL) | 1323 | while (devtmp->next != NULL) |
1324 | devtmp = devtmp->next; | 1324 | devtmp = devtmp->next; |
1325 | 1325 | ||
1326 | devtmp->next = dev; | 1326 | devtmp->next = dev; |
1327 | return 0; | 1327 | return 0; |
1328 | } | 1328 | } |
1329 | 1329 | ||
1330 | I2C_MUX_DEVICE *i2c_mux_search_device(int id) | 1330 | I2C_MUX_DEVICE *i2c_mux_search_device(int id) |
1331 | { | 1331 | { |
1332 | I2C_MUX_DEVICE *device = i2c_mux_devices; | 1332 | I2C_MUX_DEVICE *device = i2c_mux_devices; |
1333 | 1333 | ||
1334 | while (device != NULL) { | 1334 | while (device != NULL) { |
1335 | if (device->busid == id) | 1335 | if (device->busid == id) |
1336 | return device; | 1336 | return device; |
1337 | device = device->next; | 1337 | device = device->next; |
1338 | } | 1338 | } |
1339 | return NULL; | 1339 | return NULL; |
1340 | } | 1340 | } |
1341 | 1341 | ||
1342 | /* searches in the buf from *pos the next ':'. | 1342 | /* searches in the buf from *pos the next ':'. |
1343 | * returns: | 1343 | * returns: |
1344 | * 0 if found (with *pos = where) | 1344 | * 0 if found (with *pos = where) |
1345 | * < 0 if an error occured | 1345 | * < 0 if an error occured |
1346 | * > 0 if the end of buf is reached | 1346 | * > 0 if the end of buf is reached |
1347 | */ | 1347 | */ |
1348 | static int i2c_mux_search_next (int *pos, uchar *buf, int len) | 1348 | static int i2c_mux_search_next (int *pos, uchar *buf, int len) |
1349 | { | 1349 | { |
1350 | while ((buf[*pos] != ':') && (*pos < len)) { | 1350 | while ((buf[*pos] != ':') && (*pos < len)) { |
1351 | *pos += 1; | 1351 | *pos += 1; |
1352 | } | 1352 | } |
1353 | if (*pos >= len) | 1353 | if (*pos >= len) |
1354 | return 1; | 1354 | return 1; |
1355 | if (buf[*pos] != ':') | 1355 | if (buf[*pos] != ':') |
1356 | return -1; | 1356 | return -1; |
1357 | return 0; | 1357 | return 0; |
1358 | } | 1358 | } |
1359 | 1359 | ||
1360 | static int i2c_mux_get_busid (void) | 1360 | static int i2c_mux_get_busid (void) |
1361 | { | 1361 | { |
1362 | int tmp = i2c_mux_busid; | 1362 | int tmp = i2c_mux_busid; |
1363 | 1363 | ||
1364 | i2c_mux_busid ++; | 1364 | i2c_mux_busid ++; |
1365 | return tmp; | 1365 | return tmp; |
1366 | } | 1366 | } |
1367 | 1367 | ||
1368 | /* Analyses a Muxstring and sends immediately the | 1368 | /* Analyses a Muxstring and sends immediately the |
1369 | Commands to the Muxes. Runs from Flash. | 1369 | Commands to the Muxes. Runs from Flash. |
1370 | */ | 1370 | */ |
1371 | int i2c_mux_ident_muxstring_f (uchar *buf) | 1371 | int i2c_mux_ident_muxstring_f (uchar *buf) |
1372 | { | 1372 | { |
1373 | int pos = 0; | 1373 | int pos = 0; |
1374 | int oldpos; | 1374 | int oldpos; |
1375 | int ret = 0; | 1375 | int ret = 0; |
1376 | int len = strlen((char *)buf); | 1376 | int len = strlen((char *)buf); |
1377 | int chip; | 1377 | int chip; |
1378 | uchar channel; | 1378 | uchar channel; |
1379 | int was = 0; | 1379 | int was = 0; |
1380 | 1380 | ||
1381 | while (ret == 0) { | 1381 | while (ret == 0) { |
1382 | oldpos = pos; | 1382 | oldpos = pos; |
1383 | /* search name */ | 1383 | /* search name */ |
1384 | ret = i2c_mux_search_next(&pos, buf, len); | 1384 | ret = i2c_mux_search_next(&pos, buf, len); |
1385 | if (ret != 0) | 1385 | if (ret != 0) |
1386 | printf ("ERROR\n"); | 1386 | printf ("ERROR\n"); |
1387 | /* search address */ | 1387 | /* search address */ |
1388 | pos ++; | 1388 | pos ++; |
1389 | oldpos = pos; | 1389 | oldpos = pos; |
1390 | ret = i2c_mux_search_next(&pos, buf, len); | 1390 | ret = i2c_mux_search_next(&pos, buf, len); |
1391 | if (ret != 0) | 1391 | if (ret != 0) |
1392 | printf ("ERROR\n"); | 1392 | printf ("ERROR\n"); |
1393 | buf[pos] = 0; | 1393 | buf[pos] = 0; |
1394 | chip = simple_strtoul((char *)&buf[oldpos], NULL, 16); | 1394 | chip = simple_strtoul((char *)&buf[oldpos], NULL, 16); |
1395 | buf[pos] = ':'; | 1395 | buf[pos] = ':'; |
1396 | /* search channel */ | 1396 | /* search channel */ |
1397 | pos ++; | 1397 | pos ++; |
1398 | oldpos = pos; | 1398 | oldpos = pos; |
1399 | ret = i2c_mux_search_next(&pos, buf, len); | 1399 | ret = i2c_mux_search_next(&pos, buf, len); |
1400 | if (ret < 0) | 1400 | if (ret < 0) |
1401 | printf ("ERROR\n"); | 1401 | printf ("ERROR\n"); |
1402 | was = 0; | 1402 | was = 0; |
1403 | if (buf[pos] != 0) { | 1403 | if (buf[pos] != 0) { |
1404 | buf[pos] = 0; | 1404 | buf[pos] = 0; |
1405 | was = 1; | 1405 | was = 1; |
1406 | } | 1406 | } |
1407 | channel = simple_strtoul((char *)&buf[oldpos], NULL, 16); | 1407 | channel = simple_strtoul((char *)&buf[oldpos], NULL, 16); |
1408 | if (was) | 1408 | if (was) |
1409 | buf[pos] = ':'; | 1409 | buf[pos] = ':'; |
1410 | if (i2c_write(chip, 0, 0, &channel, 1) != 0) { | 1410 | if (i2c_write(chip, 0, 0, &channel, 1) != 0) { |
1411 | printf ("Error setting Mux: chip:%x channel: \ | 1411 | printf ("Error setting Mux: chip:%x channel: \ |
1412 | %x\n", chip, channel); | 1412 | %x\n", chip, channel); |
1413 | return -1; | 1413 | return -1; |
1414 | } | 1414 | } |
1415 | pos ++; | 1415 | pos ++; |
1416 | oldpos = pos; | 1416 | oldpos = pos; |
1417 | 1417 | ||
1418 | } | 1418 | } |
1419 | 1419 | ||
1420 | return 0; | 1420 | return 0; |
1421 | } | 1421 | } |
1422 | 1422 | ||
1423 | /* Analyses a Muxstring and if this String is correct | 1423 | /* Analyses a Muxstring and if this String is correct |
1424 | * adds a new I2C Bus. | 1424 | * adds a new I2C Bus. |
1425 | */ | 1425 | */ |
1426 | I2C_MUX_DEVICE *i2c_mux_ident_muxstring (uchar *buf) | 1426 | I2C_MUX_DEVICE *i2c_mux_ident_muxstring (uchar *buf) |
1427 | { | 1427 | { |
1428 | I2C_MUX_DEVICE *device; | 1428 | I2C_MUX_DEVICE *device; |
1429 | I2C_MUX *mux; | 1429 | I2C_MUX *mux; |
1430 | int pos = 0; | 1430 | int pos = 0; |
1431 | int oldpos; | 1431 | int oldpos; |
1432 | int ret = 0; | 1432 | int ret = 0; |
1433 | int len = strlen((char *)buf); | 1433 | int len = strlen((char *)buf); |
1434 | int was = 0; | 1434 | int was = 0; |
1435 | 1435 | ||
1436 | device = (I2C_MUX_DEVICE *)malloc (sizeof(I2C_MUX_DEVICE)); | 1436 | device = (I2C_MUX_DEVICE *)malloc (sizeof(I2C_MUX_DEVICE)); |
1437 | device->mux = NULL; | 1437 | device->mux = NULL; |
1438 | device->busid = i2c_mux_get_busid (); | 1438 | device->busid = i2c_mux_get_busid (); |
1439 | device->next = NULL; | 1439 | device->next = NULL; |
1440 | while (ret == 0) { | 1440 | while (ret == 0) { |
1441 | mux = (I2C_MUX *)malloc (sizeof(I2C_MUX)); | 1441 | mux = (I2C_MUX *)malloc (sizeof(I2C_MUX)); |
1442 | mux->next = NULL; | 1442 | mux->next = NULL; |
1443 | /* search name of mux */ | 1443 | /* search name of mux */ |
1444 | oldpos = pos; | 1444 | oldpos = pos; |
1445 | ret = i2c_mux_search_next(&pos, buf, len); | 1445 | ret = i2c_mux_search_next(&pos, buf, len); |
1446 | if (ret != 0) | 1446 | if (ret != 0) |
1447 | printf ("%s no name.\n", __FUNCTION__); | 1447 | printf ("%s no name.\n", __FUNCTION__); |
1448 | mux->name = (char *)malloc (pos - oldpos + 1); | 1448 | mux->name = (char *)malloc (pos - oldpos + 1); |
1449 | memcpy (mux->name, &buf[oldpos], pos - oldpos); | 1449 | memcpy (mux->name, &buf[oldpos], pos - oldpos); |
1450 | mux->name[pos - oldpos] = 0; | 1450 | mux->name[pos - oldpos] = 0; |
1451 | /* search address */ | 1451 | /* search address */ |
1452 | pos ++; | 1452 | pos ++; |
1453 | oldpos = pos; | 1453 | oldpos = pos; |
1454 | ret = i2c_mux_search_next(&pos, buf, len); | 1454 | ret = i2c_mux_search_next(&pos, buf, len); |
1455 | if (ret != 0) | 1455 | if (ret != 0) |
1456 | printf ("%s no mux address.\n", __FUNCTION__); | 1456 | printf ("%s no mux address.\n", __FUNCTION__); |
1457 | buf[pos] = 0; | 1457 | buf[pos] = 0; |
1458 | mux->chip = simple_strtoul((char *)&buf[oldpos], NULL, 16); | 1458 | mux->chip = simple_strtoul((char *)&buf[oldpos], NULL, 16); |
1459 | buf[pos] = ':'; | 1459 | buf[pos] = ':'; |
1460 | /* search channel */ | 1460 | /* search channel */ |
1461 | pos ++; | 1461 | pos ++; |
1462 | oldpos = pos; | 1462 | oldpos = pos; |
1463 | ret = i2c_mux_search_next(&pos, buf, len); | 1463 | ret = i2c_mux_search_next(&pos, buf, len); |
1464 | if (ret < 0) | 1464 | if (ret < 0) |
1465 | printf ("%s no mux channel.\n", __FUNCTION__); | 1465 | printf ("%s no mux channel.\n", __FUNCTION__); |
1466 | was = 0; | 1466 | was = 0; |
1467 | if (buf[pos] != 0) { | 1467 | if (buf[pos] != 0) { |
1468 | buf[pos] = 0; | 1468 | buf[pos] = 0; |
1469 | was = 1; | 1469 | was = 1; |
1470 | } | 1470 | } |
1471 | mux->channel = simple_strtoul((char *)&buf[oldpos], NULL, 16); | 1471 | mux->channel = simple_strtoul((char *)&buf[oldpos], NULL, 16); |
1472 | if (was) | 1472 | if (was) |
1473 | buf[pos] = ':'; | 1473 | buf[pos] = ':'; |
1474 | if (device->mux == NULL) | 1474 | if (device->mux == NULL) |
1475 | device->mux = mux; | 1475 | device->mux = mux; |
1476 | else { | 1476 | else { |
1477 | I2C_MUX *muxtmp = device->mux; | 1477 | I2C_MUX *muxtmp = device->mux; |
1478 | while (muxtmp->next != NULL) { | 1478 | while (muxtmp->next != NULL) { |
1479 | muxtmp = muxtmp->next; | 1479 | muxtmp = muxtmp->next; |
1480 | } | 1480 | } |
1481 | muxtmp->next = mux; | 1481 | muxtmp->next = mux; |
1482 | } | 1482 | } |
1483 | pos ++; | 1483 | pos ++; |
1484 | oldpos = pos; | 1484 | oldpos = pos; |
1485 | } | 1485 | } |
1486 | if (ret > 0) { | 1486 | if (ret > 0) { |
1487 | /* Add Device */ | 1487 | /* Add Device */ |
1488 | i2c_mux_add_device (device); | 1488 | i2c_mux_add_device (device); |
1489 | return device; | 1489 | return device; |
1490 | } | 1490 | } |
1491 | 1491 | ||
1492 | return NULL; | 1492 | return NULL; |
1493 | } | 1493 | } |
1494 | 1494 | ||
1495 | int i2x_mux_select_mux(int bus) | 1495 | int i2x_mux_select_mux(int bus) |
1496 | { | 1496 | { |
1497 | I2C_MUX_DEVICE *dev; | 1497 | I2C_MUX_DEVICE *dev; |
1498 | I2C_MUX *mux; | 1498 | I2C_MUX *mux; |
1499 | 1499 | ||
1500 | if ((gd->flags & GD_FLG_RELOC) != GD_FLG_RELOC) { | 1500 | if ((gd->flags & GD_FLG_RELOC) != GD_FLG_RELOC) { |
1501 | /* select Default Mux Bus */ | 1501 | /* select Default Mux Bus */ |
1502 | #if defined(CONFIG_SYS_I2C_IVM_BUS) | 1502 | #if defined(CONFIG_SYS_I2C_IVM_BUS) |
1503 | i2c_mux_ident_muxstring_f ((uchar *)CONFIG_SYS_I2C_IVM_BUS); | 1503 | i2c_mux_ident_muxstring_f ((uchar *)CONFIG_SYS_I2C_IVM_BUS); |
1504 | #else | 1504 | #else |
1505 | { | 1505 | { |
1506 | unsigned char *buf; | 1506 | unsigned char *buf; |
1507 | buf = (unsigned char *) getenv("EEprom_ivm"); | 1507 | buf = (unsigned char *) getenv("EEprom_ivm"); |
1508 | if (buf != NULL) | 1508 | if (buf != NULL) |
1509 | i2c_mux_ident_muxstring_f (buf); | 1509 | i2c_mux_ident_muxstring_f (buf); |
1510 | } | 1510 | } |
1511 | #endif | 1511 | #endif |
1512 | return 0; | 1512 | return 0; |
1513 | } | 1513 | } |
1514 | dev = i2c_mux_search_device(bus); | 1514 | dev = i2c_mux_search_device(bus); |
1515 | if (dev == NULL) | 1515 | if (dev == NULL) |
1516 | return -1; | 1516 | return -1; |
1517 | 1517 | ||
1518 | mux = dev->mux; | 1518 | mux = dev->mux; |
1519 | while (mux != NULL) { | 1519 | while (mux != NULL) { |
1520 | if (i2c_write(mux->chip, 0, 0, &mux->channel, 1) != 0) { | 1520 | if (i2c_write(mux->chip, 0, 0, &mux->channel, 1) != 0) { |
1521 | printf ("Error setting Mux: chip:%x channel: \ | 1521 | printf ("Error setting Mux: chip:%x channel: \ |
1522 | %x\n", mux->chip, mux->channel); | 1522 | %x\n", mux->chip, mux->channel); |
1523 | return -1; | 1523 | return -1; |
1524 | } | 1524 | } |
1525 | mux = mux->next; | 1525 | mux = mux->next; |
1526 | } | 1526 | } |
1527 | return 0; | 1527 | return 0; |
1528 | } | 1528 | } |
1529 | #endif /* CONFIG_I2C_MUX */ | 1529 | #endif /* CONFIG_I2C_MUX */ |
1530 | 1530 |