@@ -43,6 +43,7 @@ BUILD_ASSERT(NRF_QDEC_SAMPLEPER_16384US == SAMPLEPER_16384US,
4343	     "Different SAMPLEPER register values in devicetree binding and nRF HAL" );
4444
4545struct  qdec_nrfx_data  {
46+ 	nrfx_qdec_t  qdec ;
4647	int32_t  fetched_acc ;
4748	int32_t  acc ;
4849	bool  overflow ;
@@ -51,7 +52,6 @@ struct qdec_nrfx_data {
5152};
5253
5354struct  qdec_nrfx_config  {
54- 	nrfx_qdec_t  qdec ;
5555	nrfx_qdec_config_t  config ;
5656	void  (* irq_connect )(void );
5757	const  struct  pinctrl_dev_config  * pcfg ;
@@ -78,7 +78,6 @@ static void accumulate(struct qdec_nrfx_data *data, int32_t acc)
7878static  int  qdec_nrfx_sample_fetch (const  struct  device  * dev ,
7979				  enum  sensor_channel  chan )
8080{
81- 	const  struct  qdec_nrfx_config  * config  =  dev -> config ;
8281	struct  qdec_nrfx_data  * data  =  dev -> data ;
8382	int32_t  acc ;
8483	uint32_t  accdbl ;
@@ -87,7 +86,7 @@ static int qdec_nrfx_sample_fetch(const struct device *dev,
8786		return  - ENOTSUP ;
8887	}
8988
90- 	nrfx_qdec_accumulators_read (& config -> qdec , & acc , & accdbl );
89+ 	nrfx_qdec_accumulators_read (& data -> qdec , & acc , & accdbl );
9190
9291	accumulate (data , acc );
9392
@@ -212,8 +211,9 @@ static DEVICE_API(sensor, qdec_nrfx_driver_api) = {
212211static  void  qdec_pm_suspend (const  struct  device  * dev )
213212{
214213	const  struct  qdec_nrfx_config  * config  =  dev -> config ;
214+ 	struct  qdec_nrfx_data  * dev_data  =  dev -> data ;
215215
216- 	nrfx_qdec_disable (& config -> qdec );
216+ 	nrfx_qdec_disable (& dev_data -> qdec );
217217	qdec_nrfx_gpio_ctrl (dev , false);
218218
219219	(void )pinctrl_apply_state (config -> pcfg , PINCTRL_STATE_SLEEP );
@@ -222,10 +222,11 @@ static void qdec_pm_suspend(const struct device *dev)
222222static  void  qdec_pm_resume (const  struct  device  * dev )
223223{
224224	const  struct  qdec_nrfx_config  * config  =  dev -> config ;
225+ 	struct  qdec_nrfx_data  * dev_data  =  dev -> data ;
225226
226227	(void )pinctrl_apply_state (config -> pcfg , PINCTRL_STATE_DEFAULT );
227228	qdec_nrfx_gpio_ctrl (dev , true);
228- 	nrfx_qdec_enable (& config -> qdec );
229+ 	nrfx_qdec_enable (& dev_data -> qdec );
229230}
230231
231232static  int  qdec_nrfx_pm_action (const  struct  device  * dev , enum  pm_device_action  action )
@@ -251,13 +252,15 @@ static int qdec_nrfx_pm_action(const struct device *dev, enum pm_device_action a
251252static  int  qdec_nrfx_init (const  struct  device  * dev )
252253{
253254	const  struct  qdec_nrfx_config  * config  =  dev -> config ;
254- 	nrfx_err_t  nerr ;
255+ 	struct  qdec_nrfx_data  * dev_data  =  dev -> data ;
256+ 	int  nerr ;
255257
256258	config -> irq_connect ();
257259
258- 	nerr  =  nrfx_qdec_init (& config -> qdec , & config -> config , qdec_nrfx_event_handler , (void  * )dev );
259- 	if  (nerr  !=  NRFX_SUCCESS ) {
260- 		return  (nerr  ==  NRFX_ERROR_INVALID_STATE ) ? - EBUSY  : - EFAULT ;
260+ 	nerr  =  nrfx_qdec_init (& dev_data -> qdec , & config -> config , qdec_nrfx_event_handler ,
261+ 		(void  * )dev );
262+ 	if  (nerr  !=  0 ) {
263+ 		return  - EALREADY ;
261264	}
262265
263266	/* End up in suspend state. */ 
@@ -269,88 +272,63 @@ static int qdec_nrfx_init(const struct device *dev)
269272	return  pm_device_driver_init (dev , qdec_nrfx_pm_action );
270273}
271274
272- #define  QDEC (idx )			DT_NODELABEL(qdec##idx)
273- #define  QDEC_PROP (idx , prop )		DT_PROP(QDEC(idx), prop)
274- 
275275/* Macro determines PM actions interrupt safety level. 
276276 * 
277277 * Requesting/releasing QDEC device may be ISR safe, but it cannot be reliably known whether 
278278 * managing its power domain is. It is then assumed that if power domains are used, device is 
279279 * no longer ISR safe. This macro let's us check if we will be requesting/releasing 
280280 * power domains and determines PM device ISR safety value. 
281281 */ 
282- #define  QDEC_PM_ISR_SAFE (idx )									\
283- 	COND_CODE_1(										\
284- 		UTIL_AND(									\
285- 			IS_ENABLED(CONFIG_PM_DEVICE_POWER_DOMAIN),				\
286- 			UTIL_AND(								\
287- 				DT_NODE_HAS_PROP(QDEC(idx), power_domains),			\
288- 				DT_NODE_HAS_STATUS_OKAY(DT_PHANDLE(QDEC(idx), power_domains))	\
289- 			)									\
290- 		),										\
291- 		(0),										\
292- 		(PM_DEVICE_ISR_SAFE)								\
282+ #define  QDEC_PM_ISR_SAFE (inst )								        \
283+ 	COND_CODE_1(									        \
284+ 		UTIL_AND(								        \
285+ 			IS_ENABLED(CONFIG_PM_DEVICE_POWER_DOMAIN),			        \
286+ 			UTIL_AND(DT_INST_NODE_HAS_PROP(inst, power_domains),		        \
287+ 				 DT_NODE_HAS_STATUS_OKAY(DT_INST_PHANDLE(inst, power_domains))) \
288+ 		),									        \
289+ 		(0),									        \
290+ 		(PM_DEVICE_ISR_SAFE)							        \
293291	)
294292
295- #define  SENSOR_NRFX_QDEC_DEVICE (idx )							     \
296- 	NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(QDEC(idx));					     \
297- 	BUILD_ASSERT(QDEC_PROP(idx, steps) > 0,						     \
298- 		     "Wrong QDEC"#idx" steps setting in dts. Only positive number valid");   \
299- 	BUILD_ASSERT(QDEC_PROP(idx, steps) <= 2048,					     \
300- 		     "Wrong QDEC"#idx" steps setting in dts. Overflow possible");	     \
301- 	static void irq_connect##idx(void)						     \
302- 	{										     \
303- 		IRQ_CONNECT(DT_IRQN(QDEC(idx)), DT_IRQ(QDEC(idx), priority),		     \
304- 			    nrfx_isr, nrfx_qdec_##idx##_irq_handler, 0);		     \
305- 	}										     \
306- 	static struct qdec_nrfx_data qdec_##idx##_data;					     \
307- 	PINCTRL_DT_DEFINE(QDEC(idx));							     \
308- 	static struct qdec_nrfx_config qdec_##idx##_config = {				     \
309- 		.qdec = NRFX_QDEC_INSTANCE(idx),					     \
310- 		.config = {								     \
311- 			.reportper = NRF_QDEC_REPORTPER_40,				     \
312- 			.sampleper = DT_STRING_TOKEN(QDEC(idx), nordic_period),              \
313- 			.skip_gpio_cfg = true,						     \
314- 			.skip_psel_cfg = true,						     \
315- 			.ledpre  = QDEC_PROP(idx, led_pre),				     \
316- 			.ledpol  = NRF_QDEC_LEPOL_ACTIVE_HIGH,				     \
317- 			.reportper_inten = true,					     \
318- 		},									     \
319- 		.irq_connect = irq_connect##idx,					     \
320- 		.pcfg = PINCTRL_DT_DEV_CONFIG_GET(QDEC(idx)),				     \
321- 		.enable_pin = DT_PROP_OR(QDEC(idx), enable_pin, NRF_QDEC_PIN_NOT_CONNECTED), \
322- 		.steps = QDEC_PROP(idx, steps),						     \
323- 	};										     \
324- 	PM_DEVICE_DT_DEFINE(QDEC(idx), qdec_nrfx_pm_action, QDEC_PM_ISR_SAFE(idx));	     \
325- 	SENSOR_DEVICE_DT_DEFINE(QDEC(idx),						     \
326- 				qdec_nrfx_init,						     \
327- 				PM_DEVICE_DT_GET(QDEC(idx)),				     \
328- 				&qdec_##idx##_data,					     \
329- 				&qdec_##idx##_config,					     \
330- 				POST_KERNEL,						     \
331- 				CONFIG_SENSOR_INIT_PRIORITY,				     \
293+ #define  SENSOR_NRFX_QDEC_DEVICE (inst )							    \
294+ 	NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(DT_DRV_INST(inst));			            \
295+ 	BUILD_ASSERT(DT_INST_PROP(inst, steps) > 0,				            \
296+ 		     "Wrong QDEC"#inst" steps setting in dts. Only positive number valid"); \
297+ 	BUILD_ASSERT(DT_INST_PROP(inst, steps) <= 2048,					    \
298+ 		     "Wrong QDEC"#inst" steps setting in dts. Overflow possible");	    \
299+ 	static struct qdec_nrfx_data qdec_##inst##_data = {				    \
300+ 		.qdec = NRFX_QDEC_INSTANCE(DT_INST_REG_ADDR(inst)),			    \
301+ 	};										    \
302+ 	static void irq_connect##inst(void)						    \
303+ 	{										    \
304+ 		IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority),		    \
305+ 			nrfx_qdec_irq_handler, &qdec_##inst##_data.qdec, 0);		    \
306+ 	}										    \
307+ 	PINCTRL_DT_DEFINE(DT_DRV_INST(inst));						    \
308+ 	static struct qdec_nrfx_config qdec_##inst##_config = {				    \
309+ 		.config = {								    \
310+ 			.reportper = NRF_QDEC_REPORTPER_40,				    \
311+ 			.sampleper = DT_STRING_TOKEN(DT_DRV_INST(inst), nordic_period),	    \
312+ 			.skip_gpio_cfg = true,						    \
313+ 			.skip_psel_cfg = true,						    \
314+ 			.ledpre  = DT_INST_PROP(inst, led_pre),				    \
315+ 			.ledpol  = NRF_QDEC_LEPOL_ACTIVE_HIGH,				    \
316+ 			.reportper_inten = true,					    \
317+ 		},									    \
318+ 		.irq_connect = irq_connect##inst,					    \
319+ 		.pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_DRV_INST(inst)),			    \
320+ 		.enable_pin = DT_PROP_OR(						    \
321+ 			DT_DRV_INST(inst), enable_pin, NRF_QDEC_PIN_NOT_CONNECTED),	    \
322+ 		.steps = DT_INST_PROP(inst, steps),					    \
323+ 	};										    \
324+ 	PM_DEVICE_DT_INST_DEFINE(inst, qdec_nrfx_pm_action, QDEC_PM_ISR_SAFE(inst));	    \
325+ 	SENSOR_DEVICE_DT_DEFINE(DT_DRV_INST(inst),					    \
326+ 				qdec_nrfx_init,						    \
327+ 				PM_DEVICE_DT_INST_GET(inst),				    \
328+ 				&qdec_##inst##_data,					    \
329+ 				&qdec_##inst##_config,					    \
330+ 				POST_KERNEL,						    \
331+ 				CONFIG_SENSOR_INIT_PRIORITY,				    \
332332				&qdec_nrfx_driver_api)
333333
334- #ifdef  CONFIG_HAS_HW_NRF_QDEC0 
335- SENSOR_NRFX_QDEC_DEVICE (0 );
336- #endif 
337- 
338- #ifdef  CONFIG_HAS_HW_NRF_QDEC1 
339- SENSOR_NRFX_QDEC_DEVICE (1 );
340- #endif 
341- 
342- #ifdef  CONFIG_HAS_HW_NRF_QDEC20 
343- SENSOR_NRFX_QDEC_DEVICE (20 );
344- #endif 
345- 
346- #ifdef  CONFIG_HAS_HW_NRF_QDEC21 
347- SENSOR_NRFX_QDEC_DEVICE (21 );
348- #endif 
349- 
350- #ifdef  CONFIG_HAS_HW_NRF_QDEC130 
351- SENSOR_NRFX_QDEC_DEVICE (130 );
352- #endif 
353- 
354- #ifdef  CONFIG_HAS_HW_NRF_QDEC131 
355- SENSOR_NRFX_QDEC_DEVICE (131 );
356- #endif 
334+ DT_INST_FOREACH_STATUS_OKAY (SENSOR_NRFX_QDEC_DEVICE )
0 commit comments