Add fan sensor support, from Thomas E. Spanjaard
This commit is contained in:
parent
e610f24a9a
commit
e38f75f075
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: thinkpad_acpi.c,v 1.15 2008/05/05 00:14:11 jmcneill Exp $ */
|
||||
/* $NetBSD: thinkpad_acpi.c,v 1.16 2008/10/18 16:35:40 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: thinkpad_acpi.c,v 1.15 2008/05/05 00:14:11 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: thinkpad_acpi.c,v 1.16 2008/10/18 16:35:40 jmcneill Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -48,7 +48,9 @@ __KERNEL_RCSID(0, "$NetBSD: thinkpad_acpi.c,v 1.15 2008/05/05 00:14:11 jmcneill
|
|||
#include <machine/pio.h>
|
||||
#endif
|
||||
|
||||
#define THINKPAD_NSENSORS 8
|
||||
#define THINKPAD_NTEMPSENSORS 8
|
||||
#define THINKPAD_NFANSENSORS 1
|
||||
#define THINKPAD_NSENSORS (THINKPAD_NTEMPSENSORS + THINKPAD_NFANSENSORS)
|
||||
|
||||
typedef struct thinkpad_softc {
|
||||
device_t sc_dev;
|
||||
|
@ -112,8 +114,10 @@ static ACPI_STATUS thinkpad_mask_init(thinkpad_softc_t *, uint32_t);
|
|||
static void thinkpad_notify_handler(ACPI_HANDLE, UINT32, void *);
|
||||
static void thinkpad_get_hotkeys(void *);
|
||||
|
||||
static void thinkpad_temp_init(thinkpad_softc_t *);
|
||||
static void thinkpad_sensors_init(thinkpad_softc_t *);
|
||||
static void thinkpad_sensors_refresh(struct sysmon_envsys *, envsys_data_t *);
|
||||
static void thinkpad_temp_refresh(struct sysmon_envsys *, envsys_data_t *);
|
||||
static void thinkpad_fan_refresh(struct sysmon_envsys *, envsys_data_t *);
|
||||
|
||||
static void thinkpad_wireless_toggle(thinkpad_softc_t *);
|
||||
|
||||
|
@ -252,8 +256,8 @@ thinkpad_attach(device_t parent, device_t self, void *opaque)
|
|||
}
|
||||
}
|
||||
|
||||
/* Register temperature sensors with envsys */
|
||||
thinkpad_temp_init(sc);
|
||||
/* Register temperature and fan sensors with envsys */
|
||||
thinkpad_sensors_init(sc);
|
||||
|
||||
fail:
|
||||
if (!pmf_device_register(self, NULL, thinkpad_resume))
|
||||
|
@ -433,16 +437,17 @@ thinkpad_mask_init(thinkpad_softc_t *sc, uint32_t mask)
|
|||
}
|
||||
|
||||
static void
|
||||
thinkpad_temp_init(thinkpad_softc_t *sc)
|
||||
thinkpad_sensors_init(thinkpad_softc_t *sc)
|
||||
{
|
||||
char sname[5] = "TMP?";
|
||||
int i, err;
|
||||
char fname[5] = "FAN?";
|
||||
int i, j, err;
|
||||
|
||||
if (sc->sc_ecdev == NULL)
|
||||
return; /* no chance of this working */
|
||||
|
||||
sc->sc_sme = sysmon_envsys_create();
|
||||
for (i = 0; i < THINKPAD_NSENSORS; i++) {
|
||||
for (i = 0; i < THINKPAD_NTEMPSENSORS; i++) {
|
||||
sname[3] = '0' + i;
|
||||
strcpy(sc->sc_sensor[i].desc, sname);
|
||||
sc->sc_sensor[i].units = ENVSYS_STEMP;
|
||||
|
@ -451,10 +456,20 @@ thinkpad_temp_init(thinkpad_softc_t *sc)
|
|||
aprint_error_dev(sc->sc_dev,
|
||||
"couldn't attach sensor %s\n", sname);
|
||||
}
|
||||
j = i; /* THINKPAD_NTEMPSENSORS */
|
||||
for (; i < (j + THINKPAD_NFANSENSORS); i++) {
|
||||
fname[3] = '0' + (i - j);
|
||||
strcpy(sc->sc_sensor[i].desc, fname);
|
||||
sc->sc_sensor[i].units = ENVSYS_SFANRPM;
|
||||
|
||||
if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor[i]))
|
||||
aprint_error_dev(sc->sc_dev,
|
||||
"couldn't attach sensor %s\n", fname);
|
||||
}
|
||||
|
||||
sc->sc_sme->sme_name = device_xname(sc->sc_dev);
|
||||
sc->sc_sme->sme_cookie = sc;
|
||||
sc->sc_sme->sme_refresh = thinkpad_temp_refresh;
|
||||
sc->sc_sme->sme_refresh = thinkpad_sensors_refresh;
|
||||
|
||||
err = sysmon_envsys_register(sc->sc_sme);
|
||||
if (err) {
|
||||
|
@ -464,6 +479,21 @@ thinkpad_temp_init(thinkpad_softc_t *sc)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
thinkpad_sensors_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
{
|
||||
switch (edata->units) {
|
||||
case ENVSYS_STEMP:
|
||||
thinkpad_temp_refresh(sme, edata);
|
||||
break;
|
||||
case ENVSYS_SFANRPM:
|
||||
thinkpad_fan_refresh(sme, edata);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
thinkpad_temp_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
{
|
||||
|
@ -489,6 +519,42 @@ thinkpad_temp_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
|
|||
edata->state = ENVSYS_SVALID;
|
||||
}
|
||||
|
||||
static void
|
||||
thinkpad_fan_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
{
|
||||
thinkpad_softc_t *sc = sme->sme_cookie;
|
||||
ACPI_INTEGER lo;
|
||||
ACPI_INTEGER hi;
|
||||
ACPI_STATUS rv;
|
||||
int rpm;
|
||||
|
||||
/*
|
||||
* Read the low byte first to avoid a firmware bug.
|
||||
*/
|
||||
rv = acpiec_bus_read(sc->sc_ecdev, 0x84, &lo, 1);
|
||||
if (ACPI_FAILURE(rv)) {
|
||||
edata->state = ENVSYS_SINVALID;
|
||||
return;
|
||||
}
|
||||
rv = acpiec_bus_read(sc->sc_ecdev, 0x85, &hi, 1);
|
||||
if (ACPI_FAILURE(rv)) {
|
||||
edata->state = ENVSYS_SINVALID;
|
||||
return;
|
||||
}
|
||||
rpm = ((((int)hi) << 8) | ((int)lo));
|
||||
if (rpm < 0) {
|
||||
edata->state = ENVSYS_SINVALID;
|
||||
return;
|
||||
}
|
||||
|
||||
edata->value_cur = rpm;
|
||||
if (rpm < edata->value_min || edata->value_min == -1)
|
||||
edata->value_min = rpm;
|
||||
if (rpm > edata->value_max || edata->value_max == -1)
|
||||
edata->value_max = rpm;
|
||||
edata->state = ENVSYS_SVALID;
|
||||
}
|
||||
|
||||
static void
|
||||
thinkpad_wireless_toggle(thinkpad_softc_t *sc)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue