drivers: sensor: qdec_nrfx: Add support for pinctrl

Add support for the new pinctrl API to the nRF QDEC driver.
Update code of the driver and the related devicetree binding.

Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
This commit is contained in:
Andrzej Głąbek 2022-03-08 14:01:51 +01:00 committed by Carles Cufí
commit 1a01ca2adf
2 changed files with 64 additions and 15 deletions

View file

@ -6,6 +6,8 @@
#include <drivers/sensor.h> #include <drivers/sensor.h>
#include <pm/device.h> #include <pm/device.h>
#include <drivers/pinctrl.h>
#include <soc.h>
#include <nrfx_qdec.h> #include <nrfx_qdec.h>
#include <hal/nrf_gpio.h> #include <hal/nrf_gpio.h>
@ -27,9 +29,14 @@ struct qdec_nrfx_data {
sensor_trigger_handler_t data_ready_handler; sensor_trigger_handler_t data_ready_handler;
}; };
static struct qdec_nrfx_data qdec_nrfx_data; static struct qdec_nrfx_data qdec_nrfx_data;
#ifdef CONFIG_PINCTRL
PINCTRL_DT_DEFINE(DT_DRV_INST(0));
static const struct pinctrl_dev_config *qdec_nrfx_pcfg =
PINCTRL_DT_DEV_CONFIG_GET(DT_DRV_INST(0));
#endif
static void accumulate(struct qdec_nrfx_data *data, int16_t acc) static void accumulate(struct qdec_nrfx_data *data, int16_t acc)
{ {
unsigned int key = irq_lock(); unsigned int key = irq_lock();
@ -166,23 +173,24 @@ static void qdec_nrfx_gpio_ctrl(bool enable)
#endif #endif
} }
NRF_DT_ENSURE_PINS_ASSIGNED(DT_DRV_INST(0), a_pin);
static int qdec_nrfx_init(const struct device *dev) static int qdec_nrfx_init(const struct device *dev)
{ {
static const nrfx_qdec_config_t config = { static const nrfx_qdec_config_t config = {
.reportper = NRF_QDEC_REPORTPER_40, .reportper = NRF_QDEC_REPORTPER_40,
.sampleper = NRF_QDEC_SAMPLEPER_2048us, .sampleper = NRF_QDEC_SAMPLEPER_2048us,
.psela = DT_INST_PROP(0, a_pin), #ifdef CONFIG_PINCTRL
.pselb = DT_INST_PROP(0, b_pin), .skip_gpio_cfg = true,
#if DT_INST_NODE_HAS_PROP(0, led_pin) .skip_psel_cfg = true,
.pselled = DT_INST_PROP(0, led_pin),
#else #else
.pselled = 0xFFFFFFFF, /* disabled */ .psela = DT_INST_PROP(0, a_pin),
.pselb = DT_INST_PROP(0, b_pin),
.pselled = DT_INST_PROP_OR(0, led_pin,
NRF_QDEC_LED_NOT_CONNECTED),
#endif #endif
.ledpre = DT_INST_PROP(0, led_pre), .ledpre = DT_INST_PROP(0, led_pre),
.ledpol = NRF_QDEC_LEPOL_ACTIVE_HIGH, .ledpol = NRF_QDEC_LEPOL_ACTIVE_HIGH,
.interrupt_priority = NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY,
.dbfen = 0, /* disabled */
.sample_inten = 0, /* disabled */
}; };
nrfx_err_t nerr; nrfx_err_t nerr;
@ -192,6 +200,14 @@ static int qdec_nrfx_init(const struct device *dev)
IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
nrfx_isr, nrfx_qdec_irq_handler, 0); nrfx_isr, nrfx_qdec_irq_handler, 0);
#ifdef CONFIG_PINCTRL
int ret = pinctrl_apply_state(qdec_nrfx_pcfg, PINCTRL_STATE_DEFAULT);
if (ret < 0) {
return ret;
}
#endif
nerr = nrfx_qdec_init(&config, qdec_nrfx_event_handler); nerr = nrfx_qdec_init(&config, qdec_nrfx_event_handler);
if (nerr == NRFX_ERROR_INVALID_STATE) { if (nerr == NRFX_ERROR_INVALID_STATE) {
LOG_ERR("qdec already in use"); LOG_ERR("qdec already in use");
@ -211,27 +227,51 @@ static int qdec_nrfx_init(const struct device *dev)
static int qdec_nrfx_pm_action(const struct device *dev, static int qdec_nrfx_pm_action(const struct device *dev,
enum pm_device_action action) enum pm_device_action action)
{ {
int ret = 0;
ARG_UNUSED(dev); ARG_UNUSED(dev);
switch (action) { switch (action) {
case PM_DEVICE_ACTION_RESUME: case PM_DEVICE_ACTION_RESUME:
#ifdef CONFIG_PINCTRL
ret = pinctrl_apply_state(qdec_nrfx_pcfg,
PINCTRL_STATE_DEFAULT);
if (ret < 0) {
return ret;
}
#endif
qdec_nrfx_gpio_ctrl(true); qdec_nrfx_gpio_ctrl(true);
nrfx_qdec_enable(); nrfx_qdec_enable();
break; break;
case PM_DEVICE_ACTION_TURN_OFF: case PM_DEVICE_ACTION_TURN_OFF:
/* device must be uninitialized */ /* device must be uninitialized */
nrfx_qdec_uninit(); nrfx_qdec_uninit();
#ifdef CONFIG_PINCTRL
ret = pinctrl_apply_state(qdec_nrfx_pcfg,
PINCTRL_STATE_SLEEP);
if (ret < 0) {
return ret;
}
#endif
break; break;
case PM_DEVICE_ACTION_SUSPEND: case PM_DEVICE_ACTION_SUSPEND:
/* device must be suspended */ /* device must be suspended */
nrfx_qdec_disable(); nrfx_qdec_disable();
qdec_nrfx_gpio_ctrl(false); qdec_nrfx_gpio_ctrl(false);
#ifdef CONFIG_PINCTRL
ret = pinctrl_apply_state(qdec_nrfx_pcfg,
PINCTRL_STATE_SLEEP);
if (ret < 0) {
return ret;
}
#endif
break; break;
default: default:
return -ENOTSUP; return -ENOTSUP;
} }
return 0; return ret;
} }
#endif /* CONFIG_PM_DEVICE */ #endif /* CONFIG_PM_DEVICE */

View file

@ -5,7 +5,7 @@ description: Nordic nRF quadrature decoder (QDEC) node
compatible: "nordic,nrf-qdec" compatible: "nordic,nrf-qdec"
include: base.yaml include: [base.yaml, pinctrl-device.yaml]
properties: properties:
reg: reg:
@ -18,6 +18,9 @@ properties:
type: int type: int
required: true required: true
description: | description: |
IMPORTANT: This option will only be used if the new pin control driver
is not enabled. It will be deprecated in the future.
The A pin to use. The A pin to use.
For pins P0.0 through P0.31, use the pin number. For example, For pins P0.0 through P0.31, use the pin number. For example,
@ -34,6 +37,9 @@ properties:
type: int type: int
required: true required: true
description: | description: |
IMPORTANT: This option will only be used if the new pin control driver
is not enabled. It will be deprecated in the future.
The B pin to use. The pin numbering scheme is the same as The B pin to use. The pin numbering scheme is the same as
the a-pin property's. the a-pin property's.
@ -41,6 +47,9 @@ properties:
type: int type: int
required: false required: false
description: | description: |
IMPORTANT: This option will only be used if the new pin control driver
is not enabled. It will be deprecated in the future.
The LED pin to use for a light based QDEC device. The pin The LED pin to use for a light based QDEC device. The pin
numbering scheme is the same as the a-pin property's. numbering scheme is the same as the a-pin property's.