From 48c56cebaa4c75be806306e4e885db52987975f1 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 22 Aug 2023 14:42:00 +0200 Subject: [PATCH] drivers: gpio: Smartbond: Add pdc support This change allows to have GPIO interrupts configured that will work while chip enters low power modes where PD_COM is turned off. PDC controller can wake up system on GPIO changes even when PD_COM is off. This is done by adding PDC entries that will wakeup Cortex-M33 at the same time when WAKEUP controller is programmed to handle GPIO state changes. Signed-off-by: Jerzy Kasenberg --- drivers/gpio/gpio_smartbond.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio_smartbond.c b/drivers/gpio/gpio_smartbond.c index 8996690ccb4..81ce31296f2 100644 --- a/drivers/gpio/gpio_smartbond.c +++ b/drivers/gpio/gpio_smartbond.c @@ -13,6 +13,7 @@ #include #include +#include #define GPIO_MODE_RESET 0x200 @@ -68,6 +69,8 @@ struct gpio_smartbond_config { volatile uint32_t *mode_regs; volatile struct gpio_smartbond_latch_regs *latch_regs; volatile struct gpio_smartbond_wkup_regs *wkup_regs; + /* Value of TRIG_SELECT for PDC_CTRLx_REG entry */ + uint8_t wkup_trig_select; }; static void gpio_smartbond_wkup_init(void) @@ -210,15 +213,26 @@ static int gpio_smartbond_pin_interrupt_configure(const struct device *dev, const struct gpio_smartbond_config *config = dev->config; struct gpio_smartbond_data *data = dev->data; uint32_t pin_mask = BIT(pin); +#if CONFIG_PM + int trig_select_id = (config->wkup_trig_select << 5) | pin; + int pdc_ix; +#endif /* Not supported by hardware */ if (mode == GPIO_INT_MODE_LEVEL) { return -ENOTSUP; } +#if CONFIG_PM + pdc_ix = da1469x_pdc_find(trig_select_id, MCU_PDC_MASTER_M33, MCU_PDC_EN_XTAL); +#endif if (mode == GPIO_INT_MODE_DISABLED) { - config->wkup_regs->sel &= ~BIT(pin); - config->wkup_regs->clear = BIT(pin); + config->wkup_regs->sel &= ~pin_mask; + config->wkup_regs->clear = pin_mask; + data->both_edges_pins &= ~pin_mask; +#if CONFIG_PM + da1469x_pdc_del(pdc_ix); +#endif } else { if (trig == GPIO_INT_TRIG_BOTH) { /* Not supported by hardware */ @@ -231,6 +245,15 @@ static int gpio_smartbond_pin_interrupt_configure(const struct device *dev, } config->wkup_regs->sel |= pin_mask; +#if CONFIG_PM + if (pdc_ix < 0) { + pdc_ix = da1469x_pdc_add(trig_select_id, MCU_PDC_MASTER_M33, + MCU_PDC_EN_XTAL); + } + if (pdc_ix < 0) { + return -ENOMEM; + } +#endif } return 0; @@ -294,6 +317,7 @@ static const struct gpio_driver_api gpio_smartbond_drv_api_funcs = { DT_INST_REG_ADDR_BY_NAME(id, latch), \ .wkup_regs = (volatile struct gpio_smartbond_wkup_regs *) \ DT_INST_REG_ADDR_BY_NAME(id, wkup), \ + .wkup_trig_select = id, \ }; \ \ static struct gpio_smartbond_data gpio_smartbond_p##id##_data; \