Hi!

At least on my post-Feb 2005 12" powerbook the therm_adt746x module sometimes
showed a fairly strange behaviour - my fan was steadily spinning up and down
every other second. AFAIK this happens, if either the GPU- or the CPU sensor
show an elevated temperature, but not both of them. 

The attached patch
- IMHO fixes this issue
- tries to do smoother speed-changes by considering the previous speed and
  temperature too
- shows the correct sensor-location in case of a single fan too
- does not use the fan_speed-parameter anymore - it tries to keep the speed
  appropriate for temperature relative to the limit, thus one can change the
  fan-speed/noise by changing the limit. Still, it could easily be changed back
  to the former use of this parameter.

Comments are appreciated,
Michael

PS.: I only modified the update_fans_speed-function, thus the patch, although
made for 2.6.13, should work for 2.6.12.x as well!
--- linux-2.6.13/drivers/macintosh/therm_adt746x.c      2005-08-29 
01:41:01.000000000 +0200
+++ linux-2.6.12-rc6/drivers/macintosh/therm_adt746x.c  2005-08-31 
22:47:20.000000000 +0200
@@ -282,28 +282,40 @@
                int var = th->temps[i] - th->limits[i];
 
                if (var > -1) {
-                       int step = (255 - fan_speed) / 7;
-                       int new_speed = 0;
-
-                       /* hysteresis : change fan speed only if variation is
-                        * more than two degrees */
-                       if (abs(var - th->last_var[fan_number]) < 2)
+                       int step = 255 / 14;
+                       int new_speed = var + th->last_var[i-1] + 2;
+                       
+                       
+                       /* hysteresis : update last_var only if variation is
+                        * more than one */
+                       if (var > 0 && abs(var - th->last_var[fan_number]) < 2) 
{
+                               lastvar = var;
                                continue;
+                       }
+                               
+                               
+                       th->last_var[i-1] = (var + th->last_var[i-1])/2 + 1;
 
-                       started = 1;
-                       new_speed = fan_speed + ((var-1)*step);
-
-                       if (new_speed < fan_speed)
-                               new_speed = fan_speed;
+                       if (i == 2 && fan_number == 0 && lastvar >= var)
+                               continue;
+                       lastvar = var;
+                       
+                       new_speed = ( ( new_speed * step ) + 
th->last_speed[fan_number] ) / 2;
+                       
+                       if (new_speed < 0)
+                               new_speed = 0;
                        if (new_speed > 255)
                                new_speed = 255;
+               
+                       if (new_speed == th->last_speed[fan_number])
+                               continue;
+                       started = 1;
 
                        printk(KERN_DEBUG "adt746x: setting fans speed to %d "
                                         "(limit exceeded by %d on %s) \n",
                                        new_speed, var,
-                                       sensor_location[fan_number+1]);
+                                       sensor_location[i]);
                        write_both_fan_speed(th, new_speed);
-                       th->last_var[fan_number] = var;
                } else if (var < -2) {
                        /* don't stop fan if sensor2 is cold and sensor1 is not
                         * so cold (lastvar >= -1) */

Reply via email to