@@ -37,6 +37,7 @@ struct i2c_gecko_config {
37
37
38
38
struct i2c_gecko_data {
39
39
struct k_sem device_sync_sem ;
40
+ struct k_sem bus_lock ;
40
41
uint32_t dev_config ;
41
42
#if defined(CONFIG_I2C_TARGET )
42
43
struct i2c_target_config * target_cfg ;
@@ -68,6 +69,8 @@ static int i2c_gecko_configure(const struct device *dev, uint32_t dev_config_raw
68
69
return - EINVAL ;
69
70
}
70
71
72
+ k_sem_take (& data -> bus_lock , K_FOREVER );
73
+
71
74
data -> dev_config = dev_config_raw ;
72
75
i2cInit .freq = baudrate ;
73
76
@@ -77,6 +80,8 @@ static int i2c_gecko_configure(const struct device *dev, uint32_t dev_config_raw
77
80
78
81
I2C_Init (base , & i2cInit );
79
82
83
+ k_sem_give (& data -> bus_lock );
84
+
80
85
return 0 ;
81
86
}
82
87
@@ -93,6 +98,8 @@ static int i2c_gecko_transfer(const struct device *dev, struct i2c_msg *msgs, ui
93
98
return 0 ;
94
99
}
95
100
101
+ k_sem_take (& data -> bus_lock , K_FOREVER );
102
+
96
103
seq .addr = addr << 1 ;
97
104
98
105
do {
@@ -137,6 +144,8 @@ static int i2c_gecko_transfer(const struct device *dev, struct i2c_msg *msgs, ui
137
144
} while (num_msgs );
138
145
139
146
finish :
147
+ k_sem_give (& data -> bus_lock );
148
+
140
149
if (ret != i2cTransferDone ) {
141
150
ret = - EIO ;
142
151
}
@@ -145,10 +154,16 @@ static int i2c_gecko_transfer(const struct device *dev, struct i2c_msg *msgs, ui
145
154
146
155
static int i2c_gecko_init (const struct device * dev )
147
156
{
157
+ struct i2c_gecko_data * data = dev -> data ;
148
158
const struct i2c_gecko_config * config = dev -> config ;
149
159
uint32_t bitrate_cfg ;
150
160
int error ;
151
161
162
+ /* Initialize mutex to guarantee that each transaction
163
+ * is atomic and has exclusive access to the I2C bus
164
+ */
165
+ k_sem_init (& data -> bus_lock , 1 , 1 );
166
+
152
167
CMU_ClockEnable (config -> clock , true);
153
168
154
169
error = pinctrl_apply_state (config -> pcfg , PINCTRL_STATE_DEFAULT );
0 commit comments