@@ -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