Hi all,
I recently built a new system with an ASRock B450M Pro4 motherboard. This
board has a Nuvoton NCT6779D chip to monitor temperatures, fans and
voltages. OpenBSD's lm(4) currently only supports the Nuvoton NCT6776F
chip, added by Marco Pfatschbacher in 2011:
https://marc.info/?l=openbsd-cvs&m=132318770131497&w=2
NetBSD's lm(4) gained support for several other Nuvoton chips in this
commit by SAITOH Masanobu in 2017:
http://mail-index.netbsd.org/source-changes/2017/07/11/msg086253.html
I have adapted the NetBSD code to OpenBSD and confirmed that it appears to
work correctly with my NCT6779D chip. With the attached patch, I get this
in dmesg:
wbsio0 at isa0 port 0x2e/2: NCT6779D rev 0x62
lm1 at wbsio0 port 0x290/8: NCT6779D
And here's the sensor data:
$ sysctl hw.sensors.lm1
hw.sensors.lm1.temp0=29.00 degC (MB Temperature)
hw.sensors.lm1.temp1=31.00 degC (CPU Temperature)
hw.sensors.lm1.temp2=78.00 degC (Aux Temp0)
hw.sensors.lm1.temp3=98.00 degC (Aux Temp1)
hw.sensors.lm1.temp4=22.50 degC (Aux Temp2)
hw.sensors.lm1.temp5=-23.00 degC (Aux Temp3)
hw.sensors.lm1.fan0=1095 RPM (System Fan)
hw.sensors.lm1.fan1=739 RPM (CPU Fan)
hw.sensors.lm1.fan2=400 RPM (Aux Fan0)
hw.sensors.lm1.fan3=0 RPM (Aux Fan1)
hw.sensors.lm1.fan4=387 RPM (Aux Fan2)
hw.sensors.lm1.volt0=0.74 VDC (VCore)
hw.sensors.lm1.volt1=2.16 VDC (VIN1)
hw.sensors.lm1.volt2=3.33 VDC (AVCC)
hw.sensors.lm1.volt3=3.33 VDC (+3.3V)
hw.sensors.lm1.volt4=21.56 VDC (VIN0)
hw.sensors.lm1.volt5=0.87 VDC (VIN8)
hw.sensors.lm1.volt6=0.59 VDC (VIN4)
hw.sensors.lm1.volt7=3.46 VDC (+3.3VSB)
hw.sensors.lm1.volt8=0.00 VDC (VBAT)
hw.sensors.lm1.volt9=0.00 VDC (VTT)
hw.sensors.lm1.volt10=0.45 VDC (VIN5)
hw.sensors.lm1.volt11=2.13 VDC (VIN6)
hw.sensors.lm1.volt12=3.38 VDC (VIN2)
hw.sensors.lm1.volt13=5.12 VDC (VIN3)
hw.sensors.lm1.volt14=1.81 VDC (VIN7)
The motherboard and CPU temperature values look very reasonable; the Aux
Temp values look like garbage, possibly because there aren't any other
sensors on this board? Fan values look reasonable. I am unsure about the
voltage values, but the ones that claim to be 3.3 volts look sane.
This is the first non-trivial patch I'm submitting and my C is pretty
rusty, so I would appreciate review and corrections. I don't have any
other systems with different Nuvoton chips to test, so I can't confirm
that this works for the other chips.
Could anyone please review this and help me get it into commit-ready shape?
Thanks,
Joe
--
Joe Gidi
j...@entropicblur.com
"You cannot buy skill." -- Ross Seyfried
Index: share/man/man4/lm.4
===================================================================
RCS file: /cvs/src/share/man/man4/lm.4,v
retrieving revision 1.25
diff -u -p -u -r1.25 lm.4
--- share/man/man4/lm.4 16 Jul 2013 16:05:49 -0000 1.25
+++ share/man/man4/lm.4 13 Dec 2019 22:49:02 -0000
@@ -82,7 +82,7 @@ National Semiconductor LM79
.It
National Semiconductor LM81
.It
-Nuvoton NCT6776F
+Nuvoton NCT6775F, NCT6776F, NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D
.It
Winbond W83627HF, W83627THF, W83637HF and W83697HF
.It
Index: sys/dev/ic/lm78.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/lm78.c,v
retrieving revision 1.24
diff -u -p -u -r1.24 lm78.c
--- sys/dev/ic/lm78.c 14 Mar 2015 03:38:47 -0000 1.24
+++ sys/dev/ic/lm78.c 13 Dec 2019 22:49:03 -0000
@@ -67,6 +67,7 @@ void wb_refresh_temp(struct lm_softc *,
void wb_refresh_fanrpm(struct lm_softc *, int);
void wb_nct6776f_refresh_fanrpm(struct lm_softc *, int);
void wb_w83792d_refresh_fanrpm(struct lm_softc *, int);
+const char * wb_nct67xx_id2str(uint8_t);
void as_refresh_temp(struct lm_softc *, int);
@@ -80,6 +81,20 @@ struct lm_chip lm_chips[] = {
{ def_match } /* Must be last */
};
+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"},
+};
+
struct lm_sensor lm78_sensors[] = {
/* Voltage */
{ "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volt, RFACT_NONE },
@@ -215,6 +230,43 @@ struct lm_sensor nct6776f_sensors[] = {
{ NULL }
};
+/* NCT6779D */
+struct lm_sensor nct6779d_sensors[] = {
+ /* Voltage */
+ { "VCore", SENSOR_VOLTS_DC, 4, 0x80, lm_refresh_volt, RFACT_NONE / 2 },
+ { "VIN1", SENSOR_VOLTS_DC, 4, 0x81, lm_refresh_volt, RFACT(56, 10) / 2 },
+ { "AVCC", SENSOR_VOLTS_DC, 4, 0x82, lm_refresh_volt, RFACT(34, 34) / 2 },
+ { "+3.3V", SENSOR_VOLTS_DC, 4, 0x83, lm_refresh_volt, RFACT(34, 34) / 2 },
+ { "VIN0", SENSOR_VOLTS_DC, 4, 0x84, lm_refresh_volt, RFACT(48600, 10000) },
+ { "VIN8", SENSOR_VOLTS_DC, 4, 0x85, lm_refresh_volt, RFACT_NONE / 2 },
+ { "VIN4", SENSOR_VOLTS_DC, 4, 0x86, lm_refresh_volt, RFACT_NONE },
+ { "+3.3VSB", SENSOR_VOLTS_DC, 4, 0x87, lm_refresh_volt, RFACT(34, 34) / 2 },
+ { "VBAT", SENSOR_VOLTS_DC, 4, 0x88, lm_refresh_volt, RFACT_NONE },
+ { "VTT", SENSOR_VOLTS_DC, 4, 0x89, lm_refresh_volt, RFACT_NONE },
+ { "VIN5", SENSOR_VOLTS_DC, 4, 0x8a, lm_refresh_volt, RFACT_NONE },
+ { "VIN6", SENSOR_VOLTS_DC, 4, 0x8b, lm_refresh_volt, RFACT_NONE },
+ { "VIN2", SENSOR_VOLTS_DC, 4, 0x8c, lm_refresh_volt, RFACT_NONE },
+ { "VIN3", SENSOR_VOLTS_DC, 4, 0x8d, lm_refresh_volt, RFACT(14414, 10000) },
+ { "VIN7", SENSOR_VOLTS_DC, 4, 0x8e, lm_refresh_volt, RFACT_NONE / 2 },
+
+ /* Temperature */
+ { "MB Temperature", SENSOR_TEMP, 4, 0x90, lm_refresh_temp, 0 },
+ { "CPU Temperature", SENSOR_TEMP, 4, 0x91, wb_refresh_temp, 0 },
+ { "Aux Temp0", SENSOR_TEMP, 4, 0x92, wb_refresh_temp, 0 },
+ { "Aux Temp1", SENSOR_TEMP, 4, 0x93, wb_refresh_temp, 0 },
+ { "Aux Temp2", SENSOR_TEMP, 4, 0x94, wb_refresh_temp, 0 },
+ { "Aux Temp3", SENSOR_TEMP, 4, 0x95, wb_refresh_temp, 0 },
+
+ /* Fans */
+ { "System Fan", SENSOR_FANRPM, 4, 0xc0, wb_nct6776f_refresh_fanrpm, 0 },
+ { "CPU Fan", SENSOR_FANRPM, 4, 0xc2, wb_nct6776f_refresh_fanrpm, 0 },
+ { "Aux Fan0", SENSOR_FANRPM, 4, 0xc4, wb_nct6776f_refresh_fanrpm, 0 },
+ { "Aux Fan1", SENSOR_FANRPM, 4, 0xc6, wb_nct6776f_refresh_fanrpm, 0 },
+ { "Aux Fan2", SENSOR_FANRPM, 4, 0xc8, wb_nct6776f_refresh_fanrpm, 0 },
+
+ { NULL }
+};
+
struct lm_sensor w83637hf_sensors[] = {
/* Voltage */
{ "VCore", SENSOR_VOLTS_DC, 0, 0x20, wb_w83637hf_refresh_vcore },
@@ -489,6 +541,7 @@ def_match(struct lm_softc *sc)
int
wb_match(struct lm_softc *sc)
{
+ const char *model = NULL;
int banksel, vendid, devid;
/* Read vendor ID */
@@ -526,12 +579,46 @@ wb_match(struct lm_softc *sc)
lm_setup_sensors(sc, w83627ehf_sensors);
break;
case WB_CHIPID_W83627DHG:
- if (sc->sioid == WBSIO_ID_NCT6776F) {
- printf(": NCT6776F\n");
- lm_setup_sensors(sc, nct6776f_sensors);
+ model = wb_nct67xx_id2str(sc->sioid);
+ if (model != NULL) {
+ switch (sc->sioid) {
+ case WBSIO_ID_NCT6775F:
+ printf(": NCT6775F\n");
+ lm_setup_sensors(sc, nct6776f_sensors);
+ break;
+ case WBSIO_ID_NCT6776F:
+ printf(": NCT6776F\n");
+ lm_setup_sensors(sc, nct6776f_sensors);
+ break;
+ case WBSIO_ID_NCT5104D:
+ printf(": NCT5104D\n");
+ lm_setup_sensors(sc, nct6776f_sensors);
+ break;
+ case WBSIO_ID_NCT6779D:
+ printf(": NCT6779D\n");
+ lm_setup_sensors(sc, nct6779d_sensors);
+ break;
+ case WBSIO_ID_NCT6791D:
+ printf(": NCT6791D\n");
+ lm_setup_sensors(sc, nct6779d_sensors);
+ break;
+ case WBSIO_ID_NCT6792D:
+ printf(": NCT6792D\n");
+ lm_setup_sensors(sc, nct6779d_sensors);
+ break;
+ case WBSIO_ID_NCT6793D:
+ printf(": NCT6793D\n");
+ lm_setup_sensors(sc, nct6779d_sensors);
+ break;
+ case WBSIO_ID_NCT6795D:
+ printf(": NCT6795D\n");
+ lm_setup_sensors(sc, nct6779d_sensors);
+ break;
+ }
} else {
printf(": W83627DHG\n");
lm_setup_sensors(sc, w83627dhg_sensors);
+ break;
}
break;
case WB_CHIPID_W83637HF:
@@ -851,6 +938,20 @@ wb_nct6776f_refresh_fanrpm(struct lm_sof
sensor->flags &= ~SENSOR_FINVALID;
sensor->value = (datah << 8) | datal;
}
+}
+
+const char *
+wb_nct67xx_id2str(uint8_t id)
+{
+ int i;
+
+ for (i = 0; i < nitems(nct_chips); i++) {
+ if (nct_chips[i].id == id)
+ return nct_chips[i].str;
+}
+
+ /* Not Found */
+ return NULL;
}
void
Index: sys/dev/ic/lm78var.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/lm78var.h,v
retrieving revision 1.18
diff -u -p -u -r1.18 lm78var.h
--- sys/dev/ic/lm78var.h 15 Mar 2016 20:50:22 -0000 1.18
+++ sys/dev/ic/lm78var.h 13 Dec 2019 22:49:03 -0000
@@ -123,7 +123,7 @@
#define WB_VREF 3600
#define WB_W83627EHF_VREF 2048
-#define WB_MAX_SENSORS 19
+#define WB_MAX_SENSORS 36
struct lm_softc;
Index: sys/dev/isa/wbsio.c
===================================================================
RCS file: /cvs/src/sys/dev/isa/wbsio.c,v
retrieving revision 1.10
diff -u -p -u -r1.10 wbsio.c
--- sys/dev/isa/wbsio.c 14 Mar 2015 03:38:47 -0000 1.10
+++ sys/dev/isa/wbsio.c 13 Dec 2019 22:49:03 -0000
@@ -110,8 +110,12 @@ wbsio_probe(struct device *parent, void
case WBSIO_ID_W83627UHG:
case WBSIO_ID_W83637HF:
case WBSIO_ID_W83697HF:
+ case WBSIO_ID_NCT6775F:
case WBSIO_ID_NCT6776F:
case WBSIO_ID_NCT5104D:
+ case WBSIO_ID_NCT6779D:
+ case WBSIO_ID_NCT6791D:
+ case WBSIO_ID_NCT6792D:
ia->ipa_nio = 1;
ia->ipa_io[0].length = WBSIO_IOSIZE;
ia->ipa_nmem = 0;
@@ -170,8 +174,26 @@ wbsio_attach(struct device *parent, stru
case WBSIO_ID_W83697HF:
printf(": W83697HF");
break;
+ case WBSIO_ID_NCT6775F:
+ printf(": NCT6775F");
+ break;
case WBSIO_ID_NCT6776F:
printf(": NCT6776F");
+ break;
+ case WBSIO_ID_NCT6779D:
+ printf(": NCT6779D");
+ break;
+ case WBSIO_ID_NCT6791D:
+ printf(": NCT6791D");
+ break;
+ case WBSIO_ID_NCT6792D:
+ printf(": NCT6792D");
+ break;
+ case WBSIO_ID_NCT6793D:
+ printf(": NCT6793D");
+ break;
+ case WBSIO_ID_NCT6795D:
+ printf(": NCT6795D");
break;
case WBSIO_ID_NCT5104D:
printf(": NCT5104D");
Index: sys/dev/isa/wbsioreg.h
===================================================================
RCS file: /cvs/src/sys/dev/isa/wbsioreg.h,v
retrieving revision 1.4
diff -u -p -u -r1.4 wbsioreg.h
--- sys/dev/isa/wbsioreg.h 2 Jan 2015 23:02:54 -0000 1.4
+++ sys/dev/isa/wbsioreg.h 13 Dec 2019 22:49:03 -0000
@@ -42,8 +42,14 @@
#define WBSIO_ID_W83627SF 0x59
#define WBSIO_ID_W83637HF 0x70
#define WBSIO_ID_W83697HF 0x60
+#define WBSIO_ID_NCT6775F 0xb4
#define WBSIO_ID_NCT6776F 0xc3
#define WBSIO_ID_NCT5104D 0xc4
+#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
/* Logical Device Number (LDN) Assignments */
#define WBSIO_LDN_HM 0x0b