NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/49747: [PATCH] add support Nuvoton NCT6776F from OpenBSD



>Number:         49747
>Category:       kern
>Synopsis:       [PATCH] add support Nuvoton NCT6776F from OpenBSD
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Mar 15 00:05:00 +0000 2015
>Originator:     HITOSHI Osada
>Release:        NetBSD-current 20150314
>Organization:
None
>Environment:
NetBSD athlon5350 7.99.6 NetBSD 7.99.6 (ATHLON5350) #0: Sat Mar 14 09:39:31 JST 2015  that@athlon5350:/tmp/obj/sys/arch/amd64/compile/ATHLON5350 amd64
>Description:
Add support for Nuvoton NCT6776F fan, voltage and temperature sensors.
Most of the codes are taken from OpenBSD.
>How-To-Repeat:

>Fix:
>From 96cdc6f4cd2c8e74d8417d24526c118cc91827e9 Mon Sep 17 00:00:00 2001
From: HITOSHI Osada <qfh02545%nifty.com@localhost>
Date: Mon, 2 Mar 2015 15:01:19 +0900
Subject: [PATCH] add support Nuvoton NCT6776F from OpenBSD

---
 sys/dev/ic/nslm7x.c         | 179 +++++++++++++++++++++++++++++++++++++++++++-
 sys/dev/ic/nslm7xvar.h      |   4 +
 sys/dev/isa/lm_isa_common.c |   2 +
 sys/dev/isa/wbsio.c         |  21 +++++-
 4 files changed, 200 insertions(+), 6 deletions(-)

diff --git a/sys/dev/ic/nslm7x.c b/sys/dev/ic/nslm7x.c
index 51bd4e6..2efb187 100644
--- a/sys/dev/ic/nslm7x.c
+++ b/sys/dev/ic/nslm7x.c
@@ -91,6 +91,7 @@ static void wb_refresh_nvolt(struct lm_softc *, int);
 static void wb_w83627ehf_refresh_nvolt(struct lm_softc *, int);
 static void wb_refresh_temp(struct lm_softc *, int);
 static void wb_refresh_fanrpm(struct lm_softc *, int);
+static void wb_nct6776f_refresh_fanrpm(struct lm_softc *, int);
 static void wb_w83792d_refresh_fanrpm(struct lm_softc *, int);
 
 static void as_refresh_temp(struct lm_softc *, int);
@@ -613,6 +614,154 @@ static struct lm_sensor w83627dhg_sensors[] = {
 	{ .desc = NULL }
 };
 
