drivers: audio: dmic_nrfx_pdm: Add support for pinctrl

Add support for the new pinctrl API to the DMIC driver that handles
the nRF PDM peripheral. 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-01 17:02:33 +01:00 committed by Carles Cufí
commit 1c20443ce0
2 changed files with 47 additions and 8 deletions

View file

@ -6,6 +6,8 @@
#include <audio/dmic.h> #include <audio/dmic.h>
#include <drivers/clock_control/nrf_clock_control.h> #include <drivers/clock_control/nrf_clock_control.h>
#include <drivers/pinctrl.h>
#include <soc.h>
#include <nrfx_pdm.h> #include <nrfx_pdm.h>
#include <logging/log.h> #include <logging/log.h>
@ -26,6 +28,9 @@ struct dmic_nrfx_pdm_drv_data {
struct dmic_nrfx_pdm_drv_cfg { struct dmic_nrfx_pdm_drv_cfg {
nrfx_pdm_event_handler_t event_handler; nrfx_pdm_event_handler_t event_handler;
nrfx_pdm_config_t nrfx_def_cfg; nrfx_pdm_config_t nrfx_def_cfg;
#ifdef CONFIG_PINCTRL
const struct pinctrl_dev_config *pcfg;
#endif
enum clock_source { enum clock_source {
PCLK32M, PCLK32M,
PCLK32M_HFXO, PCLK32M_HFXO,
@ -532,15 +537,26 @@ static const struct _dmic_ops dmic_ops = {
}; };
#define PDM(idx) DT_NODELABEL(pdm##idx) #define PDM(idx) DT_NODELABEL(pdm##idx)
#define PDM_PIN(idx, name) DT_PROP_OR(PDM(idx), name##_pin, 0)
#define PDM_CLK_SRC(idx) DT_STRING_TOKEN(PDM(idx), clock_source) #define PDM_CLK_SRC(idx) DT_STRING_TOKEN(PDM(idx), clock_source)
#define PDM_NRFX_DEVICE(idx) \ #define PDM_NRFX_DEVICE(idx) \
NRF_DT_ENSURE_PINS_ASSIGNED(PDM(idx), clk_pin); \
static void *rx_msgs##idx[DT_PROP(PDM(idx), queue_size)]; \ static void *rx_msgs##idx[DT_PROP(PDM(idx), queue_size)]; \
static struct dmic_nrfx_pdm_drv_data dmic_nrfx_pdm_data##idx; \ static struct dmic_nrfx_pdm_drv_data dmic_nrfx_pdm_data##idx; \
static int pdm_nrfx_init##idx(const struct device *dev) \ static int pdm_nrfx_init##idx(const struct device *dev) \
{ \ { \
IRQ_CONNECT(DT_IRQN(PDM(idx)), DT_IRQ(PDM(idx), priority), \ IRQ_CONNECT(DT_IRQN(PDM(idx)), DT_IRQ(PDM(idx), priority), \
nrfx_isr, nrfx_pdm_irq_handler, 0); \ nrfx_isr, nrfx_pdm_irq_handler, 0); \
IF_ENABLED(CONFIG_PINCTRL, ( \
const struct dmic_nrfx_pdm_drv_cfg *drv_cfg = \
dev->config; \
int err = pinctrl_apply_state(drv_cfg->pcfg, \
PINCTRL_STATE_DEFAULT);\
if (err < 0) { \
return err; \
} \
)) \
k_msgq_init(&dmic_nrfx_pdm_data##idx.rx_queue, \ k_msgq_init(&dmic_nrfx_pdm_data##idx.rx_queue, \
(char *)rx_msgs##idx, sizeof(void *), \ (char *)rx_msgs##idx, sizeof(void *), \
ARRAY_SIZE(rx_msgs##idx)); \ ARRAY_SIZE(rx_msgs##idx)); \
@ -551,11 +567,15 @@ static const struct _dmic_ops dmic_ops = {
{ \ { \
event_handler(DEVICE_DT_GET(PDM(idx)), evt); \ event_handler(DEVICE_DT_GET(PDM(idx)), evt); \
} \ } \
IF_ENABLED(CONFIG_PINCTRL, (PINCTRL_DT_DEFINE(PDM(idx)))); \
static const struct dmic_nrfx_pdm_drv_cfg dmic_nrfx_pdm_cfg##idx = { \ static const struct dmic_nrfx_pdm_drv_cfg dmic_nrfx_pdm_cfg##idx = { \
.event_handler = event_handler##idx, \ .event_handler = event_handler##idx, \
.nrfx_def_cfg = NRFX_PDM_DEFAULT_CONFIG( \ .nrfx_def_cfg = NRFX_PDM_DEFAULT_CONFIG(PDM_PIN(idx, clk), \
DT_PROP(PDM(idx), clk_pin), \ PDM_PIN(idx, din)), \
DT_PROP(PDM(idx), din_pin)), \ IF_ENABLED(CONFIG_PINCTRL, \
(.nrfx_def_cfg.skip_gpio_cfg = true, \
.nrfx_def_cfg.skip_psel_cfg = true, \
.pcfg = PINCTRL_DT_DEV_CONFIG_GET(PDM(idx)),)) \
.clk_src = PDM_CLK_SRC(idx), \ .clk_src = PDM_CLK_SRC(idx), \
}; \ }; \
BUILD_ASSERT(PDM_CLK_SRC(idx) != ACLK || NRF_PDM_HAS_MCLKCONFIG, \ BUILD_ASSERT(PDM_CLK_SRC(idx) != ACLK || NRF_PDM_HAS_MCLKCONFIG, \

View file

@ -5,7 +5,7 @@ description: Nordic PDM (Pulse Density Modulation interface)
compatible: "nordic,nrf-pdm" compatible: "nordic,nrf-pdm"
include: base.yaml include: [base.yaml, pinctrl-device.yaml]
properties: properties:
reg: reg:
@ -16,13 +16,32 @@ properties:
clk-pin: clk-pin:
type: int type: int
required: true required: false
description: CLK pin 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 CLK pin to use.
For pins P0.0 through P0.31, use the pin number. For example,
to use P0.16 for CLK, set:
clk-pin = <16>;
For pins P1.0 through P1.31, add 32 to the pin number. For
example, to use P1.2 for CLK, set:
clk-pin = <34>; /* 32 + 2 */
din-pin: din-pin:
type: int type: int
required: true required: false
description: DIN pin 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 DIN pin to use. The pin numbering scheme is the same as
the clk-pin property's.
clock-source: clock-source:
type: string type: string