2222#define  GPIO_HAS_PAD_GROUP  0
2323#endif 
2424
25+ #define  GPIOTE_PHANDLE (id ) DT_INST_PHANDLE(id, gpiote_instance)
26+ #define  GPIOTE_PROP (idx , prop )     DT_PROP(GPIOTE(idx), prop)
27+ 
28+ #define  IS_NO_PORT_INSTANCE (id ) DT_PROP_OR(GPIOTE_PHANDLE(id), no_port_event, 0) ||
29+ #define  IS_FIXED_CH_INSTANCE (id ) DT_PROP_OR(GPIOTE_PHANDLE(id), fixed_channels_supported, 0) ||
30+ 
31+ #if  DT_INST_FOREACH_STATUS_OKAY (IS_NO_PORT_INSTANCE ) 0 
32+ #define  GPIOTE_NO_PORT_EVT_SUPPORT  1
33+ #endif 
34+ 
35+ #if  DT_INST_FOREACH_STATUS_OKAY (IS_FIXED_CH_INSTANCE ) 0 
36+ #define  GPIOTE_FIXED_CH_SUPPORT  1
37+ #endif 
38+ 
39+ #if  defined(GPIOTE_NO_PORT_EVT_SUPPORT ) ||  defined(GPIOTE_FIXED_CH_SUPPORT )
40+ #define  GPIOTE_FEATURE_FLAG  1
41+ #define  GPIOTE_FLAG_NO_PORT_EVT  BIT(0)
42+ #define  GPIOTE_FLAG_FIXED_CHAN   BIT(1)
43+ #endif 
44+ 
2545struct  gpio_nrfx_data  {
2646	/* gpio_driver_data needs to be first */ 
2747	struct  gpio_driver_data  common ;
@@ -38,6 +58,9 @@ struct gpio_nrfx_cfg {
3858#if  GPIO_HAS_PAD_GROUP 
3959	const  struct  device  * pad_group ;
4060#endif 
61+ #if  defined(GPIOTE_FEATURE_FLAG )
62+ 	uint32_t  flags ;
63+ #endif 
4164};
4265
4366static  inline  struct  gpio_nrfx_data  * get_port_data (const  struct  device  * port )
@@ -77,6 +100,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
77100	nrfx_gpiote_pin_t  abs_pin  =  NRF_GPIO_PIN_MAP (cfg -> port_num , pin );
78101	nrf_gpio_pin_pull_t  pull  =  get_pull (flags );
79102	nrf_gpio_pin_drive_t  drive ;
103+ 	int  pm_ret ;
80104
81105	switch  (flags  &  (NRF_GPIO_DRIVE_MSK  | GPIO_OPEN_DRAIN )) {
82106	case  NRF_GPIO_DRIVE_S0S1 :
@@ -156,6 +180,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
156180				abs_pin , & input_pin_config );
157181			if  (err  !=  NRFX_SUCCESS ) {
158182				ret  =  - EINVAL ;
183+ 
159184				goto end ;
160185			}
161186		}
@@ -187,12 +212,20 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
187212	}
188213
189214	if  (IS_ENABLED (CONFIG_GPIO_NRFX_INTERRUPT ) &&  free_ch ) {
215+ #ifdef  GPIOTE_FEATURE_FLAG 
216+ 		/* Fixed channel was used, no need to free. */ 
217+ 		if  (cfg -> flags  &  GPIOTE_FLAG_FIXED_CHAN ) {
218+ 			goto end ;
219+ 		}
220+ #endif 
190221		err  =  nrfx_gpiote_channel_free (& cfg -> gpiote , ch );
191222		__ASSERT_NO_MSG (err  ==  NRFX_SUCCESS );
192223	}
193224
194225end :
195- 	return  pm_device_runtime_put (port );
226+ 	pm_ret  =  pm_device_runtime_put (port );
227+ 
228+ 	return  (ret  !=  0 ) ? ret  : pm_ret ;
196229}
197230
198231#ifdef  CONFIG_GPIO_GET_CONFIG 
@@ -360,6 +393,37 @@ static nrfx_gpiote_trigger_t get_trigger(enum gpio_int_mode mode,
360393					    NRFX_GPIOTE_TRIGGER_LOTOHI ;
361394}
362395
396+ static  nrfx_err_t  chan_alloc (const  struct  gpio_nrfx_cfg  * cfg , gpio_pin_t  pin , uint8_t  * ch )
397+ {
398+ #ifdef  GPIOTE_FEATURE_FLAG 
399+ 	if  (cfg -> flags  &  GPIOTE_FLAG_FIXED_CHAN ) {
400+ 		/* Currently fixed channel relation is only present in one instance (GPIOTE0 on 
401+ 		 * cpurad). The rules are following: 
402+ 		 * - GPIOTE0 can only be used with P1 (pins 4-11) and P2 (pins (0-11)) 
403+ 		 * - P1: channel => pin - 4, e.g. P1.4 => channel 0, P1.5 => channel 1 
404+ 		 * - P2: channel => pin % 8, e.g. P2.0 => channel 0, P2.8 => channel 0 
405+ 		 */ 
406+ 		nrfx_err_t  err  =  NRFX_SUCCESS ;
407+ 
408+ 		if  (cfg -> port_num  ==  1 ) {
409+ 			if  (pin  <  4 ) {
410+ 				err  =  NRFX_ERROR_INVALID_PARAM ;
411+ 			} else  {
412+ 				* ch  =  pin  -  4 ;
413+ 			}
414+ 		} else  if  (cfg -> port_num  ==  2 ) {
415+ 			* ch  =  pin  &  0x7 ;
416+ 		} else  {
417+ 			err  =  NRFX_ERROR_INVALID_PARAM ;
418+ 		}
419+ 
420+ 		return  err ;
421+ 	}
422+ #endif 
423+ 
424+ 	return  nrfx_gpiote_channel_alloc (& cfg -> gpiote , ch );
425+ }
426+ 
363427static  int  gpio_nrfx_pin_interrupt_configure (const  struct  device  * port ,
364428					     gpio_pin_t  pin ,
365429					     enum  gpio_int_mode  mode ,
@@ -395,14 +459,19 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
395459	    (nrf_gpio_pin_dir_get (abs_pin ) ==  NRF_GPIO_PIN_DIR_INPUT )) {
396460		err  =  nrfx_gpiote_channel_get (& cfg -> gpiote , abs_pin , & ch );
397461		if  (err  ==  NRFX_ERROR_INVALID_PARAM ) {
398- 			err  =  nrfx_gpiote_channel_alloc ( & cfg -> gpiote , & ch );
462+ 			err  =  chan_alloc ( cfg ,  pin , & ch );
399463			if  (err  !=  NRFX_SUCCESS ) {
400464				return  - ENOMEM ;
401465			}
402466		}
403467
404468		trigger_config .p_in_channel  =  & ch ;
405469	} else  {
470+ #ifdef  GPIOTE_FEATURE_FLAG 
471+ 		if  (cfg -> flags  &  GPIOTE_FLAG_NO_PORT_EVT ) {
472+ 			return  - ENOTSUP ;
473+ 		}
474+ #endif 
406475		/* If edge mode with channel was previously used and we are changing to sense or 
407476		 * level triggered, we must free the channel. 
408477		 */ 
@@ -600,7 +669,6 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
600669#endif 
601670};
602671
603- #define  GPIOTE_PHANDLE (id ) DT_INST_PHANDLE(id, gpiote_instance)
604672#define  GPIOTE_INST (id )    DT_PROP(GPIOTE_PHANDLE(id), instance)
605673
606674#define  GPIOTE_INSTANCE (id )                                     \
@@ -626,30 +694,37 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
626694#define  GPIO_NRF_PAD_GROUP_INIT (id )
627695#endif 
628696
629- #define  GPIO_NRF_DEVICE (id )						\
630- 	GPIOTE_CHECK(id);						\
631- 	static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = {	\
632- 		.common = {						\
633- 			.port_pin_mask =				\
634- 			GPIO_PORT_PIN_MASK_FROM_DT_INST(id),		\
635- 		},							\
636- 		.port = _CONCAT(NRF_P, DT_INST_PROP(id, port)),		\
637- 		.port_num = DT_INST_PROP(id, port),			\
638- 		.edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0),	\
639- 		.gpiote = GPIOTE_INSTANCE(id),				\
640- 		GPIO_NRF_PAD_GROUP_INIT(id)				\
641- 	};								\
642- 									\
643- 	static struct gpio_nrfx_data gpio_nrfx_p##id##_data;		\
644- 									\
645- 	PM_DEVICE_DT_INST_DEFINE(id, gpio_nrfx_pm_hook);		\
646- 									\
647- 	DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init,			\
648- 			 PM_DEVICE_DT_INST_GET(id),			\
649- 			 &gpio_nrfx_p##id##_data,			\
650- 			 &gpio_nrfx_p##id##_cfg,			\
651- 			 PRE_KERNEL_1,					\
652- 			 CONFIG_GPIO_INIT_PRIORITY,			\
697+ #define  GPIO_NRF_DEVICE (id )								\
698+ 	GPIOTE_CHECK(id);								\
699+ 	static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = {			\
700+ 		.common = {								\
701+ 			.port_pin_mask =						\
702+ 			GPIO_PORT_PIN_MASK_FROM_DT_INST(id),				\
703+ 		},									\
704+ 		.port = _CONCAT(NRF_P, DT_INST_PROP(id, port)),				\
705+ 		.port_num = DT_INST_PROP(id, port),					\
706+ 		.edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0),			\
707+ 		.gpiote = GPIOTE_INSTANCE(id),						\
708+ 		GPIO_NRF_PAD_GROUP_INIT(id)						\
709+ 		IF_ENABLED(GPIOTE_FEATURE_FLAG,						\
710+ 			(.flags =							\
711+ 			 (DT_PROP_OR(GPIOTE_PHANDLE(id), no_port_event, 0) ?		\
712+ 			    GPIOTE_FLAG_NO_PORT_EVT : 0) |				\
713+ 			 (DT_PROP_OR(GPIOTE_PHANDLE(id), fixed_channels_supported, 0) ?	\
714+ 			  GPIOTE_FLAG_FIXED_CHAN : 0),)					\
715+ 			)								\
716+ 	};										\
717+ 											\
718+ 	static struct gpio_nrfx_data gpio_nrfx_p##id##_data;				\
719+ 											\
720+ 	PM_DEVICE_DT_INST_DEFINE(id, gpio_nrfx_pm_hook);				\
721+ 											\
722+ 	DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init,					\
723+ 			 PM_DEVICE_DT_INST_GET(id),					\
724+ 			 &gpio_nrfx_p##id##_data,					\
725+ 			 &gpio_nrfx_p##id##_cfg,					\
726+ 			 PRE_KERNEL_1,							\
727+ 			 CONFIG_GPIO_INIT_PRIORITY,					\
653728			 &gpio_nrfx_drv_api_funcs);
654729
655730DT_INST_FOREACH_STATUS_OKAY (GPIO_NRF_DEVICE )
0 commit comments