From: wdenk Date: Sun, 10 Mar 2002 16:15:17 +0000 (+0000) Subject: Patch by Jerry Van Baren, 08 Mar 2002: X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=23778354dc5bc128ae9faaec3e2d40612fa0decc;p=users%2Frw%2Fppcboot.git Patch by Jerry Van Baren, 08 Mar 2002: Grand Unifying I2C interface patch --- diff --git a/CHANGELOG b/CHANGELOG index 23c5233..a848d3d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,22 @@ + + B I G F A T W A R N I N G : + =============================== + + We are working on the Grand Unifying I2C interface patch. The + current version of PPCBoot may not run, and even corrupt your + EEPROM contents. Use at your own risk! + + You have been warned! + + If you want to play safe, use version 1.1.5! + ====================================================================== Modifications for 1.1.6: ====================================================================== +* Patch by Jerry Van Baren, 08 Mar 2002: + Grand Unifying I2C interface patch + * Patch by Brad Kemp, 8 Mar 2002: - fixes protection for the flash on ppmc8260 board - come doc cleanup diff --git a/MAINTAINERS b/MAINTAINERS index 7103b47..890161f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -79,6 +79,11 @@ Frank Gottschling BAB7xx MPC740/MPC750 +Erik Theisen + + W7OLMC PPC4xx + W7OLMG PPC4xx + ------------------------------------------------------------------------- Unknown / orphaned boards: @@ -109,8 +114,6 @@ Unknown / orphaned boards: MIP405 PPC4xx OCRTC PPC4xx PIP405 PPC4xx - W7OLMC PPC4xx - W7OLMG PPC4xx WALNUT405 PPC4xx MOUSSE MPC824x diff --git a/board/RPXClassic/RPXClassic.c b/board/RPXClassic/RPXClassic.c index 12d6477..eb7ccfa 100644 --- a/board/RPXClassic/RPXClassic.c +++ b/board/RPXClassic/RPXClassic.c @@ -113,15 +113,12 @@ void board_get_enetaddr (uchar *enet) { int i; char buff [256], *cp; - uchar addr [2] = {0x54, 0}; /* Initialize I2C */ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); /* Read 256 bytes in EEPROM */ - i2c_read (addr, 2, buff, 128); - addr [1] = 128; - i2c_read (addr, 2, buff + 128, 128); + i2c_read (0x54, 0, 1, buff, 256); /* Retrieve MAC address in buffer (key EA) */ for (cp = buff;;) { diff --git a/board/cray/L1/L1.c b/board/cray/L1/L1.c index 17b4c54..f918991 100644 --- a/board/cray/L1/L1.c +++ b/board/cray/L1/L1.c @@ -24,7 +24,7 @@ #include #include "L1.h" #include -#include <405gp_i2c.h> +#include #include #include #include diff --git a/board/eric/eric.c b/board/eric/eric.c index 8e8fe6c..eb81e06 100644 --- a/board/eric/eric.c +++ b/board/eric/eric.c @@ -22,6 +22,7 @@ */ #include +#include #include "eric.h" #include @@ -122,7 +123,6 @@ int checkboard (void) long int initdram (int board_type) { #ifndef CONFIG_ERIC - unsigned char dataout[1]; int i; unsigned char datain[128]; int TotalSize; @@ -139,11 +139,9 @@ long int initdram (int board_type) #else /* Read Serial Presence Detect Information */ - dataout[0] = 0; for (i=0; i<128;i++) datain[i] = 127; - i2c_send(EEPROM_WRITE_ADDRESS,1,dataout); - i2c_receive(EEPROM_READ_ADDRESS,128,datain); + i2c_send(SPD_EEPROM_ADDRESS,0,1,datain,128); printf("\nReading DIMM...\n"); #if 0 for (i=0;i<128;i++) diff --git a/board/esd/canbt/canbt.c b/board/esd/canbt/canbt.c index ade686e..517869c 100644 --- a/board/esd/canbt/canbt.c +++ b/board/esd/canbt/canbt.c @@ -24,7 +24,6 @@ #include #include "canbt.h" #include -#include <405gp_i2c.h> #include #include diff --git a/board/esd/cpci405/cpci405.c b/board/esd/cpci405/cpci405.c index 97fb719..1b48c8c 100644 --- a/board/esd/cpci405/cpci405.c +++ b/board/esd/cpci405/cpci405.c @@ -24,7 +24,6 @@ #include #include "cpci405.h" #include -#include <405gp_i2c.h> #include #include diff --git a/board/esd/cpciiser4/cpciiser4.c b/board/esd/cpciiser4/cpciiser4.c index 28a7414..3274e8c 100644 --- a/board/esd/cpciiser4/cpciiser4.c +++ b/board/esd/cpciiser4/cpciiser4.c @@ -24,7 +24,6 @@ #include #include "cpciiser4.h" #include -#include <405gp_i2c.h> #include #include diff --git a/board/esd/ocrtc/ocrtc.c b/board/esd/ocrtc/ocrtc.c index d3314c8..2e2768a 100644 --- a/board/esd/ocrtc/ocrtc.c +++ b/board/esd/ocrtc/ocrtc.c @@ -24,7 +24,7 @@ #include #include "ocrtc.h" #include -#include <405gp_i2c.h> +#include #include #include diff --git a/board/evb64260/i2c.c b/board/evb64260/i2c.c index 60a5e43..ee7cf20 100644 --- a/board/evb64260/i2c.c +++ b/board/evb64260/i2c.c @@ -17,14 +17,13 @@ /* Assuming that there is only one master on the bus (us) */ static void -i2c_init(void) +i2c_init(int speed, int slaveaddr) { unsigned int n, m, freq, margin, power; unsigned int actualFreq, actualN=0, actualM=0; unsigned int control, status; unsigned int minMargin = 0xffffffff; unsigned int tclk = 125000000; - unsigned int i2cFreq = 400000; DP(puts("i2c_init\n")); @@ -34,10 +33,10 @@ i2c_init(void) { power = 2< freq) - margin = i2cFreq - freq; + if (speed > freq) + margin = speed - freq; else - margin = freq - i2cFreq; + margin = freq - speed; if(margin < minMargin) { minMargin = margin; @@ -263,10 +262,11 @@ i2c_read(uchar dev_addr, unsigned int offset, int len, uchar* data, int ten_bit) { uchar status = 0; + unsigned int i2cFreq = 400000; DP(puts("i2c_read\n")); - i2c_init(); + i2c_init(i2cFreq,0); status = i2c_start(); @@ -285,7 +285,7 @@ i2c_read(uchar dev_addr, unsigned int offset, int len, uchar* data, return status; } - i2c_init(); + i2c_init(i2cFreq,0); status = i2c_start(); if (status) { diff --git a/board/hymod/bsp.c b/board/hymod/bsp.c index c8bf2ee..16cc88e 100644 --- a/board/hymod/bsp.c +++ b/board/hymod/bsp.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -275,16 +276,16 @@ do_eecl(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) switch (argc) { case 1: - offset = HYMOD_EEOFF_MAIN << 8; + offset = HYMOD_EEOFF_MAIN; break; case 2: if (strcmp(argv[1], "main") == 0) { - offset = HYMOD_EEOFF_MAIN << 8; + offset = HYMOD_EEOFF_MAIN; break; } if (strcmp(argv[1], "mezz") == 0) { - offset = HYMOD_EEOFF_MEZZ << 8; + offset = HYMOD_EEOFF_MEZZ; break; } /* fall through ... */ @@ -295,7 +296,11 @@ do_eecl(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } memset(data, 0, HYMOD_EEPROM_SIZE); - if (eeprom_write(CFG_DEF_EEPROM_ADDR, offset, data, HYMOD_EEPROM_SIZE) != 0) rcode = 1; + if (i2c_write(CFG_I2C_EEPROM_ADDR | offset, 0, CFG_I2C_EEPROM_ADDR_LEN, + data, HYMOD_EEPROM_SIZE)) { + rcode = 1; + } + return rcode; } diff --git a/board/hymod/hymod.c b/board/hymod/hymod.c index 2d578c3..43f1355 100644 --- a/board/hymod/hymod.c +++ b/board/hymod/hymod.c @@ -233,8 +233,6 @@ iopin_t pa11 = { IOPIN_PORTA, 11, 0 }; void board_postclk_init(void) { - i2c_state_t state; - i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); /* @@ -247,13 +245,7 @@ board_postclk_init(void) * to print it on, nor any RAM to store it in - it will be obvious * if this doesn't work */ - i2c_newio(&state); - - (void) i2c_send(&state, fs6377_addr, 0, - I2CF_ENABLE_SECONDARY|I2CF_START_COND|I2CF_STOP_COND, - sizeof (fs6377_regs), fs6377_regs); - - (void) i2c_doio(&state); + (void) i2c_write(fs6377_addr, 0, 1, fs6377_regs, sizeof (fs6377_regs)); } /* ------------------------------------------------------------------------- */ @@ -411,42 +403,6 @@ initdram(int board_type) static char *bddb_cfgdir = "/hymod/bddb"; static char *global_env_path = "/hymod/global_env"; -static int had_tx_nak; - -static void -i2c_test_callback(int flags, int xnum) -{ - if ((flags & I2CECB_TX_ERR) && (flags & I2CECB_TX_NAK)) - had_tx_nak = 1; -} - -static int -i2c_test(uchar addr) -{ - i2c_state_t state; - int rc; - uchar buf[1]; - - i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); - - i2c_newio(&state); - - state.err_cb = i2c_test_callback; - had_tx_nak = 0; - - rc = i2c_receive(&state, addr, 0, I2CF_START_COND|I2CF_STOP_COND, 1, buf); - - if (rc != 0) - return (0); - - rc = i2c_doio(&state); - - if (rc != 0 && rc != I2CERR_TIMEOUT) - return (0); - - return (!had_tx_nak); -} - static ulong get_serno(const char *prompt) { @@ -608,7 +564,7 @@ misc_init_r(bd_t *bd) /* set up main board config info */ - if (i2c_test(CFG_I2C_EEPROM_ADDR|HYMOD_EEOFF_MAIN)) { + if (i2c_probe(CFG_I2C_EEPROM_ADDR|HYMOD_EEOFF_MAIN)) { if (read_eeprom(bd, "main", HYMOD_EEOFF_MAIN << 8, &cp->main.eeprom)) cp->main.eeprom_valid = 1; @@ -655,7 +611,7 @@ misc_init_r(bd_t *bd) /* set up mezzanine board config info */ - if (i2c_test(CFG_I2C_EEPROM_ADDR|HYMOD_EEOFF_MEZZ)) { + if (i2c_probe(CFG_I2C_EEPROM_ADDR|HYMOD_EEOFF_MEZZ)) { if (read_eeprom(bd, "mezz", HYMOD_EEOFF_MEZZ << 8, &cp->mezz.eeprom)) cp->mezz.eeprom_valid = 1; diff --git a/board/lwmon/lwmon.c b/board/lwmon/lwmon.c index 18ffdf7..b7e184b 100644 --- a/board/lwmon/lwmon.c +++ b/board/lwmon/lwmon.c @@ -314,18 +314,18 @@ void misc_init_r (bd_t *bd) /* Read initial keyboard error code */ val = KEYBD_CMD_READ_STATUS; - i2c_write (&kbd_addr, 1, &val, 1); - i2c_read (&kbd_addr, 1, &errcd, 1); + i2c_write (kbd_addr, 0, 0, &val, 1); + i2c_read (kbd_addr, 0, 0, &errcd, 1); if (errcd) { printf ("KEYBD: Error %02X\n", errcd); } /* Reset error code and verify */ val = KEYBD_CMD_RESET_ERRORS; - i2c_write (&kbd_addr, 1, &val, 1); + i2c_write (kbd_addr, 0, 0, &val, 1); val = KEYBD_CMD_READ_STATUS; - i2c_write (&kbd_addr, 1, &val, 1); - i2c_read (&kbd_addr, 1, &val, 1); + i2c_write (kbd_addr, 0, 0, &val, 1); + i2c_read (kbd_addr, 0, 0, &val, 1); if (val) { /* permanent error, report it */ printf ("*** Keyboard error code %02X ***\n", val); @@ -346,14 +346,14 @@ void misc_init_r (bd_t *bd) /* Read Version */ val = KEYBD_CMD_READ_VERSION; - i2c_write (&kbd_addr, 1, &val, 1); - i2c_read (&kbd_addr, 1, kbd_data, KEYBD_VERSIONLEN); + i2c_write (kbd_addr, 0, 0, &val, 1); + i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_VERSIONLEN); printf ("KEYBD: Version %d.%d\n", kbd_data[0], kbd_data[1]); /* Read keys */ val = KEYBD_CMD_READ_KEYS; - i2c_write (&kbd_addr, 1, &val, 1); - i2c_read (&kbd_addr, 1, kbd_data, KEYBD_DATALEN); + i2c_write (kbd_addr, 0, 0, &val, 1); + i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN); for (i=0; i #include "pip405.h" #include -#include <405gp_i2c.h> +#include #include #include "../common/isa.h" #include "../common/video.h" @@ -206,14 +206,9 @@ int board_pre_init (void) dataout[0] = 0; for (i = 0; i < 128; i++) datain[i] = 127; - i = i2c_send (SDRAM_EEPROM_WRITE_ADDRESS, 1, dataout); + i2c_read(SPD_EEPROM_ADDRESS,0,1,datain,128); #ifdef SDRAM_DEBUG - serial_puts ("i2c_send returns "); - write_hex (i); -#endif - i = i2c_receive (SDRAM_EEPROM_READ_ADDRESS, 128, datain); -#ifdef SDRAM_DEBUG - serial_puts ("\ni2c_receive returns "); + serial_puts ("\ni2c_read returns "); write_hex (i); serial_puts ("\n"); #endif diff --git a/board/rsdproto/rsdproto.c b/board/rsdproto/rsdproto.c index 051c983..df15e0c 100644 --- a/board/rsdproto/rsdproto.c +++ b/board/rsdproto/rsdproto.c @@ -204,104 +204,39 @@ struct tm { unsigned int tm_year; }; -void read_RS5C372_time(struct tm *timedate) +void read_RS5C372_time (struct tm *timedate) { - i2c_state_t i2c_state; unsigned char buffer[8]; - int rc; + #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) - i2c_newio(&i2c_state); - - /* schedule send command with start condition */ - rc = i2c_send(&i2c_state, - RS5C372_PPC_I2C_ADR, /* address */ - 0x00, /* secondary address */ - I2CF_ENABLE_SECONDARY | I2CF_START_COND, - 0, /* size */ - NULL); /* data */ - if (rc) - goto i2c_error; - - /* schedule the read command with repeated start condition */ - rc = i2c_receive(&i2c_state, - RS5C372_PPC_I2C_ADR, /* address */ - 0, /* secondary address */ - I2CF_START_COND | I2CF_STOP_COND, - sizeof(buffer), /* size to expect */ - buffer); /* data */ - if (rc) - goto i2c_error; - - /* perform io operations */ - rc = i2c_doio(&i2c_state); - if (rc) - goto i2c_error; - - timedate->tm_sec = BCD_TO_BIN(buffer[0]); - timedate->tm_min = BCD_TO_BIN(buffer[1]); - timedate->tm_hour = BCD_TO_BIN(buffer[2]); - timedate->tm_wday = BCD_TO_BIN(buffer[3]); - timedate->tm_mday = BCD_TO_BIN(buffer[4]); - timedate->tm_mon = BCD_TO_BIN(buffer[5]); - timedate->tm_year = BCD_TO_BIN(buffer[6]) + 2000; - return; - -i2c_error: - /*printf("i2c error %02x\n", rc);*/ - memset(timedate, 0, sizeof(struct tm)); - return; + if (i2c_read (RS5C372_PPC_I2C_ADR, 0, 1, buffer, sizeof (buffer))) { + timedate->tm_sec = BCD_TO_BIN (buffer[0]); + timedate->tm_min = BCD_TO_BIN (buffer[1]); + timedate->tm_hour = BCD_TO_BIN (buffer[2]); + timedate->tm_wday = BCD_TO_BIN (buffer[3]); + timedate->tm_mday = BCD_TO_BIN (buffer[4]); + timedate->tm_mon = BCD_TO_BIN (buffer[5]); + timedate->tm_year = BCD_TO_BIN (buffer[6]) + 2000; + } else { + /*printf("i2c error %02x\n", rc); */ + memset (timedate, 0, sizeof (struct tm)); + } } /* ------------------------------------------------------------------------- */ -int read_LM84_temp(int address) +int read_LM84_temp (int address) { - i2c_state_t i2c_state; unsigned char buffer[8]; int rc; - /* begin new i2c packet */ - i2c_newio(&i2c_state); - - /* schedule send operation */ - rc = i2c_send(&i2c_state, - address, /* address */ - 0x00, /* secondary address */ - I2CF_ENABLE_SECONDARY | I2CF_START_COND | I2CF_STOP_COND, - 0, /* size */ - NULL); /* data */ - if (rc) - goto i2c_error; - - /* perform io operations */ - rc = i2c_doio(&i2c_state); - if (rc) - goto i2c_error; - - /* begin new i2c packet */ - i2c_newio(&i2c_state); - - /* schedule send operation */ - rc = i2c_receive(&i2c_state, - address, /* address */ - 0, /* secondary address */ - I2CF_START_COND | I2CF_STOP_COND, - 1, /* size to expect */ - buffer); /* data */ - if (rc) - goto i2c_error; - - /* perform io operations */ - rc = i2c_doio(&i2c_state); - if (rc) - goto i2c_error; - - return (int)buffer[0]; - -i2c_error: - /*printf("i2c error %02x\n", rc);*/ - return -42; + if (i2c_read (address, 0, 1, buffer, 1)) { + return (int) buffer[0]; + } else { + /*printf("i2c error %02x\n", rc); */ + return -42; + } } /* ------------------------------------------------------------------------- */ @@ -310,7 +245,7 @@ i2c_error: * Check Board Identity: */ -int checkboard(void) +int checkboard (void) { struct tm timedate; unsigned int ppctemp, prottemp; @@ -318,17 +253,17 @@ int checkboard(void) puts ("Rohde & Schwarz 8260 Protocol Board\n"); /* initialise i2c */ - i2c_init(100000 >> 1, PPC8260_I2C_ADR); - - read_RS5C372_time(&timedate); - printf(" Time: %02d:%02d:%02d\n", - timedate.tm_hour, timedate.tm_min, timedate.tm_sec); - printf(" Date: %02d-%02d-%04d\n", - timedate.tm_mday, timedate.tm_mon, timedate.tm_year); - ppctemp = read_LM84_temp(LM84_PPC_I2C_ADR); - prottemp = read_LM84_temp(LM84_SHARC_I2C_ADR); - printf(" Temp: PPC %d C, Protocol Board %d C\n", - ppctemp, prottemp); + i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); + + read_RS5C372_time (&timedate); + printf (" Time: %02d:%02d:%02d\n", + timedate.tm_hour, timedate.tm_min, timedate.tm_sec); + printf (" Date: %02d-%02d-%04d\n", + timedate.tm_mday, timedate.tm_mon, timedate.tm_year); + ppctemp = read_LM84_temp (LM84_PPC_I2C_ADR); + prottemp = read_LM84_temp (LM84_SHARC_I2C_ADR); + printf (" Temp: PPC %d C, Protocol Board %d C\n", + ppctemp, prottemp); return 1; } @@ -340,30 +275,30 @@ int checkboard(void) * running in flash */ -int misc_init_f(void) +int misc_init_f (void) { return 1; } /* ------------------------------------------------------------------------- */ -long int initdram(int board_type) +long int initdram (int board_type) { - volatile immap_t *immap = (immap_t *)CFG_IMMR; - volatile memctl8260_t *memctl = &immap->im_memctl; + volatile immap_t *immap = (immap_t *) CFG_IMMR; + volatile memctl8260_t *memctl = &immap->im_memctl; + #ifdef INIT_LOCAL_BUS_SDRAM - volatile uchar *ramaddr8; + volatile uchar *ramaddr8; #endif - volatile ulong *ramaddr32; - ulong sdmr; - int i; - - /* - * Only initialize SDRAM when running from FLASH. - * When running from RAM, don't touch it. - */ - if ((ulong)initdram & 0xff000000) - { + volatile ulong *ramaddr32; + ulong sdmr; + int i; + + /* + * Only initialize SDRAM when running from FLASH. + * When running from RAM, don't touch it. + */ + if ((ulong) initdram & 0xff000000) { immap->im_siu_conf.sc_ppc_acr = 0x02; immap->im_siu_conf.sc_ppc_alrh = 0x01267893; immap->im_siu_conf.sc_ppc_alrl = 0x89ABCDEF; @@ -380,26 +315,25 @@ long int initdram(int board_type) /* * Perform Power-Up Initialisation of SDRAM (see 8260 UM, 10.4.2) * - * The appropriate BRx/ORx registers have already - * been set when we get here (see cpu_init_f). The - * SDRAM can be accessed at the address CFG_SDRAM_BASE. + * The appropriate BRx/ORx registers have already + * been set when we get here (see cpu_init_f). The + * SDRAM can be accessed at the address CFG_SDRAM_BASE. */ memctl->memc_mptpr = 0x2000; - memctl->memc_mar = 0x0200; + memctl->memc_mar = 0x0200; #ifdef INIT_LOCAL_BUS_SDRAM /* initialise local bus ram * * (using the PSRMR_ definitions is NOT an error here * - the LSDMR has the same fields as the PSDMR!) */ - memctl->memc_lsrt = 0x0b; - memctl->memc_lurt = 0x00; - ramaddr = (uchar*)PHYS_SDRAM_LOCAL; + memctl->memc_lsrt = 0x0b; + memctl->memc_lurt = 0x00; + ramaddr = (uchar *) PHYS_SDRAM_LOCAL; sdmr = CFG_LSDMR & ~(PSDMR_OP_MSK | PSDMR_RFEN | PSDMR_PBI); memctl->memc_lsdmr = sdmr | PSDMR_OP_PREA; *ramaddr = 0xff; - for (i = 0; i < 8; i++) - { + for (i = 0; i < 8; i++) { memctl->memc_lsdmr = sdmr | PSDMR_OP_CBRR; *ramaddr = 0xff; } @@ -408,16 +342,15 @@ long int initdram(int board_type) memctl->memc_lsdmr = CFG_LSDMR | PSDMR_OP_NORM; #endif /* initialise 60x bus ram */ - memctl->memc_psrt = 0x0b; - memctl->memc_purt = 0x08; - ramaddr32 = (ulong*)PHYS_SDRAM_60X; + memctl->memc_psrt = 0x0b; + memctl->memc_purt = 0x08; + ramaddr32 = (ulong *) PHYS_SDRAM_60X; sdmr = CFG_PSDMR & ~(PSDMR_OP_MSK | PSDMR_RFEN | PSDMR_PBI); memctl->memc_psdmr = sdmr | PSDMR_OP_PREA; ramaddr32[0] = 0x00ff00ff; ramaddr32[1] = 0x00ff00ff; memctl->memc_psdmr = sdmr | PSDMR_OP_CBRR; - for (i = 0; i < 8; i++) - { + for (i = 0; i < 8; i++) { ramaddr32[0] = 0x00ff00ff; ramaddr32[1] = 0x00ff00ff; } @@ -425,10 +358,10 @@ long int initdram(int board_type) ramaddr32[0] = 0x00ff00ff; ramaddr32[1] = 0x00ff00ff; memctl->memc_psdmr = sdmr | PSDMR_OP_NORM | PSDMR_RFEN; - } + } - /* return the size of the 60x bus ram */ - return PHYS_SDRAM_60X_SIZE; + /* return the size of the 60x bus ram */ + return PHYS_SDRAM_60X_SIZE; } /* ------------------------------------------------------------------------- */ @@ -438,7 +371,7 @@ long int initdram(int board_type) * has been relocated into ram */ -void misc_init_r(bd_t *bd) +void misc_init_r (bd_t * bd) { - printf("misc_init_r\n"); + printf ("misc_init_r\n"); } diff --git a/board/sbc8260/sbc8260.c b/board/sbc8260/sbc8260.c index 77d6dbf..916728a 100644 --- a/board/sbc8260/sbc8260.c +++ b/board/sbc8260/sbc8260.c @@ -41,7 +41,7 @@ const iop_conf_t iop_conf_tab[4][32] = { /* Port A configuration */ { /* conf ppar psor pdir podr pdat */ - /* PA31 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 *ATMTXEN */ + /* PA31 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 *ATMTXEN */ /* PA30 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTCA */ /* PA29 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTSOC */ /* PA28 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 *ATMRXEN */ @@ -162,11 +162,21 @@ const iop_conf_t iop_conf_tab[4][32] = { /* PD21 */ { 1, 0, 0, 1, 0, 0 }, /* PD21 */ /* PD20 */ { 1, 0, 0, 1, 0, 0 }, /* PD20 */ /* PD19 */ { 1, 0, 0, 1, 0, 0 }, /* PD19 */ - /* PD18 */ { 1, 0, 0, 1, 0, 0 }, /* PD19 */ + /* PD18 */ { 1, 0, 0, 1, 0, 0 }, /* PD18 */ /* PD17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */ /* PD16 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */ +#if defined(CONFIG_SOFT_I2C) + /* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */ + /* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */ +#else +#if defined(CONFIG_HARD_I2C) /* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */ /* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */ +#else /* normal I/O port pins */ + /* PD15 */ { 1, 0, 0, 1, 0, 0 }, /* I2C SDA */ + /* PD14 */ { 1, 0, 0, 1, 0, 0 }, /* I2C SCL */ +#endif +#endif /* PD13 */ { 1, 0, 0, 0, 0, 0 }, /* PD13 */ /* PD12 */ { 1, 0, 0, 0, 0, 0 }, /* PD12 */ /* PD11 */ { 1, 0, 0, 0, 0, 0 }, /* PD11 */ diff --git a/board/walnut405/walnut405.c b/board/walnut405/walnut405.c index 5ab2d53..42f9983 100644 --- a/board/walnut405/walnut405.c +++ b/board/walnut405/walnut405.c @@ -63,19 +63,19 @@ int board_pre_init (void) mtebc(pb1ap,0x02815480); mtebc(pb1cr,0xF0018000); - // BAS=0xF01,BS=0x0(1MB),BU=0x3(R/W),BW=0x0(8 bits) + /* BAS=0xF01,BS=0x0(1MB),BU=0x3(R/W),BW=0x0(8 bits) */ mtebc(pb2ap,0x04815A80); mtebc(pb2cr,0xF0118000); - // BAS=0xF02,BS=0x0(1MB),BU=0x3(R/W),BW=0x0( 8 bits) + /* BAS=0xF02,BS=0x0(1MB),BU=0x3(R/W),BW=0x0( 8 bits) */ mtebc(pb3ap,0x01815280); mtebc(pb3cr,0xF0218000); - // BAS=0xF03,BS=0x0(1MB),BU=0x3(R/W),BW=0x0(8 bits) + /* BAS=0xF03,BS=0x0(1MB),BU=0x3(R/W),BW=0x0(8 bits) */ mtebc(pb7ap,0x01815280); mtebc(pb7cr,0xF0318000); - //set UART1 control to select CTS/RTS + /* set UART1 control to select CTS/RTS */ #define FPGA_BRDC 0xF0300004 *(volatile char *)(FPGA_BRDC) |= 0x1; diff --git a/common/Makefile b/common/Makefile index 486c1b0..05a1605 100644 --- a/common/Makefile +++ b/common/Makefile @@ -37,7 +37,7 @@ COBJS = board.o main.o command.o environment.o bedbug.o \ console.o devices.o dlmalloc.o docecc.o \ flash.o hush.o kgdb.o lists.o \ miiphybb.o miiphyutil.o s_record.o \ - usb.o usb_kbd.o usb_storage.o + usb.o usb_kbd.o usb_storage.o soft_i2c.o OBJS = $(AOBJS) $(COBJS) diff --git a/common/board.c b/common/board.c index b0a98a4..d2437ee 100644 --- a/common/board.c +++ b/common/board.c @@ -58,6 +58,10 @@ #if (CONFIG_COMMANDS & CFG_CMD_DOC) void doc_init (void); #endif +#if defined(CONFIG_HARD_I2C) || \ + defined(CONFIG_SOFT_I2C) +#include +#endif static char *failed = "*** failed ***\n"; @@ -299,6 +303,12 @@ board_init_f (ulong bootflag) WATCHDOG_RESET(); +#if defined(CONFIG_HARD_I2C) || \ + defined(CONFIG_SOFT_I2C) + puts ("I2C\n"); + i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); +#endif + /* Digital Thermometers and Thermostats */ #if defined(CONFIG_DTT) dtt_init(); diff --git a/common/cmd_eeprom.c b/common/cmd_eeprom.c index b5433b9..0e5e12e 100644 --- a/common/cmd_eeprom.c +++ b/common/cmd_eeprom.c @@ -41,6 +41,8 @@ extern int eeprom_write (unsigned dev_addr, unsigned offset, /* Maximum number of times to poll for acknowledge after write. */ #define MAX_ACKNOWLEDGE_POLLS 10 + +#warning "x40430 modifications for the Grand Unifying I2C interface is untested" #endif /* ------------------------------------------------------------------------- */ @@ -149,7 +151,8 @@ int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt #ifdef CONFIG_SPI spi_read (addr, alen, buffer, len); #else - if (i2c_read (addr, alen, buffer, len) != 0) rcode = 1; + if (i2c_read (addr[0], offset, alen-1, buffer, len) != 0) + rcode = 1; #endif buffer += len; offset += len; @@ -240,10 +243,7 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn addr_void[0] |= CFG_I2C_EEPROM_ADDR; #endif contr_reg[0] = 0xff; - if (i2c_write (contr_r_addr, 1, contr_reg, 1) != 0) { - rcode = 1; - } - if (i2c_read (contr_r_addr, 1, contr_reg, 1) != 0) { + if (i2c_read (contr_r_addr[0], contr_r_addr[1], 1, contr_reg, 1) != 0) { rcode = 1; } ctrl_reg_v = contr_reg[0]; @@ -257,25 +257,22 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn /* Set write enable latch. */ - contr_reg[0] = 0xff; - contr_reg[1] = 0x02; - if (i2c_write (contr_r_addr, 1, contr_reg, 2) != 0) { + contr_reg[0] = 0x02; + if (i2c_write (contr_r_addr[0], 0xff, 1, contr_reg, 1) != 0) { rcode = 1; } /* Set register write enable latch. */ - contr_reg[0] = 0xff; - contr_reg[1] = 0x06; - if (i2c_write (contr_r_addr, 1, contr_reg, 2) != 0) { + contr_reg[0] = 0x06; + if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) { rcode = 1; } /* Modify ctrl register. */ - contr_reg[0] = 0xff; - contr_reg[1] = ctrl_reg_v; - if (i2c_write (contr_r_addr, 1, contr_reg, 2) != 0) { + contr_reg[0] = ctrl_reg_v; + if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) { rcode = 1; } @@ -289,7 +286,7 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn */ contr_reg[0] = 0; for (i = 0; i < MAX_ACKNOWLEDGE_POLLS; i++) { - if (i2c_read (addr_void, 1, contr_reg, 1) == 1) + if (i2c_read (addr_void[0], addr_void[1], 1, contr_reg, 1) == 1) break; /* got ack */ #if defined(CFG_EEPROM_PAGE_WRITE_DELAY_MS) udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000); @@ -306,16 +303,17 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn else if (!(ctrl_reg_v & 0x02)) { /* Set write enable latch. */ - contr_reg[0] = 0xff; - contr_reg[1] = 0x02; - if (i2c_write (contr_r_addr, 1, contr_reg, 2) != 0) { + contr_reg[0] = 0x02; + if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) { rcode = 1; } } /* Write is enabled ... now write eeprom value. */ #endif - if (i2c_write (addr, alen, buffer, len) != 0) rcode = 1; + if (i2c_write (addr[0], offset, alen-1, buffer, len) != 0) + rcode = 1; + #endif buffer += len; offset += len; @@ -347,10 +345,6 @@ void eeprom_init (void) i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); # endif #endif -#if defined(CONFIG_MPC824X) && defined(CONFIG_I2C) - i2c_init (); -#endif - } /*----------------------------------------------------------------------- */ diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 17e5e9b..5d9a391 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -1,6 +1,6 @@ /* - * (C) Copyright 2000, 2001 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * (C) Copyright 2001 + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. * * See file CREDITS for list of people who contributed to this * project. @@ -19,258 +19,768 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA - * - * hacked for i2c support by Murray.Jensen@cmst.csiro.au, 20-Dec-00 */ /* - * I2C support + * I2C Functions just like the standard memory functions + * + * Adapted from cmd_mem.c, Wolfgang Denk (wd@denx.de). */ + #include #include -#include #include +#include -#define I2C_DEBUG +#if (CONFIG_COMMANDS & CFG_CMD_I2C) -#ifdef I2C_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif +/* Display values from last command. + * Memory modify remembered values are different from display memory. + */ +static uchar i2c_dp_last_chip; +static uint i2c_dp_last_addr; +static uint i2c_dp_last_alen; +static uint i2c_dp_last_length = 0x10; -#if defined(CONFIG_I2C) && (CONFIG_COMMANDS & CFG_CMD_I2C) +static uchar i2c_mm_last_chip; +static uint i2c_mm_last_addr; +static uint i2c_mm_last_alen; -/* ------------------------------------------------------------------------- */ +static int +mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]); -int -do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) -{ - unsigned char i2c_addr, sec_addr, *data_addr; - unsigned short size; - int speed; - int rc; -#if !(defined(CONFIG_I2C_4XX) || defined (CONFIG_MPC824X)) - i2c_state_t state; -#endif +/* + * Syntax: + * imd {i2c_chip} {addr}{.1, .2} {len} + * addr len + */ +#define DISP_LINE_LEN 16 - switch (argc) { +int do_i2c_md (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + u_char chip; + uint addr, alen, length; + int j, nbytes, linebytes; + + /* We use the last specified parameters, unless new ones are + * entered. + */ + chip = i2c_dp_last_chip; + addr = i2c_dp_last_addr; + alen = i2c_dp_last_alen; + length = i2c_dp_last_length; + + if (argc < 3) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } - case 0: - case 1: - break; + if ((flag & CMD_FLAG_REPEAT) == 0) { + /* + * New command specified. + */ + alen = 1; + + /* + * I2C chip address + */ + chip = simple_strtoul(argv[1], NULL, 16); + + /* + * I2C data address within the chip. This can be 1 or + * 2 bytes long. Some day it might be 3 bytes long :-). + */ + addr = simple_strtoul(argv[2], NULL, 16); + alen = 1; + for(j = 0; j < 8; j++) { + if (argv[2][j] == '.') { + alen = argv[2][j+1] - '0'; + if (alen > 4) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + break; + } else if (argv[2][j] == '\0') { + break; + } + } - case 2: - if (strncmp (argv[1], "res", 3) == 0) { - printf ("I2C reset 50kHz ... "); -#if defined(CONFIG_I2C_4XX) || defined (CONFIG_MPC824X) - i2c_init (); -#else - i2c_init (50000, 0xfe); /* use all one's as slave address */ -#endif - printf ("DONE\n"); - return 0; - } - break; - - case 3: - if (strncmp(argv[1], "res", 3) == 0) { - speed = (int)simple_strtoul(argv[2], NULL, 10); - if (speed % 1000) - printf ("I2C reset %d.%03dkHz ... ", speed/1000, speed%1000); - else - printf ("I2C reset %dkHz ... ", speed/1000); -#if defined(CONFIG_I2C_4XX) || defined (CONFIG_MPC824X) - i2c_init (); -#else - i2c_init (speed, 0xfe); /* use all one's as slave address */ -#endif - printf ("DONE\n"); - return 0; + /* + * If another parameter, it is the length to display. + * Length is the number of objects, not number of bytes. + */ + if (argc > 3) + length = simple_strtoul(argv[3], NULL, 16); } - break; - case 4: - break; + /* + * Print the lines. + * + * We buffer all read data, so we can make sure data is read only + * once. + */ + nbytes = length; + do { + unsigned char linebuf[DISP_LINE_LEN]; + unsigned char *cp; + + linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; + + if(i2c_read(chip, addr, alen, linebuf, linebytes) != 0) { + printf("Error reading the chip.\n"); + } else { + printf("%04x:", addr); + cp = linebuf; + for (j=0; j 0x7e)) + printf("."); + else + printf("%c", *cp); + cp++; + } + printf("\n"); + } + nbytes -= linebytes; + } while (nbytes > 0); - case 5: - if (strncmp(argv[1], "recv", 4) == 0) { - i2c_addr = (unsigned char)simple_strtoul(argv[2], NULL, 16); - data_addr = (unsigned char *)simple_strtoul(argv[3], NULL, 16); - size = (unsigned short)simple_strtoul(argv[4], NULL, 16); + i2c_dp_last_chip = chip; + i2c_dp_last_addr = addr; + i2c_dp_last_alen = alen; + i2c_dp_last_length = length; - printf ("I2C recv: i2c_addr 0x%02x, data_addr 0x%08lx, " - "size %u ... " -#ifdef I2C_DEBUG - "\n" -#endif - , i2c_addr, (ulong)data_addr, size); + return 0; +} -#if !(defined(CONFIG_I2C_4XX) || defined (CONFIG_MPC824X)) - i2c_newio (&state); -#endif +int do_i2c_mm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + return mod_i2c_mem (cmdtp, 1, flag, argc, argv); +} -#if defined(CONFIG_I2C_4XX) - rc = i2c_receive (i2c_addr, size, data_addr); -#elif defined(CONFIG_MPC824X) - rc = i2c_receive (i2c_addr, 0, size, data_addr); -#else - rc = i2c_receive (&state, i2c_addr, 0, - I2CF_START_COND|I2CF_STOP_COND, - size, data_addr); -#endif +int do_i2c_nm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + return mod_i2c_mem (cmdtp, 0, flag, argc, argv); +} +/* Write (fill) memory + * + * Syntax: + * imw {i2c_chip} {addr}{.1, .2} {data} [{count}] + */ +int do_i2c_mw (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + uchar chip; + ulong addr; + uint alen; + uchar byte; + int count; + int j; + + if ((argc < 4) || (argc > 5)) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } - if (rc) { - printf ("i2c_receive FAILED rc=%d\n", rc); - return 1; + /* + * Chip is always specified. + */ + chip = simple_strtoul(argv[1], NULL, 16); + + /* + * Address is always specified. + */ + addr = simple_strtoul(argv[2], NULL, 16); + alen = 1; + for(j = 0; j < 8; j++) { + if (argv[2][j] == '.') { + alen = argv[2][j+1] - '0'; + if(alen > 4) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + break; + } else if (argv[2][j] == '\0') { + break; } + } -#if !(defined(CONFIG_I2C_4XX) || defined (CONFIG_MPC824X)) - rc = i2c_doio (&state); -#endif + /* + * Value to write is always specified. + */ + byte = simple_strtoul(argv[3], NULL, 16); + + /* + * Optional count + */ + if(argc == 5) { + count = simple_strtoul(argv[4], NULL, 16); + } else { + count = 1; + } - if (rc) { - printf ("i2c_doio FAILED rc=%d\n", rc); - return 1; + while (count-- > 0) { + if(i2c_write(chip, addr++, alen, &byte, 1) != 0) { + printf("Error writing the chip.\n"); } + /* + * Wait for the write to complete. The write can take + * up to 10mSec (we allow a little more time). + * + * On some chips, while the write is in progress, the + * chip doesn't respond. This apparently isn't a + * universal feature so we don't take advantage of it. + */ + udelay(11000); +#if 0 + for(timeout = 0; timeout < 10; timeout++) { + udelay(2000); + if(i2c_probe(chip) == 0) + break; + } +#endif + } - printf ("DONE\n"); - return 0; - } else if (strncmp(argv[1], "send",4) == 0) { - i2c_addr = (unsigned char)simple_strtoul(argv[2], NULL, 16); - data_addr = (unsigned char *)simple_strtoul(argv[3], NULL, 16); - size = (unsigned short)simple_strtoul(argv[4], NULL, 16); - - printf ("I2C send: i2c_addr 0x%02x, data_addr 0x%08lx, " - "size %u ... ", i2c_addr, (ulong)data_addr, size); + return (0); +} -#if !(defined(CONFIG_I2C_4XX) || defined (CONFIG_MPC824X)) - i2c_newio (&state); -#endif +/* Calculate a CRC on memory + * + * Syntax: + * icrc32 {i2c_chip} {addr}{.1, .2} {count} + */ +int do_i2c_crc (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + uchar chip; + ulong addr; + uint alen; + int count; + uchar byte; + ulong crc; + ulong err; + int j; + + if (argc < 4) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } -#if defined(CONFIG_I2C_4XX) - rc = i2c_send (i2c_addr, size, data_addr); -#elif defined(CONFIG_MPC824X) - rc = i2c_send (i2c_addr, 0, size, data_addr); -#else - rc = i2c_send (&state, i2c_addr, 0, - I2CF_START_COND|I2CF_STOP_COND, size, data_addr); -#endif - if (rc) { - printf ("i2c_receive FAILED rc=%d\n", rc); - return 1; + /* + * Chip is always specified. + */ + chip = simple_strtoul(argv[1], NULL, 16); + + /* + * Address is always specified. + */ + addr = simple_strtoul(argv[2], NULL, 16); + alen = 1; + for(j = 0; j < 8; j++) { + if (argv[2][j] == '.') { + alen = argv[2][j+1] - '0'; + if(alen > 4) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + break; + } else if (argv[2][j] == '\0') { + break; } + } -#if !(defined(CONFIG_I2C_4XX) || defined (CONFIG_MPC824X)) - rc = i2c_doio (&state); -#endif - - if (rc) { - printf ("i2c_doio FAILED rc=%d\n", rc); - return 1; + /* + * Count is always specified + */ + count = simple_strtoul(argv[3], NULL, 16); + + printf ("CRC32 for %08lx ... %08lx ==> ", addr, addr + count - 1); + /* + * CRC a byte at a time. This is going to be slooow, but hey, the + * memories are small and slow too so hopefully nobody notices. + */ + crc = 0; + err = 0; + while(count-- > 0) { + if(i2c_read(chip, addr, alen, &byte, 1) != 0) { + err++; } - - printf ("DONE\n"); - return 0; + crc = crc32 (crc, &byte, 1); + addr++; + } + if(err > 0) + { + printf("Error reading the chip,\n"); + } else { + printf ("%08lx\n", crc); } - break; - case 6: - if (strncmp(argv[1], "rcvs", 4) == 0) { - i2c_addr = (unsigned char)simple_strtoul(argv[2], NULL, 16); - sec_addr = (unsigned char)simple_strtoul(argv[3], NULL, 16); - data_addr = (unsigned char *)simple_strtoul(argv[4], NULL, 16); - size = (unsigned short)simple_strtoul(argv[5], NULL, 16); + return 0; +} - printf ("I2C recv: i2c_addr 0x%02x, sec_addr 0x%02x, " - "data_addr 0x%08lx, size %u ... ", - i2c_addr, sec_addr, (ulong)data_addr, size); -#if !(defined(CONFIG_I2C_4XX) || defined (CONFIG_MPC824X)) - i2c_newio (&state); -#endif +/* Modify memory. + * + * Syntax: + * imm {i2c_chip} {addr}{.1, .2} + * inm {i2c_chip} {addr}{.1, .2} + */ -#if defined(CONFIG_I2C_4XX) - rc = i2c_receive (i2c_addr, size, data_addr); -#elif defined(CONFIG_MPC824X) - rc = i2c_receive (i2c_addr, sec_addr, size, data_addr); -#else - rc = i2c_receive (&state, i2c_addr, sec_addr, - I2CF_ENABLE_SECONDARY|I2CF_START_COND|I2CF_STOP_COND, - size, data_addr); -#endif +static int +mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) +{ + uchar chip; + ulong addr; + uint alen; + ulong data; + int size = 1; + int nbytes; + int j; + extern char console_buffer[]; + + if (argc != 3) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } - if (rc) { - printf ("i2c_receive FAILED rc=%d\n", rc); - return 1; +#ifdef CONFIG_BOOT_RETRY_TIME + reset_cmd_timeout(); /* got a good command to get here */ +#endif + /* + * We use the last specified parameters, unless new ones are + * entered. + */ + chip = i2c_mm_last_chip; + addr = i2c_mm_last_addr; + alen = i2c_mm_last_alen; + + if ((flag & CMD_FLAG_REPEAT) == 0) { + /* + * New command specified. Check for a size specification. + * Defaults to byte if no or incorrect specification. + */ + size = 1; + if (argv[0][3] == '.') { + if (argv[0][4] == 'b') { + size = 1; + } else if (argv[0][4] == 'w') { + size = 2; + } else if (argv[0][4] == 'l') { + size = 4; + } } -#if !(defined(CONFIG_I2C_4XX) || defined (CONFIG_MPC824X)) - rc = i2c_doio (&state); -#endif + /* + * Chip is always specified. + */ + chip = simple_strtoul(argv[1], NULL, 16); + + /* + * Address is always specified. + */ + addr = simple_strtoul(argv[2], NULL, 16); + alen = 1; + for(j = 0; j < 8; j++) { + if (argv[2][j] == '.') { + alen = argv[2][j+1] - '0'; + if(alen > 4) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + break; + } else if (argv[2][j] == '\0') { + break; + } + } + } - if (rc) { - printf ("i2c_doio FAILED rc=%d\n", rc); - return 1; + /* + * Print the address, followed by value. Then accept input for + * the next value. A non-converted value exits. + */ + do { + printf("%08lx:", addr); + if(i2c_read(chip, addr, alen, (char *)&data, size) != 0) { + printf("\nError reading the chip,\n"); + } else { + if(size == 1) { + printf(" %02lx", (data >> 24) & 0x000000FF); + } else if(size == 2) { + printf(" %04lx", (data >> 16) & 0x0000FFFF); + } else { + printf(" %08lx", data); + } } - printf ("DONE\n"); - return 0; - } - else if (strncmp(argv[1], "snds",4) == 0) { - i2c_addr = (unsigned char)simple_strtoul(argv[2], NULL, 16); - sec_addr = (unsigned char)simple_strtoul(argv[3], NULL, 16); - data_addr = (unsigned char *)simple_strtoul(argv[4], NULL, 16); - size = (unsigned short)simple_strtoul(argv[5], NULL, 16); - - printf ("I2C send: i2c_addr 0x%02x, sec_addr 0x%02x, " - "data_addr 0x%08lx, size %u ... ", - i2c_addr, sec_addr, (ulong)data_addr, size); - -#if !(defined(CONFIG_I2C_4XX) || defined (CONFIG_MPC824X)) - i2c_newio (&state); + nbytes = readline (" ? "); + if (nbytes == 0) { + /* + * pressed as only input, don't modify current + * location and move to next. + */ + if (incrflag) + addr += size; + nbytes = size; +#ifdef CONFIG_BOOT_RETRY_TIME + reset_cmd_timeout(); /* good enough to not time out */ #endif - -#if defined(CONFIG_I2C_4XX) - rc = i2c_send (i2c_addr, size, data_addr); -#elif defined(CONFIG_MPC824X) - rc = i2c_send (i2c_addr, sec_addr, size, data_addr); -#else - rc = i2c_send (&state, i2c_addr, sec_addr, - I2CF_ENABLE_SECONDARY|I2CF_START_COND|I2CF_STOP_COND, - size, data_addr); + } +#ifdef CONFIG_BOOT_RETRY_TIME + else if (nbytes == -2) { + break; /* timed out, exit the command */ + } +#endif + else { + char *endp; + + data = simple_strtoul(console_buffer, &endp, 16); + if(size == 1) { + data = data << 24; + } else if(size == 2) { + data = data << 16; + } + nbytes = endp - console_buffer; + if (nbytes) { +#ifdef CONFIG_BOOT_RETRY_TIME + /* + * good enough to not time out + */ + reset_cmd_timeout(); #endif + if(i2c_write(chip, addr, alen, (char *)&data, size) != 0) { + printf("Error writing the chip.\n"); + } + if (incrflag) + addr += size; + } + } + } while (nbytes); - if (rc) { - printf ("i2c_send FAILED rc=%d\n", rc); - return 1; + chip = i2c_mm_last_chip; + addr = i2c_mm_last_addr; + alen = i2c_mm_last_alen; + + return 0; +} + +/* + * Syntax: + * iprobe {addr}{.1, .2} + */ +int do_i2c_probe(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + int j; + + printf("Valid chip addresses:"); + for(j = 0; j < 128; j++) { + if(i2c_probe(j) == 0) { + printf(" %02X", j); } + } + printf("\n"); -#if !(defined(CONFIG_I2C_4XX) || defined (CONFIG_MPC824X)) - rc = i2c_doio (&state); -#endif + return 0; +} + + +/* + * Syntax: + * iloop {i2c_chip} {addr}{.1, .2} [{length}] [{delay}] + * {length} - Number of bytes to read + * {delay} - A DECIMAL number and defaults to 1000 uSec + */ +int do_i2c_loop(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + u_char chip; + ulong alen; + uint addr; + uint length; + u_char bytes[16]; + int delay; + int j; + + if (argc < 3) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } - if (rc) { - printf ("i2c_doio FAILED rc=%d\n", rc); - return 1; + /* + * Chip is always specified. + */ + chip = simple_strtoul(argv[1], NULL, 16); + + /* + * Address is always specified. + */ + addr = simple_strtoul(argv[2], NULL, 16); + alen = 1; + for(j = 0; j < 8; j++) { + if (argv[2][j] == '.') { + alen = argv[2][j+1] - '0'; + if (alen > 4) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + break; + } else if (argv[2][j] == '\0') { + break; } + } - printf ("DONE\n"); - return 0; + /* + * Length is the number of objects, not number of bytes. + */ + length = 1; + length = simple_strtoul(argv[3], NULL, 16); + if(length > sizeof(bytes)) { + length = sizeof(bytes); } - break; - default: - break; - } + /* + * The delay time (uSec) is optional. + */ + delay = 1000; + if (argc > 3) { + delay = simple_strtoul(argv[4], NULL, 10); + } + /* + * Run the loop... + */ + while(1) { + if(i2c_read(chip, addr, alen, bytes, length) != 0) { + printf("Error reading the chip.\n"); + } + udelay(delay); + } - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; + /* NOTREACHED */ + return 0; } -/* ------------------------------------------------------------------------- */ +/* + * Syntax: + * sdram {i2c_chip} + */ +int do_sdram(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + u_char chip; + u_char data[128]; + u_char cksum; + int j; + + if (argc < 2) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + /* + * Chip is always specified. + */ + chip = simple_strtoul(argv[1], NULL, 16); + + if(i2c_read(chip, 0, 1, data, sizeof(data)) != 0) { + printf("No SDRAM Serial Presence Detect found.\n"); + return 1; + } + + cksum = 0; + for(j = 0; j < 63; j++) { + cksum += data[j]; + } + if(cksum != data[63]) { + printf ("WARNING: Configuration data checksum failure:\n" + " is 0x%02x, calculated 0x%02x\n", + data[63], cksum); + } + printf("SPD data revision %d.%d\n", + (data[62] >> 4) & 0x0F, data[62] & 0x0F); + printf("Bytes used 0x%02X\n", data[0]); + printf("Serial memory size 0x%02X\n", 1 << data[1]); + printf("Memory type "); + switch(data[2]) { + case 2: printf("EDO\n"); break; + case 4: printf("SDRAM\n"); break; + default: printf("unknown\n"); break; + } + printf("Row address bits "); + if((data[3] & 0x00F0) == 0) { + printf("%d\n", data[3] & 0x0F); + } else { + printf("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F); + } + printf("Column address bits "); + if((data[4] & 0x00F0) == 0) { + printf("%d\n", data[4] & 0x0F); + } else { + printf("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F); + } + printf("Module rows %d\n", data[5]); + printf("Module data width %d bits\n", (data[7] << 8) | data[6]); + printf("Interface signal levels "); + switch(data[8]) { + case 0: printf("5.0v/TTL\n"); break; + case 1: printf("LVTTL\n"); break; + case 2: printf("HSTL 1.5\n"); break; + case 3: printf("SSTL 3.3\n"); break; + case 4: printf("SSTL 2.5\n"); break; + default: printf("unknown\n"); break; + } + printf("SDRAM cycle time %d.%d nS\n", + (data[9] >> 4) & 0x0F, data[9] & 0x0F); + printf("SDRAM access time %d.%d nS\n", + (data[10] >> 4) & 0x0F, data[10] & 0x0F); + printf("EDC configuration "); + switch(data[11]) { + case 0: printf("None\n"); break; + case 1: printf("Parity\n"); break; + case 2: printf("ECC\n"); break; + default: printf("unknown\n"); break; + } + if((data[12] & 0x80) == 0) { + printf("No self refresh, rate "); + } else { + printf("Self refresh, rate "); + } + switch(data[12] & 0x7F) { + case 0: printf("15.625uS\n"); break; + case 1: printf("3.9uS\n"); break; + case 2: printf("7.8uS\n"); break; + case 3: printf("31.3uS\n"); break; + case 4: printf("62.5uS\n"); break; + case 5: printf("125uS\n"); break; + default: printf("unknown\n"); break; + } + printf("SDRAM width (primary) %d\n", data[13] & 0x7F); + if((data[13] & 0x80) != 0) { + printf(" (second bank) %d\n", + 2 * (data[13] & 0x7F)); + } + if(data[14] != 0) { + printf("EDC width %d\n", + data[14] & 0x7F); + if((data[14] & 0x80) != 0) { + printf(" (second bank) %d\n", + 2 * (data[14] & 0x7F)); + } + } + printf("Min clock delay, back-to-back random column addresses %d\n", + data[15]); + printf("Burst length(s) "); + if(data[16] & 0x80) printf(" Page"); + if(data[16] & 0x08) printf(" 8"); + if(data[16] & 0x04) printf(" 4"); + if(data[16] & 0x02) printf(" 2"); + if(data[16] & 0x01) printf(" 1"); + printf("\n"); + printf("Number of banks %d\n", data[17]); + printf("CAS latency(s) "); + if(data[18] & 0x80) printf(" TBD"); + if(data[18] & 0x40) printf(" 7"); + if(data[18] & 0x20) printf(" 6"); + if(data[18] & 0x10) printf(" 5"); + if(data[18] & 0x08) printf(" 4"); + if(data[18] & 0x04) printf(" 3"); + if(data[18] & 0x02) printf(" 2"); + if(data[18] & 0x01) printf(" 1"); + printf("\n"); + printf("CS latency(s) "); + if(data[19] & 0x80) printf(" TBD"); + if(data[19] & 0x40) printf(" 6"); + if(data[19] & 0x20) printf(" 5"); + if(data[19] & 0x10) printf(" 4"); + if(data[19] & 0x08) printf(" 3"); + if(data[19] & 0x04) printf(" 2"); + if(data[19] & 0x02) printf(" 1"); + if(data[19] & 0x01) printf(" 0"); + printf("\n"); + printf("WE latency(s) "); + if(data[20] & 0x80) printf(" TBD"); + if(data[20] & 0x40) printf(" 6"); + if(data[20] & 0x20) printf(" 5"); + if(data[20] & 0x10) printf(" 4"); + if(data[20] & 0x08) printf(" 3"); + if(data[20] & 0x04) printf(" 2"); + if(data[20] & 0x02) printf(" 1"); + if(data[20] & 0x01) printf(" 0"); + printf("\n"); + printf("Module attributes:\n"); + if(!data[21]) printf(" (none)\n"); + if(data[21] & 0x80) printf(" TBD (bit 7)\n"); + if(data[21] & 0x40) printf(" Redundant row address\n"); + if(data[21] & 0x20) printf(" Differential clock input\n"); + if(data[21] & 0x10) printf(" Registerd DQMB inputs\n"); + if(data[21] & 0x08) printf(" Buffered DQMB inputs\n"); + if(data[21] & 0x04) printf(" On-card PLL\n"); + if(data[21] & 0x02) printf(" Registered address/control lines\n"); + if(data[21] & 0x01) printf(" Buffered address/control lines\n"); + printf("Device attributes:\n"); + if(data[22] & 0x80) printf(" TBD (bit 7)\n"); + if(data[22] & 0x40) printf(" TBD (bit 6)\n"); + if(data[22] & 0x20) printf(" Upper Vcc tolerance 5%%\n"); + else printf(" Upper Vcc tolerance 10%%\n"); + if(data[22] & 0x10) printf(" Lower Vcc tolerance 5%%\n"); + else printf(" Lower Vcc tolerance 10%%\n"); + if(data[22] & 0x08) printf(" Supports write1/read burst\n"); + if(data[22] & 0x04) printf(" Supports precharge all\n"); + if(data[22] & 0x02) printf(" Supports auto precharge\n"); + if(data[22] & 0x01) printf(" Supports early RAS# precharge\n"); + printf("SDRAM cycle time (2nd highest CAS latency) %d.%d nS\n", + (data[23] >> 4) & 0x0F, data[23] & 0x0F); + printf("SDRAM access from clock (2nd highest CAS latency) %d.%d nS\n", + (data[24] >> 4) & 0x0F, data[24] & 0x0F); + printf("SDRAM cycle time (3rd highest CAS latency) %d.%d nS\n", + (data[25] >> 4) & 0x0F, data[25] & 0x0F); + printf("SDRAM access from clock (3rd highest CAS latency) %d.%d nS\n", + (data[26] >> 4) & 0x0F, data[26] & 0x0F); + printf("Minimum row precharge %d nS\n", data[27]); + printf("Row active to row active min %d nS\n", data[28]); + printf("RAS to CAS delay min %d nS\n", data[29]); + printf("Minimum RAS pulse width %d nS\n", data[30]); + printf("Density of each row "); + if(data[31] & 0x80) printf(" 512MByte"); + if(data[31] & 0x40) printf(" 256MByte"); + if(data[31] & 0x20) printf(" 128MByte"); + if(data[31] & 0x10) printf(" 64MByte"); + if(data[31] & 0x08) printf(" 32MByte"); + if(data[31] & 0x04) printf(" 16MByte"); + if(data[31] & 0x02) printf(" 8MByte"); + if(data[31] & 0x01) printf(" 4MByte"); + printf("\n"); + printf("Command and Address setup %c%d.%d nS\n", + (data[32] & 0x80) ? '-' : '+', + (data[32] >> 4) & 0x07, data[32] & 0x0F); + printf("Command and Address hold %c%d.%d nS\n", + (data[33] & 0x80) ? '-' : '+', + (data[33] >> 4) & 0x07, data[33] & 0x0F); + printf("Data signal input setup %c%d.%d nS\n", + (data[34] & 0x80) ? '-' : '+', + (data[34] >> 4) & 0x07, data[34] & 0x0F); + printf("Data signal input hold %c%d.%d nS\n", + (data[35] & 0x80) ? '-' : '+', + (data[35] >> 4) & 0x07, data[35] & 0x0F); + printf("Manufacturer's JEDEC ID "); + for(j = 64; j <= 71; j++) + printf("%02X ", data[j]); + printf("\n"); + printf("Manufacturing Location %02X\n", data[72]); + printf("Manufacturer's Part Number "); + for(j = 73; j <= 90; j++) + printf("%02X ", data[j]); + printf("\n"); + printf("Revision Code %02X %02X\n", data[91], data[92]); + printf("Manufacturing Date %02X %02X\n", data[93], data[94]); + printf("Assembly Serial Number "); + for(j = 95; j <= 98; j++) + printf("%02X ", data[j]); + printf("\n"); + printf("Speed rating PC%d\n", + data[126] == 0x66 ? 66 : data[126]); + + return 0; +} -#endif /* CONFIG_COMMANDS & CFG_CMD_I2C */ +#endif /* CFG_CMD_I2C */ diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 61c2ee4..3755a2c 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -51,6 +51,9 @@ #if (CONFIG_COMMANDS & CFG_CMD_NET) #include #endif +#if defined(CFG_ENV_IS_IN_EEPROM) +#include +#endif #ifdef CONFIG_SHOW_BOOT_PROGRESS # include @@ -317,14 +320,11 @@ void env_relocate (ulong offset) DEBUGF ("%s[%d] ENV is valid\n", __FUNCTION__,__LINE__); # if defined(CFG_ENV_IS_IN_EEPROM) DEBUGF ("%s[%d] read ENV from EEPROM\n", __FUNCTION__,__LINE__); - eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+offsetof(env_t,data), - env_ptr->data, - ENV_SIZE); -#elif defined(CFG_ENV_IS_IN_NVRAM) && defined(CFG_NVRAM_ACCESS_ROUTINE) - DEBUGF ("%s[%d] read ENV from NVRAM\n", __FUNCTION__,__LINE__); - nvram_read(env_ptr->data, - CFG_ENV_ADDR + sizeof(long), - ENV_SIZE); + i2c_read (CFG_I2C_EEPROM_ADDR, + CFG_ENV_OFFSET+offsetof(env_t,data), + CFG_I2C_EEPROM_ADDR_LEN, + env_ptr->data, + ENV_SIZE); # else DEBUGF ("%s[%d] read ENV from NVRAM/FLASH\n",__FUNCTION__,__LINE__); memcpy (env_ptr->data, @@ -390,10 +390,13 @@ static uchar get_env_char_eeprom (int index) init_data_t *idata = (init_data_t*)(CFG_INIT_RAM_ADDR+CFG_INIT_DATA_OFFSET); /* if the EEPROM crc was bad, use the default environment */ - if (idata->env_valid) { - eeprom_read (CFG_DEF_EEPROM_ADDR, - CFG_ENV_OFFSET+index+offsetof(env_t,data), - &c, 1); + if (idata->env_valid) + { + i2c_read (CFG_I2C_EEPROM_ADDR, + CFG_ENV_OFFSET+index+offsetof(env_t,data), + CFG_I2C_EEPROM_ADDR_LEN, + &c, + 1); } else { c = default_environment[index]; } @@ -849,10 +852,11 @@ int saveenv(void) int saveenv(void) { - return (eeprom_write (CFG_DEF_EEPROM_ADDR, - CFG_ENV_OFFSET, - (uchar *)env_ptr, CFG_ENV_SIZE) - ); + return (i2c_write (CFG_I2C_EEPROM_ADDR, + CFG_ENV_OFFSET, + CFG_I2C_EEPROM_ADDR_LEN, + (uchar *)env_ptr, + CFG_ENV_SIZE) ); } #else /* !CFG_ENV_IS_IN_NVRAM, !CFG_ENV_IS_IN_EEPROM => Must be flash, then */ @@ -993,12 +997,15 @@ void env_init(init_data_t *idata) unsigned off; uchar buf[64]; - eeprom_init (); /* prepare for EEPROM read/write */ + /* prepare for EEPROM read/write */ + i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); /* read old CRC */ - eeprom_read (CFG_DEF_EEPROM_ADDR, - CFG_ENV_OFFSET+offsetof(env_t,crc), - (uchar *)&crc, sizeof(ulong)); + i2c_read (CFG_I2C_EEPROM_ADDR, + CFG_ENV_OFFSET+offsetof(env_t,crc), + CFG_I2C_EEPROM_ADDR_LEN, + (uchar *)&crc, + sizeof(ulong)); new = 0; len = ENV_SIZE; @@ -1006,7 +1013,11 @@ void env_init(init_data_t *idata) while (len > 0) { int n = (len > sizeof(buf)) ? sizeof(buf) : len; - eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n); + i2c_read (CFG_I2C_EEPROM_ADDR, + CFG_ENV_OFFSET+off, + CFG_I2C_EEPROM_ADDR_LEN, + buf, + n); new = crc32 (new, buf, n); len -= n; off += n; diff --git a/common/cmd_pcmcia.c b/common/cmd_pcmcia.c index 4ca4fbb..e41e25e 100644 --- a/common/cmd_pcmcia.c +++ b/common/cmd_pcmcia.c @@ -752,7 +752,7 @@ static int hardware_enable(int slot) volatile pcmconf8xx_t *pcmp; volatile sysconf8xx_t *sysp; uint reg, mask; - uchar addr, val; + uchar val; PCMCIA_DEBUG ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); @@ -828,10 +828,9 @@ static int hardware_enable(int slot) } /* switch VCC on */ - addr = CFG_I2C_POWER_A_ADDR; val |= MAX1604_OP_SUS | MAX1604_VCCBON; i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); - i2c_write (&addr, 1, &val, 1); + i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1); udelay(500000); @@ -856,7 +855,7 @@ static int hardware_disable(int slot) volatile immap_t *immap; volatile pcmconf8xx_t *pcmp; u_long reg; - uchar addr, val; + uchar val; PCMCIA_DEBUG ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); @@ -864,10 +863,9 @@ static int hardware_disable(int slot) pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia)); /* remove all power, put output in high impedance state */ - addr = CFG_I2C_POWER_A_ADDR; val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ; i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); - i2c_write (&addr, 1, &val, 1); + i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1); /* Configure PCMCIA General Control Register */ PCMCIA_PGCRX(_slot_) = 0; @@ -901,7 +899,7 @@ static int voltage_set(int slot, int vcc, int vpp) volatile immap_t *immap; volatile pcmconf8xx_t *pcmp; u_long reg; - uchar addr, val; + uchar val; PCMCIA_DEBUG ("voltage_set: " \ PCMCIA_BOARD_MSG \ @@ -925,10 +923,9 @@ static int voltage_set(int slot, int vcc, int vpp) * Turn off all power (switch to high impedance) */ PCMCIA_DEBUG ("PCMCIA power OFF\n"); - addr = CFG_I2C_POWER_A_ADDR; val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ; i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); - i2c_write (&addr, 1, &val, 1); + i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1); val = 0; switch(vcc) { @@ -944,7 +941,7 @@ static int voltage_set(int slot, int vcc, int vpp) pcmp->pcmc_pipr, (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V"); - i2c_write (&addr, 1, &val, 1); + i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1); if (val) { PCMCIA_DEBUG ("PCMCIA powered at %sV\n", (val & MAX1604_VCC_35) ? "3.3" : "5.0"); diff --git a/common/command.c b/common/command.c index f046ef2..41492b8 100644 --- a/common/command.c +++ b/common/command.c @@ -43,7 +43,6 @@ #include #include -#include #include #include #include @@ -240,7 +239,6 @@ cmd_tbl_t cmd_tbl[] = { CMD_TBL_DOC CMD_TBL_DTT CMD_TBL_ECHO - CMD_TBL_EEPROM CMD_TBL_FCCINFO CMD_TBL_FLERASE CMD_TBL_FDC @@ -249,11 +247,18 @@ cmd_tbl_t cmd_tbl[] = { CMD_TBL_GO CMD_TBL_HELP CMD_TBL_I2CINFO - CMD_TBL_I2C CMD_TBL_ICACHE #ifdef CONFIG_8260 CMD_TBL_ICINFO #endif + CMD_TBL_IMD + CMD_TBL_IMM + CMD_TBL_INM + CMD_TBL_IMW + CMD_TBL_ICRC + CMD_TBL_IPROBE + CMD_TBL_ILOOP + CMD_TBL_ISDRAM CMD_TBL_IDE CMD_TBL_IMINFO CMD_TBL_IOPINFO diff --git a/common/devices.c b/common/devices.c index 9bae49c..9aa5a23 100644 --- a/common/devices.c +++ b/common/devices.c @@ -164,8 +164,8 @@ int devices_init (bd_t *bd, ulong relocation_offset) eputs ("Cannot initialize the list of devices!\n"); return -1; } -#if defined(CONFIG_I2C) && !defined(CONFIG_8xx) && !defined(CONFIG_8260) - i2c_init (); +#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) + i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); #endif #ifdef CONFIG_LCD drv_lcd_init (bd); diff --git a/common/soft_i2c.c b/common/soft_i2c.c new file mode 100644 index 0000000..6afddfb --- /dev/null +++ b/common/soft_i2c.c @@ -0,0 +1,343 @@ +/* + *(C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or(at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * This has been changed substantially by Gerald Van Baren, Custom IDEAS, + * vanbaren@cideas.com. It was heavily influenced by LiMon, written by + * Neil Russell. + */ + +#include +#include +#include + +#if defined(CONFIG_SOFT_I2C) + +#undef DEBUG_I2C + + +/*----------------------------------------------------------------------- + * Definitions + */ + +#define RETRIES 0 + + +#define I2C_ACK 0 /* PD_SDA level to ack a byte */ +#define I2C_NOACK 1 /* PD_SDA level to noack a byte */ + + +#ifdef DEBUG_I2C +#define PRINTD(x) printf x +#else +#define PRINTD(x) +#endif + +/*----------------------------------------------------------------------- + * Local functions + */ +static void send_reset (void); +static void send_start (void); +static void send_stop (void); +static void send_ack (int); +static int write_byte (uchar byte); +static uchar read_byte (int); + + +/*----------------------------------------------------------------------- + * Send a reset sequence consisting of 9 clocks with the data signal high + * to clock any confused device back into an idle state. Also send a + * at the end of the sequence for belts & suspenders. + */ +static void send_reset(void) +{ + volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT); + int j; + + I2C_ACTIVE; + I2C_SDA(1); + for(j = 0; j < 9; j++) { + I2C_SCL(0); + I2C_DELAY; + I2C_DELAY; + I2C_SCL(1); + I2C_DELAY; + I2C_DELAY; + } + send_stop(); + I2C_TRISTATE; +} + +/*----------------------------------------------------------------------- + * START: High -> Low on SDA while SCL is High + */ +static void send_start(void) +{ + volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT); + + I2C_DELAY; + I2C_SDA(1); + I2C_ACTIVE; + I2C_DELAY; + I2C_SCL(1); + I2C_DELAY; + I2C_SDA(0); + I2C_DELAY; +} + +/*----------------------------------------------------------------------- + * STOP: Low -> High on SDA while SCL is High + */ +static void send_stop(void) +{ + volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT); + + I2C_SCL(0); + I2C_DELAY; + I2C_SDA(0); + I2C_ACTIVE; + I2C_DELAY; + I2C_SCL(1); + I2C_DELAY; + I2C_SDA(1); + I2C_DELAY; + I2C_TRISTATE; +} + + +/*----------------------------------------------------------------------- + * ack should be I2C_ACK or I2C_NOACK + */ +static void send_ack(int ack) +{ + volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT); + + I2C_ACTIVE; + I2C_SCL(0); + I2C_DELAY; + + I2C_SDA(ack); + + I2C_ACTIVE; + I2C_DELAY; + I2C_SCL(1); + I2C_DELAY; + I2C_DELAY; +} + + +/*----------------------------------------------------------------------- + * Send 8 bits and look for an acknowledgement. + */ +static int write_byte(uchar data) +{ + volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT); + int j; + int nack; + + I2C_ACTIVE; + for(j = 0; j < 8; j++) { + I2C_SCL(0); + I2C_DELAY; + I2C_SDA(data & 0x80); + I2C_DELAY; + I2C_SCL(1); + I2C_DELAY; + I2C_DELAY; + + data <<= 1; + } + + /* + * Look for an (negative logic) and return it. + */ + I2C_SCL(0); + I2C_DELAY; + I2C_TRISTATE; + I2C_DELAY; + I2C_SCL(1); + I2C_DELAY; + nack = I2C_READ; + I2C_SDA(0); + I2C_ACTIVE; + I2C_DELAY; + + return(nack); /* not a nack is an ack */ +} + + +/*----------------------------------------------------------------------- + * if ack == I2C_ACK, ACK the byte so can continue reading, else + * send I2C_NOACK to end the read. + */ +static uchar read_byte(int ack) +{ + volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT); + int data; + int j; + + /* + * Read 8 bits, MSB first. + */ + I2C_TRISTATE; + data = 0; + for(j = 0; j < 8; j++) { + I2C_SCL(0); + I2C_DELAY; + I2C_SCL(1); + I2C_DELAY; + data <<= 1; + data |= I2C_READ; + I2C_DELAY; + } + send_ack(ack); + + return(data); +} + +/*=====================================================================*/ +/* Public Functions */ +/*=====================================================================*/ + +/*----------------------------------------------------------------------- + * Initialization + */ +void i2c_init(int speed, int slaveaddr) +{ + /* + * WARNING: Do NOT save speed in a static variable: if the I2C routines are + * called before RAM is initialized (to read the DIMM SPD, for instance), + * RAM won't be usable and your system will crash. + */ + send_reset(); +} + +/*----------------------------------------------------------------------- + * Probe to see if a chip is present. Also good for checking for the + * completion of EEPROM writes since the chip stops responding until + * the write completes (typically 10mSec). + */ +int i2c_probe(uchar addr) +{ + send_start(); + if(write_byte((addr << 1) | 1)) /* read cycle */ + { + send_stop(); + return(1); + } + send_stop(); + return(0); +} + +/*----------------------------------------------------------------------- + * Read bytes + */ +int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) +{ + /* + * Do the addressing portion of a write cycle to set the + * chip's address pointer. If the address length is zero, + * don't do the normal write cycle to set the address pointer, + * there is no address pointer in this chip. + */ + send_start(); + if(alen > 0) { + if(write_byte(chip << 1)) { /* write cycle */ + send_stop(); + PRINTD(("i2c_read, no chip responded %02X\n", chip)); + return(1); + } + while(alen-- > 0) { + if(write_byte(addr)) { + PRINTD("i2c_read, address not ed\n"); + return(1); + } + addr >>= 8; + } + send_stop(); /* reportedly some chips need a full stop */ + send_start(); + } + /* + * Send the chip address again, this time for a read cycle. + * Then read the data. On the last byte, we do a NACK instead + * of an ACK(len == 0) to terminate the read. + */ + write_byte((chip << 1) | 1); /* read cycle */ + while(len-- > 0) { + *buffer++ = read_byte(len == 0); + } + send_stop(); + return(0); +} + +/*----------------------------------------------------------------------- + * Write bytes + */ +int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) +{ + int failures = 0; + + send_start(); + if(write_byte(chip << 1)) { /* write cycle */ + send_stop(); + PRINTD(("i2c_write, no chip responded %02X\n", chip)); + return(1); + } + while(alen-- > 0) { + if(write_byte(addr)) { + PRINTD("i2c_write, address not ed\n"); + return(1); + } + addr >>= 8; + } + + while(len-- > 0) { + if(write_byte(*buffer++)) { + failures++; + } + } + send_stop(); + return(failures); +} + +/*----------------------------------------------------------------------- + * Read a register + */ +uchar i2c_reg_read(uchar i2c_addr, uchar reg) +{ + char buf; + + i2c_read(i2c_addr, reg, 1, &buf, 1); + + return(buf); +} + +/*----------------------------------------------------------------------- + * Write a register + */ +void i2c_reg_write(uchar i2c_addr, uchar reg, uchar val) +{ + i2c_write(i2c_addr, reg, 1, &val, 1); +} + + +#endif /* CONFIG_SOFT_I2C */ + diff --git a/cpu/mpc824x/drivers/i2c/i2c1.c b/cpu/mpc824x/drivers/i2c/i2c1.c index 17b78cb..4a97301 100644 --- a/cpu/mpc824x/drivers/i2c/i2c1.c +++ b/cpu/mpc824x/drivers/i2c/i2c1.c @@ -19,13 +19,13 @@ */ #define TIMEOUT 10*CFG_HZ #define PRINT if ( app_print ) app_print -static int (*app_print)(char *,...); +static int (*app_print) (char *, ...); /******************* Internal to I2C Driver *****************/ static unsigned int ByteToXmit = 0; static unsigned int XmitByte = 0; static unsigned char *XmitBuf = 0; -static unsigned int XmitBufEmptyStop =0; +static unsigned int XmitBufEmptyStop = 0; static unsigned int ByteToRcv = 0; static unsigned int RcvByte = 0; static unsigned char *RcvBuf = 0; @@ -47,9 +47,11 @@ static unsigned int MasterRcvAddress = 0; */ static unsigned int Global_eumbbar = 0; -extern unsigned int load_runtime_reg( unsigned int eumbbar, unsigned int reg ); +extern unsigned int load_runtime_reg (unsigned int eumbbar, + unsigned int reg); -extern unsigned int store_runtime_reg( unsigned int eumbbar, unsigned int reg, unsigned int val ); +extern unsigned int store_runtime_reg (unsigned int eumbbar, + unsigned int reg, unsigned int val); /************************** API *****************/ @@ -70,48 +72,45 @@ extern unsigned int store_runtime_reg( unsigned int eumbbar, unsigned int reg, u * * This function must be called before I2C unit can be used. */ -I2C_Status I2C_Initialize( - unsigned char addr, - I2C_INTERRUPT_MODE en_int, - int (*p)(char *,...)) +I2C_Status I2C_Initialize (unsigned char addr, + I2C_INTERRUPT_MODE en_int, + int (*p) (char *, ...)) { - I2CStatus status; - /* establish the pointer, if there is one, to the application's "printf" */ - app_print = p; - - /* If this is the first call, get the embedded utilities memory block - * base address. I'm not sure what to do about error handling here: - * if a non-zero value is returned, accept it. - */ - if ( Global_eumbbar == 0) - Global_eumbbar = get_eumbbar(); - if ( Global_eumbbar == 0) - { - PRINT( "I2C_Initialize: can't find EUMBBAR\n" ); - return I2C_ERROR; - } - - /* validate the I2C address */ - if (addr & 0x80) - { - PRINT( "I2C_Initialize, I2C address invalid: %d 0x%x\n", - (unsigned int)addr, (unsigned int)addr ); - return I2C_ERROR; - } - - /* Call the internal I2C library function to perform work. - * Accept the default frequency sampling rate (no way to set it currently, - * via I2C_Init) and set the clock frequency to something reasonable. - */ - status = I2C_Init( Global_eumbbar, (unsigned char)0x31, addr, en_int); - if (status != I2CSUCCESS) - { - PRINT( "I2C_Initialize: error in initiation\n" ); - return I2C_ERROR; - } - - /* all is well */ - return I2C_SUCCESS; + I2CStatus status; + + /* establish the pointer, if there is one, to the application's "printf" */ + app_print = p; + + /* If this is the first call, get the embedded utilities memory block + * base address. I'm not sure what to do about error handling here: + * if a non-zero value is returned, accept it. + */ + if (Global_eumbbar == 0) + Global_eumbbar = get_eumbbar (); + if (Global_eumbbar == 0) { + PRINT ("I2C_Initialize: can't find EUMBBAR\n"); + return I2C_ERROR; + } + + /* validate the I2C address */ + if (addr & 0x80) { + PRINT ("I2C_Initialize, I2C address invalid: %d 0x%x\n", + (unsigned int) addr, (unsigned int) addr); + return I2C_ERROR; + } + + /* Call the internal I2C library function to perform work. + * Accept the default frequency sampling rate (no way to set it currently, + * via I2C_Init) and set the clock frequency to something reasonable. + */ + status = I2C_Init (Global_eumbbar, (unsigned char) 0x31, addr, en_int); + if (status != I2CSUCCESS) { + PRINT ("I2C_Initialize: error in initiation\n"); + return I2C_ERROR; + } + + /* all is well */ + return I2C_SUCCESS; } @@ -130,18 +129,17 @@ I2C_Status I2C_Initialize( * rsta = I2C_NO_RESTART, this is not continuation of existing transaction * I2C_RESTART, this is a continuation of existing transaction */ -I2C_Status I2C_do_transaction( I2C_INTERRUPT_MODE en_int, - I2C_TRANSACTION_MODE act, - unsigned char i2c_addr, - unsigned char data_addr, - int len, - char *buffer, - I2C_STOP_MODE stop, - int retry, - I2C_RESTART_MODE rsta) +I2C_Status I2C_do_transaction ( I2C_INTERRUPT_MODE en_int, + I2C_TRANSACTION_MODE act, + unsigned char i2c_addr, + unsigned char data_addr, + int len, + char *buffer, + I2C_STOP_MODE stop, + int retry, I2C_RESTART_MODE rsta) { - I2C_Status status; - unsigned char data_addr_buffer[1]; + I2C_Status status; + unsigned char data_addr_buffer[1]; #if 1 /* This is a temporary work-around. The I2C library breaks the protocol @@ -155,69 +153,70 @@ I2C_Status I2C_do_transaction( I2C_INTERRUPT_MODE en_int, * "stop" and "rsta" are enough to reflect the states, maybe so; but the logic * in the library is insufficient) to control correct handling of the protocol. */ -unsigned char dummy_buffer[257]; -if (act == I2C_MASTER_XMIT) -{ -int i; -if (len > 256 ) return I2C_ERROR; -for (i=1;i<=len;i++)dummy_buffer[i]=buffer[i-1]; -dummy_buffer[0]=data_addr; - status = I2C_do_buffer(en_int, act, i2c_addr, 1 + len, - dummy_buffer, stop, retry, rsta); - if (status != I2C_SUCCESS) - { - PRINT( "I2C_do_transaction: can't perform data transfer\n"); - return I2C_ERROR; - } -return I2C_SUCCESS; -} -#endif /* end of temp work-around */ - - /* validate requested transaction type */ - if ((act != I2C_MASTER_XMIT) && (act != I2C_MASTER_RCV)) - { - PRINT( "I2C_do_transaction, invalid transaction request: %d\n", act); - return I2C_ERROR; - } - - /* range check the I2C address */ - if (i2c_addr & 0x80) - { - PRINT( "I2C_do_transaction, I2C address out of range: %d 0x%x\n", - (unsigned int)i2c_addr, (unsigned int)i2c_addr ); - return I2C_ERROR; - } else { - data_addr_buffer[0] = data_addr; - } - - /* We first have to contact the slave device and transmit the data address. - * Be careful about the STOP and restart stuff. We don't want to signal STOP - * after sending the data address, but this could be a continuation if the - * application didn't release the bus after the previous transaction, by - * not sending a STOP after it. - */ - status = I2C_do_buffer(en_int, I2C_MASTER_XMIT, i2c_addr, 1, - data_addr_buffer, I2C_NO_STOP, retry, rsta); - if (status != I2C_SUCCESS) - { - PRINT( "I2C_do_transaction: can't send data address for read\n"); - return I2C_ERROR; - } - - /* The data transfer will be a continuation. */ - rsta = I2C_RESTART; - - /* now handle the user data */ - status = I2C_do_buffer(en_int, act, i2c_addr, len, - buffer, stop, retry, rsta); - if (status != I2C_SUCCESS) - { - PRINT( "I2C_do_transaction: can't perform data transfer\n"); - return I2C_ERROR; - } - - /* all is well */ - return I2C_SUCCESS; + unsigned char dummy_buffer[257]; + + if (act == I2C_MASTER_XMIT) { + int i; + + if (len > 256) + return I2C_ERROR; + for (i = 1; i <= len; i++) + dummy_buffer[i] = buffer[i - 1]; + dummy_buffer[0] = data_addr; + status = I2C_do_buffer (en_int, act, i2c_addr, 1 + len, + dummy_buffer, stop, retry, rsta); + if (status != I2C_SUCCESS) { + PRINT ("I2C_do_transaction: can't perform data transfer\n"); + return I2C_ERROR; + } + return I2C_SUCCESS; + } +#endif /* end of temp work-around */ + + /* validate requested transaction type */ + if ((act != I2C_MASTER_XMIT) && (act != I2C_MASTER_RCV)) { + PRINT ("I2C_do_transaction, invalid transaction request: %d\n", + act); + return I2C_ERROR; + } + + /* range check the I2C address */ + if (i2c_addr & 0x80) { + PRINT ("I2C_do_transaction, I2C address out of range: %d 0x%x\n", + (unsigned int) i2c_addr, (unsigned int) i2c_addr); + return I2C_ERROR; + } else { + data_addr_buffer[0] = data_addr; + } + + /* + * We first have to contact the slave device and transmit the + * data address. Be careful about the STOP and restart stuff. + * We don't want to signal STOP after sending the data + * address, but this could be a continuation if the + * application didn't release the bus after the previous + * transaction, by not sending a STOP after it. + */ + status = I2C_do_buffer (en_int, I2C_MASTER_XMIT, i2c_addr, 1, + data_addr_buffer, I2C_NO_STOP, retry, rsta); + if (status != I2C_SUCCESS) { + PRINT ("I2C_do_transaction: can't send data address for read\n"); + return I2C_ERROR; + } + + /* The data transfer will be a continuation. */ + rsta = I2C_RESTART; + + /* now handle the user data */ + status = I2C_do_buffer (en_int, act, i2c_addr, len, + buffer, stop, retry, rsta); + if (status != I2C_SUCCESS) { + PRINT ("I2C_do_transaction: can't perform data transfer\n"); + return I2C_ERROR; + } + + /* all is well */ + return I2C_SUCCESS; } /* This function performs the work for I2C_do_transaction. The work is @@ -236,71 +235,69 @@ return I2C_SUCCESS; * rsta = I2C_NO_RESTART, this is not continuation of existing transaction * I2C_RESTART, this is a continuation of existing transaction */ -static I2C_Status I2C_do_buffer( I2C_INTERRUPT_MODE en_int, - I2C_TRANSACTION_MODE act, - unsigned char i2c_addr, - int len, - unsigned char *buffer, - I2C_STOP_MODE stop, - int retry, - I2C_RESTART_MODE rsta) +static I2C_Status I2C_do_buffer (I2C_INTERRUPT_MODE en_int, + I2C_TRANSACTION_MODE act, + unsigned char i2c_addr, + int len, + unsigned char *buffer, + I2C_STOP_MODE stop, + int retry, I2C_RESTART_MODE rsta) { - I2CStatus rval; - unsigned int dev_stat; - if (act == I2C_MASTER_RCV) - { - /* set up for master-receive transaction */ - rval = I2C_get(Global_eumbbar,i2c_addr,buffer,len,stop,rsta); - } else { - /* set up for master-transmit transaction */ - rval = I2C_put(Global_eumbbar,i2c_addr,buffer,len,stop,rsta); - } - - /* validate the setup */ - if ( rval != I2CSUCCESS ) - { - dev_stat = load_runtime_reg( Global_eumbbar, I2CSR ); - PRINT( "Error(I2C_do_buffer): control phase, code(0x%08x), status(0x%08x)\n", rval, dev_stat); - I2C_Stop( Global_eumbbar ); - return I2C_ERROR; - } - - if (en_int == 1) - { - /* this should not happen, no interrupt handling yet */ - return I2C_SUCCESS; - } - - /* this performs the polling action, when the transfer is completed, - * the status returned from I2C_Timer_Event will be I2CBUFFFULL or - * I2CBUFFEMPTY (rcv or xmit), I2CSUCCESS or I2CADDRESS indicates the - * transaction is not yet complete, anything else is an error. - */ - while ( rval == I2CSUCCESS || rval == I2CADDRESS ) - { - int timeval = get_timer(0); - - /* poll the device until something happens */ - do - { - rval = I2C_Timer_Event( Global_eumbbar, 0 ); - } - while ( rval == I2CNOEVENT && get_timer(timeval) < TIMEOUT); - - /* check for error condition */ - if ( rval == I2CSUCCESS || rval == I2CBUFFFULL || - rval == I2CBUFFEMPTY || rval == I2CADDRESS ) - { ; /* do nothing */ - } else { - /* report the error condition */ - dev_stat = load_runtime_reg( Global_eumbbar, I2CSR ); - PRINT( "Error(I2C_do_buffer): code(0x%08x), status(0x%08x)\n", rval, dev_stat ); - return I2C_ERROR; - } - } - - /* all is well */ - return I2C_SUCCESS; + I2CStatus rval; + unsigned int dev_stat; + + if (act == I2C_MASTER_RCV) { + /* set up for master-receive transaction */ + rval = I2C_get (Global_eumbbar, i2c_addr, buffer, len, stop, rsta); + } else { + /* set up for master-transmit transaction */ + rval = I2C_put (Global_eumbbar, i2c_addr, buffer, len, stop, rsta); + } + + /* validate the setup */ + if (rval != I2CSUCCESS) { + dev_stat = load_runtime_reg (Global_eumbbar, I2CSR); + PRINT ("Error(I2C_do_buffer): control phase, code(0x%08x), status(0x%08x)\n", rval, dev_stat); + I2C_Stop (Global_eumbbar); + return I2C_ERROR; + } + + if (en_int == 1) { + /* this should not happen, no interrupt handling yet */ + return I2C_SUCCESS; + } + + /* this performs the polling action, when the transfer is completed, + * the status returned from I2C_Timer_Event will be I2CBUFFFULL or + * I2CBUFFEMPTY (rcv or xmit), I2CSUCCESS or I2CADDRESS indicates the + * transaction is not yet complete, anything else is an error. + */ + while (rval == I2CSUCCESS || rval == I2CADDRESS) { + int timeval = get_timer (0); + + /* poll the device until something happens */ + do { + rval = I2C_Timer_Event (Global_eumbbar, 0); + } + while (rval == I2CNOEVENT && get_timer (timeval) < TIMEOUT); + + /* check for error condition */ + if (rval == I2CSUCCESS || + rval == I2CBUFFFULL || + rval == I2CBUFFEMPTY || + rval == I2CADDRESS) { + ; /* do nothing */ + } else { + /* report the error condition */ + dev_stat = load_runtime_reg (Global_eumbbar, I2CSR); + PRINT ("Error(I2C_do_buffer): code(0x%08x), status(0x%08x)\n", + rval, dev_stat); + return I2C_ERROR; + } + } + + /* all is well */ + return I2C_SUCCESS; } /** @@ -326,38 +323,34 @@ static I2C_Status I2C_do_buffer( I2C_INTERRUPT_MODE en_int, * * note: this is master xmit API *********************************************************/ -static I2CStatus I2C_put( unsigned int eumbbar, - unsigned char rcv_addr, /* receiver's address */ - unsigned char *buffer_ptr, /* pointer of data to be sent */ - unsigned int length, /* number of byte of in the buffer */ - unsigned int stop_flag, /* 1 - signal STOP when buffer is empty - * 0 - no STOP signal when buffer is empty - */ - unsigned int is_cnt ) /* 1 - this is a restart, don't check MBB - * 0 - this is a new start, check MBB - */ - -{ - if ( buffer_ptr == 0 || length == 0 ) - { - return I2CERROR; - } - +static I2CStatus I2C_put (unsigned int eumbbar, unsigned char rcv_addr, /* receiver's address */ + unsigned char *buffer_ptr, /* pointer of data to be sent */ + unsigned int length, /* number of byte of in the buffer */ + unsigned int stop_flag, /* 1 - signal STOP when buffer is empty + * 0 - no STOP signal when buffer is empty + */ + unsigned int is_cnt) +{ /* 1 - this is a restart, don't check MBB + * 0 - this is a new start, check MBB + */ + if (buffer_ptr == 0 || length == 0) { + return I2CERROR; + } #ifdef I2CDBG0 - PRINT( "%s(%d): I2C_put\n", __FILE__, __LINE__ ); + PRINT ("%s(%d): I2C_put\n", __FILE__, __LINE__); #endif - XmitByte = 0; - ByteToXmit = length; - XmitBuf = buffer_ptr; - XmitBufEmptyStop = stop_flag; + XmitByte = 0; + ByteToXmit = length; + XmitBuf = buffer_ptr; + XmitBufEmptyStop = stop_flag; - RcvByte = 0; - ByteToRcv = 0; - RcvBuf = 0; + RcvByte = 0; + ByteToRcv = 0; + RcvBuf = 0; - /* we are the master, start transaction */ - return I2C_Start( eumbbar, rcv_addr, XMIT, is_cnt ); + /* we are the master, start transaction */ + return I2C_Start (eumbbar, rcv_addr, XMIT, is_cnt); } /*********************************************************** @@ -373,41 +366,38 @@ static I2CStatus I2C_put( unsigned int eumbbar, * * note: this is master receive API **********************************************************/ -static I2CStatus I2C_get( unsigned int eumbbar, - unsigned char rcv_from, /* sender's address */ - unsigned char *buffer_ptr, /* pointer of receiving buffer */ - unsigned int length, /* length of the receiving buffer */ - unsigned int stop_flag, /* 1 - signal STOP when buffer is full - * 0 - no STOP signal when buffer is full - */ - unsigned int is_cnt ) /* 1 - this is a restart, don't check MBB - * 0 - this is a new start, check MBB - */ -{ - if ( buffer_ptr == 0 || length == 0 ) - { - return I2CERROR; - } - +static I2CStatus I2C_get (unsigned int eumbbar, unsigned char rcv_from, /* sender's address */ + unsigned char *buffer_ptr, /* pointer of receiving buffer */ + unsigned int length, /* length of the receiving buffer */ + unsigned int stop_flag, /* 1 - signal STOP when buffer is full + * 0 - no STOP signal when buffer is full + */ + unsigned int is_cnt) +{ /* 1 - this is a restart, don't check MBB + * 0 - this is a new start, check MBB + */ + if (buffer_ptr == 0 || length == 0) { + return I2CERROR; + } #ifdef I2CDBG0 - PRINT( "%s(%d): I2C_get\n", __FILE__, __LINE__ ); + PRINT ("%s(%d): I2C_get\n", __FILE__, __LINE__); #endif - RcvByte = 0; - ByteToRcv = length; - RcvBuf = buffer_ptr; - RcvBufFulStop = stop_flag; + RcvByte = 0; + ByteToRcv = length; + RcvBuf = buffer_ptr; + RcvBufFulStop = stop_flag; - XmitByte = 0; - ByteToXmit = 0; - XmitBuf = 0; + XmitByte = 0; + ByteToXmit = 0; + XmitBuf = 0; - /* we are the master, start the transaction */ - return I2C_Start( eumbbar, rcv_from, RCV, is_cnt ); + /* we are the master, start the transaction */ + return I2C_Start (eumbbar, rcv_from, RCV, is_cnt); } -#if 0 /* turn off dead code */ +#if 0 /* turn off dead code */ /********************************************************* * function: I2C_write * @@ -431,29 +421,27 @@ static I2CStatus I2C_get( unsigned int eumbbar, * control the interval of data byte at the * master side. *******************************************************/ -static I2CStatus I2C_write( unsigned int eumbbar, - unsigned char *buffer_ptr, /* pointer of data to be sent */ - unsigned int length, /* number of byte of in the buffer */ - unsigned int stop_flag ) /* 1 - signal STOP when buffer is empty - * 0 - no STOP signal when buffer is empty - */ -{ - if ( buffer_ptr == 0 || length == 0 ) - { - return I2CERROR; - } - - XmitByte = 0; - ByteToXmit = length; - XmitBuf = buffer_ptr; - XmitBufEmptyStop = 0; /* in order to avoid bus hung, ignored the user's stop_flag */ - - RcvByte = 0; - ByteToRcv = 0; - RcvBuf = 0; - - /* we are the slave, just wait for being called, or pull */ - /* I2C_Timer_Event( eumbbar ); */ +static I2CStatus I2C_write (unsigned int eumbbar, unsigned char *buffer_ptr, /* pointer of data to be sent */ + unsigned int length, /* number of byte of in the buffer */ + unsigned int stop_flag) +{ /* 1 - signal STOP when buffer is empty + * 0 - no STOP signal when buffer is empty + */ + if (buffer_ptr == 0 || length == 0) { + return I2CERROR; + } + + XmitByte = 0; + ByteToXmit = length; + XmitBuf = buffer_ptr; + XmitBufEmptyStop = 0; /* in order to avoid bus hung, ignored the user's stop_flag */ + + RcvByte = 0; + ByteToRcv = 0; + RcvBuf = 0; + + /* we are the slave, just wait for being called, or pull */ + /* I2C_Timer_Event( eumbbar ); */ } /****************************************************** @@ -467,31 +455,29 @@ static I2CStatus I2C_write( unsigned int eumbbar, * * note: this is slave receive API ****************************************************/ -static I2CStatus I2C_read(unsigned int eumbbar, - unsigned char *buffer_ptr, /* pointer of receiving buffer */ - unsigned int length, /* length of the receiving buffer */ - unsigned int stop_flag ) /* 1 - signal STOP when buffer is full - * 0 - no STOP signal when buffer is full - */ -{ - if ( buffer_ptr == 0 || length == 0 ) - { - return I2CERROR; - } - - RcvByte = 0; - ByteToRcv = length; - RcvBuf = buffer_ptr; - RcvBufFulStop = stop_flag; - - XmitByte = 0; - ByteToXmit = 0; - XmitBuf = 0; - - /* wait for master to call us, or poll */ - /* I2C_Timer_Event( eumbbar ); */ +static I2CStatus I2C_read (unsigned int eumbbar, unsigned char *buffer_ptr, /* pointer of receiving buffer */ + unsigned int length, /* length of the receiving buffer */ + unsigned int stop_flag) +{ /* 1 - signal STOP when buffer is full + * 0 - no STOP signal when buffer is full + */ + if (buffer_ptr == 0 || length == 0) { + return I2CERROR; + } + + RcvByte = 0; + ByteToRcv = length; + RcvBuf = buffer_ptr; + RcvBufFulStop = stop_flag; + + XmitByte = 0; + ByteToXmit = 0; + XmitBuf = 0; + + /* wait for master to call us, or poll */ + /* I2C_Timer_Event( eumbbar ); */ } -#endif /* turn off dead code */ +#endif /* turn off dead code */ /********************************************************* * function: I2c_Timer_Event @@ -502,29 +488,26 @@ static I2CStatus I2C_read(unsigned int eumbbar, * to check the I2C status and call appropriate function to * handle the status event. ********************************************************/ -static I2CStatus I2C_Timer_Event( unsigned int eumbbar, I2CStatus (*handler)( unsigned int ) ) +static I2CStatus I2C_Timer_Event (unsigned int eumbbar, + I2CStatus (*handler) (unsigned int)) { - I2C_STAT stat; + I2C_STAT stat; #ifdef I2CDBG0 - PRINT( "%s(%d): I2C_Timer_Event\n", __FILE__, __LINE__ ); + PRINT ("%s(%d): I2C_Timer_Event\n", __FILE__, __LINE__); #endif - stat = I2C_Get_Stat( eumbbar ); - - if ( stat.mif == 1 ) - { - if ( handler == 0 ) - { - return I2C_ISR( eumbbar ); - } - else - { - return (*handler)( eumbbar ); - } - } - - return I2CNOEVENT; + stat = I2C_Get_Stat (eumbbar); + + if (stat.mif == 1) { + if (handler == 0) { + return I2C_ISR (eumbbar); + } else { + return (*handler) (eumbbar); + } + } + + return I2CNOEVENT; } @@ -540,76 +523,70 @@ static I2CStatus I2C_Timer_Event( unsigned int eumbbar, I2CStatus (*handler)( un * * note: ****************************************************/ -static I2CStatus I2C_Start( unsigned int eumbbar, - unsigned char slave_addr, /* address of the receiver */ - I2C_MODE mode, /* XMIT(1) - put (write) - * RCV(0) - get (read) - */ - unsigned int is_cnt ) /* 1 - this is a restart, don't check MBB - * 0 - this is a new start - */ -{ - unsigned int tmp = 0; - I2C_STAT stat; - I2C_CTRL ctrl; +static I2CStatus I2C_Start (unsigned int eumbbar, unsigned char slave_addr, /* address of the receiver */ + I2C_MODE mode, /* XMIT(1) - put (write) + * RCV(0) - get (read) + */ + unsigned int is_cnt) +{ /* 1 - this is a restart, don't check MBB + * 0 - this is a new start + */ + unsigned int tmp = 0; + I2C_STAT stat; + I2C_CTRL ctrl; #ifdef I2CDBG0 - PRINT( "%s(%d): I2C_Start addr 0x%x mode %d cnt %d\n", __FILE__, __LINE__ , - slave_addr,mode,is_cnt); + PRINT ("%s(%d): I2C_Start addr 0x%x mode %d cnt %d\n", __FILE__, + __LINE__, slave_addr, mode, is_cnt); #endif - ctrl = I2C_Get_Ctrl( eumbbar ); - - /* first make sure I2C has been initialized */ - if ( ctrl.men == 0 ) - { - return I2CERROR; - } - - /* next make sure bus is idle */ - stat = I2C_Get_Stat( eumbbar ); - - if ( is_cnt == 0 && stat.mbb == 1 ) - { - /* sorry, we lost */ - return I2CBUSBUSY; - } - else if ( is_cnt == 1 && stat.mif == 1 && stat.mal == 0 ) - { - /* sorry, we lost the bus */ - return I2CALOSS; - } - - - /* OK, I2C is enabled and we have the bus */ - - /* prepare to write the slave address */ - ctrl.msta = 1; - ctrl.mtx = 1; - ctrl.txak = 0; - ctrl.rsta = is_cnt; /* set the repeat start bit */ - I2C_Set_Ctrl( eumbbar, ctrl ); - - /* write the slave address and xmit/rcv mode bit */ - tmp = load_runtime_reg( eumbbar, I2CDR ); - tmp = ( tmp & 0xffffff00 ) | ((slave_addr & 0x007f)<<1) | ( mode == XMIT ? 0x0 : 0x1 ); - store_runtime_reg( eumbbar, I2CDR, tmp ); - - if ( mode == RCV ) - { - MasterRcvAddress = 1; + ctrl = I2C_Get_Ctrl (eumbbar); + + /* first make sure I2C has been initialized */ + if (ctrl.men == 0) { + return I2CERROR; + } + + /* next make sure bus is idle */ + stat = I2C_Get_Stat (eumbbar); + + if (is_cnt == 0 && stat.mbb == 1) { + /* sorry, we lost */ + return I2CBUSBUSY; + } else if (is_cnt == 1 && stat.mif == 1 && stat.mal == 0) { + /* sorry, we lost the bus */ + return I2CALOSS; } - else - { + + + /* OK, I2C is enabled and we have the bus */ + + /* prepare to write the slave address */ + ctrl.msta = 1; + ctrl.mtx = 1; + ctrl.txak = 0; + ctrl.rsta = is_cnt; /* set the repeat start bit */ + I2C_Set_Ctrl (eumbbar, ctrl); + + /* write the slave address and xmit/rcv mode bit */ + tmp = load_runtime_reg (eumbbar, I2CDR); + tmp = (tmp & 0xffffff00) | + ((slave_addr & 0x007f) << 1) | + (mode == XMIT ? 0x0 : 0x1); + store_runtime_reg (eumbbar, I2CDR, tmp); + + if (mode == RCV) { + MasterRcvAddress = 1; + } else { MasterRcvAddress = 0; } #ifdef I2CDBG0 - PRINT( "%s(%d): I2C_Start exit\n", __FILE__, __LINE__ ); + PRINT ("%s(%d): I2C_Start exit\n", __FILE__, __LINE__); #endif - /* wait for the interrupt or poll */ - return I2CSUCCESS; + /* wait for the interrupt or poll */ + return I2CSUCCESS; } /*********************************************************** @@ -620,23 +597,23 @@ static I2CStatus I2C_Start( unsigned int eumbbar, * return I2CSUCCESS * **********************************************************/ -static I2CStatus I2C_Stop( unsigned int eumbbar ) +static I2CStatus I2C_Stop (unsigned int eumbbar) { - I2C_CTRL ctrl; + I2C_CTRL ctrl; #ifdef I2CDBG0 - PRINT( "%s(%d): I2C_Stop enter\n", __FILE__, __LINE__ ); + PRINT ("%s(%d): I2C_Stop enter\n", __FILE__, __LINE__); #endif - ctrl = I2C_Get_Ctrl(eumbbar ); - ctrl.msta = 0; - I2C_Set_Ctrl( eumbbar, ctrl ); + ctrl = I2C_Get_Ctrl (eumbbar); + ctrl.msta = 0; + I2C_Set_Ctrl (eumbbar, ctrl); #ifdef I2CDBG0 - PRINT( "%s(%d): I2C_Stop exit\n", __FILE__, __LINE__ ); + PRINT ("%s(%d): I2C_Stop exit\n", __FILE__, __LINE__); #endif - return I2CSUCCESS; + return I2CSUCCESS; } /**************************************************** @@ -653,40 +630,38 @@ static I2CStatus I2C_Stop( unsigned int eumbbar ) * I2CCR(MSTA) == 1 && I2CCR(MTX) == 1 * ***************************************************/ -static I2CStatus I2C_Master_Xmit( unsigned int eumbbar ) +static I2CStatus I2C_Master_Xmit (unsigned int eumbbar) { unsigned int val; - if ( ByteToXmit > 0 ) - { - if ( ByteToXmit == XmitByte ) - { - /* all xmitted */ - ByteToXmit = 0; + if (ByteToXmit > 0) { - if ( XmitBufEmptyStop == 1 ) - { - I2C_Stop( eumbbar ); - } + if (ByteToXmit == XmitByte) { + /* all xmitted */ + ByteToXmit = 0; - return I2CBUFFEMPTY; + if (XmitBufEmptyStop == 1) { + I2C_Stop (eumbbar); + } - } + return I2CBUFFEMPTY; + } #ifdef I2CDBG0 - PRINT( "%s(%d): xmit 0x%02x\n", __FILE__, __LINE__, *(XmitBuf + XmitByte) ); + PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__, + *(XmitBuf + XmitByte)); #endif - val = *(XmitBuf + XmitByte); - val &= 0x000000ff; - store_runtime_reg( eumbbar, I2CDR, val ); - XmitByte++; + val = *(XmitBuf + XmitByte); + val &= 0x000000ff; + store_runtime_reg (eumbbar, I2CDR, val); + XmitByte++; - return I2CSUCCESS; + return I2CSUCCESS; - } + } - return I2CBUFFEMPTY; + return I2CBUFFEMPTY; } /*********************************************** @@ -702,59 +677,57 @@ static I2CStatus I2C_Master_Xmit( unsigned int eumbbar ) * I2CCR(MSTA) == 1 && I2CCR(MTX) == 0 * ***********************************************/ -static I2CStatus I2C_Master_Rcv( unsigned int eumbbar ) +static I2CStatus I2C_Master_Rcv (unsigned int eumbbar) { I2C_CTRL ctrl; unsigned int val; - if ( ByteToRcv > 0 ) - { - - if ( ByteToRcv - RcvByte == 2 && RcvBufFulStop == 1 ) - { - /* master requests more than or equal to 2 bytes - * we are reading 2nd to last byte - */ - - /* we need to set I2CCR(TXAK) to generate a STOP */ - ctrl = I2C_Get_Ctrl( eumbbar ); - ctrl.txak = 1; - I2C_Set_Ctrl( eumbbar, ctrl ); - - /* Kahlua will automatically generate a STOP - * next time a transaction happens - */ - - /* note: the case of master requesting one byte is - * handled in I2C_ISR - */ - } - - /* generat a STOP before reading the last byte */ - if ( RcvByte + 1 == ByteToRcv && RcvBufFulStop == 1 ) - { - I2C_Stop( eumbbar ); - } - - val = load_runtime_reg( eumbbar, I2CDR ); - *(RcvBuf + RcvByte) = val & 0xFF; + + if (ByteToRcv > 0) { + + if (ByteToRcv - RcvByte == 2 && RcvBufFulStop == 1) { + /* master requests more than or equal to 2 bytes + * we are reading 2nd to last byte + */ + + /* we need to set I2CCR(TXAK) to generate a STOP */ + ctrl = I2C_Get_Ctrl (eumbbar); + ctrl.txak = 1; + I2C_Set_Ctrl (eumbbar, ctrl); + + /* Kahlua will automatically generate a STOP + * next time a transaction happens + */ + + /* note: the case of master requesting one byte is + * handled in I2C_ISR + */ + } + + /* generat a STOP before reading the last byte */ + if (RcvByte + 1 == ByteToRcv && RcvBufFulStop == 1) { + I2C_Stop (eumbbar); + } + + val = load_runtime_reg (eumbbar, I2CDR); + *(RcvBuf + RcvByte) = val & 0xFF; #ifdef I2CDBG0 - PRINT( "%s(%d): rcv 0x%02x\n", __FILE__, __LINE__, *(RcvBuf + RcvByte) ); + PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__, + *(RcvBuf + RcvByte)); #endif - RcvByte++; + RcvByte++; - if ( ByteToRcv == RcvByte ) - { - ByteToRcv = 0; + if (ByteToRcv == RcvByte) { + ByteToRcv = 0; - return I2CBUFFFULL; - } + return I2CBUFFFULL; + } - return I2CSUCCESS; - } + return I2CSUCCESS; + } - return I2CBUFFFULL; + return I2CBUFFFULL; } @@ -772,40 +745,41 @@ static I2CStatus I2C_Master_Rcv( unsigned int eumbbar ) * I2CCR(MSTA) == 0 && I2CCR(MTX) == 1 * ***************************************************/ -static I2CStatus I2C_Slave_Xmit( unsigned int eumbbar ) +static I2CStatus I2C_Slave_Xmit (unsigned int eumbbar) { - unsigned int val; - if ( ByteToXmit > 0 ) - { + unsigned int val; - if ( ByteToXmit == XmitByte ) - { - /* no more data to send */ - ByteToXmit = 0; + if (ByteToXmit > 0) { - /* do not toggle I2CCR(MTX). Doing so will cause bus-hung - * since current Kahlua design does not give master a way - * to detect slave stop. It is always a good idea for - * master to use timer to prevent the long long delays - */ + if (ByteToXmit == XmitByte) { + /* no more data to send */ + ByteToXmit = 0; - return I2CBUFFEMPTY; - } + /* + * do not toggle I2CCR(MTX). Doing so will + * cause bus-hung since current Kahlua design + * does not give master a way to detect slave + * stop. It is always a good idea for master + * to use timer to prevent the long long + * delays + */ + return I2CBUFFEMPTY; + } #ifdef I2CDBG - PRINT( "%s(%d): xmit 0x%02x\n", __FILE__, __LINE__, *(XmitBuf + XmitByte) ); + PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__, + *(XmitBuf + XmitByte)); #endif - val = *(XmitBuf + XmitByte); - val &= 0x000000ff; - store_runtime_reg( eumbbar, I2CDR, val ); - XmitByte++; + val = *(XmitBuf + XmitByte); + val &= 0x000000ff; + store_runtime_reg (eumbbar, I2CDR, val); + XmitByte++; + return I2CSUCCESS; + } - return I2CSUCCESS; - } - - return I2CBUFFEMPTY; + return I2CBUFFEMPTY; } /*********************************************** @@ -821,37 +795,36 @@ static I2CStatus I2C_Slave_Xmit( unsigned int eumbbar ) * I2CCR(MSTA) == 0 && I2CCR(MTX) = 0 * ***********************************************/ -static I2CStatus I2C_Slave_Rcv(unsigned int eumbbar ) +static I2CStatus I2C_Slave_Rcv (unsigned int eumbbar) { unsigned int val; - I2C_CTRL ctrl; - if ( ByteToRcv > 0 ) - { - val = load_runtime_reg( eumbbar, I2CDR ); - *( RcvBuf + RcvByte ) = val & 0xff; + I2C_CTRL ctrl; + + if (ByteToRcv > 0) { + val = load_runtime_reg (eumbbar, I2CDR); + *(RcvBuf + RcvByte) = val & 0xff; #ifdef I2CDBG - PRINT( "%s(%d): rcv 0x%02x\n", __FILE__, __LINE__, *(RcvBuf + RcvByte) ); + PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__, + *(RcvBuf + RcvByte)); #endif - RcvByte++; - - if ( ByteToRcv == RcvByte ) - { - if ( RcvBufFulStop == 1 ) - { - /* all done */ - ctrl = I2C_Get_Ctrl( eumbbar ); - ctrl.txak = 1; - I2C_Set_Ctrl( eumbbar, ctrl ); - } - - ByteToRcv = 0; - return I2CBUFFFULL; - } - - return I2CSUCCESS; - } - - return I2CBUFFFULL; + RcvByte++; + + if (ByteToRcv == RcvByte) { + if (RcvBufFulStop == 1) { + /* all done */ + ctrl = I2C_Get_Ctrl (eumbbar); + ctrl.txak = 1; + I2C_Set_Ctrl (eumbbar, ctrl); + } + + ByteToRcv = 0; + return I2CBUFFFULL; + } + + return I2CSUCCESS; + } + + return I2CBUFFFULL; } /****************** Device Control Function *************/ @@ -865,44 +838,43 @@ static I2CStatus I2C_Slave_Rcv(unsigned int eumbbar ) * * note: ********************************************************/ -static I2CStatus I2C_Init( unsigned int eumbbar, - unsigned char fdr, /* frequency divider */ - unsigned char slave_addr, /* driver's address used for receiving */ - unsigned int en_int) /* 1 - enable I2C interrupt - * 0 - disable I2C interrup - */ -{ - I2C_CTRL ctrl; - unsigned int tmp; +static I2CStatus I2C_Init (unsigned int eumbbar, unsigned char fdr, /* frequency divider */ + unsigned char slave_addr, /* driver's address used for receiving */ + unsigned int en_int) +{ /* 1 - enable I2C interrupt + * 0 - disable I2C interrup + */ + I2C_CTRL ctrl; + unsigned int tmp; #ifdef I2CDBG0 - PRINT( "%s(%d): I2C_Init enter\n", __FILE__, __LINE__ ); + PRINT ("%s(%d): I2C_Init enter\n", __FILE__, __LINE__); #endif - ctrl = I2C_Get_Ctrl( eumbbar ); - /* disable the I2C module before we change everything */ - ctrl.men = 0; - I2C_Set_Ctrl( eumbbar, ctrl ); - - /* set the frequency diver */ - tmp = load_runtime_reg( eumbbar, I2CFDR ); - tmp = ( tmp & 0xffffffc0 ) | ( fdr & 0x3f ); - store_runtime_reg( eumbbar, I2CFDR, tmp ); - - /* Set our listening (slave) address */ - tmp = load_runtime_reg( eumbbar, I2CADR ); - tmp = ( tmp & 0xffffff01 ) | ( ( slave_addr & 0x7f) << 1 ); - store_runtime_reg( eumbbar, I2CADR, tmp ); - - /* enable I2C with desired interrupt setting */ - ctrl.men = 1; - ctrl.mien = en_int & 0x1; - I2C_Set_Ctrl( eumbbar, ctrl ); + ctrl = I2C_Get_Ctrl (eumbbar); + /* disable the I2C module before we change everything */ + ctrl.men = 0; + I2C_Set_Ctrl (eumbbar, ctrl); + + /* set the frequency diver */ + tmp = load_runtime_reg (eumbbar, I2CFDR); + tmp = (tmp & 0xffffffc0) | (fdr & 0x3f); + store_runtime_reg (eumbbar, I2CFDR, tmp); + + /* Set our listening (slave) address */ + tmp = load_runtime_reg (eumbbar, I2CADR); + tmp = (tmp & 0xffffff01) | ((slave_addr & 0x7f) << 1); + store_runtime_reg (eumbbar, I2CADR, tmp); + + /* enable I2C with desired interrupt setting */ + ctrl.men = 1; + ctrl.mien = en_int & 0x1; + I2C_Set_Ctrl (eumbbar, ctrl); #ifdef I2CDBG0 - PRINT( "%s(%d): I2C_Init exit\n", __FILE__, __LINE__ ); + PRINT ("%s(%d): I2C_Init exit\n", __FILE__, __LINE__); #endif - return I2CSUCCESS; + return I2CSUCCESS; } @@ -912,26 +884,26 @@ static I2CStatus I2C_Init( unsigned int eumbbar, * description: Query I2C Status, i.e., read I2CSR * ****************************************/ -static I2C_STAT I2C_Get_Stat( unsigned int eumbbar ) +static I2C_STAT I2C_Get_Stat (unsigned int eumbbar) { - unsigned int temp; - I2C_STAT stat; + unsigned int temp; + I2C_STAT stat; #ifdef I2CDBG0 - PRINT( "%s(%d): get stat = 0x%08x\n", __FILE__, __LINE__, temp ); + PRINT ("%s(%d): get stat = 0x%08x\n", __FILE__, __LINE__, temp); #endif - temp = load_runtime_reg( eumbbar, I2CSR ); - stat.rsrv0 = ( temp & 0xffffff00 ) >> 8; - stat.mcf = ( temp & 0x00000080 ) >> 7; - stat.maas = ( temp & 0x00000040 ) >> 6; - stat.mbb = ( temp & 0x00000020 ) >> 5; - stat.mal = ( temp & 0x00000010 ) >> 4; - stat.rsrv1 = ( temp & 0x00000008 ) >> 3; - stat.srw = ( temp & 0x00000004 ) >> 2; - stat.mif = ( temp & 0x00000002 ) >> 1; - stat.rxak = ( temp & 0x00000001 ); - return stat; + temp = load_runtime_reg (eumbbar, I2CSR); + stat.rsrv0 = (temp & 0xffffff00) >> 8; + stat.mcf = (temp & 0x00000080) >> 7; + stat.maas = (temp & 0x00000040) >> 6; + stat.mbb = (temp & 0x00000020) >> 5; + stat.mal = (temp & 0x00000010) >> 4; + stat.rsrv1 = (temp & 0x00000008) >> 3; + stat.srw = (temp & 0x00000004) >> 2; + stat.mif = (temp & 0x00000002) >> 1; + stat.rxak = (temp & 0x00000001); + return stat; } /********************************************* @@ -941,20 +913,21 @@ static I2C_STAT I2C_Get_Stat( unsigned int eumbbar ) * i.e., write to I2CCR * ********************************************/ -static void I2C_Set_Ctrl( unsigned int eumbbar, I2C_CTRL ctrl ) /* new control value */ -{ - unsigned int temp = load_runtime_reg( eumbbar, I2CCR ); - temp &= 0xffffff03; - temp |= ( ( ctrl.men & 0x1 ) << 7 ); - temp |= ( ( ctrl.mien & 0x1 ) << 6 ); - temp |= ( ( ctrl.msta & 0x1 ) << 5 ); - temp |= ( ( ctrl.mtx & 0x1 ) << 4 ); - temp |= ( ( ctrl.txak & 0x1 ) << 3 ); - temp |= ( ( ctrl.rsta & 0x1 ) << 2 ); +static void I2C_Set_Ctrl (unsigned int eumbbar, I2C_CTRL ctrl) +{ /* new control value */ + unsigned int temp = load_runtime_reg (eumbbar, I2CCR); + + temp &= 0xffffff03; + temp |= ((ctrl.men & 0x1) << 7); + temp |= ((ctrl.mien & 0x1) << 6); + temp |= ((ctrl.msta & 0x1) << 5); + temp |= ((ctrl.mtx & 0x1) << 4); + temp |= ((ctrl.txak & 0x1) << 3); + temp |= ((ctrl.rsta & 0x1) << 2); #ifdef I2CDBG0 - PRINT( "%s(%d): set ctrl = 0x%08x\n", __FILE__, __LINE__, temp ); + PRINT ("%s(%d): set ctrl = 0x%08x\n", __FILE__, __LINE__, temp); #endif - store_runtime_reg( eumbbar, I2CCR, temp ); + store_runtime_reg (eumbbar, I2CCR, temp); } @@ -964,18 +937,19 @@ static void I2C_Set_Ctrl( unsigned int eumbbar, I2C_CTRL ctrl ) /* new control v * description: Query I2C Control bits, * i.e., read I2CCR *****************************************/ -static I2C_CTRL I2C_Get_Ctrl( unsigned int eumbbar ) +static I2C_CTRL I2C_Get_Ctrl (unsigned int eumbbar) { - union { - I2C_CTRL ctrl ; - unsigned int temp; - } s; - s.temp = load_runtime_reg( eumbbar, I2CCR ); + union { + I2C_CTRL ctrl; + unsigned int temp; + } s; + + s.temp = load_runtime_reg (eumbbar, I2CCR); #ifdef I2CDBG0 - PRINT( "%s(%d): get ctrl = 0x%08x\n", __FILE__, __LINE__, s.temp ); + PRINT ("%s(%d): get ctrl = 0x%08x\n", __FILE__, __LINE__, s.temp); #endif - return s.ctrl; + return s.ctrl; } @@ -989,25 +963,24 @@ static I2C_CTRL I2C_Get_Ctrl( unsigned int eumbbar ) * I2CSR(MIF) == 1 && * I2CSR(MAAS) == 1 ****************************************/ -static I2CStatus I2C_Slave_Addr( unsigned int eumbbar ) +static I2CStatus I2C_Slave_Addr (unsigned int eumbbar) { - I2C_STAT stat = I2C_Get_Stat( eumbbar ); - I2C_CTRL ctrl = I2C_Get_Ctrl( eumbbar ); - - if ( stat.srw == 1 ) - { - /* we are asked to xmit */ - ctrl.mtx = 1; - I2C_Set_Ctrl( eumbbar, ctrl ); /* set MTX */ - return I2C_Slave_Xmit( eumbbar ); - } - - /* we are asked to receive data */ - ctrl.mtx = 0; - I2C_Set_Ctrl(eumbbar, ctrl ); - (void)load_runtime_reg( eumbbar, I2CDR ); /* do a fake read to start */ - - return I2CADDRESS; + I2C_STAT stat = I2C_Get_Stat (eumbbar); + I2C_CTRL ctrl = I2C_Get_Ctrl (eumbbar); + + if (stat.srw == 1) { + /* we are asked to xmit */ + ctrl.mtx = 1; + I2C_Set_Ctrl (eumbbar, ctrl); /* set MTX */ + return I2C_Slave_Xmit (eumbbar); + } + + /* we are asked to receive data */ + ctrl.mtx = 0; + I2C_Set_Ctrl (eumbbar, ctrl); + (void) load_runtime_reg (eumbbar, I2CDR); /* do a fake read to start */ + + return I2CADDRESS; } /*********************************************** @@ -1018,114 +991,101 @@ static I2CStatus I2C_Slave_Addr( unsigned int eumbbar ) * note: Precondition: * I2CSR(MIF) == 1 **********************************************/ -static I2CStatus I2C_ISR( unsigned int eumbbar ) +static I2CStatus I2C_ISR (unsigned int eumbbar) { - I2C_STAT stat; - I2C_CTRL ctrl; + I2C_STAT stat; + I2C_CTRL ctrl; #ifdef I2CDBG0 - PRINT( "%s(%d): I2C_ISR\n", __FILE__, __LINE__ ); + PRINT ("%s(%d): I2C_ISR\n", __FILE__, __LINE__); #endif - stat = I2C_Get_Stat( eumbbar ); - ctrl = I2C_Get_Ctrl( eumbbar ); - - /* clear MIF */ - stat.mif = 0; - - /* Now let see what kind of event this is */ - if ( stat.mcf == 1 ) - { - /* transfer compete */ - - /* clear the MIF bit */ - I2C_Set_Stat( eumbbar, stat ); - - if ( ctrl.msta == 1 ) - { - /* master */ - if ( ctrl.mtx == 1 ) - { - /* check if this is the address phase for master receive */ - if ( MasterRcvAddress == 1 ) - { - /* Yes, it is the address phase of master receive */ - ctrl.mtx = 0; - /* now check how much we want to receive */ - if ( ByteToRcv == 1 && RcvBufFulStop == 1 ) - { - ctrl.txak = 1; - } - - I2C_Set_Ctrl( eumbbar, ctrl ); - (void)load_runtime_reg( eumbbar, I2CDR ); /* fake read first */ - - MasterRcvAddress = 0; - return I2CADDRESS; + stat = I2C_Get_Stat (eumbbar); + ctrl = I2C_Get_Ctrl (eumbbar); - } + /* clear MIF */ + stat.mif = 0; + + /* Now let see what kind of event this is */ + if (stat.mcf == 1) { + /* transfer compete */ + + /* clear the MIF bit */ + I2C_Set_Stat (eumbbar, stat); + + if (ctrl.msta == 1) { + /* master */ + if (ctrl.mtx == 1) { + /* check if this is the address phase for master receive */ + if (MasterRcvAddress == 1) { + /* Yes, it is the address phase of master receive */ + ctrl.mtx = 0; + /* now check how much we want to receive */ + if (ByteToRcv == 1 && RcvBufFulStop == 1) { + ctrl.txak = 1; + } + + I2C_Set_Ctrl (eumbbar, ctrl); + (void) load_runtime_reg (eumbbar, I2CDR); /* fake read first */ + + MasterRcvAddress = 0; + return I2CADDRESS; - /* master xmit */ - if ( stat.rxak == 0 ) - { - /* slave has acknowledged */ - return I2C_Master_Xmit( eumbbar ); - } - - /* slave has not acknowledged yet, generate a STOP */ - if ( XmitBufEmptyStop == 1 ) - { - ctrl.msta = 0; - I2C_Set_Ctrl( eumbbar, ctrl ); + } + + /* master xmit */ + if (stat.rxak == 0) { + /* slave has acknowledged */ + return I2C_Master_Xmit (eumbbar); + } + + /* slave has not acknowledged yet, generate a STOP */ + if (XmitBufEmptyStop == 1) { + ctrl.msta = 0; + I2C_Set_Ctrl (eumbbar, ctrl); + } + + return I2CSUCCESS; } - return I2CSUCCESS; - } + /* master receive */ + return I2C_Master_Rcv (eumbbar); + } - /* master receive */ - return I2C_Master_Rcv( eumbbar ); - } + /* slave */ + if (ctrl.mtx == 1) { + /* slave xmit */ + if (stat.rxak == 0) { + /* master has acknowledged */ + return I2C_Slave_Xmit (eumbbar); + } - /* slave */ - if ( ctrl.mtx == 1 ) - { - /* slave xmit */ - if ( stat.rxak == 0 ) - { - /* master has acknowledged */ - return I2C_Slave_Xmit( eumbbar ); - } - - /* master has not acknowledged, wait for STOP */ - /* do nothing for preventing bus from hung */ - return I2CSUCCESS; - } + /* master has not acknowledged, wait for STOP */ + /* do nothing for preventing bus from hung */ + return I2CSUCCESS; + } - /* slave rcv */ - return I2C_Slave_Rcv( eumbbar ); + /* slave rcv */ + return I2C_Slave_Rcv (eumbbar); - } - else if ( stat.maas == 1 ) - { - /* received a call from master */ + } else if (stat.maas == 1) { + /* received a call from master */ - /* clear the MIF bit */ - I2C_Set_Stat(eumbbar, stat ); + /* clear the MIF bit */ + I2C_Set_Stat (eumbbar, stat); - /* master is calling us, process the address phase */ - return I2C_Slave_Addr( eumbbar ); - } - else - { - /* has to be arbitration lost */ - stat.mal = 0; - I2C_Set_Stat( eumbbar, stat ); + /* master is calling us, process the address phase */ + return I2C_Slave_Addr (eumbbar); + } else { + /* has to be arbitration lost */ + stat.mal = 0; + I2C_Set_Stat (eumbbar, stat); - ctrl.msta = 0; /* return to receive mode */ - I2C_Set_Ctrl( eumbbar, ctrl ); - } + ctrl.msta = 0; /* return to receive mode */ + I2C_Set_Ctrl (eumbbar, ctrl); + } - return I2CSUCCESS; + return I2CSUCCESS; } @@ -1135,126 +1095,135 @@ static I2CStatus I2C_ISR( unsigned int eumbbar ) * description: modify the I2CSR * *****************************************************/ -static void I2C_Set_Stat( unsigned int eumbbar, I2C_STAT stat ) +static void I2C_Set_Stat (unsigned int eumbbar, I2C_STAT stat) { - union { - unsigned int val; - I2C_STAT stat; - } s_tmp; - union { - unsigned int val; - I2C_STAT stat; - } s; - s.val = load_runtime_reg( eumbbar, I2CSR ); - s.val &= 0xffffff08; - s_tmp.stat = stat; - s.val |= (s_tmp.val & 0xf7); + union { + unsigned int val; + I2C_STAT stat; + } s_tmp; + union { + unsigned int val; + I2C_STAT stat; + } s; + + s.val = load_runtime_reg (eumbbar, I2CSR); + s.val &= 0xffffff08; + s_tmp.stat = stat; + s.val |= (s_tmp.val & 0xf7); #ifdef I2CDBG0 - PRINT( "%s(%d): set stat = 0x%08x\n", __FILE__, __LINE__, s.val ); + PRINT ("%s(%d): set stat = 0x%08x\n", __FILE__, __LINE__, s.val); #endif - store_runtime_reg( eumbbar, I2CSR, s.val ); + store_runtime_reg (eumbbar, I2CSR, s.val); } -void i2c_init(void) +/****************************************************** + * The following are routines to glue the rest of + * PPCBoot to the Sandpoint I2C driver. + *****************************************************/ + +#warning "This is an untested modification, please test. gvb" + +void i2c_init (int speed, int slaveadd) { - I2C_Initialize(0x7f, 0, (void *) printf); + I2C_Initialize (0x7f, 0, (void *) printf); } -int i2c_receive(unsigned char address, - unsigned char secondary_address, - unsigned short size_to_expect, - unsigned char *datain) +int i2c_probe (uchar chip) { - return I2C_do_transaction(0, I2C_MASTER_RCV, address, - secondary_address, size_to_expect, - datain, I2C_STOP, 1, I2C_NO_RESTART); + return 0; } -int i2c_send(unsigned char address, - unsigned char secondary_address, - unsigned short size_to_send, - unsigned char *dataout) +#if 0 +int i2c_receive (unsigned char address, + unsigned char secondary_address, + unsigned short size_to_expect, unsigned char *datain) { - return I2C_do_transaction(0, I2C_MASTER_XMIT, address, - secondary_address, size_to_send, - dataout, I2C_STOP, 1, I2C_NO_RESTART); + return I2C_do_transaction (0, I2C_MASTER_RCV, address, + secondary_address, size_to_expect, + datain, I2C_STOP, 1, I2C_NO_RESTART); } -int i2c_read(uchar *addr, int alen, uchar *buffer, int len) +int i2c_send (unsigned char address, + unsigned char secondary_address, + unsigned short size_to_send, unsigned char *dataout) { - I2CStatus status; + return I2C_do_transaction (0, I2C_MASTER_XMIT, address, + secondary_address, size_to_send, + dataout, I2C_STOP, 1, I2C_NO_RESTART); +} +#endif - status = I2C_do_buffer(0, I2C_MASTER_XMIT, addr[0], alen - 1, - addr + 1, I2C_NO_STOP, 1, I2C_NO_RESTART); - if (status != I2C_SUCCESS) - { - PRINT( "I2C_do_transaction: can't send data address for read\n"); +int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) +{ + I2CStatus status; + uchar xaddr[4]; + + xaddr[0] = (addr >> 24) & 0xFF; + xaddr[1] = (addr >> 16) & 0xFF; + xaddr[2] = (addr >> 8) & 0xFF; + xaddr[3] = addr & 0xFF; + + status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen, + &xaddr[4 - alen], I2C_NO_STOP, 1, + I2C_NO_RESTART); + if (status != I2C_SUCCESS) { + PRINT ("I2C_do_transaction: can't send data address for read\n"); return 1; } /* The data transfer will be a continuation. */ - status = I2C_do_buffer(0, I2C_MASTER_RCV, addr[0], len, - buffer, I2C_STOP, 1, I2C_RESTART); - if (status != I2C_SUCCESS) - { - PRINT( "I2C_do_transaction: can't perform data transfer\n"); + status = I2C_do_buffer (0, I2C_MASTER_RCV, chip, len, + buffer, I2C_STOP, 1, I2C_RESTART); + if (status != I2C_SUCCESS) { + PRINT ("I2C_do_transaction: can't perform data transfer\n"); return 1; } return 0; } -int i2c_write(uchar *addr, int alen, uchar *buffer, int len) +int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len) { I2CStatus status; unsigned char dummy_buffer[I2C_RXTX_LEN + 2]; - int i,n; + int i, n; + + n = alen - 1; + dummy_buffer[0] = addr & 0xFF; + if (n == 2) + dummy_buffer[1] = (addr >> 8) & 0xFF; + for (i = 0; i < len; i++) + dummy_buffer[i + n] = buffer[i]; - n = alen -1; - dummy_buffer[0] = addr[1]; - if (n == 2) dummy_buffer[1] = addr[2]; - for (i=0;iim_cpm.cp_cpcr & CPM_CR_FLG) && ++count < 1000000); -#ifdef CONFIG_I2C +#ifdef CONFIG_HARD_I2C *((unsigned short*)(&immr->im_dprambase[PROFF_I2C_BASE])) = 0; #endif } diff --git a/cpu/mpc8260/i2c.c b/cpu/mpc8260/i2c.c index db3bc23..d3f8fe6 100644 --- a/cpu/mpc8260/i2c.c +++ b/cpu/mpc8260/i2c.c @@ -26,16 +26,24 @@ #include -#ifdef CONFIG_I2C +#if defined(CONFIG_HARD_I2C) #include #include /* define to enable debug messages */ -#undef DEBUG_I2C +#undef DEBUG_I2C -/* us to wait before checking the i2c */ -#define DELAY_US 100000 +/* uSec to wait between polls of the i2c */ +#define DELAY_US 100 +/* uSec to wait for the CPM to start processing the buffer */ +#define START_DELAY_US 1000 + +/* + * tx/rx per-byte timeout: we delay DELAY_US uSec between polls so the + * timeout will be (tx_length + rx_length) * DELAY_US * TOUT_LOOP + */ +#define TOUT_LOOP 5 /*----------------------------------------------------------------------- * Set default values @@ -50,8 +58,49 @@ /*----------------------------------------------------------------------- */ -/* tx/rx timeout (we need the i2c early, so we don't use get_timer()) */ -#define TOUT_LOOP 100000 +typedef void (*i2c_ecb_t)(int, int); /* error callback function */ + +/* This structure keeps track of the bd and buffer space usage. */ +typedef struct i2c_state { + int rx_idx; /* index to next free Rx BD */ + int tx_idx; /* index to next free Tx BD */ + void *rxbd; /* pointer to next free Rx BD */ + void *txbd; /* pointer to next free Tx BD */ + int tx_space; /* number of Tx bytes left */ + unsigned char *tx_buf; /* pointer to free Tx area */ + i2c_ecb_t err_cb; /* error callback function */ +} i2c_state_t; + +/* flags for i2c_send() and i2c_receive() */ +#define I2CF_ENABLE_SECONDARY 0x01 /* secondary_address is valid */ +#define I2CF_START_COND 0x02 /* tx: generate start condition */ +#define I2CF_STOP_COND 0x04 /* tx: generate stop condition */ + +/* return codes */ +#define I2CERR_NO_BUFFERS 0x01 /* no more BDs or buffer space */ +#define I2CERR_MSG_TOO_LONG 0x02 /* tried to send/receive to much data */ +#define I2CERR_TIMEOUT 0x03 /* timeout in i2c_doio() */ +#define I2CERR_QUEUE_EMPTY 0x04 /* i2c_doio called without send/receive */ + +/* error callback flags */ +#define I2CECB_RX_ERR 0x10 /* this is a receive error */ +#define I2CECB_RX_ERR_OV 0x02 /* receive overrun error */ +#define I2CECB_RX_MASK 0x0f /* mask for error bits */ +#define I2CECB_TX_ERR 0x20 /* this is a transmit error */ +#define I2CECB_TX_CL 0x01 /* transmit collision error */ +#define I2CECB_TX_UN 0x02 /* transmit underflow error */ +#define I2CECB_TX_NAK 0x04 /* transmit no ack error */ +#define I2CECB_TX_MASK 0x0f /* mask for error bits */ +#define I2CECB_TIMEOUT 0x40 /* this is a timeout error */ + +#define ERROR_I2C_NONE 0 +#define ERROR_I2C_LENGTH 1 + +#define I2C_WRITE_BIT 0x00 +#define I2C_READ_BIT 0x01 + +#define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */ + #define NUM_RX_BDS 4 #define NUM_TX_BDS 4 @@ -160,12 +209,12 @@ static int i2c_setrate(int hz, int speed) return 1 ; } -void i2c_init(int speed, int slaveaddr) +void i2c_init(int speed, int slaveadd) { init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET); volatile immap_t *immap = (immap_t *)CFG_IMMR ; volatile cpm8260_t *cp = (cpm8260_t *)&immap->im_cpm; - volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c; + volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c; volatile iic_t *iip; ulong rbase, tbase; volatile I2C_BD *rxbd, *txbd; @@ -199,7 +248,7 @@ void i2c_init(int speed, int slaveaddr) i2c->i2c_i2mod = 0x00; i2c->i2c_i2cmr = 0x00; i2c->i2c_i2cer = 0xff; - i2c->i2c_i2add = slaveaddr; + i2c->i2c_i2add = slaveadd; /* * Set the I2C BRG Clock division factor from desired i2c rate @@ -207,7 +256,7 @@ void i2c_init(int speed, int slaveaddr) * divide BRGCLK by 1) */ PRINTD(("[I2C] Setting rate...\n")); - i2c_setrate (idata->brg_clk, speed) ; + i2c_setrate (idata->brg_clk, CFG_I2C_SPEED) ; /* Set I2C controller in master mode */ i2c->i2c_i2com = 0x01; @@ -243,6 +292,7 @@ void i2c_init(int speed, int slaveaddr) i2c->i2c_i2cmr = 0x00; } +static void i2c_newio(i2c_state_t *state) { volatile immap_t *immap = (immap_t *)CFG_IMMR ; @@ -269,6 +319,7 @@ void i2c_newio(i2c_state_t *state) memset((char *)state->tx_buf, 0, MAX_TX_SPACE); } +static int i2c_send(i2c_state_t *state, unsigned char address, unsigned char secondary_address, @@ -345,6 +396,7 @@ int i2c_send(i2c_state_t *state, return 0; } +static int i2c_receive(i2c_state_t *state, unsigned char address, unsigned char secondary_address, @@ -424,13 +476,15 @@ int i2c_receive(i2c_state_t *state, } +static int i2c_doio(i2c_state_t *state) { volatile immap_t *immap = (immap_t *)CFG_IMMR ; volatile iic_t *iip; volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c; volatile I2C_BD *txbd, *rxbd; - volatile int j = 0; + int j; + int timeout; uint dpaddr; PRINTD(("[I2C] i2c_doio\n")); @@ -452,26 +506,31 @@ int i2c_doio(i2c_state_t *state) /* Begin transmission */ i2c->i2c_i2com |= 0x80; - /* This is a patch! */ - udelay (DELAY_US) - ; - /* Loop until transmit & receive completed */ if (state->tx_idx > 0) { txbd = ((I2C_BD*)state->txbd) - 1; + j = 0; + timeout = TOUT_LOOP * txbd->length; + PRINTD(("[I2C] Transmitting...(txbd=0x%08lx)\n", (ulong)txbd)); - while((txbd->status & BD_SC_READY) && (j++ < TOUT_LOOP)) { + udelay(START_DELAY_US); /* give it time to start */ + while((txbd->status & BD_SC_READY) && (j++ < timeout)) { + udelay(DELAY_US); if (ctrlc()) return (-1); __asm__ __volatile__ ("eieio"); } } - if ((state->rx_idx > 0) && (j < TOUT_LOOP)) { + if ((state->rx_idx > 0) && (j < timeout)) { rxbd = ((I2C_BD*)state->rxbd) - 1; + j = 0; + timeout = TOUT_LOOP * rxbd->length; PRINTD(("[I2C] Receiving...(rxbd=0x%08lx)\n", (ulong)rxbd)); - while((rxbd->status & BD_SC_EMPTY) && (j++ < TOUT_LOOP)) { + udelay(START_DELAY_US); /* give it time to start */ + while((rxbd->status & BD_SC_EMPTY) && (j++ < timeout)) { + udelay(DELAY_US); if (ctrlc()) return (-1); __asm__ __volatile__ ("eieio"); @@ -505,28 +564,91 @@ int i2c_doio(i2c_state_t *state) } } - if (j >= TOUT_LOOP) + if (j >= timeout) (*state->err_cb)(I2CECB_TIMEOUT, 0); } - return (j >= TOUT_LOOP) ? I2CERR_TIMEOUT : 0; + /* sort out errors and return appropriate good/error status */ + if(j >= timeout) + return(I2CERR_TIMEOUT); + if((txbd->status & BD_I2C_TX_ERR) != 0) + return(I2CECB_TX_ERR | (txbd->status & I2CECB_TX_MASK)); + if((rxbd->status & BD_I2C_RX_ERR) != 0) + return(I2CECB_RX_ERR | (rxbd->status & I2CECB_RX_MASK)); + + return(0); +} + +static int had_tx_nak; + +static void +i2c_test_callback(int flags, int xnum) +{ + if ((flags & I2CECB_TX_ERR) && (flags & I2CECB_TX_NAK)) + had_tx_nak = 1; +} + +int i2c_probe(uchar chip) +{ + i2c_state_t state; + int rc; + uchar buf[1]; + + i2c_newio(&state); + + state.err_cb = i2c_test_callback; + had_tx_nak = 0; + + rc = i2c_receive(&state, chip, 0, I2CF_START_COND|I2CF_STOP_COND, 1, buf); + + if (rc != 0) + return (rc); + + rc = i2c_doio(&state); + + if ((rc != 0) && (rc != I2CERR_TIMEOUT)) + return (rc); + + return (had_tx_nak); } + int -i2c_read(uchar *addr, int alen, uchar *buffer, int len) +i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) { i2c_state_t state; + uchar xaddr[4]; int rc; + xaddr[0] = (addr >> 24) & 0xFF; + xaddr[1] = (addr >> 16) & 0xFF; + xaddr[2] = (addr >> 8) & 0xFF; + xaddr[3] = addr & 0xFF; + +#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW + /* + * EEPROM chips that implement "address overflow" are ones + * like Catalyst 24WC04/08/16 which has 9/10/11 bits of address + * and the extra bits end up in the "chip address" bit slots. + * This makes a 24WC08 (1Kbyte) chip look like four 256 byte + * chips. + * + * Note that we consider the length of the address field to still + * be one byte because the extra address bits are hidden in the + * chip address. + */ + chip |= ((addr >> alen) & CFG_I2C_EEPROM_ADDR_OVERFLOW); +#endif + i2c_newio(&state); - rc = i2c_send(&state, *addr, 0, I2CF_START_COND, alen - 1, addr + 1); + rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]); if (rc != 0) { printf("i2c_read: i2c_send failed (%d)\n", rc); return 1; } - rc = i2c_receive(&state, *addr, 0, I2CF_STOP_COND, len, buffer); + rc = i2c_receive(&state, chip, 0, I2CF_STOP_COND, len, buffer); if (rc != 0) { printf("i2c_read: i2c_receive failed (%d)\n", rc); return 1; @@ -541,14 +663,35 @@ i2c_read(uchar *addr, int alen, uchar *buffer, int len) } int -i2c_write(uchar *addr, int alen, uchar *buffer, int len) +i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) { i2c_state_t state; + uchar xaddr[4]; int rc; + xaddr[0] = (addr >> 24) & 0xFF; + xaddr[1] = (addr >> 16) & 0xFF; + xaddr[2] = (addr >> 8) & 0xFF; + xaddr[3] = addr & 0xFF; + +#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW + /* + * EEPROM chips that implement "address overflow" are ones + * like Catalyst 24WC04/08/16 which has 9/10/11 bits of address + * and the extra bits end up in the "chip address" bit slots. + * This makes a 24WC08 (1Kbyte) chip look like four 256 byte + * chips. + * + * Note that we consider the length of the address field to still + * be one byte because the extra address bits are hidden in the + * chip address. + */ + chip |= ((addr >> alen) & CFG_I2C_EEPROM_ADDR_OVERFLOW); +#endif + i2c_newio(&state); - rc = i2c_send(&state, *addr, 0, I2CF_START_COND, alen - 1, addr + 1); + rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]); if (rc != 0) { printf("i2c_write: first i2c_send failed (%d)\n", rc); return 1; @@ -569,32 +712,19 @@ i2c_write(uchar *addr, int alen, uchar *buffer, int len) } uchar -i2c_reg_read(uchar i2c_addr, uchar reg) +i2c_reg_read(uchar chip, uchar reg) { - char addr[2]; - char buf[1]; - - i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); + char buf; - addr[0] = i2c_addr; - addr[1] = reg; + i2c_read(chip, reg, 1, &buf, 1); - i2c_read(addr, 2, buf, 1); - - return (buf[0]); + return (buf); } void -i2c_reg_write(uchar i2c_addr, uchar reg, uchar val) +i2c_reg_write(uchar chip, uchar reg, uchar val) { - char addr[2]; - - i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); - - addr[0] = i2c_addr; - addr[1] = reg; - - i2c_write(addr, 2, &val, 1); + i2c_write(chip, reg, 1, &val, 1); } -#endif /* CONFIG_I2C */ +#endif /* CONFIG_HARD_I2C */ diff --git a/cpu/mpc8xx/Makefile b/cpu/mpc8xx/Makefile index 3e33bab..be62ca8 100644 --- a/cpu/mpc8xx/Makefile +++ b/cpu/mpc8xx/Makefile @@ -30,7 +30,7 @@ LIB = lib$(CPU).a START = start.o kgdb.o OBJS = bedbug_860.o commproc.o cpu.o cpu_init.o \ fec.o i2c.o interrupts.o lcd.o scc.o \ - serial.o soft_i2c.o speed.o spi.o status_led.o\ + serial.o speed.o spi.o status_led.o\ traps.o upatch.o video.o wlkbd.o all: .depend $(START) $(LIB) diff --git a/cpu/mpc8xx/i2c.c b/cpu/mpc8xx/i2c.c index b4b82cb..bd4009b 100644 --- a/cpu/mpc8xx/i2c.c +++ b/cpu/mpc8xx/i2c.c @@ -29,7 +29,7 @@ #include -#ifdef CONFIG_I2C +#ifdef CONFIG_HARD_I2C #include #include @@ -59,6 +59,7 @@ #define NUM_RX_BDS 4 #define NUM_TX_BDS 4 #define MAX_TX_SPACE 256 +#define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */ typedef struct I2C_BD { @@ -75,6 +76,42 @@ typedef struct I2C_BD #define BD_I2C_RX_ERR BD_SC_OV +typedef void (*i2c_ecb_t)(int, int); /* error callback function */ + +/* This structure keeps track of the bd and buffer space usage. */ +typedef struct i2c_state { + int rx_idx; /* index to next free Rx BD */ + int tx_idx; /* index to next free Tx BD */ + void *rxbd; /* pointer to next free Rx BD */ + void *txbd; /* pointer to next free Tx BD */ + int tx_space; /* number of Tx bytes left */ + unsigned char *tx_buf; /* pointer to free Tx area */ + i2c_ecb_t err_cb; /* error callback function */ +} i2c_state_t; + + +/* flags for i2c_send() and i2c_receive() */ +#define I2CF_ENABLE_SECONDARY 0x01 /* secondary_address is valid */ +#define I2CF_START_COND 0x02 /* tx: generate start condition */ +#define I2CF_STOP_COND 0x04 /* tx: generate stop condition */ + +/* return codes */ +#define I2CERR_NO_BUFFERS 0x01 /* no more BDs or buffer space */ +#define I2CERR_MSG_TOO_LONG 0x02 /* tried to send/receive to much data */ +#define I2CERR_TIMEOUT 0x03 /* timeout in i2c_doio() */ +#define I2CERR_QUEUE_EMPTY 0x04 /* i2c_doio called without send/receive */ + +/* error callback flags */ +#define I2CECB_RX_ERR 0x10 /* this is a receive error */ +#define I2CECB_RX_ERR_OV 0x02 /* receive overrun error */ +#define I2CECB_RX_MASK 0x0f /* mask for error bits */ +#define I2CECB_TX_ERR 0x20 /* this is a transmit error */ +#define I2CECB_TX_CL 0x01 /* transmit collision error */ +#define I2CECB_TX_UN 0x02 /* transmit underflow error */ +#define I2CECB_TX_NAK 0x04 /* transmit no ack error */ +#define I2CECB_TX_MASK 0x0f /* mask for error bits */ +#define I2CECB_TIMEOUT 0x40 /* this is a timeout error */ + #ifdef DEBUG_I2C #define PRINTD(x) printf x #else @@ -224,7 +261,7 @@ i2c_init(int speed, int slaveaddr) * divide BRGCLK by 1) */ PRINTD(("[I2C] Setting rate...\n")); - i2c_setrate (idata->cpu_clk, speed) ; + i2c_setrate (idata->cpu_clk, CFG_I2C_SPEED) ; /* Set I2C controller in master mode */ i2c->i2c_i2com = 0x01; @@ -270,7 +307,7 @@ i2c_init(int speed, int slaveaddr) i2c->i2c_i2cmr = 0x00; } -void +static void i2c_newio(i2c_state_t *state) { volatile immap_t *immap = (immap_t *)CFG_IMMR ; @@ -298,7 +335,7 @@ i2c_newio(i2c_state_t *state) memset((char *)state->tx_buf, 0, MAX_TX_SPACE); } -int +static int i2c_send(i2c_state_t *state, unsigned char address, unsigned char secondary_address, @@ -369,12 +406,13 @@ i2c_send(i2c_state_t *state, return 0; } -int i2c_receive(i2c_state_t *state, - unsigned char address, - unsigned char secondary_address, - unsigned int flags, - unsigned short size_to_expect, - unsigned char *datain) +static int +i2c_receive(i2c_state_t *state, + unsigned char address, + unsigned char secondary_address, + unsigned int flags, + unsigned short size_to_expect, + unsigned char *datain) { volatile I2C_BD *rxbd, *txbd; @@ -444,7 +482,7 @@ int i2c_receive(i2c_state_t *state, } -int i2c_doio(i2c_state_t *state) +static int i2c_doio(i2c_state_t *state) { volatile immap_t *immap = (immap_t *)CFG_IMMR ; volatile cpm8xx_t *cp = (cpm8xx_t *)&immap->im_cpm; @@ -536,24 +574,78 @@ int i2c_doio(i2c_state_t *state) return (j >= TOUT_LOOP) ? I2CERR_TIMEOUT : 0; } -int -i2c_read(uchar *addr, int alen, uchar *buffer, int len) +static int had_tx_nak; + +static void +i2c_test_callback(int flags, int xnum) +{ + if ((flags & I2CECB_TX_ERR) && (flags & I2CECB_TX_NAK)) + had_tx_nak = 1; +} + +int i2c_probe(uchar chip) +{ + i2c_state_t state; + int rc; + uchar buf[1]; + + i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); + + i2c_newio(&state); + + state.err_cb = i2c_test_callback; + had_tx_nak = 0; + + rc = i2c_receive(&state, chip, 0, I2CF_START_COND|I2CF_STOP_COND, 1, buf); + + if (rc != 0) + return (rc); + + rc = i2c_doio(&state); + + if ((rc != 0) && (rc != I2CERR_TIMEOUT)) + return (rc); + + return (had_tx_nak); +} + +int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) { init_data_t *idata = (init_data_t *) (CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET); i2c_state_t state; + uchar xaddr[4]; int rc; + xaddr[0] = (addr >> 24) & 0xFF; + xaddr[1] = (addr >> 16) & 0xFF; + xaddr[2] = (addr >> 8) & 0xFF; + xaddr[3] = addr & 0xFF; + +#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW + /* + * EEPROM chips that implement "address overflow" are ones like + * Catalyst 24WC04/08/16 which has 9/10/11 bits of address and the + * extra bits end up in the "chip address" bit slots. This makes + * a 24WC08 (1Kbyte) chip look like four 256 byte chips. + * + * Note that we consider the length of the address field to still + * be one byte because the extra address bits are hidden in the + * chip address. + */ + chip |= ((addr >> alen) & CFG_I2C_EEPROM_ADDR_OVERFLOW); +#endif + i2c_newio(&state); - rc = i2c_send(&state, *addr, 0, I2CF_START_COND, alen - 1, addr + 1); + rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]); if (rc != 0) { if (idata->have_console) printf("i2c_read: i2c_send failed (%d)\n", rc); return 1; } - rc = i2c_receive(&state, *addr, 0, I2CF_STOP_COND, len, buffer); + rc = i2c_receive(&state, chip, 0, I2CF_STOP_COND, len, buffer); if (rc != 0) { if (idata->have_console) printf("i2c_read: i2c_receive failed (%d)\n", rc); @@ -569,17 +661,36 @@ i2c_read(uchar *addr, int alen, uchar *buffer, int len) return 0; } -int -i2c_write(uchar *addr, int alen, uchar *buffer, int len) +int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) { init_data_t *idata = (init_data_t *) (CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET); i2c_state_t state; + uchar xaddr[4]; int rc; + xaddr[0] = (addr >> 24) & 0xFF; + xaddr[1] = (addr >> 16) & 0xFF; + xaddr[2] = (addr >> 8) & 0xFF; + xaddr[3] = addr & 0xFF; + +#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW + /* + * EEPROM chips that implement "address overflow" are ones like + * Catalyst 24WC04/08/16 which has 9/10/11 bits of address and the + * extra bits end up in the "chip address" bit slots. This makes + * a 24WC08 (1Kbyte) chip look like four 256 byte chips. + * + * Note that we consider the length of the address field to still + * be one byte because the extra address bits are hidden in the + * chip address. + */ + chip |= ((addr >> alen) & CFG_I2C_EEPROM_ADDR_OVERFLOW); +#endif + i2c_newio(&state); - rc = i2c_send(&state, *addr, 0, I2CF_START_COND, alen - 1, addr + 1); + rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]); if (rc != 0) { if (idata->have_console) printf("i2c_write: first i2c_send failed (%d)\n", rc); @@ -605,30 +716,21 @@ i2c_write(uchar *addr, int alen, uchar *buffer, int len) uchar i2c_reg_read(uchar i2c_addr, uchar reg) { - char addr[2]; - char buf[1]; + char buf; i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); - addr[0] = i2c_addr; - addr[1] = reg; - - i2c_read(addr, 2, buf, 1); + i2c_read(i2c_addr, reg, 1, &buf, 1); - return (buf[0]); + return (buf); } void i2c_reg_write(uchar i2c_addr, uchar reg, uchar val) { - char addr[2]; - i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); - addr[0] = i2c_addr; - addr[1] = reg; - - i2c_write(addr, 2, &val, 1); + i2c_write(i2c_addr, reg, 1, &val, 1); } -#endif /* CONFIG_I2C */ +#endif /* CONFIG_HARD_I2C */ diff --git a/cpu/mpc8xx/video.c b/cpu/mpc8xx/video.c index ddd07df..76fc23a 100644 --- a/cpu/mpc8xx/video.c +++ b/cpu/mpc8xx/video.c @@ -717,12 +717,11 @@ static int video_mode_generate (void) static void video_encoder_init (void) { #ifdef VIDEO_I2C - i2c_state_t state; int rc; /* Initialize the I2C */ PRINTD("\n[VIDEO ENCODER] Initializing I2C bus..."); - i2c_init(VIDEO_I2C_RATE, 0xfe); /* slave address not important */ + i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); #ifdef CONFIG_FADS /* Reset ADV7176 chip */ @@ -746,30 +745,9 @@ static void video_encoder_init (void) printf("Sending %d bytes (%08x) to I2C 0x%x\n", VIDEO_I2C_DATA_SIZE, VIDEO_I2C_DATA_ADDR, VIDEO_I2C_ADDR); #endif - i2c_newio(&state); - rc = i2c_send(&state, VIDEO_I2C_ADDR, 0, - I2CF_ENABLE_SECONDARY|I2CF_START_COND|I2CF_STOP_COND, - VIDEO_I2C_DATA_SIZE, VIDEO_I2C_DATA_ADDR); - if (rc != 0) { - /* - * do somthing intelligent here: < 0 means user typed Ctrl-C, - * > 0 means an i2c error (see I2CERR_* in include/i2c.h). - * (that something might very well be to ignore it altogether) - */ - if (rc < 0) { - printf (" \n"); - } else { - printf ("i2c_send error: rc=%d\n", rc); - } - return; - } - rc = i2c_doio(&state); - if (rc != 0) { - if (rc < 0) { - printf (" \n"); - } else { - printf ("i2c_doio error: rc=%d\n", rc); - } + if ((rc = i2c_write(VIDEO_I2C_ADDR, 0, 1, + VIDEO_I2C_DATA_ADDR, VIDEO_I2C_DATA_SIZE)) != 0) { + printf ("i2c_send error: rc=%d\n", rc); return; } #endif diff --git a/cpu/ppc4xx/405_dimm.c b/cpu/ppc4xx/405_dimm.c deleted file mode 100644 index 5d5245f..0000000 --- a/cpu/ppc4xx/405_dimm.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * (C) Copyright 2001 - * Kenneth Johansson ,Ericsson Business Innovation. - * kenneth.johansson@inn.ericsson.se - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include <405gp_i2c.h> - -#ifdef CONFIG_DIMM_EEPROM - -#define SDRAM0_CFG_DCE_MASK 0x80000000 -#define SDRAM0_CFG_SRE_MASK 0x40000000 -#define SDRAM0_CFG_PME_MASK 0x20000000 -#define SDRAM0_CFG_MEMCHK_MASK 0x10000000 -#define SDRAM0_CFG_REGEN_MASK 0x08000000 -#define SDRAM0_CFG_DRW_MASK 0x06000000 -#define SDRAM0_CFG_BRPF_MASK 0x01800000 -#define SDRAM0_CFG_ECCDD_MASK 0x00400000 -#define SDRAM0_CFG_EMDULR_MASK 0x00200000 - -#define SDRAM0_CFG_DCE_SHIFT (31-0) -#define SDRAM0_CFG_SRE_SHIFT (31-1) -#define SDRAM0_CFG_PME_SHIFT (31-2) -#define SDRAM0_CFG_MEMCHK_SHIFT (31-3) -#define SDRAM0_CFG_REGEN_SHIFT (31-4) -#define SDRAM0_CFG_DRW_SHIFT (31-6) -#define SDRAM0_CFG_BRPF_SHIFT (31-8) -#define SDRAM0_CFG_ECCDD_SHIFT (31-9) -#define SDRAM0_CFG_EMDULR_SHIFT (31-10) - -#define SDRAM0_TR_CASL_SHIFT (31-8) -#define SDRAM0_TR_PTA_SHIFT (31-13) -#define SDRAM0_TR_CTP_SHIFT (31-15) -#define SDRAM0_TR_LDF_SHIFT (31-17) -#define SDRAM0_TR_RFTA_SHIFT (31-29) -#define SDRAM0_TR_RCD_SHIFT (31-31) - -#define SDRAM0_RTR_SHIFT (31-12) - -/* SDRAM0_CFG enable macro */ -#define SDRAM0_CFG_DCE(x) ( (( x << SDRAM0_CFG_DCE_SHIFT) & SDRAM0_CFG_DCE_MASK) ) -#define SDRAM0_CFG_BRPF(x) ( (( x << SDRAM0_CFG_BRPF_SHIFT) & SDRAM0_CFG_BRPF_MASK) ) - - -#define SDRAM0_BXCR_SZ_MASK 0x000e0000 -#define SDRAM0_BXCR_AM_MASK 0x0000e000 - -#define SDRAM0_BXCR_SZ_SHIFT (31-14) -#define SDRAM0_BXCR_AM_SHIFT (31-18) - -#define SDRAM0_BXCR_SZ(x) ( (( x << SDRAM0_BXCR_SZ_SHIFT) & SDRAM0_BXCR_SZ_MASK) ) -#define SDRAM0_BXCR_AM(x) ( (( x << SDRAM0_BXCR_AM_SHIFT) & SDRAM0_BXCR_AM_MASK) ) - - -/* - * what we really want is - * (1/hertz) but we don't want to use floats so multiply with 10E9 - * - * The error needs to be on the safe side so we want the floor function. - * This means we get an exact value or we calculate that our bus frequency is - * a bit faster than it really is and thus we don't progam the sdram controller - * to run to fast - */ -#define sdram_HZ_to_ns(hertz) (1000000000/(hertz)) - - -/* - * This function is reading data from the DIMM module EEPROM over the SPD bus - * and uses that to program the sdram controller. - * - * This works on boards that has the same schematics that the IBM walnut has. - * - * BUG: Don't handle ECC memory - * BUG: A few values in the TR register is currently hardcoded - */ - -long int walnut_dimm(void) -{ - unsigned char dataout[1]; - unsigned char datain[128]; - int i,bus_period,tmp; - int TotalSize; - - int bank_size, mode = 0; - - int sdram0_pmit=0x07c00000; - int sdram0_besr0=-1; - int sdram0_besr1=-1; - int sdram0_eccesr=-1; - int sdram0_ecccfg=0; - - int sdram0_rtr=0; - int sdram0_tr=0; - - int sdram0_b0cr; - int sdram0_b1cr; - int sdram0_b2cr; - int sdram0_b3cr; - - int sdram0_cfg=0; - - PPC405_SYS_INFO sys_info; - - - get_sys_info(&sys_info); - bus_period = sdram_HZ_to_ns(sys_info.freqPLB ); - - /* Read Serial Presence Detect Information */ - dataout[0] = 0; - for (i=0; i<128;i++) - datain[i] = 127; - i2c_send(EEPROM_WRITE_ADDRESS,1,dataout); - i2c_receive(EEPROM_READ_ADDRESS,128,datain); - printf("\nReading DIMM...\n"); - -#if 0 - for (i=0;i<128;i++) - printf("%d=0x%x \n", i, datain[i]); - printf("\n"); -#endif - - /* Make shure we are using SDRAM */ - if(datain[2] != 0x4){ - printf("Detected memory type %d\n",datain[2]); - printf("Memory error: We only suport SDRAM\n"); - hang(); - } - - -/*------------------------------------------------------------------ - configure memory timing register - - data from DIMM: - 27 IN Row Precharge Time ( t RP) - 29 MIN RAS to CAS Delay ( t RCD) - 127 Component and Clock Detail ,clk0-clk3, junction temp, CAS - -------------------------------------------------------------------*/ - - /* - * set CASL - * datain[127] bit1 = cas2 bit2=cas3 - */ - - if(datain[127] & 0x02) - sdram0_tr = 1 << SDRAM0_TR_CASL_SHIFT; - else if (datain[127] & 0x04) - sdram0_tr = 2 << SDRAM0_TR_CASL_SHIFT; - else { - printf("Found unsupported CAS value\n"); - hang(); - } - - /* - * set PTA - * datain[27] time in ns - */ - tmp = datain[27]/bus_period; - if( tmp*bus_period < datain[27]) - tmp+=1; - tmp--; /* the value is coded in the reg */ - sdram0_tr |= tmp << SDRAM0_TR_PTA_SHIFT ; - - /* - * set CTP - * 2 => 3clk - */ - sdram0_tr |= 2 << SDRAM0_TR_CTP_SHIFT ; - - /* - * set LDF - * 1 => 2 clk - */ - sdram0_tr |= 1 << SDRAM0_TR_LDF_SHIFT ; - - /* - * set RFTA - * 3 => 7clk - */ - sdram0_tr |= 3 << SDRAM0_TR_RFTA_SHIFT ; - - /* - set RCD - datain[29] Ras to cas delay - */ - tmp = datain[29]/bus_period; - - if( tmp*bus_period < datain[29]) - tmp+=1; - tmp--; /* the value is coded in the reg */ - sdram0_tr |= tmp << SDRAM0_TR_RCD_SHIFT ; - -/* sdram0_tr=0x0106400d; */ - -/*------------------------------------------------------------------ - configure RTR register - -------------------------------------------------------------------*/ - - tmp = datain[12] & 0x7f ; /* Mask away self refresh bit */ - - switch(tmp){ - case 0x00: - tmp=15625; - break; - case 0x01: - tmp=15625/4; - break; - case 0x02: - tmp=15625/2; - break; - case 0x03: - tmp=15625*2; - break; - case 0x04: - tmp=15625*4; - break; - case 0x05: - tmp=15625*8; - break; - default: - printf("DRAM Refresh rate outside spec\n"); - hang(); - } - tmp = tmp/bus_period; - sdram0_rtr = tmp << SDRAM0_RTR_SHIFT; - -/*------------------------------------------------------------------ - configure memory bank register - -------------------------------------------------------------------*/ - - /* byte 31 (sdram) module bank density */ - switch( datain[31] ){ - case 0x1: - TotalSize = 4; - bank_size = 0; - break; - case 0x2: - TotalSize = 8; - bank_size = 0; - break; - case 0x4: - TotalSize = 16; - bank_size = 1; - break; - case 0x8: - TotalSize = 32; - bank_size = 2; - break; - case 0x10: - TotalSize = 64; - bank_size = 3; - break; - case 0x20: - TotalSize = 128; - bank_size = 4; - break; - case 0x40: - TotalSize = 256; - bank_size = 5; - break; - case 0x80: - TotalSize = 512; - bank_size = 6; - break; - default: - printf("Invalid module size\n"); - TotalSize = 128; - bank_size = 2; - } - - /* Need this in bytes */ - TotalSize*= 1024*1024; - - /* map rows * cols * banks to a mode - * datain[ 3] number of row - * datain[ 4] number of column - * datain[ 17] number of internal banks - */ - switch( datain[3] ) - { - case 11: - switch ( datain[4] ) - { - case 8: - mode=4; /* mode 5 */ - break; - case 9: - case 10: - mode=0; /* mode 1 */ - break; - default: - printf("DRAM column number not supported"); - } - break; - case 12: - switch ( datain[4] ) - { - case 8: - mode=3; /* mode 4 */ - break; - case 9: - case 10: - mode=1; /* mode 2 */ - break; - default: - printf("DRAM column number not supported"); - } - break; - case 13: - switch ( datain[4] ) - { - case 8: - mode=5; /* mode 6 */ - break; - case 9: - case 10: - if (datain[17] ==2 ) - mode=6; /* mode 7 */ - else - mode=2; /* mode 3 */ - break; - case 11: - mode=2; /* mode 3 */ - break; - default: - printf("DRAM column number not supported"); - } - break; - default: - printf("DRAM row number not supported\n"); - } - - /* double-sided DIMM ? */ - if (datain[5] == 2){ - printf("double-sided DIMM\n"); - TotalSize *= 2; - - sdram0_b0cr = (TotalSize>>2) * 0 | SDRAM0_BXCR_SZ(bank_size) | SDRAM0_BXCR_AM(mode) | 1; - sdram0_b1cr = (TotalSize>>2) * 1 | SDRAM0_BXCR_SZ(bank_size) | SDRAM0_BXCR_AM(mode) | 1; - sdram0_b2cr = (TotalSize>>2) * 2 | SDRAM0_BXCR_SZ(bank_size) | SDRAM0_BXCR_AM(mode) | 1; - sdram0_b3cr = (TotalSize>>2) * 3 | SDRAM0_BXCR_SZ(bank_size) | SDRAM0_BXCR_AM(mode) | 1; - } - else{ /* else single-sided DIMM => SDRAM bank 0 and bank 2 are valid */ - printf("single-sided DIMM\n"); - sdram0_b0cr = (TotalSize>>1) * 0 | SDRAM0_BXCR_SZ(bank_size) | SDRAM0_BXCR_AM(mode) | 1; - sdram0_b2cr = (TotalSize>>1) * 1 | SDRAM0_BXCR_SZ(bank_size) | SDRAM0_BXCR_AM(mode) | 1; - - sdram0_b1cr = 0; - sdram0_b3cr = 0; - } - - /* - * enable sdram controller DCE=1 - * enable burst read prefetch to 16 bytes BRPF=1 - * leave other functions off - */ - sdram0_cfg = SDRAM0_CFG_DCE(1) | SDRAM0_CFG_BRPF(1); - - - -#ifdef VERBOSE_SDRAM_REPORT - printf("sdram0_pmit %x\n",sdram0_pmit); - - printf("sdram0_besr0 %x\n",sdram0_besr0); - printf("sdram0_besr1 %x\n",sdram0_besr1); - printf("sdram0_ecccfg %x\n",sdram0_ecccfg); - printf("sdram0_eccesr %x\n",sdram0_eccesr); - - printf("sdram0_rtr %x\n",sdram0_rtr); - printf("sdram0_tr %x\n",sdram0_tr); - - printf("sdram0_b0cr %x\n",sdram0_b0cr); - printf("sdram0_b1cr %x\n",sdram0_b1cr); - printf("sdram0_b2cr %x\n",sdram0_b2cr); - printf("sdram0_b3cr %x\n",sdram0_b3cr); - - printf("sdram0_cfg %x\n",sdram0_cfg); -#endif - - -#define mtsdram0(reg, data) mtdcr(memcfga,reg);mtdcr(memcfgd,data) - - mtsdram0( mem_besra , sdram0_besr0 ); - mtsdram0( mem_besrb , sdram0_besr1 ); - mtsdram0( mem_rtr , sdram0_rtr ); - mtsdram0( mem_pmit , sdram0_pmit ); - mtsdram0( mem_mb0cf , sdram0_b0cr ); - mtsdram0( mem_mb1cf , sdram0_b1cr ); - mtsdram0( mem_mb2cf , sdram0_b2cr ); - mtsdram0( mem_mb3cf , sdram0_b3cr ); - mtsdram0( mem_sdtr1 , sdram0_tr ); - mtsdram0( mem_ecccf , sdram0_ecccfg ); - mtsdram0( mem_eccerr, sdram0_eccesr ); - - /* SDRAM have a power on delay, 500 micro should do */ - udelay(500); - mtsdram0( mem_mcopt1, sdram0_cfg ); - - - /* kernel 2.4.2 from mvista has a bug with memory over 128MB */ -#ifdef MVISTA_MEM_BUG - if (TotalSize > 128*1024*1024 ) - TotalSize=128*1024*1024; -#endif - return (TotalSize); -} - -#endif /* CONFIG_DIMM_EEPROM */ diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c index 38f2018..eac3947 100644 --- a/cpu/ppc4xx/i2c.c +++ b/cpu/ppc4xx/i2c.c @@ -10,16 +10,59 @@ #include <405gp_i2c.h> #include +#ifdef CONFIG_HARD_I2C + +/* + * PPC405GP I2C interface definitions. + */ +#define I2C_REGISTERS_BASE_ADDRESS 0xEF600500 +#define IIC_MDBUF (I2C_REGISTERS_BASE_ADDRESS+IICMDBUF) +#define IIC_SDBUF (I2C_REGISTERS_BASE_ADDRESS+IICSDBUF) +#define IIC_LMADR (I2C_REGISTERS_BASE_ADDRESS+IICLMADR) +#define IIC_HMADR (I2C_REGISTERS_BASE_ADDRESS+IICHMADR) +#define IIC_CNTL (I2C_REGISTERS_BASE_ADDRESS+IICCNTL) +#define IIC_MDCNTL (I2C_REGISTERS_BASE_ADDRESS+IICMDCNTL) +#define IIC_STS (I2C_REGISTERS_BASE_ADDRESS+IICSTS) +#define IIC_EXTSTS (I2C_REGISTERS_BASE_ADDRESS+IICEXTSTS) +#define IIC_LSADR (I2C_REGISTERS_BASE_ADDRESS+IICLSADR) +#define IIC_HSADR (I2C_REGISTERS_BASE_ADDRESS+IICHSADR) +#define IIC_CLKDIV (I2C_REGISTERS_BASE_ADDRESS+IICCLKDIV) +#define IIC_INTRMSK (I2C_REGISTERS_BASE_ADDRESS+IICINTRMSK) +#define IIC_XFRCNT (I2C_REGISTERS_BASE_ADDRESS+IICXFRCNT) +#define IIC_XTCNTLSS (I2C_REGISTERS_BASE_ADDRESS+IICXTCNTLSS) +#define IIC_DIRECTCNTL (I2C_REGISTERS_BASE_ADDRESS+IICDIRECTCNTL) + +/* MDCNTL Register Bit definition */ +#define IIC_MDCNTL_HSCL 0x01 +#define IIC_MDCNTL_EUBS 0x02 +#define IIC_MDCNTL_FMDB 0x40 +#define IIC_MDCNTL_FSDB 0x80 + +/* CNTL Register Bit definition */ +#define IIC_CNTL_PT 0x01 +#define IIC_CNTL_READ 0x02 +#define IIC_CNTL_CHT 0x04 + +/* STS Register Bit definition */ +#DEFIne IIC_STS_PT 0X01 +#define IIC_STS_ERR 0X04 +#define IIC_STS_MDBS 0X20 + +/* EXTSTS Register Bit definition */ +#define IIC_EXTSTS_XFRA 0X01 +#define IIC_EXTSTS_ICT 0X02 +#define IIC_EXTSTS_LA 0X04 + #define IIC_OK 0 #define IIC_NOK 1 -#define IIC_NOK_LA 2 /* Lost arbitration */ -#define IIC_NOK_ICT 3 /* Incomplete transfer */ -#define IIC_NOK_XFRA 4 /* Transfer aborted */ -#define IIC_NOK_DATA 5 /* No data in buffer */ -#define IIC_NOK_TOUT 6 /* Transfer timeout */ +#define IIC_NOK_LA 2 /* Lost arbitration */ +#define IIC_NOK_ICT 3 /* Incomplete transfer */ +#define IIC_NOK_XFRA 4 /* Transfer aborted */ +#define IIC_NOK_DATA 5 /* No data in buffer */ +#define IIC_NOK_TOUT 6 /* Transfer timeout */ -#define IIC_TIMEOUT 1 /* 1 seconde */ +#define IIC_TIMEOUT 1 /* 1 seconde */ /* * Handle page write settings. @@ -32,341 +75,373 @@ /* __asm__ volatile("eieio"); */ -static void _i2c_bus_reset(void) +static void _i2c_bus_reset (void) { - int i, status; - - /* first clear out status registers */ - out8(IIC_STS, 0x0A); - out8(IIC_EXTSTS, 0x8F); - __asm__ volatile("eieio"); - - /* - * Get current state, reset bus - * only if no transfers are pending. - */ - i = 10; - do { - /* Get status */ - status = in8(IIC_STS); - udelay(500); /* 500us */ - i--; - } while ((status & IIC_STS_PT) && (i>0)); - /* Soft reset controller */ - status = in8(IIC_XTCNTLSS); - out8(IIC_XTCNTLSS, (status | 0x1)); - __asm__ volatile("eieio"); - - /* make sure where in initial state, data hi, clock hi */ - out8(IIC_DIRECTCNTL, 0xC); - for (i = 0; i < 10; i++){ - if ((in8(IIC_DIRECTCNTL) & 0x3) != 0x3){ - /* clock until we get to known state */ - out8(IIC_DIRECTCNTL, 0x8); /* clock lo */ - udelay(100); /* 100us */ - out8(IIC_DIRECTCNTL, 0xC); /* clock hi */ - udelay(100); /* 100us */ - } else { - break; - } - } - /* send start condition */ - out8(IIC_DIRECTCNTL, 0x4); - udelay(1000); /* 1ms */ - /* send stop condition */ - out8(IIC_DIRECTCNTL, 0xC); - udelay(1000); /* 1ms */ - /* Unreset controller */ - out8(IIC_XTCNTLSS, (status & ~0x1)); - udelay(1000); /* 1ms */ + int i, status; + + /* first clear out status registers */ + out8 (IIC_STS, 0x0A); + out8 (IIC_EXTSTS, 0x8F); + __asm__ volatile ("eieio"); + + /* + * Get current state, reset bus + * only if no transfers are pending. + */ + i = 10; + do { + /* Get status */ + status = in8 (IIC_STS); + udelay (500); /* 500us */ + i--; + } while ((status & IIC_STS_PT) && (i > 0)); + /* Soft reset controller */ + status = in8 (IIC_XTCNTLSS); + out8 (IIC_XTCNTLSS, (status | 0x1)); + __asm__ volatile ("eieio"); + + /* make sure where in initial state, data hi, clock hi */ + out8 (IIC_DIRECTCNTL, 0xC); + for (i = 0; i < 10; i++) { + if ((in8 (IIC_DIRECTCNTL) & 0x3) != 0x3) { + /* clock until we get to known state */ + out8 (IIC_DIRECTCNTL, 0x8); /* clock lo */ + udelay (100); /* 100us */ + out8 (IIC_DIRECTCNTL, 0xC); /* clock hi */ + udelay (100); /* 100us */ + } else { + break; + } + } + /* send start condition */ + out8 (IIC_DIRECTCNTL, 0x4); + udelay (1000); /* 1ms */ + /* send stop condition */ + out8 (IIC_DIRECTCNTL, 0xC); + udelay (1000); /* 1ms */ + /* Unreset controller */ + out8 (IIC_XTCNTLSS, (status & ~0x1)); + udelay (1000); /* 1ms */ } -void i2c_init(void) +void i2c_init (int speed, int slaveadd) { - PPC405_SYS_INFO sysInfo; - unsigned long freqOPB; - int val, divisor; - - /* Reset status register */ - /* write 1 in SCMP and IRQA to clear these fields */ - out8(IIC_STS, 0x0A); - - /* write 1 in IRQP IRQD LA ICT XFRA to clear these fields */ - out8(IIC_EXTSTS, 0x8F); - - /* Handle possible failed I2C state */ - _i2c_bus_reset(); - - /* clear lo master address */ - out8(IIC_LMADR,0); - - /* clear hi master address */ - out8(IIC_HMADR,0); - - /* clear lo slave address */ - out8(IIC_LSADR,0); - - /* clear hi slave address */ - out8(IIC_HSADR,0); - - /* Clock divide Register */ - /* get OPB frequency */ - get_sys_info (&sysInfo); - freqOPB = sysInfo.freqPLB / sysInfo.pllOpbDiv; - /* set divisor according to freqOPB */ - divisor = (freqOPB - 1) / 10000000; - if (divisor == 0) - divisor = 1; - out8(IIC_CLKDIV,divisor); - - /* no interrupts */ - out8(IIC_INTRMSK,0); - - /* clear transfer count */ - out8(IIC_XFRCNT,0); - - /* clear extended control & stat */ - /* write 1 in SRC SRS SWC SWS to clear these fields */ - out8(IIC_XTCNTLSS,0xF0); - - /* Mode Control Register - Flush Slave/Master data buffer */ - out8(IIC_MDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB); - __asm__ volatile("eieio"); - - /* Ignore General Call, 100kHz, slave transfers are ignored, - disable interrupts, exit unknown bus state, enable hold - SCL - */ - val = in8(IIC_MDCNTL) | IIC_MDCNTL_EUBS | IIC_MDCNTL_HSCL; - __asm__ volatile("eieio"); - out8(IIC_MDCNTL, val); - - /* clear control reg */ - out8(IIC_CNTL,0x00); - __asm__ volatile("eieio"); -} + PPC405_SYS_INFO sysInfo; + unsigned long freqOPB; + int val, divisor; + + /* Reset status register */ + /* write 1 in SCMP and IRQA to clear these fields */ + out8 (IIC_STS, 0x0A); + + /* write 1 in IRQP IRQD LA ICT XFRA to clear these fields */ + out8 (IIC_EXTSTS, 0x8F); + + /* Handle possible failed I2C state */ + _i2c_bus_reset (); + + /* clear lo master address */ + out8 (IIC_LMADR, 0); + + /* clear hi master address */ + out8 (IIC_HMADR, 0); + + /* clear lo slave address */ + out8 (IIC_LSADR, 0); + + /* clear hi slave address */ + out8 (IIC_HSADR, 0); + + /* Clock divide Register */ + /* get OPB frequency */ + get_sys_info (&sysInfo); + freqOPB = sysInfo.freqPLB / sysInfo.pllOpbDiv; + /* set divisor according to freqOPB */ + divisor = (freqOPB - 1) / 10000000; + if (divisor == 0) + divisor = 1; + out8 (IIC_CLKDIV, divisor); + + /* no interrupts */ + out8 (IIC_INTRMSK, 0); + /* clear transfer count */ + out8 (IIC_XFRCNT, 0); -int i2c_transfer(unsigned char command_is_reading, unsigned char address, - unsigned short size_to_transfer, unsigned char data[] ) + /* clear extended control & stat */ + /* write 1 in SRC SRS SWC SWS to clear these fields */ + out8 (IIC_XTCNTLSS, 0xF0); + + /* Mode Control Register + Flush Slave/Master data buffer */ + out8 (IIC_MDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB); + __asm__ volatile ("eieio"); + + /* Ignore General Call, 100kHz, slave transfers are ignored, + disable interrupts, exit unknown bus state, enable hold + SCL + */ + val = in8 (IIC_MDCNTL) | IIC_MDCNTL_EUBS | IIC_MDCNTL_HSCL; + __asm__ volatile ("eieio"); + + out8 (IIC_MDCNTL, val); + + /* clear control reg */ + out8 (IIC_CNTL, 0x00); + __asm__ volatile ("eieio"); +} + +static +int i2c_transfer (unsigned char command_is_reading, unsigned char address, + unsigned short size_to_transfer, unsigned char data[]) { - int bytes_transfered; - int result; - int status; - int i; - - result = IIC_OK; - bytes_transfered = 0; - - i2c_init(); - - /* Check init */ - i=10; - do{ - /* Get status */ - status = in8(IIC_STS); - i--; - }while ((status & IIC_STS_PT) && (i>0)); - if (status & IIC_STS_PT) - { - result = IIC_NOK_TOUT; - return(result); - } - - /* 7-bit adressing */ - out8(IIC_HMADR,0); - out8(IIC_LMADR, address); - - while ((bytes_transfered < size_to_transfer) && (result == IIC_OK)) - { - /* Control register = - Normal transfer, 7-bits adressing, Transfer 1 byte, Normal start, - Transfer is a sequence of transfers - Write/Read, Start transfer */ - - /* ACTION => Start - Transfer - Ack - pause */ - /* ACTION - LAST BYTE => Start - Transfer - Nack - Stop */ - if (command_is_reading) - { - /* issue read command */ - if (bytes_transfered == size_to_transfer-1) - { - out8(IIC_CNTL, IIC_CNTL_READ | IIC_CNTL_PT); - } - else - { - out8(IIC_CNTL, IIC_CNTL_READ | IIC_CNTL_CHT | IIC_CNTL_PT); - } - } - else - { - /* Set buffer */ - out8(IIC_MDBUF,data[bytes_transfered]); - udelay(1); - /* issue write command */ - if (bytes_transfered == size_to_transfer-1) - { - out8(IIC_CNTL, IIC_CNTL_PT); - } - else - { - out8(IIC_CNTL, IIC_CNTL_CHT | IIC_CNTL_PT); - } - } - __asm__ volatile("eieio"); - - /* Transfer is in progress */ - i=20; - do{ - /* Get status */ - status = in8(IIC_STS); - udelay(10); - i--; - }while ((status & IIC_STS_PT) && !(status & IIC_STS_ERR) && (i>0)); - - if (status & IIC_STS_ERR) - { - result = IIC_NOK; - status = in8(IIC_EXTSTS); - /* Lost arbitration? */ - if (status & IIC_EXTSTS_LA) - result = IIC_NOK_LA; - /* Incomplete transfer? */ - if (status & IIC_EXTSTS_ICT) - result = IIC_NOK_ICT; - /* Transfer aborted? */ - if (status & IIC_EXTSTS_XFRA) - result = IIC_NOK_XFRA; + int bytes_transfered; + int result; + int status; + int i; + + result = IIC_OK; + bytes_transfered = 0; + + /* Check init */ + i = 10; + do { + /* Get status */ + status = in8 (IIC_STS); + i--; + } while ((status & IIC_STS_PT) && (i > 0)); + if (status & IIC_STS_PT) { + result = IIC_NOK_TOUT; + return (result); } - else if (status & IIC_STS_PT) - { - result = IIC_NOK_TOUT; - } - /* Command is reading => get buffer */ - if ((command_is_reading) && (result == IIC_OK)) - { - /* Are there data in buffer */ - if (status & IIC_STS_MDBS) - { - udelay(1); - data[bytes_transfered] = in8(IIC_MDBUF); - } - else result = IIC_NOK_DATA; + + /* 7-bit adressing */ + out8 (IIC_HMADR, 0); + out8 (IIC_LMADR, address); + + while ((bytes_transfered < size_to_transfer) && (result == IIC_OK)) { + /* Control register = + Normal transfer, 7-bits adressing, Transfer 1 byte, Normal start, + Transfer is a sequence of transfers + Write/Read, Start transfer */ + + /* ACTION => Start - Transfer - Ack - pause */ + /* ACTION - LAST BYTE => Start - Transfer - Nack - Stop */ + if (command_is_reading) { + /* issue read command */ + if (bytes_transfered == size_to_transfer - 1) { + out8 (IIC_CNTL, IIC_CNTL_READ | IIC_CNTL_PT); + } else { + out8 (IIC_CNTL, IIC_CNTL_READ | + IIC_CNTL_CHT | + IIC_CNTL_PT); + } + } else { + /* Set buffer */ + out8 (IIC_MDBUF, data[bytes_transfered]); + udelay (1); + /* issue write command */ + if (bytes_transfered == size_to_transfer - 1) { + out8 (IIC_CNTL, IIC_CNTL_PT); + } else { + out8 (IIC_CNTL, IIC_CNTL_CHT | IIC_CNTL_PT); + } + } + __asm__ volatile ("eieio"); + + /* Transfer is in progress */ + i = 20; + do { + /* Get status */ + status = in8 (IIC_STS); + udelay (10); + i--; + } while ((status & IIC_STS_PT) && !(status & IIC_STS_ERR) + && (i > 0)); + + if (status & IIC_STS_ERR) { + result = IIC_NOK; + status = in8 (IIC_EXTSTS); + /* Lost arbitration? */ + if (status & IIC_EXTSTS_LA) + result = IIC_NOK_LA; + /* Incomplete transfer? */ + if (status & IIC_EXTSTS_ICT) + result = IIC_NOK_ICT; + /* Transfer aborted? */ + if (status & IIC_EXTSTS_XFRA) + result = IIC_NOK_XFRA; + } else if (status & IIC_STS_PT) { + result = IIC_NOK_TOUT; + } + /* Command is reading => get buffer */ + if ((command_is_reading) && (result == IIC_OK)) { + /* Are there data in buffer */ + if (status & IIC_STS_MDBS) { + udelay (1); + data[bytes_transfered] = in8 (IIC_MDBUF); + } else + result = IIC_NOK_DATA; + } + bytes_transfered++; } - bytes_transfered++; - } - return(result); + return (result); } - -int i2c_receive(unsigned char address, - unsigned short size_to_expect, unsigned char datain[] ) +static +int i2c_receive (unsigned char address, + unsigned short size_to_expect, unsigned char datain[]) { - int status; - status = i2c_transfer(1, address, size_to_expect, datain); - return status; + int status; + + status = i2c_transfer (1, address, size_to_expect, datain); + return status; } +static +int i2c_send (unsigned char address, + unsigned short size_to_send, unsigned char dataout[]) +{ + int status; + + status = i2c_transfer (0, address, size_to_send, dataout); + return status; +} -int i2c_send(unsigned char address, - unsigned short size_to_send, unsigned char dataout[] ) +int i2c_probe (uchar chip) { - int status; - status = i2c_transfer(0, address, size_to_send, dataout); - return status; + uchar buf[1]; + + buf[0] = 0; + + /* + * What is needed is to send the chip address and verify that the + * address was ed (i.e. there was a chip at that address which + * drove the data line low). + */ + return (i2c_send (chip << 1, 1, buf) != 0); } -int i2c_read (uchar *addr, int alen, uchar *buffer, int len) +int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) { - if ((alen < 1) || (alen > 3)) { - /* Can't out string when called early in boot process. */ - /* printf ("I2C read: addr len %d not supported\n", alen); */ + uchar xaddr[4]; + int rcode = 0; + + if ((alen < 1) || (alen > 2)) { + printf ("I2C read: addr len %d not supported\n", alen); return 1; } - if (i2c_send (addr[0] << 1, alen-1, addr + 1) != 0) - return 1; - - if (i2c_receive ((addr[0] << 1) | 0x01, len, buffer) != 0) + xaddr[0] = (addr >> 24) & 0xFF; + xaddr[1] = (addr >> 16) & 0xFF; + xaddr[2] = (addr >> 8) & 0xFF; + xaddr[3] = addr & 0xFF; + +#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW + /* + * EEPROM chips that implement "address overflow" are ones + * like Catalyst 24WC04/08/16 which has 9/10/11 bits of + * address and the extra bits end up in the "chip address" + * bit slots. This makes a 24WC08 (1Kbyte) chip look like + * four 256 byte chips. + * + * Note that we consider the length of the address field to + * still be one byte because the extra address bits are + * hidden in the chip address. + */ + chip |= ((addr >> alen) & CFG_I2C_EEPROM_ADDR_OVERFLOW); +#endif + + if (i2c_send (chip << 1, alen, &xaddr[4 - alen]) != 0) + rcode = 1; + if (i2c_receive ((chip << 1) | 0x01, len, buffer) != 0) + rcode = 1; + return rcode; +} + +#ifndef CFG_EEPROM_PAGE_WRITE_ENABLE + +int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len) +{ + uchar xbuf[3]; + + if ((alen < 1) || (alen > 2)) { + printf ("I2C write: addr len %d not supported\n", alen); return 1; - + } +#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW + /* + * EEPROM chips that implement "address overflow" are ones + * like Catalyst 24WC04/08/16 which has 9/10/11 bits of + * address and the extra bits end up in the "chip address" + * bit slots. This makes a 24WC08 (1Kbyte) chip look like + * four 256 byte chips. + * + * Note that we consider the length of the address field to + * still be one byte because the extra address bits are + * hidden in the chip address. + */ + chip |= ((addr >> alen) & CFG_I2C_EEPROM_ADDR_OVERFLOW); +#endif + + /* write with ack polling */ + while (len-- > 0) { + xbuf[0] = (addr >> 8) & 0xFF; /* High addr (if used) */ + xbuf[1] = addr & 0xFF; /* Low addr */ + xbuf[2] = *buffer++; + addr++; /* increase write offset */ + /* single write + ack polling */ + while (i2c_send (chip << 1, alen + 1, &xbuf[2 - alen]) != 0) { + udelay (100); + } + } return 0; } +#else /* CFG_EEPROM_PAGE_WRITE_ENABLE */ -/* - * i2c_wr_page() - Write a buffer as a series of pages. - * For devices that don't support page writes, pass a 1 as - * the page size. For devices that support an infinite - * page size, use a page size of 0. - */ -#define _I2C_MAX_ADDR_SIZE (sizeof(long)) -int i2c_wr_page (unsigned char *addr, int alen, unsigned char *data, int dlen, int page_size) +int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len) { - unsigned long idx, i, offset = 0; - unsigned char *data_ptr = data; - unsigned char xbuf[_I2C_MAX_ADDR_SIZE + (1 << CFG_EEPROM_PAGE_WRITE_BITS)]; - - /* Validate parameters. */ - if ((alen < 1) || (alen > _I2C_MAX_ADDR_SIZE) || - (dlen < 0) || (page_size > 20)) - return 1; - - /* create a cardinal address from the address char array */ - /* why do we go through all this trouble converting to cardinal - and then back to array? so we can have address wrap correctly - when we reach a 256 byte boundry on large parts. */ - for (i = 0; i < alen; i++) - offset = (offset << 8) + addr[i]; - - /* write with ack polling */ - while (dlen > 0) { - /* reset pointers */ - idx = 0; - - /* move the address bytes into array, msb first */ - for (i = alen; i > 0; i--) { - xbuf[idx++] = (unsigned char)((offset>>((i-1)*8)) & 0xff); - } - - /* - * Move the data to output buffer - * stop when we reach end of page, or - * when all data is sent - */ - do { - xbuf[idx++] = *data_ptr++; - offset++; - dlen--; - } while (((page_size == 0) || (offset % page_size)) && (dlen > 0)); - - /* - * Write the page, i2c expects the 1st address byte - * to be handled specialy, so we separate it out, - * inc the pointer, and dec the len - */ - i2c_send(xbuf[0] << 1, idx - 1, xbuf + 1); - udelay(100); - - /* - * Wait for completion, we use a short msg and look for ack, - * when we get an ack, the i2c is finished, and returns 0. - * - * FIXME - Needs timeout error handling. - */ - while ((i2c_send(xbuf[0] << 1, 1, xbuf + 1)) != 0) { - udelay(100); - } - } - return 0; -} /* i2c_wr_page() */ - - -int i2c_write (uchar *addr, int alen, uchar *buffer, int len) -{ - return i2c_wr_page(addr, alen, buffer, len, 1 << CFG_EEPROM_PAGE_WRITE_BITS); -} /* i2c_write() */ + /* buffer for one page + addresses */ + uchar wbuffer[(1 << CFG_EEPROM_PAGE_WRITE_BITS) + 2]; + int i; + + if ((alen < 1) || (alen > 2)) { + printf ("I2C read: addr len %d not supported\n", alen); + return 1; + } + /* fill in the address first */ + wbuffer[0] = (addr >> 8) & 0xFF; /* High addr (if used) */ + wbuffer[1] = addr & 0xFF; /* Low addr */ + + for (i = 2; i < len + 2; i++) { + wbuffer[i] = *buffer++; /* copy data */ + } + +#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW + /* + * EEPROM chips that implement "address overflow" are ones + * like Catalyst 24WC04/08/16 which has 9/10/11 bits of + * address and the extra bits end up in the "chip address" + * bit slots. This makes a 24WC08 (1Kbyte) chip look like + * four 256 byte chips. + * + * Note that we consider the length of the address field to + * still be one byte because the extra address bits are + * hidden in the chip address. + */ + chip |= ((addr >> alen) & CFG_I2C_EEPROM_ADDR_OVERFLOW); +#endif + + /* write page + ack polling */ + while (i2c_send (chip << 1, alen + len, &wbuffer[2 - alen]) != 0) { + udelay (100); + } + + return 0; +} +#endif /* CFG_EEPROM_PAGE_WRITE_ENABLE */ +#endif /* CONFIG_HARD_I2C */ diff --git a/include/405gp_i2c.h b/include/405gp_i2c.h index 04ba75b..4babc04 100644 --- a/include/405gp_i2c.h +++ b/include/405gp_i2c.h @@ -39,10 +39,4 @@ #define IIC_EXTSTS_ICT 0X02 #define IIC_EXTSTS_LA 0X04 - -int i2c_receive(unsigned char address, - unsigned short size_to_expect, unsigned char datain[] ); -int i2c_send(unsigned char address, - unsigned short size_to_send, unsigned char dataout[] ); - #endif diff --git a/include/asm/cpm_8260.h b/include/asm/cpm_8260.h index b8a6380..0c54de7 100644 --- a/include/asm/cpm_8260.h +++ b/include/asm/cpm_8260.h @@ -695,6 +695,45 @@ typedef struct iic { uint iic_txtmp; /* Internal */ } iic_t; +/* SPI parameter RAM. +*/ +typedef struct spi { + ushort spi_rbase; /* Rx Buffer descriptor base address */ + ushort spi_tbase; /* Tx Buffer descriptor base address */ + u_char spi_rfcr; /* Rx function code */ + u_char spi_tfcr; /* Tx function code */ + ushort spi_mrblr; /* Max receive buffer length */ + uint spi_rstate; /* Internal */ + uint spi_rdp; /* Internal */ + ushort spi_rbptr; /* Internal */ + ushort spi_rbc; /* Internal */ + uint spi_rxtmp; /* Internal */ + uint spi_tstate; /* Internal */ + uint spi_tdp; /* Internal */ + ushort spi_tbptr; /* Internal */ + ushort spi_tbc; /* Internal */ + uint spi_txtmp; /* Internal */ + uint spi_res; /* Tx temp. */ + uint spi_res1[4]; /* SDMA temp. */ +} spi_t; + +/* SPI Mode register. +*/ +#define SPMODE_LOOP ((ushort)0x4000) /* Loopback */ +#define SPMODE_CI ((ushort)0x2000) /* Clock Invert */ +#define SPMODE_CP ((ushort)0x1000) /* Clock Phase */ +#define SPMODE_DIV16 ((ushort)0x0800) /* BRG/16 mode */ +#define SPMODE_REV ((ushort)0x0400) /* Reversed Data */ +#define SPMODE_MSTR ((ushort)0x0200) /* SPI Master */ +#define SPMODE_EN ((ushort)0x0100) /* Enable */ +#define SPMODE_LENMSK ((ushort)0x00f0) /* character length */ +#define SPMODE_PMMSK ((ushort)0x000f) /* prescale modulus */ + +#define SPMODE_LEN(x) ((((x)-1)&0xF)<<4) +#define SPMODE_PM(x) ((x) &0xF) + +#define SPI_EB ((u_char)0x10) /* big endian byte order */ + #define BD_IIC_START ((ushort)0x0400) #endif /* __CPM_82XX__ */ diff --git a/include/asm/immap_8260.h b/include/asm/immap_8260.h index 4f9894c..c61cc4f 100644 --- a/include/asm/immap_8260.h +++ b/include/asm/immap_8260.h @@ -294,7 +294,7 @@ typedef struct smc { /* Serial management channels */ /* Serial Peripheral Interface. */ -typedef struct spi { +typedef struct im_spi { ushort spi_spmode; char res1[4]; u_char spi_spie; @@ -303,7 +303,7 @@ typedef struct spi { char res3[2]; u_char spi_spcom; char res4[82]; -} spi_t; +} im_spi_t; /* CPM Mux. */ @@ -407,7 +407,7 @@ typedef struct immap { scc_t im_scc[4]; /* Four SCCs */ smc_t im_smc[2]; /* Couple of SMCs */ - spi_t im_spi; /* A SPI */ + im_spi_t im_spi; /* A SPI */ cpmux_t im_cpmux; /* CPM clock route mux */ siramctl_t im_siramctl1; /* First SI RAM Control */ mcc_t im_mcc1; /* First MCC */ diff --git a/include/cmd_confdefs.h b/include/cmd_confdefs.h index 4fb9674..15a172f 100644 --- a/include/cmd_confdefs.h +++ b/include/cmd_confdefs.h @@ -30,6 +30,7 @@ /* * Configurable monitor commands */ +#define CFG_CMD_unused 0x00010000 /* was EEPROM, superceeded by I2C */ #define CFG_CMD_BDI 0x00000001 /* bdinfo */ #define CFG_CMD_LOADS 0x00000002 /* loads */ #define CFG_CMD_LOADB 0x00000004 /* loadb */ diff --git a/include/cmd_i2c.h b/include/cmd_i2c.h index 097d431..4ec4e6c 100644 --- a/include/cmd_i2c.h +++ b/include/cmd_i2c.h @@ -1,6 +1,6 @@ /* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * (C) Copyright 2001 + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. * * See file CREDITS for list of people who contributed to this * project. @@ -19,39 +19,81 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA - * - * hacked for I2C support by Murray.Jensen@cmst.csiro.au, 20-Dec-00 */ /* - * I2C support + * I2C Functions */ #ifndef _CMD_I2C_H -#define _CMD_I2C_H - -#include -#include +#define _CMD_I2C_H -#if defined(CONFIG_I2C) && (CONFIG_COMMANDS & CFG_CMD_I2C) - -#define CMD_TBL_I2C MK_CMD_TBL_ENTRY( \ - "i2c", 3, 6, 1, do_i2c, \ - "i2c - I2C sub-system\n", \ - "reset [speed] - reset I2C controller using clock speed `speed'\n"\ - " (defaults to 50kHz)\n" \ - "i2c recv i2c_addr data_addr size\n" \ - "i2c send i2c_addr data_addr size - recv/send `size' bytes to/from\n"\ - " mem addr `data_addr' from/to device with i2c address `i2c_addr'\n"\ - "i2c rcvs i2c_addr sec_addr data_addr size\n" \ - "i2c snds i2c_addr sec_addr data_addr size - recv/send `size' bytes\n"\ - " to/from mem addr `data_addr' from/to device with i2c address\n"\ - " `i2c_addr' and secondary address `sec_addr'\n" \ +#if (CONFIG_COMMANDS & CFG_CMD_I2C) +#define CMD_TBL_IMD MK_CMD_TBL_ENTRY( \ + "imd", 3, 4, 1, do_i2c_md, \ + "imd - i2c memory display\n", \ + "chip address[.0, .1, .2] [# of objects]\n - i2c memory display\n" \ +), +#define CMD_TBL_IMM MK_CMD_TBL_ENTRY( \ + "imm", 3, 3, 1, do_i2c_mm, \ + "imm - i2c memory modify (auto-incrementing)\n", \ + "chip address[.0, .1, .2]\n" \ + " - memory modify, auto increment address\n" \ +), +#define CMD_TBL_INM MK_CMD_TBL_ENTRY( \ + "inm", 3, 3, 1, do_i2c_nm, \ + "inm - memory modify (constant address)\n", \ + "chip address[.0, .1, .2]\n - memory modify, read and keep address\n" \ +), +#define CMD_TBL_IMW MK_CMD_TBL_ENTRY( \ + "imw", 3, 5, 1, do_i2c_mw, \ + "imw - memory write (fill)\n", \ + "chip address[.0, .1, .2] value [count]\n - memory write (fill)\n" \ +), +#define CMD_TBL_ICRC MK_CMD_TBL_ENTRY( \ + "icrc32", 4, 5, 1, do_i2c_crc, \ + "icrc32 - checksum calculation\n", \ + "chip address[.0, .1, .2] count\n - compute CRC32 checksum\n" \ ), +#define CMD_TBL_IPROBE MK_CMD_TBL_ENTRY( \ + "iprobe", 3, 1, 1, do_i2c_probe, \ + "iprobe - probe to discover valid I2C chip addresses\n", \ + "\n -discover valid I2C chip addresses\n" \ +), +/* + * Require full name for "iloop" because it is an infinite loop! + */ +#define CMD_TBL_ILOOP MK_CMD_TBL_ENTRY( \ + "iloop", 5, 5, 1, do_i2c_loop, \ + "iloop - infinite loop on address range\n", \ + "chip address[.0, .1, .2] [# of objects]\n" \ + " - loop, reading a set of addresses\n" \ +), +#define CMD_TBL_ISDRAM MK_CMD_TBL_ENTRY( \ + "isdram", 6, 2, 1, do_sdram, \ + "isdram - print SDRAM configuration information\n", \ + "chip\n - print SDRAM configuration information\n" \ + " (valid chip values 50..57)\n" \ +), + -int do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_i2c_md(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_i2c_mm(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_i2c_nm(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_i2c_mw(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_i2c_crc(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_i2c_probe(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_i2c_loop(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_sdram(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #else -#define CMD_TBL_I2C -#endif +#define CMD_TBL_IMD +#define CMD_TBL_IMM +#define CMD_TBL_INM +#define CMD_TBL_IMW +#define CMD_TBL_ICRC +#define CMD_TBL_IPROBE +#define CMD_TBL_ILOOP +#define CMD_TBL_ISDRAM +#endif /* CFG_CMD_MEMORY */ #endif /* _CMD_I2C_H */ diff --git a/include/config_ADS860.h b/include/config_ADS860.h index e1c6801..a46677e 100644 --- a/include/config_ADS860.h +++ b/include/config_ADS860.h @@ -27,7 +27,9 @@ #define CONFIG_BAUDRATE 19200 /* console baudrate */ #define CONFIG_PCMCIA 1 /* To enable PCMCIA support */ -#define CONFIG_I2C_X 1 /* extended addressing on I2C bus */ +#define CONFIG_HARD_I2C 1 /* I2C with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address defaults */ +#define CFG_I2C_SLAVE 0x7F #define MPC8XX_XIN 32768 /* 32.768 kHz input frequency */ #define MPC8XX_FACT 0x5F6 /* Multiply by 1526 */ @@ -57,7 +59,7 @@ #if 0 /* private command defs */ -#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_EEPROM | \ +#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_I2C | \ CFG_CMD_IDE | CFG_CMD_PCMCIA) #endif /* default command defs */ diff --git a/include/config_CANBT.h b/include/config_CANBT.h index 0b27c02..9da683c 100644 --- a/include/config_CANBT.h +++ b/include/config_CANBT.h @@ -148,20 +148,24 @@ #else /* Use EEPROM for environment variables */ -/*----------------------------------------------------------------------- - * I2C EEPROM (CAT24WC08) for environment - */ -#undef CONFIG_I2C_X /* 8 bit access */ #define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ #define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */ #define CFG_ENV_SIZE 0x400 /* 1024 bytes may be used for env vars */ /* total size of a CAT24WC08 is 1024 bytes */ +#endif + +/*----------------------------------------------------------------------- + * I2C EEPROM (CAT24WC08) for environment + */ +#define CONFIG_HARD_I2C /* I2C with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F #define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */ -#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */ - /* 16 byte page write mode using*/ - /* last 4 bits of the address */ -#endif +#define CFG_I2C_EEPROM_ADDR_LEN 1 /* bytes of address */ +/* mask of address bits that overflow into the "EEPROM chip address" */ +#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x03 + /*----------------------------------------------------------------------- * Cache Configuration */ diff --git a/include/config_CCM.h b/include/config_CCM.h index 3c339cf..57cdf3e 100644 --- a/include/config_CCM.h +++ b/include/config_CCM.h @@ -71,6 +71,12 @@ #define CONFIG_SPI /* enable SPI driver */ #define CONFIG_SPI_X /* 16 bit EEPROM addressing */ +#define CONFIG_HARD_I2C 1 /* I2C with hardware support */ +#undef CONFIG_SOFT_I2C +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + + /* ---------------------------------------------------------------- * Offset to initial SPI buffers in DPRAM (used if the environment * is in the SPI EEPROM): We need a 520 byte scratch DPRAM area to @@ -81,8 +87,6 @@ * ---------------------------------------------------------------- */ #define CFG_SPI_INIT_OFFSET 0xB00 -#define CFG_EEPROM_PAGE_WRITE_BITS 5 /* 32-byte page size */ - #define CONFIG_MAC_PARTITION /* nod used yet */ #define CONFIG_DOS_PARTITION @@ -92,7 +96,7 @@ #define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \ CFG_CMD_DHCP | \ CFG_CMD_DATE | \ - CFG_CMD_EEPROM | \ + CFG_CMD_I2C | \ CFG_CMD_BSP ) /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ @@ -207,6 +211,8 @@ #else /* Final version: environment in EEPROM */ #define CFG_ENV_IS_IN_EEPROM 1 +#define CFG_I2C_EEPROM_ADDR 0 +#define CFG_I2C_EEPROM_ADDR_LEN 2 #define CFG_ENV_OFFSET 2048 #define CFG_ENV_SIZE 2048 #endif diff --git a/include/config_CPCI405.h b/include/config_CPCI405.h index 31dc987..a915266 100644 --- a/include/config_CPCI405.h +++ b/include/config_CPCI405.h @@ -223,17 +223,24 @@ #define CFG_NVRAM_VXWORKS_OFFS 0x6900 /* Offset for VxWorks eth-addr */ #else /* Use EEPROM for environment variables */ -/*----------------------------------------------------------------------- - * I2C EEPROM (CAT24WC08) for environment - */ -#undef CONFIG_I2C_X /* 8 bit access */ + #define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ #define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */ #define CFG_ENV_SIZE 0x200 /* 512 bytes may be used for env vars */ /* total size of a CAT24WC08 is 1024 bytes */ #endif +/*----------------------------------------------------------------------- + * I2C EEPROM (CAT24WC08) for environment + */ +#define CONFIG_HARD_I2C /* I2c with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + #define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */ +#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */ +/* mask of address bits that overflow into the "EEPROM chip address" */ +#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x03 #define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */ /* 16 byte page write mode using*/ /* last 4 bits of the address */ diff --git a/include/config_CPCIISER4.h b/include/config_CPCIISER4.h index f0e7c05..97417fa 100644 --- a/include/config_CPCIISER4.h +++ b/include/config_CPCIISER4.h @@ -161,17 +161,23 @@ /*----------------------------------------------------------------------- * I2C EEPROM (CAT24WC08) for environment */ -#undef CONFIG_I2C_X /* 8 bit access */ -#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ -#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */ -#define CFG_ENV_SIZE 0x300 /* 768 bytes may be used for env vars */ - /* total size of a CAT24WC08 is 1024 bytes */ +#define CONFIG_HARD_I2C /* I2C with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F #define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */ +#define CFG_I2C_EEPROM_ADDR_LEN 1 /* bytes of address */ +/* mask of address bits that overflow into the "EEPROM chip address" */ +#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x03 #define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */ /* 16 byte page write mode using*/ /* last 4 bits of the address */ +#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ +#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */ +#define CFG_ENV_SIZE 0x300 /* 768 bytes may be used for env vars */ + /* total size of a CAT24WC08 is 1024 bytes */ + /*----------------------------------------------------------------------- * Cache Configuration */ diff --git a/include/config_DASA_SIM.h b/include/config_DASA_SIM.h index eb4846c..d5731b5 100644 --- a/include/config_DASA_SIM.h +++ b/include/config_DASA_SIM.h @@ -70,7 +70,9 @@ CFG_CMD_BSP ) #endif +#if 0 /* Does not appear to be used?! If it is used, needs to be fixed */ #define CONFIG_SOFT_I2C /* Software I2C support enabled */ +#endif /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include diff --git a/include/config_DU405.h b/include/config_DU405.h index 7fdaf41..e268432 100644 --- a/include/config_DU405.h +++ b/include/config_DU405.h @@ -187,17 +187,23 @@ /*----------------------------------------------------------------------- * I2C EEPROM (CAT24WC08) for environment */ -#undef CONFIG_I2C_X /* 8 bit access */ +#define CONFIG_HARD_I2C /* I2c with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + +#define CFG_I2C_EEPROM_ADDR 0x50 +#define CFG_I2C_EEPROM_ADDR_LEN 1 +/* mask of address bits that overflow into the "EEPROM chip address" */ +#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x03 +#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */ + /* 16 byte page write mode using*/ + /* last 4 bits of the address */ + #define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ #define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */ #define CFG_ENV_SIZE 0x400 /* 1024 bytes may be used for env vars */ /* total size of a CAT24WC08 is 1024 bytes */ -#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */ -#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */ - /* 16 byte page write mode using*/ - /* last 4 bits of the address */ - /*----------------------------------------------------------------------- * Cache Configuration */ diff --git a/include/config_ERIC.h b/include/config_ERIC.h index 9504b10..e2687a7 100644 --- a/include/config_ERIC.h +++ b/include/config_ERIC.h @@ -51,8 +51,12 @@ #define CFG_ENV_SIZE 0x800 /* 2048 bytes may be used for env vars */ #endif /* total size of a X1240 is 2048 bytes */ -#define CONFIG_I2C_X 1 /* 16 bit access */ +#define CONFIG_HARD_I2C 1 /* I2C with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + #define CFG_I2C_EEPROM_ADDR 0x57 /* X1240 has two I2C slave addresses, one for EEPROM */ +#define CFG_I2C_EEPROM_ADDR_LEN 2 /* address length for the eeprom */ #define CONFIG_I2C_RTC 1 /* we have a Xicor X1240 RTC */ #define CFG_I2C_RTC_ADDR 0x6F /* and one for RTC */ @@ -71,8 +75,6 @@ #endif #endif -#undef CONFIG_I2C /* To enable I2C support for nvram */ - #define CONFIG_BAUDRATE 115200 #define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */ @@ -354,8 +356,7 @@ * Definitions for Serial Presence Detect EEPROM address * (to get SDRAM settings) */ -#define EEPROM_WRITE_ADDRESS 0xA0 -#define EEPROM_READ_ADDRESS 0xA1 +#define SPD_EEPROM_ADDRESS 0x50 /* * Internal Definitions diff --git a/include/config_EVB64260.h b/include/config_EVB64260.h index bae2035..0af5885 100644 --- a/include/config_EVB64260.h +++ b/include/config_EVB64260.h @@ -327,10 +327,15 @@ #define CFG_DBAT3L (CFG_MISC_REGION_BASE | BATL_CACHEINHIBIT | BATL_PP_RW | BATL_GUARDEDSTORAGE) #define CFG_DBAT3U CFG_IBAT3U +/* I2C speed and slave address (for compatability) defaults */ +#define CFG_I2C_SPEED 400000 +#define CFG_I2C_SLAVE 0x7F + /* I2C addresses for the two DIMM SPD chips */ #define DIMM0_I2C_ADDR 0x56 #define DIMM1_I2C_ADDR 0x54 + /* * For booting Linux, the board info and command line data * have to be in the first 8 MB of memory, since this is diff --git a/include/config_FADS823.h b/include/config_FADS823.h index ca04ebd..8b93857 100644 --- a/include/config_FADS823.h +++ b/include/config_FADS823.h @@ -41,7 +41,10 @@ #define CONFIG_ENV_OVERWRITE 1 /* Overwrite the environment */ #define CONFIG_VIDEO 1 /* To enable video controller support */ -#define CONFIG_I2C 1 /* To enable I2C support */ +#define CONFIG_HARD_I2C 1 /* To I2C with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + /*Now included by CFG_CMD_PCMCIA */ /*#define CONFIG_PCMCIA 1 / * To enable PCMCIA support */ diff --git a/include/config_GENIETV.h b/include/config_GENIETV.h index 7ddfd6c..b72972e 100644 --- a/include/config_GENIETV.h +++ b/include/config_GENIETV.h @@ -47,7 +47,7 @@ /*#define CONFIG_VIDEO 1 // To enable the video initialization */ /*#define CONFIG_VIDEO_ADDR 0x00200000 */ -/*#define CONFIG_I2C 1 // Needed for 7176 & 7177 */ +/*#define CONFIG_HARD_I2C 1 // I2C with hardware support */ /*#define CONFIG_PCMCIA 1 // To enable the PCMCIA initialization */ /*#define CFG_PCMCIA_IO_ADDR 0xff020000 */ diff --git a/include/config_IAD210.h b/include/config_IAD210.h index 5e92b6c..8d4aa05 100644 --- a/include/config_IAD210.h +++ b/include/config_IAD210.h @@ -98,16 +98,24 @@ #define CONFIG_MAC_PARTITION #define CONFIG_DOS_PARTITION -#define CONFIG_I2C -#define CFG_I2C_SPEED 50000 -#define CFG_I2C_SLAVE 0xDD - -#if 0 -#define CONFIG_SOFT_I2C /* Software I2C support enabled */ +/* enable I2C and select the hardware/software driver */ +#undef CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ # define CFG_I2C_SPEED 50000 -# define CFG_I2C_SLAVE 0xFE +# define CFG_I2C_SLAVE 0xDD # define CFG_I2C_EEPROM_ADDR 0x50 -#endif +/* + * Software (bit-bang) I2C driver configuration + */ +#define I2C_PORT 1 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00000010) +#define I2C_TRISTATE (iop->pdir &= ~0x00000010) +#define I2C_READ ((iop->pdat & 0x00000010) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00000010; \ + else iop->pdat &= ~0x00000010 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00000020; \ + else iop->pdat &= ~0x00000020 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ #define CONFIG_RTC_MPC8xx /* use internal RTC of MPC8xx */ diff --git a/include/config_ICU862.h b/include/config_ICU862.h index 09e683a..d719659 100644 --- a/include/config_ICU862.h +++ b/include/config_ICU862.h @@ -89,10 +89,24 @@ #define CONFIG_MAC_PARTITION #define CONFIG_DOS_PARTITION -#define CONFIG_SOFT_I2C /* Software I2C support enabled */ +/* enable I2C and select the hardware/software driver */ +#undef CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ # define CFG_I2C_SPEED 50000 # define CFG_I2C_SLAVE 0xFE # define CFG_I2C_EEPROM_ADDR 0x50 +/* + * Software (bit-bang) I2C driver configuration + */ +#define I2C_PORT 1 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00000010) +#define I2C_TRISTATE (iop->pdir &= ~0x00000010) +#define I2C_READ ((iop->pdat & 0x00000010) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00000010; \ + else iop->pdat &= ~0x00000010 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00000020; \ + else iop->pdat &= ~0x00000020 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ #define CFG_EEPROM_X40430 /* Use a Xicor X40430 EEPROM */ #define CFG_EEPROM_PAGE_WRITE_BITS 4 /* 16 bytes page write mode */ diff --git a/include/config_IP860.h b/include/config_IP860.h index d83ca30..05a02d3 100644 --- a/include/config_IP860.h +++ b/include/config_IP860.h @@ -60,15 +60,32 @@ #undef CONFIG_WATCHDOG /* watchdog disabled */ -#define CONFIG_SOFT_I2C /* Software I2C support enabled */ + +/* enable I2C and select the hardware/software driver */ +#undef CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ +/* + * Software (bit-bang) I2C driver configuration + */ +#define I2C_PORT 1 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00000010) +#define I2C_TRISTATE (iop->pdir &= ~0x00000010) +#define I2C_READ ((iop->pdat & 0x00000010) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00000010; \ + else iop->pdat &= ~0x00000010 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00000020; \ + else iop->pdat &= ~0x00000020 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ + + # define CFG_I2C_SPEED 50000 # define CFG_I2C_SLAVE 0xFE # define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM X24C16 */ -# define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Xicor X24C16 has 16 byte */ - /* page write mode using last */ - /* 4 bits of the address */ +# define CFG_I2C_EEPROM_ADDR_LEN 2 /* bytes of address */ -#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_EEPROM) +#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ + CFG_CMD_I2C | \ + CFG_CMD_EEPROM) #define CONFIG_BOOTP_MASK CONFIG_BOOTP_DEFAULT @@ -133,7 +150,11 @@ #ifdef DEBUG #define CFG_MONITOR_LEN (512 << 10) /* Reserve 512 kB for Monitor */ #else +#if 0 /* need more space for I2C tests */ #define CFG_MONITOR_LEN (128 << 10) /* Reserve 128 kB for Monitor */ +#else +#define CFG_MONITOR_LEN (256 << 10) +#endif #endif #define CFG_MONITOR_BASE CFG_FLASH_BASE #define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ @@ -159,11 +180,8 @@ #define CFG_ENV_OFFSET 0 /* Start right at beginning of NVRAM */ #define CFG_ENV_SIZE 1024 /* Use only a part of it - it's slow! */ - -/*----------------------------------------------------------------------- - * EEPROM Configuration - */ -#define CFG_EEPROM_ADDR 0xA0 +#define CFG_ENV_EEPROM_ADDR 0xA0 +#define CFG_ENV_EEPROM_ADDR_LEN 2 /*----------------------------------------------------------------------- * Cache Configuration diff --git a/include/config_MHPC.h b/include/config_MHPC.h index 8974f44..9745838 100644 --- a/include/config_MHPC.h +++ b/include/config_MHPC.h @@ -70,7 +70,28 @@ #define CONFIG_RTC_MPC8xx /* use internal RTC of MPC8xx */ #undef CONFIG_UCODE_PATCH -#define CONFIG_I2C 1 /* To enable I2C support */ + +/* enable I2C and select the hardware/software driver */ +#undef CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ +/* + * Software (bit-bang) I2C driver configuration + */ +#define I2C_PORT 1 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00000010) +#define I2C_TRISTATE (iop->pdir &= ~0x00000010) +#define I2C_READ ((iop->pdat & 0x00000010) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00000010; \ + else iop->pdat &= ~0x00000010 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00000020; \ + else iop->pdat &= ~0x00000020 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ + + +# define CFG_I2C_SPEED 50000 +# define CFG_I2C_SLAVE 0xFE +# define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM X24C16 */ +# define CFG_I2C_EEPROM_ADDR_LEN 1 /* bytes of address */ #define CONFIG_BR0_WORKAROUND 1 diff --git a/include/config_MIP405.h b/include/config_MIP405.h index 9f076f3..b1a8a8b 100644 --- a/include/config_MIP405.h +++ b/include/config_MIP405.h @@ -68,19 +68,30 @@ * I2C Stuff: * the PIP405 is equiped with an Atmel 24C128/256 EEPROM at address * 0x53. - * Caution: on the same bus is the SPD (Serial Presens Detect + * Caution: on the same bus is the SPD (Serial Presence Detect * EEPROM of the SDRAM * The Atmel EEPROM uses 16Bit addressing. ***************************************************************/ -#define CONFIG_I2C -#define CONFIG_I2C_X -#define CFG_I2C_EEPROM_ADDR 0x53 + +#define CONFIG_HARD_I2C /* I2c with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + +#define CFG_I2C_EEPROM_ADDR 0x53 /* EEPROM 24C128/256 */ +#define CFG_I2C_EEPROM_ADDR_LEN 2 /* Bytes of address */ +/* mask of address bits that overflow into the "EEPROM chip address" */ +#undef CFG_I2C_EEPROM_ADDR_OVERFLOW +#define CFG_EEPROM_PAGE_WRITE_BITS 6 +#define CFG_EEPROM_PAGE_WRITE_BITS 6 /* The Atmel 24C128/256 has */ + /* 64 byte page write mode using*/ + /* last 6 bits of the address */ +#define CFG_EEPROM_PAGE_WRITE_ENABLE /* enable Page write */ + + #define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ #define CFG_ENV_OFFSET 0x00000 /* environment starts at the beginning of the EEPROM */ #define CFG_ENV_SIZE 0x00800 /* 2k bytes may be used for env vars */ -/* The Atmel 24C128/256 has 64 byte page write mode using last 6 bits of the address */ -#define CFG_EEPROM_PAGE_WRITE_BITS 6 -#define CFG_EEPROM_PAGE_WRITE_ENABLE /* enable Page write */ + /*************************************************************** * Definitions for Serial Presence Detect EEPROM address * (to get SDRAM settings) diff --git a/include/config_MPC8260ADS.h b/include/config_MPC8260ADS.h index fac169a..c03a9d3 100644 --- a/include/config_MPC8260ADS.h +++ b/include/config_MPC8260ADS.h @@ -93,7 +93,10 @@ #endif /* CONFIG_ETHER_INDEX */ /* other options */ -#define CONFIG_I2C 1 /* To enable I2C support */ +#define CONFIG_HARD_I2C 1 /* To enable I2C support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + #define CONFIG_8260_CLKIN 66666666 /* in Hz */ #define CONFIG_BAUDRATE 115200 diff --git a/include/config_OCRTC.h b/include/config_OCRTC.h index d319e29..79ebffb 100644 --- a/include/config_OCRTC.h +++ b/include/config_OCRTC.h @@ -180,17 +180,24 @@ #define CFG_NVRAM_VXWORKS_OFFS 0x6900 /* Offset for VxWorks eth-addr */ #else /* Use EEPROM for environment variables */ -/*----------------------------------------------------------------------- - * I2C EEPROM (CAT24WC08) for environment - */ -#undef CONFIG_I2C_X /* 8 bit access */ + #define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ #define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */ #define CFG_ENV_SIZE 0x300 /* 768 bytes may be used for env vars */ /* total size of a CAT24WC08 is 1024 bytes */ #endif +/*----------------------------------------------------------------------- + * I2C EEPROM (CAT24WC08) for environment + */ +#define CONFIG_HARD_I2C /* I2c with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + #define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */ +#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */ +/* mask of address bits that overflow into the "EEPROM chip address" */ +#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x03 #define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */ /* 16 byte page write mode using*/ /* last 4 bits of the address */ diff --git a/include/config_ORSG.h b/include/config_ORSG.h index c06cc6c..03291b3 100644 --- a/include/config_ORSG.h +++ b/include/config_ORSG.h @@ -180,17 +180,24 @@ #define CFG_NVRAM_VXWORKS_OFFS 0x6900 /* Offset for VxWorks eth-addr */ #else /* Use EEPROM for environment variables */ -/*----------------------------------------------------------------------- - * I2C EEPROM (CAT24WC08) for environment - */ -#undef CONFIG_I2C_X /* 8 bit access */ + #define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ #define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */ #define CFG_ENV_SIZE 0x300 /* 768 bytes may be used for env vars */ /* total size of a CAT24WC08 is 1024 bytes */ #endif +/*----------------------------------------------------------------------- + * I2C EEPROM (CAT24WC08) for environment + */ +#define CONFIG_HARD_I2C /* I2c with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + #define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */ +#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */ +/* mask of address bits that overflow into the "EEPROM chip address" */ +#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x03 #define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */ /* 16 byte page write mode using*/ /* last 4 bits of the address */ diff --git a/include/config_PIP405.h b/include/config_PIP405.h index aaf823e..1ea4eb6 100644 --- a/include/config_PIP405.h +++ b/include/config_PIP405.h @@ -72,23 +72,26 @@ * Caution: on the same bus is the SPD (Serial Presens Detect * EEPROM of the SDRAM * The Atmel EEPROM uses 16Bit addressing. - ***************************************************************/ -#define CONFIG_I2C -#define CONFIG_I2C_X + ***************************************************************/ +#define CONFIG_HARD_I2C /* I2c with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + #define CFG_I2C_EEPROM_ADDR 0x53 -#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ -#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */ -#define CFG_ENV_SIZE 0x200 /* 512 bytes may be used for env vars */ +#define CFG_I2C_EEPROM_ADDR_LEN 2 +#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ +#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */ +#define CFG_ENV_SIZE 0x200 /* 512 bytes may be used for env vars */ /* The Atmel 24C128/256 has 64 byte page write mode using last 6 bits of the address */ #define CFG_EEPROM_PAGE_WRITE_BITS 6 #define CFG_EEPROM_PAGE_WRITE_ENABLE /* enable Page write */ + /*************************************************************** * Definitions for Serial Presence Detect EEPROM address * (to get SDRAM settings) ***************************************************************/ -#define SDRAM_EEPROM_WRITE_ADDRESS 0xA0 -#define SDRAM_EEPROM_READ_ADDRESS 0xA1 +#define SPD_EEPROM_ADDRESS 0x50 #define CONFIG_BOARD_PRE_INIT /************************************************************** diff --git a/include/config_PM826.h b/include/config_PM826.h index 9f02e27..319da10 100644 --- a/include/config_PM826.h +++ b/include/config_PM826.h @@ -55,13 +55,26 @@ "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; " \ "bootm" -#define CONFIG_SOFT_I2C 1 /* I2C support */ +/* enable I2C and select the hardware/software driver */ +#undef CONFIG_HARD_I2C +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ +# define CFG_I2C_SPEED 50000 +# define CFG_I2C_SLAVE 0xFE +/* + * Software (bit-bang) I2C driver configuration + */ +#define I2C_PORT 1 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00000010) +#define I2C_TRISTATE (iop->pdir &= ~0x00000010) +#define I2C_READ ((iop->pdat & 0x00000010) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00000010; \ + else iop->pdat &= ~0x00000010 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00000020; \ + else iop->pdat &= ~0x00000020 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ #define CONFIG_RTC_PCF8563 -#define CFG_I2C_EEPROM_ADDR 0x58 -#define CFG_EEPROM_PAGE_WRITE_BITS 4 - #define CFG_I2C_RTC_ADDR 0x51 /* @@ -194,6 +207,8 @@ #else /* Final version: environment in EEPROM */ #define CFG_ENV_IS_IN_EEPROM 1 +#define CFG_I2C_EEPROM_ADDR 0x58 +#define CFG_I2C_EEPROM_ADDR_LEN 2 #define CFG_ENV_OFFSET 0 #define CFG_ENV_SIZE 2048 #endif diff --git a/include/config_RPXClassic.h b/include/config_RPXClassic.h index 157f908..8eb528a 100644 --- a/include/config_RPXClassic.h +++ b/include/config_RPXClassic.h @@ -126,6 +126,29 @@ #define CFG_I2C_SPEED 50000 #define CFG_I2C_SLAVE 0x34 + +/* enable I2C and select the hardware/software driver */ +#define CONFIG_HARD_I2C 1 /* I2C with hardware support */ +#undef CONFIG_SOFT_I2C /* I2C bit-banged */ +/* + * Software (bit-bang) I2C driver configuration + */ +#define I2C_PORT 1 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00000010) +#define I2C_TRISTATE (iop->pdir &= ~0x00000010) +#define I2C_READ ((iop->pdat & 0x00000010) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00000010; \ + else iop->pdat &= ~0x00000010 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00000020; \ + else iop->pdat &= ~0x00000020 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ + + +# define CFG_I2C_SPEED 50000 +# define CFG_I2C_SLAVE 0x34 +# define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM X24C16 */ +# define CFG_I2C_EEPROM_ADDR_LEN 2 /* bytes of address */ + /*----------------------------------------------------------------------- * Definitions for initial stack pointer and data area (in DPRAM) */ diff --git a/include/config_RPXsuper.h b/include/config_RPXsuper.h index 5989a63..6c1ac74 100644 --- a/include/config_RPXsuper.h +++ b/include/config_RPXsuper.h @@ -117,7 +117,10 @@ # error "on RPX Super ethernet must be FCC3" #endif /* CONFIG_ETHER_INDEX */ -#define CONFIG_I2C 1 +#define CONFIG_HARD_I2C 1 /* I2C with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + /* Define this to reserve an entire FLASH sector (256 KB) for * environment variables. Otherwise, the environment will be diff --git a/include/config_SXNI855T.h b/include/config_SXNI855T.h index ee104d5..c409c73 100644 --- a/include/config_SXNI855T.h +++ b/include/config_SXNI855T.h @@ -91,13 +91,24 @@ #define CONFIG_RTC_DS1306 /* Dallas 1306 real time clock */ -#define CONFIG_SOFT_I2C /* Software I2C support enabled */ +#define CONFIG_SOFT_I2C /* I2C bit-banged */ +/* + * Software (bit-bang) I2C driver configuration + */ +#define I2C_PORT 1 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00000010) +#define I2C_TRISTATE (iop->pdir &= ~0x00010010) +#define I2C_READ ((iop->pdat & 0x00000010) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00000010; \ + else iop->pdat &= ~0x00000010 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00000020; \ + else iop->pdat &= ~0x00000020 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ + # define CFG_I2C_SPEED 50000 # define CFG_I2C_SLAVE 0xFE # define CFG_I2C_EEPROM_ADDR 0x50 /* Atmel 24C64 */ -# define CFG_EEPROM_PAGE_WRITE_BITS 5 /* The Atmel 24C64 has 32 byte */ - /* page write mode using last */ - /* 5 bits of the address */ +# define CFG_I2C_EEPROM_ADDR_LEN 2 /* two byte address */ #define CONFIG_FEC_ENET 1 /* use FEC ethernet */ @@ -328,7 +339,6 @@ #define CFG_ENV_IS_IN_EEPROM 1 #define CFG_ENV_OFFSET 0 /* Start right at beginning of NVRAM */ #define CFG_ENV_SIZE 1024 /* Use only a part of it*/ -#define CONFIG_I2C_X 1 /* EEPROM uses 16-bit address */ #if 1 #define CONFIG_BOOT_RETRY_TIME 60 /* boot if no command in 60 seconds */ diff --git a/include/config_Sandpoint8240.h b/include/config_Sandpoint8240.h index 415645e..9082536 100644 --- a/include/config_Sandpoint8240.h +++ b/include/config_Sandpoint8240.h @@ -45,7 +45,7 @@ #undef USE_DINK32 #endif -#define CONFIG_BAUDRATE 9600 +#define CONFIG_BAUDRATE 115200 #define CONFIG_DRAM_SPEED 100 /* MHz */ #define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \ diff --git a/include/config_TQM8260.h b/include/config_TQM8260.h index d7c832e..40c4756 100644 --- a/include/config_TQM8260.h +++ b/include/config_TQM8260.h @@ -69,11 +69,44 @@ "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; " \ "bootm" -#define CONFIG_SOFT_I2C 1 /* I2C support */ -#define CONFIG_I2C_X 1 /* extended EEPROM addressing */ +/* enable I2C and select the hardware/software driver */ +#undef CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + +/* + * Software (bit-bang) I2C driver configuration + */ + +/* TQM8260 Rev.100 has the clock and data pins swapped (!!!) on EEPROM */ +#if (CONFIG_TQM8260 <= 100) + +#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00020000) +#define I2C_TRISTATE (iop->pdir &= ~0x00020000) +#define I2C_READ ((iop->pdat & 0x00020000) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00020000; \ + else iop->pdat &= ~0x00020000 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00010000; \ + else iop->pdat &= ~0x00010000 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ + +#else + +#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00010000) +#define I2C_TRISTATE (iop->pdir &= ~0x00010000) +#define I2C_READ ((iop->pdat & 0x00010000) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00010000; \ + else iop->pdat &= ~0x00010000 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00020000; \ + else iop->pdat &= ~0x00020000 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ +#endif # define CFG_I2C_EEPROM_ADDR 0x50 -# define CFG_EEPROM_PAGE_WRITE_BITS 5 +# define CFG_I2C_EEPROM_ADDR_LEN 2 /* * select serial console configuration @@ -160,7 +193,7 @@ #define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT|CONFIG_BOOTP_BOOTFILESIZE) -#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_EEPROM) +#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_I2C) /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include diff --git a/include/config_W7OLMC.h b/include/config_W7OLMC.h index e6c8644..abaea00 100644 --- a/include/config_W7OLMC.h +++ b/include/config_W7OLMC.h @@ -246,13 +246,19 @@ #endif /*----------------------------------------------------------------------- - * I2C EEPROM (Catalyst CAT24WC08) + * I2C EEPROM (CAT24WC08) for environment */ -#undef CONFIG_I2C_X /* 8 bit access */ -#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM Catalyst CAT24WC08 */ -#define CFG_I2C_MULTI_EEPROMS - -#define CONFIG_I2C +#define CONFIG_HARD_I2C /* I2c with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + +#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */ +#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */ +/* mask of address bits that overflow into the "EEPROM chip address" */ +#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x03 +#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */ + /* 16 byte page write mode using*/ + /* last 4 bits of the address */ /*----------------------------------------------------------------------- * Cache Configuration diff --git a/include/config_W7OLMG.h b/include/config_W7OLMG.h index 8523b85..0e8ec33 100644 --- a/include/config_W7OLMG.h +++ b/include/config_W7OLMG.h @@ -253,11 +253,13 @@ /*----------------------------------------------------------------------- * I2C EEPROM (ATMEL 24C04N) */ -#undef CONFIG_I2C_X /* 8 bit access */ +#define CONFIG_HARD_I2C 1 /* Hardware assisted I2C */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + #define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM ATMEL 24C04N */ #define CFG_I2C_MULTI_EEPROMS -#define CONFIG_I2C /*----------------------------------------------------------------------- * Cache Configuration diff --git a/include/config_WALNUT405.h b/include/config_WALNUT405.h index b7453d6..a235d78 100644 --- a/include/config_WALNUT405.h +++ b/include/config_WALNUT405.h @@ -142,6 +142,12 @@ #define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ +#define CONFIG_HARD_I2C 1 /* I2C with hardware support */ +#undef CONFIG_SOFT_I2C /* I2C bit-banged */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + + /*----------------------------------------------------------------------- * PCI stuff *----------------------------------------------------------------------- @@ -259,8 +265,7 @@ * Definitions for Serial Presence Detect EEPROM address * (to get SDRAM settings) */ -#define EEPROM_WRITE_ADDRESS 0xA0 -#define EEPROM_READ_ADDRESS 0xA1 +#define SPD_EEPROM_ADDRESS 0x50 /* * Internal Definitions diff --git a/include/config_cogent_mpc8xx.h b/include/config_cogent_mpc8xx.h index fadf5ab..78ca1b1 100644 --- a/include/config_cogent_mpc8xx.h +++ b/include/config_cogent_mpc8xx.h @@ -52,7 +52,10 @@ #define CONFIG_BAUDRATE 230400 -#define CONFIG_I2C +#define CONFIG_HARD_I2C /* I2C with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + #define CONFIG_COMMANDS ((CONFIG_CMD_DFL | CFG_CMD_KGDB | CFG_CMD_I2C) & ~CFG_CMD_NET) diff --git a/include/config_ep8260.h b/include/config_ep8260.h index 62924eb..040165b 100644 --- a/include/config_ep8260.h +++ b/include/config_ep8260.h @@ -187,7 +187,33 @@ # error "on EP8260 ethernet must be FCC3" #endif /* CONFIG_ETHER_INDEX */ -#define CONFIG_I2C 1 +/* + * select i2c support configuration + * + * Supported configurations are {none, software, hardware} drivers. + * If the software driver is chosen, there are some additional + * configuration items that the driver uses to drive the port pins. + */ +#undef CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + +/* + * Software (bit-bang) I2C driver configuration + */ +#ifdef CONFIG_SOFT_I2C +#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00010000) +#define I2C_TRISTATE (iop->pdir &= ~0x00010000) +#define I2C_READ ((iop->pdat & 0x00010000) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00010000; \ + else iop->pdat &= ~0x00010000 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00020000; \ + else iop->pdat &= ~0x00020000 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ +#endif /* CONFIG_SOFT_I2C */ + /* #define CONFIG_RTC_DS174x */ /* Define this to reserve an entire FLASH sector (256 KB) for diff --git a/include/config_gw8260.h b/include/config_gw8260.h index cbb24fc..54d0a11 100644 --- a/include/config_gw8260.h +++ b/include/config_gw8260.h @@ -306,7 +306,6 @@ CFG_CMD_ELF | \ CFG_CMD_ASKENV | \ CFG_CMD_ECHO | \ - CFG_CMD_I2C | \ CFG_CMD_REGINFO | \ CFG_CMD_IMMAP | \ CFG_CMD_MII) @@ -774,7 +773,7 @@ #endif /* (CFG_SDRAM0_SIZE == 64) */ #define CFG_PSRT 0x0e -#define CFG_MPTPR ( (0x32 << MPTPR_PTP_SHIFT) & MPTPR_PTP_MSK) +#define CFG_MPTPR MPTPR_PTP_DIV32 /*----------------------------------------------------------------------- diff --git a/include/config_hymod.h b/include/config_hymod.h index d27b15c..7e88783 100644 --- a/include/config_hymod.h +++ b/include/config_hymod.h @@ -115,7 +115,7 @@ /* other options */ -#define CONFIG_I2C 1 /* To enable I2C support */ +#define CONFIG_HARD_I2C 1 /* To enable I2C hardware support */ /* system clock rate (CLKIN) - equal to the 60x and local bus speed */ #ifdef DEBUG @@ -207,9 +207,7 @@ /* these are for the ST M24C02 2kbit serial i2c eeprom */ #define CFG_I2C_EEPROM_ADDR 0x50 /* base address */ -#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* 16 byte write page size */ -#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */ - +#define CFG_I2C_EEPROM_ADDR_LEN 1 /* bytes of address */ #define CFG_I2C_RTC_ADDR 0x51 /* philips PCF8563 RTC address */ /* @@ -502,10 +500,10 @@ #ifdef DEBUG #define CFG_PSRT 39 -#define CFG_MPTPR ((12<pdir |= 0x00000010) +#define I2C_TRISTATE (iop->pdir &= ~0x00000010) +#define I2C_READ ((iop->pdat & 0x00000010) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00000010; \ + else iop->pdat &= ~0x00000010 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00000020; \ + else iop->pdat &= ~0x00000020 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ + #define CONFIG_RTC_PCF8563 /* use Philips PCF8563 RTC */ #ifdef CONFIG_8xx_CONS_SCC2 /* Can't use ethernet, then */ #define CONFIG_COMMANDS ( (CONFIG_CMD_DFL & ~CFG_CMD_NET) | \ - CFG_CMD_EEPROM | \ CFG_CMD_DATE | \ + CFG_CMD_I2C | \ CFG_CMD_IDE | \ CFG_CMD_BSP ) #else #define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \ - CFG_CMD_EEPROM | \ CFG_CMD_DHCP | \ CFG_CMD_DATE | \ + CFG_CMD_I2C | \ CFG_CMD_IDE | \ CFG_CMD_BSP ) #endif @@ -240,6 +252,7 @@ #define CFG_I2C_KEYBD_ADDR 0x56 /* PIC LWE keyboard */ #define CFG_I2C_PICIO_ADDR 0x57 /* PIC IO Expander */ #define CFG_I2C_EEPROM_ADDR 0x58 /* EEPROM AT24C164 */ +#define CFG_I2C_EEPROM_ADDR_LEN 2 /*----------------------------------------------------------------------- * Cache Configuration diff --git a/include/config_pcu_e.h b/include/config_pcu_e.h index ddb05a4..00a4b8d 100644 --- a/include/config_pcu_e.h +++ b/include/config_pcu_e.h @@ -74,6 +74,11 @@ #define CONFIG_SPI /* enable SPI driver */ #define CONFIG_SPI_X /* 16 bit EEPROM addressing */ +#define CONFIG_HARD_I2C 1 /* I2C with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + + /* ---------------------------------------------------------------- * Offset to initial SPI buffers in DPRAM (used if the environment * is in the SPI EEPROM): We need a 520 byte scratch DPRAM area to @@ -84,9 +89,6 @@ * ---------------------------------------------------------------- */ #define CFG_SPI_INIT_OFFSET 0xB00 -#define CFG_EEPROM_PAGE_WRITE_BITS 5 /* 32-byte page size */ - - #define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \ CFG_CMD_DATE | \ CFG_CMD_EEPROM | \ @@ -223,6 +225,8 @@ #else /* Final version: environment in EEPROM */ #define CFG_ENV_IS_IN_EEPROM 1 +#define CFG_I2C_EEPROM_ADDR 0 +#define CFG_I2C_EEPROM_ADDR_LEN 2 #define CFG_ENV_OFFSET 1024 #define CFG_ENV_SIZE 1024 #endif diff --git a/include/config_ppmc8260.h b/include/config_ppmc8260.h index 0401c1b..ec65ce9 100644 --- a/include/config_ppmc8260.h +++ b/include/config_ppmc8260.h @@ -747,7 +747,7 @@ #define CFG_PSRT 0x0e -#define CFG_MPTPR ( (0x32 << MPTPR_PTP_SHIFT) & MPTPR_PTP_MSK) +#define CFG_MPTPR MPTPR_PTP_DIV32 /*----------------------------------------------------------------------- diff --git a/include/config_rsdproto.h b/include/config_rsdproto.h index e757e60..085306d 100644 --- a/include/config_rsdproto.h +++ b/include/config_rsdproto.h @@ -89,7 +89,10 @@ #define CONFIG_ENV_OVERWRITE /* enable I2C */ -#define CONFIG_I2C 1 +#define CONFIG_HARD_I2C 1 /* I2C with hardware support */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + /* system clock rate (CLKIN) - equal to the 60x and local bus speed */ #define CONFIG_8260_CLKIN 50000000 /* in Hz */ diff --git a/include/config_sbc8260.h b/include/config_sbc8260.h index a1b051f..5ba06ae 100644 --- a/include/config_sbc8260.h +++ b/include/config_sbc8260.h @@ -46,7 +46,7 @@ *****************************************************************************/ /* What is the oscillator's (UX2) frequency in Hz? */ -#define CONFIG_8260_CLKIN (33 * 1000 * 1000) +#define CONFIG_8260_CLKIN (66 * 1000 * 1000) /*----------------------------------------------------------------------- * MODCK_H & MODCLK[1-3] - Ref: Section 9.2 in MPC8206 User Manual @@ -74,7 +74,7 @@ * 0x6 0x1 66 133 266 Close Close Open * 0x6 0x2 66 133 300 Close Open Close */ -#define CFG_SBC_MODCK_H 0x02 +#define CFG_SBC_MODCK_H 0x05 /* Define this if you want to boot from 0x00000100. If you don't define * this, you will need to program the bootloader to 0xfff00000, and @@ -104,7 +104,7 @@ * it (in Mbytes)? */ #define CFG_SDRAM0_BASE 0x00000000 -#define CFG_SDRAM0_SIZE 16 +#define CFG_SDRAM0_SIZE 64 /* What should be the base address of the LEDs and switch S0? * If you don't want them enabled, don't define this. @@ -238,6 +238,38 @@ #endif /* CONFIG_ETHER_ON_FCC, CONFIG_ETHER_INDEX */ +/* + * select SPI support configuration + */ +#undef CONFIG_SPI /* enable SPI driver */ + +/* + * select i2c support configuration + * + * Supported configurations are {none, software, hardware} drivers. + * If the software driver is chosen, there are some additional + * configuration items that the driver uses to drive the port pins. + */ +#undef CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + +/* + * Software (bit-bang) I2C driver configuration + */ +#ifdef CONFIG_SOFT_I2C +#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00010000) +#define I2C_TRISTATE (iop->pdir &= ~0x00010000) +#define I2C_READ ((iop->pdat & 0x00010000) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00010000; \ + else iop->pdat &= ~0x00010000 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00020000; \ + else iop->pdat &= ~0x00020000 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ +#endif /* CONFIG_SOFT_I2C */ + /* Define this to reserve an entire FLASH sector (256 KB) for * environment variables. Otherwise, the environment will be @@ -327,6 +359,7 @@ CFG_CMD_ASKENV | \ CFG_CMD_ECHO | \ CFG_CMD_I2C | \ + CFG_CMD_SDRAM | \ CFG_CMD_REGINFO | \ CFG_CMD_IMMAP | \ CFG_CMD_MII ) @@ -336,6 +369,7 @@ CFG_CMD_ASKENV | \ CFG_CMD_ECHO | \ CFG_CMD_I2C | \ + CFG_CMD_SDRAM | \ CFG_CMD_REGINFO | \ CFG_CMD_IMMAP ) #endif /* CONFIG_ETHER_ON_FCC */ @@ -701,6 +735,11 @@ BRx_MS_SDRAM_P |\ BRx_V) +#define CFG_BR3_PRELIM ((CFG_SDRAM0_BASE & BRx_BA_MSK) |\ + BRx_PS_64 |\ + BRx_MS_SDRAM_P |\ + BRx_V) + /* With a 16 MB DIMM, the OR2 is configured as follows: * * - 16 MB @@ -739,10 +778,14 @@ *----------------------------------------------------------------------- */ +/* Address that the DIMM SPD memory lives at. + */ +#define SDRAM_SPD_ADDR 0x54 + #if (CFG_SDRAM0_SIZE == 16) /* With a 16 MB DIMM, the PSDMR is configured as follows: * - * - Page Based Interleaving, + * - Bank Based Interleaving, * - Refresh Enable, * - Address Multiplexing where A5 is output on A14 pin * (A6 on A15, and so on), @@ -772,7 +815,7 @@ #if (CFG_SDRAM0_SIZE == 64) /* With a 64 MB DIMM, the PSDMR is configured as follows: * - * - Page Based Interleaving, + * - Bank Based Interleaving, * - Refresh Enable, * - Address Multiplexing where A5 is output on A14 pin * (A6 on A15, and so on), @@ -799,8 +842,18 @@ PSDMR_CL_2) #endif -#define CFG_PSRT 0x0e -#define CFG_MPTPR ( (0x32 << MPTPR_PTP_SHIFT) & MPTPR_PTP_MSK) +/* + * Shoot for approximately 1MHz on the prescaler. + */ +#if (CONFIG_8260_CLKIN == (66 * 1000 * 1000)) +#define CFG_MPTPR MPTPR_PTP_DIV64 +#elif (CONFIG_8260_CLKIN == (33 * 1000 * 1000)) +#define CFG_MPTPR MPTPR_PTP_DIV32 +#else +#warning "Unconfigured bus clock freq: check CFG_MPTPR and CFG_PSRT are OK" +#define CFG_MPTPR MPTPR_PTP_DIV32 +#endif +#define CFG_PSRT 14 /* Bank 4 - On board SDRAM diff --git a/include/i2c.h b/include/i2c.h index 0612145..43d76fd 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -1,120 +1,82 @@ /* -** I2C interface -** ============= -** (C) 2000 by Paolo Scaffardi (arsenio@tin.it) -** AIRVENT SAM s.p.a - RIMINI(ITALY) -** -*/ + * (C) Copyright 2001 + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * The original I2C interface was + * (C) 2000 by Paolo Scaffardi (arsenio@tin.it) + * AIRVENT SAM s.p.a - RIMINI(ITALY) + * but has been changed substantially. + */ #ifndef _I2C_H_ #define _I2C_H_ -int i2c_read (uchar *addr, int alen, uchar *buffer, int len); -int i2c_write (uchar *addr, int alen, uchar *buffer, int len); -#if defined(CONFIG_MPC824X) -uchar i2c_reg_read (uchar i2c_addr, uchar reg); -void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val); - -/* initialize i2c usage */ -void i2c_init(void); - -/* schedule a send operation (uses 1 tx bd) */ -int i2c_send(unsigned char address, - unsigned char secondary_address, - unsigned short size, - unsigned char *dataout); - -/* schedule a receive operation (uses 1 tx bd, 1 rx bd) */ -int i2c_receive(unsigned char address, - unsigned char secondary_address, - unsigned short size_to_expect, - unsigned char *datain); -#endif -#if defined(CONFIG_4xx) || defined(CONFIG_IOP480) - -#define CONFIG_I2C_4XX /* 4xx I2C variant */ - -void i2c_init(void); -int i2c_receive(unsigned char address, - unsigned short size_to_expect, unsigned char datain[] ); -int i2c_send(unsigned char address, - unsigned short size_to_send, unsigned char dataout[] ); -int i2c_wr_page(uchar *addr, int alen, uchar *data, int dlen, int dsize); -#endif - -#if !defined(CONFIG_MPC824X) && !defined(CONFIG_4xx) && !defined(CONFIG_IOP480)/* !( CONFIG_4xx || CONFIG_IOP480) */ - -uchar i2c_reg_read (uchar i2c_addr, uchar reg); -void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val); - -typedef void (*i2c_ecb_t)(int, int); /* error callback function */ +/* + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * + * The implementation MUST NOT use static or global variables if the + * I2C routines are used to read SDRAM configuration information + * because this is done before the memories are initialized. Limited + * use of stack-based variables are OK (the initial stack size is + * limited). + * + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ -/* This structure keeps track of the bd and buffer space usage. */ -typedef struct i2c_state { - int rx_idx; /* index to next free Rx BD */ - int tx_idx; /* index to next free Tx BD */ - void *rxbd; /* pointer to next free Rx BD */ - void *txbd; /* pointer to next free Tx BD */ - int tx_space; /* number of Tx bytes left */ - unsigned char *tx_buf; /* pointer to free Tx area */ - i2c_ecb_t err_cb; /* error callback function */ -} i2c_state_t; +/* + * Configuration items. + */ +#define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */ -/* initialize i2c usage */ +/* + * Initialization, must be called once on start up, may be called + * repeatedly to change the speed and slave addresses. + */ void i2c_init(int speed, int slaveaddr); -/* prepare a new io sequence */ -void i2c_newio(i2c_state_t *state); - -/* schedule a send operation (uses 1 tx bd) */ -int i2c_send(i2c_state_t *state, - unsigned char address, - unsigned char secondary_address, - unsigned int flags, - unsigned short size, - unsigned char *dataout); - -/* schedule a receive operation (uses 1 tx bd, 1 rx bd) */ -int i2c_receive(i2c_state_t *state, - unsigned char address, - unsigned char secondary_address, - unsigned int flags, - unsigned short size_to_expect, - unsigned char *datain); - -/* execute all scheduled operations */ -int i2c_doio(i2c_state_t *state); - -/* flags for i2c_send() and i2c_receive() */ -#define I2CF_ENABLE_SECONDARY 0x01 /* secondary_address is valid */ -#define I2CF_START_COND 0x02 /* tx: generate start condition */ -#define I2CF_STOP_COND 0x04 /* tx: generate stop condition */ - -/* return codes */ -#define I2CERR_NO_BUFFERS 0x01 /* no more BDs or buffer space */ -#define I2CERR_MSG_TOO_LONG 0x02 /* tried to send/receive to much data */ -#define I2CERR_TIMEOUT 0x03 /* timeout in i2c_doio() */ -#define I2CERR_QUEUE_EMPTY 0x04 /* i2c_doio called without send/receive */ - -/* error callback flags */ -#define I2CECB_RX_ERR 0x10 /* this is a receive error */ -#define I2CECB_RX_ERR_OV 0x02 /* receive overrun error */ -#define I2CECB_RX_MASK 0x0f /* mask for error bits */ -#define I2CECB_TX_ERR 0x20 /* this is a transmit error */ -#define I2CECB_TX_CL 0x01 /* transmit collision error */ -#define I2CECB_TX_UN 0x02 /* transmit underflow error */ -#define I2CECB_TX_NAK 0x04 /* transmit no ack error */ -#define I2CECB_TX_MASK 0x0f /* mask for error bits */ -#define I2CECB_TIMEOUT 0x40 /* this is a timeout error */ - -#endif /* CPCI405, AR405, WALNUT405 */ - -#define ERROR_I2C_NONE 0 -#define ERROR_I2C_LENGTH 1 +/* + * Probe the given I2C chip address. Returns 0 if a chip responded, + * not 0 on failure. + */ +int i2c_probe(uchar chip); -#define I2C_WRITE_BIT 0x00 -#define I2C_READ_BIT 0x01 +/* + * Read/Write interface: + * chip: I2C chip address, range 0..127 + * addr: Memory (register) address within the chip + * alen: Number of bytes to use for addr (typically 1, 2 for larger + * memories, 0 for register type devices with only one + * register) + * buffer: Where to read/write the data + * len: How many bytes to read/write + * + * Returns: 0 on success, not 0 on failure + */ +int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len); +int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len); -#define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */ +/* + * Utility routines to read/write registers. + */ +uchar i2c_reg_read (uchar chip, uchar reg); +void i2c_reg_write(uchar chip, uchar reg, uchar val); #endif /* _I2C_H_ */ diff --git a/include/mpc8260.h b/include/mpc8260.h index 296a585..0462cad 100644 --- a/include/mpc8260.h +++ b/include/mpc8260.h @@ -647,9 +647,19 @@ /*----------------------------------------------------------------------- * MPTPR - Memory Refresh Timer Prescaler Register 10-32 + * See User's Manual Errata for the changed definition (matches the + * 8xx now). The wrong prescaler definition causes excessive refreshes + * (typically "divide by 2" when "divide by 32" is intended) which will + * cause unnecessary memory subsystem slowdown. */ -#define MPTPR_PTP_MSK 0xff00 /* Periodic Timers Prescaler Mask*/ -#define MPTPR_PTP_SHIFT 8 +#define MPTPR_PTP_MSK 0xff00 /* Periodic Timers Prescaler Mask */ +#define MPTPR_PTP_DIV2 0x2000 /* BRGCLK divided by 2 */ +#define MPTPR_PTP_DIV4 0x1000 /* BRGCLK divided by 4 */ +#define MPTPR_PTP_DIV8 0x0800 /* BRGCLK divided by 8 */ +#define MPTPR_PTP_DIV16 0x0400 /* BRGCLK divided by 16 */ +#define MPTPR_PTP_DIV32 0x0200 /* BRGCLK divided by 32 */ +#define MPTPR_PTP_DIV64 0x0100 /* BRGCLK divided by 64 */ + /*----------------------------------------------------------------------- * TGCR1/TGCR2 - Timer Global Configuration Registers 17-4 @@ -875,5 +885,13 @@ #define UPMB 2 #define UPMC 3 -#endif /* __MPC8260_H__ */ +#if !defined(__ASSEMBLY__) && defined(CONFIG_WATCHDOG) +extern __inline__ void +reset_8260_watchdog(volatile immap_t *immr) +{ + immr->im_siu_conf.sc_swsr = 0x556c; + immr->im_siu_conf.sc_swsr = 0xaa39; +} +#endif /* !__ASSEMBLY && CONFIG_WATCHDOG */ +#endif /* __MPC8260_H__ */