Skip to content

Commit 7adeac1

Browse files
FlorianWeber1018fabiobaltieri
authored andcommitted
drivers: i2c: tca9544a
Extend tca954x (tca9546a, tca9548a) driver to support tca9544a i2c MUX. (different bitmask and flag for enable bit in register) Signed-off-by: Florian Weber <[email protected]>
1 parent 2fe54b4 commit 7adeac1

File tree

3 files changed

+34
-10
lines changed

3 files changed

+34
-10
lines changed

drivers/i2c/Kconfig.tca954x

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
menuconfig I2C_TCA954X
55
bool "I2C addressable switch"
66
default y
7-
depends on DT_HAS_TI_TCA9546A_ENABLED || DT_HAS_TI_TCA9548A_ENABLED
7+
depends on DT_HAS_TI_TCA9546A_ENABLED || DT_HAS_TI_TCA9548A_ENABLED \
8+
|| DT_HAS_TI_TCA9544A_ENABLED
89
help
910
Enable TCA954x series I2C bus switch
1011

drivers/i2c/i2c_tca954x.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct tca954x_root_data {
2828
struct tca954x_channel_config {
2929
const struct device *root;
3030
uint8_t chan_mask;
31+
bool has_enable;
3132
};
3233

3334
static inline struct tca954x_root_data *
@@ -143,7 +144,8 @@ static int tca954x_channel_init(const struct device *dev)
143144
return -ENODEV;
144145
}
145146

146-
if (chan_cfg->chan_mask >= BIT(root_cfg->nchans)) {
147+
if ((chan_cfg->chan_mask >= BIT(root_cfg->nchans) && !chan_cfg->has_enable) ||
148+
(chan_cfg->chan_mask > (BIT(2) | (root_cfg->nchans - 1)) && chan_cfg->has_enable)) {
147149
LOG_ERR("Wrong DTS address provided for %s", dev->name);
148150
return -EINVAL;
149151
}
@@ -162,11 +164,13 @@ static const struct i2c_driver_api tca954x_api_funcs = {
162164
BUILD_ASSERT(CONFIG_I2C_TCA954X_CHANNEL_INIT_PRIO > CONFIG_I2C_TCA954X_ROOT_INIT_PRIO,
163165
"I2C multiplexer channels must be initialized after their root");
164166

165-
#define TCA954x_CHILD_DEFINE(node_id, n) \
167+
#define TCA954x_CHILD_DEFINE(node_id, n, has_enable_bit) \
166168
static const struct tca954x_channel_config \
167169
tca##n##a_down_config_##node_id = { \
168-
.chan_mask = BIT(DT_REG_ADDR(node_id)), \
170+
.chan_mask = has_enable_bit ? BIT(2) | DT_REG_ADDR(node_id) \
171+
: BIT(DT_REG_ADDR(node_id)), \
169172
.root = DEVICE_DT_GET(DT_PARENT(node_id)), \
173+
.has_enable = has_enable_bit, \
170174
}; \
171175
DEVICE_DT_DEFINE(node_id, \
172176
tca954x_channel_init, \
@@ -176,7 +180,7 @@ BUILD_ASSERT(CONFIG_I2C_TCA954X_CHANNEL_INIT_PRIO > CONFIG_I2C_TCA954X_ROOT_INIT
176180
POST_KERNEL, CONFIG_I2C_TCA954X_CHANNEL_INIT_PRIO, \
177181
&tca954x_api_funcs);
178182

179-
#define TCA954x_ROOT_DEFINE(n, inst, ch) \
183+
#define TCA954x_ROOT_DEFINE(n, inst, ch, has_enable_bit) \
180184
static const struct tca954x_root_config tca##n##a_cfg_##inst = { \
181185
.i2c = I2C_DT_SPEC_INST_GET(inst), \
182186
.nchans = ch, \
@@ -191,20 +195,29 @@ BUILD_ASSERT(CONFIG_I2C_TCA954X_CHANNEL_INIT_PRIO > CONFIG_I2C_TCA954X_ROOT_INIT
191195
&tca##n##a_data_##inst, &tca##n##a_cfg_##inst, \
192196
POST_KERNEL, CONFIG_I2C_TCA954X_ROOT_INIT_PRIO, \
193197
NULL); \
194-
DT_FOREACH_CHILD_VARGS(DT_INST(inst, ti_tca##n##a), TCA954x_CHILD_DEFINE, n);
198+
DT_FOREACH_CHILD_VARGS(DT_INST(inst, ti_tca##n##a), TCA954x_CHILD_DEFINE, n, \
199+
has_enable_bit);
195200

196201
/*
197-
* TCA9546A: 4 channels
202+
* TCA9544A: 4 channels mux
198203
*/
199-
#define TCA9546A_INIT(n) TCA954x_ROOT_DEFINE(9546, n, 4)
204+
#define TCA9544A_INIT(n) TCA954x_ROOT_DEFINE(9544, n, 4, true)
205+
#undef DT_DRV_COMPAT
206+
#define DT_DRV_COMPAT ti_tca9544a
207+
DT_INST_FOREACH_STATUS_OKAY(TCA9544A_INIT)
208+
209+
/*
210+
* TCA9546A: 4 channels switch
211+
*/
212+
#define TCA9546A_INIT(n) TCA954x_ROOT_DEFINE(9546, n, 4, false)
200213
#undef DT_DRV_COMPAT
201214
#define DT_DRV_COMPAT ti_tca9546a
202215
DT_INST_FOREACH_STATUS_OKAY(TCA9546A_INIT)
203216

204217
/*
205-
* TCA9548A: 8 channels
218+
* TCA9548A: 8 channels switch
206219
*/
207-
#define TCA9548A_INIT(n) TCA954x_ROOT_DEFINE(9548, n, 8)
220+
#define TCA9548A_INIT(n) TCA954x_ROOT_DEFINE(9548, n, 8, false)
208221
#undef DT_DRV_COMPAT
209222
#define DT_DRV_COMPAT ti_tca9548a
210223
DT_INST_FOREACH_STATUS_OKAY(TCA9548A_INIT)

dts/bindings/i2c/ti,tca9544a.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Binding for TI TCA9544A, compatible with NXP PCA9544A
2+
3+
description: Texas Instruments TCA9544A binding
4+
5+
compatible: "ti,tca9544a"
6+
7+
include: ti,tca954x-base.yaml
8+
9+
child-binding:
10+
compatible: "ti,tca9544a-channel"

0 commit comments

Comments
 (0)