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) */