Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
6d54f144
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
6d54f144
编写于
8月 26, 2016
作者:
W
Wolfram Sang
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'i2c-mux-dt-3' of
https://github.com/peda-r/i2c-mux
into i2c/for-4.9
Signed-off-by:
N
Wolfram Sang
<
wsa@the-dreams.de
>
上级
0317e6c0
8a191a7a
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
214 addition
and
35 deletion
+214
-35
Documentation/devicetree/bindings/i2c/i2c-arb-gpio-challenge.txt
...tation/devicetree/bindings/i2c/i2c-arb-gpio-challenge.txt
+2
-6
Documentation/devicetree/bindings/i2c/i2c-arb.txt
Documentation/devicetree/bindings/i2c/i2c-arb.txt
+35
-0
Documentation/devicetree/bindings/i2c/i2c-gate.txt
Documentation/devicetree/bindings/i2c/i2c-gate.txt
+41
-0
Documentation/devicetree/bindings/i2c/i2c-mux.txt
Documentation/devicetree/bindings/i2c/i2c-mux.txt
+18
-5
Documentation/devicetree/bindings/i2c/nxp,pca9541.txt
Documentation/devicetree/bindings/i2c/nxp,pca9541.txt
+29
-0
MAINTAINERS
MAINTAINERS
+2
-0
drivers/i2c/i2c-mux.c
drivers/i2c/i2c-mux.c
+36
-8
drivers/i2c/muxes/i2c-arb-gpio-challenge.c
drivers/i2c/muxes/i2c-arb-gpio-challenge.c
+1
-1
drivers/i2c/muxes/i2c-mux-pca9541.c
drivers/i2c/muxes/i2c-mux-pca9541.c
+10
-1
drivers/i2c/muxes/i2c-mux-pca954x.c
drivers/i2c/muxes/i2c-mux-pca954x.c
+34
-12
include/linux/i2c-mux.h
include/linux/i2c-mux.h
+6
-2
未找到文件。
Documentation/devicetree/bindings/i2c/i2c-arb-gpio-challenge.txt
浏览文件 @
6d54f144
...
...
@@ -44,8 +44,7 @@ Required properties:
- our-claim-gpio: The GPIO that we use to claim the bus.
- their-claim-gpios: The GPIOs that the other sides use to claim the bus.
Note that some implementations may only support a single other master.
- Standard I2C mux properties. See i2c-mux.txt in this directory.
- Single I2C child bus node at reg 0. See i2c-mux.txt in this directory.
- I2C arbitration bus node. See i2c-arb.txt in this directory.
Optional properties:
- slew-delay-us: microseconds to wait for a GPIO to go high. Default is 10 us.
...
...
@@ -63,8 +62,6 @@ Example:
i2c-arbitrator {
compatible = "i2c-arb-gpio-challenge";
#address-cells = <1>;
#size-cells = <0>;
i2c-parent = <&{/i2c@12CA0000}>;
...
...
@@ -74,8 +71,7 @@ Example:
wait-retry-us = <3000>;
wait-free-us = <50000>;
i2c@0 {
reg = <0>;
i2c-arb {
#address-cells = <1>;
#size-cells = <0>;
...
...
Documentation/devicetree/bindings/i2c/i2c-arb.txt
0 → 100644
浏览文件 @
6d54f144
Common i2c arbitration bus properties.
- i2c-arb child node
Required properties for the i2c-arb child node:
- #address-cells = <1>;
- #size-cells = <0>;
Optional properties for i2c-arb child node:
- Child nodes conforming to i2c bus binding
Example :
/*
An NXP pca9541 I2C bus master selector at address 0x74
with a NXP pca8574 GPIO expander attached.
*/
arb@74 {
compatible = "nxp,pca9541";
reg = <0x74>;
i2c-arb {
#address-cells = <1>;
#size-cells = <0>;
gpio@38 {
compatible = "nxp,pca8574";
reg = <0x38>;
#gpio-cells = <2>;
gpio-controller;
};
};
};
Documentation/devicetree/bindings/i2c/i2c-gate.txt
0 → 100644
浏览文件 @
6d54f144
An i2c gate is useful to e.g. reduce the digital noise for RF tuners connected
to the i2c bus. Gates are similar to arbitrators in that you need to perform
some kind of operation to access the i2c bus past the arbitrator/gate, but
there are no competing masters to consider for gates and therefore there is
no arbitration happening for gates.
Common i2c gate properties.
- i2c-gate child node
Required properties for the i2c-gate child node:
- #address-cells = <1>;
- #size-cells = <0>;
Optional properties for i2c-gate child node:
- Child nodes conforming to i2c bus binding
Example :
/*
An Invensense mpu9150 at address 0x68 featuring an on-chip Asahi
Kasei ak8975 compass behind a gate.
*/
mpu9150@68 {
compatible = "invensense,mpu9150";
reg = <0x68>;
interrupt-parent = <&gpio1>;
interrupts = <18 1>;
i2c-gate {
#address-cells = <1>;
#size-cells = <0>;
ax8975@c {
compatible = "ak,ak8975";
reg = <0x0c>;
};
};
};
Documentation/devicetree/bindings/i2c/i2c-mux.txt
浏览文件 @
6d54f144
...
...
@@ -2,19 +2,32 @@ Common i2c bus multiplexer/switch properties.
An i2c bus multiplexer/switch will have several child busses that are
numbered uniquely in a device dependent manner. The nodes for an i2c bus
multiplexer/switch will have one child node for each child
bus.
multiplexer/switch will have one child node for each child bus.
Required properties:
Optional properties:
- #address-cells = <1>;
This property is required is the i2c-mux child node does not exist.
- #size-cells = <0>;
This property is required is the i2c-mux child node does not exist.
- i2c-mux
For i2c multiplexers/switches that have child nodes that are a mixture
of both i2c child busses and other child nodes, the 'i2c-mux' subnode
can be used for populating the i2c child busses. If an 'i2c-mux'
subnode is present, only subnodes of this will be considered as i2c
child busses.
Required properties for the i2c-mux child node:
- #address-cells = <1>;
- #size-cells = <0>;
Required properties for
child
nodes:
Required properties for
i2c child bus
nodes:
- #address-cells = <1>;
- #size-cells = <0>;
- reg : The sub-bus number.
Optional properties for
child
nodes:
Optional properties for
i2c child bus
nodes:
- Other properties specific to the multiplexer/switch hardware.
- Child nodes conforming to i2c bus binding
...
...
Documentation/devicetree/bindings/i2c/nxp,pca9541.txt
0 → 100644
浏览文件 @
6d54f144
* NXP PCA9541 I2C bus master selector
Required Properties:
- compatible: Must be "nxp,pca9541"
- reg: The I2C address of the device.
The following required properties are defined externally:
- I2C arbitration bus node. See i2c-arb.txt in this directory.
Example:
i2c-arbitrator@74 {
compatible = "nxp,pca9541";
reg = <0x74>;
i2c-arb {
#address-cells = <1>;
#size-cells = <0>;
eeprom@54 {
compatible = "at,24c08";
reg = <0x54>;
};
};
};
MAINTAINERS
浏览文件 @
6d54f144
...
...
@@ -5675,6 +5675,8 @@ S: Maintained
F: Documentation/i2c/i2c-topology
F: Documentation/i2c/muxes/
F: Documentation/devicetree/bindings/i2c/i2c-mux*
F: Documentation/devicetree/bindings/i2c/i2c-arb*
F: Documentation/devicetree/bindings/i2c/i2c-gate*
F: drivers/i2c/i2c-mux.c
F: drivers/i2c/muxes/
F: include/linux/i2c-mux.h
...
...
drivers/i2c/i2c-mux.c
浏览文件 @
6d54f144
...
...
@@ -255,6 +255,10 @@ struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent,
muxc
->
dev
=
dev
;
if
(
flags
&
I2C_MUX_LOCKED
)
muxc
->
mux_locked
=
true
;
if
(
flags
&
I2C_MUX_ARBITRATOR
)
muxc
->
arbitrator
=
true
;
if
(
flags
&
I2C_MUX_GATE
)
muxc
->
gate
=
true
;
muxc
->
select
=
select
;
muxc
->
deselect
=
deselect
;
muxc
->
max_adapters
=
max_adapters
;
...
...
@@ -335,18 +339,42 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
* nothing if !CONFIG_OF.
*/
if
(
muxc
->
dev
->
of_node
)
{
struct
device_node
*
child
;
struct
device_node
*
dev_node
=
muxc
->
dev
->
of_node
;
struct
device_node
*
mux_node
,
*
child
=
NULL
;
u32
reg
;
for_each_child_of_node
(
muxc
->
dev
->
of_node
,
child
)
{
ret
=
of_property_read_u32
(
child
,
"reg"
,
&
reg
);
if
(
ret
)
continue
;
if
(
chan_id
==
reg
)
{
priv
->
adap
.
dev
.
of_node
=
child
;
break
;
if
(
muxc
->
arbitrator
)
mux_node
=
of_get_child_by_name
(
dev_node
,
"i2c-arb"
);
else
if
(
muxc
->
gate
)
mux_node
=
of_get_child_by_name
(
dev_node
,
"i2c-gate"
);
else
mux_node
=
of_get_child_by_name
(
dev_node
,
"i2c-mux"
);
if
(
mux_node
)
{
/* A "reg" property indicates an old-style DT entry */
if
(
!
of_property_read_u32
(
mux_node
,
"reg"
,
&
reg
))
{
of_node_put
(
mux_node
);
mux_node
=
NULL
;
}
}
if
(
!
mux_node
)
mux_node
=
of_node_get
(
dev_node
);
else
if
(
muxc
->
arbitrator
||
muxc
->
gate
)
child
=
of_node_get
(
mux_node
);
if
(
!
child
)
{
for_each_child_of_node
(
mux_node
,
child
)
{
ret
=
of_property_read_u32
(
child
,
"reg"
,
&
reg
);
if
(
ret
)
continue
;
if
(
chan_id
==
reg
)
break
;
}
}
priv
->
adap
.
dev
.
of_node
=
child
;
of_node_put
(
mux_node
);
}
/*
...
...
drivers/i2c/muxes/i2c-arb-gpio-challenge.c
浏览文件 @
6d54f144
...
...
@@ -130,7 +130,7 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
return
-
EINVAL
;
}
muxc
=
i2c_mux_alloc
(
NULL
,
dev
,
1
,
sizeof
(
*
arb
),
0
,
muxc
=
i2c_mux_alloc
(
NULL
,
dev
,
1
,
sizeof
(
*
arb
),
I2C_MUX_ARBITRATOR
,
i2c_arbitrator_select
,
i2c_arbitrator_deselect
);
if
(
!
muxc
)
return
-
ENOMEM
;
...
...
drivers/i2c/muxes/i2c-mux-pca9541.c
浏览文件 @
6d54f144
...
...
@@ -85,6 +85,13 @@ static const struct i2c_device_id pca9541_id[] = {
MODULE_DEVICE_TABLE
(
i2c
,
pca9541_id
);
#ifdef CONFIG_OF
static
const
struct
of_device_id
pca9541_of_match
[]
=
{
{
.
compatible
=
"nxp,pca9541"
},
{}
};
#endif
/*
* Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer()
* as they will try to lock the adapter a second time.
...
...
@@ -349,7 +356,8 @@ static int pca9541_probe(struct i2c_client *client,
force
=
0
;
if
(
pdata
)
force
=
pdata
->
modes
[
0
].
adap_id
;
muxc
=
i2c_mux_alloc
(
adap
,
&
client
->
dev
,
1
,
sizeof
(
*
data
),
0
,
muxc
=
i2c_mux_alloc
(
adap
,
&
client
->
dev
,
1
,
sizeof
(
*
data
),
I2C_MUX_ARBITRATOR
,
pca9541_select_chan
,
pca9541_release_chan
);
if
(
!
muxc
)
return
-
ENOMEM
;
...
...
@@ -382,6 +390,7 @@ static int pca9541_remove(struct i2c_client *client)
static
struct
i2c_driver
pca9541_driver
=
{
.
driver
=
{
.
name
=
"pca9541"
,
.
of_match_table
=
of_match_ptr
(
pca9541_of_match
),
},
.
probe
=
pca9541_probe
,
.
remove
=
pca9541_remove
,
...
...
drivers/i2c/muxes/i2c-mux-pca954x.c
浏览文件 @
6d54f144
...
...
@@ -42,6 +42,7 @@
#include <linux/i2c/pca954x.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pm.h>
#include <linux/slab.h>
...
...
@@ -58,14 +59,6 @@ enum pca_type {
pca_9548
,
};
struct
pca954x
{
enum
pca_type
type
;
u8
last_chan
;
/* last register value */
u8
deselect
;
struct
i2c_client
*
client
;
};
struct
chip_desc
{
u8
nchans
;
u8
enable
;
/* used for muxes only */
...
...
@@ -75,6 +68,14 @@ struct chip_desc {
}
muxtype
;
};
struct
pca954x
{
const
struct
chip_desc
*
chip
;
u8
last_chan
;
/* last register value */
u8
deselect
;
struct
i2c_client
*
client
;
};
/* Provide specs for the PCA954x types we know about */
static
const
struct
chip_desc
chips
[]
=
{
[
pca_9540
]
=
{
...
...
@@ -119,6 +120,20 @@ static const struct i2c_device_id pca954x_id[] = {
};
MODULE_DEVICE_TABLE
(
i2c
,
pca954x_id
);
#ifdef CONFIG_OF
static
const
struct
of_device_id
pca954x_of_match
[]
=
{
{
.
compatible
=
"nxp,pca9540"
,
.
data
=
&
chips
[
pca_9540
]
},
{
.
compatible
=
"nxp,pca9542"
,
.
data
=
&
chips
[
pca_9542
]
},
{
.
compatible
=
"nxp,pca9543"
,
.
data
=
&
chips
[
pca_9543
]
},
{
.
compatible
=
"nxp,pca9544"
,
.
data
=
&
chips
[
pca_9544
]
},
{
.
compatible
=
"nxp,pca9545"
,
.
data
=
&
chips
[
pca_9545
]
},
{
.
compatible
=
"nxp,pca9546"
,
.
data
=
&
chips
[
pca_9546
]
},
{
.
compatible
=
"nxp,pca9547"
,
.
data
=
&
chips
[
pca_9547
]
},
{
.
compatible
=
"nxp,pca9548"
,
.
data
=
&
chips
[
pca_9548
]
},
{}
};
#endif
/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer()
for this as they will try to lock adapter a second time */
static
int
pca954x_reg_write
(
struct
i2c_adapter
*
adap
,
...
...
@@ -151,7 +166,7 @@ static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan)
{
struct
pca954x
*
data
=
i2c_mux_priv
(
muxc
);
struct
i2c_client
*
client
=
data
->
client
;
const
struct
chip_desc
*
chip
=
&
chips
[
data
->
type
]
;
const
struct
chip_desc
*
chip
=
data
->
chip
;
u8
regval
;
int
ret
=
0
;
...
...
@@ -197,6 +212,7 @@ static int pca954x_probe(struct i2c_client *client,
int
num
,
force
,
class
;
struct
i2c_mux_core
*
muxc
;
struct
pca954x
*
data
;
const
struct
of_device_id
*
match
;
int
ret
;
if
(
!
i2c_check_functionality
(
adap
,
I2C_FUNC_SMBUS_BYTE
))
...
...
@@ -226,14 +242,19 @@ static int pca954x_probe(struct i2c_client *client,
return
-
ENODEV
;
}
data
->
type
=
id
->
driver_data
;
match
=
of_match_device
(
of_match_ptr
(
pca954x_of_match
),
&
client
->
dev
);
if
(
match
)
data
->
chip
=
of_device_get_match_data
(
&
client
->
dev
);
else
data
->
chip
=
&
chips
[
id
->
driver_data
];
data
->
last_chan
=
0
;
/* force the first selection */
idle_disconnect_dt
=
of_node
&&
of_property_read_bool
(
of_node
,
"i2c-mux-idle-disconnect"
);
/* Now create an adapter for each channel */
for
(
num
=
0
;
num
<
chips
[
data
->
type
].
nchans
;
num
++
)
{
for
(
num
=
0
;
num
<
data
->
chip
->
nchans
;
num
++
)
{
bool
idle_disconnect_pd
=
false
;
force
=
0
;
/* dynamic adap number */
...
...
@@ -263,7 +284,7 @@ static int pca954x_probe(struct i2c_client *client,
dev_info
(
&
client
->
dev
,
"registered %d multiplexed busses for I2C %s %s
\n
"
,
num
,
chips
[
data
->
type
].
muxtype
==
pca954x_ismux
num
,
data
->
chip
->
muxtype
==
pca954x_ismux
?
"mux"
:
"switch"
,
client
->
name
);
return
0
;
...
...
@@ -299,6 +320,7 @@ static struct i2c_driver pca954x_driver = {
.
driver
=
{
.
name
=
"pca954x"
,
.
pm
=
&
pca954x_pm
,
.
of_match_table
=
of_match_ptr
(
pca954x_of_match
),
},
.
probe
=
pca954x_probe
,
.
remove
=
pca954x_remove
,
...
...
include/linux/i2c-mux.h
浏览文件 @
6d54f144
...
...
@@ -32,7 +32,9 @@
struct
i2c_mux_core
{
struct
i2c_adapter
*
parent
;
struct
device
*
dev
;
bool
mux_locked
;
unsigned
int
mux_locked
:
1
;
unsigned
int
arbitrator
:
1
;
unsigned
int
gate
:
1
;
void
*
priv
;
...
...
@@ -51,7 +53,9 @@ struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent,
int
(
*
deselect
)(
struct
i2c_mux_core
*
,
u32
));
/* flags for i2c_mux_alloc */
#define I2C_MUX_LOCKED BIT(0)
#define I2C_MUX_LOCKED BIT(0)
#define I2C_MUX_ARBITRATOR BIT(1)
#define I2C_MUX_GATE BIT(2)
static
inline
void
*
i2c_mux_priv
(
struct
i2c_mux_core
*
muxc
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录