From d16357e67358ff583c2afea98e40a07cf38f7c33 Mon Sep 17 00:00:00 2001
From: Joshua Roys <roysjosh@gmail.com>
Date: Wed, 20 Jul 2011 09:07:58 -0400
Subject: [PATCH] Add a board enable for the ASUS P5N-E SLI

Make it8712f_gpio_set into a generic it87_gpio_set function that looks
suspiciously like intel_ich_gpio_set.

Signed-off-by: Joshua Roys <roysjosh@gmail.com>
---
 board_enable.c |   97 +++++++++++++++++++++++++++++++++++++++++---------------
 print.c        |    1 +
 2 files changed, 72 insertions(+), 26 deletions(-)

diff --git a/board_enable.c b/board_enable.c
index a9adecf..2b961aa 100644
--- a/board_enable.c
+++ b/board_enable.c
@@ -1864,48 +1864,83 @@ static int it8703f_gpio51_raise(void)
 }
 
 /*
- * General routine for raising/dropping GPIO lines on the ITE IT8712F.
- * There is only some limited checking on the port numbers.
+ * General routine for raising/dropping GPIO lines on the ITE IT87xx.
  */
-static int it8712f_gpio_set(unsigned int line, int raise)
+static int it87_gpio_set(unsigned int line, int raise)
 {
+	int allowed, i = 0, sio;
 	unsigned int port;
-	uint16_t id, base;
+	uint16_t base, sioport;
 	uint8_t tmp;
 
-	port = line / 10;
-	port--;
-	line %= 10;
+	/* IT87 GPIO configuration table */
+	static struct {
+		uint16_t id;
+		uint8_t base_reg;
+		uint32_t bank0;
+		uint32_t bank1;
+		uint32_t bank2;
+	} it87_gpio_table[] = {
+		{0x8712, 0x62, 0xCFF3FC00, 0x00FCFF3F,          0},
+		{0x8718, 0x62, 0xCFF37C00, 0xF3FCDF3F, 0x0000000F},
+		{0, 0, 0, 0, 0} /* end marker */
+	};
 
-	/* Check line */
-	if ((port > 4) || /* also catches unsigned -1 */
-	    ((port < 4) && (line > 7)) || ((port == 4) && (line > 5))) {
-	    msg_perr("\nERROR: Unsupported IT8712F GPIO line %02d.\n", line);
-	    return -1;
-	}
+	/* Find the Super I/O in the probed list */
+	for (sio = 0; sio < superio_count; sio++) {
+		if (superios[sio].vendor != SUPERIO_VENDOR_ITE)
+			continue;
 
-	/* Find the IT8712F. */
-	enter_conf_mode_ite(0x2E);
-	id = (sio_read(0x2E, 0x20) << 8) | sio_read(0x2E, 0x21);
-	exit_conf_mode_ite(0x2E);
+		/* Is this device in our list? */
+		for (i = 0; it87_gpio_table[i].id; i++)
+			if (superios[sio].model == it87_gpio_table[i].id)
+				break;
+
+		if (it87_gpio_table[i].id)
+			break;
+	}
 
-	if (id != 0x8712) {
-		msg_perr("\nERROR: IT8712F Super I/O not found.\n");
+	if (sio == superio_count) {
+		msg_perr("\nERROR: No IT87 Super I/O GPIO configuration"
+			" found.\n");
 		return -1;
 	}
 
-	/* Get the GPIO base */
-	enter_conf_mode_ite(0x2E);
-	sio_write(0x2E, 0x07, 0x07);
-	base = (sio_read(0x2E, 0x62) << 8) | sio_read(0x2E, 0x63);
-	exit_conf_mode_ite(0x2E);
+	/* Read the Simple I/O Base Address Register */
+	sioport = superios[sio].port;
+	enter_conf_mode_ite(sioport);
+	sio_write(sioport, 0x07, 0x07);
+	base = (sio_read(sioport, it87_gpio_table[i].base_reg) << 8) |
+		sio_read(sioport, it87_gpio_table[i].base_reg + 1);
 
 	if (!base) {
-		msg_perr("\nERROR: Failed to read IT8712F Super I/O GPIO"
+		msg_perr("\nERROR: Failed to read IT87 Super I/O GPIO"
 			" Base.\n");
+		exit_conf_mode_ite(sioport);
 		return -1;
 	}
 
+	msg_pdbg("Using IT87 GPIO base 0x%04x\n", base);
+
+	/* Check whether the line is allowed. */
+	if (line < 32)
+		allowed = (it87_gpio_table[i].bank0 >> line) & 0x01;
+	else if (line < 64)
+		allowed = (it87_gpio_table[i].bank1 >> (line - 32)) & 0x01;
+	else
+		allowed = (it87_gpio_table[i].bank2 >> (line - 64)) & 0x01;
+
+	if (!allowed) {
+		msg_perr("\nERROR: This IT87 does not allow"
+			" setting GPIO%02u\n", line);
+		exit_conf_mode_ite(sioport);
+		return -1;
+	}
+
+	port = line / 10;
+	port--;
+	line %= 10;
+
 	/* set GPIO. */
 	tmp = INB(base + port);
 	if (raise)
@@ -1924,7 +1959,16 @@ static int it8712f_gpio_set(unsigned int line, int raise)
  */
 static int it8712f_gpio3_1_raise(void)
 {
-	return it8712f_gpio_set(32, 1);
+	return it87_gpio_set(32, 1);
+}
+
+/*
+ * Suited for:
+ * - ASUS P5N-E SLI: NVIDIA MCP51 + IT8718F
+ */
+static int it8718f_gpio6_3_raise(void)
+{
+	return it87_gpio_set(63, 1);
 }
 
 #endif
@@ -2021,6 +2065,7 @@ const struct board_pciid_enable board_pciid_enables[] = {
 	{0x8086, 0x266a, 0x1043, 0x80a6,  0x8086, 0x2668, 0x1043, 0x814e, NULL,         NULL, NULL,           P3, "ASUS",        "P5GD1 Pro",             0,   OK, intel_ich_gpio21_raise},
 	{0x8086, 0x266a, 0x1043, 0x80a6,  0x8086, 0x2668, 0x1043, 0x813d, NULL,         NULL, NULL,           P3, "ASUS",        "P5GDC Deluxe",          0,   OK, intel_ich_gpio21_raise},
 	{0x10DE, 0x0030, 0x1043, 0x818a,  0x8086, 0x100E, 0x1043, 0x80EE, NULL,         NULL, NULL,           P3, "ASUS",        "P5ND2-SLI Deluxe",      0,   OK, nvidia_mcp_gpio10_raise},
+	{0x10DE, 0x0260, 0x1043, 0x81BC,  0x10DE, 0x026C, 0x1043, 0x8249, "^P5N-E SLI$",NULL, NULL,           P3, "ASUS",        "P5N-E SLI",             0,   OK, it8718f_gpio6_3_raise},
 	{0x8086, 0x24dd, 0x1043, 0x80a6,  0x8086, 0x2570, 0x1043, 0x8157, NULL,         NULL, NULL,           P3, "ASUS",        "P5PE-VM",               0,   OK, intel_ich_gpio21_raise},
 	{0x10b7, 0x9055, 0x1028, 0x0082,  0x8086, 0x7190,      0,      0, NULL,         NULL, NULL,           P3, "Dell",        "OptiPlex GX1",          0,   OK, intel_piix4_gpo30_lower},
 	{0x8086, 0x3590, 0x1028, 0x016c,  0x1000, 0x0030, 0x1028, 0x016c, NULL,         NULL, NULL,           P3, "Dell",        "PowerEdge 1850",        0,   OK, intel_ich_gpio23_raise},
diff --git a/print.c b/print.c
index 0db0339..156ac5b 100644
--- a/print.c
+++ b/print.c
@@ -480,6 +480,7 @@ const struct board_info boards_known[] = {
 	B("ASUS",	"P5KC",			1, "http://www.asus.com/product.aspx?P_ID=fFZ8oUIGmLpwNMjj", NULL),
 	B("ASUS",	"P5L-MX",		1, "http://www.asus.com/product.aspx?P_ID=X70d3NCzH2DE9vWH", NULL),
 	B("ASUS",	"P5GD1 Pro",		1, "http://www.asus.com/product.aspx?P_ID=50M49xQh71EZOeM1", NULL),
+	B("ASUS",	"P5N-E SLI",		1, "http://www.asus.com/Motherboards/Intel_Socket_775/P5NE_SLI/", NULL),
 	B("ASUS",	"P5N32-E SLI",		1, "http://www.asus.com/product.aspx?P_ID=vBZLIBtPzYB2bLcb", NULL),
 	B("ASUS",	"P5ND2-SLI Deluxe",	1, "http://www.asus.com/product.aspx?P_ID=WY7XroDuUImVbgp5", NULL),
 	B("ASUS",	"P5PE-VM",		1, "http://www.asus.com/product.aspx?P_ID=k3h0ZFVu9Lo1dUvk", NULL),
-- 
1.7.1