+/*  NCT6776F */
+static struct lm_sensor nct6776f_sensors[] = {
+	/* Voltage */
+	{
+		.desc = "VCore",
+		.type = ENVSYS_SVOLTS_DC,
+		.bank = 0,
+		.reg = 0x20,
+		.refresh = lm_refresh_volt,
+		.rfact = RFACT_NONE / 2
+	},
+	{
+		.desc = "+12V",
+		.type = ENVSYS_SVOLTS_DC,
+		.bank = 0,
+		.reg = 0x21,
+		.refresh = lm_refresh_volt,
+		.rfact = RFACT(56, 10) / 2
+	},
+	{
+		.desc = "AVCC",
+		.type = ENVSYS_SVOLTS_DC,
+		.bank = 0,
+		.reg = 0x22,
+		.refresh = lm_refresh_volt,
+		.rfact = RFACT(34, 34) / 2
+	},
+	{
+		.desc = "+3.3V",
+		.type = ENVSYS_SVOLTS_DC,
+		.bank = 0,
+		.reg = 0x23,
+		.refresh = lm_refresh_volt,
+		.rfact = RFACT(34, 34) / 2
+	},
+	{
+		.desc = "-12V",
+		.type = ENVSYS_SVOLTS_DC,
+		.bank = 0,
+		.reg = 0x24,
+		.refresh = wb_w83627ehf_refresh_nvolt,
+		.rfact = 0
+	},
+	{
+		.desc = "+5V",
+		.type = ENVSYS_SVOLTS_DC,
+		.bank = 0,
+		.reg = 0x25,
+		.refresh = lm_refresh_volt,
+		.rfact = 16000
+	},
+	{
+		.desc = "VIN3",
+		.type = ENVSYS_SVOLTS_DC,
+		.bank = 0,
+		.reg = 0x26,
+		.refresh = lm_refresh_volt,
+		.rfact = RFACT_NONE
+	},
+	{
+		.desc = "+3.3VSB",
+		.type = ENVSYS_SVOLTS_DC,
+		.bank = 5,
+		.reg = 0x50,
+		.refresh = lm_refresh_volt,
+		.rfact = RFACT(34, 34) / 2
+	},
+	{
+		.desc = "VBAT",
+		.type = ENVSYS_SVOLTS_DC,
+		.bank = 5,
+		.reg = 0x51,
+		.refresh = lm_refresh_volt,
+		.rfact = RFACT(34, 34) / 2
+	},
+
+	/* Temperature */
+	{
+		.desc = "MB Temperature",
+		.type = ENVSYS_STEMP,
+		.bank = 0,
+		.reg = 0x27,
+		.refresh = lm_refresh_temp,
+		.rfact = 0
+	},
+	{
+		.desc = "CPU Temperature",
+		.type = ENVSYS_STEMP,
+		.bank = 1,
+		.reg = 0x50,
+		.refresh = wb_refresh_temp,
+		.rfact = 0
+	},
+	{
+		.desc = "Aux Temp",
+		.type = ENVSYS_STEMP,
+		.bank = 2,
+		.reg = 0x50,
+		.refresh = wb_refresh_temp,
+		.rfact = 0
+	},
+
+	/* Fans */
+	{
+		.desc = "System Fan",
+		.type = ENVSYS_SFANRPM,
+		.bank = 6,
+		.reg = 0x56,
+		.refresh = wb_nct6776f_refresh_fanrpm,
+		.rfact = 0
+	},
+	{
+		.desc = "CPU Fan",
+		.type = ENVSYS_SFANRPM,
+		.bank = 6,
+		.reg = 0x58,
+		.refresh = wb_nct6776f_refresh_fanrpm,
+		.rfact = 0
+	},
+	{
+		.desc = "Aux Fan0",
+		.type = ENVSYS_SFANRPM,
+		.bank = 6,
+		.reg = 0x5a,
+		.refresh = wb_nct6776f_refresh_fanrpm,
+		.rfact = 0
+	},
+	{
+		.desc = "Aux Fan1",
+		.type = ENVSYS_SFANRPM,
+		.bank = 6,
+		.reg = 0x5c,
+		.refresh = wb_nct6776f_refresh_fanrpm,
+		.rfact = 0
+	},
+
+	{
+		.desc = "Aux Fan2",
+		.type = ENVSYS_SFANRPM,
+		.bank = 6,
+		.reg = 0x5e,
+		.refresh = wb_nct6776f_refresh_fanrpm,
+		.rfact = 0
+	},
+
+	{ .desc = NULL }
+};
+
 /* W83637HF */
 static struct lm_sensor w83637hf_sensors[] = {
 	/* Voltage */
@@ -1819,6 +1968,7 @@ static int
 wb_match(struct lm_softc *sc)
 {
 	const char *model = NULL;
+	const char *vendor = "Winbond";
 	int banksel, vendid, cf_flags;
 
 	aprint_naive("\n");
@@ -1866,8 +2016,14 @@ wb_match(struct lm_softc *sc)
 		wb_temp_diode_type(sc, cf_flags);
 		break;
 	case WB_CHIPID_W83627DHG:
-		model = "W83627DHG";
-		lm_setup_sensors(sc, w83627dhg_sensors);
+		if (sc->sioid == WBSIO_ID_NCT6776F) {
+			vendor = "Nuvoton";
+			model = "NCT6776F";
+			lm_setup_sensors(sc, nct6776f_sensors);
+		} else {
+			model = "W83627DHG";
+			lm_setup_sensors(sc, w83627dhg_sensors);
+		}
 		wb_temp_diode_type(sc, cf_flags);
 		break;
 	case WB_CHIPID_W83637HF:
@@ -1912,6 +2068,7 @@ wb_match(struct lm_softc *sc)
 		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);
@@ -1929,7 +2086,7 @@ wb_match(struct lm_softc *sc)
 		return 1;
 	}
 
-	aprint_normal_dev(sc->sc_dev, "Winbond %s Hardware monitor\n", model);
+	aprint_normal_dev(sc->sc_dev, "%s %s Hardware monitor\n", vendor, model);
 
 	sc->refresh_sensor_data = wb_refresh_sensor_data;
 	return 1;
@@ -2193,6 +2350,22 @@ wb_refresh_fanrpm(struct lm_softc *sc, int n)
 }
 
 static void
