4
4
* SPDX-License-Identifier: Apache-2.0
5
5
*/
6
6
7
-
8
7
#include <zephyr/drivers/i2c.h>
9
8
#include <zephyr/dt-bindings/i2c/i2c.h>
10
9
#include <zephyr/pm/device.h>
17
16
18
17
#include <zephyr/logging/log.h>
19
18
#include <zephyr/irq.h>
19
+
20
+ #include "i2c_nrfx_twim_common.h"
21
+
20
22
LOG_MODULE_REGISTER (i2c_nrfx_twim , CONFIG_I2C_LOG_LEVEL );
21
23
22
24
#if CONFIG_I2C_NRFX_TRANSFER_TIMEOUT
@@ -31,31 +33,18 @@ struct i2c_nrfx_twim_data {
31
33
volatile nrfx_err_t res ;
32
34
};
33
35
34
- struct i2c_nrfx_twim_config {
35
- nrfx_twim_t twim ;
36
- nrfx_twim_config_t twim_config ;
37
- uint16_t msg_buf_size ;
38
- void (* irq_connect )(void );
39
- const struct pinctrl_dev_config * pcfg ;
40
- uint8_t * msg_buf ;
41
- uint16_t max_transfer_size ;
42
- };
43
-
44
- static int i2c_nrfx_twim_recover_bus (const struct device * dev );
45
-
46
36
static int i2c_nrfx_twim_transfer (const struct device * dev ,
47
37
struct i2c_msg * msgs ,
48
38
uint8_t num_msgs , uint16_t addr )
49
39
{
50
40
struct i2c_nrfx_twim_data * dev_data = dev -> data ;
51
- const struct i2c_nrfx_twim_config * dev_config = dev -> config ;
41
+ const struct i2c_nrfx_twim_common_config * dev_config = dev -> config ;
52
42
int ret = 0 ;
53
43
uint8_t * msg_buf = dev_config -> msg_buf ;
54
44
uint16_t msg_buf_used = 0 ;
55
45
uint16_t msg_buf_size = dev_config -> msg_buf_size ;
56
- nrfx_twim_xfer_desc_t cur_xfer = {
57
- .address = addr
58
- };
46
+ uint8_t * buf ;
47
+ uint16_t buf_len ;
59
48
60
49
k_sem_take (& dev_data -> transfer_sync , K_FOREVER );
61
50
@@ -116,35 +105,15 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
116
105
}
117
106
118
107
if (msg_buf_used == 0 ) {
119
- cur_xfer . p_primary_buf = msgs [i ].buf ;
120
- cur_xfer . primary_length = msgs [i ].len ;
108
+ buf = msgs [i ].buf ;
109
+ buf_len = msgs [i ].len ;
121
110
} else {
122
- cur_xfer .p_primary_buf = msg_buf ;
123
- cur_xfer .primary_length = msg_buf_used ;
124
- }
125
- cur_xfer .type = (msgs [i ].flags & I2C_MSG_READ ) ?
126
- NRFX_TWIM_XFER_RX : NRFX_TWIM_XFER_TX ;
127
-
128
- if (cur_xfer .primary_length > dev_config -> max_transfer_size ) {
129
- LOG_ERR ("Trying to transfer more than the maximum size "
130
- "for this device: %d > %d" ,
131
- cur_xfer .primary_length ,
132
- dev_config -> max_transfer_size );
133
- return - ENOSPC ;
111
+ buf = msg_buf ;
112
+ buf_len = msg_buf_used ;
134
113
}
135
-
136
- nrfx_err_t res = nrfx_twim_xfer (& dev_config -> twim ,
137
- & cur_xfer ,
138
- (msgs [i ].flags & I2C_MSG_STOP ) ?
139
- 0 : NRFX_TWIM_FLAG_TX_NO_STOP );
140
- if (res != NRFX_SUCCESS ) {
141
- if (res == NRFX_ERROR_BUSY ) {
142
- ret = - EBUSY ;
143
- break ;
144
- } else {
145
- ret = - EIO ;
146
- break ;
147
- }
114
+ ret = i2c_nrfx_twim_msg_transfer (dev , msgs [i ].flags , buf , buf_len , addr );
115
+ if (ret < 0 ) {
116
+ break ;
148
117
}
149
118
150
119
ret = k_sem_take (& dev_data -> completion_sync ,
@@ -171,18 +140,15 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
171
140
break ;
172
141
}
173
142
174
- res = dev_data -> res ;
175
-
176
- if (res != NRFX_SUCCESS ) {
143
+ if (dev_data -> res != NRFX_SUCCESS ) {
177
144
ret = - EIO ;
178
145
break ;
179
146
}
180
147
181
148
/* If concatenated messages were I2C_MSG_READ type, then
182
149
* content of concatenation buffer has to be copied back into
183
150
* buffers provided by user. */
184
- if ((msgs [i ].flags & I2C_MSG_READ )
185
- && cur_xfer .p_primary_buf == msg_buf ) {
151
+ if ((msgs [i ].flags & I2C_MSG_READ ) && (buf == msg_buf )) {
186
152
int j = i ;
187
153
188
154
while (msg_buf_used >= msgs [j ].len ) {
@@ -227,65 +193,14 @@ static void event_handler(nrfx_twim_evt_t const *p_event, void *p_context)
227
193
k_sem_give (& dev_data -> completion_sync );
228
194
}
229
195
230
- static int i2c_nrfx_twim_configure (const struct device * dev ,
231
- uint32_t i2c_config )
232
- {
233
- const struct i2c_nrfx_twim_config * dev_config = dev -> config ;
234
-
235
- if (I2C_ADDR_10_BITS & i2c_config ) {
236
- return - EINVAL ;
237
- }
238
-
239
- switch (I2C_SPEED_GET (i2c_config )) {
240
- case I2C_SPEED_STANDARD :
241
- nrf_twim_frequency_set (dev_config -> twim .p_twim ,
242
- NRF_TWIM_FREQ_100K );
243
- break ;
244
- case I2C_SPEED_FAST :
245
- nrf_twim_frequency_set (dev_config -> twim .p_twim ,
246
- NRF_TWIM_FREQ_400K );
247
- break ;
248
- #if NRF_TWIM_HAS_1000_KHZ_FREQ
249
- case I2C_SPEED_FAST_PLUS :
250
- nrf_twim_frequency_set (dev_config -> twim .p_twim ,
251
- NRF_TWIM_FREQ_1000K );
252
- break ;
253
- #endif
254
- default :
255
- LOG_ERR ("unsupported speed" );
256
- return - EINVAL ;
257
- }
258
-
259
- return 0 ;
260
- }
261
-
262
- static int i2c_nrfx_twim_recover_bus (const struct device * dev )
196
+ static int i2c_nrfx_twim_init (const struct device * dev )
263
197
{
264
- const struct i2c_nrfx_twim_config * dev_config = dev -> config ;
265
- enum pm_device_state state ;
266
- uint32_t scl_pin ;
267
- uint32_t sda_pin ;
268
- nrfx_err_t err ;
269
-
270
- scl_pin = nrf_twim_scl_pin_get (dev_config -> twim .p_twim );
271
- sda_pin = nrf_twim_sda_pin_get (dev_config -> twim .p_twim );
272
-
273
- /* disable peripheral if active (required to release SCL/SDA lines) */
274
- (void )pm_device_state_get (dev , & state );
275
- if (state == PM_DEVICE_STATE_ACTIVE ) {
276
- nrfx_twim_disable (& dev_config -> twim );
277
- }
198
+ struct i2c_nrfx_twim_data * data = dev -> data ;
278
199
279
- err = nrfx_twim_bus_recover (scl_pin , sda_pin );
280
-
281
- /* restore peripheral if it was active before */
282
- if (state == PM_DEVICE_STATE_ACTIVE ) {
283
- (void )pinctrl_apply_state (dev_config -> pcfg ,
284
- PINCTRL_STATE_DEFAULT );
285
- nrfx_twim_enable (& dev_config -> twim );
286
- }
200
+ k_sem_init (& data -> transfer_sync , 1 , 1 );
201
+ k_sem_init (& data -> completion_sync , 0 , 1 );
287
202
288
- return ( err == NRFX_SUCCESS ? 0 : - EBUSY );
203
+ return i2c_nrfx_twim_common_init ( dev );
289
204
}
290
205
291
206
static const struct i2c_driver_api i2c_nrfx_twim_driver_api = {
@@ -297,62 +212,6 @@ static const struct i2c_driver_api i2c_nrfx_twim_driver_api = {
297
212
.recover_bus = i2c_nrfx_twim_recover_bus ,
298
213
};
299
214
300
- static int twim_nrfx_pm_action (const struct device * dev ,
301
- enum pm_device_action action )
302
- {
303
- const struct i2c_nrfx_twim_config * dev_config = dev -> config ;
304
-
305
- switch (action ) {
306
- case PM_DEVICE_ACTION_RESUME :
307
- (void )pinctrl_apply_state (dev_config -> pcfg , PINCTRL_STATE_DEFAULT );
308
- nrfx_twim_enable (& dev_config -> twim );
309
- break ;
310
- case PM_DEVICE_ACTION_SUSPEND :
311
- nrfx_twim_disable (& dev_config -> twim );
312
- (void )pinctrl_apply_state (dev_config -> pcfg , PINCTRL_STATE_SLEEP );
313
- break ;
314
- default :
315
- return - ENOTSUP ;
316
- }
317
-
318
- return 0 ;
319
- }
320
-
321
- static int i2c_nrfx_twim_init (const struct device * dev )
322
- {
323
- const struct i2c_nrfx_twim_config * dev_config = dev -> config ;
324
- struct i2c_nrfx_twim_data * dev_data = dev -> data ;
325
-
326
- dev_config -> irq_connect ();
327
-
328
- k_sem_init (& dev_data -> transfer_sync , 1 , 1 );
329
- k_sem_init (& dev_data -> completion_sync , 0 , 1 );
330
-
331
- (void )pinctrl_apply_state (dev_config -> pcfg , PINCTRL_STATE_SLEEP );
332
-
333
- if (nrfx_twim_init (& dev_config -> twim , & dev_config -> twim_config ,
334
- event_handler , dev_data ) != NRFX_SUCCESS ) {
335
- LOG_ERR ("Failed to initialize device: %s" , dev -> name );
336
- return - EIO ;
337
- }
338
-
339
- return pm_device_driver_init (dev , twim_nrfx_pm_action );
340
- }
341
-
342
- #define I2C_NRFX_TWIM_INVALID_FREQUENCY ((nrf_twim_frequency_t)-1)
343
- #define I2C_NRFX_TWIM_FREQUENCY (bitrate ) \
344
- (bitrate == I2C_BITRATE_STANDARD ? NRF_TWIM_FREQ_100K : \
345
- bitrate == 250000 ? NRF_TWIM_FREQ_250K : \
346
- bitrate == I2C_BITRATE_FAST ? NRF_TWIM_FREQ_400K : \
347
- IF_ENABLED(NRF_TWIM_HAS_1000_KHZ_FREQ, \
348
- (bitrate == I2C_BITRATE_FAST_PLUS ? NRF_TWIM_FREQ_1000K :)) \
349
- I2C_NRFX_TWIM_INVALID_FREQUENCY)
350
-
351
- #define I2C (idx ) DT_NODELABEL(i2c##idx)
352
- #define I2C_HAS_PROP (idx , prop ) DT_NODE_HAS_PROP(I2C(idx), prop)
353
- #define I2C_FREQUENCY (idx ) \
354
- I2C_NRFX_TWIM_FREQUENCY(DT_PROP(I2C(idx), clock_frequency))
355
-
356
215
#define CONCAT_BUF_SIZE (idx ) \
357
216
COND_CODE_1(DT_NODE_HAS_PROP(I2C(idx), zephyr_concat_buf_size), \
358
217
(DT_PROP(I2C(idx), zephyr_concat_buf_size)), (0))
@@ -381,13 +240,15 @@ static int i2c_nrfx_twim_init(const struct device *dev)
381
240
I2C_MEMORY_SECTION(idx);)) \
382
241
static struct i2c_nrfx_twim_data twim_##idx##_data; \
383
242
PINCTRL_DT_DEFINE(I2C(idx)); \
384
- static const struct i2c_nrfx_twim_config twim_##idx##z_config = { \
243
+ static const \
244
+ struct i2c_nrfx_twim_common_config twim_##idx##z_config = { \
385
245
.twim = NRFX_TWIM_INSTANCE(idx), \
386
246
.twim_config = { \
387
247
.skip_gpio_cfg = true, \
388
248
.skip_psel_cfg = true, \
389
249
.frequency = I2C_FREQUENCY(idx), \
390
250
}, \
251
+ .event_handler = event_handler, \
391
252
.msg_buf_size = MSG_BUF_SIZE(idx), \
392
253
.irq_connect = irq_connect##idx, \
393
254
.pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2C(idx)), \
0 commit comments