Skip to content

Commit 1cc7307

Browse files
MulinChaonashif
authored andcommitted
driver: gpio: npcx: fixed leakage current in npcx7 series.
It was found that npcx7 series' GPIOs which support low-voltage power supply, there is an excessive power consumption if they are selected to low-voltage mode and their input voltage is 1.8V. To avoid this excessive power consumption, this CL suspends the connection between IO pads and hardware instances before ec enters deep sleep mode. Then restore them after waking up. Signed-off-by: Mulin Chao <[email protected]>
1 parent 4e6cb11 commit 1cc7307

File tree

7 files changed

+119
-0
lines changed

7 files changed

+119
-0
lines changed

drivers/gpio/gpio_npcx.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,34 @@ const struct device *npcx_get_gpio_dev(int port)
5858
return gpio_devs[port];
5959
}
6060

61+
void npcx_gpio_enable_io_pads(const struct device *dev, int pin)
62+
{
63+
const struct gpio_npcx_config *const config = DRV_CONFIG(dev);
64+
const struct npcx_wui *io_wui = &config->wui_maps[pin];
65+
66+
/*
67+
* If this pin is configurred as a GPIO interrupt source, do not
68+
* implement bypass. Or ec cannot wake up via this event.
69+
*/
70+
if (pin < NPCX_GPIO_PORT_PIN_NUM && !npcx_miwu_irq_get_state(io_wui)) {
71+
npcx_miwu_io_enable(io_wui);
72+
}
73+
}
74+
75+
void npcx_gpio_disable_io_pads(const struct device *dev, int pin)
76+
{
77+
const struct gpio_npcx_config *const config = DRV_CONFIG(dev);
78+
const struct npcx_wui *io_wui = &config->wui_maps[pin];
79+
80+
/*
81+
* If this pin is configurred as a GPIO interrupt source, do not
82+
* implement bypass. Or ec cannot wake up via this event.
83+
*/
84+
if (pin < NPCX_GPIO_PORT_PIN_NUM && !npcx_miwu_irq_get_state(io_wui)) {
85+
npcx_miwu_io_disable(io_wui);
86+
}
87+
}
88+
6189
/* GPIO api functions */
6290
static int gpio_npcx_config(const struct device *dev,
6391
gpio_pin_t pin, gpio_flags_t flags)

drivers/interrupt_controller/intc_miwu.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,20 @@ void npcx_miwu_irq_disable(const struct npcx_wui *wui)
170170
NPCX_WKEN(base, wui->group) &= ~BIT(wui->bit);
171171
}
172172

173+
void npcx_miwu_io_enable(const struct npcx_wui *wui)
174+
{
175+
const uint32_t base = DRV_CONFIG(miwu_devs[wui->table])->base;
176+
177+
NPCX_WKINEN(base, wui->group) |= BIT(wui->bit);
178+
}
179+
180+
void npcx_miwu_io_disable(const struct npcx_wui *wui)
181+
{
182+
const uint32_t base = DRV_CONFIG(miwu_devs[wui->table])->base;
183+
184+
NPCX_WKINEN(base, wui->group) &= ~BIT(wui->bit);
185+
}
186+
173187
bool npcx_miwu_irq_get_state(const struct npcx_wui *wui)
174188
{
175189
const uint32_t base = DRV_CONFIG(miwu_devs[wui->table])->base;

soc/arm/nuvoton_npcx/common/scfg.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
*/
66

77
#include <device.h>
8+
#include <drivers/gpio.h>
89
#include <dt-bindings/pinctrl/npcx-pinctrl.h>
910
#include <kernel.h>
1011
#include <soc.h>
1112

13+
#include "soc_gpio.h"
14+
1215
#include <logging/log.h>
1316
LOG_MODULE_REGISTER(pimux_npcx, LOG_LEVEL_ERR);
1417

@@ -106,6 +109,24 @@ void npcx_lvol_pads_configure(void)
106109
}
107110
}
108111

