1 /* 2 * (C) Copyright 2008 3 * Heiko Schocher, DENX Software Engineering, hs@denx.de. 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24 #include <common.h> 25 #include <mpc8260.h> 26 #include <ioports.h> 27 #include <malloc.h> 28 #include <hush.h> 29 30 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) 31 #include <libfdt.h> 32 #endif 33 34 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) 35 #include <i2c.h> 36 #endif 37 38 extern int i2c_soft_read_pin (void); 39 40 int ivm_calc_crc (unsigned char *buf, int len) 41 { 42 const unsigned short crc_tab[16] = { 43 0x0000, 0xCC01, 0xD801, 0x1400, 44 0xF001, 0x3C00, 0x2800, 0xE401, 45 0xA001, 0x6C00, 0x7800, 0xB401, 46 0x5000, 0x9C01, 0x8801, 0x4400}; 47 48 unsigned short crc = 0; /* final result */ 49 unsigned short r1 = 0; /* temp */ 50 unsigned char byte = 0; /* input buffer */ 51 int i; 52 53 /* calculate CRC from array data */ 54 for (i = 0; i < len; i++) { 55 byte = buf[i]; 56 57 /* lower 4 bits */ 58 r1 = crc_tab[crc & 0xF]; 59 crc = ((crc) >> 4) & 0x0FFF; 60 crc = crc ^ r1 ^ crc_tab[byte & 0xF]; 61 62 /* upper 4 bits */ 63 r1 = crc_tab[crc & 0xF]; 64 crc = (crc >> 4) & 0x0FFF; 65 crc = crc ^ r1 ^ crc_tab[(byte >> 4) & 0xF]; 66 } 67 return crc; 68 } 69 70 static int ivm_set_value (char *name, char *value) 71 { 72 char tempbuf[256]; 73 74 if (value != NULL) { 75 sprintf (tempbuf, "%s=%s", name, value); 76 return set_local_var (tempbuf, 0); 77 } else { 78 unset_local_var (name); 79 } 80 return 0; 81 } 82 83 static int ivm_get_value (unsigned char *buf, int len, char *name, int off, 84 int check) 85 { 86 unsigned short val; 87 unsigned char valbuf[30]; 88 89 if ((buf[off + 0] != buf[off + 2]) && 90 (buf[off + 2] != buf[off + 4])) { 91 printf ("%s Error corrupted %s\n", __FUNCTION__, name); 92 val = -1; 93 } else { 94 val = buf[off + 0] + (buf[off + 1] << 8); 95 if ((val == 0) && (check == 1)) 96 val = -1; 97 } 98 sprintf ((char *)valbuf, "%x", val); 99 ivm_set_value (name, (char *)valbuf); 100 return val; 101 } 102 103 #define INVENTORYBLOCKSIZE 0x100 104 #define INVENTORYDATAADDRESS 0x21 105 #define INVENTORYDATASIZE (INVENTORYBLOCKSIZE - INVENTORYDATAADDRESS - 3) 106 107 #define IVM_POS_SHORT_TEXT 0 108 #define IVM_POS_MANU_ID 1 109 #define IVM_POS_MANU_SERIAL 2 110 #define IVM_POS_PART_NUMBER 3 111 #define IVM_POS_BUILD_STATE 4 112 #define IVM_POS_SUPPLIER_PART_NUMBER 5 113 #define IVM_POS_DELIVERY_DATE 6 114 #define IVM_POS_SUPPLIER_BUILD_STATE 7 115 #define IVM_POS_CUSTOMER_ID 8 116 #define IVM_POS_CUSTOMER_PROD_ID 9 117 #define IVM_POS_HISTORY 10 118 #define IVM_POS_SYMBOL_ONLY 11 119 120 static char convert_char (char c) 121 { 122 return (c < ' ' || c > '~') ? '.' : c; 123 } 124 125 static int ivm_findinventorystring (int type, 126 unsigned char* const string, 127 unsigned long maxlen, 128 unsigned char *buf) 129 { 130 int xcode = 0; 131 unsigned long cr = 0; 132 unsigned long addr = INVENTORYDATAADDRESS; 133 unsigned long size = 0; 134 unsigned long nr = type; 135 int stop = 0; /* stop on semicolon */ 136 137 memset(string, '\0', maxlen); 138 switch (type) { 139 case IVM_POS_SYMBOL_ONLY: 140 nr = 0; 141 stop= 1; 142 break; 143 default: 144 nr = type; 145 stop = 0; 146 } 147 148 /* Look for the requested number of CR. */ 149 while ((cr != nr) && (addr < INVENTORYDATASIZE)) { 150 if ((buf[addr] == '\r')) { 151 cr++; 152 } 153 addr++; 154 } 155 156 /* the expected number of CR was found until the end of the IVM 157 * content --> fill string */ 158 if (addr < INVENTORYDATASIZE) { 159 /* Copy the IVM string in the corresponding string */ 160 for (; (buf[addr] != '\r') && 161 ((buf[addr] != ';') || (!stop)) && 162 (size < (maxlen - 1) && 163 (addr < INVENTORYDATASIZE)); addr++) 164 { 165 size += sprintf((char *)string + size, "%c", 166 convert_char (buf[addr])); 167 } 168 169 /* copy phase is done: check if everything is ok. If not, 170 * the inventory data is most probably corrupted: tell 171 * the world there is a problem! */ 172 if (addr == INVENTORYDATASIZE) { 173 xcode = -1; 174 printf ("Error end of string not found\n"); 175 } else if ((size >= (maxlen - 1)) && 176 (buf[addr] != '\r')) { 177 xcode = -1; 178 printf ("string too long till next CR\n"); 179 } 180 } else { 181 /* some CR are missing... 182 * the inventory data is most probably corrupted */ 183 xcode = -1; 184 printf ("not enough cr found\n"); 185 } 186 return xcode; 187 } 188 189 #define GET_STRING(name, which, len) \ 190 if (ivm_findinventorystring (which, valbuf, len, buf) == 0) { \ 191 ivm_set_value (name, (char *)valbuf); \ 192 } 193 194 static int ivm_check_crc (unsigned char *buf, int block) 195 { 196 unsigned long crc; 197 unsigned long crceeprom; 198 199 crc = ivm_calc_crc (buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2); 200 crceeprom = (buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 1] + \ 201 buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2] * 256); 202 if (crc != crceeprom) { 203 printf ("Error CRC Block: %d EEprom: calculated: %lx EEprom: %lx\n", 204 block, crc, crceeprom); 205 return -1; 206 } 207 return 0; 208 } 209 210 static int ivm_analyze_block2 (unsigned char *buf, int len) 211 { 212 unsigned char valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN]; 213 unsigned long count; 214 215 /* IVM_MacAddress */ 216 sprintf ((char *)valbuf, "%02X:%02X:%02X:%02X:%02X:%02X", 217 buf[1], 218 buf[2], 219 buf[3], 220 buf[4], 221 buf[5], 222 buf[6]); 223 ivm_set_value ("IVM_MacAddress", (char *)valbuf); 224 if (getenv ("ethaddr") == NULL) 225 setenv ((char *)"ethaddr", (char *)valbuf); 226 /* IVM_MacCount */ 227 count = (buf[10] << 24) + 228 (buf[11] << 16) + 229 (buf[12] << 8) + 230 buf[13]; 231 if (count == 0xffffffff) 232 count = 1; 233 sprintf ((char *)valbuf, "%lx", count); 234 ivm_set_value ("IVM_MacCount", (char *)valbuf); 235 return 0; 236 } 237 238 int ivm_analyze_eeprom (unsigned char *buf, int len) 239 { 240 unsigned short val; 241 unsigned char valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN]; 242 unsigned char *tmp; 243 244 if (ivm_check_crc (buf, 0) != 0) 245 return -1; 246 247 ivm_get_value (buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN, "IVM_BoardId", 0, 1); 248 val = ivm_get_value (buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN, "IVM_HWKey", 6, 1); 249 if (val != 0xffff) { 250 sprintf ((char *)valbuf, "%x", ((val /100) % 10)); 251 ivm_set_value ("IVM_HWVariant", (char *)valbuf); 252 sprintf ((char *)valbuf, "%x", (val % 100)); 253 ivm_set_value ("IVM_HWVersion", (char *)valbuf); 254 } 255 ivm_get_value (buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN, "IVM_Functions", 12, 0); 256 257 GET_STRING("IVM_Symbol", IVM_POS_SYMBOL_ONLY, 8) 258 GET_STRING("IVM_DeviceName", IVM_POS_SHORT_TEXT, 64) 259 tmp = (unsigned char *) getenv("IVM_DeviceName"); 260 if (tmp) { 261 int len = strlen ((char *)tmp); 262 int i = 0; 263 264 while (i < len) { 265 if (tmp[i] == ';') { 266 ivm_set_value ("IVM_ShortText", (char *)&tmp[i + 1]); 267 break; 268 } 269 i++; 270 } 271 if (i >= len) 272 ivm_set_value ("IVM_ShortText", NULL); 273 } else { 274 ivm_set_value ("IVM_ShortText", NULL); 275 } 276 GET_STRING("IVM_ManufacturerID", IVM_POS_MANU_ID, 32) 277 GET_STRING("IVM_ManufacturerSerialNumber", IVM_POS_MANU_SERIAL, 20) 278 GET_STRING("IVM_ManufacturerPartNumber", IVM_POS_PART_NUMBER, 32) 279 GET_STRING("IVM_ManufacturerBuildState", IVM_POS_BUILD_STATE, 32) 280 GET_STRING("IVM_SupplierPartNumber", IVM_POS_SUPPLIER_PART_NUMBER, 32) 281 GET_STRING("IVM_DelieveryDate", IVM_POS_DELIVERY_DATE, 32) 282 GET_STRING("IVM_SupplierBuildState", IVM_POS_SUPPLIER_BUILD_STATE, 32) 283 GET_STRING("IVM_CustomerID", IVM_POS_CUSTOMER_ID, 32) 284 GET_STRING("IVM_CustomerProductID", IVM_POS_CUSTOMER_PROD_ID, 32) 285 286 if (ivm_check_crc (&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2], 2) != 0) 287 return -2; 288 ivm_analyze_block2 (&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2], CONFIG_SYS_IVM_EEPROM_PAGE_LEN); 289 290 return 0; 291 } 292 293 int ivm_read_eeprom (void) 294 { 295 I2C_MUX_DEVICE *dev = NULL; 296 uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; 297 uchar *buf; 298 unsigned dev_addr = CONFIG_SYS_IVM_EEPROM_ADR; 299 300 /* First init the Bus, select the Bus */ 301 #if defined(CONFIG_SYS_I2C_IVM_BUS) 302 dev = i2c_mux_ident_muxstring ((uchar *)CONFIG_SYS_I2C_IVM_BUS); 303 #else 304 buf = (unsigned char *) getenv ("EEprom_ivm"); 305 if (buf != NULL) 306 dev = i2c_mux_ident_muxstring (buf); 307 #endif 308 if (dev == NULL) { 309 printf ("Error couldnt add Bus for IVM\n"); 310 return -1; 311 } 312 i2c_set_bus_num (dev->busid); 313 314 buf = (unsigned char *) getenv ("EEprom_ivm_addr"); 315 if (buf != NULL) 316 dev_addr = simple_strtoul ((char *)buf, NULL, 16); 317 318 if (eeprom_read (dev_addr, 0, i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN) != 0) { 319 printf ("Error reading EEprom\n"); 320 return -2; 321 } 322 323 return ivm_analyze_eeprom (i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN); 324 } 325 326 #if defined(CONFIG_SYS_I2C_INIT_BOARD) 327 #define DELAY_ABORT_SEQ 62 328 #define DELAY_HALF_PERIOD (500 / (CONFIG_SYS_I2C_SPEED / 1000)) 329 330 #if defined(CONFIG_MGCOGE) 331 #define SDA_MASK 0x00010000 332 #define SCL_MASK 0x00020000 333 static void set_pin (int state, unsigned long mask) 334 { 335 volatile ioport_t *iop = ioport_addr ((immap_t *)CONFIG_SYS_IMMR, 3); 336 337 if (state) 338 iop->pdat |= (mask); 339 else 340 iop->pdat &= ~(mask); 341 342 iop->pdir |= (mask); 343 } 344 345 static int get_pin (unsigned long mask) 346 { 347 volatile ioport_t *iop = ioport_addr ((immap_t *)CONFIG_SYS_IMMR, 3); 348 349 iop->pdir &= ~(mask); 350 return (0 != (iop->pdat & (mask))); 351 } 352 353 static void set_sda (int state) 354 { 355 set_pin (state, SDA_MASK); 356 } 357 358 static void set_scl (int state) 359 { 360 set_pin (state, SCL_MASK); 361 } 362 363 static int get_sda (void) 364 { 365 return get_pin (SDA_MASK); 366 } 367 368 static int get_scl (void) 369 { 370 return get_pin (SCL_MASK); 371 } 372 373 #if defined(CONFIG_HARD_I2C) 374 static void setports (int gpio) 375 { 376 volatile ioport_t *iop = ioport_addr ((immap_t *)CONFIG_SYS_IMMR, 3); 377 378 if (gpio) { 379 iop->ppar &= ~(SDA_MASK | SCL_MASK); 380 iop->podr &= ~(SDA_MASK | SCL_MASK); 381 } else { 382 iop->ppar |= (SDA_MASK | SCL_MASK); 383 iop->pdir &= ~(SDA_MASK | SCL_MASK); 384 iop->podr |= (SDA_MASK | SCL_MASK); 385 } 386 } 387 #endif 388 #endif 389 390 #if defined(CONFIG_MGSUVD) 391 static void set_sda (int state) 392 { 393 I2C_SDA(state); 394 } 395 396 static void set_scl (int state) 397 { 398 I2C_SCL(state); 399 } 400 401 static int get_sda (void) 402 { 403 return i2c_soft_read_pin (); 404 } 405 406 static int get_scl (void) 407 { 408 int val; 409 410 *(unsigned short *)(I2C_BASE_DIR) &= ~SCL_CONF; 411 udelay (1); 412 val = *(unsigned char *)(I2C_BASE_PORT); 413 414 return ((val & SCL_BIT) == SCL_BIT); 415 } 416 417 #endif 418 419 static void writeStartSeq (void) 420 { 421 set_sda (1); 422 udelay (DELAY_HALF_PERIOD); 423 set_scl (1); 424 udelay (DELAY_HALF_PERIOD); 425 set_sda (0); 426 udelay (DELAY_HALF_PERIOD); 427 set_scl (0); 428 udelay (DELAY_HALF_PERIOD); 429 } 430 431 /* I2C is a synchronous protocol and resets of the processor in the middle 432 of an access can block the I2C Bus until a powerdown of the full unit is 433 done. This function toggles the SCL until the SCL and SCA line are 434 released, but max. 16 times, after this a I2C start-sequence is sent. 435 This I2C Deblocking mechanism was developed by Keymile in association 436 with Anatech and Atmel in 1998. 437 */ 438 static int i2c_make_abort (void) 439 { 440 int scl_state = 0; 441 int sda_state = 0; 442 int i = 0; 443 int ret = 0; 444 445 if (!get_sda ()) { 446 ret = -1; 447 while (i < 16) { 448 i++; 449 set_scl (0); 450 udelay (DELAY_ABORT_SEQ); 451 set_scl (1); 452 udelay (DELAY_ABORT_SEQ); 453 scl_state = get_scl (); 454 sda_state = get_sda (); 455 if (scl_state && sda_state) { 456 ret = 0; 457 break; 458 } 459 } 460 } 461 if (ret == 0) { 462 for (i =0; i < 5; i++) { 463 writeStartSeq (); 464 } 465 } 466 get_sda (); 467 return ret; 468 } 469 470 /** 471 * i2c_init_board - reset i2c bus. When the board is powercycled during a 472 * bus transfer it might hang; for details see doc/I2C_Edge_Conditions. 473 */ 474 void i2c_init_board(void) 475 { 476 #if defined(CONFIG_HARD_I2C) 477 volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ; 478 volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c; 479 480 /* disable I2C controller first, otherwhise it thinks we want to */ 481 /* talk to the slave port... */ 482 i2c->i2c_i2mod &= ~0x01; 483 484 /* Set the PortPins to GPIO */ 485 setports (1); 486 #endif 487 488 /* Now run the AbortSequence() */ 489 i2c_make_abort (); 490 491 #if defined(CONFIG_HARD_I2C) 492 /* Set the PortPins back to use for I2C */ 493 setports (0); 494 #endif 495 } 496 #endif 497