* 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.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
284
cpu/mpc824x/drivers/i2c/i2c.c
Normal file
284
cpu/mpc824x/drivers/i2c/i2c.c
Normal file
@@ -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 */
|
||||
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user