44 * SPDX-License-Identifier: Apache-2.0
55 */
66
7-
87#include <zephyr/drivers/i2c.h>
98#include <zephyr/dt-bindings/i2c/i2c.h>
109#include <zephyr/pm/device.h>
1716
1817#include <zephyr/logging/log.h>
1918#include <zephyr/irq.h>
19+
20+ #include "i2c_nrfx_twim_common.h"
21+
2022LOG_MODULE_REGISTER (i2c_nrfx_twim , CONFIG_I2C_LOG_LEVEL );
2123
2224#if CONFIG_I2C_NRFX_TRANSFER_TIMEOUT
@@ -31,31 +33,18 @@ struct i2c_nrfx_twim_data {
3133 volatile nrfx_err_t res ;
3234};
3335
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-
4636static int i2c_nrfx_twim_transfer (const struct device * dev ,
4737 struct i2c_msg * msgs ,
4838 uint8_t num_msgs , uint16_t addr )
4939{
5040 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 ;
5242 int ret = 0 ;
5343 uint8_t * msg_buf = dev_config -> msg_buf ;
5444 uint16_t msg_buf_used = 0 ;
5545 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 ;
5948
6049 k_sem_take (& dev_data -> transfer_sync , K_FOREVER );
6150
@@ -116,35 +105,15 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
116105 }
117106
118107 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 ;
121110 } 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 ;
134113 }
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 ;
148117 }
149118
150119 ret = k_sem_take (& dev_data -> completion_sync ,
@@ -171,18 +140,15 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
171140 break ;
172141 }
173142
174- res = dev_data -> res ;
175-
176- if (res != NRFX_SUCCESS ) {
143+ if (dev_data -> res != NRFX_SUCCESS ) {
177144 ret = - EIO ;
178145 break ;
179146 }
180147
181148 /* If concatenated messages were I2C_MSG_READ type, then
182149 * content of concatenation buffer has to be copied back into
183150 * 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 )) {
186152 int j = i ;
187153
188154 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)
227193 k_sem_give (& dev_data -> completion_sync );
228194}
229195
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 )
263197{
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 ;
278199
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 );
287202
288- return ( err == NRFX_SUCCESS ? 0 : - EBUSY );
203+ return i2c_nrfx_twim_common_init ( dev );
289204}
290205
291206static 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 = {
297212 .recover_bus = i2c_nrfx_twim_recover_bus ,
298213};
299214
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-
356215#define CONCAT_BUF_SIZE (idx ) \
357216 COND_CODE_1(DT_NODE_HAS_PROP(I2C(idx), zephyr_concat_buf_size), \
358217 (DT_PROP(I2C(idx), zephyr_concat_buf_size)), (0))
@@ -381,13 +240,15 @@ static int i2c_nrfx_twim_init(const struct device *dev)
381240 I2C_MEMORY_SECTION(idx);)) \
382241 static struct i2c_nrfx_twim_data twim_##idx##_data; \
383242 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 = { \
385245 .twim = NRFX_TWIM_INSTANCE(idx), \
386246 .twim_config = { \
387247 .skip_gpio_cfg = true, \
388248 .skip_psel_cfg = true, \
389249 .frequency = I2C_FREQUENCY(idx), \
390250 }, \
251+ .event_handler = event_handler, \
391252 .msg_buf_size = MSG_BUF_SIZE(idx), \
392253 .irq_connect = irq_connect##idx, \
393254 .pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2C(idx)), \
0 commit comments