Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
b7633517
U
U-Boot.Mirror
项目概览
OS
/
U-Boot.Mirror
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
U-Boot.Mirror
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b7633517
编写于
10月 20, 2010
作者:
W
Wolfgang Denk
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.denx.de/u-boot-i2c
上级
d9d47d18
fbad3555
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
117 addition
and
92 deletion
+117
-92
drivers/i2c/omap24xx_i2c.c
drivers/i2c/omap24xx_i2c.c
+117
-92
未找到文件。
drivers/i2c/omap24xx_i2c.c
浏览文件 @
b7633517
...
...
@@ -27,7 +27,7 @@
#include "omap24xx_i2c.h"
#define I2C_TIMEOUT 10
#define I2C_TIMEOUT 10
00
static
void
wait_for_bb
(
void
);
static
u16
wait_for_pin
(
void
);
...
...
@@ -159,58 +159,56 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
/* no stop bit needed here */
writew
(
I2C_CON_EN
|
I2C_CON_MST
|
I2C_CON_STT
|
I2C_CON_TRX
,
&
i2c_base
->
con
);
status
=
wait_for_pin
();
if
(
status
&
I2C_STAT_XRDY
)
{
/* Important: have to use byte access */
writeb
(
regoffset
,
&
i2c_base
->
data
);
udelay
(
20000
);
if
(
readw
(
&
i2c_base
->
stat
)
&
I2C_STAT_NACK
)
{
/* send register offset */
while
(
1
)
{
status
=
wait_for_pin
();
if
(
status
==
0
||
status
&
I2C_STAT_NACK
)
{
i2c_error
=
1
;
goto
read_exit
;
}
if
(
status
&
I2C_STAT_XRDY
)
{
/* Important: have to use byte access */
writeb
(
regoffset
,
&
i2c_base
->
data
);
writew
(
I2C_STAT_XRDY
,
&
i2c_base
->
stat
);
}
if
(
status
&
I2C_STAT_ARDY
)
{
writew
(
I2C_STAT_ARDY
,
&
i2c_base
->
stat
);
break
;
}
}
else
{
i2c_error
=
1
;
}
if
(
!
i2c_error
)
{
writew
(
I2C_CON_EN
,
&
i2c_base
->
con
);
while
(
readw
(
&
i2c_base
->
stat
)
&
(
I2C_STAT_XRDY
|
I2C_STAT_ARDY
))
{
udelay
(
10000
);
/* Have to clear pending interrupt to clear I2C_STAT */
writew
(
0xFFFF
,
&
i2c_base
->
stat
);
/* set slave address */
writew
(
devaddr
,
&
i2c_base
->
sa
);
/* read one byte from slave */
writew
(
1
,
&
i2c_base
->
cnt
);
/* need stop bit here */
writew
(
I2C_CON_EN
|
I2C_CON_MST
|
I2C_CON_STT
|
I2C_CON_STP
,
&
i2c_base
->
con
);
/* receive data */
while
(
1
)
{
status
=
wait_for_pin
();
if
(
status
==
0
||
status
&
I2C_STAT_NACK
)
{
i2c_error
=
1
;
goto
read_exit
;
}
/* set slave address */
writew
(
devaddr
,
&
i2c_base
->
sa
);
/* read one byte from slave */
writew
(
1
,
&
i2c_base
->
cnt
);
/* need stop bit here */
writew
(
I2C_CON_EN
|
I2C_CON_MST
|
I2C_CON_STT
|
I2C_CON_STP
,
&
i2c_base
->
con
);
status
=
wait_for_pin
();
if
(
status
&
I2C_STAT_RRDY
)
{
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
defined(CONFIG_OMAP44XX)
*
value
=
readb
(
&
i2c_base
->
data
);
*
value
=
readb
(
&
i2c_base
->
data
);
#else
*
value
=
readw
(
&
i2c_base
->
data
);
*
value
=
readw
(
&
i2c_base
->
data
);
#endif
udelay
(
20000
);
}
else
{
i2c_error
=
1
;
writew
(
I2C_STAT_RRDY
,
&
i2c_base
->
stat
);
}
if
(
!
i2c_error
)
{
writew
(
I2C_CON_EN
,
&
i2c_base
->
con
);
while
(
readw
(
&
i2c_base
->
stat
)
&
(
I2C_STAT_RRDY
|
I2C_STAT_ARDY
))
{
udelay
(
10000
);
writew
(
0xFFFF
,
&
i2c_base
->
stat
);
}
if
(
status
&
I2C_STAT_ARDY
)
{
writew
(
I2C_STAT_ARDY
,
&
i2c_base
->
stat
);
break
;
}
}
read_exit:
flush_fifo
();
writew
(
0xFFFF
,
&
i2c_base
->
stat
);
writew
(
0
,
&
i2c_base
->
cnt
);
...
...
@@ -220,7 +218,7 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
static
int
i2c_write_byte
(
u8
devaddr
,
u8
regoffset
,
u8
value
)
{
int
i2c_error
=
0
;
u16
status
,
stat
;
u16
status
;
/* wait until bus not busy */
wait_for_bb
();
...
...
@@ -233,49 +231,55 @@ static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
writew
(
I2C_CON_EN
|
I2C_CON_MST
|
I2C_CON_STT
|
I2C_CON_TRX
|
I2C_CON_STP
,
&
i2c_base
->
con
);
/* wait until state change */
status
=
wait_for_pin
();
if
(
status
&
I2C_STAT_XRDY
)
{
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
defined(CONFIG_OMAP44XX)
/* send out 1 byte */
writeb
(
regoffset
,
&
i2c_base
->
data
);
writew
(
I2C_STAT_XRDY
,
&
i2c_base
->
stat
);
status
=
wait_for_pin
();
if
((
status
&
I2C_STAT_XRDY
))
{
/* send out next 1 byte */
writeb
(
value
,
&
i2c_base
->
data
);
writew
(
I2C_STAT_XRDY
,
&
i2c_base
->
stat
);
}
else
{
while
(
1
)
{
status
=
wait_for_pin
();
if
(
status
==
0
||
status
&
I2C_STAT_NACK
)
{
i2c_error
=
1
;
goto
write_exit
;
}
if
(
status
&
I2C_STAT_XRDY
)
{
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
defined(CONFIG_OMAP44XX)
/* send register offset */
writeb
(
regoffset
,
&
i2c_base
->
data
);
writew
(
I2C_STAT_XRDY
,
&
i2c_base
->
stat
);
while
(
1
)
{
status
=
wait_for_pin
();
if
(
status
==
0
||
status
&
I2C_STAT_NACK
)
{
i2c_error
=
1
;
goto
write_exit
;
}
if
(
status
&
I2C_STAT_XRDY
)
{
/* send data */
writeb
(
value
,
&
i2c_base
->
data
);
writew
(
I2C_STAT_XRDY
,
&
i2c_base
->
stat
);
}
if
(
status
&
I2C_STAT_ARDY
)
{
writew
(
I2C_STAT_ARDY
,
&
i2c_base
->
stat
);
break
;
}
}
break
;
#else
/* send out two bytes */
writew
((
value
<<
8
)
+
regoffset
,
&
i2c_base
->
data
);
/* send out two bytes */
writew
((
value
<<
8
)
+
regoffset
,
&
i2c_base
->
data
);
writew
(
I2C_STAT_XRDY
,
&
i2c_base
->
stat
);
#endif
/* must have enough delay to allow BB bit to go low */
udelay
(
50000
);
if
(
readw
(
&
i2c_base
->
stat
)
&
I2C_STAT_NACK
)
{
i2c_error
=
1
;
}
}
else
{
i2c_error
=
1
;
if
(
status
&
I2C_STAT_ARDY
)
{
writew
(
I2C_STAT_ARDY
,
&
i2c_base
->
stat
);
break
;
}
}
if
(
!
i2c_error
)
{
int
eout
=
200
;
wait_for_bb
();
writew
(
I2C_CON_EN
,
&
i2c_base
->
con
);
while
((
stat
=
readw
(
&
i2c_base
->
stat
))
||
(
readw
(
&
i2c_base
->
con
)
&
I2C_CON_MST
))
{
udelay
(
1000
);
/* have to read to clear intrrupt */
writew
(
0xFFFF
,
&
i2c_base
->
stat
);
if
(
--
eout
==
0
)
/* better leave with error than hang */
break
;
}
}
status
=
readw
(
&
i2c_base
->
stat
);
if
(
status
&
I2C_STAT_NACK
)
i2c_error
=
1
;
write_exit:
flush_fifo
();
writew
(
0xFFFF
,
&
i2c_base
->
stat
);
writew
(
0
,
&
i2c_base
->
cnt
);
...
...
@@ -306,6 +310,7 @@ static void flush_fifo(void)
int
i2c_probe
(
uchar
chip
)
{
u16
status
;
int
res
=
1
;
/* default = fail */
if
(
chip
==
readw
(
&
i2c_base
->
oa
))
{
...
...
@@ -321,19 +326,37 @@ int i2c_probe (uchar chip)
writew
(
chip
,
&
i2c_base
->
sa
);
/* stop bit needed here */
writew
(
I2C_CON_EN
|
I2C_CON_MST
|
I2C_CON_STT
|
I2C_CON_STP
,
&
i2c_base
->
con
);
/* enough delay for the NACK bit set */
udelay
(
50000
);
if
(
!
(
readw
(
&
i2c_base
->
stat
)
&
I2C_STAT_NACK
))
{
res
=
0
;
/* success case */
flush_fifo
();
writew
(
0xFFFF
,
&
i2c_base
->
stat
);
}
else
{
writew
(
0xFFFF
,
&
i2c_base
->
stat
);
/* failue, clear sources*/
writew
(
readw
(
&
i2c_base
->
con
)
|
I2C_CON_STP
,
&
i2c_base
->
con
);
/* finish up xfer */
udelay
(
20000
);
wait_for_bb
();
while
(
1
)
{
status
=
wait_for_pin
();
if
(
status
==
0
)
{
res
=
1
;
goto
probe_exit
;
}
if
(
status
&
I2C_STAT_NACK
)
{
res
=
1
;
writew
(
0xff
,
&
i2c_base
->
stat
);
writew
(
readw
(
&
i2c_base
->
con
)
|
I2C_CON_STP
,
&
i2c_base
->
con
);
wait_for_bb
();
break
;
}
if
(
status
&
I2C_STAT_ARDY
)
{
writew
(
I2C_STAT_ARDY
,
&
i2c_base
->
stat
);
break
;
}
if
(
status
&
I2C_STAT_RRDY
)
{
res
=
0
;
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
defined(CONFIG_OMAP44XX)
readb
(
&
i2c_base
->
data
);
#else
readw
(
&
i2c_base
->
data
);
#endif
writew
(
I2C_STAT_RRDY
,
&
i2c_base
->
stat
);
}
}
probe_exit:
flush_fifo
();
writew
(
0
,
&
i2c_base
->
cnt
);
/* don't allow any more data in...we don't want it.*/
writew
(
0xFFFF
,
&
i2c_base
->
stat
);
...
...
@@ -392,13 +415,13 @@ int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
static
void
wait_for_bb
(
void
)
{
int
timeout
=
10
;
int
timeout
=
I2C_TIMEOUT
;
u16
stat
;
writew
(
0xFFFF
,
&
i2c_base
->
stat
);
/* clear current interruts...*/
while
((
stat
=
readw
(
&
i2c_base
->
stat
)
&
I2C_STAT_BB
)
&&
timeout
--
)
{
writew
(
stat
,
&
i2c_base
->
stat
);
udelay
(
50
000
);
udelay
(
1
000
);
}
if
(
timeout
<=
0
)
{
...
...
@@ -411,7 +434,7 @@ static void wait_for_bb (void)
static
u16
wait_for_pin
(
void
)
{
u16
status
;
int
timeout
=
10
;
int
timeout
=
I2C_TIMEOUT
;
do
{
udelay
(
1000
);
...
...
@@ -424,8 +447,10 @@ static u16 wait_for_pin (void)
if
(
timeout
<=
0
)
{
printf
(
"timed out in wait_for_pin: I2C_STAT=%x
\n
"
,
readw
(
&
i2c_base
->
stat
));
writew
(
0xFFFF
,
&
i2c_base
->
stat
);
}
writew
(
0xFFFF
,
&
i2c_base
->
stat
);
status
=
0
;
}
return
status
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录