Submit #2833 » 0001-wbsio-support-NCT6776F-0xc3-supported-by-lm-4-as-W83.patch
sys/config/X86_64_GENERIC | ||
---|---|---|
device it3 at isa? port 0x228
|
||
device wbsio0 at isa? port 0x2e
|
||
device wbsio1 at isa? port 0x4e
|
||
device lm#3 at wbsio?
|
||
device lm1 at wbsio0
|
||
device lm2 at wbsio1
|
||
# Intel Core and newer CPUs on-die digital thermal sensor support
|
||
device coretemp
|
||
device dimm # DIMM information (location, etc.)
|
sys/dev/powermng/lm/lm78.c | ||
---|---|---|
#include <sys/sensors.h>
|
||
#include "lm78var.h"
|
||
#include "../wbsio/wbsioreg.h"
|
||
#if defined(LMDEBUG)
|
||
#define DPRINTF(x) do { kprintf x; } while (0)
|
||
... | ... | |
void wb_w83627ehf_refresh_nvolt(struct lm_softc *, int);
|
||
void wb_refresh_temp(struct lm_softc *, int);
|
||
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);
|
||
void as_refresh_temp(struct lm_softc *, int);
|
||
... | ... | |
{ NULL }
|
||
};
|
||
struct lm_sensor nct6776f_sensors[] = {
|
||
/* Voltage */
|
||
{ "VCore", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volt, RFACT_NONE / 2},
|
||
{ "+12V", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volt, RFACT(56, 10) / 2 },
|
||
{ "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volt, RFACT(34, 34) / 2 },
|
||
{ "+3.3V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volt, RFACT(34, 34) / 2 },
|
||
{ "-12V", SENSOR_VOLTS_DC, 0, 0x24, wb_w83627ehf_refresh_nvolt },
|
||
{ "", SENSOR_VOLTS_DC, 0, 0x25, lm_refresh_volt, RFACT_NONE / 2 },
|
||
{ "", SENSOR_VOLTS_DC, 0, 0x26, lm_refresh_volt, RFACT_NONE / 2 },
|
||
{ "3.3VSB", SENSOR_VOLTS_DC, 5, 0x50, lm_refresh_volt, RFACT(34, 34) / 2 },
|
||
{ "VBAT", SENSOR_VOLTS_DC, 5, 0x51, lm_refresh_volt, RFACT_NONE / 2 },
|
||
/* Temperature */
|
||
{ "", SENSOR_TEMP, 0, 0x27, lm_refresh_temp },
|
||
{ "", SENSOR_TEMP, 1, 0x50, wb_refresh_temp },
|
||
{ "", SENSOR_TEMP, 2, 0x50, wb_refresh_temp },
|
||
/* Fans */
|
||
{ "", SENSOR_FANRPM, 6, 0x56, wb_nct6776f_refresh_fanrpm },
|
||
{ "", SENSOR_FANRPM, 6, 0x58, wb_nct6776f_refresh_fanrpm },
|
||
{ "", SENSOR_FANRPM, 6, 0x5a, wb_nct6776f_refresh_fanrpm },
|
||
{ "", SENSOR_FANRPM, 6, 0x5c, wb_nct6776f_refresh_fanrpm },
|
||
{ "", SENSOR_FANRPM, 6, 0x5e, wb_nct6776f_refresh_fanrpm },
|
||
{ NULL }
|
||
};
|
||
struct lm_sensor w83637hf_sensors[] = {
|
||
/* Voltage */
|
||
{ "VCore", SENSOR_VOLTS_DC, 0, 0x20, wb_w83637hf_refresh_vcore },
|
||
... | ... | |
lm_setup_sensors(sc, w83627ehf_sensors);
|
||
break;
|
||
case WB_CHIPID_W83627DHG:
|
||
cdesc = "W83627DHG";
|
||
lm_setup_sensors(sc, w83627dhg_sensors);
|
||
if (sc->sioid == WBSIO_ID_NCT6776F) {
|
||
cdesc = "NCT6776F";
|
||
lm_setup_sensors(sc, nct6776f_sensors);
|
||
} else {
|
||
cdesc = "W83627DHG";
|
||
lm_setup_sensors(sc, w83627dhg_sensors);
|
||
}
|
||
break;
|
||
case WB_CHIPID_W83637HF:
|
||
cdesc = "W83637HF";
|
||
... | ... | |
}
|
||
void
|
||
wb_nct6776f_refresh_fanrpm(struct lm_softc *sc, int n)
|
||
{
|
||
struct ksensor *sensor = &sc->sensors[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) {
|
||
sensor->flags |= SENSOR_FINVALID;
|
||
sensor->value = 0;
|
||
} else {
|
||
sensor->flags &= ~SENSOR_FINVALID;
|
||
sensor->value = (datah << 8) | datal;
|
||
}
|
||
}
|
||
void
|
||
as_refresh_temp(struct lm_softc *sc, int n)
|
||
{
|
||
struct ksensor *sensor = &sc->sensors[n];
|
sys/dev/powermng/lm/lm78_isa.c | ||
---|---|---|
#include <sys/sensors.h>
|
||
#include "lm78var.h"
|
||
#include "../wbsio/wbsioreg.h"
|
||
#include "../wbsio/wbsiovar.h"
|
||
/* ISA registers */
|
||
#define LMC_ADDR 0x05
|
||
... | ... | |
static devclass_t lm_devclass;
|
||
DRIVER_MODULE(lm, isa, lm_isa_driver, lm_devclass, NULL, NULL);
|
||
DRIVER_MODULE(lm, wbsio, lm_isa_driver, lm_devclass, NULL, NULL);
|
||
int
|
||
lm_isa_probe(struct device *dev)
|
||
{
|
||
struct lm_isa_softc *sc = device_get_softc(dev);
|
||
struct wbsio_softc *wbsc = NULL;
|
||
struct resource *iores;
|
||
struct devclass *parent_devclass;
|
||
const char *parent_name;
|
||
int iorid = 0;
|
||
bus_space_tag_t iot;
|
||
bus_space_handle_t ioh;
|
||
int banksel, vendid, chipid, addr;
|
||
parent_devclass = device_get_devclass(device_get_parent(dev));
|
||
parent_name = devclass_get_name(parent_devclass);
|
||
if (strcmp("wbsio", parent_name) == 0) {
|
||
wbsc = device_get_softc(device_get_parent(dev));
|
||
sc->sc_lmsc.sioid = wbsc->sc_devid;
|
||
} else {
|
||
sc->sc_lmsc.sioid = 0;
|
||
}
|
||
iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &iorid,
|
||
0ul, ~0ul, 8, RF_ACTIVE);
|
||
if (iores == NULL) {
|
||
... | ... | |
/* Probe for Winbond chips. */
|
||
bus_space_write_1(iot, ioh, LMC_ADDR, WB_BANKSEL);
|
||
banksel = bus_space_read_1(iot, ioh, LMC_DATA);
|
||
bus_space_write_1(iot, ioh, LMC_ADDR, WB_BANKSEL);
|
||
bus_space_write_1(iot, ioh, LMC_DATA, WB_BANKSEL_HBAC);
|
||
bus_space_write_1(iot, ioh, LMC_ADDR, WB_VENDID);
|
||
vendid = bus_space_read_1(iot, ioh, LMC_DATA);
|
||
if (((banksel & 0x80) && vendid == (WB_VENDID_WINBOND >> 8)) ||
|
||
(!(banksel & 0x80) && vendid == (WB_VENDID_WINBOND & 0xff)))
|
||
vendid = bus_space_read_1(iot, ioh, LMC_DATA) << 8;
|
||
bus_space_write_1(iot, ioh, LMC_ADDR, WB_BANKSEL);
|
||
bus_space_write_1(iot, ioh, LMC_DATA, 0);
|
||
bus_space_write_1(iot, ioh, LMC_ADDR, WB_VENDID);
|
||
vendid |= bus_space_read_1(iot, ioh, LMC_DATA);
|
||
bus_space_write_1(iot, ioh, LMC_ADDR, WB_BANKSEL);
|
||
bus_space_write_1(iot, ioh, LMC_DATA, banksel);
|
||
if (vendid == WB_VENDID_WINBOND)
|
||
goto found;
|
||
/* Probe for ITE chips (and don't attach if we find one). */
|
sys/dev/powermng/lm/lm78var.h | ||
---|---|---|
#define WB_CHIPID_W83627EHF_A 0x88 /* early version, only for ASUS MBs */
|
||
#define WB_CHIPID_W83627THF 0x90
|
||
#define WB_CHIPID_W83627EHF 0xa1
|
||
#define WB_CHIPID_W83627DHG 0xc1
|
||
#define WB_CHIPID_W83627DHG 0xc1 /* also used in WBSIO_ID_NCT6776F */
|
||
/* Config bits */
|
||
#define WB_CONFIG_VMR9 0x01
|
||
... | ... | |
u_int8_t sbusaddr;
|
||
u_int8_t chipid;
|
||
u_int8_t sioid;
|
||
u_int8_t vrm9;
|
||
};
|
||
void lm_probe(struct lm_softc *);
|
sys/dev/powermng/wbsio/wbsio.c | ||
---|---|---|
#include <sys/systm.h>
|
||
#include <bus/isa/isavar.h>
|
||
#include <bus/isa/isa_common.h>
|
||
/* 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_W83627DHGP 0xb0
|
||
#define WBSIO_ID_W83627SF 0x59
|
||
#define WBSIO_ID_W83627UHG 0xa2
|
||
#define WBSIO_ID_W83637HF 0x70
|
||
#define WBSIO_ID_W83667HG 0xa5
|
||
#define WBSIO_ID_W83687THF 0x85
|
||
#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] */
|
||
struct wbsio_softc {
|
||
struct device *sc_dev;
|
||
struct resource *sc_iores;
|
||
int sc_iorid;
|
||
bus_space_tag_t sc_iot;
|
||
bus_space_handle_t sc_ioh;
|
||
};
|
||
#include "wbsioreg.h"
|
||
#include "wbsiovar.h"
|
||
static void wbsio_identify(driver_t *, struct device *);
|
||
static int wbsio_probe(struct device *);
|
||
... | ... | |
static int wbsio_detach(struct device *);
|
||
static device_method_t wbsio_methods[] = {
|
||
/* Device interface */
|
||
DEVMETHOD(device_identify, wbsio_identify),
|
||
DEVMETHOD(device_probe, wbsio_probe),
|
||
DEVMETHOD(device_attach, wbsio_attach),
|
||
DEVMETHOD(device_detach, wbsio_detach),
|
||
{ NULL, NULL}
|
||
/* Bus interface */
|
||
DEVMETHOD(bus_add_child, bus_generic_add_child),
|
||
DEVMETHOD(bus_set_resource, bus_generic_set_resource),
|
||
DEVMETHOD(bus_alloc_resource, isa_alloc_resource),
|
||
DEVMETHOD(bus_release_resource, isa_release_resource),
|
||
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
|
||
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
|
||
DEVMETHOD_END
|
||
};
|
||
static driver_t wbsio_driver = {
|
||
... | ... | |
case WBSIO_ID_W83697HF:
|
||
desc = "W83697HF";
|
||
break;
|
||
case WBSIO_ID_NCT6776F:
|
||
desc = "NCT6776F";
|
||
break;
|
||
}
|
||
if (desc == NULL) {
|
||
... | ... | |
struct wbsio_softc *sc = device_get_softc(dev);
|
||
uint8_t reg0, reg1;
|
||
uint16_t iobase;
|
||
struct device *parent = device_get_parent(dev);
|
||
struct device *child;
|
||
struct devclass *c_dc;
|
||
int c_maxunit;
|
||
/* Map ISA I/O space */
|
||
sc->sc_iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->sc_iorid,
|
||
... | ... | |
/* Enter configuration mode */
|
||
wbsio_conf_enable(sc->sc_iot, sc->sc_ioh);
|
||
/* Read device ID */
|
||
sc->sc_devid = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID);
|
||
/* Select HM logical device */
|
||
wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_HM);
|
||
... | ... | |
return 0;
|
||
}
|
||
child = NULL;
|
||
c_dc = devclass_find("lm");
|
||
if (c_dc == NULL) {
|
||
device_printf(dev, "lm devclass not found\n");
|
||
return ENXIO;
|
||
}
|
||
c_maxunit = devclass_get_maxunit(c_dc);
|
||
for (int u = 0; u < c_maxunit; u++) {
|
||
child = devclass_get_device(c_dc, u);
|
||
if (child == NULL)
|
||
continue;
|
||
if (isa_get_port(child) == iobase) {
|
||
if (device_is_attached(child)) {
|
||
device_printf(dev,
|
||
"%s is already attached at 0x%x\n",
|
||
device_get_nameunit(child), iobase);
|
||
return 0;
|
||
}
|
||
break;
|
||
}
|
||
if (device_is_attached(child)) {
|
||
child = NULL;
|
||
continue;
|
||
}
|
||
device_printf(dev,
|
||
"found unused %s at 0x%x with state %i, reusing at 0x%x\n",
|
||
device_get_nameunit(child), isa_get_port(child),
|
||
device_get_state(child), iobase);
|
||
break;
|
||
}
|
||
if (child == NULL)
|
||
child = BUS_ADD_CHILD(parent, parent, ISA_ORDER_PNP,
|
||
"lm", -1);
|
||
// child = BUS_ADD_CHILD(parent, parent, ISA_ORDER_PNP,
|
||
// "lm", 3 + device_get_unit(dev));
|
||
child = BUS_ADD_CHILD(dev, dev, 0, "lm", -1);
|
||
if (child == NULL) {
|
||
device_printf(dev, "cannot add child\n");
|
||
return ENXIO;
|
sys/dev/powermng/wbsio/wbsioreg.h | ||
---|---|---|
/* $OpenBSD: wbsioreg.h,v 1.3 2012/07/01 02:15:09 lteo Exp $ */
|
||
/*
|
||
* Copyright (c) 2008 Mark Kettenis <kettenis@openbsd.org>
|
||
*
|
||
* Permission to use, copy, modify, and distribute this software for any
|
||
* purpose with or without fee is hereby granted, provided that the above
|
||
* copyright notice and this permission notice appear in all copies.
|
||
*
|
||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||
*/
|
||
/*
|
||
* Winbond LPC Super I/O driver registers
|
||
*/
|
||
/* 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_W83627DHGP 0xb0
|
||
#define WBSIO_ID_W83627UHG 0xa2
|
||
#define WBSIO_ID_W83627SF 0x59
|
||
#define WBSIO_ID_W83637HF 0x70
|
||
#define WBSIO_ID_W83667HG 0xa5
|
||
#define WBSIO_ID_W83687THF 0x85
|
||
#define WBSIO_ID_W83697HF 0x60
|
||
#define WBSIO_ID_NCT6776F 0xc3
|
||
/* 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] */
|
sys/dev/powermng/wbsio/wbsiovar.h | ||
---|---|---|
/*
|
||
* Copyright (c) 2015 Imre Vadász <imre@vdsz.com>
|
||
*
|
||
* Permission to use, copy, modify, and distribute this software for any
|
||
* purpose with or without fee is hereby granted, provided that the above
|
||
* copyright notice and this permission notice appear in all copies.
|
||
*
|
||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||
*/
|
||
struct wbsio_softc {
|
||
struct device *sc_dev;
|
||
struct resource *sc_iores;
|
||
int sc_iorid;
|
||
bus_space_tag_t sc_iot;
|
||
bus_space_handle_t sc_ioh;
|
||
int sc_devid;
|
||
};
|