@@ -1864,48 +1864,82 @@ 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);
+ exit_conf_mode_ite(sioport);
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");
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);
+ return -1;
+ }
+
+ port = line / 10;
+ port--;
+ line %= 10;
+
/* set GPIO. */
tmp = INB(base + port);
if (raise)
@@ -1924,7 +1958,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 +2064,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},
@@ -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),