Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/dev/isa/wbsio.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/dev/isa/wbsio.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.9 retrieving revision 1.9.6.1 diff -u -p -r1.9 -r1.9.6.1 --- src/sys/dev/isa/wbsio.c 2012/01/18 00:23:30 1.9 +++ src/sys/dev/isa/wbsio.c 2017/12/03 11:37:05 1.9.6.1 @@ -1,5 +1,5 @@ -/* $NetBSD: wbsio.c,v 1.9 2012/01/18 00:23:30 jakllsch Exp $ */ -/* $OpenBSD: wbsio.c,v 1.5 2009/03/29 21:53:52 sthen Exp $ */ +/* $NetBSD: wbsio.c,v 1.9.6.1 2017/12/03 11:37:05 jdolecek Exp $ */ +/* $OpenBSD: wbsio.c,v 1.10 2015/03/14 03:38:47 jsg Exp $ */ /* * Copyright (c) 2008 Mark Kettenis * @@ -30,36 +30,7 @@ #include #include - -/* ISA bus registers */ -#define WBSIO_INDEX 0x00 /* Configuration Index Register */ -#define WBSIO_DATA 0x01 /* Configuration Data Register */ - -#define WBSIO_IOSIZE 0x02 /* ISA I/O space size */ - -#define WBSIO_CONF_EN_MAGIC 0x87 /* enable configuration mode */ -#define WBSIO_CONF_DS_MAGIC 0xaa /* disable configuration mode */ - -/* Configuration Space Registers */ -#define WBSIO_LDN 0x07 /* Logical Device Number */ -#define WBSIO_ID 0x20 /* Device ID */ -#define WBSIO_REV 0x21 /* Device Revision */ - -#define WBSIO_ID_W83627HF 0x52 -#define WBSIO_ID_W83627THF 0x82 -#define WBSIO_ID_W83627EHF 0x88 -#define WBSIO_ID_W83627DHG 0xa0 -#define WBSIO_ID_W83627SF 0x59 -#define WBSIO_ID_W83637HF 0x70 -#define WBSIO_ID_W83667HG 0xa5 -#define WBSIO_ID_W83697HF 0x60 - -/* Logical Device Number (LDN) Assignments */ -#define WBSIO_LDN_HM 0x0b - -/* Hardware Monitor Control Registers (LDN B) */ -#define WBSIO_HM_ADDR_MSB 0x60 /* Address [15:8] */ -#define WBSIO_HM_ADDR_LSB 0x61 /* Address [7:0] */ +#include struct wbsio_softc { device_t sc_dev; @@ -72,17 +43,45 @@ struct wbsio_softc { struct isa_io sc_io; }; -int wbsio_probe(device_t, cfdata_t, void *); -void wbsio_attach(device_t, device_t, void *); -int wbsio_detach(device_t, int); -int wbsio_rescan(device_t, const char *, const int *); -void wbsio_childdet(device_t, device_t); -int wbsio_print(void *, const char *); +static const struct wbsio_product { + uint16_t id; + bool idis12bits; + const char *str; +} wbsio_products[] = { + { WBSIO_ID_W83627HF, false, "W83627HF" }, + { WBSIO_ID_W83697HF, false, "W83697HF" }, + { WBSIO_ID_W83637HF, false, "W83637HF" }, + { WBSIO_ID_W83627THF, false, "W83627THF" }, + { WBSIO_ID_W83687THF, false, "W83687THF" }, + { WBSIO_ID_W83627DHG, true, "W83627DHG" }, + { WBSIO_ID_W83627DHGP, true, "W83627DHG-P" }, + { WBSIO_ID_W83627EHF, true, "W83627EHF" }, + { WBSIO_ID_W83627SF, true, "W83627SF" }, + { WBSIO_ID_W83627UHG, true, "W83627UHG" }, + { WBSIO_ID_W83667HG, true, "W83667HG" }, + { WBSIO_ID_W83667HGB, true, "W83667HGB" }, + { WBSIO_ID_W83697UG, true, "W83697UG" }, + { WBSIO_ID_NCT6775F, true, "NCT6775F" }, + { WBSIO_ID_NCT6776F, true, "NCT6776F" }, + { WBSIO_ID_NCT5104D, true, "NCT5104D or 610[246]D" }, + { WBSIO_ID_NCT6779D, true, "NCT6779D" }, + { WBSIO_ID_NCT6791D, true, "NCT6791D" }, + { WBSIO_ID_NCT6792D, true, "NCT6792D" }, + { WBSIO_ID_NCT6793D, true, "NCT6793D" }, + { WBSIO_ID_NCT6795D, true, "NCT6795D" }, +}; -static int wbsio_search(device_t, cfdata_t, const int *, void *); +static const struct wbsio_product *wbsio_lookup(uint8_t id, uint8_t rev); +static int wbsio_match(device_t, cfdata_t, void *); +static void wbsio_attach(device_t, device_t, void *); +static int wbsio_detach(device_t, int); +static int wbsio_rescan(device_t, const char *, const int *); +static void wbsio_childdet(device_t, device_t); +static int wbsio_print(void *, const char *); +static int wbsio_search(device_t, cfdata_t, const int *, void *); CFATTACH_DECL2_NEW(wbsio, sizeof(struct wbsio_softc), - wbsio_probe, wbsio_attach, wbsio_detach, NULL, + wbsio_match, wbsio_attach, wbsio_detach, NULL, wbsio_rescan, wbsio_childdet); static __inline void @@ -113,13 +112,34 @@ wbsio_conf_write(bus_space_tag_t iot, bu bus_space_write_1(iot, ioh, WBSIO_DATA, data); } +static const struct wbsio_product * +wbsio_lookup(uint8_t id, uint8_t rev) +{ + uint16_t wid = ((uint16_t)id << 4) | (rev >> 4); + int i; + + for (i = 0; i < __arraycount(wbsio_products); i++) { + if (wbsio_products[i].idis12bits) { + if (wbsio_products[i].id == wid) + return &wbsio_products[i]; + } else { + if (wbsio_products[i].id == id) + return &wbsio_products[i]; + } + } + + /* Not found */ + return NULL; +} + int -wbsio_probe(device_t parent, cfdata_t match, void *aux) +wbsio_match(device_t parent, cfdata_t match, void *aux) { struct isa_attach_args *ia = aux; + const struct wbsio_product *product; bus_space_tag_t iot; bus_space_handle_t ioh; - uint8_t reg; + uint8_t id, rev; /* Must supply an address */ if (ia->ia_nio < 1) @@ -136,26 +156,21 @@ wbsio_probe(device_t parent, cfdata_t ma if (bus_space_map(iot, ia->ia_io[0].ir_addr, WBSIO_IOSIZE, 0, &ioh)) return 0; wbsio_conf_enable(iot, ioh); - reg = wbsio_conf_read(iot, ioh, WBSIO_ID); - aprint_debug("wbsio_probe: id 0x%02x\n", reg); + id = wbsio_conf_read(iot, ioh, WBSIO_ID); + rev = wbsio_conf_read(iot, ioh, WBSIO_REV); + aprint_debug("wbsio_probe: id 0x%02x, rev 0x%02x\n", id, rev); wbsio_conf_disable(iot, ioh); bus_space_unmap(iot, ioh, WBSIO_IOSIZE); - switch (reg) { - case WBSIO_ID_W83627HF: - case WBSIO_ID_W83627THF: - case WBSIO_ID_W83627EHF: - case WBSIO_ID_W83627DHG: - case WBSIO_ID_W83637HF: - case WBSIO_ID_W83697HF: - ia->ia_nio = 1; - ia->ia_io[0].ir_size = WBSIO_IOSIZE; - ia->ia_niomem = 0; - ia->ia_nirq = 0; - ia->ia_ndrq = 0; - return 1; - } - return 0; + if ((product = wbsio_lookup(id, rev)) == NULL) + return 0; + + ia->ia_nio = 1; + ia->ia_io[0].ir_size = WBSIO_IOSIZE; + ia->ia_niomem = 0; + ia->ia_nirq = 0; + ia->ia_ndrq = 0; + return 1; } void @@ -163,8 +178,10 @@ wbsio_attach(device_t parent, device_t s { struct wbsio_softc *sc = device_private(self); struct isa_attach_args *ia = aux; - const char *desc = NULL; - uint8_t reg; + const struct wbsio_product *product; + const char *desc; + const char *vendor; + uint8_t id, rev; sc->sc_dev = self; @@ -182,43 +199,35 @@ wbsio_attach(device_t parent, device_t s wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); /* Read device ID */ - reg = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID); - switch (reg) { - case WBSIO_ID_W83627HF: - desc = "W83627HF"; - break; - case WBSIO_ID_W83627THF: - desc = "W83627THF"; - break; - case WBSIO_ID_W83627EHF: - desc = "W83627EHF"; - break; - case WBSIO_ID_W83627DHG: - desc = "W83627DHG"; - break; - case WBSIO_ID_W83637HF: - desc = "W83637HF"; - break; - case WBSIO_ID_W83667HG: - desc = "W83667HG"; - break; - case WBSIO_ID_W83697HF: - desc = "W83697HF"; - break; - } - + id = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID); /* Read device revision */ - reg = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV); - - aprint_naive("\n"); - aprint_normal(": Winbond LPC Super I/O %s rev 0x%02x\n", desc, reg); + rev = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV); /* Escape from configuration mode */ wbsio_conf_disable(sc->sc_iot, sc->sc_ioh); + if ((product = wbsio_lookup(id, rev)) == NULL) { + aprint_error_dev(self, "Unknown device. Failed to attach\n"); + return; + } + if (product->idis12bits) + rev &= 0x0f; /* Revision is low 4bits */ + + desc = product->str; + if (desc[0] == 'W') + vendor = "Winbond"; + else + vendor = "Nuvoton"; + aprint_naive("\n"); + aprint_normal(": %s LPC Super I/O %s rev ", vendor, desc); + if (product->idis12bits) { + /* Revision filed is 4bit only */ + aprint_normal("%c\n", 'A' + rev); + } else + aprint_normal("0x%02x\n", rev); + if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); - wbsio_rescan(self, "wbsio", NULL); } @@ -257,8 +266,10 @@ static int wbsio_search(device_t parent, cfdata_t cf, const int *slocs, void *aux) { struct wbsio_softc *sc = device_private(parent); + const struct wbsio_product *product; uint16_t iobase; - uint8_t reg0, reg1; + uint16_t devid; + uint8_t reg0, reg1, rev; /* Enter configuration mode */ wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); @@ -283,6 +294,21 @@ wbsio_search(device_t parent, cfdata_t c if (iobase == 0) return -1; + /* Enter configuration mode */ + wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); + /* Read device ID and revision */ + devid = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID); + rev = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV); + /* Escape from configuration mode */ + wbsio_conf_disable(sc->sc_iot, sc->sc_ioh); + + if ((product = wbsio_lookup(devid, rev)) == NULL) { + aprint_error_dev(parent, "%s: Unknown device.\n", __func__); + return -1; + } + if (product->idis12bits) + devid = (devid << 4) | (rev >> 4); + sc->sc_ia.ia_nio = 1; sc->sc_ia.ia_io = &sc->sc_io; sc->sc_ia.ia_io[0].ir_addr = iobase; @@ -290,6 +316,8 @@ wbsio_search(device_t parent, cfdata_t c sc->sc_ia.ia_niomem = 0; sc->sc_ia.ia_nirq = 0; sc->sc_ia.ia_ndrq = 0; + /* Store device-id to ia_aux */ + sc->sc_ia.ia_aux = (void *)(uintptr_t)devid; sc->sc_lm_dev = config_attach(parent, cf, &sc->sc_ia, wbsio_print); return 0;