Module Name: src Committed By: msaitoh Date: Fri Aug 18 04:07:51 UTC 2017
Modified Files: src/sys/dev/i2c: lm_i2c.c src/sys/dev/ic: nslm7x.c nslm7xvar.h src/sys/dev/isa: lm_isa_common.c wbsio.c wbsioreg.h Log Message: - WBSIO_ID_W83627DHG and newer devices have 12bit device ID. So, change sioid from 8bit to 16bit and check with it strictly. - s/lm_match/nslm_match/ - split {wb,lm,def}_match() to XXX_match and XXX_attach(). - Rename lm_probe with lm_match and call {wb,nslm,def}_match() at the end of the function to check strictly. - NCT610[246]D is different from otehrs, so add new nct6102d_sensors[] table. - Register offsets of vendor ID and chip id of NCT610[246]D are different from others. When it failed reading vendor ID or chip ID, fallback to NCT610[246]D's register offsets. - Add debug messages. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/dev/i2c/lm_i2c.c cvs rdiff -u -r1.69 -r1.70 src/sys/dev/ic/nslm7x.c cvs rdiff -u -r1.32 -r1.33 src/sys/dev/ic/nslm7xvar.h cvs rdiff -u -r1.5 -r1.6 src/sys/dev/isa/lm_isa_common.c cvs rdiff -u -r1.14 -r1.15 src/sys/dev/isa/wbsio.c cvs rdiff -u -r1.2 -r1.3 src/sys/dev/isa/wbsioreg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/i2c/lm_i2c.c diff -u src/sys/dev/i2c/lm_i2c.c:1.3 src/sys/dev/i2c/lm_i2c.c:1.4 --- src/sys/dev/i2c/lm_i2c.c:1.3 Thu Aug 17 05:27:48 2017 +++ src/sys/dev/i2c/lm_i2c.c Fri Aug 18 04:07:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: lm_i2c.c,v 1.3 2017/08/17 05:27:48 msaitoh Exp $ */ +/* $NetBSD: lm_i2c.c,v 1.4 2017/08/18 04:07:51 msaitoh Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lm_i2c.c,v 1.3 2017/08/17 05:27:48 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lm_i2c.c,v 1.4 2017/08/18 04:07:51 msaitoh Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -76,7 +76,7 @@ lm_i2c_match(device_t parent, cfdata_t m sc.sc_lmsc.lm_readreg = lm_i2c_readreg; sc.sc_tag = ia->ia_tag; sc.sc_addr = ia->ia_addr; - rv = lm_probe(&sc.sc_lmsc); + rv = lm_match(&sc.sc_lmsc); return rv; } Index: src/sys/dev/ic/nslm7x.c diff -u src/sys/dev/ic/nslm7x.c:1.69 src/sys/dev/ic/nslm7x.c:1.70 --- src/sys/dev/ic/nslm7x.c:1.69 Thu Aug 17 05:27:48 2017 +++ src/sys/dev/ic/nslm7x.c Fri Aug 18 04:07:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: nslm7x.c,v 1.69 2017/08/17 05:27:48 msaitoh Exp $ */ +/* $NetBSD: nslm7x.c,v 1.70 2017/08/18 04:07:51 msaitoh Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nslm7x.c,v 1.69 2017/08/17 05:27:48 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nslm7x.c,v 1.70 2017/08/18 04:07:51 msaitoh Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -72,10 +72,16 @@ __KERNEL_RCSID(0, "$NetBSD: nslm7x.c,v 1 #define LM_REFRESH_TIMO (2 * hz) /* 2 seconds */ -static int lm_match(struct lm_softc *); +static const struct wb_product *wb_lookup(struct lm_softc *, + const struct wb_product *, uint16_t); static int wb_match(struct lm_softc *); +static int wb_attach(struct lm_softc *); +static int nslm_match(struct lm_softc *); +static int nslm_attach(struct lm_softc *); static int def_match(struct lm_softc *); +static int def_attach(struct lm_softc *); static void wb_temp_diode_type(struct lm_softc *, int); +static uint16_t wb_read_vendorid(struct lm_softc *); static void lm_refresh(void *); @@ -94,32 +100,18 @@ static void wb_refresh_temp(struct lm_so static void wb_refresh_fanrpm(struct lm_softc *, int); static void wb_w83792d_refresh_fanrpm(struct lm_softc *, int); static void wb_nct6776f_refresh_fanrpm(struct lm_softc *, int); -static const char * wb_nct67xx_id2str(uint8_t); static void as_refresh_temp(struct lm_softc *, int); struct lm_chip { int (*chip_match)(struct lm_softc *); + int (*chip_attach)(struct lm_softc *); }; static struct lm_chip lm_chips[] = { - { wb_match }, - { lm_match }, - { def_match } /* Must be last */ -}; - -static struct { - uint8_t id; - const char *str; -} nct_chips[] = { - {WBSIO_ID_NCT6775F, "NCT6775F"}, - {WBSIO_ID_NCT6776F, "NCT6776F"}, - {WBSIO_ID_NCT5104D, "NCT5104D or 610[246]D"}, - {WBSIO_ID_NCT6779D, "NCT6779D"}, - {WBSIO_ID_NCT6791D, "NCT6791D"}, - {WBSIO_ID_NCT6792D, "NCT6792D"}, - {WBSIO_ID_NCT6793D, "NCT6793D"}, - {WBSIO_ID_NCT6795D, "NCT6795D"}, + { wb_match, wb_attach }, + { nslm_match, nslm_attach }, + { def_match, def_attach } /* Must be last */ }; /* LM78/78J/79/81 */ @@ -1784,6 +1776,137 @@ static const struct lm_sensor nct6776f_s { .desc = NULL } }; +/* NCT610[246]D */ +static const struct lm_sensor nct6102d_sensors[] = { + /* Voltage */ + { + .desc = "VCore", + .type = ENVSYS_SVOLTS_DC, + .bank = 0, + .reg = 0x00, + .refresh = lm_refresh_volt, + .rfact = RFACT_NONE + }, + { + .desc = "VIN0", + .type = ENVSYS_SVOLTS_DC, + .bank = 0, + .reg = 0x01, + .refresh = lm_refresh_volt, + .rfact = RFACT_NONE + }, + { + .desc = "AVCC", + .type = ENVSYS_SVOLTS_DC, + .bank = 0, + .reg = 0x02, + .refresh = lm_refresh_volt, + .rfact = RFACT(34, 34) / 2 + }, + { + .desc = "3VCC", + .type = ENVSYS_SVOLTS_DC, + .bank = 0, + .reg = 0x03, + .refresh = lm_refresh_volt, + .rfact = RFACT(34, 34) / 2 + }, + { + .desc = "VIN1", + .type = ENVSYS_SVOLTS_DC, + .bank = 0, + .reg = 0x04, + .refresh = lm_refresh_volt, + .rfact = RFACT_NONE + }, + { + .desc = "VIN2", + .type = ENVSYS_SVOLTS_DC, + .bank = 0, + .reg = 0x05, + .refresh = lm_refresh_volt, + .rfact = RFACT(34, 34) / 2 + }, + { + .desc = "+3.3VSB", + .type = ENVSYS_SVOLTS_DC, + .bank = 0, + .reg = 0x07, + .refresh = lm_refresh_volt, + .rfact = RFACT(34, 34) / 2 + }, + { + .desc = "VBAT", + .type = ENVSYS_SVOLTS_DC, + .bank = 0, + .reg = 0x08, + .refresh = lm_refresh_volt, + .rfact = RFACT(34, 34) / 2 + }, + { + .desc = "VTT", + .type = ENVSYS_SVOLTS_DC, + .bank = 0, + .reg = 0x09, + .refresh = lm_refresh_volt, + .rfact = RFACT_NONE + }, + + /* Temperature */ + { + .desc = "MB Temperature", + .type = ENVSYS_STEMP, + .bank = 0, + .reg = 0x18, + .refresh = lm_refresh_temp, + .rfact = 0 + }, + { + .desc = "CPU Temperature", + .type = ENVSYS_STEMP, + .bank = 0, + .reg = 0x19, + .refresh = lm_refresh_temp, + .rfact = 0 + }, + { + .desc = "Aux Temp", + .type = ENVSYS_STEMP, + .bank = 0, + .reg = 0x1a, + .refresh = lm_refresh_temp, + .rfact = 0 + }, + + /* Fans */ + { + .desc = "System Fan", + .type = ENVSYS_SFANRPM, + .bank = 0, + .reg = 0x30, + .refresh = wb_nct6776f_refresh_fanrpm, + .rfact = 0 + }, + { + .desc = "CPU Fan", + .type = ENVSYS_SFANRPM, + .bank = 0, + .reg = 0x32, + .refresh = wb_nct6776f_refresh_fanrpm, + .rfact = 0 + }, + { + .desc = "Aux Fan", + .type = ENVSYS_SFANRPM, + .bank = 0, + .reg = 0x34, + .refresh = wb_nct6776f_refresh_fanrpm, + .rfact = 0 + }, + + { .desc = NULL } +}; + /* NCT6779D */ static const struct lm_sensor nct6779d_sensors[] = { /* Voltage */ @@ -2003,6 +2126,44 @@ static const struct lm_sensor nct6779d_s { .desc = NULL } }; +static const struct wb_product wb_products[] = { + { WB_CHIPID_W83627HF, "W83627HF", w83627hf_sensors, NULL }, + { WB_CHIPID_W83627THF, "W83627THF",w83637hf_sensors, NULL }, + { WB_CHIPID_W83627EHF_A,"W83627EHF-A",w83627ehf_sensors,NULL }, + { WB_CHIPID_W83627EHF, "W83627EHF",w83627ehf_sensors,NULL }, + { WB_CHIPID_W83627DHG, NULL, NULL, NULL }, + { WB_CHIPID_W83637HF, "W83637HF", w83637hf_sensors, NULL }, + { WB_CHIPID_W83697HF, "W83697HF", w83697hf_sensors, NULL }, + { WB_CHIPID_W83781D, "W83781D", w83781d_sensors, NULL }, + { WB_CHIPID_W83781D_2, "W83781D", w83781d_sensors, NULL }, + { WB_CHIPID_W83782D, "W83782D", w83782d_sensors, NULL }, + { WB_CHIPID_W83783S, "W83783S", w83783s_sensors, NULL }, + { WB_CHIPID_W83791D, "W83791D", w83791d_sensors, NULL }, + { WB_CHIPID_W83791SD, "W83791SD", NULL, NULL }, + { WB_CHIPID_W83792D, "W83792D", w83792d_sensors, NULL }, + { WB_CHIPID_AS99127F, NULL, NULL, NULL }, + { 0, NULL, NULL, NULL } +}; + +static const struct wb_product wbsio_products[] = { + { WBSIO_ID_W83627DHG, "W83627DHG",w83627dhg_sensors,NULL }, + { WBSIO_ID_NCT6775F, "NCT6775F", nct6776f_sensors, NULL }, + { WBSIO_ID_NCT6776F, "NCT6776F", nct6776f_sensors, NULL }, + { WBSIO_ID_NCT5104D, "NCT5104D or 610[246]D",nct6102d_sensors,NULL }, + { WBSIO_ID_NCT6779D, "NCT6779D", nct6779d_sensors, NULL }, + { WBSIO_ID_NCT6791D, "NCT6791D", nct6779d_sensors, NULL }, + { WBSIO_ID_NCT6792D, "NCT6792D", nct6779d_sensors, NULL }, + { WBSIO_ID_NCT6793D, "NCT6793D", nct6779d_sensors, NULL }, + { WBSIO_ID_NCT6795D, "NCT6795D", nct6779d_sensors, NULL }, + { 0, NULL, NULL, NULL } +}; + +static const struct wb_product as99127f_products[] = { + { WB_VENDID_ASUS, "AS99127F", w83781d_sensors, NULL }, + { WB_VENDID_WINBOND, "AS99127F rev 2",as99127f_sensors,NULL }, + { 0, NULL, NULL, NULL } +}; + static void lm_generic_banksel(struct lm_softc *lmsc, uint8_t bank) { @@ -2010,16 +2171,16 @@ lm_generic_banksel(struct lm_softc *lmsc } /* - * bus independent probe + * bus independent match * * prerequisites: lmsc contains valid lm_{read,write}reg() routines * and associated bus access data is present in attachment's softc */ int -lm_probe(struct lm_softc *lmsc) +lm_match(struct lm_softc *lmsc) { uint8_t cr; - int rv; + int i, rv; /* Perform LM78 reset */ /*(*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x80); */ @@ -2027,24 +2188,52 @@ lm_probe(struct lm_softc *lmsc) cr = (*lmsc->lm_readreg)(lmsc, LMD_CONFIG); /* XXX - spec says *only* 0x08! */ - if ((cr == 0x08) || (cr == 0x01) || (cr == 0x03) || (cr == 0x06)) - rv = 1; - else - rv = 0; + if ((cr != 0x08) && (cr != 0x01) && (cr != 0x03) && (cr != 0x06)) + return 0; + + DPRINTF(("%s: 0x80 check: cr = %x\n", __func__, cr)); - DPRINTF(("%s: rv = %d, cr = %x\n", __func__, rv, cr)); + for (i = 0; i < __arraycount(lm_chips); i++) + if ((rv = lm_chips[i].chip_match(lmsc)) != 0) + return rv; - return rv; + return 0; +} + +int +nslm_match(struct lm_softc *sc) +{ + uint8_t chipid; + + /* See if we have an LM78/LM78J/LM79 or LM81 */ + chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; + switch(chipid) { + case LM_ID_LM78: + case LM_ID_LM78J: + case LM_ID_LM79: + case LM_ID_LM81: + break; + default: + return 0; + } + DPRINTF(("%s: chipid %x\n", __func__, chipid)); + return 1; } void lm_attach(struct lm_softc *lmsc) { uint32_t i; + int rv; - for (i = 0; i < __arraycount(lm_chips); i++) - if (lm_chips[i].chip_match(lmsc)) - break; + for (i = 0; i < __arraycount(lm_chips); i++) { + if (lm_chips[i].chip_match(lmsc) != 0) { + if (lm_chips[i].chip_attach(lmsc) == 0) + break; + else + return; + } + } /* Start the monitoring loop */ (*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x01); @@ -2053,9 +2242,11 @@ lm_attach(struct lm_softc *lmsc) /* Initialize sensors */ for (i = 0; i < lmsc->numsensors; i++) { lmsc->sensors[i].state = ENVSYS_SINVALID; - if (sysmon_envsys_sensor_attach(lmsc->sc_sme, - &lmsc->sensors[i])) { + if ((rv = sysmon_envsys_sensor_attach(lmsc->sc_sme, + &lmsc->sensors[i])) != 0) { sysmon_envsys_destroy(lmsc->sc_sme); + aprint_error_dev(lmsc->sc_dev, + "sysmon_envsys_sensor_attach() returned %d\n", rv); return; } } @@ -2102,7 +2293,7 @@ lm_refresh(void *arg) } static int -lm_match(struct lm_softc *sc) +nslm_attach(struct lm_softc *sc) { const char *model = NULL; uint8_t chipid; @@ -2123,7 +2314,7 @@ lm_match(struct lm_softc *sc) model = "LM81"; break; default: - return 0; + return -1; } aprint_naive("\n"); @@ -2133,22 +2324,29 @@ lm_match(struct lm_softc *sc) lm_setup_sensors(sc, lm78_sensors); sc->refresh_sensor_data = lm_refresh_sensor_data; - return 1; + return 0; } static int def_match(struct lm_softc *sc) { + + return 1; +} + +static int +def_attach(struct lm_softc *sc) +{ uint8_t chipid; chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK; aprint_naive("\n"); aprint_normal("\n"); - aprint_error_dev(sc->sc_dev, "Unknown chip (ID %02x)\n", chipid); + aprint_error_dev(sc->sc_dev, "Unknown chip (ID 0x%02x)\n", chipid); lm_setup_sensors(sc, lm78_sensors); sc->refresh_sensor_data = lm_refresh_sensor_data; - return 1; + return 0; } static void @@ -2199,152 +2397,236 @@ wb_temp_diode_type(struct lm_softc *sc, } } +static const struct wb_product * +wb_lookup(struct lm_softc *sc, const struct wb_product *products, uint16_t id) +{ + const struct wb_product *prod = products; + int i = 0; + + while (prod[i].id != 0) { + if (prod[i].id != id) { + i++; + continue; + } + if (prod[i].str == NULL) { + if (products == wb_products) { + if (id == WB_CHIPID_W83627DHG) { + /* + * Lookup wbsio_products + * with WBSIO_ID. + */ + return wb_lookup(sc, wbsio_products, + sc->sioid); + } else if (id == WB_CHIPID_AS99127F) { + /* + * Lookup as99127f_products + * with WB_VENDID. + */ + return wb_lookup(sc, as99127f_products, + wb_read_vendorid(sc)); + } else + return NULL; /* not occur */ + } + return NULL; /* not occur */ + } + return &prod[i]; + } + + /* Not found */ + return NULL; +} + +static uint16_t +wb_read_vendorid(struct lm_softc *sc) +{ + uint16_t vendid; + uint8_t vendidreg; + uint8_t banksel; + + /* Save bank */ + banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); + + /* Check default vendor ID register first */ + vendidreg = WB_VENDID; + +retry: + /* Read vendor ID */ + lm_generic_banksel(sc, WB_BANKSEL_HBAC); + vendid = (*sc->lm_readreg)(sc, vendidreg) << 8; + lm_generic_banksel(sc, 0); + vendid |= (*sc->lm_readreg)(sc, vendidreg); + + if ((vendidreg == WB_VENDID) + && (vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS)) { + /* If it failed, try NCT6102 vendor ID register */ + vendidreg = WB_NCT6102_VENDID; + goto retry; + } else if ((vendidreg == WB_NCT6102_VENDID) + && (vendid != WB_VENDID_WINBOND)) + vendid = 0; /* XXX */ + + /* Restore bank */ + lm_generic_banksel(sc, banksel); + + return vendid; +} + +static uint8_t +wb_read_chipid(struct lm_softc *sc) +{ + const struct wb_product *prod; + uint8_t chipidreg, chipid, banksel; + + /* Save bank */ + banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); + + /* Check default vendor ID register first */ + chipidreg = WB_BANK0_CHIPID; + lm_generic_banksel(sc, WB_BANKSEL_B0); + +retry: + (void)(*sc->lm_readreg)(sc, LMD_CHIPID); + chipid = (*sc->lm_readreg)(sc, chipidreg); + prod = wb_lookup(sc, wb_products, chipid); + if (prod == NULL) { + if (chipidreg == WB_BANK0_CHIPID) { + chipidreg = WB_BANK0_NCT6102_CHIPID; + goto retry; + } else + chipid = 0; + } + /* Restore bank */ + lm_generic_banksel(sc, banksel); + + return chipid; +} + static int wb_match(struct lm_softc *sc) { + const struct wb_product *prod; + uint16_t vendid; + uint8_t chipid; + + /* Read vendor ID */ + vendid = wb_read_vendorid(sc); + DPRINTF(("%s: winbond vend id 0x%x\n", __func__, vendid)); + if ((vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS)) + return 0; + + /* Read device/chip ID */ + chipid = wb_read_chipid(sc); + DPRINTF(("%s: winbond chip id 0x%x\n", __func__, chipid)); + prod = wb_lookup(sc, wb_products, chipid); + + if (prod == NULL) { + if (vendid == WB_VENDID_WINBOND) + return 1; /* Generic match */ + else + return 0; + } + DPRINTF(("%s: chipid %02x, sioid = %04x\n", __func__, chipid, + sc->sioid)); + + return 10; /* found */ +} + +static int +wb_attach(struct lm_softc *sc) +{ + device_t dev = sc->sc_dev; + const struct wb_product *prod; const char *model = NULL; const char *vendor = "Winbond"; + const struct lm_sensor *sensors; uint16_t vendid; uint8_t banksel; int cf_flags; aprint_naive("\n"); aprint_normal("\n"); - /* Read vendor ID */ - banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); - lm_generic_banksel(sc, WB_BANKSEL_HBAC); - vendid = (*sc->lm_readreg)(sc, WB_VENDID) << 8; - lm_generic_banksel(sc, 0); - vendid |= (*sc->lm_readreg)(sc, WB_VENDID); - DPRINTF(("%s: winbond vend id 0x%x\n", __func__, vendid)); - if (vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS) - return 0; - /* Read device/chip ID */ - lm_generic_banksel(sc, WB_BANKSEL_B0); - (void)(*sc->lm_readreg)(sc, LMD_CHIPID); - sc->chipid = (*sc->lm_readreg)(sc, WB_BANK0_CHIPID); - lm_generic_banksel(sc, banksel); - cf_flags = device_cfdata(sc->sc_dev)->cf_flags; + sc->chipid = wb_read_chipid(sc); DPRINTF(("%s: winbond chip id 0x%x\n", __func__, sc->chipid)); + if ((prod = wb_lookup(sc, wb_products, sc->chipid)) != NULL) { + switch (prod->str[0]) { + case 'W': + vendor = "Winbond"; + break; + case 'A': + vendor = "ASUS"; + break; + case 'N': + vendor = "Nuvoton"; + break; + default: + aprint_error_dev(dev, "Unknown model (%s)\n", model); + return -1; + } + model = prod->str; + sensors = prod->sensors; + sc->refresh_sensor_data = wb_refresh_sensor_data; + if (prod->extattach != NULL) + prod->extattach(sc); + } else { + vendid = wb_read_vendorid(sc); + if (vendid == WB_VENDID_WINBOND) { + vendor = "Winbond"; + model = "unknown-model"; + + /* Handle as a standard LM78. */ + sensors = lm78_sensors; + sc->refresh_sensor_data = lm_refresh_sensor_data; + } else { + aprint_error_dev(dev, "Unknown chip (ID %02x)\n", + sc->chipid); + return -1; + } + } + + cf_flags = device_cfdata(dev)->cf_flags; + + if (sensors != NULL) { + lm_setup_sensors(sc, sensors); + + /* XXX Is this correct? Check all datasheets. */ + switch (sc->chipid) { + case WB_CHIPID_W83627EHF_A: + case WB_CHIPID_W83781D: + case WB_CHIPID_W83781D_2: + case WB_CHIPID_W83791SD: + case WB_CHIPID_W83792D: + case WB_CHIPID_AS99127F: + break; + default: + wb_temp_diode_type(sc, cf_flags); + break; + } + } + + /* XXX Is this correct? Check all datasheets. */ + banksel = (*sc->lm_readreg)(sc, WB_BANKSEL); switch(sc->chipid) { - case WB_CHIPID_W83627HF: - model = "W83627HF"; - lm_setup_sensors(sc, w83627hf_sensors); - wb_temp_diode_type(sc, cf_flags); - break; case WB_CHIPID_W83627THF: - model = "W83627THF"; lm_generic_banksel(sc, WB_BANKSEL_B0); if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9) sc->vrm9 = 1; lm_generic_banksel(sc, banksel); - lm_setup_sensors(sc, w83637hf_sensors); - wb_temp_diode_type(sc, cf_flags); - break; - case WB_CHIPID_W83627EHF_A: - model = "W83627EHF-A"; - lm_setup_sensors(sc, w83627ehf_sensors); - break; - case WB_CHIPID_W83627EHF: - model = "W83627EHF"; - lm_setup_sensors(sc, w83627ehf_sensors); - wb_temp_diode_type(sc, cf_flags); - break; - case WB_CHIPID_W83627DHG: - model = wb_nct67xx_id2str(sc->sioid); - if (model != NULL) { - vendor = "Nuvoton"; - switch (sc->sioid) { - case WBSIO_ID_NCT6775F: - case WBSIO_ID_NCT6776F: - case WBSIO_ID_NCT5104D: - lm_setup_sensors(sc, nct6776f_sensors); - break; - case WBSIO_ID_NCT6779D: - case WBSIO_ID_NCT6791D: - case WBSIO_ID_NCT6792D: - case WBSIO_ID_NCT6793D: - case WBSIO_ID_NCT6795D: - lm_setup_sensors(sc, nct6779d_sensors); - break; - default: - panic("%s: unknown id (%02x)", __func__, - sc->sioid); - break; - } - } else { - model = "W83627DHG"; - lm_setup_sensors(sc, w83627dhg_sensors); - break; - } - wb_temp_diode_type(sc, cf_flags); break; case WB_CHIPID_W83637HF: - model = "W83637HF"; lm_generic_banksel(sc, WB_BANKSEL_B0); if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9) sc->vrm9 = 1; lm_generic_banksel(sc, banksel); - lm_setup_sensors(sc, w83637hf_sensors); - wb_temp_diode_type(sc, cf_flags); - break; - case WB_CHIPID_W83697HF: - model = "W83697HF"; - lm_setup_sensors(sc, w83697hf_sensors); - wb_temp_diode_type(sc, cf_flags); - break; - case WB_CHIPID_W83781D: - case WB_CHIPID_W83781D_2: - model = "W83781D"; - lm_setup_sensors(sc, w83781d_sensors); - break; - case WB_CHIPID_W83782D: - model = "W83782D"; - lm_setup_sensors(sc, w83782d_sensors); - wb_temp_diode_type(sc, cf_flags); - break; - case WB_CHIPID_W83783S: - model = "W83783S"; - lm_setup_sensors(sc, w83783s_sensors); - wb_temp_diode_type(sc, cf_flags); - break; - case WB_CHIPID_W83791D: - model = "W83791D"; - lm_setup_sensors(sc, w83791d_sensors); - wb_temp_diode_type(sc, cf_flags); - break; - case WB_CHIPID_W83791SD: - model = "W83791SD"; - break; - case WB_CHIPID_W83792D: - model = "W83792D"; - lm_setup_sensors(sc, w83792d_sensors); - break; - case WB_CHIPID_AS99127F: - vendor = "ASUS"; - if (vendid == WB_VENDID_ASUS) { - model = "AS99127F"; - lm_setup_sensors(sc, w83781d_sensors); - } else { - model = "AS99127F rev 2"; - lm_setup_sensors(sc, as99127f_sensors); - } break; default: - aprint_normal_dev(sc->sc_dev, - "unknown Winbond chip (ID 0x%x)\n", sc->chipid); - /* Handle as a standard LM78. */ - lm_setup_sensors(sc, lm78_sensors); - sc->refresh_sensor_data = lm_refresh_sensor_data; - return 1; + break; } - aprint_normal_dev(sc->sc_dev, "%s %s Hardware monitor\n", vendor, model); + aprint_normal_dev(dev, "%s %s Hardware monitor\n", vendor, model); - sc->refresh_sensor_data = wb_refresh_sensor_data; - return 1; + return 0; } static void @@ -2621,20 +2903,6 @@ wb_nct6776f_refresh_fanrpm(struct lm_sof } } -static const char * -wb_nct67xx_id2str(uint8_t id) -{ - int i; - - for (i = 0; i < __arraycount(nct_chips); i++) { - if (nct_chips[i].id == id) - return nct_chips[i].str; - } - - /* Not Found */ - return NULL; -} - static void wb_w83792d_refresh_fanrpm(struct lm_softc *sc, int n) { Index: src/sys/dev/ic/nslm7xvar.h diff -u src/sys/dev/ic/nslm7xvar.h:1.32 src/sys/dev/ic/nslm7xvar.h:1.33 --- src/sys/dev/ic/nslm7xvar.h:1.32 Thu Aug 17 05:27:48 2017 +++ src/sys/dev/ic/nslm7xvar.h Fri Aug 18 04:07:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: nslm7xvar.h,v 1.32 2017/08/17 05:27:48 msaitoh Exp $ */ +/* $NetBSD: nslm7xvar.h,v 1.33 2017/08/18 04:07:51 msaitoh Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -86,6 +86,7 @@ #define WB_PIN 0x4b /* Pin Control */ #define WB_BANKSEL 0x4e /* Bank Select */ #define WB_VENDID 0x4f /* Vendor ID */ +#define WB_NCT6102_VENDID 0xfe /* Vendor ID for NCT610[246] */ /* Bank 0 regs */ #define WB_BANK0_CHIPID 0x58 /* Chip ID */ @@ -96,6 +97,7 @@ #define WB_BANK0_FAN5 0xbb /* Fan 5 reading (W83791D only) */ #define WB_BANK0_CONFIG 0x18 /* VRM & OVT Config (W83627THF/W83637HF) */ +#define WB_BANK0_NCT6102_CHIPID 0xff /* Chip ID for NCT610[246] */ /* Bank 1 registers */ #define WB_BANK1_T2H 0x50 /* Temperature 2 High Byte */ @@ -170,7 +172,7 @@ struct lm_softc { const struct lm_sensor *lm_sensors; uint8_t chipid; uint8_t vrm9; - uint8_t sioid; + uint16_t sioid; }; struct lm_sensor { @@ -182,8 +184,15 @@ struct lm_sensor { int rfact; }; +struct wb_product { + uint16_t id; /* WB_CHIPID(8b) or WBSIO_ID(16b) or WB_VENDID(16b) */ + const char *str; + const struct lm_sensor *sensors; + void (*extattach)(struct lm_softc *); +}; + +int lm_match(struct lm_softc *); void lm_attach(struct lm_softc *); void lm_detach(struct lm_softc *); -int lm_probe(struct lm_softc *); #endif /* _DEV_ISA_NSLM7XVAR_H_ */ Index: src/sys/dev/isa/lm_isa_common.c diff -u src/sys/dev/isa/lm_isa_common.c:1.5 src/sys/dev/isa/lm_isa_common.c:1.6 --- src/sys/dev/isa/lm_isa_common.c:1.5 Thu Aug 17 05:27:48 2017 +++ src/sys/dev/isa/lm_isa_common.c Fri Aug 18 04:07:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: lm_isa_common.c,v 1.5 2017/08/17 05:27:48 msaitoh Exp $ */ +/* $NetBSD: lm_isa_common.c,v 1.6 2017/08/18 04:07:51 msaitoh Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lm_isa_common.c,v 1.5 2017/08/17 05:27:48 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lm_isa_common.c,v 1.6 2017/08/18 04:07:51 msaitoh Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -80,13 +80,12 @@ lm_isa_match(device_t parent, cfdata_t m if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, 8, 0, &ioh)) return 0; - /* Bus independent probe */ sc.lm_iot = ia->ia_iot; sc.lm_ioh = ioh; sc.lmsc.lm_writereg = lm_isa_writereg; sc.lmsc.lm_readreg = lm_isa_readreg; - rv = lm_probe(&sc.lmsc); + rv = lm_match(&sc.lmsc); bus_space_unmap(ia->ia_iot, ioh, 8); @@ -122,7 +121,7 @@ lm_isa_attach(device_t parent, device_t sc->lmsc.lm_writereg = lm_isa_writereg; sc->lmsc.lm_readreg = lm_isa_readreg; /* pass wbsio Device ID */ - sc->lmsc.sioid = (uint8_t)(uintptr_t)ia->ia_aux; + sc->lmsc.sioid = (uint16_t)(uintptr_t)ia->ia_aux; lm_attach(&sc->lmsc); } Index: src/sys/dev/isa/wbsio.c diff -u src/sys/dev/isa/wbsio.c:1.14 src/sys/dev/isa/wbsio.c:1.15 --- src/sys/dev/isa/wbsio.c:1.14 Thu Aug 17 05:32:04 2017 +++ src/sys/dev/isa/wbsio.c Fri Aug 18 04:07:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wbsio.c,v 1.14 2017/08/17 05:32:04 msaitoh Exp $ */ +/* $NetBSD: wbsio.c,v 1.15 2017/08/18 04:07:51 msaitoh Exp $ */ /* $OpenBSD: wbsio.c,v 1.10 2015/03/14 03:38:47 jsg Exp $ */ /* * Copyright (c) 2008 Mark Kettenis <kette...@openbsd.org> @@ -43,7 +43,36 @@ struct wbsio_softc { struct isa_io sc_io; }; -static int wbsio_probe(device_t, cfdata_t, void *); +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 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 *); @@ -52,7 +81,7 @@ static int wbsio_print(void *, const cha 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 @@ -83,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) @@ -106,39 +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_W83627DHG: - case WBSIO_ID_W83627DHGP: - case WBSIO_ID_W83627EHF: - case WBSIO_ID_W83627SF: - case WBSIO_ID_W83627THF: - case WBSIO_ID_W83627UHG: - case WBSIO_ID_W83637HF: - case WBSIO_ID_W83667HG: - case WBSIO_ID_W83667HGB: - case WBSIO_ID_W83687THF: - case WBSIO_ID_W83697HF: - case WBSIO_ID_W83697UG: - case WBSIO_ID_NCT5104D: - case WBSIO_ID_NCT6775F: - case WBSIO_ID_NCT6776F: - case WBSIO_ID_NCT6779D: - case WBSIO_ID_NCT6791D: - case WBSIO_ID_NCT6792D: - 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 @@ -146,9 +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; - const char *vendor = "Winbond"; - uint8_t reg; + const struct wbsio_product *product; + const char *desc; + const char *vendor; + uint8_t id, rev; sc->sc_dev = self; @@ -166,89 +199,33 @@ 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_W83627DHG: - desc = "W83627DHG"; - break; - case WBSIO_ID_W83627DHGP: - desc = "W83627DHG-P"; - break; - case WBSIO_ID_W83627EHF: - desc = "W83627EHF"; - break; - case WBSIO_ID_W83627SF: - desc = "W83627SF"; - break; - case WBSIO_ID_W83627THF: - desc = "W83627THF"; - break; - case WBSIO_ID_W83627UHG: - desc = "W83627UHG"; - break; - case WBSIO_ID_W83637HF: - desc = "W83637HF"; - break; - case WBSIO_ID_W83667HG: - desc = "W83667HG"; - break; - case WBSIO_ID_W83667HGB: - desc = "W83667HGB"; - break; - case WBSIO_ID_W83687THF: - desc = "W83687THF"; - break; - case WBSIO_ID_W83697HF: - desc = "W83697HF"; - break; - case WBSIO_ID_W83697UG: - desc = "W83697UG"; - break; - case WBSIO_ID_NCT5104D: - vendor = "Nuvoton"; - desc = "NCT5104D"; - break; - case WBSIO_ID_NCT6775F: - vendor = "Nuvoton"; - desc = "NCT6775F"; - break; - case WBSIO_ID_NCT6776F: - vendor = "Nuvoton"; - desc = "NCT6776F"; - break; - case WBSIO_ID_NCT6779D: - vendor = "Nuvoton"; - desc = "NCT6779D"; - break; - case WBSIO_ID_NCT6791D: - vendor = "Nuvoton"; - desc = "NCT6791D"; - break; - case WBSIO_ID_NCT6792D: - vendor = "Nuvoton"; - desc = "NCT6792D"; - break; - case WBSIO_ID_NCT6793D: - vendor = "Nuvoton"; - desc = "NCT6793D"; - break; - case WBSIO_ID_NCT6795D: - vendor = "Nuvoton"; - desc = "NCT6795D"; - 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(": %s LPC Super I/O %s rev 0x%02x\n", vendor, 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); @@ -289,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, devid; + uint16_t devid; + uint8_t reg0, reg1, rev; /* Enter configuration mode */ wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); @@ -317,11 +296,19 @@ wbsio_search(device_t parent, cfdata_t c /* Enter configuration mode */ wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); - /* Read device ID */ + /* 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; Index: src/sys/dev/isa/wbsioreg.h diff -u src/sys/dev/isa/wbsioreg.h:1.2 src/sys/dev/isa/wbsioreg.h:1.3 --- src/sys/dev/isa/wbsioreg.h:1.2 Tue Jul 11 10:10:51 2017 +++ src/sys/dev/isa/wbsioreg.h Fri Aug 18 04:07:51 2017 @@ -34,26 +34,27 @@ #define WBSIO_REV 0x21 /* Device Revision */ #define WBSIO_ID_W83627HF 0x52 -#define WBSIO_ID_W83627SF 0x59 #define WBSIO_ID_W83697HF 0x60 -#define WBSIO_ID_W83697UG 0x68 #define WBSIO_ID_W83637HF 0x70 #define WBSIO_ID_W83627THF 0x82 #define WBSIO_ID_W83687THF 0x85 -#define WBSIO_ID_W83627EHF 0x88 -#define WBSIO_ID_W83627DHG 0xa0 -#define WBSIO_ID_W83627UHG 0xa2 -#define WBSIO_ID_W83667HG 0xa5 -#define WBSIO_ID_W83627DHGP 0xb0 -#define WBSIO_ID_W83667HGB 0xb3 -#define WBSIO_ID_NCT6775F 0xb4 -#define WBSIO_ID_NCT6776F 0xc3 -#define WBSIO_ID_NCT5104D 0xc4 /* 610[246]D */ -#define WBSIO_ID_NCT6779D 0xc5 -#define WBSIO_ID_NCT6791D 0xc8 -#define WBSIO_ID_NCT6792D 0xc9 -#define WBSIO_ID_NCT6793D 0xd1 -#define WBSIO_ID_NCT6795D 0xd3 +#define WBSIO_ID_W83627SF 0x595 +#define WBSIO_ID_W83697UG 0x681 +#define WBSIO_ID_W83627EHF_A 0x885 +#define WBSIO_ID_W83627EHF 0x886 +#define WBSIO_ID_W83627DHG 0xa02 +#define WBSIO_ID_W83627UHG 0xa23 +#define WBSIO_ID_W83667HG 0xa51 +#define WBSIO_ID_W83627DHGP 0xb07 +#define WBSIO_ID_W83667HGB 0xb35 +#define WBSIO_ID_NCT6775F 0xb47 +#define WBSIO_ID_NCT6776F 0xc33 +#define WBSIO_ID_NCT5104D 0xc45 /* 610[246]D */ +#define WBSIO_ID_NCT6779D 0xc56 +#define WBSIO_ID_NCT6791D 0xc80 +#define WBSIO_ID_NCT6792D 0xc91 +#define WBSIO_ID_NCT6793D 0xd12 +#define WBSIO_ID_NCT6795D 0xd35 /* Logical Device Number (LDN) Assignments */ #define WBSIO_LDN_HM 0x0b