112+
void npcx_lvol_restore_io_pads(void)
113+
{
114+
for (int i = 0; i < ARRAY_SIZE(def_lvols); i++) {
115+
npcx_gpio_enable_io_pads(
116+
npcx_get_gpio_dev(def_lvols[i].io_port),
117+
def_lvols[i].io_bit);
118+
}
119+
}
120+
121+
void npcx_lvol_suspend_io_pads(void)
122+
{
123+
for (int i = 0; i < ARRAY_SIZE(def_lvols); i++) {
124+
npcx_gpio_disable_io_pads(
125+
npcx_get_gpio_dev(def_lvols[i].io_port),
126+
def_lvols[i].io_bit);
127+
}
128+
}
129+
109130
void npcx_pinctrl_i2c_port_sel(int controller, int port)
110131
{
111132
struct glue_reg *const inst_glue = HAL_GLUE_INST();

soc/arm/nuvoton_npcx/common/soc_gpio.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,22 @@ extern "C" {
2424
*/
2525
const struct device *npcx_get_gpio_dev(int port);
2626

27+
/**
28+
* @brief Enable the connection between io pads and GPIO instance
29+
*
30+
* @param dev Pointer to device structure for the gpio driver instance.
31+
* @param pin Pin number.
32+
*/
33+
void npcx_gpio_enable_io_pads(const struct device *dev, int pin);
34+
35+
/**
36+
* @brief Disable the connection between io pads and GPIO instance
37+
*
38+
* @param dev Pointer to device structure for the gpio driver instance.
39+
* @param pin Pin number.
40+
*/
41+
void npcx_gpio_disable_io_pads(const struct device *dev, int pin);
42+
2743
#ifdef __cplusplus
2844
}
2945
#endif

soc/arm/nuvoton_npcx/common/soc_miwu.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,20 @@ void npcx_miwu_irq_enable(const struct npcx_wui *wui);
130130
*/
131131
void npcx_miwu_irq_disable(const struct npcx_wui *wui);
132132

133+
/**
134+
* @brief Connect io to the wake-up input source
135+
*
136+
* @param wui A pointer on wake-up input source
137+
*/
138+
void npcx_miwu_io_enable(const struct npcx_wui *wui);
139+
140+
/**
141+
* @brief Disconnect io to the wake-up input source
142+
*
143+
* @param wui A pointer on wake-up input source
144+
*/
145+
void npcx_miwu_io_disable(const struct npcx_wui *wui);
146+
133147
/**
134148
* @brief Get interrupt state of the wake-up input source
135149
*

soc/arm/nuvoton_npcx/common/soc_pins.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,22 @@ void npcx_pinctrl_psl_input_configure(void);
142142
*/
143143
bool npcx_pinctrl_psl_input_asserted(uint32_t i);
144144

145+
/**
146+
* @brief Restore all connections between IO pads that support low-voltage power
147+
* supply and GPIO hardware devices. This utility is used for solving a
148+
* leakage current issue found in npcx7 series. The npcx9 and later
149+
* series fixed the issue and needn't it.
150+
*/
151+
void npcx_lvol_restore_io_pads(void);
152+
153+
/**
154+
* @brief Disable all connections between IO pads that support low-voltage power
155+
* supply and GPIO hardware devices. This utility is used for solving a
156+
* leakage current issue found in npcx7 series. The npcx9 and later
157+
* series fixed the issue and needn't it.
158+
*/
159+
void npcx_lvol_suspend_io_pads(void);
160+
145161
#ifdef __cplusplus
146162
}
147163
#endif

soc/arm/nuvoton_npcx/npcx7/power.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ static void npcx_power_enter_system_sleep(int slp_mode, int wk_mode)
118118
npcx_clock_control_turn_on_system_sleep(slp_mode == NPCX_DEEP_SLEEP,
119119
wk_mode == NPCX_INSTANT_WAKE_UP);
120120

121+
/* A bypass in npcx7 series to prevent leakage in low-voltage pads */
122+
if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX7)) {
123+
npcx_lvol_suspend_io_pads();
124+
}
125+
121126
/* Turn on host access wake-up interrupt. */
122127
npcx_host_enable_access_interrupt();
123128

@@ -139,6 +144,11 @@ static void npcx_power_enter_system_sleep(int slp_mode, int wk_mode)
139144
/* Turn off host access wake-up interrupt. */
140145
npcx_host_disable_access_interrupt();
141146

147+
/* A bypass in npcx7 series to prevent leakage in low-voltage pads */
148+
if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX7)) {
149+
npcx_lvol_restore_io_pads();
150+
}
151+
142152
/* Turn off system sleep mode. */
143153
npcx_clock_control_turn_off_system_sleep();
144154
}

0 commit comments

Comments
 (0)