Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
234d1298
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,发现更多精彩内容 >>
提交
234d1298
编写于
4月 04, 2017
作者:
T
Tom Rini
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.denx.de/u-boot-i2c
上级
db40c1aa
e46f8a33
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
270 addition
and
103 deletion
+270
-103
arch/arm/include/asm/arch-lpc32xx/i2c.h
arch/arm/include/asm/arch-lpc32xx/i2c.h
+37
-0
cmd/i2c.c
cmd/i2c.c
+10
-0
drivers/i2c/Kconfig
drivers/i2c/Kconfig
+14
-0
drivers/i2c/lpc32xx_i2c.c
drivers/i2c/lpc32xx_i2c.c
+163
-73
drivers/i2c/omap24xx_i2c.c
drivers/i2c/omap24xx_i2c.c
+41
-25
drivers/i2c/omap24xx_i2c.h
drivers/i2c/omap24xx_i2c.h
+5
-5
未找到文件。
arch/arm/include/asm/arch-lpc32xx/i2c.h
0 → 100644
浏览文件 @
234d1298
#ifndef _LPC32XX_I2C_H
#define _LPC32XX_I2C_H
#include <common.h>
#include <asm/types.h>
/* i2c register set */
struct
lpc32xx_i2c_base
{
union
{
u32
rx
;
u32
tx
;
};
u32
stat
;
u32
ctrl
;
u32
clk_hi
;
u32
clk_lo
;
u32
adr
;
u32
rxfl
;
u32
txfl
;
u32
rxb
;
u32
txb
;
u32
stx
;
u32
stxfl
;
};
#ifdef CONFIG_DM_I2C
enum
{
I2C_0
,
I2C_1
,
I2C_2
,
};
struct
lpc32xx_i2c_dev
{
struct
lpc32xx_i2c_base
*
base
;
int
index
;
uint
speed
;
};
#endif
/* CONFIG_DM_I2C */
#endif
/* _LPC32XX_I2C_H */
cmd/i2c.c
浏览文件 @
234d1298
...
...
@@ -151,6 +151,16 @@ static int cmd_i2c_set_bus_num(unsigned int busnum)
static
int
i2c_get_cur_bus
(
struct
udevice
**
busp
)
{
#ifdef CONFIG_I2C_SET_DEFAULT_BUS_NUM
if
(
!
i2c_cur_bus
)
{
if
(
cmd_i2c_set_bus_num
(
CONFIG_I2C_DEFAULT_BUS_NUMBER
))
{
printf
(
"Default I2C bus %d not found
\n
"
,
CONFIG_I2C_DEFAULT_BUS_NUMBER
);
return
-
ENODEV
;
}
}
#endif
if
(
!
i2c_cur_bus
)
{
puts
(
"No I2C bus selected
\n
"
);
return
-
ENODEV
;
...
...
drivers/i2c/Kconfig
浏览文件 @
234d1298
...
...
@@ -49,6 +49,20 @@ config I2C_CROS_EC_LDO
avoid duplicating the logic in the TPS65090 regulator driver for
enabling/disabling an LDO.
config I2C_SET_DEFAULT_BUS_NUM
bool "Set default I2C bus number"
depends on DM_I2C
help
Set default number of I2C bus to be accessed. This option provides
behaviour similar to old (i.e. pre DM) I2C bus driver.
config I2C_DEFAULT_BUS_NUMBER
hex "I2C default bus number"
depends on I2C_SET_DEFAULT_BUS_NUM
default 0x0
help
Number of default I2C bus to use
config DM_I2C_GPIO
bool "Enable Driver Model for software emulated I2C bus driver"
depends on DM_I2C && DM_GPIO
...
...
drivers/i2c/lpc32xx_i2c.c
浏览文件 @
234d1298
...
...
@@ -5,9 +5,6 @@
* Written-by: Albert ARIBAUD - 3ADEV <albert.aribaud@3adev.fr>
*
* 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>
...
...
@@ -15,6 +12,9 @@
#include <i2c.h>
#include <linux/errno.h>
#include <asm/arch/clk.h>
#include <asm/arch/i2c.h>
#include <dm.h>
#include <mapmem.h>
/*
* Provide default speed and slave if target did not
...
...
@@ -28,25 +28,6 @@
#define CONFIG_SYS_I2C_LPC32XX_SLAVE 0
#endif
/* i2c register set */
struct
lpc32xx_i2c_registers
{
union
{
u32
rx
;
u32
tx
;
};
u32
stat
;
u32
ctrl
;
u32
clk_hi
;
u32
clk_lo
;
u32
adr
;
u32
rxfl
;
u32
txfl
;
u32
rxb
;
u32
txb
;
u32
stx
;
u32
stxfl
;
};
/* TX register fields */
#define LPC32XX_I2C_TX_START 0x00000100
#define LPC32XX_I2C_TX_STOP 0x00000200
...
...
@@ -61,15 +42,17 @@ struct lpc32xx_i2c_registers {
#define LPC32XX_I2C_STAT_NAI 0x00000004
#define LPC32XX_I2C_STAT_TDI 0x00000001
static
struct
lpc32xx_i2c_registers
*
lpc32xx_i2c
[]
=
{
(
struct
lpc32xx_i2c_registers
*
)
I2C1_BASE
,
(
struct
lpc32xx_i2c_registers
*
)
I2C2_BASE
,
(
struct
lpc32xx_i2c_registers
*
)(
USB_BASE
+
0x300
)
#ifndef CONFIG_DM_I2C
static
struct
lpc32xx_i2c_base
*
lpc32xx_i2c
[]
=
{
(
struct
lpc32xx_i2c_base
*
)
I2C1_BASE
,
(
struct
lpc32xx_i2c_base
*
)
I2C2_BASE
,
(
struct
lpc32xx_i2c_base
*
)(
USB_BASE
+
0x300
)
};
#endif
/* Set I2C bus speed */
static
unsigned
int
lpc32xx_i2c_set_bus_speed
(
struct
i2c_adapter
*
adap
,
unsigned
int
speed
)
static
unsigned
int
__i2c_set_bus_speed
(
struct
lpc32xx_i2c_base
*
base
,
unsigned
int
speed
,
unsigned
int
chip
)
{
int
half_period
;
...
...
@@ -77,7 +60,7 @@ static unsigned int lpc32xx_i2c_set_bus_speed(struct i2c_adapter *adap,
return
-
EINVAL
;
/* OTG I2C clock source and CLK registers are different */
if
(
adap
->
hwadapnr
==
2
)
{
if
(
chip
==
2
)
{
half_period
=
(
get_periph_clk_rate
()
/
speed
)
/
2
;
if
(
half_period
>
0xFF
)
return
-
EINVAL
;
...
...
@@ -87,38 +70,35 @@ static unsigned int lpc32xx_i2c_set_bus_speed(struct i2c_adapter *adap,
return
-
EINVAL
;
}
writel
(
half_period
,
&
lpc32xx_i2c
[
adap
->
hwadapnr
]
->
clk_hi
);
writel
(
half_period
,
&
lpc32xx_i2c
[
adap
->
hwadapnr
]
->
clk_lo
);
writel
(
half_period
,
&
base
->
clk_hi
);
writel
(
half_period
,
&
base
->
clk_lo
);
return
0
;
}
/* I2C init called by cmd_i2c when doing 'i2c reset'. */
static
void
_
i2c_init
(
struct
i2c_adapter
*
adap
,
int
requested_speed
,
int
slaveadd
)
static
void
_
_i2c_init
(
struct
lpc32xx_i2c_base
*
base
,
int
requested_speed
,
int
slaveadd
,
unsigned
int
chip
)
{
struct
lpc32xx_i2c_registers
*
i2c
=
lpc32xx_i2c
[
adap
->
hwadapnr
];
/* soft reset (auto-clears) */
writel
(
LPC32XX_I2C_SOFT_RESET
,
&
i2c
->
ctrl
);
writel
(
LPC32XX_I2C_SOFT_RESET
,
&
base
->
ctrl
);
/* set HI and LO periods for half of the default speed */
lpc32xx_i2c_set_bus_speed
(
adap
,
requested_speed
);
__i2c_set_bus_speed
(
base
,
requested_speed
,
chip
);
}
/* I2C probe called by cmd_i2c when doing 'i2c probe'. */
static
int
lpc32xx_i2c_probe
(
struct
i2c_adapter
*
adap
,
u8
dev
)
static
int
__i2c_probe_chip
(
struct
lpc32xx_i2c_base
*
base
,
u8
dev
)
{
struct
lpc32xx_i2c_registers
*
i2c
=
lpc32xx_i2c
[
adap
->
hwadapnr
];
int
stat
;
/* Soft-reset the controller */
writel
(
LPC32XX_I2C_SOFT_RESET
,
&
i2c
->
ctrl
);
while
(
readl
(
&
i2c
->
ctrl
)
&
LPC32XX_I2C_SOFT_RESET
)
writel
(
LPC32XX_I2C_SOFT_RESET
,
&
base
->
ctrl
);
while
(
readl
(
&
base
->
ctrl
)
&
LPC32XX_I2C_SOFT_RESET
)
;
/* Addre slave for write with start before and stop after */
writel
((
dev
<<
1
)
|
LPC32XX_I2C_TX_START
|
LPC32XX_I2C_TX_STOP
,
&
i2c
->
tx
);
&
base
->
tx
);
/* wait for end of transation */
while
(
!
((
stat
=
readl
(
&
i2c
->
stat
))
&
LPC32XX_I2C_STAT_TDI
))
while
(
!
((
stat
=
readl
(
&
base
->
stat
))
&
LPC32XX_I2C_STAT_TDI
))
;
/* was there no acknowledge? */
return
(
stat
&
LPC32XX_I2C_STAT_NAI
)
?
-
1
:
0
;
...
...
@@ -128,20 +108,19 @@ static int lpc32xx_i2c_probe(struct i2c_adapter *adap, u8 dev)
* I2C read called by cmd_i2c when doing 'i2c read' and by cmd_eeprom.c
* Begin write, send address byte(s), begin read, receive data bytes, end.
*/
static
int
lpc32xx_i2c_read
(
struct
i2c_adapter
*
adap
,
u8
dev
,
uint
addr
,
int
alen
,
u8
*
data
,
int
length
)
static
int
__i2c_read
(
struct
lpc32xx_i2c_base
*
base
,
u8
dev
,
uint
addr
,
int
alen
,
u8
*
data
,
int
length
)
{
struct
lpc32xx_i2c_registers
*
i2c
=
lpc32xx_i2c
[
adap
->
hwadapnr
];
int
stat
,
wlen
;
/* Soft-reset the controller */
writel
(
LPC32XX_I2C_SOFT_RESET
,
&
i2c
->
ctrl
);
while
(
readl
(
&
i2c
->
ctrl
)
&
LPC32XX_I2C_SOFT_RESET
)
writel
(
LPC32XX_I2C_SOFT_RESET
,
&
base
->
ctrl
);
while
(
readl
(
&
base
->
ctrl
)
&
LPC32XX_I2C_SOFT_RESET
)
;
/* do we need to write an address at all? */
if
(
alen
)
{
/* Address slave in write mode */
writel
((
dev
<<
1
)
|
LPC32XX_I2C_TX_START
,
&
i2c
->
tx
);
writel
((
dev
<<
1
)
|
LPC32XX_I2C_TX_START
,
&
base
->
tx
);
/* write address bytes */
while
(
alen
--
)
{
/* compute address byte + stop for the last one */
...
...
@@ -149,44 +128,44 @@ static int lpc32xx_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,
if
(
!
alen
)
a
|=
LPC32XX_I2C_TX_STOP
;
/* Send address byte */
writel
(
a
,
&
i2c
->
tx
);
writel
(
a
,
&
base
->
tx
);
}
/* wait for end of transation */
while
(
!
((
stat
=
readl
(
&
i2c
->
stat
))
&
LPC32XX_I2C_STAT_TDI
))
while
(
!
((
stat
=
readl
(
&
base
->
stat
))
&
LPC32XX_I2C_STAT_TDI
))
;
/* clear end-of-transaction flag */
writel
(
1
,
&
i2c
->
stat
);
writel
(
1
,
&
base
->
stat
);
}
/* do we have to read data at all? */
if
(
length
)
{
/* Address slave in read mode */
writel
(
1
|
(
dev
<<
1
)
|
LPC32XX_I2C_TX_START
,
&
i2c
->
tx
);
writel
(
1
|
(
dev
<<
1
)
|
LPC32XX_I2C_TX_START
,
&
base
->
tx
);
wlen
=
length
;
/* get data */
while
(
length
|
wlen
)
{
/* read status for TFF and RFE */
stat
=
readl
(
&
i2c
->
stat
);
stat
=
readl
(
&
base
->
stat
);
/* must we, can we write a trigger byte? */
if
((
wlen
>
0
)
&
(
!
(
stat
&
LPC32XX_I2C_STAT_TFF
)))
{
wlen
--
;
/* write trigger byte + stop if last */
writel
(
wlen
?
0
:
LPC32XX_I2C_TX_STOP
,
&
i2c
->
tx
);
LPC32XX_I2C_TX_STOP
,
&
base
->
tx
);
}
/* must we, can we read a data byte? */
if
((
length
>
0
)
&
(
!
(
stat
&
LPC32XX_I2C_STAT_RFE
)))
{
length
--
;
/* read byte */
*
(
data
++
)
=
readl
(
&
i2c
->
rx
);
*
(
data
++
)
=
readl
(
&
base
->
rx
);
}
}
/* wait for end of transation */
while
(
!
((
stat
=
readl
(
&
i2c
->
stat
))
&
LPC32XX_I2C_STAT_TDI
))
while
(
!
((
stat
=
readl
(
&
base
->
stat
))
&
LPC32XX_I2C_STAT_TDI
))
;
/* clear end-of-transaction flag */
writel
(
1
,
&
i2c
->
stat
);
writel
(
1
,
&
base
->
stat
);
}
/* success */
return
0
;
...
...
@@ -196,38 +175,37 @@ static int lpc32xx_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,
* I2C write called by cmd_i2c when doing 'i2c write' and by cmd_eeprom.c
* Begin write, send address byte(s), send data bytes, end.
*/
static
int
lpc32xx_i2c_write
(
struct
i2c_adapter
*
adap
,
u8
dev
,
uint
addr
,
int
alen
,
u8
*
data
,
int
length
)
static
int
__i2c_write
(
struct
lpc32xx_i2c_base
*
base
,
u8
dev
,
uint
addr
,
int
alen
,
u8
*
data
,
int
length
)
{
struct
lpc32xx_i2c_registers
*
i2c
=
lpc32xx_i2c
[
adap
->
hwadapnr
];
int
stat
;
/* Soft-reset the controller */
writel
(
LPC32XX_I2C_SOFT_RESET
,
&
i2c
->
ctrl
);
while
(
readl
(
&
i2c
->
ctrl
)
&
LPC32XX_I2C_SOFT_RESET
)
writel
(
LPC32XX_I2C_SOFT_RESET
,
&
base
->
ctrl
);
while
(
readl
(
&
base
->
ctrl
)
&
LPC32XX_I2C_SOFT_RESET
)
;
/* do we need to write anything at all? */
if
(
alen
|
length
)
/* Address slave in write mode */
writel
((
dev
<<
1
)
|
LPC32XX_I2C_TX_START
,
&
i2c
->
tx
);
writel
((
dev
<<
1
)
|
LPC32XX_I2C_TX_START
,
&
base
->
tx
);
else
return
0
;
/* write address bytes */
while
(
alen
)
{
/* wait for transmit fifo not full */
stat
=
readl
(
&
i2c
->
stat
);
stat
=
readl
(
&
base
->
stat
);
if
(
!
(
stat
&
LPC32XX_I2C_STAT_TFF
))
{
alen
--
;
int
a
=
(
addr
>>
(
8
*
alen
))
&
0xff
;
if
(
!
(
alen
|
length
))
a
|=
LPC32XX_I2C_TX_STOP
;
/* Send address byte */
writel
(
a
,
&
i2c
->
tx
);
writel
(
a
,
&
base
->
tx
);
}
}
while
(
length
)
{
/* wait for transmit fifo not full */
stat
=
readl
(
&
i2c
->
stat
);
stat
=
readl
(
&
base
->
stat
);
if
(
!
(
stat
&
LPC32XX_I2C_STAT_TFF
))
{
/* compute data byte, add stop if length==0 */
length
--
;
...
...
@@ -235,34 +213,146 @@ static int lpc32xx_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr,
if
(
!
length
)
d
|=
LPC32XX_I2C_TX_STOP
;
/* Send data byte */
writel
(
d
,
&
i2c
->
tx
);
writel
(
d
,
&
base
->
tx
);
}
}
/* wait for end of transation */
while
(
!
((
stat
=
readl
(
&
i2c
->
stat
))
&
LPC32XX_I2C_STAT_TDI
))
while
(
!
((
stat
=
readl
(
&
base
->
stat
))
&
LPC32XX_I2C_STAT_TDI
))
;
/* clear end-of-transaction flag */
writel
(
1
,
&
i2c
->
stat
);
writel
(
1
,
&
base
->
stat
);
return
0
;
}
U_BOOT_I2C_ADAP_COMPLETE
(
lpc32xx_0
,
_i2c_init
,
lpc32xx_i2c_probe
,
#ifndef CONFIG_DM_I2C
static
void
lpc32xx_i2c_init
(
struct
i2c_adapter
*
adap
,
int
requested_speed
,
int
slaveadd
)
{
__i2c_init
(
lpc32xx_i2c
[
adap
->
hwadapnr
],
requested_speed
,
slaveadd
,
adap
->
hwadapnr
);
}
static
int
lpc32xx_i2c_probe_chip
(
struct
i2c_adapter
*
adap
,
u8
dev
)
{
return
__i2c_probe_chip
(
lpc32xx_i2c
[
adap
->
hwadapnr
],
dev
);
}
static
int
lpc32xx_i2c_read
(
struct
i2c_adapter
*
adap
,
u8
dev
,
uint
addr
,
int
alen
,
u8
*
data
,
int
length
)
{
return
__i2c_read
(
lpc32xx_i2c
[
adap
->
hwadapnr
],
dev
,
addr
,
alen
,
data
,
length
);
}
static
int
lpc32xx_i2c_write
(
struct
i2c_adapter
*
adap
,
u8
dev
,
uint
addr
,
int
alen
,
u8
*
data
,
int
length
)
{
return
__i2c_write
(
lpc32xx_i2c
[
adap
->
hwadapnr
],
dev
,
addr
,
alen
,
data
,
length
);
}
static
unsigned
int
lpc32xx_i2c_set_bus_speed
(
struct
i2c_adapter
*
adap
,
unsigned
int
speed
)
{
return
__i2c_set_bus_speed
(
lpc32xx_i2c
[
adap
->
hwadapnr
],
speed
,
adap
->
hwadapnr
);
}
U_BOOT_I2C_ADAP_COMPLETE
(
lpc32xx_0
,
lpc32xx_i2c_init
,
lpc32xx_i2c_probe_chip
,
lpc32xx_i2c_read
,
lpc32xx_i2c_write
,
lpc32xx_i2c_set_bus_speed
,
CONFIG_SYS_I2C_LPC32XX_SPEED
,
CONFIG_SYS_I2C_LPC32XX_SLAVE
,
0
)
U_BOOT_I2C_ADAP_COMPLETE
(
lpc32xx_1
,
_i2c_init
,
lpc32xx_i2c_probe
,
U_BOOT_I2C_ADAP_COMPLETE
(
lpc32xx_1
,
lpc32xx_i2c_init
,
lpc32xx_i2c_probe_chip
,
lpc32xx_i2c_read
,
lpc32xx_i2c_write
,
lpc32xx_i2c_set_bus_speed
,
CONFIG_SYS_I2C_LPC32XX_SPEED
,
CONFIG_SYS_I2C_LPC32XX_SLAVE
,
1
)
U_BOOT_I2C_ADAP_COMPLETE
(
lpc32xx_2
,
_i2c_init
,
NULL
,
U_BOOT_I2C_ADAP_COMPLETE
(
lpc32xx_2
,
lpc32xx
_i2c_init
,
NULL
,
lpc32xx_i2c_read
,
lpc32xx_i2c_write
,
lpc32xx_i2c_set_bus_speed
,
100000
,
0
,
2
)
#else
/* CONFIG_DM_I2C */
static
int
lpc32xx_i2c_probe
(
struct
udevice
*
bus
)
{
struct
lpc32xx_i2c_dev
*
dev
=
dev_get_platdata
(
bus
);
bus
->
seq
=
dev
->
index
;
__i2c_init
(
dev
->
base
,
dev
->
speed
,
0
,
dev
->
index
);
return
0
;
}
static
int
lpc32xx_i2c_probe_chip
(
struct
udevice
*
bus
,
u32
chip_addr
,
u32
chip_flags
)
{
struct
lpc32xx_i2c_dev
*
dev
=
dev_get_platdata
(
bus
);
return
__i2c_probe_chip
(
dev
->
base
,
chip_addr
);
}
static
int
lpc32xx_i2c_xfer
(
struct
udevice
*
bus
,
struct
i2c_msg
*
msg
,
int
nmsgs
)
{
struct
lpc32xx_i2c_dev
*
dev
=
dev_get_platdata
(
bus
);
struct
i2c_msg
*
dmsg
,
*
omsg
,
dummy
;
uint
i
=
0
,
address
=
0
;
memset
(
&
dummy
,
0
,
sizeof
(
struct
i2c_msg
));
/* We expect either two messages (one with an offset and one with the
* actual 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
;
/* the address is expected to be a uint, not a array. */
address
=
omsg
->
buf
[
0
];
for
(
i
=
1
;
i
<
omsg
->
len
;
i
++
)
address
=
(
address
<<
8
)
+
omsg
->
buf
[
i
];
if
(
dmsg
->
flags
&
I2C_M_RD
)
return
__i2c_read
(
dev
->
base
,
dmsg
->
addr
,
address
,
omsg
->
len
,
dmsg
->
buf
,
dmsg
->
len
);
else
return
__i2c_write
(
dev
->
base
,
dmsg
->
addr
,
address
,
omsg
->
len
,
dmsg
->
buf
,
dmsg
->
len
);
}
static
int
lpc32xx_i2c_set_bus_speed
(
struct
udevice
*
bus
,
unsigned
int
speed
)
{
struct
lpc32xx_i2c_dev
*
dev
=
dev_get_platdata
(
bus
);
return
__i2c_set_bus_speed
(
dev
->
base
,
speed
,
dev
->
index
);
}
static
int
lpc32xx_i2c_reset
(
struct
udevice
*
bus
)
{
struct
lpc32xx_i2c_dev
*
dev
=
dev_get_platdata
(
bus
);
__i2c_init
(
dev
->
base
,
dev
->
speed
,
0
,
dev
->
index
);
return
0
;
}
static
const
struct
dm_i2c_ops
lpc32xx_i2c_ops
=
{
.
xfer
=
lpc32xx_i2c_xfer
,
.
probe_chip
=
lpc32xx_i2c_probe_chip
,
.
deblock
=
lpc32xx_i2c_reset
,
.
set_bus_speed
=
lpc32xx_i2c_set_bus_speed
,
};
U_BOOT_DRIVER
(
i2c_lpc32xx
)
=
{
.
id
=
UCLASS_I2C
,
.
name
=
"i2c_lpc32xx"
,
.
probe
=
lpc32xx_i2c_probe
,
.
ops
=
&
lpc32xx_i2c_ops
,
};
#endif
/* CONFIG_DM_I2C */
drivers/i2c/omap24xx_i2c.c
浏览文件 @
234d1298
...
...
@@ -64,36 +64,52 @@ struct omap_i2c {
static
int
omap24_i2c_findpsc
(
u32
*
pscl
,
u32
*
psch
,
uint
speed
)
{
unsigned
int
sampleclk
,
prescaler
;
int
fsscll
,
fssclh
;
unsigned
long
internal_clk
=
0
,
fclk
;
unsigned
int
prescaler
;
speed
<<=
1
;
prescaler
=
0
;
/*
* some divisors may cause a precission loss, but shouldn't
* be a big thing, because i2c_clk is then allready very slow.
* This method is only called for Standard and Fast Mode speeds
*
* For some TI SoCs it is explicitly written in TRM (e,g, SPRUHZ6G,
* page 5685, Table 24-7)
* that the internal I2C clock (after prescaler) should be between
* 7-12 MHz (at least for Fast Mode (FS)).
*
* Such approach is used in v4.9 Linux kernel in:
* ./drivers/i2c/busses/i2c-omap.c (omap_i2c_init function).
*/
while
(
prescaler
<=
0xFF
)
{
sampleclk
=
I2C_IP_CLK
/
(
prescaler
+
1
);
fsscll
=
sampleclk
/
speed
;
fssclh
=
fsscll
;
fsscll
-=
I2C_FASTSPEED_SCLL_TRIM
;
fssclh
-=
I2C_FASTSPEED_SCLH_TRIM
;
if
(((
fsscll
>
0
)
&&
(
fssclh
>
0
))
&&
((
fsscll
<=
(
255
-
I2C_FASTSPEED_SCLL_TRIM
))
&&
(
fssclh
<=
(
255
-
I2C_FASTSPEED_SCLH_TRIM
))))
{
if
(
pscl
)
*
pscl
=
fsscll
;
if
(
psch
)
*
psch
=
fssclh
;
return
prescaler
;
}
prescaler
++
;
speed
/=
1000
;
/* convert speed to kHz */
if
(
speed
>
100
)
internal_clk
=
9600
;
else
internal_clk
=
4000
;
fclk
=
I2C_IP_CLK
/
1000
;
prescaler
=
fclk
/
internal_clk
;
prescaler
=
prescaler
-
1
;
if
(
speed
>
100
)
{
unsigned
long
scl
;
/* Fast mode */
scl
=
internal_clk
/
speed
;
*
pscl
=
scl
-
(
scl
/
3
)
-
I2C_FASTSPEED_SCLL_TRIM
;
*
psch
=
(
scl
/
3
)
-
I2C_FASTSPEED_SCLH_TRIM
;
}
else
{
/* Standard mode */
*
pscl
=
internal_clk
/
(
speed
*
2
)
-
I2C_FASTSPEED_SCLL_TRIM
;
*
psch
=
internal_clk
/
(
speed
*
2
)
-
I2C_FASTSPEED_SCLH_TRIM
;
}
return
-
1
;
debug
(
"%s: speed [kHz]: %d psc: 0x%x sscl: 0x%x ssch: 0x%x
\n
"
,
__func__
,
speed
,
prescaler
,
*
pscl
,
*
psch
);
if
(
*
pscl
<=
0
||
*
psch
<=
0
||
prescaler
<=
0
)
return
-
EINVAL
;
return
prescaler
;
}
/*
...
...
drivers/i2c/omap24xx_i2c.h
浏览文件 @
234d1298
...
...
@@ -121,17 +121,17 @@
* scll_trim = 7
* sclh_trim = 5
*
* The linux
2.6.30
kernel uses
* scll_trim =
6
* sclh_trim =
6
* The linux
4.9
kernel uses
* scll_trim =
7
* sclh_trim =
5
*
* These are the trim values for standard and fast speed
*/
#ifndef I2C_FASTSPEED_SCLL_TRIM
#define I2C_FASTSPEED_SCLL_TRIM
6
#define I2C_FASTSPEED_SCLL_TRIM
7
#endif
#ifndef I2C_FASTSPEED_SCLH_TRIM
#define I2C_FASTSPEED_SCLH_TRIM
6
#define I2C_FASTSPEED_SCLH_TRIM
5
#endif
/* These are the trim values for high speed */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录