summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
authorwdenk <wdenk>2003-09-10 22:30:53 +0000
committerwdenk <wdenk>2003-09-10 22:30:53 +0000
commit7205e4075d8b50e4dd89fe39ed03860b23cbb704 (patch)
tree0dfa865e7087ff4ee07967a2531c91ff5645a802 /cpu
parent149dded2b178bc0fb62cb6f61b87968d914b580a (diff)
downloadu-boot-imx-7205e4075d8b50e4dd89fe39ed03860b23cbb704.zip
u-boot-imx-7205e4075d8b50e4dd89fe39ed03860b23cbb704.tar.gz
u-boot-imx-7205e4075d8b50e4dd89fe39ed03860b23cbb704.tar.bz2
* Patches by Denis Peter, 9 Sep 2003:
add FAT support for IDE, SCSI and USB * Patches by Gleb Natapov, 2 Sep 2003: - cleanup of POST code for unsupported architectures - MPC824x locks way0 of data cache for use as initial RAM; this patch unlocks it after relocation to RAM and invalidates the locked entries. * Patch by Gleb Natapov, 30 Aug 2003: new I2C driver for mpc107 bridge. Now works from flash. * Patch by Dave Ellis, 11 Aug 2003: - JFFS2: fix typo in common/cmd_jffs2.c - JFFS2: fix CFG_JFFS2_SORT_FRAGMENTS option - JFFS2: remove node version 0 warning - JFFS2: accept JFFS2 PADDING nodes - SXNI855T: add AM29LV800 support - SXNI855T: move environment from EEPROM to flash - SXNI855T: boot from JFFS2 in NOR or NAND flash * Patch by Bill Hargen, 11 Aug 2003: fixes for I2C on MPC8240 - fix i2c_write routine - fix iprobe command - eliminates use of global variables, plus dead code, cleanup.
Diffstat (limited to 'cpu')
-rw-r--r--cpu/mpc824x/Makefile6
-rw-r--r--cpu/mpc824x/drivers/i2c/Makefile84
-rw-r--r--cpu/mpc824x/drivers/i2c/Makefile_pc91
-rw-r--r--cpu/mpc824x/drivers/i2c/README104
-rw-r--r--cpu/mpc824x/drivers/i2c/i2c.c284
-rw-r--r--cpu/mpc824x/drivers/i2c/i2c.h309
-rw-r--r--cpu/mpc824x/drivers/i2c/i2c1.c1243
-rw-r--r--cpu/mpc824x/drivers/i2c/i2c2.S52
-rw-r--r--cpu/mpc824x/drivers/i2c/i2c_export.h103
-rw-r--r--cpu/mpc824x/start.S17
-rw-r--r--cpu/pxa/mmc.c31
11 files changed, 330 insertions, 1994 deletions
diff --git a/cpu/mpc824x/Makefile b/cpu/mpc824x/Makefile
index 3c00fc7..df0d64e 100644
--- a/cpu/mpc824x/Makefile
+++ b/cpu/mpc824x/Makefile
@@ -25,14 +25,14 @@ include $(TOPDIR)/config.mk
LIB = lib$(CPU).a
-START = start.S drivers/i2c/i2c2.o
+START = start.S
OBJS = traps.o cpu.o cpu_init.o interrupts.o speed.o \
- drivers/epic/epic1.o drivers/i2c/i2c1.o pci.o bedbug_603e.o
+ drivers/epic/epic1.o drivers/i2c/i2c.o pci.o bedbug_603e.o
all: .depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS) drivers/i2c/i2c2.o
+ $(AR) crv $@ $(OBJS)
bedbug_603e.c:
ln -s ../mpc8260/bedbug_603e.c bedbug_603e.c
diff --git a/cpu/mpc824x/drivers/i2c/Makefile b/cpu/mpc824x/drivers/i2c/Makefile
deleted file mode 100644
index ae1a94c..0000000
--- a/cpu/mpc824x/drivers/i2c/Makefile
+++ /dev/null
@@ -1,84 +0,0 @@
-##########################################################################
-#
-# Copyright Motorola, Inc. 1997
-# ALL RIGHTS RESERVED
-#
-# You are hereby granted a copyright license to use, modify, and
-# distribute the SOFTWARE so long as this entire notice is retained
-# without alteration in any modified and/or redistributed versions,
-# and that such modified versions are clearly identified as such.
-# No licenses are granted by implication, estoppel or otherwise under
-# any patents or trademarks of Motorola, Inc.
-#
-# The SOFTWARE is provided on an "AS IS" basis and without warranty.
-# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-# INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libi2c.a
-
-#DEBUG = -g
-DEBUG = -DI2CDBG
-LST = -Hanno -S
-OPTIM =
-CC = /risc/tools/pkgs/metaware/bin/hcppc
-CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT = -big_si -c
-ASDEBUG = -l -fm
-AS = /risc/tools/pkgs/metaware/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT = -Bbase=0 -q -Qn -r
-LKCMD =
-LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL = rm
-COPY = cp
-LIST = ls
-
-OBJECTS = i2c1.o i2c2.o
-
-all: $(TARGET)
-
-objects: $(OBJECTS)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(OBJECTS) -o $@
-
-clean:
- $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
-# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
- $(CCobj) $<
-
-.c.s:
- $(CCobj) $(LST) $<
-
-i2c1.o: i2c_export.h i2c.h i2c1.c
-
-i2c2.o: i2c.h i2c2.s
diff --git a/cpu/mpc824x/drivers/i2c/Makefile_pc b/cpu/mpc824x/drivers/i2c/Makefile_pc
deleted file mode 100644
index 4d42c7b..0000000
--- a/cpu/mpc824x/drivers/i2c/Makefile_pc
+++ /dev/null
@@ -1,91 +0,0 @@
-##########################################################################
-#
-# makefile_pc for use with PC mksnt tools dink32/drivers/i2c
-#
-# Copyright Motorola, Inc. 1997
-# ALL RIGHTS RESERVED
-#
-# You are hereby granted a copyright license to use, modify, and
-# distribute the SOFTWARE so long as this entire notice is retained
-# without alteration in any modified and/or redistributed versions,
-# and that such modified versions are clearly identified as such.
-# No licenses are granted by implication, estoppel or otherwise under
-# any patents or trademarks of Motorola, Inc.
-#
-# The SOFTWARE is provided on an "AS IS" basis and without warranty.
-# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-# INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libi2c.a
-
-#DEBUG = -g
-DEBUG = -DI2CDBG
-LST = -Hanno -S
-OPTIM =
-CC = m:/old_tools/tools/hcppc/bin/hcppc
-CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT = -big_si -c
-ASDEBUG = -l -fm
-AS = m:/old_tools/tools/hcppc/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT = -Bbase=0 -q -Qn -r
-LKCMD =
-LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL = rm
-COPY = cp
-LIST = ls
-
-OBJECTS = i2c1.o i2c2.o
-
-all: $(TARGET)
-
-objects: $(OBJECTS)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(OBJECTS) -o $@
-
-clean:
- $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
-# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
- $(CCobj) $<
-
-.c.s:
- $(CCobj) $(LST) $<
-
-i2c1.o: i2c_export.h i2c.h i2c1.c
- $(CCobj) $<
-
-
-i2c2.o: i2c.h i2c2.s
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
diff --git a/cpu/mpc824x/drivers/i2c/README b/cpu/mpc824x/drivers/i2c/README
deleted file mode 100644
index 1db7210..0000000
--- a/cpu/mpc824x/drivers/i2c/README
+++ /dev/null
@@ -1,104 +0,0 @@
-CONTENT:
-
- i2c.h
- i2c1.c
- i2c2.s
-
-WHAT ARE THESE FILES:
-
-These files contain MPC8240 (Kahlua) I2C
-driver routines. The driver routines are not
-written for any specific operating system.
-They serves the purpose of code sample, and
-jump-start for using the MPC8240 I2C unit.
-
-For the reason of correctness of C language
-syntax, these files are compiled by Metaware
-C compiler and assembler.
-
-ENDIAN NOTATION:
-
-The algorithm is designed for big-endian mode,
-software is responsible for byte swapping.
-
-USAGE:
-
-1. The host system that is running on MPC8240
- shall link the files listed here. The memory
- location of driver routines shall take into
- account of that driver routines need to run
- in supervisor mode and they process I2C
- interrupt.
-
-2. The host system is responsible for configuring
- the MPC8240 including Embedded Utilities Memory
- Block. All I2C driver functions require the
- content of Embedded Utilities Memory Block
- Base Address Register, EUMBBAR, as the first
- parameter.
-
-3. Before I2C unit of MPC8240 can be used,
- initialize I2C unit by calling I2C_Init
- with the corresponding parameters.
-
- Note that the I2CFDR register shall be written
- once during the initialization. If it is written
- in the midst of transers, or after I2C STOPs or
- REPEAT STATRs, depending on the data written,
- a long reset time may be encountered.
-
-4. After I2C unit has been successfully initialized,
- use the Application level API to send data or
- receive data upon the desired mode, Master or
- Slave.
-
-5. If the host system is also using the EPIC unit
- on MPC8240, the system can register the
- I2C_ISR with the EPIC including other
- desired resources.
-
- If the host system does not using the EPIC unit
- on MPC8240, I2C_Timer_Event function can
- be called for each desired time interval.
-
- In both cases, the host system is free to provide
- its own timer event handler and interrupt service
- routine.
-
-6. The I2C driver routines contains a set
- of utilities, Set and Get, for host system
- to query and modify the desired I2C registers.
-
-7. It is the host system's responsibility of
- queueing the I2C I/O request. The host
- system shall check the I2C_ISR return code
- for I2C I/O status. If I2C_ISR returns
- I2CBUFFEMPTY or I2CBUFFFULL, it means
- I2C unit has completed a I/O request
- stated by the Application API.
-
-8. If the host system has more than one master
- mode I2C unit I/O requests but doesn't want
- to be intervented by being addressed as slave,
- the host system can use the master mode
- Application API with stop_flag set to 0 in
- conjunction with is_cnt flag set to 1.
- The first API call sets both stop_flag and
- is_cnt to 0, indicating a START condition
- shall be generated but when the end of
- transaction is reached, do not generate a
- STOP condition. Once the host system is
- informed that the transaction has been
- completed, the next Application API call
- shall set is_cnt flag to 1, indicating a
- repeated START condition shall be generated.
- The last Application API call shall set
- stop_flag
- to 1.
-
-9. The I2C_Timer_Event function containes
- a user defined function pointer. It
- serves the purpose of providing the
- host system a way to use its own event
- handler instead of the I2C_ISR provided
- here.
diff --git a/cpu/mpc824x/drivers/i2c/i2c.c b/cpu/mpc824x/drivers/i2c/i2c.c
new file mode 100644
index 0000000..7445a1c
--- /dev/null
+++ b/cpu/mpc824x/drivers/i2c/i2c.c
@@ -0,0 +1,284 @@
+/*
+ * (C) Copyright 2003
+ * Gleb Natapov <gnatapov@mrv.com>
+ * Some bits are taken from linux driver writen by adrian@humboldt.co.uk
+ *
+ * Hardware I2C driver for MPC107 PCI bridge.
+ *
+ * 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 <common.h>
+
+#undef I2CDBG
+
+#ifdef CONFIG_HARD_I2C
+#include <i2c.h>
+
+#define TIMEOUT (CFG_HZ/4)
+
+#define I2C_Addr ((unsigned *)(CFG_EUMB_ADDR + 0x3000))
+
+#define I2CADR &I2C_Addr[0]
+#define I2CFDR &I2C_Addr[1]
+#define I2CCCR &I2C_Addr[2]
+#define I2CCSR &I2C_Addr[3]
+#define I2CCDR &I2C_Addr[4]
+
+#define MPC107_CCR_MEN 0x80
+#define MPC107_CCR_MIEN 0x40
+#define MPC107_CCR_MSTA 0x20
+#define MPC107_CCR_MTX 0x10
+#define MPC107_CCR_TXAK 0x08
+#define MPC107_CCR_RSTA 0x04
+
+#define MPC107_CSR_MCF 0x80
+#define MPC107_CSR_MAAS 0x40
+#define MPC107_CSR_MBB 0x20
+#define MPC107_CSR_MAL 0x10
+#define MPC107_CSR_SRW 0x04
+#define MPC107_CSR_MIF 0x02
+#define MPC107_CSR_RXAK 0x01
+
+#define I2C_READ 1
+#define I2C_WRITE 0
+
+/* taken from linux include/asm-ppc/io.h */
+inline unsigned in_le32 (volatile unsigned *addr)
+{
+ unsigned ret;
+
+ __asm__ __volatile__ ("lwbrx %0,0,%1;\n"
+ "twi 0,%0,0;\n"
+ "isync":"=r" (ret): "r" (addr), "m" (*addr));
+ return ret;
+}
+
+inline void out_le32 (volatile unsigned *addr, int val)
+{
+ __asm__ __volatile__ ("stwbrx %1,0,%2; eieio":"=m" (*addr):"r" (val),
+ "r" (addr));
+}
+
+#define writel(val, addr) out_le32(addr, val)
+#define readl(addr) in_le32(addr)
+
+void i2c_init (int speed, int slaveadd)
+{
+ /* stop I2C controller */
+ writel (0x0, I2CCCR);
+ /* set clock */
+ writel (0x1020, I2CFDR);
+ /* write slave address */
+ writel (slaveadd, I2CADR);
+ /* clear status register */
+ writel (0x0, I2CCSR);
+ /* start I2C controller */
+ writel (MPC107_CCR_MEN, I2CCCR);
+
+ return;
+}
+
+static __inline__ int i2c_wait4bus (void)
+{
+ ulong timeval = get_timer (0);
+
+ while (readl (I2CCSR) & MPC107_CSR_MBB)
+ if (get_timer (timeval) > TIMEOUT)
+ return -1;
+
+ return 0;
+}
+
+static __inline__ int i2c_wait (int write)
+{
+ u32 csr;
+ ulong timeval = get_timer (0);
+
+ do {
+ csr = readl (I2CCSR);
+
+ if (!(csr & MPC107_CSR_MIF))
+ continue;
+
+ writel (0x0, I2CCSR);
+
+ if (csr & MPC107_CSR_MAL) {
+#ifdef I2CDBG
+ printf ("i2c_wait: MAL\n");
+#endif
+ return -1;
+ }
+
+ if (!(csr & MPC107_CSR_MCF)) {
+#ifdef I2CDBG
+ printf ("i2c_wait: unfinished\n");
+#endif
+ return -1;
+ }
+
+ if (write == I2C_WRITE && (csr & MPC107_CSR_RXAK)) {
+#ifdef I2CDBG
+ printf ("i2c_wait: No RXACK\n");
+#endif
+ return -1;
+ }
+
+ return 0;
+ } while (get_timer (timeval) < TIMEOUT);
+
+#ifdef I2CDBG
+ printf ("i2c_wait: timed out\n");
+#endif
+ return -1;
+}
+
+static __inline__ int i2c_write_addr (u8 dev, u8 dir, int rsta)
+{
+ writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_MTX |
+ (rsta ? MPC107_CCR_RSTA : 0), I2CCCR);
+
+ writel ((dev << 1) | dir, I2CCDR);
+
+ if (i2c_wait (I2C_WRITE) < 0)
+ return 0;
+
+ return 1;
+}
+
+static __inline__ int __i2c_write (u8 * data, int length)
+{
+ int i;
+
+ writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_MTX, I2CCCR);
+
+ for (i = 0; i < length; i++) {
+ writel (data[i], I2CCDR);
+
+ if (i2c_wait (I2C_WRITE) < 0)
+ break;
+ }
+
+ return i;
+}
+
+static __inline__ int __i2c_read (u8 * data, int length)
+{
+ int i;
+
+ writel (MPC107_CCR_MEN | MPC107_CCR_MSTA |
+ ((length == 1) ? MPC107_CCR_TXAK : 0), I2CCCR);
+
+ /* dummy read */
+ readl (I2CCDR);
+
+ for (i = 0; i < length; i++) {
+ if (i2c_wait (I2C_READ) < 0)
+ break;
+
+ /* Generate ack on last next to last byte */
+ if (i == length - 2)
+ writel (MPC107_CCR_MEN | MPC107_CCR_MSTA |
+ MPC107_CCR_TXAK, I2CCCR);
+
+ /* Generate stop on last byte */
+ if (i == length - 1)
+ writel (MPC107_CCR_MEN | MPC107_CCR_TXAK, I2CCCR);
+
+ data[i] = readl (I2CCDR);
+ }
+
+ return i;
+}
+
+int i2c_read (u8 dev, uint addr, int alen, u8 * data, int length)
+{
+ int i = 0;
+ u8 *a = (u8 *) & addr;
+
+ if (i2c_wait4bus () < 0)
+ goto exit;
+
+ if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
+ goto exit;
+
+ if (__i2c_write (&a[4 - alen], alen) != alen)
+ goto exit;
+
+ if (i2c_write_addr (dev, I2C_READ, 1) == 0)
+ goto exit;
+
+ i = __i2c_read (data, length);
+
+exit:
+ writel (MPC107_CCR_MEN, I2CCCR);
+
+ return !(i == length);
+}
+
+int i2c_write (u8 dev, uint addr, int alen, u8 * data, int length)
+{
+ int i = 0;
+ u8 *a = (u8 *) & addr;
+
+ if (i2c_wait4bus () < 0)
+ goto exit;
+
+ if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
+ goto exit;
+
+ if (__i2c_write (&a[4 - alen], alen) != alen)
+ goto exit;
+
+ i = __i2c_write (data, length);
+
+exit:
+ writel (MPC107_CCR_MEN, I2CCCR);
+
+ return !(i == length);
+}
+
+int i2c_probe (uchar chip)
+{
+ int tmp;
+
+ /*
+ * Try to read the first location of the chip. The underlying
+ * driver doesn't appear to support sending just the chip address
+ * and looking for an <ACK> back.
+ */
+ udelay (10000);
+ return i2c_read (chip, 0, 1, (char *) &tmp, 1);
+}
+
+uchar i2c_reg_read (uchar i2c_addr, uchar reg)
+{
+ char buf[1];
+
+ i2c_read (i2c_addr, reg, 1, buf, 1);
+
+ return (buf[0]);
+}
+
+void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
+{
+ i2c_write (i2c_addr, reg, 1, &val, 1);
+}
+
+#endif /* CONFIG_HARD_I2C */
diff --git a/cpu/mpc824x/drivers/i2c/i2c.h b/cpu/mpc824x/drivers/i2c/i2c.h
deleted file mode 100644
index 48a401d..0000000
--- a/cpu/mpc824x/drivers/i2c/i2c.h
+++ /dev/null
@@ -1,309 +0,0 @@
-#ifndef I2C_H
-#define I2C_H
-
-/****************************************************
- *
- * Copyright Motrola 1999
- *
- ****************************************************/
-#define get_eumbbar() CFG_EUMB_ADDR
-
-#define I2CADR 0x00003000
-#define I2CFDR 0x00003004
-#define I2CCR 0x00003008
-#define I2CSR 0x0000300C
-#define I2CDR 0x00003010
-
-typedef enum _i2cstatus
-{
- I2CSUCCESS = 0x3000,
- I2CADDRESS,
- I2CERROR,
- I2CBUFFFULL,
- I2CBUFFEMPTY,
- I2CXMITERROR,
- I2CRCVERROR,
- I2CBUSBUSY,
- I2CALOSS,
- I2CNOEVENT,
-} I2CStatus;
-
-typedef enum i2c_control
-{
- MEN = 0x00000080,
- MIEN = 0x00000040,
- MSTA = 0x00000020,
- MTX = 0x00000010,
- TXAK = 0x00000008,
- RSTA = 0x00000004,
-} I2C_CONTROL;
-
-typedef enum i2c_status
-{
- MCF = 0x00000080,
- MAAS = 0x00000040,
- MBB = 0x00000020,
- MAL = 0x00000010,
- SRW = 0x00000004,
- MIF = 0x00000002,
- RXAK = 0x00000001,
-} I2C_STATUS;
-
-typedef struct _i2c_ctrl
-{
- unsigned int reserved0 : 24;
- unsigned int men : 1;
- unsigned int mien : 1;
- unsigned int msta : 1;
- unsigned int mtx : 1;
- unsigned int txak : 1;
- unsigned int rsta : 1;
- unsigned int reserved1 : 2;
-} I2C_CTRL;
-
-typedef struct _i2c_stat
-{
- unsigned int rsrv0 : 24;
- unsigned int mcf : 1;
- unsigned int maas : 1;
- unsigned int mbb : 1;
- unsigned int mal : 1;
- unsigned int rsrv1 : 1;
- unsigned int srw : 1;
- unsigned int mif : 1;
- unsigned int rxak : 1;
-} I2C_STAT;
-
-typedef enum _i2c_mode
-{
- RCV = 0,
- XMIT = 1,
-} I2C_MODE;
-
-/******************** App. API ********************
- * The application API is for user level application
- * to use the funcitonality provided by I2C driver
- *
- * Note: Its App.s responsibility to swap the data
- * byte. In our API, we just transfer whatever
- * we are given
- **************************************************/
-/**
- * Note:
- *
- * In all following functions,
- * the caller shall pass the configured embedded utility memory
- * block base, EUMBBAR.
- **/
-
-/* Send a buffer of data to the intended rcv_addr.
- * If stop_flag is set, after the whole buffer
- * is sent, generate a STOP signal provided that the
- * receiver doesn't signal the STOP in the middle.
- * I2C is the master performing transmitting. If
- * no STOP signal is generated at the end of current
- * transaction, the master can generate a START signal
- * to another slave addr.
- *
- * return I2CSUCCESS if no error.
- */
-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
- */
-
-/* Receive a buffer of data from the desired sender_addr
- * If stop_flag is set, when the buffer is full and the
- * sender does not signal STOP, generate a STOP signal.
- * I2C is the master performing receiving. If no STOP signal
- * is generated, the master can generate a START signal
- * to another slave addr.
- *
- * return I2CSUCCESS if no error.
- */
-static I2CStatus I2C_get( unsigned int eumbbar,
- unsigned char sender_addr, /* 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 0 /* the I2C_write and I2C_read functions are not active */
-/* Send a buffer of data to the requiring master.
- * If stop_flag is set, after the whole buffer is sent,
- * generate a STOP signal provided that the requiring
- * receiver doesn't signal the STOP in the middle.
- * I2C is the slave performing transmitting.
- *
- * return I2CSUCCESS if no error.
- *
- * Note: due to the Kahlua design, slave transmitter
- * shall not signal STOP since there is no way
- * for master to detect it, causing I2C bus hung.
- *
- * For the above reason, the stop_flag is always
- * set, i.e., 1.
- *
- * programmer shall use the timer on Kahlua to
- * 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
- */
-
- /* Receive a buffer of data from the sending master.
- * If stop_flag is set, when the buffer is full and the
- * sender does not signal STOP, generate a STOP signal.
- * I2C is the slave performing receiving.
- *
- * return I2CSUCCESS if no error.
- */
-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
- */
-#endif /* of if0 for turning off I2C_read & I2C_write */
-
-/* if interrupt is not used, this is the timer event handler.
- * After each fixed time interval, this function can be called
- * 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 ) );
-
-/********************* Kernel API ************************
- * Kernel APIs are functions I2C driver provides to the
- * O.S.
- *********************************************************/
-
-/******************* device I/O function ***************/
-
-/* Generate a START signal in the desired mode.
- * I2C is the master.
- *
- * return I2CSUCCESS if no error.
- * I2CERROR if i2c unit is not enabled.
- * I2CBUSBUSY if bus cannot be granted
- */
-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, check MBB
- */
-
-/* Generate a STOP signal to terminate the transaction. */
-static I2CStatus I2C_Stop( unsigned int eumbbar );
-
-/* Do a one-byte master transmit.
- *
- * return I2CBUFFEMPTY if this is the last byte.
- * Otherwise return I2CSUCCESS
- */
-static I2CStatus I2C_Master_Xmit( unsigned int eumbbar );
-
-/* Do a one-byte master receive.
- *
- * return I2CBUFFFULL if this is the last byte.
- * Otherwise return I2CSUCCESS
- */
-static I2CStatus I2C_Master_Rcv( unsigned int eumbbar );
-
-/* Do a one-byte slave transmit.
- *
- * return I2CBUFFEMPTY if this is the last byte.
- * Otherwise return I2CSUCCESS
- *
- */
-static I2CStatus I2C_Slave_Xmit( unsigned int eumbbar );
-
-/* Do a one-byte slave receive.
- *
- * return I2CBUFFFULL if this is the last byte.
- * Otherwise return I2CSUCCESS
- */
-static I2CStatus I2C_Slave_Rcv( unsigned int eumbbar );
-
-/* Process slave address phase.
- *
- * return I2CADDRESS if this is slave receiver's address phase
- * Otherwise return the result of slave xmit one byte.
- */
-static I2CStatus I2C_Slave_Addr( unsigned int eumbbar );
-
-/******************* Device Control Fucntion ****************/
-/* Initialize I2C unit with desired frequency divider,
- * driver's slave address w/o interrupt enabled.
- *
- * This function must be called before I2C unit can
- * be used.
- */
-static I2CStatus I2C_Init( unsigned int eumbbar,
- unsigned char fdr, /* frequency divider */
- unsigned char addr, /* driver's address used for receiving */
- unsigned int en_int); /* 1 - enable I2C interrupt
- * 0 - disable I2C interrup
- */
-
-/* I2C interrupt service routine.
- *
- * return I2CADDRESS if it is receiver's (either master or slave) address phase.
- * return the result of xmit or receive one byte
- */
-static I2CStatus I2C_ISR(unsigned int eumbbar );
-
-/* Set I2C Status, i.e., write to I2CSR */
-static void I2C_Set_Stat( unsigned int eumbbar, I2C_STAT stat );
-
-/* Query I2C Status, i.e., read I2CSR */
-static I2C_STAT I2C_Get_Stat( unsigned int eumbbar );
-
-/* Change I2C Control bits, i.e., write to I2CCR */
-static void I2C_Set_Ctrl( unsigned int eumbbar, I2C_CTRL ); /* new control value */
-
-/* Query I2C Control bits, i.e., read I2CCR */
-static I2C_CTRL I2C_Get_Ctrl( unsigned int eumbbar );
-
-/* This function performs the work for I2C_do_transaction. The work is
- * split into this function to enable I2C_do_transaction to first transmit
- * the data address to the I2C slave device without putting the data address
- * into the first byte of the buffer.
- *
- * en_int controls interrupt/polling mode
- * act is the type of transaction
- * i2c_addr is the I2C address of the slave device
- * len is the length of data to send or receive
- * buffer is the address of the data buffer
- * stop = I2C_NO_STOP, don't signal STOP at end of transaction
- * I2C_STOP, signal STOP at end of transaction
- * retry is the timeout retry value, currently ignored
- * 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);
-#endif
diff --git a/cpu/mpc824x/drivers/i2c/i2c1.c b/cpu/mpc824x/drivers/i2c/i2c1.c
deleted file mode 100644
index 94c671e..0000000
--- a/cpu/mpc824x/drivers/i2c/i2c1.c
+++ /dev/null
@@ -1,1243 +0,0 @@
-/*************************************************************
- *
- * Copyright @ Motorola, 1999
- *
- ************************************************************/
-#include <common.h>
-
-#ifdef CONFIG_HARD_I2C
-#include <i2c.h>
-#include "i2c_export.h"
-#include "i2c.h"
-
-#undef I2CDBG0
-#undef DEBUG
-
-/* Define a macro to use an optional application-layer print function, if
- * one was passed to the I2C library during initialization. If there was
- * no function pointer passed, this protects against calling it. Also define
- * the global variable that holds the passed pointer.
- */
-#define TIMEOUT (CFG_HZ/4)
-#define PRINT if ( app_print ) app_print
-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 ByteToRcv = 0;
-static unsigned int RcvByte = 0;
-static unsigned char *RcvBuf = 0;
-static unsigned int RcvBufFulStop = 0;
-static unsigned int MasterRcvAddress = 0;
-
-/* Set by call to get_eumbbar during I2C_Initialize.
- * This could be globally available to the I2C library, but there is
- * an advantage to passing it as a parameter: it is already in a register
- * and doesn't have to be loaded from memory. Also, that is the way the
- * I2C library was already implemented and I don't want to change it without
- * a more detailed analysis.
- * It is being set as a global variable in I2C_Initialize to hide it from
- * the DINK application layer, because it is Kahlua-specific. I think that
- * get_eumbbar, load_runtime_reg, and store_runtime_reg should be defined in
- * a Kahlua-specific library dealing with the embedded utilities memory block.
- * Right now, get_eumbbar is defined in dink32/kahlua.s. The other two are
- * defined in dink32/drivers/i2c/i2c2.s.
- */
-static unsigned int Global_eumbbar = 0;
-
-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);
-
-/************************** API *****************/
-
-/* Application Program Interface (API) are the calls provided by the I2C
- * library to upper layer applications (i.e., DINK) to access the Kahlua
- * I2C bus interface. The functions and values that are part of this API
- * are declared in i2c_export.h.
- */
-
-/* Initialize I2C unit with the following:
- * driver's slave address
- * interrupt enabled
- * optional pointer to application layer print function
- *
- * These parameters may be added:
- * desired clock rate
- * digital filter frequency sampling rate
- *
- * 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 *, ...))
-{
- 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;
-}
-
-
-/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
- * are implemented. Both are only in polling mode.
- *
- * en_int controls interrupt/polling mode
- * act is the type of transaction
- * i2c_addr is the I2C address of the slave device
- * data_addr is the address of the data on the slave device
- * len is the length of data to send or receive
- * buffer is the address of the data buffer
- * stop = I2C_NO_STOP, don't signal STOP at end of transaction
- * I2C_STOP, signal STOP at end of transaction
- * retry is the timeout retry value, currently ignored
- * 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 status;
- unsigned char data_addr_buffer[1];
-
-#if 1
-/* This is a temporary work-around. The I2C library breaks the protocol
- * if it attempts to handle a data transmission in more than one
- * transaction, so the data address and the actual data bytes are put
- * into a single buffer before sending it to the library internal functions.
- * The problem is related to being able to restart a transaction without
- * sending the I2C device address or repeating the data address. It may take
- * a day or two to sort it all out, so I'll have to get back to it later.
- * Look at I2C_Start to see about using some status flags (I'm not sure that
- * "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;
-}
-
-/* This function performs the work for I2C_do_transaction. The work is
- * split into this function to enable I2C_do_transaction to first transmit
- * the data address to the I2C slave device without putting the data address
- * into the first byte of the buffer.
- *
- * en_int controls interrupt/polling mode
- * act is the type of transaction
- * i2c_addr is the I2C address of the slave device
- * len is the length of data to send or receive
- * buffer is the address of the data buffer
- * stop = I2C_NO_STOP, don't signal STOP at end of transaction
- * I2C_STOP, signal STOP at end of transaction
- * retry is the timeout retry value, currently ignored
- * 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)
-{
- 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:
- *
- * In all following functions,
- * the caller shall pass the configured embedded utility memory
- * block base, EUMBBAR.
- **/
-
-/***********************************************************
- * function: I2C_put
- *
- * description:
- Send a buffer of data to the intended rcv_addr.
- * If stop_flag is set, after the whole buffer
- * is sent, generate a STOP signal provided that the
- * receiver doesn't signal the STOP in the middle.
- * I2C is the master performing transmitting. If
- * no STOP signal is generated at the end of current
- * transaction, the master can generate a START signal
- * to another slave addr.
- *
- * 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;
- }
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_put\n", __FILE__, __LINE__);
-#endif
-
- XmitByte = 0;
- ByteToXmit = length;
- XmitBuf = buffer_ptr;
- XmitBufEmptyStop = stop_flag;
-
- RcvByte = 0;
- ByteToRcv = 0;
- RcvBuf = 0;
-
- /* we are the master, start transaction */
- return I2C_Start (eumbbar, rcv_addr, XMIT, is_cnt);
-}
-
-/***********************************************************
- * function: I2C_get
- *
- * description:
- * Receive a buffer of data from the desired sender_addr
- * If stop_flag is set, when the buffer is full and the
- * sender does not signal STOP, generate a STOP signal.
- * I2C is the master performing receiving. If no STOP signal
- * is generated, the master can generate a START signal
- * to another slave addr.
- *
- * 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;
- }
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_get\n", __FILE__, __LINE__);
-#endif
-
- RcvByte = 0;
- ByteToRcv = length;
- RcvBuf = buffer_ptr;
- RcvBufFulStop = stop_flag;
-
- XmitByte = 0;
- ByteToXmit = 0;
- XmitBuf = 0;
-
- /* we are the master, start the transaction */
- return I2C_Start (eumbbar, rcv_from, RCV, is_cnt);
-
-}
-
-#if 0 /* turn off dead code */
-/*********************************************************
- * function: I2C_write
- *
- * description:
- * Send a buffer of data to the requiring master.
- * If stop_flag is set, after the whole buffer is sent,
- * generate a STOP signal provided that the requiring
- * receiver doesn't signal the STOP in the middle.
- * I2C is the slave performing transmitting.
- *
- * Note: this is slave xmit API.
- *
- * due to the current Kahlua design, slave transmitter
- * shall not signal STOP since there is no way
- * for master to detect it, causing I2C bus hung.
- *
- * For the above reason, the stop_flag is always
- * set, i.e., 0.
- *
- * programmer shall use the timer on Kahlua to
- * 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 ); */
-}
-
-/******************************************************
- * function: I2C_read
- *
- * description:
- * Receive a buffer of data from the sending master.
- * If stop_flag is set, when the buffer is full and the
- * sender does not signal STOP, generate a STOP signal.
- * I2C is the slave performing receiving.
- *
- * 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 ); */
-}
-#endif /* turn off dead code */
-
-/*********************************************************
- * function: I2c_Timer_Event
- *
- * description:
- * if interrupt is not used, this is the timer event handler.
- * After each fixed time interval, this function can be called
- * 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))
-{
- I2C_STAT stat;
-
-#ifdef I2CDBG0
- 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;
-}
-
-
-/****************** Device I/O function *****************/
-
-/******************************************************
- * function: I2C_Start
- *
- * description: Generate a START signal in the desired mode.
- * I2C is the master.
- *
- * Return I2CSUCCESS if no error.
- *
- * 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;
-
-#ifdef I2CDBG0
- 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;
- } else {
- MasterRcvAddress = 0;
- }
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_Start exit\n", __FILE__, __LINE__);
-#endif
-
- /* wait for the interrupt or poll */
- return I2CSUCCESS;
-}
-
-/***********************************************************
- * function: I2c_Stop
- *
- * description: Generate a STOP signal to terminate the master
- * transaction.
- * return I2CSUCCESS
- *
- **********************************************************/
-static I2CStatus I2C_Stop (unsigned int eumbbar)
-{
- I2C_CTRL ctrl;
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_Stop enter\n", __FILE__, __LINE__);
-#endif
-
- ctrl = I2C_Get_Ctrl (eumbbar);
- ctrl.msta = 0;
- I2C_Set_Ctrl (eumbbar, ctrl);
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_Stop exit\n", __FILE__, __LINE__);
-#endif
-
- return I2CSUCCESS;
-}
-
-/****************************************************
- * function: I2C_Master_Xmit
- *
- * description: Master sends one byte of data to
- * slave target
- *
- * return I2CSUCCESS if the byte transmitted.
- * Otherwise no-zero
- *
- * Note: condition must meet when this function is called:
- * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && I2CSR(RXAK) == 0
- * I2CCR(MSTA) == 1 && I2CCR(MTX) == 1
- *
- ***************************************************/
-static I2CStatus I2C_Master_Xmit (unsigned int eumbbar)
-{
- unsigned int val;
-
- if (ByteToXmit > 0) {
-
- if (ByteToXmit == XmitByte) {
- /* all xmitted */
- ByteToXmit = 0;
-
- if (XmitBufEmptyStop == 1) {
- I2C_Stop (eumbbar);
- }
-
- return I2CBUFFEMPTY;
-
- }
-#ifdef I2CDBG0
- PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__,
- *(XmitBuf + XmitByte));
-#endif
-
- val = *(XmitBuf + XmitByte);
- val &= 0x000000ff;
- store_runtime_reg (eumbbar, I2CDR, val);
- XmitByte++;
-
- return I2CSUCCESS;
-
- }
-
- return I2CBUFFEMPTY;
-}
-
-/***********************************************
- * function: I2C_Master_Rcv
- *
- * description: master reads one byte data
- * from slave source
- *
- * return I2CSUCCESS if no error
- *
- * Note: condition must meet when this function is called:
- * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&
- * I2CCR(MSTA) == 1 && I2CCR(MTX) == 0
- *
- ***********************************************/
-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;
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__,
- *(RcvBuf + RcvByte));
-#endif
-
- RcvByte++;
-
- if (ByteToRcv == RcvByte) {
- ByteToRcv = 0;
-
- return I2CBUFFFULL;
- }
-
- return I2CSUCCESS;
- }
-
- return I2CBUFFFULL;
-
-}
-
-/****************************************************
- * function: I2C_Slave_Xmit
- *
- * description: Slave sends one byte of data to
- * requesting destination
- *
- * return SUCCESS if the byte transmitted. Otherwise
- * No-zero
- *
- * Note: condition must meet when this function is called:
- * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && I2CSR(RXAK) = 0
- * I2CCR(MSTA) == 0 && I2CCR(MTX) == 1
- *
- ***************************************************/
-static I2CStatus I2C_Slave_Xmit (unsigned int eumbbar)
-{
- unsigned int val;
-
- if (ByteToXmit > 0) {
-
- if (ByteToXmit == XmitByte) {
- /* no more data to send */
- 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
- */
-
- return I2CBUFFEMPTY;
- }
-#ifdef I2CDBG
- PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__,
- *(XmitBuf + XmitByte));
-#endif
-
- val = *(XmitBuf + XmitByte);
- val &= 0x000000ff;
- store_runtime_reg (eumbbar, I2CDR, val);
- XmitByte++;
-
- return I2CSUCCESS;
- }
-
- return I2CBUFFEMPTY;
-}
-
-/***********************************************
- * function: I2C_Slave_Rcv
- *
- * description: slave reads one byte data
- * from master source
- *
- * return I2CSUCCESS if no error otherwise non-zero
- *
- * Note: condition must meet when this function is called:
- * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&
- * I2CCR(MSTA) == 0 && I2CCR(MTX) = 0
- *
- ***********************************************/
-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;
-#ifdef I2CDBG
- 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;
-}
-
-/****************** Device Control Function *************/
-
-/*********************************************************
- * function: I2C_Init
- *
- * description: Initialize I2C unit with desired frequency divider,
- * master's listening address, with interrupt enabled
- * or disabled.
- *
- * 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;
-
-#ifdef I2CDBG0
- 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);
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_Init exit\n", __FILE__, __LINE__);
-#endif
-
- return I2CSUCCESS;
-
-}
-
-/*****************************************
- * function I2c_Get_Stat
- *
- * description: Query I2C Status, i.e., read I2CSR
- *
- ****************************************/
-static I2C_STAT I2C_Get_Stat (unsigned int eumbbar)
-{
- unsigned int temp;
- I2C_STAT stat;
-
- temp = load_runtime_reg (eumbbar, I2CSR);
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): get stat = 0x%08x\n", __FILE__, __LINE__, temp);
-#endif
-
- 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;
-}
-
-/*********************************************
- * function: I2c_Set_Ctrl
- *
- * description: Change I2C Control bits,
- * 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);
-#ifdef I2CDBG0
- PRINT ("%s(%d): set ctrl = 0x%08x\n", __FILE__, __LINE__, temp);
-#endif
- store_runtime_reg (eumbbar, I2CCR, temp);
-
-}
-
-/*****************************************
- * function: I2C_Get_Ctrl
- *
- * description: Query I2C Control bits,
- * i.e., read I2CCR
- *****************************************/
-static I2C_CTRL I2C_Get_Ctrl (unsigned int eumbbar)
-{
- 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);
-#endif
-
- return s.ctrl;
-}
-
-
-/****************************************
- * function: I2C_Slave_Addr
- *
- * description: Process slave address phase.
- * return I2CSUCCESS if no error
- *
- * note: Precondition for calling this function:
- * I2CSR(MIF) == 1 &&
- * I2CSR(MAAS) == 1
- ****************************************/
-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;
-}
-
-/***********************************************
- * function: I2C_ISR
- *
- * description: I2C Interrupt service routine
- *
- * note: Precondition:
- * I2CSR(MIF) == 1
- **********************************************/
-static I2CStatus I2C_ISR (unsigned int eumbbar)
-{
- I2C_STAT stat;
- I2C_CTRL ctrl;
-
-#ifdef I2CDBG0
- 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;
-
- }
-
- /* 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;
- }
-
- /* 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);
- }
-
- /* master has not acknowledged, wait for STOP */
- /* do nothing for preventing bus from hung */
- return I2CSUCCESS;
- }
-
- /* slave rcv */
- return I2C_Slave_Rcv (eumbbar);
-
- } else if (stat.maas == 1) {
- /* received a call from master */
-
- /* 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);
-
- ctrl.msta = 0; /* return to receive mode */
- I2C_Set_Ctrl (eumbbar, ctrl);
- }
-
- return I2CSUCCESS;
-
-}
-
-/******************************************************
- * function: I2C_Set_Stat
- *
- * description: modify the I2CSR
- *
- *****************************************************/
-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);
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): set stat = 0x%08x\n", __FILE__, __LINE__, s.val);
-#endif
-
- store_runtime_reg (eumbbar, I2CSR, s.val);
-
-}
-
-/******************************************************
- * The following are routines to glue the rest of
- * U-Boot to the Sandpoint I2C driver.
- *****************************************************/
-
-void i2c_init (int speed, int slaveadd)
-{
-#ifdef CFG_I2C_INIT_BOARD
- /*
- * call board specific i2c bus reset routine before accessing the
- * environment, which might be in a chip on that bus. For details
- * about this problem see doc/I2C_Edge_Conditions.
- */
- i2c_init_board();
-#endif
-
-#ifdef DEBUG
- I2C_Initialize (0x7f, 0, (void *) printf);
-#else
- I2C_Initialize (0x7f, 0, 0);
-#endif
-}
-
-int i2c_probe (uchar chip)
-{
- int tmp;
-
- /*
- * Try to read the first location of the chip. The underlying
- * driver doesn't appear to support sending just the chip address
- * and looking for an <ACK> back.
- */
- udelay(10000);
- return i2c_read (chip, 0, 1, (char *)&tmp, 1);
-}
-
-int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
- I2CStatus status;
- uchar xaddr[4];
-
- if (alen > 0) {
- 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_read: 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, chip, len,
- buffer, I2C_STOP, 1, (alen > 0 ? I2C_RESTART :
- I2C_NO_RESTART));
-
- if (status != I2C_SUCCESS) {
- PRINT ("i2c_read: can't perform data transfer\n");
- return 1;
- }
-
- return 0;
-}
-
-int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
- I2CStatus status;
- uchar dummy_buffer[I2C_RXTX_LEN + 2];
- uchar *p;
- int i;
-
- /* fill in address in big endian order */
- for (i=alen-1; i>=0; --i) {
- buffer[i] = addr & 0xFF;
- addr >>= 8;
- }
- /* fill in data */
- p = dummy_buffer + alen;
-
- for (i=0; i<len; ++i)
- *p++ = *buffer++;
-
- status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen + len,
- dummy_buffer, I2C_STOP, 1, I2C_NO_RESTART);
-
-#ifdef CFG_EEPROM_PAGE_WRITE_DELAY_MS
- udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
-#endif
- if (status != I2C_SUCCESS) {
- PRINT ("i2c_write: can't perform data transfer\n");
- return 1;
- }
-
- return 0;
-}
-
-uchar i2c_reg_read (uchar i2c_addr, uchar reg)
-{
- char buf[1];
-
- i2c_init (0, 0);
-
- i2c_read (i2c_addr, reg, 1, buf, 1);
-
- return (buf[0]);
-}
-
-void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
-{
- i2c_init (0, 0);
-
- i2c_write (i2c_addr, reg, 1, &val, 1);
-}
-
-#endif /* CONFIG_HARD_I2C */
diff --git a/cpu/mpc824x/drivers/i2c/i2c2.S b/cpu/mpc824x/drivers/i2c/i2c2.S
deleted file mode 100644
index 3fd7e03..0000000
--- a/cpu/mpc824x/drivers/i2c/i2c2.S
+++ /dev/null
@@ -1,52 +0,0 @@
-/**************************************
- *
- * copyright @ Motorola, 1999
- *
- **************************************/
-
-#include <config.h>
-#ifdef CONFIG_HARD_I2C
-#include <ppc_asm.tmpl>
-#include <asm/mmu.h>
-/**********************************************************
- * function: load_runtime_reg
- *
- * input: r3 - value of eumbbar
- * r4 - register offset in embedded utility space
- *
- * output: r3 - register content
- **********************************************************/
- .text
- .align 2
- .global load_runtime_reg
-load_runtime_reg:
-
-/* xor r5,r5,r5
- * or r5,r5,r3
- *
- * lwbrx r3,r4,r5
- */
- lwbrx r3,r4,r3
- sync
-
- bclr 20, 0
-
-/****************************************************************
- * function: store_runtime_reg
- *
- * input: r3 - value of eumbbar
- * r4 - register offset in embedded utility space
- * r5 - new value to be stored
- *
- ****************************************************************/
- .text
- .align 2
- .global store_runtime_reg
-store_runtime_reg:
-
- stwbrx r5, r4, r3
- sync
-
- bclr 20,0
-
-#endif /* CONFIG_HARD_I2C */
diff --git a/cpu/mpc824x/drivers/i2c/i2c_export.h b/cpu/mpc824x/drivers/i2c/i2c_export.h
deleted file mode 100644
index 6264d18..0000000
--- a/cpu/mpc824x/drivers/i2c/i2c_export.h
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef I2C_EXPORT_H
-#define I2C_EXPORT_H
-
-/****************************************************
- *
- * Copyright Motrola 1999
- *
- ****************************************************/
-
-/* These are the defined return values for the I2C_do_transaction function.
- * Any non-zero value indicates failure. Failure modes can be added for
- * more detailed error reporting.
- */
-typedef enum _i2c_status
-{
- I2C_SUCCESS = 0,
- I2C_ERROR,
-} I2C_Status;
-
-/* These are the defined tasks for I2C_do_transaction.
- * Modes for SLAVE_RCV and SLAVE_XMIT will be added.
- */
-typedef enum _i2c_transaction_mode
-{
- I2C_MASTER_RCV = 0,
- I2C_MASTER_XMIT = 1,
-} I2C_TRANSACTION_MODE;
-
-typedef enum _i2c_interrupt_mode
-{
- I2C_INT_DISABLE = 0,
- I2C_INT_ENABLE = 1,
-} I2C_INTERRUPT_MODE;
-
-typedef enum _i2c_stop
-{
- I2C_NO_STOP = 0,
- I2C_STOP = 1,
-} I2C_STOP_MODE;
-
-typedef enum _i2c_restart
-{
- I2C_NO_RESTART = 0,
- I2C_RESTART = 1,
-} I2C_RESTART_MODE;
-
-/******************** App. API ********************
- * The application API is for user level application
- * to use the functionality provided by I2C driver.
- * This is a "generic" I2C interface, it should contain
- * nothing specific to the Kahlua implementation.
- * Only the generic functions are exported by the library.
- *
- * Note: Its App.s responsibility to swap the data
- * byte. In our API, we just transfer whatever
- * we are given
- **************************************************/
-
-
-/* Initialize I2C unit with the following:
- * driver's slave address
- * interrupt enabled
- * optional pointer to application layer print function
- *
- * These parameters may be added:
- * desired clock rate
- * digital filter frequency sampling rate
- *
- * This function must be called before I2C unit can be used.
- */
-extern I2C_Status I2C_Initialize(
- unsigned char addr, /* driver's I2C slave address */
- I2C_INTERRUPT_MODE en_int, /* 1 - enable I2C interrupt
- * 0 - disable I2C interrupt
- */
- int (*app_print_function)(char *,...)); /* pointer to optional "printf"
- * provided by application
- */
-
-/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
- * are implemented. Both are only in polling mode.
- *
- * en_int controls interrupt/polling mode
- * act is the type of transaction
- * addr is the I2C address of the slave device
- * len is the length of data to send or receive
- * buffer is the address of the data buffer
- * stop = I2C_NO_STOP, don't signal STOP at end of transaction
- * I2C_STOP, signal STOP at end of transaction
- * retry is the timeout retry value, currently ignored
- * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
- * I2C_RESTART, this is a continuation of existing transaction
- */
-extern 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);
-#endif
diff --git a/cpu/mpc824x/start.S b/cpu/mpc824x/start.S
index a22137c..9ff052c 100644
--- a/cpu/mpc824x/start.S
+++ b/cpu/mpc824x/start.S
@@ -526,11 +526,26 @@ relocate_code:
stwu r0,-4(r7)
bdnz 3b
+4:
+#if !defined(CONFIG_BMW)
+/* Unlock the data cache and invalidate locked area */
+ xor r0, r0, r0
+ mtspr 1011, r0
+ lis r4, CFG_INIT_RAM_ADDR@h
+ ori r4, r4, CFG_INIT_RAM_ADDR@l
+ li r0, 128
+ mtctr r0
+41:
+ dcbi r0, r4
+ addi r4, r4, 32
+ bdnz 41b
+#endif
+
/*
* Now flush the cache: note that we must start from a cache aligned
* address. Otherwise we might miss one cache line.
*/
-4: cmpwi r6,0
+ cmpwi r6,0
add r5,r3,r5
beq 7f /* Always flush prefetch queue in any case */
subi r0,r6,1
diff --git a/cpu/pxa/mmc.c b/cpu/pxa/mmc.c
index 9e6e1e3..4363a5f 100644
--- a/cpu/pxa/mmc.c
+++ b/cpu/pxa/mmc.c
@@ -26,11 +26,19 @@
#include <mmc.h>
#include <asm/errno.h>
#include <asm/arch/hardware.h>
+#include <part.h>
#ifdef CONFIG_MMC
extern int
-fat_register_read(int(*block_read)(int device, ulong blknr, ulong blkcnt, uchar *buffer));
+fat_register_device(block_dev_desc_t *dev_desc, int part_no);
+
+static block_dev_desc_t mmc_dev;
+
+block_dev_desc_t * mmc_get_dev(int dev)
+{
+ return ((block_dev_desc_t *)&mmc_dev);
+}
/*
* FIXME needs to read cid and csd info to determine block size
@@ -379,9 +387,9 @@ mmc_write(uchar *src, ulong dst, int size)
return 0;
}
-int
+ulong
/****************************************************/
-mmc_bread(int dev_num, ulong blknr, ulong blkcnt, uchar *dst)
+mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst)
/****************************************************/
{
int mmc_block_size = MMC_BLOCK_SIZE;
@@ -441,6 +449,21 @@ mmc_init(int verbose)
printf("Month = %d\n",cid->month);
printf("Year = %d\n",1997 + cid->year);
}
+ /* fill in device description */
+ mmc_dev.if_type = IF_TYPE_MMC;
+ mmc_dev.dev = 0;
+ mmc_dev.lun = 0;
+ mmc_dev.type = 0;
+ /* FIXME fill in the correct size (is set to 32MByte) */
+ mmc_dev.blksz = 512;
+ mmc_dev.lba = 0x10000;
+ sprintf(mmc_dev.vendor,"Man %02x%02x%02x Snr %02x%02x%02x",
+ cid->id[0], cid->id[1], cid->id[2],
+ cid->sn[0], cid->sn[1], cid->sn[2]);
+ sprintf(mmc_dev.product,"%s",cid->name);
+ sprintf(mmc_dev.revision,"%x %x",cid->hwrev, cid->fwrev);
+ mmc_dev.removable = 0;
+ mmc_dev.block_read = mmc_bread;
/* MMC exists, get CSD too */
resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
@@ -458,7 +481,7 @@ mmc_init(int verbose)
MMC_CLKRT = 0; /* 20 MHz */
resp = mmc_cmd(7, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
- fat_register_read(mmc_bread);
+ fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
return rc;
}