superio/nuvoton/nct5104d: Add soft reset GPIO functionality

So far, only hard power off could reset GPIOs state to defaults:
IN, Open-drain. Now, defaults are set with every boot to ensure
that GPIOs are not in unknown/unwanted state.

Change-Id: I67878dbab2ddf0deaaa8f5d79416368c6164ba1d
Signed-off-by: Piotr Kleinschmidt <piotr.kleinschmidt@3mdeb.com>
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/35482
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
This commit is contained in:
Piotr Kleinschmidt 2019-09-19 16:25:56 +02:00 committed by Felix Held
parent bd467d1481
commit b52f7c7c46
2 changed files with 59 additions and 1 deletions

View File

@ -26,6 +26,16 @@
#define GLOBAL_OPTION_CR26 0x26 #define GLOBAL_OPTION_CR26 0x26
#define CR26_LOCK_REG (1 << 4) /* required to access CR10/CR11 */ #define CR26_LOCK_REG (1 << 4) /* required to access CR10/CR11 */
/* LDN 0x07 specific registers */
#define NCT5104D_GPIO0_IO 0xE0
#define NCT5104D_GPIO1_IO 0xE4
#define NCT5104D_GPIO6_IO 0xF8
/* LDN 0x0F specific registers */
#define NCT5104D_GPIO0_PP_OD 0xE0
#define NCT5104D_GPIO1_PP_OD 0xE1
#define NCT5104D_GPIO6_PP_OD 0xE6
/* Logical Device Numbers (LDN). */ /* Logical Device Numbers (LDN). */
#define NCT5104D_FDC 0x00 /* FDC - not pinned out */ #define NCT5104D_FDC 0x00 /* FDC - not pinned out */
#define NCT5104D_SP1 0x02 /* UARTA */ #define NCT5104D_SP1 0x02 /* UARTA */

View File

@ -106,6 +106,47 @@ static void route_pins_to_uart(struct device *dev, bool to_uart)
pnp_write_config(dev, 0x1c, reg); pnp_write_config(dev, 0x1c, reg);
} }
static void reset_gpio_default_in(struct device *dev)
{
pnp_set_logical_device(dev);
/* Soft reset GPIOs to default state: IN */
switch (dev->path.pnp.device) {
case NCT5104D_GPIO0:
pnp_write_config(dev, NCT5104D_GPIO0_IO, 0xFF);
break;
case NCT5104D_GPIO1:
pnp_write_config(dev, NCT5104D_GPIO1_IO, 0xFF);
break;
case NCT5104D_GPIO6:
pnp_write_config(dev, NCT5104D_GPIO6_IO, 0xFF);
break;
default:
break;
}
}
static void reset_gpio_default_od(struct device *dev)
{
struct device *gpio0, *gpio1, *gpio6;
gpio0 = dev_find_slot_pnp(dev->path.pnp.port, NCT5104D_GPIO0);
gpio1 = dev_find_slot_pnp(dev->path.pnp.port, NCT5104D_GPIO1);
gpio6 = dev_find_slot_pnp(dev->path.pnp.port, NCT5104D_GPIO6);
pnp_set_logical_device(dev);
/* Soft reset GPIOs to default state: Open-drain */
if (gpio0 && gpio0->enabled)
pnp_write_config(dev, NCT5104D_GPIO0_PP_OD, 0xFF);
if (gpio1 && gpio1->enabled)
pnp_write_config(dev, NCT5104D_GPIO1_PP_OD, 0xFF);
if (gpio6 && gpio6->enabled)
pnp_write_config(dev, NCT5104D_GPIO6_PP_OD, 0xFF);
}
static void nct5104d_init(struct device *dev) static void nct5104d_init(struct device *dev)
{ {
struct superio_nuvoton_nct5104d_config *conf = dev->chip_info; struct superio_nuvoton_nct5104d_config *conf = dev->chip_info;
@ -128,6 +169,13 @@ static void nct5104d_init(struct device *dev)
case NCT5104D_GPIO0: case NCT5104D_GPIO0:
case NCT5104D_GPIO1: case NCT5104D_GPIO1:
route_pins_to_uart(dev, false); route_pins_to_uart(dev, false);
reset_gpio_default_in(dev);
break;
case NCT5104D_GPIO6:
reset_gpio_default_in(dev);
break;
case NCT5104D_GPIO_PP_OD:
reset_gpio_default_od(dev);
break; break;
default: default:
break; break;
@ -152,10 +200,10 @@ static struct pnp_info pnp_dev_info[] = {
{ NULL, NCT5104D_SP3, PNP_IO0 | PNP_IRQ0, 0x07f8, }, { NULL, NCT5104D_SP3, PNP_IO0 | PNP_IRQ0, 0x07f8, },
{ NULL, NCT5104D_SP4, PNP_IO0 | PNP_IRQ0, 0x07f8, }, { NULL, NCT5104D_SP4, PNP_IO0 | PNP_IRQ0, 0x07f8, },
{ NULL, NCT5104D_GPIO_WDT}, { NULL, NCT5104D_GPIO_WDT},
{ NULL, NCT5104D_GPIO_PP_OD},
{ NULL, NCT5104D_GPIO0}, { NULL, NCT5104D_GPIO0},
{ NULL, NCT5104D_GPIO1}, { NULL, NCT5104D_GPIO1},
{ NULL, NCT5104D_GPIO6}, { NULL, NCT5104D_GPIO6},
{ NULL, NCT5104D_GPIO_PP_OD},
{ NULL, NCT5104D_PORT80}, { NULL, NCT5104D_PORT80},
}; };