Module Name: src Committed By: macallan Date: Fri Nov 22 05:16:54 UTC 2019
Modified Files: src/sys/arch/macppc/dev: psoc.c Log Message: report fan speeds disclaimer: this is guesswork obtained from watching temperatures, listening to fan noise and staring at register dumps. Use with caution. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/arch/macppc/dev/psoc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/macppc/dev/psoc.c diff -u src/sys/arch/macppc/dev/psoc.c:1.1 src/sys/arch/macppc/dev/psoc.c:1.2 --- src/sys/arch/macppc/dev/psoc.c:1.1 Fri Nov 1 17:51:56 2019 +++ src/sys/arch/macppc/dev/psoc.c Fri Nov 22 05:16:54 2019 @@ -1,4 +1,4 @@ - /* $NetBSD: psoc.c,v 1.1 2019/11/01 17:51:56 macallan Exp $ */ + /* $NetBSD: psoc.c,v 1.2 2019/11/22 05:16:54 macallan Exp $ */ /*- * Copyright (c) 2018 Michael Lorenz @@ -30,15 +30,19 @@ * fan controller found in 1GHz TiBook * * register values from OF: - * fan1 - 0x20 ( status ), 0x31 ( data) + * fan1 - 0x20 ( status ), 0x31 ( data ) * fan2 - 0x26 ( status ), 0x45 ( data ) - * fan3 - 0x59 + * fan status byte 0: + * 0x5* - fan is running, 0x6* - fan stopped + * byte 1: unknown, 0x80 seems always set, lower bits seem to fluctuate + * byte 2: lower 6 bit seem to indicate speed + * fan speed may be lower 6 bit of byte 2 and lower 6 of byte 1 * temperature sensors start at 6, two bytes each, first appears to be * the temperature in degrees Celsius */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: psoc.c,v 1.1 2019/11/01 17:51:56 macallan Exp $"); +__KERNEL_RCSID(0, "$NetBSD: psoc.c,v 1.2 2019/11/22 05:16:54 macallan Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -71,6 +75,8 @@ static void psoc_attach(device_t, device static void psoc_sensors_refresh(struct sysmon_envsys *, envsys_data_t *); +static void psoc_dump(struct psoc_softc *); + CFATTACH_DECL_NEW(psoc, sizeof(struct psoc_softc), psoc_match, psoc_attach, NULL, NULL); @@ -98,7 +104,7 @@ psoc_attach(device_t parent, device_t se struct i2c_attach_args *ia = aux; char path[256]; envsys_data_t *s; - int error, ih, r; + int error, ih, r, i; sc->sc_dev = self; sc->sc_i2c = ia->ia_tag; @@ -122,19 +128,8 @@ psoc_attach(device_t parent, device_t se sc->sc_sme->sme_refresh = psoc_sensors_refresh; sc->sc_nsensors = 0; - int i, j; - uint8_t data, cmd; - for (i = 0; i < 0x7f; i+= 8) { - printf("%02x:", i); - for (j = 0; j < 8; j++) { - cmd = i + j; - data = 0; - iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, - sc->sc_addr, &cmd, 1, &data, 1, 0); - printf(" %02x", data); - } - printf("\n"); - } + psoc_dump(sc); + for (i = 0; i < 4; i++) { r = i * 2 + 6; s = &sc->sc_sensors[sc->sc_nsensors]; @@ -145,8 +140,8 @@ psoc_attach(device_t parent, device_t se sysmon_envsys_sensor_attach(sc->sc_sme, s); sc->sc_nsensors++; } -#if 0 - for (r = 0x31; r < 0x50; r += 0x14) { + + for (r = 0x20; r < 0x2b; r += 0x06) { s = &sc->sc_sensors[sc->sc_nsensors]; s->state = ENVSYS_SINVALID; s->units = ENVSYS_SFANRPM; @@ -155,7 +150,7 @@ psoc_attach(device_t parent, device_t se sysmon_envsys_sensor_attach(sc->sc_sme, s); sc->sc_nsensors++; } -#endif + sysmon_envsys_register(sc->sc_sme); } @@ -164,8 +159,8 @@ psoc_sensors_refresh(struct sysmon_envsy { struct psoc_softc *sc = sme->sme_cookie; uint8_t cmd = 6; - uint8_t buf[0x28]; - int error = 1, data, i; + uint8_t buf[0x28], *bptr; + int error = 1, data; if ( edata->private < 0x20) { cmd = 0; @@ -183,19 +178,30 @@ psoc_sensors_refresh(struct sysmon_envsy /* Celsius -> microkelvin */ edata->value_cur = ((int)data * 1000000) + 273150000; } +#ifdef PSOC_DEBUG + if (edata->private == 6) + psoc_dump(sc); +#endif } else { - cmd = 0x31; + cmd = 0x20; iic_acquire_bus(sc->sc_i2c, 0); error = iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, - sc->sc_addr, &cmd, 1, buf, 0x28, 0); + sc->sc_addr, &cmd, 1, buf, 12, 0); iic_release_bus(sc->sc_i2c, 0); if (error) return; - if (edata->private > 0) { - data = buf[edata->private - 0x20]; - edata->value_cur = data; - for (i = 0; i < 14; i++) - printf(" %02x", buf[edata->private - 0x31 + i]); - printf("\n"); + if (edata->private >= 0x20) { + bptr = &buf[edata->private - 0x20]; + switch (bptr[0] & 0xf0) { + case 0x50: + data = bptr[edata->private - 0x20]; + edata->value_cur = ((bptr[2] & 0x3f) << 6) | (bptr[1] & 0x3f); + break; + case 0x60: + edata->value_cur = 0; + break; + default: + error = -1; + } } } if (error) { @@ -204,3 +210,21 @@ psoc_sensors_refresh(struct sysmon_envsy edata->state = ENVSYS_SVALID; } } + +static void +psoc_dump(struct psoc_softc *sc) +{ + int i, j; + uint8_t data, cmd; + for (i = 0x20; i < 0x5f; i+= 8) { + printf("%02x:", i); + for (j = 0; j < 8; j++) { + cmd = i + j; + data = 0; + iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, + sc->sc_addr, &cmd, 1, &data, 1, 0); + printf(" %02x", data); + } + printf("\n"); + } +}