55 */
66
77#include <zephyr/drivers/i2c.h>
8+ #include <zephyr/drivers/i2c/i2c_nrfx_twim.h>
89#include <zephyr/dt-bindings/i2c/i2c.h>
910#include <zephyr/pm/device.h>
1011#include <zephyr/pm/device_runtime.h>
@@ -31,8 +32,57 @@ struct i2c_nrfx_twim_data {
3132 struct k_sem transfer_sync ;
3233 struct k_sem completion_sync ;
3334 volatile nrfx_err_t res ;
35+ i2c_nrfx_twim_async_transfer_handler_t async_transfer_handler ;
36+ void * async_transfer_handler_ctx ;
3437};
3538
39+ int i2c_nrfx_twim_exclusive_access_acquire (const struct device * dev , k_timeout_t timeout )
40+ {
41+ struct i2c_nrfx_twim_data * dev_data = dev -> data ;
42+ int ret ;
43+
44+ ret = k_sem_take (& dev_data -> transfer_sync , timeout );
45+
46+ if (ret == 0 ) {
47+ (void )pm_device_runtime_get (dev );
48+ }
49+
50+ return ret ;
51+ }
52+
53+ void i2c_nrfx_twim_exclusive_access_release (const struct device * dev )
54+ {
55+ struct i2c_nrfx_twim_data * dev_data = dev -> data ;
56+
57+ (void )pm_device_runtime_put (dev );
58+
59+ k_sem_give (& dev_data -> transfer_sync );
60+ }
61+
62+ int i2c_nrfx_twim_async_transfer_begin (const struct device * dev , struct i2c_msg * msg , uint16_t addr ,
63+ i2c_nrfx_twim_async_transfer_handler_t handler , void * ctx )
64+ {
65+ struct i2c_nrfx_twim_data * dev_data = dev -> data ;
66+ const struct i2c_nrfx_twim_common_config * dev_config = dev -> config ;
67+
68+ if (I2C_MSG_ADDR_10_BITS & msg -> flags ) {
69+ return - ENOTSUP ;
70+ }
71+
72+ if (!nrf_dma_accessible_check (& dev_config -> twim , msg -> buf )) {
73+ return - ENOTSUP ;
74+ }
75+
76+ if (handler == NULL ) {
77+ return - ENOTSUP ;
78+ }
79+
80+ dev_data -> async_transfer_handler = handler ;
81+ dev_data -> async_transfer_handler_ctx = ctx ;
82+
83+ return i2c_nrfx_twim_msg_transfer (dev , msg -> flags , msg -> buf , msg -> len , addr );
84+ }
85+
3686static int i2c_nrfx_twim_transfer (const struct device * dev ,
3787 struct i2c_msg * msgs ,
3888 uint8_t num_msgs , uint16_t addr )
@@ -46,13 +96,11 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
4696 uint8_t * buf ;
4797 uint16_t buf_len ;
4898
49- k_sem_take ( & dev_data -> transfer_sync , K_FOREVER );
99+ ( void ) i2c_nrfx_twim_exclusive_access_acquire ( dev , K_FOREVER );
50100
51101 /* Dummy take on completion_sync sem to be sure that it is empty */
52102 k_sem_take (& dev_data -> completion_sync , K_NO_WAIT );
53103
54- (void )pm_device_runtime_get (dev );
55-
56104 for (size_t i = 0 ; i < num_msgs ; i ++ ) {
57105 if (I2C_MSG_ADDR_10_BITS & msgs [i ].flags ) {
58106 ret = - ENOTSUP ;
@@ -164,9 +212,7 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
164212 msg_buf_used = 0 ;
165213 }
166214
167- (void )pm_device_runtime_put (dev );
168-
169- k_sem_give (& dev_data -> transfer_sync );
215+ i2c_nrfx_twim_exclusive_access_release (dev );
170216
171217 return ret ;
172218}
@@ -191,6 +237,15 @@ static void event_handler(nrfx_twim_evt_t const *p_event, void *p_context)
191237 break ;
192238 }
193239
240+ if (dev_data -> async_transfer_handler != NULL ) {
241+ i2c_nrfx_twim_async_transfer_handler_t handler = dev_data -> async_transfer_handler ;
242+ void * ctx = dev_data -> async_transfer_handler_ctx ;
243+
244+ dev_data -> async_transfer_handler = NULL ;
245+ handler (dev , dev_data -> res == NRFX_SUCCESS ? 0 : - EIO , ctx );
246+ return ;
247+ }
248+
194249 k_sem_give (& dev_data -> completion_sync );
195250}
196251
0 commit comments