+wb_nct6776f_refresh_fanrpm(struct lm_softc *sc, int n)
+{
+	int datah, datal;
+
+	datah = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
+	datal = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1);
+
+	if ((datah == 0xff) || (datah == 0)) {
+		sc->sensors[n].state = ENVSYS_SINVALID;
+	} else {
+		sc->sensors[n].state = ENVSYS_SVALID;
+		sc->sensors[n].value_cur = (datah << 8) | datal;
+	}
+}
+
+static void
 wb_w83792d_refresh_fanrpm(struct lm_softc *sc, int n)
 {
 	int reg, shift, data, divisor = 1;
diff --git a/sys/dev/ic/nslm7xvar.h b/sys/dev/ic/nslm7xvar.h
index 49d0d65..d1cf4dd 100644
--- a/sys/dev/ic/nslm7xvar.h
+++ b/sys/dev/ic/nslm7xvar.h
@@ -144,6 +144,9 @@
 #define WB_CHIPID_W83627EHF	0xa1
 #define WB_CHIPID_W83627DHG	0xc1
 
+/* wbsio Device IDs */
+#define WBSIO_ID_NCT6776F	0xc3
+
 /* Config bits */
 #define WB_CONFIG_VMR9		0x01
 
@@ -170,6 +173,7 @@ struct lm_softc {
 	struct lm_sensor *lm_sensors;
 	uint8_t	chipid;
 	uint8_t	vrm9;
+	uint8_t sioid;
 };
 
 struct lm_sensor {
diff --git a/sys/dev/isa/lm_isa_common.c b/sys/dev/isa/lm_isa_common.c
index 4078ca9..573b21c 100644
--- a/sys/dev/isa/lm_isa_common.c
+++ b/sys/dev/isa/lm_isa_common.c
@@ -121,6 +121,8 @@ lm_isa_attach(device_t parent, device_t self, void *aux)
 	sc->lmsc.sc_dev = self;
 	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;
 
 	lm_attach(&sc->lmsc);
 }
diff --git a/sys/dev/isa/wbsio.c b/sys/dev/isa/wbsio.c
index 3708fe6..0f78347 100644
--- a/sys/dev/isa/wbsio.c
+++ b/sys/dev/isa/wbsio.c
@@ -53,6 +53,7 @@
 #define WBSIO_ID_W83637HF	0x70
 #define WBSIO_ID_W83667HG	0xa5
 #define WBSIO_ID_W83697HF	0x60
+#define WBSIO_ID_NCT6776F	0xc3
 
 /* Logical Device Number (LDN) Assignments */
 #define WBSIO_LDN_HM		0x0b
@@ -147,6 +148,7 @@ wbsio_probe(device_t parent, cfdata_t match, void *aux)
 	case WBSIO_ID_W83627DHG:
 	case WBSIO_ID_W83637HF:
 	case WBSIO_ID_W83697HF:
+	case WBSIO_ID_NCT6776F:
 		ia->ia_nio = 1;
 		ia->ia_io[0].ir_size = WBSIO_IOSIZE;
 		ia->ia_niomem = 0;
@@ -164,6 +166,7 @@ wbsio_attach(device_t parent, device_t self, void *aux)
 	struct wbsio_softc *sc = device_private(self);
 	struct isa_attach_args *ia = aux;
 	const char *desc = NULL;
+	const char *vendor = "Winbond";
 	uint8_t reg;
 
 	sc->sc_dev = self;
@@ -205,20 +208,23 @@ wbsio_attach(device_t parent, device_t self, void *aux)
 	case WBSIO_ID_W83697HF:
 		desc = "W83697HF";
 		break;
+	case WBSIO_ID_NCT6776F:
+		vendor = "Nuvoton";
+		desc = "NCT6776F";
+		break;
 	}
 
 	/* 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);
+	aprint_normal(": %s LPC Super I/O %s rev 0x%02x\n", vendor, desc, reg);
 
 	/* Escape from configuration mode */
 	wbsio_conf_disable(sc->sc_iot, sc->sc_ioh);
 
 	if (!pmf_device_register(self, NULL, NULL))
 		aprint_error_dev(self, "couldn't establish power handler\n");
-
 	wbsio_rescan(self, "wbsio", NULL);
 }
 
@@ -258,7 +264,7 @@ wbsio_search(device_t parent, cfdata_t cf, const int *slocs, void *aux)
 {
 	struct wbsio_softc *sc = device_private(parent);
 	uint16_t iobase;
-	uint8_t reg0, reg1;
+	uint8_t reg0, reg1, devid;
 
 	/* Enter configuration mode */
 	wbsio_conf_enable(sc->sc_iot, sc->sc_ioh);
@@ -283,6 +289,13 @@ wbsio_search(device_t parent, cfdata_t cf, const int *slocs, void *aux)
 	if (iobase == 0)
 		return -1;
 
+	/* Enter configuration mode */
+	wbsio_conf_enable(sc->sc_iot, sc->sc_ioh);
+	/* Read device ID */
+	devid = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID);
+	/* Escape from configuration mode */
+	wbsio_conf_disable(sc->sc_iot, sc->sc_ioh);
+
 	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 +303,8 @@ wbsio_search(device_t parent, cfdata_t cf, const int *slocs, void *aux)
 	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;
-- 
2.3.2




Home | Main Index | Thread Index | Old Index