Add Winbond SuperIO helper functions to clear up the board enables. Also reveals some nastyness in the iwill dk8 htx, which is to be rectified in one of the subsequent commits. Properly constify the argument of all board enables: otherwise the compiler bombs out here (warning is treated like error in this Makefile). Signed-Off-By: Luc Verhaegen Index: board_enable.c =================================================================== --- board_enable.c (revision 2624) +++ board_enable.c (working copy) @@ -23,53 +23,78 @@ #include "flash.h" #include "debug.h" -static int board_iwill_dk8_htx(const char *name) +/* + * Helper functions for many Winbond superIOs of the w836xx range. + */ +#define W836_INDEX 0x2E +#define W836_DATA 0x2F + +/* Enter extended functions */ +static void +w836xx_ext_enter(void) { - /* Extended function index register, either 0x2e or 0x4e. */ -#define EFIR 0x2e - /* Extended function data register, one plus the index reg. */ -#define EFDR EFIR + 1 - char b; + outb(0x87, W836_INDEX); + outb(0x87, W836_INDEX); +} - /* Disable the flash write protect (which is connected to the - * Winbond W83627HF GPIOs). - */ - outb(0x87, EFIR); /* Sequence to unlock extended functions */ - outb(0x87, EFIR); +/* Leave extended functions */ +static void +w836xx_ext_leave(void) +{ + outb(0xAA, W836_INDEX); +} - /* Activate logical device. */ - outb(0x7, EFIR); - outb(8, EFDR); +/* General functions for read/writing WB SuperIOs */ +static unsigned char +wbsio_read(unsigned char index) +{ + outb(index, W836_INDEX); + return inb(W836_DATA); +} - /* Set GPIO regs. */ - outb(0x2b, EFIR); /* GPIO multiplexed pin reg. */ - b = inb(EFDR) | 0xd0; - outb(0x2b, EFIR); - outb(b, EFDR); +static void +wbsio_write(unsigned char index, unsigned char data) +{ + outb(index, W836_INDEX); + outb(data, W836_DATA); +} - outb(0x30, EFIR); /* GPIO2 */ - b = inb(EFDR) | 0x01; - outb(0x30, EFIR); - outb(b, EFDR); +static void +wbsio_mask(unsigned char index, unsigned char data, + unsigned char mask) +{ + unsigned char tmp; - outb(0xf0, EFIR); /* IO sel */ - b = inb(EFDR) | 0xef; - outb(0xf0, EFIR); - outb(b, EFDR); + outb(index, W836_INDEX); + tmp = inb(W836_DATA) & ~mask; + outb(tmp | (data & mask), W836_DATA); +} - outb(0xf1, EFIR); /* GPIO data reg */ - b = inb(EFDR) | 0x16; - outb(0xf1, EFIR); - outb(b, EFDR); +/* + * Disable the flash write protect (which is connected to the + * Winbond W83627HF GPIOs). + */ +static int board_iwill_dk8_htx(const char *name) +{ + w836xx_ext_enter(); - outb(0xf2, EFIR); /* GPIO inversion reg */ - b = inb(EFDR) | 0x00; - outb(0xf2, EFIR); - outb(b, EFDR); + /* set to SCL or GPIO. */ + wbsio_mask(0x2B, 0xD0, 0xD0); /* GPIO 21,22,24 */ - /* Lock extended functions again. */ - outb(0xaa, EFIR); /* Command to exit extended functions */ + wbsio_write(0x07, 0x08); /* Activate logical device 8: GPIO port 2. */ + wbsio_mask(0x30, 0x01, 0x01); /* Activate logical device */ + + wbsio_mask(0xF0, 0xEF, 0xEF); /* GPIO 20,21,22,23,25,26,27 = input */ + + wbsio_mask(0xF1, 0x16, 0x16); /* Raise GPIO 21,22,24 */ + +#if 0 /* Surely this is wrong */ + wbsio_mask(0xF2, 0x00, 0x00); /* GPIO inversion reg */ +#endif + + w836xx_ext_leave(); + return 0; } @@ -78,53 +103,36 @@ * specific code: * main: 0x1022:0x746B, which is the SMBUS controller. * card: 0x1022:0x36C0... + * + * Flash write protect is connected to GPIO24 of the WinBond w83627hf. */ - -static int board_agami_aruma(char *name) +static int board_agami_aruma(const char *name) { - /* Extended function index register, either 0x2e or 0x4e */ -#define EFIR 0x2e - /* Extended function data register, one plus the index reg. */ -#define EFDR EFIR + 1 - char b; + w836xx_ext_enter(); - /* Disable the flash write protect. The flash write protect is - * connected to the WinBond w83627hf GPIO 24. - */ - outb(0x87, EFIR); /* sequence to unlock extended functions */ - outb(0x87, EFIR); - - outb(0x20, EFIR); /* SIO device ID register */ - b = inb(EFDR); - printf_debug("\nW83627HF device ID = 0x%x\n",b); - - if (b != 0x52) { - fprintf(stderr, "\nIncorrect device ID, aborting write protect disable\n"); + if (wbsio_read(0x20) != 0x52) { /* SIO device ID register */ + fprintf(stderr, "\n%s: Incorrect Winbond device ID (0x%02X)," + " aborting.\n", name, wbsio_read(0x20)); + w836xx_ext_leave(); return -1; } - outb(0x2b, EFIR); /* GPIO multiplexed pin reg. */ - b = inb(EFDR) | 0x10; - outb(0x2b, EFIR); - outb(b, EFDR); /* select GPIO 24 instead of WDTO */ + /* GPIO multiplexed pin reg: select GPIO24 instead of WDTO */ + wbsio_mask(0x2B, 0x10, 0x10); - outb(0x7, EFIR); /* logical device select */ - outb(0x8, EFDR); /* point to device 8, GPIO port 2 */ + /* logical device select: point to device 8, GPIO port 2 */ + wbsio_write(0x07, 0x08); - outb(0x30, EFIR); /* logic device activation control */ - outb(0x1, EFDR); /* activate */ + /* logic device activation control: activate */ + wbsio_write(0x30, 0x01); - outb(0xf0, EFIR); /* GPIO 20-27 I/O selection register */ - b = inb(EFDR) & ~0x10; - outb(0xf0, EFIR); - outb(b, EFDR); /* set GPIO 24 as an output */ + /* GPIO 20-27 I/O selection register: GPIO24 = output */ + wbsio_mask(0xF0, 0x00, 0x10); - outb(0xf1, EFIR); /* GPIO 20-27 data register */ - b = inb(EFDR) | 0x10; - outb(0xf1, EFIR); - outb(b, EFDR); /* set GPIO 24 */ + /* GPIO 20-27 data register: set GPIO24 */ + wbsio_mask(0xF1, 0x10, 0x10); - outb(0xaa, EFIR); /* command to exit extended functions */ + w836xx_ext_leave(); return 0; } @@ -135,7 +143,7 @@ * We don't need to do this when using linuxbios, GPIO15 is never lowered there. */ -static int board_via_epia_m(char *name) +static int board_via_epia_m(const char *name) { struct pci_dev *dev; unsigned int base; @@ -164,33 +172,11 @@ } /* - * Winbond LPC super IO. - * - * Raises the ROM MEMW# line. - */ - -static void w83697_rom_memw_enable(void) -{ - uint8_t val; - - outb(0x87, 0x2E); /* enable extended functions */ - outb(0x87, 0x2E); - - outb(0x24, 0x2E); /* rom bits live here */ - - val = inb(0x2F); - if (!(val & 0x02)) /* flash rom enabled? */ - outb(val | 0x08, 0x2F); /* enable MEMW# */ - - outb(0xAA, 0x2E); /* disable extended functions */ -} - -/* * Suited for Asus A7V8X-MX SE and A7V400-MX. * */ -static int board_asus_a7v8x_mx(char *name) +static int board_asus_a7v8x_mx(const char *name) { struct pci_dev *dev; uint8_t val; @@ -206,8 +192,14 @@ val &= 0x7F; pci_write_byte(dev, 0x59, val); - w83697_rom_memw_enable(); + /* Raise ROM MEMW# line on Winbond w83697 SuperIO */ + w836xx_ext_enter(); + if (!(wbsio_read(0x24) & 0x02)) /* flash rom enabled? */ + wbsio_mask(0x24, 0x08, 0x08); /* enable MEMW# */ + + w836xx_ext_leave(); + return 0; } @@ -241,7 +233,7 @@ char *lb_part; char *name; - int (*enable)(char *name); + int (*enable)(const char *name); }; struct board_pciid_enable board_pciid_enables[] = {