drivers: i2c: nrfx: Add support for pinctrl
Add support for the new pinctrl API to the I2C drivers that handle the nRF TWI and TWIM peripherals. Update code of the drivers and related devicetree bindings. Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
This commit is contained in:
parent
32b9e65e4b
commit
b2a4a3672f
3 changed files with 95 additions and 9 deletions
|
@ -8,6 +8,8 @@
|
|||
#include <drivers/i2c.h>
|
||||
#include <dt-bindings/i2c/i2c.h>
|
||||
#include <pm/device.h>
|
||||
#include <drivers/pinctrl.h>
|
||||
#include <soc.h>
|
||||
#include <nrfx_twi.h>
|
||||
|
||||
#include <logging/log.h>
|
||||
|
@ -25,6 +27,9 @@ struct i2c_nrfx_twi_data {
|
|||
struct i2c_nrfx_twi_config {
|
||||
nrfx_twi_t twi;
|
||||
nrfx_twi_config_t config;
|
||||
#ifdef CONFIG_PINCTRL
|
||||
const struct pinctrl_dev_config *pcfg;
|
||||
#endif
|
||||
};
|
||||
|
||||
static int i2c_nrfx_twi_transfer(const struct device *dev,
|
||||
|
@ -228,6 +233,13 @@ static int twi_nrfx_pm_action(const struct device *dev,
|
|||
|
||||
switch (action) {
|
||||
case PM_DEVICE_ACTION_RESUME:
|
||||
#ifdef CONFIG_PINCTRL
|
||||
ret = pinctrl_apply_state(config->pcfg,
|
||||
PINCTRL_STATE_DEFAULT);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
init_twi(dev);
|
||||
if (data->dev_config) {
|
||||
i2c_nrfx_twi_configure(dev, data->dev_config);
|
||||
|
@ -236,6 +248,14 @@ static int twi_nrfx_pm_action(const struct device *dev,
|
|||
|
||||
case PM_DEVICE_ACTION_SUSPEND:
|
||||
nrfx_twi_uninit(&config->twi);
|
||||
|
||||
#ifdef CONFIG_PINCTRL
|
||||
ret = pinctrl_apply_state(config->pcfg,
|
||||
PINCTRL_STATE_SLEEP);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -256,14 +276,30 @@ static int twi_nrfx_pm_action(const struct device *dev,
|
|||
#define I2C_FREQUENCY(idx) \
|
||||
I2C_NRFX_TWI_FREQUENCY(DT_PROP(I2C(idx), clock_frequency))
|
||||
|
||||
#define I2C_NRFX_TWI_PIN_CFG(idx) \
|
||||
COND_CODE_1(CONFIG_PINCTRL, \
|
||||
(.skip_gpio_cfg = true, \
|
||||
.skip_psel_cfg = true,), \
|
||||
(.scl = DT_PROP(I2C(idx), scl_pin), \
|
||||
.sda = DT_PROP(I2C(idx), sda_pin),))
|
||||
|
||||
#define I2C_NRFX_TWI_DEVICE(idx) \
|
||||
NRF_DT_ENSURE_PINS_ASSIGNED(I2C(idx), scl_pin); \
|
||||
BUILD_ASSERT(I2C_FREQUENCY(idx) != \
|
||||
I2C_NRFX_TWI_INVALID_FREQUENCY, \
|
||||
"Wrong I2C " #idx " frequency setting in dts"); \
|
||||
static int twi_##idx##_init(const struct device *dev) \
|
||||
static int twi_##idx##_init(const struct device *dev) \
|
||||
{ \
|
||||
IRQ_CONNECT(DT_IRQN(I2C(idx)), DT_IRQ(I2C(idx), priority), \
|
||||
nrfx_isr, nrfx_twi_##idx##_irq_handler, 0); \
|
||||
IF_ENABLED(CONFIG_PINCTRL, ( \
|
||||
const struct i2c_nrfx_twi_config *config = dev->config;\
|
||||
int err = pinctrl_apply_state(config->pcfg, \
|
||||
PINCTRL_STATE_DEFAULT); \
|
||||
if (err < 0) { \
|
||||
return err; \
|
||||
} \
|
||||
)) \
|
||||
return init_twi(dev); \
|
||||
} \
|
||||
static struct i2c_nrfx_twi_data twi_##idx##_data = { \
|
||||
|
@ -272,13 +308,15 @@ static int twi_nrfx_pm_action(const struct device *dev,
|
|||
.completion_sync = Z_SEM_INITIALIZER( \
|
||||
twi_##idx##_data.completion_sync, 0, 1) \
|
||||
}; \
|
||||
IF_ENABLED(CONFIG_PINCTRL, (PINCTRL_DT_DEFINE(I2C(idx)))); \
|
||||
static const struct i2c_nrfx_twi_config twi_##idx##z_config = { \
|
||||
.twi = NRFX_TWI_INSTANCE(idx), \
|
||||
.config = { \
|
||||
.scl = DT_PROP(I2C(idx), scl_pin), \
|
||||
.sda = DT_PROP(I2C(idx), sda_pin), \
|
||||
I2C_NRFX_TWI_PIN_CFG(idx) \
|
||||
.frequency = I2C_FREQUENCY(idx), \
|
||||
} \
|
||||
}, \
|
||||
IF_ENABLED(CONFIG_PINCTRL, \
|
||||
(.pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2C(idx)),)) \
|
||||
}; \
|
||||
PM_DEVICE_DT_DEFINE(I2C(idx), twi_nrfx_pm_action); \
|
||||
I2C_DEVICE_DT_DEFINE(I2C(idx), \
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <drivers/i2c.h>
|
||||
#include <dt-bindings/i2c/i2c.h>
|
||||
#include <pm/device.h>
|
||||
#include <drivers/pinctrl.h>
|
||||
#include <soc.h>
|
||||
#include <nrfx_twim.h>
|
||||
#include <sys/util.h>
|
||||
|
||||
|
@ -29,6 +31,9 @@ struct i2c_nrfx_twim_config {
|
|||
nrfx_twim_t twim;
|
||||
uint16_t concat_buf_size;
|
||||
uint16_t flash_buf_max_size;
|
||||
#ifdef CONFIG_PINCTRL
|
||||
const struct pinctrl_dev_config *pcfg;
|
||||
#endif
|
||||
};
|
||||
|
||||
static int init_twim(const struct device *dev);
|
||||
|
@ -317,15 +322,33 @@ static const struct i2c_driver_api i2c_nrfx_twim_driver_api = {
|
|||
static int twim_nrfx_pm_action(const struct device *dev,
|
||||
enum pm_device_action action)
|
||||
{
|
||||
#ifdef CONFIG_PINCTRL
|
||||
const struct i2c_nrfx_twim_config *dev_config = dev->config;
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
||||
switch (action) {
|
||||
case PM_DEVICE_ACTION_RESUME:
|
||||
#ifdef CONFIG_PINCTRL
|
||||
ret = pinctrl_apply_state(dev_config->pcfg,
|
||||
PINCTRL_STATE_DEFAULT);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
ret = init_twim(dev);
|
||||
break;
|
||||
|
||||
case PM_DEVICE_ACTION_SUSPEND:
|
||||
deinit_twim(dev);
|
||||
|
||||
#ifdef CONFIG_PINCTRL
|
||||
ret = pinctrl_apply_state(dev_config->pcfg,
|
||||
PINCTRL_STATE_SLEEP);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -362,7 +385,15 @@ static int twim_nrfx_pm_action(const struct device *dev,
|
|||
(1))
|
||||
#define MSG_BUF_SIZE(idx) MAX(CONCAT_BUF_SIZE(idx), FLASH_BUF_MAX_SIZE(idx))
|
||||
|
||||
#define I2C_NRFX_TWIM_PIN_CFG(idx) \
|
||||
COND_CODE_1(CONFIG_PINCTRL, \
|
||||
(.skip_gpio_cfg = true, \
|
||||
.skip_psel_cfg = true,), \
|
||||
(.scl = DT_PROP(I2C(idx), scl_pin), \
|
||||
.sda = DT_PROP(I2C(idx), sda_pin),))
|
||||
|
||||
#define I2C_NRFX_TWIM_DEVICE(idx) \
|
||||
NRF_DT_ENSURE_PINS_ASSIGNED(I2C(idx), scl_pin); \
|
||||
BUILD_ASSERT(I2C_FREQUENCY(idx) != \
|
||||
I2C_NRFX_TWIM_INVALID_FREQUENCY, \
|
||||
"Wrong I2C " #idx " frequency setting in dts"); \
|
||||
|
@ -370,14 +401,22 @@ static int twim_nrfx_pm_action(const struct device *dev,
|
|||
{ \
|
||||
IRQ_CONNECT(DT_IRQN(I2C(idx)), DT_IRQ(I2C(idx), priority), \
|
||||
nrfx_isr, nrfx_twim_##idx##_irq_handler, 0); \
|
||||
IF_ENABLED(CONFIG_PINCTRL, ( \
|
||||
const struct i2c_nrfx_twim_config *dev_config = \
|
||||
dev->config; \
|
||||
int err = pinctrl_apply_state(dev_config->pcfg, \
|
||||
PINCTRL_STATE_DEFAULT); \
|
||||
if (err < 0) { \
|
||||
return err; \
|
||||
} \
|
||||
)) \
|
||||
return init_twim(dev); \
|
||||
} \
|
||||
IF_ENABLED(USES_MSG_BUF(idx), \
|
||||
(static uint8_t twim_##idx##_msg_buf[MSG_BUF_SIZE(idx)];)) \
|
||||
static struct i2c_nrfx_twim_data twim_##idx##_data = { \
|
||||
.twim_config = { \
|
||||
.scl = DT_PROP(I2C(idx), scl_pin), \
|
||||
.sda = DT_PROP(I2C(idx), sda_pin), \
|
||||
I2C_NRFX_TWIM_PIN_CFG(idx) \
|
||||
.frequency = I2C_FREQUENCY(idx), \
|
||||
}, \
|
||||
.transfer_sync = Z_SEM_INITIALIZER( \
|
||||
|
@ -387,10 +426,13 @@ static int twim_nrfx_pm_action(const struct device *dev,
|
|||
IF_ENABLED(USES_MSG_BUF(idx), \
|
||||
(.msg_buf = twim_##idx##_msg_buf,)) \
|
||||
}; \
|
||||
IF_ENABLED(CONFIG_PINCTRL, (PINCTRL_DT_DEFINE(I2C(idx)))); \
|
||||
static const struct i2c_nrfx_twim_config twim_##idx##z_config = { \
|
||||
.twim = NRFX_TWIM_INSTANCE(idx), \
|
||||
.concat_buf_size = CONCAT_BUF_SIZE(idx), \
|
||||
.flash_buf_max_size = FLASH_BUF_MAX_SIZE(idx), \
|
||||
IF_ENABLED(CONFIG_PINCTRL, \
|
||||
(.pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2C(idx)),)) \
|
||||
}; \
|
||||
PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action); \
|
||||
I2C_DEVICE_DT_DEFINE(I2C(idx), \
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
# Common fields for Nordic nRF family TWI peripherals
|
||||
|
||||
include: i2c-controller.yaml
|
||||
include: [i2c-controller.yaml, pinctrl-device.yaml]
|
||||
|
||||
properties:
|
||||
reg:
|
||||
|
@ -15,8 +15,11 @@ properties:
|
|||
|
||||
sda-pin:
|
||||
type: int
|
||||
required: true
|
||||
required: false
|
||||
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 SDA pin to use.
|
||||
|
||||
For pins P0.0 through P0.31, use the pin number. For example,
|
||||
|
@ -31,7 +34,10 @@ properties:
|
|||
|
||||
scl-pin:
|
||||
type: int
|
||||
required: true
|
||||
required: false
|
||||
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 SCL pin to use. The pin numbering scheme is the same as
|
||||
the sda-pin property's.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue