From 36bbd67653eb46c06996a4d5036a4e2ae09ddd00 Mon Sep 17 00:00:00 2001 From: Mikhail Siomin Date: Fri, 13 Dec 2024 16:41:56 +0300 Subject: [PATCH] drivers: gpio_pca95xx: add pins initialization to default state After a non-power reset (wdt) pins may remain in non-default state. To ensure that a system initialization is the same after any reset, it is necessary to initialize pins to the default state. Signed-off-by: Mikhail Siomin --- drivers/gpio/gpio_pca95xx.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio_pca95xx.c b/drivers/gpio/gpio_pca95xx.c index b31d85eeae6..662a92465f3 100644 --- a/drivers/gpio/gpio_pca95xx.c +++ b/drivers/gpio/gpio_pca95xx.c @@ -301,6 +301,15 @@ static inline int update_direction_reg(const struct device *dev, uint8_t pin, &drv_data->reg_cache.dir, value); } +static inline int update_direction_regs(const struct device *dev, uint16_t value) +{ + struct gpio_pca95xx_drv_data * const drv_data = + (struct gpio_pca95xx_drv_data * const)dev->data; + + return write_port_regs(dev, REG_CONF_PORT0, + &drv_data->reg_cache.dir, value); +} + static inline int update_pul_sel_reg(const struct device *dev, uint8_t pin, uint16_t value) { @@ -374,6 +383,18 @@ static int setup_pin_dir(const struct device *dev, uint32_t pin, int flags) return ret; } +/** + * @brief Initialize pins to default state + * + * @param dev Device struct of the PCA95XX + * + * @return 0 if successful, failed otherwise + */ +static int init_pins(const struct device *dev) +{ + return update_direction_regs(dev, 0xFFFF); +} + /** * @brief Setup the pin pull up/pull down status * @@ -783,6 +804,7 @@ static int gpio_pca95xx_init(const struct device *dev) const struct gpio_pca95xx_config * const config = dev->config; struct gpio_pca95xx_drv_data * const drv_data = (struct gpio_pca95xx_drv_data * const)dev->data; + int ret; if (!device_is_ready(config->bus.bus)) { return -ENODEV; @@ -790,11 +812,14 @@ static int gpio_pca95xx_init(const struct device *dev) k_sem_init(&drv_data->lock, 1, 1); + ret = init_pins(dev); + if (ret != 0) { + return ret; + } + #ifdef CONFIG_GPIO_PCA95XX_INTERRUPT /* Check if GPIO port supports interrupts */ if ((config->capabilities & PCA_HAS_INTERRUPT) != 0) { - int ret; - /* Store self-reference for interrupt handling */ drv_data->instance = dev;