Imported envsys 2, a brief description of the new features:
(Part 2: drivers) * Support for detachable sensors. * Cleaned up the API for simplicity and efficiency. * Ability to send capacity/critical/warning events to powerd(8). * Adapted all the code to the new locking order. * Compatibility with the old envsys API: the ENVSYS_GTREINFO and ENVSYS_GTREDATA ioctl(2)s are supported. * Added support for a 'dictionary based communication channel' between sysmon_power(9) and powerd(8), that means there is no 32 bytes event size restriction anymore. * Binary compatibility with old envstat(8) and powerd(8) via COMPAT_40. * All drivers with the n^2 gtredata bug were fixed, PR kern/36226. Tested by: blymn: smsc(4). bouyer: ipmi(4), mfi(4). kefren: ug(4). njoly: viaenv(4), adt7463.c. riz: owtemp(4). xtraeme: acpiacad(4), acpibat(4), acpitz(4), aiboost(4), it(4), lm(4).
This commit is contained in:
parent
752a9d4a34
commit
bb8e671373
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nslm7x.c,v 1.36 2007/05/26 04:19:29 tsutsui Exp $ */
|
||||
/* $NetBSD: nslm7x.c,v 1.37 2007/07/01 08:29:48 xtraeme Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: nslm7x.c,v 1.36 2007/05/26 04:19:29 tsutsui Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nslm7x.c,v 1.37 2007/07/01 08:29:48 xtraeme Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -75,17 +75,6 @@ __KERNEL_RCSID(0, "$NetBSD: nslm7x.c,v 1.36 2007/05/26 04:19:29 tsutsui Exp $");
|
||||
#define RFACT(x, y) (RFACT_NONE * ((x) + (y)) / (y))
|
||||
#define NRFACT(x, y) (-RFACT_NONE * (x) / (y))
|
||||
|
||||
const struct envsys_range lm_ranges[] = { /* sc->sensors sub-intervals */
|
||||
/* for each unit type */
|
||||
{ 7, 7, ENVSYS_STEMP },
|
||||
{ 8, 10, ENVSYS_SFANRPM },
|
||||
{ 1, 0, ENVSYS_SVOLTS_AC }, /* None */
|
||||
{ 0, 6, ENVSYS_SVOLTS_DC },
|
||||
{ 1, 0, ENVSYS_SOHMS }, /* None */
|
||||
{ 1, 0, ENVSYS_SWATTS }, /* None */
|
||||
{ 1, 0, ENVSYS_SAMPS } /* None */
|
||||
};
|
||||
|
||||
static int lm_match(struct lm_softc *);
|
||||
static int wb_match(struct lm_softc *);
|
||||
static int def_match(struct lm_softc *);
|
||||
@ -93,12 +82,12 @@ static int def_match(struct lm_softc *);
|
||||
static void lm_generic_banksel(struct lm_softc *, int);
|
||||
static void lm_setup_sensors(struct lm_softc *, struct lm_sensor *);
|
||||
|
||||
static void lm_refresh_sensor_data(struct lm_softc *);
|
||||
static void lm_refresh_sensor_data(struct lm_softc *, int);
|
||||
static void lm_refresh_volt(struct lm_softc *, int);
|
||||
static void lm_refresh_temp(struct lm_softc *, int);
|
||||
static void lm_refresh_fanrpm(struct lm_softc *, int);
|
||||
|
||||
static void wb_refresh_sensor_data(struct lm_softc *);
|
||||
static void wb_refresh_sensor_data(struct lm_softc *, int);
|
||||
static void wb_w83637hf_refresh_vcore(struct lm_softc *, int);
|
||||
static void wb_refresh_nvolt(struct lm_softc *, int);
|
||||
static void wb_w83627ehf_refresh_nvolt(struct lm_softc *, int);
|
||||
@ -108,12 +97,7 @@ static void wb_w83792d_refresh_fanrpm(struct lm_softc *, int);
|
||||
|
||||
static void as_refresh_temp(struct lm_softc *, int);
|
||||
|
||||
static int lm_gtredata(struct sysmon_envsys *, struct envsys_tre_data *);
|
||||
static int generic_streinfo_fan(struct lm_softc *, struct envsys_basic_info *,
|
||||
int, struct envsys_basic_info *);
|
||||
static int lm_streinfo(struct sysmon_envsys *, struct envsys_basic_info *);
|
||||
static int wb781_streinfo(struct sysmon_envsys *, struct envsys_basic_info *);
|
||||
static int wb782_streinfo(struct sysmon_envsys *, struct envsys_basic_info *);
|
||||
static int lm_gtredata(struct sysmon_envsys *, envsys_data_t *);
|
||||
|
||||
struct lm_chip {
|
||||
int (*chip_match)(struct lm_softc *);
|
||||
@ -522,20 +506,28 @@ static struct lm_sensor w83627dhg_sensors[] = {
|
||||
.rfact = RFACT(56, 10) / 2
|
||||
},
|
||||
{
|
||||
.desc = "+3.3V",
|
||||
.desc = "AVCC",
|
||||
.type = ENVSYS_SVOLTS_DC,
|
||||
.bank = 0,
|
||||
.reg = 0x22,
|
||||
.refresh = lm_refresh_volt,
|
||||
.rfact = RFACT_NONE
|
||||
.rfact = RFACT(34, 34) / 2
|
||||
},
|
||||
{
|
||||
.desc = "AVCC",
|
||||
.desc = "+3.3V",
|
||||
.type = ENVSYS_SVOLTS_DC,
|
||||
.bank = 0,
|
||||
.reg = 0x23,
|
||||
.refresh = lm_refresh_volt,
|
||||
.rfact = RFACT_NONE
|
||||
.rfact = RFACT(34, 34) / 2
|
||||
},
|
||||
{
|
||||
.desc = "VIN1",
|
||||
.type = ENVSYS_SVOLTS_DC,
|
||||
.bank = 0,
|
||||
.reg = 0x24,
|
||||
.refresh = wb_w83627ehf_refresh_nvolt,
|
||||
.rfact = 0
|
||||
},
|
||||
{
|
||||
.desc = "+5V",
|
||||
@ -543,36 +535,23 @@ static struct lm_sensor w83627dhg_sensors[] = {
|
||||
.bank = 0,
|
||||
.reg = 0x25,
|
||||
.refresh = lm_refresh_volt,
|
||||
.rfact = RFACT(32, 56)
|
||||
},
|
||||
/*
|
||||
* I'm not sure about which one is -12V or -5V.
|
||||
*/
|
||||
#if 0
|
||||
{
|
||||
.desc = "-12V",
|
||||
.type = ENVSYS_SVOLTS_DC,
|
||||
.bank = 0,
|
||||
.reg = 0x24,
|
||||
.refresh = wb_refresh_nvolt,
|
||||
.rfact = RFACT(232, 60)
|
||||
.rfact = 16000
|
||||
},
|
||||
{
|
||||
.desc = "-5V",
|
||||
.desc = "VIN3",
|
||||
.type = ENVSYS_SVOLTS_DC,
|
||||
.bank = 0,
|
||||
.reg = 0x26,
|
||||
.refresh = wb_w83627ehf_refresh_nvolt
|
||||
.rfact = 0
|
||||
.refresh = lm_refresh_volt,
|
||||
.rfact = RFACT_NONE / 2
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.desc = "+3.3VSB",
|
||||
.type = ENVSYS_SVOLTS_DC,
|
||||
.bank = 5,
|
||||
.reg = 0x50,
|
||||
.refresh = lm_refresh_volt,
|
||||
.rfact = RFACT_NONE
|
||||
.rfact = RFACT(34, 34) / 2
|
||||
},
|
||||
{
|
||||
.desc = "VBAT",
|
||||
@ -580,12 +559,12 @@ static struct lm_sensor w83627dhg_sensors[] = {
|
||||
.bank = 5,
|
||||
.reg = 0x51,
|
||||
.refresh = lm_refresh_volt,
|
||||
.rfact = RFACT_NONE
|
||||
.rfact = RFACT_NONE / 2
|
||||
},
|
||||
|
||||
/* Temperature */
|
||||
{
|
||||
.desc = "System Temp",
|
||||
.desc = "MB Temperature",
|
||||
.type = ENVSYS_STEMP,
|
||||
.bank = 0,
|
||||
.reg = 0x27,
|
||||
@ -593,11 +572,11 @@ static struct lm_sensor w83627dhg_sensors[] = {
|
||||
.rfact = 0
|
||||
},
|
||||
{
|
||||
.desc = "CPU Temp",
|
||||
.desc = "CPU Temperature",
|
||||
.type = ENVSYS_STEMP,
|
||||
.bank = 1,
|
||||
.reg = 0x50,
|
||||
.refresh = wb_refresh_temp,
|
||||
.refresh = lm_refresh_temp,
|
||||
.rfact = 0
|
||||
},
|
||||
{
|
||||
@ -605,7 +584,7 @@ static struct lm_sensor w83627dhg_sensors[] = {
|
||||
.type = ENVSYS_STEMP,
|
||||
.bank = 2,
|
||||
.reg = 0x50,
|
||||
.refresh = wb_refresh_temp,
|
||||
.refresh = lm_refresh_temp,
|
||||
.rfact = 0
|
||||
},
|
||||
|
||||
@ -1663,7 +1642,7 @@ lm_probe(bus_space_tag_t iot, bus_space_handle_t ioh)
|
||||
bus_space_write_1(iot, ioh, LMC_ADDR, LMD_CONFIG);
|
||||
|
||||
/* Perform LM78 reset */
|
||||
bus_space_write_1(iot, ioh, LMC_DATA, 0x80);
|
||||
//bus_space_write_1(iot, ioh, LMC_DATA, 0x80);
|
||||
|
||||
/* XXX - Why do I have to reselect the register? */
|
||||
bus_space_write_1(iot, ioh, LMC_ADDR, LMD_CONFIG);
|
||||
@ -1675,7 +1654,7 @@ lm_probe(bus_space_tag_t iot, bus_space_handle_t ioh)
|
||||
else
|
||||
rv = 0;
|
||||
|
||||
DPRINTF(("lm: rv = %d, cr = %x\n", rv, cr));
|
||||
DPRINTF(("%s: rv = %d, cr = %x\n", __func__, rv, cr));
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -1701,24 +1680,19 @@ lm_attach(struct lm_softc *lmsc)
|
||||
|
||||
/* Initialize sensors */
|
||||
for (i = 0; i < lmsc->numsensors; ++i) {
|
||||
lmsc->sensors[i].sensor = lmsc->info[i].sensor = i;
|
||||
lmsc->sensors[i].validflags = (ENVSYS_FVALID|ENVSYS_FCURVALID);
|
||||
lmsc->info[i].validflags = ENVSYS_FVALID;
|
||||
lmsc->sensors[i].warnflags = ENVSYS_WARN_OK;
|
||||
lmsc->sensors[i].sensor = i;
|
||||
lmsc->sensors[i].state = ENVSYS_SVALID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hook into the System Monitor.
|
||||
*/
|
||||
lmsc->sc_sysmon.sme_ranges = lm_ranges;
|
||||
lmsc->sc_sysmon.sme_sensor_info = lmsc->info;
|
||||
lmsc->sc_sysmon.sme_sensor_data = lmsc->sensors;
|
||||
lmsc->sc_sysmon.sme_cookie = lmsc;
|
||||
|
||||
lmsc->sc_sysmon.sme_name = lmsc->sc_dev.dv_xname;
|
||||
lmsc->sc_sysmon.sme_gtredata = lm_gtredata;
|
||||
/* sme_streinfo set in chip-specific attach */
|
||||
|
||||
lmsc->sc_sysmon.sme_nsensors = lmsc->numsensors;
|
||||
lmsc->sc_sysmon.sme_envsys_version = 1000;
|
||||
|
||||
if (sysmon_envsys_register(&lmsc->sc_sysmon))
|
||||
aprint_error("%s: unable to register with sysmon\n",
|
||||
@ -1750,10 +1724,11 @@ lm_match(struct lm_softc *sc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
aprint_normal(": National Semiconductor %s Hardware monitor\n", model);
|
||||
aprint_normal("\n");
|
||||
aprint_normal("%s: National Semiconductor %s Hardware monitor\n",
|
||||
sc->sc_dev.dv_xname, model);
|
||||
|
||||
lm_setup_sensors(sc, lm78_sensors);
|
||||
sc->sc_sysmon.sme_streinfo = lm_streinfo;
|
||||
sc->refresh_sensor_data = lm_refresh_sensor_data;
|
||||
return 1;
|
||||
}
|
||||
@ -1764,10 +1739,11 @@ def_match(struct lm_softc *sc)
|
||||
int chipid;
|
||||
|
||||
chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK;
|
||||
aprint_error(": Unknown chip (ID %d)\n", chipid);
|
||||
aprint_normal("\n");
|
||||
aprint_error("%s: Unknown chip (ID %d)\n", sc->sc_dev.dv_xname,
|
||||
chipid);
|
||||
|
||||
lm_setup_sensors(sc, lm78_sensors);
|
||||
sc->sc_sysmon.sme_streinfo = lm_streinfo;
|
||||
sc->refresh_sensor_data = lm_refresh_sensor_data;
|
||||
return 1;
|
||||
}
|
||||
@ -1775,11 +1751,10 @@ def_match(struct lm_softc *sc)
|
||||
static int
|
||||
wb_match(struct lm_softc *sc)
|
||||
{
|
||||
const char *model;
|
||||
const char *model = NULL;
|
||||
int banksel, vendid, devid;
|
||||
|
||||
model = NULL;
|
||||
|
||||
aprint_normal("\n");
|
||||
/* Read vendor ID */
|
||||
banksel = (*sc->lm_readreg)(sc, WB_BANKSEL);
|
||||
lm_generic_banksel(sc, WB_BANKSEL_HBAC);
|
||||
@ -1787,7 +1762,7 @@ wb_match(struct lm_softc *sc)
|
||||
vendid = (*sc->lm_readreg)(sc, WB_VENDID) << 8;
|
||||
lm_generic_banksel(sc, 0);
|
||||
vendid |= (*sc->lm_readreg)(sc, WB_VENDID);
|
||||
DPRINTF(("winbond vend id 0x%x\n", vendid));
|
||||
DPRINTF(("%s: winbond vend id 0x%x\n", __func__, vendid));
|
||||
if (vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS)
|
||||
return 0;
|
||||
|
||||
@ -1796,7 +1771,7 @@ wb_match(struct lm_softc *sc)
|
||||
devid = (*sc->lm_readreg)(sc, LMD_CHIPID);
|
||||
sc->chipid = (*sc->lm_readreg)(sc, WB_BANK0_CHIPID);
|
||||
lm_generic_banksel(sc, banksel);
|
||||
DPRINTF(("winbond chip id 0x%x\n", sc->chipid));
|
||||
DPRINTF(("%s: winbond chip id 0x%x\n", __func__, sc->chipid));
|
||||
|
||||
switch(sc->chipid) {
|
||||
case WB_CHIPID_W83627HF:
|
||||
@ -1831,12 +1806,10 @@ wb_match(struct lm_softc *sc)
|
||||
case WB_CHIPID_W83781D_2:
|
||||
model = "W83781D";
|
||||
lm_setup_sensors(sc, w83781d_sensors);
|
||||
sc->sc_sysmon.sme_streinfo = wb781_streinfo;
|
||||
break;
|
||||
case WB_CHIPID_W83782D:
|
||||
model = "W83782D";
|
||||
lm_setup_sensors(sc, w83782d_sensors);
|
||||
sc->sc_sysmon.sme_streinfo = wb782_streinfo;
|
||||
break;
|
||||
case WB_CHIPID_W83783S:
|
||||
model = "W83783S";
|
||||
@ -1863,17 +1836,17 @@ wb_match(struct lm_softc *sc)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
aprint_normal(": unknown Winbond chip (ID 0x%x)\n",
|
||||
sc->chipid);
|
||||
aprint_normal("%s: unknown Winbond chip (ID 0x%x)\n",
|
||||
sc->sc_dev.dv_xname, sc->chipid);
|
||||
/* Handle as a standard LM78. */
|
||||
lm_setup_sensors(sc, lm78_sensors);
|
||||
sc->refresh_sensor_data = lm_refresh_sensor_data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
aprint_normal(": Winbond %s Hardware monitor\n", model);
|
||||
aprint_normal("%s: Winbond %s Hardware monitor\n",
|
||||
sc->sc_dev.dv_xname, model);
|
||||
|
||||
sc->sc_sysmon.sme_streinfo = lm_streinfo;
|
||||
sc->refresh_sensor_data = wb_refresh_sensor_data;
|
||||
return 1;
|
||||
}
|
||||
@ -1884,22 +1857,19 @@ lm_setup_sensors(struct lm_softc *sc, struct lm_sensor *sensors)
|
||||
int i;
|
||||
|
||||
for (i = 0; sensors[i].desc; i++) {
|
||||
sc->sensors[i].units = sc->info[i].units = sensors[i].type;
|
||||
strlcpy(sc->info[i].desc, sensors[i].desc,
|
||||
sizeof(sc->info[i].desc));
|
||||
sc->sensors[i].units = sensors[i].type;
|
||||
strlcpy(sc->sensors[i].desc, sensors[i].desc,
|
||||
sizeof(sc->sensors[i].desc));
|
||||
sc->numsensors++;
|
||||
}
|
||||
sc->lm_sensors = sensors;
|
||||
}
|
||||
|
||||
static void
|
||||
lm_refresh_sensor_data(struct lm_softc *sc)
|
||||
lm_refresh_sensor_data(struct lm_softc *sc, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Refresh our stored data for every sensor */
|
||||
for (i = 0; i < sc->numsensors; i++)
|
||||
sc->lm_sensors[i].refresh(sc, i);
|
||||
/* Refresh our stored data for the current sensor */
|
||||
sc->lm_sensors[n].refresh(sc, n);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1908,38 +1878,44 @@ lm_refresh_volt(struct lm_softc *sc, int n)
|
||||
int data;
|
||||
|
||||
data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
|
||||
DPRINTF(("%s: volt[%d] 0x%x\n", __func__, n, data));
|
||||
sc->sensors[n].cur.data_s = (data << 4);
|
||||
sc->sensors[n].cur.data_s *= sc->lm_sensors[n].rfact;
|
||||
sc->sensors[n].cur.data_s /= 10;
|
||||
sc->info[n].rfact = sc->lm_sensors[n].rfact;
|
||||
}
|
||||
if (data == 0xff)
|
||||
sc->sensors[n].state = ENVSYS_SINVALID;
|
||||
|
||||
#define INVALIDATE_SENSOR(x) \
|
||||
do { \
|
||||
sc->sensors[(x)].validflags &= ~ENVSYS_FCURVALID; \
|
||||
sc->sensors[(x)].cur.data_us = 0; \
|
||||
} while (/* CONSTCOND */ 0)
|
||||
sc->sensors[n].flags = ENVSYS_FCHANGERFACT;
|
||||
sc->sensors[n].value_cur = (data << 4);
|
||||
|
||||
if (sc->sensors[n].rfact) {
|
||||
sc->sensors[n].value_cur *= sc->sensors[n].rfact;
|
||||
sc->sensors[n].value_cur /= 10;
|
||||
} else {
|
||||
sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact;
|
||||
sc->sensors[n].value_cur /= 10;
|
||||
sc->sensors[n].rfact = sc->lm_sensors[n].rfact;
|
||||
}
|
||||
DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
|
||||
__func__, n, data, sc->sensors[n].value_cur));
|
||||
}
|
||||
|
||||
static void
|
||||
lm_refresh_temp(struct lm_softc *sc, int n)
|
||||
{
|
||||
int sdata;
|
||||
int data;
|
||||
|
||||
/*
|
||||
* The data sheet suggests that the range of the temperature
|
||||
* sensor is between -55 degC and +125 degC.
|
||||
*/
|
||||
sdata = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
|
||||
DPRINTF(("%s: temp[%d] 0x%x\n", __func__, n, sdata));
|
||||
if (sdata > 0x7d && sdata < 0xc9) {
|
||||
INVALIDATE_SENSOR(n);
|
||||
} else {
|
||||
if (sdata & 0x80)
|
||||
sdata -= 0x100;
|
||||
sc->sensors[n].validflags |= (ENVSYS_FVALID|ENVSYS_FCURVALID);
|
||||
sc->sensors[n].cur.data_us = sdata * 1000000 + 273150000;
|
||||
data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
|
||||
if (data > 0x7d && data < 0xc9)
|
||||
sc->sensors[n].state = ENVSYS_SINVALID;
|
||||
else {
|
||||
if (data & 0x80)
|
||||
data -= 0x100;
|
||||
sc->sensors[n].state = ENVSYS_SVALID;
|
||||
sc->sensors[n].value_cur = data * 1000000 + 273150000;
|
||||
}
|
||||
DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n",
|
||||
__func__, n, data, sc->sensors[n].value_cur));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1964,17 +1940,18 @@ lm_refresh_fanrpm(struct lm_softc *sc, int n)
|
||||
}
|
||||
|
||||
data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
|
||||
DPRINTF(("%s: fan[%d] 0x%x\n", __func__, n, data));
|
||||
if (data == 0xff || data == 0x00) {
|
||||
INVALIDATE_SENSOR(n);
|
||||
} else {
|
||||
sc->sensors[n].validflags |= (ENVSYS_FVALID|ENVSYS_FCURVALID);
|
||||
sc->sensors[n].cur.data_us = 1350000 / (data << divisor);
|
||||
if (data == 0xff || data == 0x00)
|
||||
sc->sensors[n].state = ENVSYS_SINVALID;
|
||||
else {
|
||||
sc->sensors[n].state = ENVSYS_SVALID;
|
||||
sc->sensors[n].value_cur = 1350000 / (data << divisor);
|
||||
}
|
||||
DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n",
|
||||
__func__, n, data, sc->sensors[n].value_cur));
|
||||
}
|
||||
|
||||
static void
|
||||
wb_refresh_sensor_data(struct lm_softc *sc)
|
||||
wb_refresh_sensor_data(struct lm_softc *sc, int n)
|
||||
{
|
||||
int banksel, bank, i;
|
||||
|
||||
@ -1999,7 +1976,6 @@ wb_w83637hf_refresh_vcore(struct lm_softc *sc, int n)
|
||||
int data;
|
||||
|
||||
data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
|
||||
DPRINTF(("%s: volt[%d] 0x%x\n", __func__, n, data));
|
||||
/*
|
||||
* Depending on the voltage detection method,
|
||||
* one of the following formulas is used:
|
||||
@ -2007,9 +1983,11 @@ wb_w83637hf_refresh_vcore(struct lm_softc *sc, int n)
|
||||
* VRM9 method: value = raw * 0.00488V + 0.70V
|
||||
*/
|
||||
if (sc->vrm9)
|
||||
sc->sensors[n].cur.data_s = (data * 4880) + 700000;
|
||||
sc->sensors[n].value_cur = (data * 4880) + 700000;
|
||||
else
|
||||
sc->sensors[n].cur.data_s = (data * 16000);
|
||||
sc->sensors[n].value_cur = (data * 16000);
|
||||
DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
|
||||
__func__, n, data, sc->sensors[n].value_cur));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2018,11 +1996,17 @@ wb_refresh_nvolt(struct lm_softc *sc, int n)
|
||||
int data;
|
||||
|
||||
data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
|
||||
DPRINTF(("%s: volt[%d] 0x%x\n", __func__, n , data));
|
||||
sc->sensors[n].cur.data_s = ((data << 4) - WB_VREF);
|
||||
sc->sensors[n].cur.data_s *= sc->lm_sensors[n].rfact;
|
||||
sc->sensors[n].cur.data_s /= 10;
|
||||
sc->sensors[n].cur.data_s += WB_VREF * 1000;
|
||||
sc->sensors[n].flags = ENVSYS_FCHANGERFACT;
|
||||
sc->sensors[n].value_cur = ((data << 4) - WB_VREF);
|
||||
if (sc->sensors[n].rfact)
|
||||
sc->sensors[n].value_cur *= sc->sensors[n].rfact;
|
||||
else
|
||||
sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact;
|
||||
|
||||
sc->sensors[n].value_cur /= 10;
|
||||
sc->sensors[n].value_cur += WB_VREF * 1000;
|
||||
DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
|
||||
__func__, n , data, sc->sensors[n].value_cur));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2031,17 +2015,23 @@ wb_w83627ehf_refresh_nvolt(struct lm_softc *sc, int n)
|
||||
int data;
|
||||
|
||||
data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
|
||||
DPRINTF(("%s: volt[%d] 0x%x\n", __func__, n , data));
|
||||
sc->sensors[n].cur.data_s = ((data << 3) - WB_W83627EHF_VREF);
|
||||
sc->sensors[n].cur.data_s *= RFACT(232, 10);
|
||||
sc->sensors[n].cur.data_s /= 10;
|
||||
sc->sensors[n].cur.data_s += WB_W83627EHF_VREF * 1000;
|
||||
sc->sensors[n].value_cur = ((data << 3) - WB_W83627EHF_VREF);
|
||||
sc->sensors[n].flags = ENVSYS_FCHANGERFACT;
|
||||
if (sc->sensors[n].rfact)
|
||||
sc->sensors[n].value_cur *= sc->sensors[n].rfact;
|
||||
else
|
||||
sc->sensors[n].value_cur *= RFACT(232, 10);
|
||||
|
||||
sc->sensors[n].value_cur /= 10;
|
||||
sc->sensors[n].value_cur += WB_W83627EHF_VREF * 1000;
|
||||
DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
|
||||
__func__, n , data, sc->sensors[n].value_cur));
|
||||
}
|
||||
|
||||
static void
|
||||
wb_refresh_temp(struct lm_softc *sc, int n)
|
||||
{
|
||||
int sdata;
|
||||
int data;
|
||||
|
||||
/*
|
||||
* The data sheet suggests that the range of the temperature
|
||||
@ -2050,17 +2040,18 @@ wb_refresh_temp(struct lm_softc *sc, int n)
|
||||
* Since such values are unreasonably low, we use -45 degC for
|
||||
* the lower limit instead.
|
||||
*/
|
||||
sdata = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1;
|
||||
sdata += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7;
|
||||
DPRINTF(("%s: temp[%d] 0x%x\n", __func__, n , sdata));
|
||||
if (sdata > 0x0fa && sdata < 0x1a6) {
|
||||
INVALIDATE_SENSOR(n);
|
||||
data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1;
|
||||
data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7;
|
||||
if (data > 0xfffffff || (data > 0x0fa && data < 0x1a6)) {
|
||||
sc->sensors[n].state = ENVSYS_SINVALID;
|
||||
} else {
|
||||
if (sdata & 0x100)
|
||||
sdata -= 0x200;
|
||||
sc->sensors[n].validflags |= (ENVSYS_FVALID|ENVSYS_FCURVALID);
|
||||
sc->sensors[n].cur.data_us = sdata * 500000 + 273150000;
|
||||
if (data & 0x100)
|
||||
data -= 0x200;
|
||||
sc->sensors[n].state = ENVSYS_SVALID;
|
||||
sc->sensors[n].value_cur = data * 500000 + 273150000;
|
||||
}
|
||||
DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n",
|
||||
__func__, n , data, sc->sensors[n].value_cur));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2102,13 +2093,14 @@ wb_refresh_fanrpm(struct lm_softc *sc, int n)
|
||||
}
|
||||
|
||||
data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
|
||||
DPRINTF(("%s: fan[%d] 0x%x\n", __func__, n , data));
|
||||
if (data == 0xff || data == 0x00) {
|
||||
INVALIDATE_SENSOR(n);
|
||||
} else {
|
||||
sc->sensors[n].validflags |= (ENVSYS_FVALID|ENVSYS_FCURVALID);
|
||||
sc->sensors[n].cur.data_us = 1350000 / (data << divisor);
|
||||
if (data >= 0xff || data == 0x00)
|
||||
sc->sensors[n].state = ENVSYS_SINVALID;
|
||||
else {
|
||||
sc->sensors[n].state = ENVSYS_SVALID;
|
||||
sc->sensors[n].value_cur = 1350000 / (data << divisor);
|
||||
}
|
||||
DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n",
|
||||
__func__, n , data, sc->sensors[n].value_cur));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2146,43 +2138,43 @@ wb_w83792d_refresh_fanrpm(struct lm_softc *sc, int n)
|
||||
}
|
||||
|
||||
data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
|
||||
DPRINTF(("%s: fan[%d] 0x%x\n", __func__, n , data));
|
||||
if (data == 0xff || data == 0x00) {
|
||||
INVALIDATE_SENSOR(n);
|
||||
} else {
|
||||
if (data == 0xff || data == 0x00)
|
||||
sc->sensors[n].state = ENVSYS_SINVALID;
|
||||
else {
|
||||
if (reg != 0)
|
||||
divisor = ((*sc->lm_readreg)(sc, reg) >> shift) & 0x7;
|
||||
sc->sensors[n].validflags |= (ENVSYS_FVALID|ENVSYS_FCURVALID);
|
||||
sc->sensors[n].cur.data_us = 1350000 / (data << divisor);
|
||||
sc->sensors[n].state = ENVSYS_SVALID;
|
||||
sc->sensors[n].value_cur = 1350000 / (data << divisor);
|
||||
}
|
||||
DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n",
|
||||
__func__, n , data, sc->sensors[n].value_cur));
|
||||
}
|
||||
|
||||
static void
|
||||
as_refresh_temp(struct lm_softc *sc, int n)
|
||||
{
|
||||
int sdata;
|
||||
int data;
|
||||
|
||||
/*
|
||||
* It seems a shorted temperature diode produces an all-ones
|
||||
* bit pattern.
|
||||
*/
|
||||
sdata = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1;
|
||||
sdata += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7;
|
||||
DPRINTF(("%s: temp[%d] 0x%x\n", __func__, n , data));
|
||||
if (sdata == 0x1ff) {
|
||||
INVALIDATE_SENSOR(n);
|
||||
} else {
|
||||
if (sdata & 0x100)
|
||||
sdata -= 0x200;
|
||||
sc->sensors[n].validflags |= (ENVSYS_FVALID|ENVSYS_FCURVALID);
|
||||
sc->sensors[n].cur.data_us = sdata * 500000 + 273150000;
|
||||
data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1;
|
||||
data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7;
|
||||
if (data == 0x1ff)
|
||||
sc->sensors[n].state = ENVSYS_SINVALID;
|
||||
else {
|
||||
if (data & 0x100)
|
||||
data -= 0x200;
|
||||
sc->sensors[n].state = ENVSYS_SVALID;
|
||||
sc->sensors[n].value_cur = data * 500000 + 273150000;
|
||||
}
|
||||
DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n",
|
||||
__func__, n, data, sc->sensors[n].value_cur));
|
||||
}
|
||||
|
||||
#undef INVALIDATE_SENSOR
|
||||
|
||||
static int
|
||||
lm_gtredata(struct sysmon_envsys *sme, envsys_tre_data_t *tred)
|
||||
lm_gtredata(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
{
|
||||
static const struct timeval onepointfive = { 1, 500000 };
|
||||
struct timeval t, utv;
|
||||
@ -2193,204 +2185,8 @@ lm_gtredata(struct sysmon_envsys *sme, envsys_tre_data_t *tred)
|
||||
timeradd(&sc->lastread, &onepointfive, &t);
|
||||
if (timercmp(&utv, &t, >)) {
|
||||
sc->lastread = utv;
|
||||
sc->refresh_sensor_data(sc);
|
||||
sc->refresh_sensor_data(sc, edata->sensor);
|
||||
}
|
||||
|
||||
*tred = sc->sensors[tred->sensor];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
generic_streinfo_fan(struct lm_softc *sc, envsys_basic_info_t *info, int n,
|
||||
envsys_basic_info_t *binfo)
|
||||
{
|
||||
uint8_t sdata;
|
||||
int divisor;
|
||||
|
||||
/* FAN1 and FAN2 can have divisors set, but not FAN3 */
|
||||
if ((sc->info[binfo->sensor].units == ENVSYS_SFANRPM)
|
||||
&& (n < 2)) {
|
||||
if (binfo->rpms == 0) {
|
||||
binfo->validflags = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* write back the nominal FAN speed */
|
||||
info->rpms = binfo->rpms;
|
||||
|
||||
/* 153 is the nominal FAN speed value */
|
||||
divisor = 1350000 / (binfo->rpms * 153);
|
||||
|
||||
/* ...but we need lg(divisor) */
|
||||
if (divisor <= 1)
|
||||
divisor = 0;
|
||||
else if (divisor <= 2)
|
||||
divisor = 1;
|
||||
else if (divisor <= 4)
|
||||
divisor = 2;
|
||||
else
|
||||
divisor = 3;
|
||||
|
||||
/*
|
||||
* FAN1 div is in bits <5:4>, FAN2 div is
|
||||
* in <7:6>
|
||||
*/
|
||||
sdata = (*sc->lm_readreg)(sc, LMD_VIDFAN);
|
||||
if ( n == 0 ) { /* FAN1 */
|
||||
divisor <<= 4;
|
||||
sdata = (sdata & 0xCF) | divisor;
|
||||
} else { /* FAN2 */
|
||||
divisor <<= 6;
|
||||
sdata = (sdata & 0x3F) | divisor;
|
||||
}
|
||||
|
||||
(*sc->lm_writereg)(sc, LMD_VIDFAN, sdata);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
lm_streinfo(struct sysmon_envsys *sme, envsys_basic_info_t *binfo)
|
||||
{
|
||||
struct lm_softc *sc = sme->sme_cookie;
|
||||
|
||||
if (sc->info[binfo->sensor].units == ENVSYS_SVOLTS_DC)
|
||||
sc->info[binfo->sensor].rfact = binfo->rfact;
|
||||
else {
|
||||
if (sc->info[binfo->sensor].units == ENVSYS_SFANRPM) {
|
||||
generic_streinfo_fan(sc, &sc->info[binfo->sensor],
|
||||
binfo->sensor - 8, binfo);
|
||||
}
|
||||
strlcpy(sc->info[binfo->sensor].desc, binfo->desc,
|
||||
sizeof(sc->info[binfo->sensor].desc));
|
||||
binfo->validflags = ENVSYS_FVALID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
wb781_streinfo(struct sysmon_envsys *sme, envsys_basic_info_t *binfo)
|
||||
{
|
||||
struct lm_softc *sc = sme->sme_cookie;
|
||||
int divisor;
|
||||
uint8_t sdata;
|
||||
int i;
|
||||
|
||||
if (sc->info[binfo->sensor].units == ENVSYS_SVOLTS_DC)
|
||||
sc->info[binfo->sensor].rfact = binfo->rfact;
|
||||
else {
|
||||
if (sc->info[binfo->sensor].units == ENVSYS_SFANRPM) {
|
||||
if (binfo->rpms == 0) {
|
||||
binfo->validflags = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* write back the nominal FAN speed */
|
||||
sc->info[binfo->sensor].rpms = binfo->rpms;
|
||||
|
||||
/* 153 is the nominal FAN speed value */
|
||||
divisor = 1350000 / (binfo->rpms * 153);
|
||||
|
||||
/* ...but we need lg(divisor) */
|
||||
for (i = 0; i < 7; i++) {
|
||||
if (divisor <= (1 << i))
|
||||
break;
|
||||
}
|
||||
divisor = i;
|
||||
|
||||
if (binfo->sensor == 10 || binfo->sensor == 11) {
|
||||
/*
|
||||
* FAN1 div is in bits <5:4>, FAN2 div
|
||||
* is in <7:6>
|
||||
*/
|
||||
sdata = (*sc->lm_readreg)(sc, LMD_VIDFAN);
|
||||
if ( binfo->sensor == 10 ) { /* FAN1 */
|
||||
sdata = (sdata & 0xCF) |
|
||||
((divisor & 0x3) << 4);
|
||||
} else { /* FAN2 */
|
||||
sdata = (sdata & 0x3F) |
|
||||
((divisor & 0x3) << 6);
|
||||
}
|
||||
(*sc->lm_writereg)(sc, LMD_VIDFAN, sdata);
|
||||
} else {
|
||||
/* FAN3 is in WB_PIN <7:6> */
|
||||
sdata = (*sc->lm_readreg)(sc, WB_PIN);
|
||||
sdata = (sdata & 0x3F) |
|
||||
((divisor & 0x3) << 6);
|
||||
(*sc->lm_writereg)(sc, WB_PIN, sdata);
|
||||
}
|
||||
}
|
||||
strlcpy(sc->info[binfo->sensor].desc, binfo->desc,
|
||||
sizeof(sc->info[binfo->sensor].desc));
|
||||
binfo->validflags = ENVSYS_FVALID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
wb782_streinfo(struct sysmon_envsys *sme, envsys_basic_info_t *binfo)
|
||||
{
|
||||
struct lm_softc *sc = sme->sme_cookie;
|
||||
int divisor;
|
||||
uint8_t sdata;
|
||||
int i;
|
||||
|
||||
if (sc->info[binfo->sensor].units == ENVSYS_SVOLTS_DC)
|
||||
sc->info[binfo->sensor].rfact = binfo->rfact;
|
||||
else {
|
||||
if (sc->info[binfo->sensor].units == ENVSYS_SFANRPM) {
|
||||
if (binfo->rpms == 0) {
|
||||
binfo->validflags = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* write back the nominal FAN speed */
|
||||
sc->info[binfo->sensor].rpms = binfo->rpms;
|
||||
|
||||
/* 153 is the nominal FAN speed value */
|
||||
divisor = 1350000 / (binfo->rpms * 153);
|
||||
|
||||
/* ...but we need lg(divisor) */
|
||||
for (i = 0; i < 7; i++) {
|
||||
if (divisor <= (1 << i))
|
||||
break;
|
||||
}
|
||||
divisor = i;
|
||||
|
||||
if (binfo->sensor == 12 || binfo->sensor == 13) {
|
||||
/*
|
||||
* FAN1 div is in bits <5:4>, FAN2 div
|
||||
* is in <7:6>
|
||||
*/
|
||||
sdata = (*sc->lm_readreg)(sc, LMD_VIDFAN);
|
||||
if ( binfo->sensor == 12 ) { /* FAN1 */
|
||||
sdata = (sdata & 0xCF) |
|
||||
((divisor & 0x3) << 4);
|
||||
} else { /* FAN2 */
|
||||
sdata = (sdata & 0x3F) |
|
||||
((divisor & 0x3) << 6);
|
||||
}
|
||||
(*sc->lm_writereg)(sc, LMD_VIDFAN, sdata);
|
||||
} else {
|
||||
/* FAN3 is in WB_PIN <7:6> */
|
||||
sdata = (*sc->lm_readreg)(sc, WB_PIN);
|
||||
sdata = (sdata & 0x3F) |
|
||||
((divisor & 0x3) << 6);
|
||||
(*sc->lm_writereg)(sc, WB_PIN, sdata);
|
||||
}
|
||||
/* Bit 2 of divisor is in WB_BANK0_VBAT */
|
||||
lm_generic_banksel(sc, WB_BANKSEL_B0);
|
||||
sdata = (*sc->lm_readreg)(sc, WB_BANK0_VBAT);
|
||||
sdata &= ~(0x20 << (binfo->sensor - 12));
|
||||
sdata |= (divisor & 0x4) << (binfo->sensor - 9);
|
||||
(*sc->lm_writereg)(sc, WB_BANK0_VBAT, sdata);
|
||||
}
|
||||
|
||||
strlcpy(sc->info[binfo->sensor].desc, binfo->desc,
|
||||
sizeof(sc->info[binfo->sensor].desc));
|
||||
binfo->validflags = ENVSYS_FVALID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nslm7xvar.h,v 1.19 2007/03/11 15:03:08 xtraeme Exp $ */
|
||||
/* $NetBSD: nslm7xvar.h,v 1.20 2007/07/01 08:29:48 xtraeme Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
@ -165,12 +165,11 @@ struct lm_softc {
|
||||
int sc_flags;
|
||||
struct timeval lastread; /* only allow reads every 1.5 seconds */
|
||||
|
||||
struct envsys_tre_data sensors[WB_MAX_SENSORS];
|
||||
struct envsys_basic_info info[WB_MAX_SENSORS];
|
||||
envsys_data_t sensors[WB_MAX_SENSORS];
|
||||
struct sysmon_envsys sc_sysmon;
|
||||
uint8_t numsensors;
|
||||
|
||||
void (*refresh_sensor_data)(struct lm_softc *);
|
||||
void (*refresh_sensor_data)(struct lm_softc *, int);
|
||||
|
||||
uint8_t (*lm_readreg)(struct lm_softc *, int);
|
||||
void (*lm_writereg)(struct lm_softc *, int, int);
|
||||
|
161
sys/dev/ic/ug.c
161
sys/dev/ic/ug.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ug.c,v 1.2 2007/05/08 17:17:14 xtraeme Exp $ */
|
||||
/* $NetBSD: ug.c,v 1.3 2007/07/01 08:29:48 xtraeme Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Mihai Chelaru <kefren@netbsd.ro>
|
||||
@ -26,7 +26,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ug.c,v 1.2 2007/05/08 17:17:14 xtraeme Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ug.c,v 1.3 2007/07/01 08:29:48 xtraeme Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -390,102 +390,91 @@ ug_setup_sensors(struct ug_softc *sc)
|
||||
|
||||
/* Setup Temps */
|
||||
for (i = 0; i < UG_VOLT_MIN; i++)
|
||||
sc->sc_data[i].units = sc->sc_info[i].units = ENVSYS_STEMP;
|
||||
sc->sc_data[i].units = ENVSYS_STEMP;
|
||||
|
||||
#define COPYDESCR(x, y) \
|
||||
do { \
|
||||
strlcpy((x), (y), sizeof(x)); \
|
||||
} while (0)
|
||||
|
||||
COPYDESCR(sc->sc_info[0].desc, "CPU Temp");
|
||||
COPYDESCR(sc->sc_info[1].desc, "SYS Temp");
|
||||
COPYDESCR(sc->sc_info[2].desc, "PWN Temp");
|
||||
COPYDESCR(sc->sc_data[0].desc, "CPU Temp");
|
||||
COPYDESCR(sc->sc_data[1].desc, "SYS Temp");
|
||||
COPYDESCR(sc->sc_data[2].desc, "PWN Temp");
|
||||
|
||||
/* Right, Now setup U sensors */
|
||||
|
||||
for (i = UG_VOLT_MIN; i < UG_FAN_MIN; i++) {
|
||||
sc->sc_data[i].units = sc->sc_info[i].units = ENVSYS_SVOLTS_DC;
|
||||
sc->sc_info[i].rfact = UG_RFACT;
|
||||
sc->sc_data[i].units = ENVSYS_SVOLTS_DC;
|
||||
sc->sc_data[i].rfact = UG_RFACT;
|
||||
}
|
||||
|
||||
COPYDESCR(sc->sc_info[3].desc, "HTVdd");
|
||||
COPYDESCR(sc->sc_info[4].desc, "VCore");
|
||||
COPYDESCR(sc->sc_info[5].desc, "DDRVdd");
|
||||
COPYDESCR(sc->sc_info[6].desc, "Vdd3V3");
|
||||
COPYDESCR(sc->sc_info[7].desc, "Vdd5V");
|
||||
COPYDESCR(sc->sc_info[8].desc, "NBVdd");
|
||||
COPYDESCR(sc->sc_info[9].desc, "AGPVdd");
|
||||
COPYDESCR(sc->sc_info[10].desc, "DDRVtt");
|
||||
COPYDESCR(sc->sc_info[11].desc, "Vdd5VSB");
|
||||
COPYDESCR(sc->sc_info[12].desc, "Vdd3VDual");
|
||||
COPYDESCR(sc->sc_info[13].desc, "SBVdd");
|
||||
COPYDESCR(sc->sc_data[3].desc, "HTVdd");
|
||||
COPYDESCR(sc->sc_data[4].desc, "VCore");
|
||||
COPYDESCR(sc->sc_data[5].desc, "DDRVdd");
|
||||
COPYDESCR(sc->sc_data[6].desc, "Vdd3V3");
|
||||
COPYDESCR(sc->sc_data[7].desc, "Vdd5V");
|
||||
COPYDESCR(sc->sc_data[8].desc, "NBVdd");
|
||||
COPYDESCR(sc->sc_data[9].desc, "AGPVdd");
|
||||
COPYDESCR(sc->sc_data[10].desc, "DDRVtt");
|
||||
COPYDESCR(sc->sc_data[11].desc, "Vdd5VSB");
|
||||
COPYDESCR(sc->sc_data[12].desc, "Vdd3VDual");
|
||||
COPYDESCR(sc->sc_data[13].desc, "SBVdd");
|
||||
|
||||
/* Fan sensors */
|
||||
for (i = UG_FAN_MIN; i < UG_NUM_SENSORS; i++)
|
||||
sc->sc_data[i].units = sc->sc_info[i].units = ENVSYS_SFANRPM;
|
||||
sc->sc_data[i].units = ENVSYS_SFANRPM;
|
||||
|
||||
COPYDESCR(sc->sc_info[14].desc, "CPU Fan");
|
||||
COPYDESCR(sc->sc_info[15].desc, "NB Fan");
|
||||
COPYDESCR(sc->sc_info[16].desc, "SYS Fan");
|
||||
COPYDESCR(sc->sc_info[17].desc, "AUX Fan 1");
|
||||
COPYDESCR(sc->sc_info[18].desc, "AUX Fan 2");
|
||||
COPYDESCR(sc->sc_data[14].desc, "CPU Fan");
|
||||
COPYDESCR(sc->sc_data[15].desc, "NB Fan");
|
||||
COPYDESCR(sc->sc_data[16].desc, "SYS Fan");
|
||||
COPYDESCR(sc->sc_data[17].desc, "AUX Fan 1");
|
||||
COPYDESCR(sc->sc_data[18].desc, "AUX Fan 2");
|
||||
}
|
||||
|
||||
int
|
||||
ug_gtredata(struct sysmon_envsys *sme, envsys_tre_data_t *tred)
|
||||
ug_gtredata(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
{
|
||||
struct ug_softc *sc = sme->sme_cookie;
|
||||
envsys_tre_data_t *t = sc->sc_data; /* For easier read */
|
||||
|
||||
/* Sensors return C while we need uK */
|
||||
|
||||
if (tred->sensor < UG_VOLT_MIN - 1) /* CPU and SYS Temps */
|
||||
t[tred->sensor].cur.data_us = ug_read(sc, UG_CPUTEMP +
|
||||
tred->sensor) * 1000000 + 273150000;
|
||||
else if (tred->sensor == 2) /* PWMTEMP */
|
||||
t[tred->sensor].cur.data_us = ug_read(sc, UG_PWMTEMP)
|
||||
if (edata->sensor < UG_VOLT_MIN - 1) /* CPU and SYS Temps */
|
||||
edata[edata->sensor].value_cur = ug_read(sc, UG_CPUTEMP +
|
||||
edata->sensor) * 1000000 + 273150000;
|
||||
else if (edata->sensor == 2) /* PWMTEMP */
|
||||
edata[edata->sensor].value_cur = ug_read(sc, UG_PWMTEMP)
|
||||
* 1000000 + 273150000;
|
||||
|
||||
/* Voltages */
|
||||
|
||||
#define VOLT_SENSOR UG_HTV + tred->sensor - UG_VOLT_MIN
|
||||
#define VOLT_SENSOR UG_HTV + edata->sensor - UG_VOLT_MIN
|
||||
|
||||
else
|
||||
if ((tred->sensor >= UG_VOLT_MIN) && (tred->sensor < UG_FAN_MIN)) {
|
||||
t[tred->sensor].cur.data_s = ug_read(sc, VOLT_SENSOR);
|
||||
if ((edata->sensor >= UG_VOLT_MIN) && (edata->sensor < UG_FAN_MIN)) {
|
||||
edata[edata->sensor].value_cur = ug_read(sc, VOLT_SENSOR);
|
||||
switch(VOLT_SENSOR) {
|
||||
case UG_5V: /* 6V RFact */
|
||||
case UG_5VSB:
|
||||
t[tred->sensor].cur.data_s *= UG_RFACT6;
|
||||
edata[edata->sensor].value_cur *= UG_RFACT6;
|
||||
break;
|
||||
case UG_3V3: /* 4V RFact */
|
||||
case UG_3VDUAL:
|
||||
t[tred->sensor].cur.data_s *= UG_RFACT4;
|
||||
edata[edata->sensor].value_cur *= UG_RFACT4;
|
||||
break;
|
||||
default: /* 3V RFact */
|
||||
t[tred->sensor].cur.data_s *= UG_RFACT3;
|
||||
edata[edata->sensor].value_cur *= UG_RFACT3;
|
||||
}
|
||||
} else
|
||||
|
||||
#undef VOLT_SENSOR
|
||||
|
||||
/* and Fans */
|
||||
if (tred->sensor >= UG_FAN_MIN)
|
||||
t[tred->sensor].cur.data_s = ug_read(sc, UG_CPUFAN +
|
||||
tred->sensor - UG_FAN_MIN) * UG_RFACT_FAN;
|
||||
if (edata->sensor >= UG_FAN_MIN)
|
||||
edata[edata->sensor].value_cur = ug_read(sc, UG_CPUFAN +
|
||||
edata->sensor - UG_FAN_MIN) * UG_RFACT_FAN;
|
||||
else
|
||||
return ENODEV; /* should I scream and panic ? */
|
||||
|
||||
*tred = sc->sc_data[tred->sensor];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ug_streinfo_ni(struct sysmon_envsys *sme, envsys_basic_info_t *binfo)
|
||||
{
|
||||
/* not implemented */
|
||||
binfo->validflags = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -493,18 +482,12 @@ void
|
||||
ug2_attach(struct ug_softc *sc)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
int i, i2;
|
||||
int i;
|
||||
struct ug2_motherboard_info *ai;
|
||||
struct ug2_sensor_info *si;
|
||||
struct envsys_range ug2_ranges[7]; /* XXX: why only 7 ?! */
|
||||
|
||||
aprint_normal(": Abit uGuru 2005 system monitor\n");
|
||||
|
||||
memcpy(ug2_ranges, ug_ranges, 7 * sizeof(struct envsys_range));
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
ug2_ranges[i].low = ug2_ranges[i].high = 0xFF;
|
||||
|
||||
if (ug2_read(sc, UG2_MISC_BANK, UG2_BOARD_ID, 2, buf) != 2) {
|
||||
aprint_error("%s: Cannot detect board ID. Using default\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
@ -528,54 +511,32 @@ ug2_attach(struct ug_softc *sc)
|
||||
sc->mbsens = (void*)ai->sensors;
|
||||
|
||||
for (i = 0, si = ai->sensors; si && si->name; si++, i++) {
|
||||
COPYDESCR(sc->sc_info[i].desc, si->name);
|
||||
sc->sc_data[i].sensor = sc->sc_info[i].sensor = i;
|
||||
sc->sc_data[i].validflags = (ENVSYS_FVALID|ENVSYS_FCURVALID);
|
||||
sc->sc_info[i].validflags = ENVSYS_FVALID;
|
||||
sc->sc_data[i].warnflags = ENVSYS_WARN_OK;
|
||||
sc->sc_info[i].rfact = 1;
|
||||
COPYDESCR(sc->sc_data[i].desc, si->name);
|
||||
sc->sc_data[i].sensor = i;
|
||||
sc->sc_data[i].state = ENVSYS_SVALID;
|
||||
sc->sc_data[i].rfact = 1;
|
||||
switch (si->type) {
|
||||
case UG2_VOLTAGE_SENSOR:
|
||||
sc->sc_data[i].units = sc->sc_info[i].units =
|
||||
ENVSYS_SVOLTS_DC;
|
||||
sc->sc_info[i].rfact = UG_RFACT;
|
||||
ug2_ranges[3].high = i;
|
||||
if (ug2_ranges[3].low == 0xFF)
|
||||
ug2_ranges[3].low = i;
|
||||
sc->sc_data[i].units = ENVSYS_SVOLTS_DC;
|
||||
sc->sc_data[i].rfact = UG_RFACT;
|
||||
break;
|
||||
case UG2_TEMP_SENSOR:
|
||||
sc->sc_data[i].units = sc->sc_info[i].units =
|
||||
ENVSYS_STEMP;
|
||||
ug2_ranges[0].high = i;
|
||||
if (ug2_ranges[0].low == 0xFF)
|
||||
ug2_ranges[0].low = i;
|
||||
sc->sc_data[i].units = ENVSYS_STEMP;
|
||||
break;
|
||||
case UG2_FAN_SENSOR:
|
||||
sc->sc_data[i].units = sc->sc_info[i].units =
|
||||
ENVSYS_SFANRPM;
|
||||
ug2_ranges[1].high = i;
|
||||
if (ug2_ranges[0].low == 0xFF)
|
||||
ug2_ranges[0].low = i;
|
||||
sc->sc_data[i].units = ENVSYS_SFANRPM;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#undef COPYDESCR
|
||||
|
||||
for (i2 = 0; i2 < 7; i2++)
|
||||
if (ug2_ranges[i2].low == 0xFF ||
|
||||
ug2_ranges[i2].high == 0xFF) {
|
||||
ug2_ranges[i2].low = 1;
|
||||
ug2_ranges[i2].high = 0;
|
||||
}
|
||||
|
||||
sc->sc_sysmon.sme_ranges = ug2_ranges;
|
||||
sc->sc_sysmon.sme_sensor_info = sc->sc_info;
|
||||
sc->sc_sysmon.sme_sensor_data = sc->sc_data;
|
||||
sc->sc_sysmon.sme_name = sc->sc_dev.dv_xname;
|
||||
sc->sc_sysmon.sme_cookie = sc;
|
||||
sc->sc_sysmon.sme_gtredata = ug2_gtredata;
|
||||
sc->sc_sysmon.sme_streinfo = ug_streinfo_ni;
|
||||
sc->sc_sysmon.sme_nsensors = i;
|
||||
sc->sc_sysmon.sme_envsys_version = UG_DRV_VERSION;
|
||||
sc->sc_sysmon.sme_flags = 0;
|
||||
|
||||
if (sysmon_envsys_register(&sc->sc_sysmon))
|
||||
aprint_error("%s: unable to register with sysmon\n",
|
||||
@ -583,18 +544,18 @@ ug2_attach(struct ug_softc *sc)
|
||||
}
|
||||
|
||||
int
|
||||
ug2_gtredata(struct sysmon_envsys *sme, envsys_tre_data_t *tred)
|
||||
ug2_gtredata(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
{
|
||||
struct ug_softc *sc = sme->sme_cookie;
|
||||
envsys_tre_data_t *t = sc->sc_data; /* makes code readable */
|
||||
envsys_data_t *t = sc->sc_data; /* makes code readable */
|
||||
struct ug2_sensor_info *si = (struct ug2_sensor_info *)sc->mbsens;
|
||||
int rfact = 1;
|
||||
uint8_t v;
|
||||
|
||||
if (tred->sensor >= sc->sc_sysmon.sme_nsensors)
|
||||
if (edata->sensor >= sc->sc_sysmon.sme_nsensors)
|
||||
return ENODEV; /* ?! */
|
||||
|
||||
si += tred->sensor;
|
||||
si += edata->sensor;
|
||||
|
||||
#define SENSOR_VALUE (v * si->multiplier * rfact / si->divisor + si->offset)
|
||||
|
||||
@ -602,22 +563,22 @@ ug2_gtredata(struct sysmon_envsys *sme, envsys_tre_data_t *tred)
|
||||
si->port, 1, &v) == 1) {
|
||||
switch (si->type) {
|
||||
case UG2_TEMP_SENSOR:
|
||||
t[tred->sensor].cur.data_us = SENSOR_VALUE * 1000000
|
||||
t[edata->sensor].value_cur = SENSOR_VALUE * 1000000
|
||||
+ 273150000;
|
||||
break;
|
||||
case UG2_VOLTAGE_SENSOR:
|
||||
rfact = UG_RFACT;
|
||||
t[tred->sensor].cur.data_us = SENSOR_VALUE;
|
||||
t[edata->sensor].value_cur = SENSOR_VALUE;
|
||||
break;
|
||||
default:
|
||||
t[tred->sensor].cur.data_s = SENSOR_VALUE;
|
||||
t[edata->sensor].value_cur = SENSOR_VALUE;
|
||||
}
|
||||
} else
|
||||
return ENODEV;
|
||||
|
||||
#undef SENSOR_VALUE
|
||||
|
||||
*tred = sc->sc_data[tred->sensor];
|
||||
*edata = sc->sc_data[edata->sensor];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ugvar.h,v 1.1 2007/05/08 16:48:38 xtraeme Exp $ */
|
||||
/* $NetBSD: ugvar.h,v 1.2 2007/07/01 08:29:48 xtraeme Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Mihai Chelaru <kefren@netbsd.ro>
|
||||
@ -28,19 +28,6 @@
|
||||
#ifndef _UGVAR_H_
|
||||
#define _UGVAR_H_
|
||||
|
||||
/*
|
||||
* sc->sensors sub-intervals for each unit type.
|
||||
*/
|
||||
static const struct envsys_range ug_ranges[] = {
|
||||
{ 0, 2, ENVSYS_STEMP },
|
||||
{ 14, 18, ENVSYS_SFANRPM },
|
||||
{ 1, 0, ENVSYS_SVOLTS_AC }, /* None */
|
||||
{ 3, 13, ENVSYS_SVOLTS_DC },
|
||||
{ 1, 0, ENVSYS_SOHMS }, /* None */
|
||||
{ 1, 0, ENVSYS_SWATTS }, /* None */
|
||||
{ 1, 0, ENVSYS_SAMPS } /* None */
|
||||
};
|
||||
|
||||
struct ug_softc {
|
||||
struct device sc_dev;
|
||||
|
||||
@ -48,8 +35,7 @@ struct ug_softc {
|
||||
bus_space_handle_t sc_ioh;
|
||||
|
||||
struct sysmon_envsys sc_sysmon;
|
||||
envsys_tre_data_t sc_data[UG_MAX_SENSORS];
|
||||
envsys_basic_info_t sc_info[UG_MAX_SENSORS];
|
||||
envsys_data_t sc_data[UG_MAX_SENSORS];
|
||||
uint8_t version;
|
||||
void *mbsens;
|
||||
};
|
||||
@ -81,8 +67,7 @@ int ug2_sync(struct ug_softc *);
|
||||
int ug2_read(struct ug_softc *, uint8_t, uint8_t, uint8_t, uint8_t*);
|
||||
|
||||
/* Envsys */
|
||||
int ug_gtredata(struct sysmon_envsys *, envsys_tre_data_t *);
|
||||
int ug_streinfo_ni(struct sysmon_envsys *, envsys_basic_info_t *);
|
||||
int ug2_gtredata(struct sysmon_envsys *, envsys_tre_data_t *);
|
||||
int ug_gtredata(struct sysmon_envsys *, envsys_data_t *);
|
||||
int ug2_gtredata(struct sysmon_envsys *, envsys_data_t *);
|
||||
|
||||
#endif /* _UGVAR_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user