On 31/01/16(Sun) 23:47, Olivier Cherrier wrote: > Hi, > > It may not be the proper solution to control the fans on macppc smu (G5) > but the following patch allows me to work with my iMac G5 without > losing my hearing capacity ... > > > > $ sysctl hw.sensors > hw.sensors.smu0.temp0=44.72 degC (CPU T-Diode) > hw.sensors.smu0.fan0=1530 RPM (System Fan) > hw.sensors.smu0.fan1=1530 RPM (CPU fan) > hw.sensors.smu0.fan2=1530 RPM (Hard Drive) > hw.sensors.smu0.volt0=11.87 VDC (CPU Voltage) > hw.sensors.smu0.current0=0.63 A (CPU Current) > hw.sensors.lmtemp0.temp0=51.00 degC > $ > > The fan range are: > smu0 at mainbus0 > system: min-value: 1000 > system: max-value: 4000 > system: unmanage-value: 4000 > cpu: min-value: 1500 > cpu: max-value: 4400 > cpu: unmanage-value: 4400 > hd: min-value: 1800 > hd: max-value: 6000 > hd: unmanage-value: 6000
Could you test the diff below and tell me if it also helps? It is adapted from a submission from Dominic Marks: https://marc.info/?l=openbsd-ppc&m=142836014007157&w=2 Index: dev/smu.c =================================================================== RCS file: /cvs/src/sys/arch/macppc/dev/smu.c,v retrieving revision 1.27 diff -u -p -r1.27 smu.c --- dev/smu.c 4 Jun 2015 18:01:44 -0000 1.27 +++ dev/smu.c 18 Mar 2016 11:58:23 -0000 @@ -54,6 +54,13 @@ struct smu_sensor { struct ksensor sensor; }; +/* SMU CPU T-Diode sensor. */ +#define SMU_CPU_TEMP 0 + +/* CPU temperature boundaries in muK. */ +#define CPU_TEMP_MAX (80 * 1000000 + 273150000) +#define CPU_TEMP_MIN (30 * 1000000 + 273150000) + struct smu_softc { struct device sc_dev; @@ -145,8 +152,9 @@ int smu_time_write(time_t); int smu_get_datablock(struct smu_softc *sc, u_int8_t, u_int8_t *, size_t); int smu_fan_set_rpm(struct smu_softc *, struct smu_fan *, u_int16_t); int smu_fan_refresh(struct smu_softc *, struct smu_fan *); +int smu_fan_adjust(struct smu_softc *, struct smu_fan *, u_int64_t); int smu_sensor_refresh(struct smu_softc *, struct smu_sensor *); -void smu_refresh_sensors(void *); +void smu_refresh(void *); int smu_i2c_acquire_bus(void *, int); void smu_i2c_release_bus(void *, int); @@ -365,7 +373,7 @@ smu_attach(struct device *parent, struct sc->sc_slots_pow_scale = (data[4] << 8) + data[5]; sc->sc_slots_pow_offset = (data[6] << 8) + data[7]; - sensor_task_register(sc, smu_refresh_sensors, 5); + sensor_task_register(sc, smu_refresh, 5); #endif /* !SMALL_KERNEL */ printf("\n"); @@ -643,9 +651,10 @@ smu_sensor_refresh(struct smu_softc *sc, } void -smu_refresh_sensors(void *arg) +smu_refresh(void *arg) { struct smu_softc *sc = arg; + struct ksensor *ks; int i; rw_enter_write(&sc->sc_lock); @@ -653,6 +662,10 @@ smu_refresh_sensors(void *arg) smu_sensor_refresh(sc, &sc->sc_sensors[i]); for (i = 0; i < sc->sc_num_fans; i++) smu_fan_refresh(sc, &sc->sc_fans[i]); + if (sensor_find(0, SENSOR_TEMP, SMU_CPU_TEMP, &ks) == 0) { + for (i = 0; i < sc->sc_num_fans; i++) + smu_fan_adjust(sc, &sc->sc_fans[i], ks->value); + } rw_exit_write(&sc->sc_lock); } @@ -754,4 +767,22 @@ smu_slew_voltage(u_int freq_scale) smu_do_cmd(sc, 250); rw_exit_write(&sc->sc_lock); +} + +int +smu_fan_adjust(struct smu_softc *sc, struct smu_fan *fan, u_int64_t ctemp) +{ + u_int16_t rpm;; + + if (ctemp < CPU_TEMP_MIN) { + rpm = fan->min_rpm; + } else if (ctemp < CPU_TEMP_MAX) { + rpm = fan->min_rpm + (ctemp - CPU_TEMP_MIN) * + (fan->max_rpm - fan->min_rpm) / + (CPU_TEMP_MAX - CPU_TEMP_MIN); + } else { + rpm = fan->max_rpm; + } + + return smu_fan_set_rpm(sc, fan, rpm); }