Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
SPARC U-Boot Custodian Tree
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
U-Boot
Custodians
SPARC U-Boot Custodian Tree
Commits
c65fdc74
Commit
c65fdc74
authored
Sep 28, 2004
by
wdenk
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* Patch by Jon Loeliger, 15 Jul 2004:
Fix MPC85xx I2C driver
parent
64f70bed
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
114 additions
and
134 deletions
+114
-134
CHANGELOG
CHANGELOG
+3
-0
cpu/mpc85xx/i2c.c
cpu/mpc85xx/i2c.c
+111
-134
No files found.
CHANGELOG
View file @
c65fdc74
...
...
@@ -2,6 +2,9 @@
Changes since U-Boot 1.1.1:
======================================================================
* Patch by Jon Loeliger, 15 Jul 2004:
Fix MPC85xx I2C driver
* Fix problems with CDROM drive as slave device on Lite5200 IDE bus.
* Patch by Stephen Williams, 15 July 2004
...
...
cpu/mpc85xx/i2c.c
View file @
c65fdc74
...
...
@@ -30,78 +30,57 @@
#include <common.h>
#include <command.h>
#define DEBUG
#if defined(DEBUG)
#define DEB(x) x
#else
#define DEB(x)
#endif
#include <asm/io.h>
#ifdef CONFIG_HARD_I2C
#include <i2c.h>
#define TIMEOUT (CFG_HZ/4)
#define I2C_Addr ((u
nsigned
*)(CFG_CCSRBAR + 0x3000))
#define I2C_Addr ((u
8
*)(CFG_CCSRBAR + 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 I2CDFSRR &I2C_Addr[
5
]
#define I2CFDR &I2C_Addr[
4
]
#define I2CCCR &I2C_Addr[
8
]
#define I2CCSR &I2C_Addr[
12
]
#define I2CCDR &I2C_Addr[
16
]
#define I2CDFSRR &I2C_Addr[
20
]
#define I2C_READ 1
#define I2C_WRITE 0
/* taken from linux include/asm-ppc/io.h */
i
nline
unsigned
in_le32
(
volatile
unsigned
*
addr
)
void
i
2c_init
(
int
speed
,
int
slaveadd
)
{
unsigned
ret
;
/* stop I2C controller */
writeb
(
0x0
,
I2CCCR
);
__asm__
__volatile__
(
"lwbrx %0,0,%1;
\n
"
"twi 0,%0,0;
\n
"
"isync"
:
"=r"
(
ret
)
:
"r"
(
addr
),
"m"
(
*
addr
));
return
ret
;
}
/* set clock */
writeb
(
0x3f
,
I2CFDR
);
inline
void
out_le32
(
volatile
unsigned
*
addr
,
int
val
)
{
__asm__
__volatile__
(
"stwbrx %1,0,%2; eieio"
:
"=m"
(
*
addr
)
:
"r"
(
val
),
"r"
(
addr
));
}
/* set default filter */
writeb
(
0x10
,
I2CDFSRR
);
#define writel(val, addr) out_le32(addr, val)
#define readl(addr) in_le32(addr)
/* write slave address */
writeb
(
slaveadd
,
I2CADR
);
void
i2c_init
(
int
speed
,
int
slaveadd
)
{
/* stop I2C controller */
writel
(
0x0
,
I2CCCR
);
/* set clock */
writel
(
0x3f
,
I2CFDR
);
/* set default filter */
writel
(
0x10
,
I2CDFSRR
);
/* write slave address */
writel
(
slaveadd
,
I2CADR
);
/* clear status register */
writel
(
0x0
,
I2CCSR
);
/* start I2C controller */
writel
(
MPC85xx_I2CCR_MEN
,
I2CCCR
);
/* clear status register */
writeb
(
0x0
,
I2CCSR
);
/* start I2C controller */
writeb
(
MPC85xx_I2CCR_MEN
,
I2CCCR
);
}
static
__inline__
int
i2c_wait4bus
(
void
)
{
ulong
timeval
=
get_timer
(
0
);
ulong
timeval
=
get_timer
(
0
);
while
(
readl
(
I2CCSR
)
&
MPC85xx_I2CSR_MBB
)
if
(
get_timer
(
timeval
)
>
TIMEOUT
)
return
-
1
;
while
(
readb
(
I2CCSR
)
&
MPC85xx_I2CSR_MBB
)
{
if
(
get_timer
(
timeval
)
>
TIMEOUT
)
{
return
-
1
;
}
}
return
0
;
}
...
...
@@ -109,153 +88,151 @@ i2c_wait4bus (void)
static
__inline__
int
i2c_wait
(
int
write
)
{
u32
csr
;
ulong
timeval
=
get_timer
(
0
);
u32
csr
;
ulong
timeval
=
get_timer
(
0
);
do
{
csr
=
readl
(
I2CCSR
);
do
{
csr
=
readb
(
I2CCSR
);
if
(
!
(
csr
&
MPC85xx_I2CSR_MIF
))
continue
;
if
(
!
(
csr
&
MPC85xx_I2CSR_MIF
))
continue
;
writel
(
0x0
,
I2CCSR
);
writeb
(
0x0
,
I2CCSR
);
if
(
csr
&
MPC85xx_I2CSR_MAL
)
{
DEB
(
printf
(
"i2c_wait: MAL
\n
"
));
return
-
1
;
}
if
(
csr
&
MPC85xx_I2CSR_MAL
)
{
debug
(
"i2c_wait: MAL
\n
"
);
return
-
1
;
}
if
(
!
(
csr
&
MPC85xx_I2CSR_MCF
))
{
DEB
(
printf
(
"i2c_wait: unfinished
\n
"
));
return
-
1
;
}
if
(
!
(
csr
&
MPC85xx_I2CSR_MCF
))
{
debug
(
"i2c_wait: unfinished
\n
"
);
return
-
1
;
}
if
(
write
==
I2C_WRITE
&&
(
csr
&
MPC85xx_I2CSR_RXAK
))
{
DEB
(
printf
(
"i2c_wait: No RXACK
\n
"
));
return
-
1
;
}
if
(
write
==
I2C_WRITE
&&
(
csr
&
MPC85xx_I2CSR_RXAK
))
{
debug
(
"i2c_wait: No RXACK
\n
"
);
return
-
1
;
}
return
0
;
}
while
(
get_timer
(
timeval
)
<
TIMEOUT
);
return
0
;
}
while
(
get_timer
(
timeval
)
<
TIMEOUT
);
DEB
(
printf
(
"i2c_wait: timed out
\n
"
)
);
return
-
1
;
debug
(
"i2c_wait: timed out
\n
"
);
return
-
1
;
}
static
__inline__
int
i2c_write_addr
(
u8
dev
,
u8
dir
,
int
rsta
)
{
writel
(
MPC85xx_I2CCR_MEN
|
MPC85xx_I2CCR_MSTA
|
MPC85xx_I2CCR_MTX
|
(
rsta
?
MPC85xx_I2CCR_RSTA
:
0
),
I2CCCR
);
writeb
(
MPC85xx_I2CCR_MEN
|
MPC85xx_I2CCR_MSTA
|
MPC85xx_I2CCR_MTX
|
(
rsta
?
MPC85xx_I2CCR_RSTA
:
0
),
I2CCCR
);
writel
((
dev
<<
1
)
|
dir
,
I2CCDR
);
writeb
((
dev
<<
1
)
|
dir
,
I2CCDR
);
if
(
i2c_wait
(
I2C_WRITE
)
<
0
)
return
0
;
if
(
i2c_wait
(
I2C_WRITE
)
<
0
)
return
0
;
return
1
;
return
1
;
}
static
__inline__
int
__i2c_write
(
u8
*
data
,
int
length
)
{
int
i
;
int
i
;
writel
(
MPC85xx_I2CCR_MEN
|
MPC85xx_I2CCR_MSTA
|
MPC85xx_I2CCR_MTX
,
I2CCCR
);
writeb
(
MPC85xx_I2CCR_MEN
|
MPC85xx_I2CCR_MSTA
|
MPC85xx_I2CCR_MTX
,
I2CCCR
);
for
(
i
=
0
;
i
<
length
;
i
++
)
{
writel
(
data
[
i
],
I2CCDR
);
for
(
i
=
0
;
i
<
length
;
i
++
)
{
writeb
(
data
[
i
],
I2CCDR
);
if
(
i2c_wait
(
I2C_WRITE
)
<
0
)
break
;
}
if
(
i2c_wait
(
I2C_WRITE
)
<
0
)
break
;
}
return
i
;
return
i
;
}
static
__inline__
int
__i2c_read
(
u8
*
data
,
int
length
)
{
int
i
;
int
i
;
writel
(
MPC85xx_I2CCR_MEN
|
MPC85xx_I2CCR_MSTA
|
((
length
==
1
)
?
MPC85xx_I2CCR_TXAK
:
0
),
I2CCCR
);
writeb
(
MPC85xx_I2CCR_MEN
|
MPC85xx_I2CCR_MSTA
|
((
length
==
1
)
?
MPC85xx_I2CCR_TXAK
:
0
),
I2CCCR
);
/* dummy read */
readl
(
I2CCDR
);
/* dummy read */
readb
(
I2CCDR
);
for
(
i
=
0
;
i
<
length
;
i
++
)
{
if
(
i2c_wait
(
I2C_READ
)
<
0
)
break
;
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
(
MPC85xx_I2CCR_MEN
|
MPC85xx_I2CCR_MSTA
|
MPC85xx_I2CCR_TXAK
,
I2CCCR
);
/* Generate ack on last next to last byte */
if
(
i
==
length
-
2
)
writeb
(
MPC85xx_I2CCR_MEN
|
MPC85xx_I2CCR_MSTA
|
MPC85xx_I2CCR_TXAK
,
I2CCCR
);
/* Generate stop on last byte */
if
(
i
==
length
-
1
)
writel
(
MPC85xx_I2CCR_MEN
|
MPC85xx_I2CCR_TXAK
,
I2CCCR
);
/* Generate stop on last byte */
if
(
i
==
length
-
1
)
writeb
(
MPC85xx_I2CCR_MEN
|
MPC85xx_I2CCR_TXAK
,
I2CCCR
);
data
[
i
]
=
readl
(
I2CCDR
);
}
data
[
i
]
=
readb
(
I2CCDR
);
}
return
i
;
return
i
;
}
int
i2c_read
(
u8
dev
,
uint
addr
,
int
alen
,
u8
*
data
,
int
length
)
{
int
i
=
0
;
u8
*
a
=
(
u8
*
)
&
addr
;
int
i
=
0
;
u8
*
a
=
(
u8
*
)
&
addr
;
if
(
i2c_wait4bus
()
<
0
)
goto
exit
;
if
(
i2c_wait4bus
()
<
0
)
goto
exit
;
if
(
i2c_write_addr
(
dev
,
I2C_WRITE
,
0
)
==
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
(
&
a
[
4
-
alen
],
alen
)
!=
alen
)
goto
exit
;
if
(
i2c_write_addr
(
dev
,
I2C_READ
,
1
)
==
0
)
goto
exit
;
if
(
i2c_write_addr
(
dev
,
I2C_READ
,
1
)
==
0
)
goto
exit
;
i
=
__i2c_read
(
data
,
length
);
i
=
__i2c_read
(
data
,
length
);
exit:
writel
(
MPC85xx_I2CCR_MEN
,
I2CCCR
);
writeb
(
MPC85xx_I2CCR_MEN
,
I2CCCR
);
return
!
(
i
==
length
);
return
!
(
i
==
length
);
}
int
i2c_write
(
u8
dev
,
uint
addr
,
int
alen
,
u8
*
data
,
int
length
)
{
int
i
=
0
;
u8
*
a
=
(
u8
*
)
&
addr
;
int
i
=
0
;
u8
*
a
=
(
u8
*
)
&
addr
;
if
(
i2c_wait4bus
()
<
0
)
goto
exit
;
if
(
i2c_wait4bus
()
<
0
)
goto
exit
;
if
(
i2c_write_addr
(
dev
,
I2C_WRITE
,
0
)
==
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
(
&
a
[
4
-
alen
],
alen
)
!=
alen
)
goto
exit
;
i
=
__i2c_write
(
data
,
length
);
i
=
__i2c_write
(
data
,
length
);
exit:
writel
(
MPC85xx_I2CCR_MEN
,
I2CCCR
);
writeb
(
MPC85xx_I2CCR_MEN
,
I2CCCR
);
return
!
(
i
==
length
);
return
!
(
i
==
length
);
}
int
i2c_probe
(
uchar
chip
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment