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);
 }

Reply via email to