From b0936ae35331c3218ed4d51477d95b06afe53ecd Mon Sep 17 00:00:00 2001 From: Maximilian Deubel Date: Mon, 24 Jun 2024 16:50:42 +0200 Subject: [PATCH] drivers: dp: swdp_bitbang: power optimization This patch changes GPIO initialization to be in PORT_OFF state by default. Also, if no transceiver is attached to the signals, the GPIOs are configured to be disconnected to preserve power. I tested this on a prototype board where we are going to have a debugger in a low-power context. Signed-off-by: Maximilian Deubel --- drivers/dp/swdp_bitbang.c | 132 ++++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 57 deletions(-) diff --git a/drivers/dp/swdp_bitbang.c b/drivers/dp/swdp_bitbang.c index 3e0b6a2ea0e..a1d28386209 100644 --- a/drivers/dp/swdp_bitbang.c +++ b/drivers/dp/swdp_bitbang.c @@ -568,29 +568,42 @@ static int sw_configure(const struct device *dev, static int sw_port_on(const struct device *dev) { const struct sw_config *config = dev->config; - - gpio_pin_set_dt(&config->clk, 1); + int ret; if (config->dnoe.port) { - gpio_pin_set_dt(&config->dnoe, 1); - } - - if (config->dout.port) { - gpio_pin_set_dt(&config->dout, 1); - } else { - int ret; - - ret = gpio_pin_configure_dt(&config->dio, GPIO_OUTPUT_ACTIVE); + ret = gpio_pin_configure_dt(&config->dnoe, GPIO_OUTPUT_ACTIVE); if (ret) { return ret; } } - if (config->noe.port) { - gpio_pin_set_dt(&config->noe, 1); + if (config->dout.port) { + ret = gpio_pin_configure_dt(&config->dout, GPIO_OUTPUT_ACTIVE); + if (ret) { + return ret; + } } - if (config->reset.port) { - gpio_pin_set_dt(&config->reset, 1); + + ret = gpio_pin_configure_dt(&config->dio, GPIO_INPUT); + if (ret) { + return ret; + } + + if (config->noe.port) { + ret = gpio_pin_configure_dt(&config->noe, GPIO_OUTPUT_ACTIVE); + if (ret) { + return ret; + } + } + + ret = gpio_pin_configure_dt(&config->clk, GPIO_OUTPUT_ACTIVE); + if (ret) { + return ret; + } + + ret = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_ACTIVE); + if (ret) { + return ret; } return 0; @@ -599,27 +612,64 @@ static int sw_port_on(const struct device *dev) static int sw_port_off(const struct device *dev) { const struct sw_config *config = dev->config; + int ret; + /* If there is a transceiver connected to IO, pins should always be driven. */ if (config->dnoe.port) { - gpio_pin_set_dt(&config->dnoe, 0); - } + ret = gpio_pin_configure_dt(&config->dnoe, GPIO_OUTPUT_INACTIVE); + if (ret) { + return ret; + } - if (config->dout.port) { - gpio_pin_set_dt(&config->dout, 0); - } else { - int ret; + if (config->dout.port) { + ret = gpio_pin_configure_dt(&config->dout, GPIO_OUTPUT_ACTIVE); + if (ret) { + return ret; + } + } ret = gpio_pin_configure_dt(&config->dio, GPIO_INPUT); if (ret) { return ret; } + } else { + if (config->dout.port) { + ret = gpio_pin_configure_dt(&config->dout, GPIO_DISCONNECTED); + if (ret) { + return ret; + } + } + + ret = gpio_pin_configure_dt(&config->dio, GPIO_DISCONNECTED); + if (ret) { + return ret; + } } + /* If there is a transceiver connected to CLK, pins should always be driven. */ if (config->noe.port) { - gpio_pin_set_dt(&config->noe, 0); + ret = gpio_pin_configure_dt(&config->noe, GPIO_OUTPUT_INACTIVE); + if (ret) { + return ret; + } + + ret = gpio_pin_configure_dt(&config->clk, GPIO_OUTPUT_ACTIVE); + if (ret) { + return ret; + } + + } else { + ret = gpio_pin_configure_dt(&config->clk, GPIO_DISCONNECTED); + if (ret) { + return ret; + } } + if (config->reset.port) { - gpio_pin_set_dt(&config->reset, 1); + ret = gpio_pin_configure_dt(&config->reset, GPIO_DISCONNECTED); + if (ret) { + return ret; + } } return 0; @@ -631,44 +681,12 @@ static int sw_gpio_init(const struct device *dev) struct sw_cfg_data *sw_data = dev->data; int ret; - ret = gpio_pin_configure_dt(&config->clk, GPIO_OUTPUT_ACTIVE); + /* start with the port turned off */ + ret = sw_port_off(dev); if (ret) { return ret; } - ret = gpio_pin_configure_dt(&config->dio, GPIO_INPUT); - if (ret) { - return ret; - } - - if (config->dout.port) { - ret = gpio_pin_configure_dt(&config->dout, GPIO_OUTPUT_ACTIVE); - if (ret) { - return ret; - } - } - - if (config->dnoe.port) { - ret = gpio_pin_configure_dt(&config->dnoe, GPIO_OUTPUT_INACTIVE); - if (ret) { - return ret; - } - } - - if (config->noe.port) { - ret = gpio_pin_configure_dt(&config->noe, GPIO_OUTPUT_INACTIVE); - if (ret) { - return ret; - } - } - - if (config->reset.port) { - ret = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_ACTIVE); - if (ret) { - return ret; - } - } - sw_data->turnaround = 1U; sw_data->data_phase = false; sw_data->fast_clock = false;