On 26 Oct 2004 at 21h10, Colin Leroy wrote: Hi,
> I'll see if I can adapt this to have proper hysteresis without too > much hassles, and if I can, will put it in. I think I'll send this. It doesn't add any parameter, but makes the fan speed change gradual (from specified fan speed, which is now 64 by default, to 255, by increments of (255-fan_speed) / 7. Hysteresis control is done simply by changing fan speed if the variation since last speed change is greater than two degrees. What do you think? (You may have to apply the patch by hand, it's against latest version). -- Colin http://dudusdl.sf.net/ : a free Puzzle Bubble clone
--- drivers/macintosh/therm_adt746x.c.orig 2004-10-26 22:44:18.342932456 +0200 +++ drivers/macintosh/therm_adt746x.c 2004-10-26 22:51:13.449826616 +0200 @@ -61,8 +61,8 @@ "by N degrees."); MODULE_PARM(fan_speed,"i"); -MODULE_PARM_DESC(fan_speed,"Specify fan speed (0-255) when lim < temp < lim+8 " - "(default 128)"); +MODULE_PARM_DESC(fan_speed,"Specify starting fan speed (0-255) " + "(default 64)"); struct thermostat { struct i2c_client clt; @@ -71,6 +71,7 @@ u8 initial_limits[3]; u8 limits[3]; int last_speed[2]; + int last_var[2]; int overriding[2]; }; @@ -211,10 +212,10 @@ if (th->last_speed[fan] != speed) { if (speed == -1) - printk(KERN_INFO "adt746x: Setting speed to automatic " + printk(KERN_DEBUG "adt746x: Setting speed to automatic " "for %s fan.\n", fan?"GPU":"CPU"); else - printk(KERN_INFO "adt746x: Setting speed to %d " + printk(KERN_DEBUG "adt746x: Setting speed to %d " "for %s fan.\n", speed, fan?"GPU":"CPU"); } else return; @@ -280,30 +281,39 @@ int var = th->temps[i] - th->limits[i]; if (var > 8) { if (th->overriding[fan_number] == 0) - printk(KERN_INFO "adt746x: Limit exceeded by " + printk(KERN_DEBUG "adt746x: Limit exceeded by " "%d, overriding specified fan speed " "for %s.\n", var, fan_number?"GPU":"CPU"); th->overriding[fan_number] = 1; + th->last_var[fan_number] = var; write_fan_speed(th, 255, fan_number); started = 1; - } else if ((!th->overriding[fan_number] || var < 6) && var > 0) { - if (th->overriding[fan_number] == 1) - printk(KERN_INFO "adt746x: Limit exceeded by " - "%d, setting speed to specified " - "for %s.\n", var, - fan_number?"GPU":"CPU"); - + } else if (var > -2) { + int step = (255 - fan_speed) / 7; + int new_speed = 0; + + /* hysteresis : change fan speed only if variation is + * more than two degrees */ + if (var > 6 || abs(var - th->last_var[fan_number]) < 2) + continue; + th->overriding[fan_number] = 0; - write_fan_speed(th, fan_speed, fan_number); started = 1; - } else if (var < -1) { + new_speed = fan_speed + ((var-1)*step); + printk(KERN_DEBUG "adt746x: setting %s fan speed to %d " + "(limit exceeded by %d) \n", + fan_number?"GPU":"CPU", + new_speed, var); + write_fan_speed(th, new_speed, fan_number); + th->last_var[fan_number] = var; + } else { /* don't stop iBook fan if GPU is cold and CPU is not * so cold (lastvar >= -1) */ if (therm_type == ADT7460 || lastvar < -1 || i == 1) { if (th->last_speed[fan_number] != 0) - printk(KERN_INFO "adt746x: Stopping %s " + printk(KERN_DEBUG "adt746x: Stopping %s " "fan.\n", fan_number?"GPU":"CPU"); write_fan_speed(th, 0, fan_number); @@ -391,7 +401,7 @@ /* force manual control to start the fan quieter */ if (fan_speed == -1) - fan_speed=128; + fan_speed=64; if(therm_type == ADT7460) { printk(KERN_INFO "adt746x: ADT7460 initializing\n"); @@ -424,7 +434,9 @@ /* be sure to really write fan speed the first time */ th->last_speed[0] = -2; th->last_speed[1] = -2; - + th->last_var[0] = -80; + th->last_var[1] = -80; + if (fan_speed != -1) { /* manual mode, stop fans */ write_both_fan_speed(th, 0);