mgcoge, mgsuvd: added support for the IVM EEprom.
PATCH v2 15/16 mgcoge, mgsuvd: added support for the IVM EEprom.
The EEprom contains some Manufacturerinformation, which are read from u-boot at boot time, and saved in same hush shell variables.
Signed-off-by Heiko Schocher <[email protected]>
--- board/keymile/common/common.c | 287 +++++++++++++++++++++++++++++++++++++++++ board/keymile/mgcoge/mgcoge.c | 7 + board/keymile/mgsuvd/mgsuvd.c | 8 + include/configs/mgcoge.h | 6 + include/configs/mgsuvd.h | 6 + 5 files changed, 314 insertions(+), 0 deletions(-)
board/keymile/common/common.c +287 -0
@@ -25,6 +25,7 @@#include <mpc8260.h> #include <ioports.h> #include <malloc.h> +#include <hush.h> #if defined(CONFIG_OF_BOARD_SETUP ) && defined(CONFIG_OF_LIBFDT )#include <libfdt.h>
@@ -36,6 +37,292 @@extern int i2c_soft_read_pin (void ); +int ivm_calc_crc (unsigned char *buf,int len) +{ +const unsigned short crc_tab[16 ] = { +0x0000 ,0xCC01 ,0xD801 ,0x1400 , +0xF001 ,0x3C00 ,0x2800 ,0xE401 , +0xA001 ,0x6C00 ,0x7800 ,0xB401 , +0x5000 ,0x9C01 ,0x8801 ,0x4400 }; + +unsigned short crc =0 ;/* final result */ +unsigned short r1 =0 ;/* temp */ +unsigned char byte =0 ;/* input buffer */ +int i; + +/* calculate CRC from array data */ +for (i =0 ; i < len; i++) { + byte = buf[i]; + +/* lower 4 bits */ + r1 = crc_tab[crc &0xF ]; + crc = ((crc) >>4 ) &0x0FFF ; + crc = crc ^ r1 ^ crc_tab[byte &0xF ]; + +/* upper 4 bits */ + r1 = crc_tab[crc &0xF ]; + crc = (crc >>4 ) &0x0FFF ; + crc = crc ^ r1 ^ crc_tab[(byte >>4 ) &0xF ]; + } +return crc; +} + +static int ivm_set_value (char *name,char *value) +{ +char tempbuf[256 ]; + +if (value !=NULL ) { +sprintf (tempbuf,"%s=%s" , name, value); +return set_local_var (tempbuf,0 ); + }else { +unset_local_var (name); + } +return 0 ; +} + +static int ivm_get_value (unsigned char *buf,int len,char *name,int off, +int check) +{ +unsigned short val; +unsigned char valbuf[30 ]; + +if ((buf[off +0 ] != buf[off +2 ]) && + (buf[off +2 ] != buf[off +4 ])) { +printf ("%s Error corrupted %s\n" , __FUNCTION__, name); + val =-1 ; + }else { + val = buf[off +0 ] + (buf[off +1 ] <<8 ); +if ((val ==0 ) && (check ==1 )) + val =-1 ; + } +sprintf ((char *)valbuf,"%x" , val); +ivm_set_value (name, (char *)valbuf); +return val; +} + +#define INVENTORYBLOCKSIZE 0x100 +#define INVENTORYDATAADDRESS 0x21 +#define INVENTORYDATASIZE (INVENTORYBLOCKSIZE - INVENTORYDATAADDRESS - 3) + +#define IVM_POS_SHORT_TEXT 0 +#define IVM_POS_MANU_ID 1 +#define IVM_POS_MANU_SERIAL 2 +#define IVM_POS_PART_NUMBER 3 +#define IVM_POS_BUILD_STATE 4 +#define IVM_POS_SUPPLIER_PART_NUMBER 5 +#define IVM_POS_DELIVERY_DATE 6 +#define IVM_POS_SUPPLIER_BUILD_STATE 7 +#define IVM_POS_CUSTOMER_ID 8 +#define IVM_POS_CUSTOMER_PROD_ID 9 +#define IVM_POS_HISTORY 10 +#define IVM_POS_SYMBOL_ONLY 11 + +static char convert_char (char c) +{ +return (c <' ' || c >'~' ) ?'.' : c; +} + +static int ivm_findinventorystring (int type, +unsigned char *const string, +unsigned long maxlen, +unsigned char *buf) +{ +int xcode =0 ; +unsigned long cr =0 ; +unsigned long addr =INVENTORYDATAADDRESS ; +unsigned long size =0 ; +unsigned long nr = type; +int stop =0 ;/* stop on semicolon */ + +memset (string,'\0' , maxlen); +switch (type) { +case IVM_POS_SYMBOL_ONLY : + nr =0 ; + stop=1 ; +break ; +default : + nr = type; + stop =0 ; + } + +/* Look for the requested number of CR. */ +while ((cr != nr) && (addr <INVENTORYDATASIZE )) { +if ((buf[addr] =='\r' )) { + cr++; + } + addr++; + } + +/* the expected number of CR was found until the end of the IVM +* content --> fill string */ +if (addr <INVENTORYDATASIZE ) { +/* Copy the IVM string in the corresponding string */ +for (; (buf[addr] !='\r' ) && + ((buf[addr] !=';' ) || (!stop)) && + (size < (maxlen -1 ) && + (addr <INVENTORYDATASIZE )); addr++) + { + size +=sprintf ((char *)string + size,"%c" , +convert_char (buf[addr])); + } + +/* copy phase is done: check if everything is ok. If not, +* the inventory data is most probably corrupted: tell +* the world there is a problem! */ +if (addr ==INVENTORYDATASIZE ) { + xcode =-1 ; +printf ("Error end of string not found\n" ); + }else if ((size >= (maxlen -1 )) && + (buf[addr] !='\r' )) { + xcode =-1 ; +printf ("string too long till next CR\n" ); + } + }else { +/* some CR are missing... +* the inventory data is most probably corrupted */ + xcode =-1 ; +printf ("not enough cr found\n" ); + } +return xcode; +} + +#define GET_STRING (name, which, len) \ + if (ivm_findinventorystring (which, valbuf, len, buf) == 0) { \ + ivm_set_value (name, (char *)valbuf); \ + } + +static int ivm_check_crc (unsigned char *buf,int block) +{ +unsigned long crc; +unsigned long crceeprom; + + crc =ivm_calc_crc (buf,CFG_IVM_EEPROM_PAGE_LEN -2 ); + crceeprom = (buf[CFG_IVM_EEPROM_PAGE_LEN -1 ] + \ + buf[CFG_IVM_EEPROM_PAGE_LEN -2 ] *256 ); +if (crc != crceeprom) { +printf ("Error CRC Block: %d EEprom: calculated: %lx EEprom: %lx\n" , + block, crc, crceeprom); +return -1 ; + } +return 0 ; +} + +static int ivm_analyze_block2 (unsigned char *buf,int len) +{ +unsigned char valbuf[CFG_IVM_EEPROM_PAGE_LEN ]; +unsigned long count; + +/* IVM_MacAddress */ +sprintf ((char *)valbuf,"%02X:%02X:%02X:%02X:%02X:%02X" , + buf[1 ], + buf[2 ], + buf[3 ], + buf[4 ], + buf[5 ], + buf[6 ]); +ivm_set_value ("IVM_MacAddress" , (char *)valbuf); +if (getenv ("ethaddr" ) ==NULL ) +setenv ((char *)"ethaddr" , (char *)valbuf); +/* IVM_MacCount */ + count = (buf[10 ] <<24 ) + + (buf[11 ] <<16 ) + + (buf[12 ] <<8 ) + + buf[13 ]; +if (count ==0xffffffff ) + count =1 ; +sprintf ((char *)valbuf,"%lx" , count); +ivm_set_value ("IVM_MacCount" , (char *)valbuf); +return 0 ; +} + +int ivm_analyze_eeprom (unsigned char *buf,int len) +{ +unsigned short val; +unsigned char valbuf[CFG_IVM_EEPROM_PAGE_LEN ]; +unsigned char *tmp; + +if (ivm_check_crc (buf,0 ) !=0 ) +return -1 ; + +ivm_get_value (buf,CFG_IVM_EEPROM_PAGE_LEN ,"IVM_BoardId" ,0 ,1 ); + val =ivm_get_value (buf,CFG_IVM_EEPROM_PAGE_LEN ,"IVM_HWKey" ,6 ,1 ); +if (val !=0xffff ) { +sprintf ((char *)valbuf,"%x" , ((val /100 ) %10 )); +ivm_set_value ("IVM_HWVariant" , (char *)valbuf); +sprintf ((char *)valbuf,"%x" , (val %100 )); +ivm_set_value ("IVM_HWVersion" , (char *)valbuf); + } +ivm_get_value (buf,CFG_IVM_EEPROM_PAGE_LEN ,"IVM_Functions" ,12 ,0 ); + + GET_STRING("IVM_Symbol", IVM_POS_SYMBOL_ONLY, 8) +GET_STRING ("IVM_DeviceName" ,IVM_POS_SHORT_TEXT ,64 ) + tmp = (unsigned char *) getenv("IVM_DeviceName"); +if (tmp) { +int len =strlen ((char *)tmp); +int i =0 ; + +while (i < len) { +if (tmp[i] ==';' ) { +ivm_set_value ("IVM_ShortText" , (char *)&tmp[i +1 ]); +break ; + } + i++; + } +if (i >= len) +ivm_set_value ("IVM_ShortText" ,NULL ); + }else { +ivm_set_value ("IVM_ShortText" ,NULL ); + } + GET_STRING("IVM_ManufacturerID", IVM_POS_MANU_ID, 32) + GET_STRING("IVM_ManufacturerSerialNumber", IVM_POS_MANU_SERIAL, 20) + GET_STRING("IVM_ManufacturerPartNumber", IVM_POS_PART_NUMBER, 32) + GET_STRING("IVM_ManufacturerBuildState", IVM_POS_BUILD_STATE, 32) + GET_STRING("IVM_SupplierPartNumber", IVM_POS_SUPPLIER_PART_NUMBER, 32) + GET_STRING("IVM_DelieveryDate", IVM_POS_DELIVERY_DATE, 32) + GET_STRING("IVM_SupplierBuildState", IVM_POS_SUPPLIER_BUILD_STATE, 32) + GET_STRING("IVM_CustomerID", IVM_POS_CUSTOMER_ID, 32) + GET_STRING("IVM_CustomerProductID", IVM_POS_CUSTOMER_PROD_ID, 32) + +if (ivm_check_crc (&buf[CFG_IVM_EEPROM_PAGE_LEN *2 ],2 ) !=0 ) +return -2 ; +ivm_analyze_block2 (&buf[CFG_IVM_EEPROM_PAGE_LEN *2 ],CFG_IVM_EEPROM_PAGE_LEN ); + +return 0 ; +} + +int ivm_read_eeprom (void ) +{ +I2C_MUX_DEVICE *dev =NULL ; +uchar i2c_buffer[CFG_IVM_EEPROM_MAX_LEN ]; +uchar *buf; +unsigned dev_addr =CFG_IVM_EEPROM_ADR ; + +/* First init the Bus, select the Bus */ +#if defined(CFG_I2C_IVM_BUS ) + dev =i2c_mux_ident_muxstring ((uchar *)CFG_I2C_IVM_BUS ); +#else + buf = (unsigned char *)getenv ("EEprom_ivm" ); +if (buf !=NULL ) + dev =i2c_mux_ident_muxstring (buf); +#endif +if (dev ==NULL ) { +printf ("Error couldnt add Bus for IVM\n" ); +return -1 ; + } +i2c_set_bus_num (dev->busid); + + buf = (unsigned char *)getenv ("EEprom_ivm_addr" ); +if (buf !=NULL ) + dev_addr =simple_strtoul ((char *)buf,NULL ,16 ); + +if (eeprom_read (dev_addr,0 , i2c_buffer,CFG_IVM_EEPROM_MAX_LEN ) !=0 ) { +printf ("Error reading EEprom\n" ); +return -2 ; + } + +return ivm_analyze_eeprom (i2c_buffer,CFG_IVM_EEPROM_MAX_LEN ); +} +#if defined(CFG_I2C_INIT_BOARD )#define DELAY_ABORT_SEQ 62#define DELAY_HALF_PERIOD (500 / (CFG_I2C_SPEED / 1000))
board/keymile/mgcoge/mgcoge.c +7 -0
@@ -34,6 +34,7 @@#include <i2c.h> #endif +extern int ivm_read_eeprom (void );/* * I/O Port configuration table *
@@ -299,6 +300,12 @@ int board_early_init_r (void)return 0 ; } +int hush_init_var (void ) +{ +ivm_read_eeprom (); +return 0 ; +} +#if defined(CONFIG_OF_BOARD_SETUP ) && defined(CONFIG_OF_LIBFDT )/* * update "memory" property in the blob
board/keymile/mgsuvd/mgsuvd.c +8 -0
@@ -32,6 +32,8 @@#include <libfdt.h> #endif +extern int ivm_read_eeprom (void ); +DECLARE_GLOBAL_DATA_PTR ; const uint sdram_table[] =
@@ -145,6 +147,12 @@ int board_early_init_r(void)return 0 ; } +int hush_init_var (void ) +{ +ivm_read_eeprom (); +return 0 ; +} +#if defined(CONFIG_OF_BOARD_SETUP ) && defined(CONFIG_OF_LIBFDT )/* * update "memory" property in the blob
include/configs/mgcoge.h +6 -0
@@ -134,6 +134,7 @@#define CFG_PROMPT_HUSH_PS2 "> "#define CFG_LONGHELP /* undef to save memory */ #define CFG_PROMPT "=> "/* Monitor Command Prompt */ +#define CONFIG_HUSH_INIT_VAR 1#if defined(CONFIG_CMD_KGDB )#define CFG_CBSIZE 1024/* Console I/O Buffer Size */ #else
@@ -212,6 +213,11 @@#define CFG_EEPROM_PAGE_WRITE_BITS 3#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 +/* Support the IVM EEprom */ +#define CFG_IVM_EEPROM_ADR 0x50 +#define CFG_IVM_EEPROM_MAX_LEN 0x400 +#define CFG_IVM_EEPROM_PAGE_LEN 0x100 +/* I2C SYSMON (LM75, AD7414 is almost compatible) */ #define CONFIG_DTT_LM75 1/* ON Semi's LM75 */ #define CONFIG_DTT_SENSORS {0}/* Sensor addresses */
include/configs/mgsuvd.h +6 -0
@@ -129,6 +129,7 @@#define CFG_HUSH_PARSER 1/* Use the HUSH parser */ #ifdef CFG_HUSH_PARSER #define CFG_PROMPT_HUSH_PS2 "> " +#define CONFIG_HUSH_INIT_VAR 1#endif #if defined(CONFIG_CMD_KGDB )
@@ -383,6 +384,11 @@#define CFG_EEPROM_PAGE_WRITE_BITS 3#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 +/* Support the IVM EEprom */ +#define CFG_IVM_EEPROM_ADR 0x50 +#define CFG_IVM_EEPROM_MAX_LEN 0x400 +#define CFG_IVM_EEPROM_PAGE_LEN 0x100 +/* I2C SYSMON (LM75, AD7414 is almost compatible) */ #define CONFIG_DTT_LM75 1/* ON Semi's LM75 */ #define CONFIG_DTT_SENSORS {0, 2, 4, 6}/* Sensor addresses */
Signature · 5 lines
1.5.6.1 -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany