[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[patch] therm_adt746x.c



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 to: