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