Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
ea0211b6
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,发现更多精彩内容 >>
提交
ea0211b6
编写于
2月 06, 2018
作者:
T
Tom Rini
浏览文件
操作
浏览文件
下载
差异文件
Merge
git://git.denx.de/u-boot-i2c
上级
a43aebee
8bcf12cc
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
311 addition
and
104 deletion
+311
-104
drivers/i2c/Kconfig
drivers/i2c/Kconfig
+6
-0
drivers/i2c/fsl_i2c.c
drivers/i2c/fsl_i2c.c
+62
-65
drivers/i2c/ihs_i2c.c
drivers/i2c/ihs_i2c.c
+241
-38
drivers/i2c/mvtwsi.c
drivers/i2c/mvtwsi.c
+2
-1
未找到文件。
drivers/i2c/Kconfig
浏览文件 @
ea0211b6
...
...
@@ -268,6 +268,12 @@ config SYS_I2C_BUS_MAX
help
Define the maximum number of available I2C buses.
config SYS_I2C_IHS
bool "gdsys IHS I2C driver"
depends on DM_I2C
help
Support for gdsys IHS I2C driver on FPGA bus.
source "drivers/i2c/muxes/Kconfig"
endmenu
drivers/i2c/fsl_i2c.c
浏览文件 @
ea0211b6
...
...
@@ -116,10 +116,10 @@ static const struct {
*
* The return value is the actual bus speed that is set.
*/
static
u
nsigned
int
set_i2c_bus_speed
(
const
struct
fsl_i2c_base
*
base
,
unsigned
int
i2c_clk
,
unsigned
int
speed
)
static
uint
set_i2c_bus_speed
(
const
struct
fsl_i2c_base
*
base
,
uint
i2c_clk
,
u
int
speed
)
{
u
nsigned
short
divider
=
min
(
i2c_clk
/
speed
,
(
unsigned
int
)
USHRT_MAX
);
u
short
divider
=
min
(
i2c_clk
/
speed
,
(
u
int
)
USHRT_MAX
);
/*
* We want to choose an FDR/DFSR that generates an I2C bus speed that
...
...
@@ -130,8 +130,8 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c_base *base,
#ifdef __PPC__
u8
dfsr
,
fdr
=
0x31
;
/* Default if no FDR found */
/* a, b and dfsr matches identifiers A,B and C respectively in AN2919 */
u
nsigned
short
a
,
b
,
ga
,
gb
;
u
nsigned
long
c_div
,
est_div
;
ushort
a
,
b
,
ga
,
gb
;
ulong
c_div
,
est_div
;
#ifdef CONFIG_FSL_I2C_CUSTOM_DFSR
dfsr
=
CONFIG_FSL_I2C_CUSTOM_DFSR
;
...
...
@@ -151,18 +151,21 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c_base *base,
for
(
ga
=
0x4
,
a
=
10
;
a
<=
30
;
ga
++
,
a
+=
2
)
{
for
(
gb
=
0
;
gb
<
8
;
gb
++
)
{
b
=
16
<<
gb
;
c_div
=
b
*
(
a
+
((
3
*
dfsr
)
/
b
)
*
2
);
if
(
(
c_div
>
divider
)
&&
(
c_div
<
est_div
)
)
{
u
nsigned
short
bin_gb
,
bin_ga
;
c_div
=
b
*
(
a
+
((
3
*
dfsr
)
/
b
)
*
2
);
if
(
c_div
>
divider
&&
c_div
<
est_div
)
{
ushort
bin_gb
,
bin_ga
;
est_div
=
c_div
;
bin_gb
=
gb
<<
2
;
bin_ga
=
(
ga
&
0x3
)
|
((
ga
&
0x4
)
<<
3
);
fdr
=
bin_gb
|
bin_ga
;
speed
=
i2c_clk
/
est_div
;
debug
(
"FDR:0x%.2x, div:%ld, ga:0x%x, gb:0x%x, "
"a:%d, b:%d, speed:%d
\n
"
,
fdr
,
est_div
,
ga
,
gb
,
a
,
b
,
speed
);
debug
(
"FDR: 0x%.2x, "
,
fdr
);
debug
(
"div: %ld, "
,
est_div
);
debug
(
"ga: 0x%x, gb: 0x%x, "
,
ga
,
gb
);
debug
(
"a: %d, b: %d, speed: %d
\n
"
,
a
,
b
,
speed
);
/* Condition 2 not accounted for */
debug
(
"Tr <= %d ns
\n
"
,
(
b
-
3
*
dfsr
)
*
1000000
/
...
...
@@ -174,13 +177,13 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c_base *base,
if
(
a
==
24
)
a
+=
4
;
}
debug
(
"divider:
%d, est_div:%ld, DFSR:
%d
\n
"
,
divider
,
est_div
,
dfsr
);
debug
(
"FDR:
0x%.2x, speed:
%d
\n
"
,
fdr
,
speed
);
debug
(
"divider:
%d, est_div: %ld, DFSR:
%d
\n
"
,
divider
,
est_div
,
dfsr
);
debug
(
"FDR:
0x%.2x, speed:
%d
\n
"
,
fdr
,
speed
);
#endif
writeb
(
dfsr
,
&
base
->
dfsrr
);
/* set default filter */
writeb
(
fdr
,
&
base
->
fdr
);
/* set bus speed */
#else
u
nsigned
int
i
;
uint
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
fsl_i2c_speed_map
);
i
++
)
if
(
fsl_i2c_speed_map
[
i
].
divider
>=
divider
)
{
...
...
@@ -197,7 +200,7 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c_base *base,
}
#ifndef CONFIG_DM_I2C
static
u
nsigned
int
get_i2c_clock
(
int
bus
)
static
uint
get_i2c_clock
(
int
bus
)
{
if
(
bus
)
return
gd
->
arch
.
i2c2_clk
;
/* I2C2 clock */
...
...
@@ -211,10 +214,11 @@ static int fsl_i2c_fixup(const struct fsl_i2c_base *base)
const
unsigned
long
long
timeout
=
usec2ticks
(
CONFIG_I2C_MBB_TIMEOUT
);
unsigned
long
long
timeval
=
0
;
int
ret
=
-
1
;
u
nsigned
int
flags
=
0
;
uint
flags
=
0
;
#ifdef CONFIG_SYS_FSL_ERRATUM_I2C_A004447
unsigned
int
svr
=
get_svr
();
uint
svr
=
get_svr
();
if
((
SVR_SOC_VER
(
svr
)
==
SVR_8548
&&
IS_SVR_REV
(
svr
,
3
,
1
))
||
(
SVR_REV
(
svr
)
<=
CONFIG_SYS_FSL_A004447_SVR_REV
))
flags
=
I2C_CR_BIT6
;
...
...
@@ -286,8 +290,7 @@ static void __i2c_init(const struct fsl_i2c_base *base, int speed, int
}
}
static
int
i2c_wait4bus
(
const
struct
fsl_i2c_base
*
base
)
static
int
i2c_wait4bus
(
const
struct
fsl_i2c_base
*
base
)
{
unsigned
long
long
timeval
=
get_ticks
();
const
unsigned
long
long
timeout
=
usec2ticks
(
CONFIG_I2C_MBB_TIMEOUT
);
...
...
@@ -300,8 +303,7 @@ i2c_wait4bus(const struct fsl_i2c_base *base)
return
0
;
}
static
inline
int
i2c_wait
(
const
struct
fsl_i2c_base
*
base
,
int
write
)
static
int
i2c_wait
(
const
struct
fsl_i2c_base
*
base
,
int
write
)
{
u32
csr
;
unsigned
long
long
timeval
=
get_ticks
();
...
...
@@ -317,29 +319,29 @@ i2c_wait(const struct fsl_i2c_base *base, int write)
writeb
(
0x0
,
&
base
->
sr
);
if
(
csr
&
I2C_SR_MAL
)
{
debug
(
"
i2c_wait: MAL
\n
"
);
debug
(
"
%s: MAL
\n
"
,
__func__
);
return
-
1
;
}
if
(
!
(
csr
&
I2C_SR_MCF
))
{
debug
(
"
i2c_wait: unfinished
\n
"
);
debug
(
"
%s: unfinished
\n
"
,
__func__
);
return
-
1
;
}
if
(
write
==
I2C_WRITE_BIT
&&
(
csr
&
I2C_SR_RXAK
))
{
debug
(
"
i2c_wait: No RXACK
\n
"
);
debug
(
"
%s: No RXACK
\n
"
,
__func__
);
return
-
1
;
}
return
0
;
}
while
((
get_ticks
()
-
timeval
)
<
timeout
);
debug
(
"
i2c_wait: timed out
\n
"
);
debug
(
"
%s: timed out
\n
"
,
__func__
);
return
-
1
;
}
static
in
line
int
i2c_write_addr
(
const
struct
fsl_i2c_base
*
base
,
u8
dev
,
u8
dir
,
int
rsta
)
static
in
t
i2c_write_addr
(
const
struct
fsl_i2c_base
*
base
,
u8
dev
,
u8
dir
,
int
rsta
)
{
writeb
(
I2C_CR_MEN
|
I2C_CR_MSTA
|
I2C_CR_MTX
|
(
rsta
?
I2C_CR_RSTA
:
0
),
...
...
@@ -353,8 +355,8 @@ i2c_write_addr(const struct fsl_i2c_base *base, u8 dev, u8 dir, int rsta)
return
1
;
}
static
in
line
int
__i2c_write_data
(
const
struct
fsl_i2c_base
*
base
,
u8
*
data
,
int
length
)
static
in
t
__i2c_write_data
(
const
struct
fsl_i2c_base
*
base
,
u8
*
data
,
int
length
)
{
int
i
;
...
...
@@ -368,8 +370,8 @@ __i2c_write_data(const struct fsl_i2c_base *base, u8 *data, int length)
return
i
;
}
static
in
line
int
__i2c_read_data
(
const
struct
fsl_i2c_base
*
base
,
u8
*
data
,
int
length
)
static
in
t
__i2c_read_data
(
const
struct
fsl_i2c_base
*
base
,
u8
*
data
,
int
length
)
{
int
i
;
...
...
@@ -399,9 +401,8 @@ __i2c_read_data(const struct fsl_i2c_base *base, u8 *data, int length)
return
i
;
}
static
int
__i2c_read
(
const
struct
fsl_i2c_base
*
base
,
u8
chip_addr
,
u8
*
offset
,
int
olen
,
u8
*
data
,
int
dlen
)
static
int
__i2c_read
(
const
struct
fsl_i2c_base
*
base
,
u8
chip_addr
,
u8
*
offset
,
int
olen
,
u8
*
data
,
int
dlen
)
{
int
ret
=
-
1
;
/* signal error */
...
...
@@ -447,9 +448,8 @@ __i2c_read(const struct fsl_i2c_base *base, u8 chip_addr, u8 *offset, int olen,
return
-
1
;
}
static
int
__i2c_write
(
const
struct
fsl_i2c_base
*
base
,
u8
chip_addr
,
u8
*
offset
,
int
olen
,
u8
*
data
,
int
dlen
)
static
int
__i2c_write
(
const
struct
fsl_i2c_base
*
base
,
u8
chip_addr
,
u8
*
offset
,
int
olen
,
u8
*
data
,
int
dlen
)
{
int
ret
=
-
1
;
/* signal error */
...
...
@@ -471,10 +471,9 @@ __i2c_write(const struct fsl_i2c_base *base, u8 chip_addr, u8 *offset, int olen,
return
-
1
;
}
static
int
__i2c_probe_chip
(
const
struct
fsl_i2c_base
*
base
,
uchar
chip
)
static
int
__i2c_probe_chip
(
const
struct
fsl_i2c_base
*
base
,
uchar
chip
)
{
/* For unknow reason the controller will ACK when
/* For unknow
n
reason the controller will ACK when
* probing for a slave with the same address, so skip
* it.
*/
...
...
@@ -484,8 +483,8 @@ __i2c_probe_chip(const struct fsl_i2c_base *base, uchar chip)
return
__i2c_read
(
base
,
chip
,
0
,
0
,
NULL
,
0
);
}
static
u
nsigned
int
__i2c_set_bus_speed
(
const
struct
fsl_i2c_base
*
base
,
unsigned
int
speed
,
int
i2c_clk
)
static
uint
__i2c_set_bus_speed
(
const
struct
fsl_i2c_base
*
base
,
u
int
speed
,
int
i2c_clk
)
{
writeb
(
0
,
&
base
->
cr
);
/* stop controller */
set_i2c_bus_speed
(
base
,
i2c_clk
,
speed
);
...
...
@@ -501,32 +500,30 @@ static void fsl_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
get_i2c_clock
(
adap
->
hwadapnr
),
adap
->
hwadapnr
);
}
static
int
fsl_i2c_probe_chip
(
struct
i2c_adapter
*
adap
,
uchar
chip
)
static
int
fsl_i2c_probe_chip
(
struct
i2c_adapter
*
adap
,
uchar
chip
)
{
return
__i2c_probe_chip
(
i2c_base
[
adap
->
hwadapnr
],
chip
);
}
static
int
fsl_i2c_read
(
struct
i2c_adapter
*
adap
,
u8
chip_addr
,
uint
offset
,
int
olen
,
u8
*
data
,
int
dlen
)
static
int
fsl_i2c_read
(
struct
i2c_adapter
*
adap
,
u8
chip_addr
,
uint
offset
,
int
olen
,
u8
*
data
,
int
dlen
)
{
u8
*
o
=
(
u8
*
)
&
offset
;
return
__i2c_read
(
i2c_base
[
adap
->
hwadapnr
],
chip_addr
,
&
o
[
4
-
olen
],
olen
,
data
,
dlen
);
}
static
int
fsl_i2c_write
(
struct
i2c_adapter
*
adap
,
u8
chip_addr
,
uint
offset
,
int
olen
,
u8
*
data
,
int
dlen
)
static
int
fsl_i2c_write
(
struct
i2c_adapter
*
adap
,
u8
chip_addr
,
uint
offset
,
int
olen
,
u8
*
data
,
int
dlen
)
{
u8
*
o
=
(
u8
*
)
&
offset
;
return
__i2c_write
(
i2c_base
[
adap
->
hwadapnr
],
chip_addr
,
&
o
[
4
-
olen
],
olen
,
data
,
dlen
);
}
static
unsigned
int
fsl_i2c_set_bus_speed
(
struct
i2c_adapter
*
adap
,
unsigned
int
speed
)
static
uint
fsl_i2c_set_bus_speed
(
struct
i2c_adapter
*
adap
,
uint
speed
)
{
return
__i2c_set_bus_speed
(
i2c_base
[
adap
->
hwadapnr
],
speed
,
get_i2c_clock
(
adap
->
hwadapnr
));
...
...
@@ -562,12 +559,14 @@ static int fsl_i2c_probe_chip(struct udevice *bus, u32 chip_addr,
u32
chip_flags
)
{
struct
fsl_i2c_dev
*
dev
=
dev_get_priv
(
bus
);
return
__i2c_probe_chip
(
dev
->
base
,
chip_addr
);
}
static
int
fsl_i2c_set_bus_speed
(
struct
udevice
*
bus
,
u
nsigned
int
speed
)
static
int
fsl_i2c_set_bus_speed
(
struct
udevice
*
bus
,
uint
speed
)
{
struct
fsl_i2c_dev
*
dev
=
dev_get_priv
(
bus
);
return
__i2c_set_bus_speed
(
dev
->
base
,
speed
,
dev
->
i2c_clk
);
}
...
...
@@ -575,22 +574,18 @@ static int fsl_i2c_ofdata_to_platdata(struct udevice *bus)
{
struct
fsl_i2c_dev
*
dev
=
dev_get_priv
(
bus
);
fdt_addr_t
addr
;
fdt_size_t
size
;
int
node
=
dev_of_offset
(
bus
);
addr
=
fdtdec_get_addr_size_auto_noparent
(
gd
->
fdt_blob
,
node
,
"reg"
,
0
,
&
size
,
false
);
addr
=
dev_read_u32_default
(
bus
,
"reg"
,
-
1
);
dev
->
base
=
map_sysmem
(
CONFIG_SYS_IMMR
+
addr
,
size
);
dev
->
base
=
map_sysmem
(
CONFIG_SYS_IMMR
+
addr
,
size
of
(
struct
fsl_i2c_base
)
);
if
(
!
dev
->
base
)
return
-
ENOMEM
;
dev
->
index
=
fdtdec_get_int
(
gd
->
fdt_blob
,
node
,
"cell-index"
,
-
1
);
dev
->
slaveadd
=
fdtdec_get_int
(
gd
->
fdt_blob
,
node
,
"u-boot,i2c-slave-addr"
,
0x7f
);
dev
->
speed
=
fdtdec_get_int
(
gd
->
fdt_blob
,
node
,
"clock-frequency"
,
400000
);
dev
->
index
=
dev_read_u32_default
(
bus
,
"cell-index"
,
-
1
);
dev
->
slaveadd
=
dev_read_u32_default
(
bus
,
"u-boot,i2c-slave-addr"
,
0x7f
);
dev
->
speed
=
dev_read_u32_default
(
bus
,
"clock-frequency"
,
400000
);
dev
->
i2c_clk
=
dev
->
index
?
gd
->
arch
.
i2c2_clk
:
gd
->
arch
.
i2c1_clk
;
...
...
@@ -600,6 +595,7 @@ static int fsl_i2c_ofdata_to_platdata(struct udevice *bus)
static
int
fsl_i2c_probe
(
struct
udevice
*
bus
)
{
struct
fsl_i2c_dev
*
dev
=
dev_get_priv
(
bus
);
__i2c_init
(
dev
->
base
,
dev
->
speed
,
dev
->
slaveadd
,
dev
->
i2c_clk
,
dev
->
index
);
return
0
;
...
...
@@ -613,7 +609,8 @@ static int fsl_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
memset
(
&
dummy
,
0
,
sizeof
(
struct
i2c_msg
));
/* We expect either two messages (one with an offset and one with the
* actucal data) or one message (just data) */
* actual data) or one message (just data)
*/
if
(
nmsgs
>
2
||
nmsgs
==
0
)
{
debug
(
"%s: Only one or two messages are supported."
,
__func__
);
return
-
1
;
...
...
drivers/i2c/ihs_i2c.c
浏览文件 @
ea0211b6
...
...
@@ -3,18 +3,39 @@
* Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
*
* SPDX-License-Identifier: GPL-2.0+
*
* NOTE: This driver should be converted to driver model before June 2017.
* Please see doc/driver-model/i2c-howto.txt for instructions.
*/
#include <common.h>
#include <i2c.h>
#ifdef CONFIG_DM_I2C
#include <dm.h>
#include <fpgamap.h>
#include "../misc/gdsys_soc.h"
#else
#include <gdsys_fpga.h>
#endif
#include <asm/unaligned.h>
#ifdef CONFIG_DM_I2C
struct
ihs_i2c_priv
{
uint
speed
;
phys_addr_t
addr
;
};
enum
{
REG_INTERRUPT_STATUS
=
0x00
,
REG_INTERRUPT_ENABLE_CONTROL
=
0x02
,
REG_WRITE_MAILBOX_EXT
=
0x04
,
REG_WRITE_MAILBOX
=
0x06
,
REG_READ_MAILBOX_EXT
=
0x08
,
REG_READ_MAILBOX
=
0x0A
,
};
#else
/* !CONFIG_DM_I2C */
DECLARE_GLOBAL_DATA_PTR
;
#ifdef CONFIG_SYS_I2C_IHS_DUAL
#define I2C_SET_REG(fld, val) \
do { \
if (I2C_ADAP_HWNR & 0x10) \
...
...
@@ -39,67 +60,135 @@ DECLARE_GLOBAL_DATA_PTR;
#define I2C_GET_REG(fld, val) \
FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val)
#endif
#endif
/* CONFIG_DM_I2C */
enum
{
I2CINT_ERROR_EV
=
1
<<
13
,
I2CINT_TRANSMIT_EV
=
1
<<
14
,
I2CINT_RECEIVE_EV
=
1
<<
15
,
I2CINT_ERROR_EV
=
BIT
(
13
)
,
I2CINT_TRANSMIT_EV
=
BIT
(
14
)
,
I2CINT_RECEIVE_EV
=
BIT
(
15
)
,
};
enum
{
I2CMB_READ
=
0
<<
10
,
I2CMB_WRITE
=
1
<<
10
,
I2CMB_1BYTE
=
0
<<
11
,
I2CMB_2BYTE
=
1
<<
11
,
I2CMB_DONT_HOLD_BUS
=
0
<<
13
,
I2CMB_HOLD_BUS
=
1
<<
13
,
I2CMB_NATIVE
=
2
<<
14
,
};
enum
{
I2COP_WRITE
=
0
,
I2COP_READ
=
1
,
};
#ifdef CONFIG_DM_I2C
static
int
wait_for_int
(
struct
udevice
*
dev
,
int
read
)
#else
static
int
wait_for_int
(
bool
read
)
#endif
{
u16
val
;
unsigned
int
ctr
=
0
;
uint
ctr
=
0
;
#ifdef CONFIG_DM_I2C
struct
ihs_i2c_priv
*
priv
=
dev_get_priv
(
dev
);
struct
udevice
*
fpga
;
gdsys_soc_get_fpga
(
dev
,
&
fpga
);
#endif
#ifdef CONFIG_DM_I2C
fpgamap_read16
(
fpga
,
priv
->
addr
+
REG_INTERRUPT_STATUS
,
&
val
);
#else
I2C_GET_REG
(
interrupt_status
,
&
val
);
#endif
/* Wait until error or receive/transmit interrupt was raised */
while
(
!
(
val
&
(
I2CINT_ERROR_EV
|
(
read
?
I2CINT_RECEIVE_EV
:
I2CINT_TRANSMIT_EV
))))
{
udelay
(
10
);
if
(
ctr
++
>
5000
)
{
if
(
ctr
++
>
5000
)
return
1
;
}
#ifdef CONFIG_DM_I2C
fpgamap_read16
(
fpga
,
priv
->
addr
+
REG_INTERRUPT_STATUS
,
&
val
);
#else
I2C_GET_REG
(
interrupt_status
,
&
val
);
#endif
}
return
(
val
&
I2CINT_ERROR_EV
)
?
1
:
0
;
}
#ifdef CONFIG_DM_I2C
static
int
ihs_i2c_transfer
(
struct
udevice
*
dev
,
uchar
chip
,
uchar
*
buffer
,
int
len
,
int
read
,
bool
is_last
)
#else
static
int
ihs_i2c_transfer
(
uchar
chip
,
uchar
*
buffer
,
int
len
,
bool
read
,
bool
is_last
)
#endif
{
u16
val
;
#ifdef CONFIG_DM_I2C
struct
ihs_i2c_priv
*
priv
=
dev_get_priv
(
dev
);
struct
udevice
*
fpga
;
gdsys_soc_get_fpga
(
dev
,
&
fpga
);
#endif
/* Clear interrupt status */
#ifdef CONFIG_DM_I2C
fpgamap_write16
(
fpga
,
priv
->
addr
+
REG_INTERRUPT_STATUS
,
I2CINT_ERROR_EV
|
I2CINT_RECEIVE_EV
|
I2CINT_TRANSMIT_EV
);
fpgamap_read16
(
fpga
,
priv
->
addr
+
REG_INTERRUPT_STATUS
,
&
val
);
#else
I2C_SET_REG
(
interrupt_status
,
I2CINT_ERROR_EV
|
I2CINT_RECEIVE_EV
|
I2CINT_TRANSMIT_EV
);
I2C_GET_REG
(
interrupt_status
,
&
val
);
#endif
/* If we want to write and have data, write the bytes to the mailbox */
if
(
!
read
&&
len
)
{
val
=
buffer
[
0
];
if
(
len
>
1
)
val
|=
buffer
[
1
]
<<
8
;
#ifdef CONFIG_DM_I2C
fpgamap_write16
(
fpga
,
priv
->
addr
+
REG_WRITE_MAILBOX_EXT
,
val
);
#else
I2C_SET_REG
(
write_mailbox_ext
,
val
);
#endif
}
#ifdef CONFIG_DM_I2C
fpgamap_write16
(
fpga
,
priv
->
addr
+
REG_WRITE_MAILBOX
,
I2CMB_NATIVE
|
(
read
?
I2CMB_READ
:
I2CMB_WRITE
)
|
(
chip
<<
1
)
|
((
len
>
1
)
?
I2CMB_2BYTE
:
I2CMB_1BYTE
)
|
(
!
is_last
?
I2CMB_HOLD_BUS
:
I2CMB_DONT_HOLD_BUS
));
#else
I2C_SET_REG
(
write_mailbox
,
I2CMB_NATIVE
|
(
read
?
0
:
I2CMB_WRITE
)
|
(
chip
<<
1
)
|
((
len
>
1
)
?
I2CMB_2BYTE
:
0
)
|
(
is_last
?
0
:
I2CMB_HOLD_BUS
));
#endif
#ifdef CONFIG_DM_I2C
if
(
wait_for_int
(
dev
,
read
))
#else
if
(
wait_for_int
(
read
))
#endif
return
1
;
/* If we want to read, get the bytes from the mailbox */
if
(
read
)
{
#ifdef CONFIG_DM_I2C
fpgamap_read16
(
fpga
,
priv
->
addr
+
REG_READ_MAILBOX_EXT
,
&
val
);
#else
I2C_GET_REG
(
read_mailbox_ext
,
&
val
);
#endif
buffer
[
0
]
=
val
&
0xff
;
if
(
len
>
1
)
buffer
[
1
]
=
val
>>
8
;
...
...
@@ -108,54 +197,157 @@ static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read,
return
0
;
}
static
int
ihs_i2c_address
(
uchar
chip
,
uint
addr
,
int
alen
,
bool
hold_bus
)
#ifdef CONFIG_DM_I2C
static
int
ihs_i2c_send_buffer
(
struct
udevice
*
dev
,
uchar
chip
,
u8
*
data
,
int
len
,
bool
hold_bus
,
int
read
)
#else
static
int
ihs_i2c_send_buffer
(
uchar
chip
,
u8
*
data
,
int
len
,
bool
hold_bus
,
int
read
)
#endif
{
int
shift
=
(
alen
-
1
)
*
8
;
while
(
alen
)
{
int
transfer
=
min
(
alen
,
2
);
uchar
buf
[
2
];
bool
is_last
=
alen
<=
transfer
;
buf
[
0
]
=
addr
>>
shift
;
if
(
alen
>
1
)
buf
[
1
]
=
addr
>>
(
shift
-
8
);
while
(
len
)
{
int
transfer
=
min
(
len
,
2
);
bool
is_last
=
len
<=
transfer
;
if
(
ihs_i2c_transfer
(
chip
,
buf
,
transfer
,
false
,
#ifdef CONFIG_DM_I2C
if
(
ihs_i2c_transfer
(
dev
,
chip
,
data
,
transfer
,
read
,
hold_bus
?
false
:
is_last
))
return
1
;
#else
if
(
ihs_i2c_transfer
(
chip
,
data
,
transfer
,
read
,
hold_bus
?
false
:
is_last
))
return
1
;
#endif
shift
-=
16
;
a
len
-=
transfer
;
data
+=
transfer
;
len
-=
transfer
;
}
return
0
;
}
static
int
ihs_i2c_access
(
struct
i2c_adapter
*
adap
,
uchar
chip
,
uint
addr
,
int
alen
,
uchar
*
buffer
,
int
len
,
bool
read
)
#ifdef CONFIG_DM_I2C
static
int
ihs_i2c_address
(
struct
udevice
*
dev
,
uchar
chip
,
u8
*
addr
,
int
alen
,
bool
hold_bus
)
#else
static
int
ihs_i2c_address
(
uchar
chip
,
u8
*
addr
,
int
alen
,
bool
hold_bus
)
#endif
{
if
(
len
<=
0
)
return
1
;
#ifdef CONFIG_DM_I2C
return
ihs_i2c_send_buffer
(
dev
,
chip
,
addr
,
alen
,
hold_bus
,
I2COP_WRITE
);
#else
return
ihs_i2c_send_buffer
(
chip
,
addr
,
alen
,
hold_bus
,
I2COP_WRITE
);
#endif
}
if
(
ihs_i2c_address
(
chip
,
addr
,
alen
,
len
))
#ifdef CONFIG_DM_I2C
static
int
ihs_i2c_access
(
struct
udevice
*
dev
,
uchar
chip
,
u8
*
addr
,
int
alen
,
uchar
*
buffer
,
int
len
,
int
read
)
#else
static
int
ihs_i2c_access
(
struct
i2c_adapter
*
adap
,
uchar
chip
,
u8
*
addr
,
int
alen
,
uchar
*
buffer
,
int
len
,
int
read
)
#endif
{
/* Don't hold the bus if length of data to send/receive is zero */
#ifdef CONFIG_DM_I2C
if
(
len
<=
0
||
ihs_i2c_address
(
dev
,
chip
,
addr
,
alen
,
len
))
return
1
;
#else
if
(
len
<=
0
||
ihs_i2c_address
(
chip
,
addr
,
alen
,
len
))
return
1
;
#endif
while
(
len
)
{
int
transfer
=
min
(
len
,
2
);
#ifdef CONFIG_DM_I2C
return
ihs_i2c_send_buffer
(
dev
,
chip
,
buffer
,
len
,
false
,
read
);
#else
return
ihs_i2c_send_buffer
(
chip
,
buffer
,
len
,
false
,
read
);
#endif
}
#ifdef CONFIG_DM_I2C
int
ihs_i2c_probe
(
struct
udevice
*
bus
)
{
struct
ihs_i2c_priv
*
priv
=
dev_get_priv
(
bus
);
int
addr
;
addr
=
dev_read_u32_default
(
bus
,
"reg"
,
-
1
);
priv
->
addr
=
addr
;
if
(
ihs_i2c_transfer
(
chip
,
buffer
,
transfer
,
read
,
len
<=
transfer
))
return
0
;
}
static
int
ihs_i2c_set_bus_speed
(
struct
udevice
*
bus
,
uint
speed
)
{
struct
ihs_i2c_priv
*
priv
=
dev_get_priv
(
bus
);
if
(
speed
!=
priv
->
speed
&&
priv
->
speed
!=
0
)
return
1
;
buffer
+=
transfer
;
addr
+=
transfer
;
len
-=
transfer
;
priv
->
speed
=
speed
;
return
0
;
}
static
int
ihs_i2c_xfer
(
struct
udevice
*
bus
,
struct
i2c_msg
*
msg
,
int
nmsgs
)
{
struct
i2c_msg
*
dmsg
,
*
omsg
,
dummy
;
memset
(
&
dummy
,
0
,
sizeof
(
struct
i2c_msg
));
/* We expect either two messages (one with an offset and one with the
* actucal data) or one message (just data)
*/
if
(
nmsgs
>
2
||
nmsgs
==
0
)
{
debug
(
"%s: Only one or two messages are supported."
,
__func__
);
return
-
1
;
}
omsg
=
nmsgs
==
1
?
&
dummy
:
msg
;
dmsg
=
nmsgs
==
1
?
msg
:
msg
+
1
;
if
(
dmsg
->
flags
&
I2C_M_RD
)
return
ihs_i2c_access
(
bus
,
dmsg
->
addr
,
omsg
->
buf
,
omsg
->
len
,
dmsg
->
buf
,
dmsg
->
len
,
I2COP_READ
);
else
return
ihs_i2c_access
(
bus
,
dmsg
->
addr
,
omsg
->
buf
,
omsg
->
len
,
dmsg
->
buf
,
dmsg
->
len
,
I2COP_WRITE
);
}
static
int
ihs_i2c_probe_chip
(
struct
udevice
*
bus
,
u32
chip_addr
,
u32
chip_flags
)
{
uchar
buffer
[
2
];
if
(
ihs_i2c_transfer
(
bus
,
chip_addr
,
buffer
,
0
,
I2COP_READ
,
true
))
return
1
;
return
0
;
}
static
const
struct
dm_i2c_ops
ihs_i2c_ops
=
{
.
xfer
=
ihs_i2c_xfer
,
.
probe_chip
=
ihs_i2c_probe_chip
,
.
set_bus_speed
=
ihs_i2c_set_bus_speed
,
};
static
const
struct
udevice_id
ihs_i2c_ids
[]
=
{
{
.
compatible
=
"gdsys,ihs_i2cmaster"
,
},
{
/* sentinel */
}
};
U_BOOT_DRIVER
(
i2c_ihs
)
=
{
.
name
=
"i2c_ihs"
,
.
id
=
UCLASS_I2C
,
.
of_match
=
ihs_i2c_ids
,
.
probe
=
ihs_i2c_probe
,
.
priv_auto_alloc_size
=
sizeof
(
struct
ihs_i2c_priv
),
.
ops
=
&
ihs_i2c_ops
,
};
#else
/* CONFIG_DM_I2C */
static
void
ihs_i2c_init
(
struct
i2c_adapter
*
adap
,
int
speed
,
int
slaveaddr
)
{
...
...
@@ -173,7 +365,7 @@ static int ihs_i2c_probe(struct i2c_adapter *adap, uchar chip)
{
uchar
buffer
[
2
];
if
(
ihs_i2c_transfer
(
chip
,
buffer
,
0
,
true
,
true
))
if
(
ihs_i2c_transfer
(
chip
,
buffer
,
0
,
I2COP_READ
,
true
))
return
1
;
return
0
;
...
...
@@ -182,13 +374,23 @@ static int ihs_i2c_probe(struct i2c_adapter *adap, uchar chip)
static
int
ihs_i2c_read
(
struct
i2c_adapter
*
adap
,
uchar
chip
,
uint
addr
,
int
alen
,
uchar
*
buffer
,
int
len
)
{
return
ihs_i2c_access
(
adap
,
chip
,
addr
,
alen
,
buffer
,
len
,
true
);
u8
addr_bytes
[
4
];
put_unaligned_le32
(
addr
,
addr_bytes
);
return
ihs_i2c_access
(
adap
,
chip
,
addr_bytes
,
alen
,
buffer
,
len
,
I2COP_READ
);
}
static
int
ihs_i2c_write
(
struct
i2c_adapter
*
adap
,
uchar
chip
,
uint
addr
,
int
alen
,
uchar
*
buffer
,
int
len
)
{
return
ihs_i2c_access
(
adap
,
chip
,
addr
,
alen
,
buffer
,
len
,
false
);
u8
addr_bytes
[
4
];
put_unaligned_le32
(
addr
,
addr_bytes
);
return
ihs_i2c_access
(
adap
,
chip
,
addr_bytes
,
alen
,
buffer
,
len
,
I2COP_WRITE
);
}
static
unsigned
int
ihs_i2c_set_bus_speed
(
struct
i2c_adapter
*
adap
,
...
...
@@ -258,3 +460,4 @@ U_BOOT_I2C_ADAP_COMPLETE(ihs3_1, ihs_i2c_init, ihs_i2c_probe,
CONFIG_SYS_I2C_IHS_SLAVE_3_1
,
19
)
#endif
#endif
#endif
/* CONFIG_DM_I2C */
drivers/i2c/mvtwsi.c
浏览文件 @
ea0211b6
...
...
@@ -490,6 +490,7 @@ static void __twsi_i2c_init(struct mvtwsi_registers *twsi, int speed,
/* Reset controller */
twsi_reset
(
twsi
);
/* Set speed */
if
(
actual_speed
)
*
actual_speed
=
__twsi_i2c_set_bus_speed
(
twsi
,
speed
);
/* Set slave address; even though we don't use it */
writel
(
slaveadd
,
&
twsi
->
slave_address
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录