+
+ 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
BAB7xx MPC740/MPC750
+Erik Theisen <etheisen@mindspring.com>
+
+ W7OLMC PPC4xx
+ W7OLMG PPC4xx
+
-------------------------------------------------------------------------
Unknown / orphaned boards:
MIP405 PPC4xx
OCRTC PPC4xx
PIP405 PPC4xx
- W7OLMC PPC4xx
- W7OLMG PPC4xx
WALNUT405 PPC4xx
MOUSSE MPC824x
{
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;;) {
#include <ppcboot.h>
#include "L1.h"
#include <asm/processor.h>
-#include <405gp_i2c.h>
+#include <i2c.h>
#include <command.h>
#include <cmd_nvedit.h>
#include <cmd_bootm.h>
*/
#include <ppcboot.h>
+#include <i2c.h>
#include "eric.h"
#include <asm/processor.h>
long int initdram (int board_type)
{
#ifndef CONFIG_ERIC
- unsigned char dataout[1];
int i;
unsigned char datain[128];
int TotalSize;
#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++)
#include <ppcboot.h>
#include "canbt.h"
#include <asm/processor.h>
-#include <405gp_i2c.h>
#include <command.h>
#include <cmd_boot.h>
#include <ppcboot.h>
#include "cpci405.h"
#include <asm/processor.h>
-#include <405gp_i2c.h>
#include <command.h>
#include <cmd_boot.h>
#include <ppcboot.h>
#include "cpciiser4.h"
#include <asm/processor.h>
-#include <405gp_i2c.h>
#include <command.h>
#include <cmd_boot.h>
#include <ppcboot.h>
#include "ocrtc.h"
#include <asm/processor.h>
-#include <405gp_i2c.h>
+#include <i2c.h>
#include <command.h>
#include <cmd_boot.h>
/* 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"));
{
power = 2<<n; /* power = 2^(n+1) */
freq = tclk/(10*(m+1)*power);
- if (i2cFreq > freq)
- margin = i2cFreq - freq;
+ if (speed > freq)
+ margin = speed - freq;
else
- margin = freq - i2cFreq;
+ margin = freq - speed;
if(margin < minMargin)
{
minMargin = margin;
int ten_bit)
{
uchar status = 0;
+ unsigned int i2cFreq = 400000;
DP(puts("i2c_read\n"));
- i2c_init();
+ i2c_init(i2cFreq,0);
status = i2c_start();
return status;
}
- i2c_init();
+ i2c_init(i2cFreq,0);
status = i2c_start();
if (status) {
#include <ppcboot.h>
#include <command.h>
#include <net.h>
+#include <i2c.h>
#include <asm/iopin_8260.h>
#include <cmd_bsp.h>
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 ... */
}
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;
}
void
board_postclk_init(void)
{
- i2c_state_t state;
-
i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
/*
* 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));
}
/* ------------------------------------------------------------------------- */
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)
{
/* 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;
/* 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;
/* 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);
/* 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<KEYBD_DATALEN; ++i) {
sprintf(keybd_env+i+i, "%02X", kbd_data[i]);
/* 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);
puts ("Keys:");
for (i=0; i<KEYBD_DATALEN; ++i) {
#include <ppcboot.h>
#include "pip405.h"
#include <asm/processor.h>
-#include <405gp_i2c.h>
+#include <i2c.h>
#include <devices.h>
#include "../common/isa.h"
#include "../common/video.h"
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
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;
+ }
}
/* ------------------------------------------------------------------------- */
* Check Board Identity:
*/
-int checkboard(void)
+int checkboard (void)
{
struct tm timedate;
unsigned int ppctemp, prottemp;
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;
}
* 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;
/*
* 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;
}
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;
}
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;
}
/* ------------------------------------------------------------------------- */
* 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");
}
/* 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 */
/* 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 */
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;
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)
#if (CONFIG_COMMANDS & CFG_CMD_DOC)
void doc_init (void);
#endif
+#if defined(CONFIG_HARD_I2C) || \
+ defined(CONFIG_SOFT_I2C)
+#include <i2c.h>
+#endif
static char *failed = "*** failed ***\n";
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();
/* 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
/* ------------------------------------------------------------------------- */
#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;
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];
/* 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;
}
*/
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);
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;
i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
# endif
#endif
-#if defined(CONFIG_MPC824X) && defined(CONFIG_I2C)
- i2c_init ();
-#endif
-
}
/*-----------------------------------------------------------------------
*/
/*
- * (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.
* 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 <ppcboot.h>
#include <command.h>
-#include <i2c.h>
#include <cmd_i2c.h>
+#include <i2c.h>
-#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<linebytes; j++) {
+ printf(" %02x", *cp++);
+ addr++;
+ }
+ printf(" ");
+ cp = linebuf;
+ for (j=0; j<linebytes; j++) {
+ if ((*cp < 0x20) || (*cp > 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) {
+ /*
+ * <CR> 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 */
#if (CONFIG_COMMANDS & CFG_CMD_NET)
#include <net.h>
#endif
+#if defined(CFG_ENV_IS_IN_EEPROM)
+#include <i2c.h>
+#endif
#ifdef CONFIG_SHOW_BOOT_PROGRESS
# include <status_led.h>
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,
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];
}
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 */
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;
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;
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);
}
/* 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);
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);
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;
volatile immap_t *immap;
volatile pcmconf8xx_t *pcmp;
u_long reg;
- uchar addr, val;
+ uchar val;
PCMCIA_DEBUG ("voltage_set: " \
PCMCIA_BOARD_MSG \
* 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) {
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");
#include <cmd_pcmcia.h>
#include <cmd_autoscript.h>
-#include <cmd_eeprom.h>
#include <cmd_i2c.h>
#include <cmd_immap.h>
#include <cmd_rtc.h>
CMD_TBL_DOC
CMD_TBL_DTT
CMD_TBL_ECHO
- CMD_TBL_EEPROM
CMD_TBL_FCCINFO
CMD_TBL_FLERASE
CMD_TBL_FDC
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
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);
--- /dev/null
+/*
+ *(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 <ppcboot.h>
+#include <ioports.h>
+#include <i2c.h>
+
+#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
+ * <stop> 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 <ACK>(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 <ACK>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 <ACK>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 */
+
*/
#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;
*/
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 *****************/
*
* 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;
}
* 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
* "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
* 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;
}
/**
*
* 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);
}
/***********************************************************
*
* 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
*
* 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 ); */
}
/******************************************************
*
* 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
* 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;
}
*
* 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;
}
/***********************************************************
* 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;
}
/****************************************************
* 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;
}
/***********************************************
* 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;
}
* 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;
}
/***********************************************
* 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 *************/
*
* 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;
}
* 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;
}
/*********************************************
* 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);
}
* 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;
}
* 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;
}
/***********************************************
* 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;
}
* 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;i<len;i++)dummy_buffer[i+n]=buffer[i];
- status = I2C_do_buffer(0, I2C_MASTER_XMIT, addr[0], n + len,
+ status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, n + len,
dummy_buffer, I2C_STOP, 1, I2C_NO_RESTART);
- if (status != I2C_SUCCESS)
- {
- PRINT( "I2C_do_transaction: can't perform data transfer\n");
+ if (status != I2C_SUCCESS) {
+ PRINT ("I2C_do_transaction: can't perform data transfer\n");
return 1;
}
return 0;
}
-uchar
-i2c_reg_read(uchar i2c_addr, uchar reg)
+uchar i2c_reg_read (uchar i2c_addr, uchar reg)
{
- char addr[2];
char buf[1];
- i2c_init();
+ i2c_init (0, 0);
- addr[0] = i2c_addr;
- addr[1] = reg;
-
- i2c_read(addr, 2, buf, 1);
+ i2c_read (i2c_addr, reg, 1, buf, 1);
return (buf[0]);
}
-void
-i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
+void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
{
- char addr[2];
-
- i2c_init();
-
- addr[0] = i2c_addr;
- addr[1] = reg;
+ i2c_init (0, 0);
- i2c_write(addr, 2, &val, 1);
+ i2c_write (i2c_addr, reg, 1, &val, 1);
}
#endif /* CONFIG_I2C */
START = start.o kgdb.o
OBJS = traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \
- interrupts.o ether_scc.o ether_fcc.o i2c.o commproc.o soft_i2c.o \
+ interrupts.o ether_scc.o ether_fcc.o i2c.o commproc.o \
bedbug_603e.o
all: .depend $(START) $(LIB)
__asm__ __volatile__ ("eieio");
} while ((immr->im_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
}
#include <ppcboot.h>
-#ifdef CONFIG_I2C
+#if defined(CONFIG_HARD_I2C)
#include <asm/cpm_8260.h>
#include <i2c.h>
/* 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
/*-----------------------------------------------------------------------
*/
-/* 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
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;
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
* 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;
i2c->i2c_i2cmr = 0x00;
}
+static
void i2c_newio(i2c_state_t *state)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR ;
memset((char *)state->tx_buf, 0, MAX_TX_SPACE);
}
+static
int i2c_send(i2c_state_t *state,
unsigned char address,
unsigned char secondary_address,
return 0;
}
+static
int i2c_receive(i2c_state_t *state,
unsigned char address,
unsigned char secondary_address,
}
+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"));
/* 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");
}
}
- 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;
}
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;
}
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 */
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)
#include <ppcboot.h>
-#ifdef CONFIG_I2C
+#ifdef CONFIG_HARD_I2C
#include <commproc.h>
#include <i2c.h>
#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
{
#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
* 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;
i2c->i2c_i2cmr = 0x00;
}
-void
+static void
i2c_newio(i2c_state_t *state)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR ;
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,
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;
}
-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;
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);
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);
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 */
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 */
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 (" <INTERRUPT> \n");
- } else {
- printf ("i2c_send error: rc=%d\n", rc);
- }
- return;
- }
- rc = i2c_doio(&state);
- if (rc != 0) {
- if (rc < 0) {
- printf (" <INTERRUPT> \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
+++ /dev/null
-/*
- * (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 <ppcboot.h>
-#include <asm/processor.h>
-#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 */
#include <405gp_i2c.h>
#include <i2c.h>
+#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.
/* __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 <ACK>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 */
#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
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__ */
/* Serial Peripheral Interface.
*/
-typedef struct spi {
+typedef struct im_spi {
ushort spi_spmode;
char res1[4];
u_char spi_spie;
char res3[2];
u_char spi_spcom;
char res4[82];
-} spi_t;
+} im_spi_t;
/* CPM Mux.
*/
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 */
/*
* 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 */
/*
- * (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.
* 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 <ppcboot.h>
-#include <command.h>
+#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 */
#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 */
#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 */
#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
*/
#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
* ---------------------------------------------------------------- */
#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
#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) */
#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
#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 */
/*-----------------------------------------------------------------------
* 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
*/
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 <cmd_confdefs.h>
/*-----------------------------------------------------------------------
* 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
*/
#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 */
#endif
#endif
-#undef CONFIG_I2C /* To enable I2C support for nvram */
-
#define CONFIG_BAUDRATE 115200
#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
* 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
#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
#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 */
/*#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 */
#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 */
#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 */
#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
#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() */
#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
#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
* 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)
#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
#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 */
#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 */
* 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
/**************************************************************
"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
/*
#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
#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)
*/
# 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
#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 */
#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 */
#undef USE_DINK32
#endif
-#define CONFIG_BAUDRATE 9600
+#define CONFIG_BAUDRATE 115200
#define CONFIG_DRAM_SPEED 100 /* MHz */
#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
"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
#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 <cmd_confdefs.h>
#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
/*-----------------------------------------------------------------------
* 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
#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
*-----------------------------------------------------------------------
* 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
#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)
# 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
CFG_CMD_ELF | \
CFG_CMD_ASKENV | \
CFG_CMD_ECHO | \
- CFG_CMD_I2C | \
CFG_CMD_REGINFO | \
CFG_CMD_IMMAP | \
CFG_CMD_MII)
#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
/*-----------------------------------------------------------------------
/* 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
/* 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 */
/*
#ifdef DEBUG
#define CFG_PSRT 39
-#define CFG_MPTPR ((12<<MPTPR_PTP_SHIFT)&MPTPR_PTP_MSK)
+#define CFG_MPTPR MPTPR_PTP_DIV8
#else
#define CFG_PSRT 31
-#define CFG_MPTPR ((32<<MPTPR_PTP_SHIFT)&MPTPR_PTP_MSK)
+#define CFG_MPTPR MPTPR_PTP_DIV32
#endif
/*
#undef CONFIG_STATUS_LED /* Status LED 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 */
# define CFG_I2C_SPEED 50000
# define CFG_I2C_SLAVE 0xFE
-# define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Atmel 24C164 has 16 byte */
- /* page write mode using last */
- /* 4 bits of the address */
+/*
+ * 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 /* 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
#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
#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
* ---------------------------------------------------------------- */
#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 | \
#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
#define CFG_PSRT 0x0e
-#define CFG_MPTPR ( (0x32 << MPTPR_PTP_SHIFT) & MPTPR_PTP_MSK)
+#define CFG_MPTPR MPTPR_PTP_DIV32
/*-----------------------------------------------------------------------
#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 */
*****************************************************************************/
/* 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
* 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
* 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.
#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
CFG_CMD_ASKENV | \
CFG_CMD_ECHO | \
CFG_CMD_I2C | \
+ CFG_CMD_SDRAM | \
CFG_CMD_REGINFO | \
CFG_CMD_IMMAP | \
CFG_CMD_MII )
CFG_CMD_ASKENV | \
CFG_CMD_ECHO | \
CFG_CMD_I2C | \
+ CFG_CMD_SDRAM | \
CFG_CMD_REGINFO | \
CFG_CMD_IMMAP )
#endif /* CONFIG_ETHER_ON_FCC */
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
*-----------------------------------------------------------------------
*/
+/* 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),
#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),
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
/*
-** 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_ */
/*-----------------------------------------------------------------------
* 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
#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__ */