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,64 @@ 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+ uint8_t * buf ;
68+
69+ if (I2C_MSG_ADDR_10_BITS & msg -> flags ) {
70+ return - ENOTSUP ;
71+ }
72+
73+ if (!nrf_dma_accessible_check (& dev_config -> twim , msg -> buf )) {
74+ if (msg -> len > dev_config -> msg_buf_size ) {
75+ return - ENOSPC ;
76+ }
77+ memcpy (dev_config -> msg_buf , msg -> buf , msg -> len );
78+ buf = dev_config -> msg_buf ;
79+ } else {
80+ buf = msg -> buf ;
81+ }
82+
83+ if (handler == NULL ) {
84+ return - ENOTSUP ;
85+ }
86+
87+ dev_data -> async_transfer_handler = handler ;
88+ dev_data -> async_transfer_handler_ctx = ctx ;
89+
90+ return i2c_nrfx_twim_msg_transfer (dev , msg -> flags , buf , msg -> len , addr );
91+ }
92+
3693static int i2c_nrfx_twim_transfer (const struct device * dev ,
3794 struct i2c_msg * msgs ,
3895 uint8_t num_msgs , uint16_t addr )
@@ -46,13 +103,11 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
46103 uint8_t * buf ;
47104 uint16_t buf_len ;
48105
49- k_sem_take ( & dev_data -> transfer_sync , K_FOREVER );
106+ ( void ) i2c_nrfx_twim_exclusive_access_acquire ( dev , K_FOREVER );
50107
51108 /* Dummy take on completion_sync sem to be sure that it is empty */
52109 k_sem_take (& dev_data -> completion_sync , K_NO_WAIT );
53110
54- (void )pm_device_runtime_get (dev );
55-
56111 for (size_t i = 0 ; i < num_msgs ; i ++ ) {
57112 if (I2C_MSG_ADDR_10_BITS & msgs [i ].flags ) {
58113 ret = - ENOTSUP ;
@@ -164,9 +219,7 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
164219 msg_buf_used = 0 ;
165220 }
166221
167- (void )pm_device_runtime_put (dev );
168-
169- k_sem_give (& dev_data -> transfer_sync );
222+ i2c_nrfx_twim_exclusive_access_release (dev );
170223
171224 return ret ;
172225}
@@ -191,6 +244,15 @@ static void event_handler(nrfx_twim_evt_t const *p_event, void *p_context)
191244 break ;
192245 }
193246
247+ if (dev_data -> async_transfer_handler != NULL ) {
248+ i2c_nrfx_twim_async_transfer_handler_t handler = dev_data -> async_transfer_handler ;
249+ void * ctx = dev_data -> async_transfer_handler_ctx ;
250+
251+ dev_data -> async_transfer_handler = NULL ;
252+ handler (dev , dev_data -> res == NRFX_SUCCESS ? 0 : - EIO , ctx );
253+ return ;
254+ }
255+
194256 k_sem_give (& dev_data -> completion_sync );
195257}
196258
0 commit comments