Add Winbond Super I/O detection and hook it up to the generic Super I/O detection framework. Incomplete and untested, but at least it shouldn't break anything.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-winbond_superio_detect/flash.h =================================================================== --- flashrom-winbond_superio_detect/flash.h (Revision 1064) +++ flashrom-winbond_superio_detect/flash.h (Arbeitskopie) @@ -350,6 +350,7 @@ /* board_enable.c */ void w836xx_ext_enter(uint16_t port); void w836xx_ext_leave(uint16_t port); +struct superio probe_superio_winbond(void); uint8_t sio_read(uint16_t port, uint8_t reg); void sio_write(uint16_t port, uint8_t reg, uint8_t data); void sio_mask(uint16_t port, uint8_t reg, uint8_t data, uint8_t mask); @@ -388,7 +389,8 @@ }; extern struct superio superio; #define SUPERIO_VENDOR_NONE 0x0 -#define SUPERIO_VENDOR_ITE 0x1 +#define SUPERIO_VENDOR_WINBOND 0x1 +#define SUPERIO_VENDOR_ITE 0x2 struct pci_dev *pci_dev_find_filter(struct pci_filter filter); struct pci_dev *pci_dev_find_vendorclass(uint16_t vendor, uint16_t class); struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device); Index: flashrom-winbond_superio_detect/internal.c =================================================================== --- flashrom-winbond_superio_detect/internal.c (Revision 1064) +++ flashrom-winbond_superio_detect/internal.c (Arbeitskopie) @@ -104,12 +104,14 @@
void probe_superio(void) { - superio = probe_superio_ite(); + superio = probe_superio_winbond(); #if 0 - /* Winbond Super I/O code is not yet available. */ + /* ITE probe causes SMSC LPC47N217 to power off the serial UART. */ if (superio.vendor == SUPERIO_VENDOR_NONE) - superio = probe_superio_winbond(); + superio = probe_superio_smsc(); #endif + if (superio.vendor == SUPERIO_VENDOR_NONE) + superio = probe_superio_ite(); } #endif
Index: flashrom-winbond_superio_detect/board_enable.c =================================================================== --- flashrom-winbond_superio_detect/board_enable.c (Revision 1064) +++ flashrom-winbond_superio_detect/board_enable.c (Arbeitskopie) @@ -229,22 +229,59 @@ address, but takes no effort to make sure the chip is really a Winbond Super I/O */
-static const struct winbond_chip * winbond_superio_detect(uint16_t base) +uint8_t probe_id_winbond(uint16_t port) { uint8_t chipid; + + w836xx_ext_enter(port); + chipid = sio_read(port, 0x20); + w836xx_ext_leave(port); + + return chipid; +} + +#define WINBOND_SUPERIO_PORT1 0x2e +#define WINBOND_SUPERIO_PORT2 0x4e + +struct superio probe_superio_winbond(void) +{ + struct superio ret = {}; + uint16_t winbond_ports[] = {WINBOND_SUPERIO_PORT1, WINBOND_SUPERIO_PORT2, 0}; + uint16_t *i = winbond_ports; + + ret.vendor = SUPERIO_VENDOR_WINBOND; + for (; *i; i++) { + ret.port = *i; + ret.model = probe_id_winbond(ret.port); + switch (ret.model) { + case WINBOND_W83627HF_ID: + case WINBOND_W83627EHF_ID: + case WINBOND_W83627THF_ID: + msg_pinfo("Found Winbond Super I/O, id %02hx\n", + ret.model); + return ret; + } + } + + /* No good ID found. */ + ret.vendor = SUPERIO_VENDOR_NONE; + ret.port = 0; + ret.model = 0; + return ret; +} + +static const struct winbond_chip *winbond_superio_chipdef(void) +{ const struct winbond_chip * chip = NULL; int i;
- w836xx_ext_enter(base); - chipid = sio_read(base, 0x20); for (i = 0; i < ARRAY_SIZE(winbond_chips); i++) - if (winbond_chips[i].device_id == chipid) + if (winbond_chips[i].device_id == superio.model) { chip = &winbond_chips[i]; break; } - w836xx_ext_leave(base); return chip; }
@@ -259,7 +296,7 @@ int port = pin / 10; int bit = pin % 10;
- chip = winbond_superio_detect(base); + chip = winbond_superio_chipdef(); if (!chip) { msg_perr("\nERROR: No supported Winbond Super I/O found\n"); return -1;