"Quiet PC", a software fan control solution


1. Disclaimer of liabilities

   This program    implements  functionality  that intervenes    in  hardware
   operation  at  a low level and   may  directly lead   to physical hardware
   malfunction or abnormal operation of operating system.

   No warranties of any kind are made. In no event shall the author be liable
   for any damage resulting from use or misuse of this product, either direct
   or consequential.


2. Overview

   Most of contemporary PCs operate with some kind of air cooling for CPU and
   mainboard, and  facilities are often provided to  adjust the  operation of
   cooling fan(s) in  these systems -   either by a built-in control  circuit
   (hardware control) or by monitoring certain mainboard components (software
   control).   A carefully fine-tuned fan control  has the benefit of reduced
   noise and  vibration level.  This package  implements the software control
   functionality for supported hardware. 

   The following hardware is currently supported and tested (known mainboards
   with a confirmed fan control operation are listed to the right): 

     * ITE IT8712F            ASUSTeK A7V880
     * Winbond W83697         EPOX 8KHA+; Shuttle AK31 series

   Before emerging as a  separate  package, this program  was  a part of  VIA
   power management  tools for OS/2.  It has been reworked a bit for  chipset
   and platform neutrality.


3. Installation

3.1 OS/2

   OS/2 v 2.0 or   later is required.  Install  the driver in  CONFIG.SYS  as
   follows: 

   DEVICE=x:\xxxx\QUIETPC.SYS 

   Do not proceed with hooking the control program into CONFIG.SYS unless you
   have finished setting up the fan control as described below. 

   The  driver  has no  command  line  and no output.    After the system has
   finished  booting, you  can check  if  the installation was successful  by
   running "QCTRL /Q". See below for interpreting the output of "QCTRL /Q". 

3.2 Linux v 2.6

   Compile the module, run "make install" from  a root account. When you have
   finished setting up  fan control parameters, place a  call to "qctrl" into
   your init script.


4. Configuration

4.1 General considerations

   This section lays out a step-by-step procedure for setting up the software
   fan control mode. It should be noted software control is to be avoided for
   systems running in  unattended mode, as  it will be rendered inoperable if
   any ill-behaved driver freezes the system. 

   Fans are  controlled   by changing their rotation  speed    in response to
   variations of  CPU/mainboard/ambient temperature; generally, the lower are
   the temperatures, the slower are the fans  allowed to run. The temperature
   readings are  readily  available from  sensors  in degrees Centigrade;  in
   contrast, there is no direct means to ask  the fan for a specific rotation
   speed (RPM), and the fans are controlled in terms of  "duty cycle" (with 0
   corresponding to  0 RPM, and a  chipset-specific upper boundary, e.g.  127
   or 255, corresponding to a fan-specific  maximum rotation speed, e.g. 5500
   or 7000 RPM).

   Notes:

   1. Always  keep  an eye  on CPU temperature  when  experimenting  with fan
      speeds! Low airflow volume may  result in malfunction of your CPU! This
      program  is not  suitable for  unattended  control of  fan speeds, even
      though it was used for this task for years on developer's machine.

      If the  CPU fan stops unexpectedly  and you feel  unable to get it back
      running using this  software, be sure reboot the  machine ASAP. This is
      an emergency condition  that should never  be ignored!  Upon reset, the
      internal circuitry  will restart the fans at   their full speed, taking
      away the danger of overheating.  After rebooting,  you can proceed with
      correcting your configuration.

      Using  debug  kernel  with software   fan control is   not recommended.
      Synchronous execution in debug  mode  may compromise the  operation  of
      control algorithm and result in  overheating. Be aware that the current
      version does not check for debug kernel during boot.

      Never rely on  your existing settings when moving  to a different  CPU,
      mainboard or computer case. Disable the software control and repeat the
      configuration procedure, paying attention to temperature readings. 

   2. The  relation  of duty  cycle lenth  to the fan  rotation speed  is not
      linear. It depends both  on the fan  and the  software monitoring chip,
      e.g. the Volcano 6Cu+ fan from ThermalTake Co. will  behave differently
      on mainboards with different hardware monitoring ICs:

         Winbond W83697HF      ITE8712F
         0/255 = 0 RPM         0/127 = 0 RPM
         3/255 = 2000 RPM      2/127 = 0 RPM
        40/255 = 5300 RPM     20/127 = 0 RPM
        60/255 = 6000 RPM     30/127 = 1800 RPM
       100/255 = 6500 RPM     50/127 = 2400 RPM
       127/255 = 6800 RPM     63/127 = 2800 RPM
       255/255 = 7000 RPM    127/127 = 7000 RPM

   3. After dropping the speed to zero (i.e.  stopping  the fan), there  will
      probably  be  a  significant inactivity  range, where  the fan will not
      start. For example, running the following sequence:

      QCTRL /FAN1:DUTY=0
      QCTRL /FAN1:DUTY=7

      may leave the  fan stopped. However, going from  0 to 255 and then to 7
      will leave  it running at low speed.  It is better that rotation speeds
      within this inactivity  range are avoided. Most modern CPUs  are unable
      to cool down to their  allowed range of  temperatures without a running
      fan.

   4. If your fan is plugged into the 4-pin  PC power connector, it cannot be
      controlled by software. The same usually applies to the onboard chipset
      fan, if  any.   Besides, the   internal  wiring of   fan  connectors on
      mainboard   may exclude some of  them  from software control. Attention
      should be  paid to  choosing  the right socket   for CPU  fan (normally
      labeled "FAN1").

   5. The  software fan control may  continue after a  trap with REIPL=OFF if
      the interrupt handler survives. However it should not be counted on.

4.2 Procedure

   Now, for  a quick start, you  can take a look at   the example .CFG files.
   They illustrate some  practical, hand-tuned setups.  You can reuse them as
   the basis for your  own configurations (the files can  be edited  with any
   plain-text editor that allows for a monospace font). 

   The first step is to query the readings with "qctrl /q":

   Hardware monitor: Winbond W83697HF, max. duty cycle: 255, granularity 0.5C
                          #1      #2      #3
   Fans (rpm)           2855       0       0
   Temp.Sensors (C)      27    46.5       -

   Two  of   reported  parameters,  namely the  resolution   (granularity) of
   temperature readings and the range of duty cycles values, are instrumental
   in  sketching the graphical  configuration file - they turn, respectively,
   into minimum step on the X axis and topmost point on the Y axis. 

   Next, one has  to  define which cells of   this table make  up the control
   circuit (the aggregate of sensor and fan attached  to a particular object,
   e.g. the CPU).  In  the previous case  it is fan  #1  and sensor  #2, both
   distinguished by their readings prominently higher than others. Sometimes,
   as illustrated below, there might  be some deceptive and totally unrelated
   readings: 

   Hardware monitor: ITE IT8712, max. duty cycle: 127, granularity 1C
                          #1      #2      #3
   Fans (rpm)           2334       0       0
   Temp.Sensors (C)      49      32      56

   The dilemma of  choosing between #1 and  #3 is resolved after watching the
   progress   of  these values   over   time,  e.g.   upon  completion  of  a
   CPU-intensive task: 

   Temp.Sensors (C)      54      33      56

   It becomes  clear  that  56C is  a phantom  reading  from an  unconnected
   sensor, and that the CPU fan control circuit is made  of fan #1 and sensor
   #1.

   These findings  are used  later   to construct  the /FAN parameter,  which
   assumes the form "/FAN<fan#>:CTRL=<sensor#>,<filename.ext>"; for case 1 it
   reads   "/FAN1:CTRL:2,mycfg.cfg",  and  for  case  2    it  would   become
   "/FAN1:CTRL=1,mycfg.cfg"

   The   rest of  the job is   purely  graphical and involves  some  time for
   experimenting. 

   1. The X axis reflects temperature (with granularity of 0.5C), the Y axis
      carries the  duty cycle  (0 to 255). The tick-marks  may be  in linear,
      logarithmic  or  any  other  scale you find  appropriate. The  distance
      between two adjacent tick-marks serves as  a linear  scale, e.g. in the
      following chart:

      255 +
      120 +
          |          *
      110 +
        0 +---+----+---+----+
             34   35   45  100

      the "*" point denotes 40C and duty cycle of 115.

   2. The chart scale is rather free-form, so you can just  mark the critical
      temperatures  and  duty cycle  values. In fact, the  following  will be
      sufficient:

          As stored in file:                    As parsed by QCTRL:

      255 +            *                   255 +            * * * *
          |                		       |         *        
       11 +      *                  =>	    11 +* * * *           
          |                  		       |                   
        0 +------+-----+-----		     0 +------+-----+------
                40     65    		             40     65    

      The temperatures below the leftmost point use the same duty cycle value
      as the one  in  leftmost point.  The  temperatures above  the rightmost
      point use the same duty cycle value as in the rightmost point. 

      Tip:     Use      the     /SHOWFAN     parameter      together     with
      /FAN<fan#>:CTRL=<sensor#>,<filename.ext>  to learn about the exact duty
      cycle values calculated by QCTRL.

   3. Now, it may turn out  that the  fan does  not run  smoothly  at several
      duty  cycle values (usually noticed  by excessive  vibration or noise),
      while it runs perfectly at some lower or higher values. This is usually
      the case  with 7000 RPM  fans. So it means that in  lower RPM area, the
      chart may be limited to a  set of "reliable" duty cycle values (usually
      found through manual adjustment with QCTRL /FAN<fan#>:DUTY=<x>):

      128 +                            *
       64 +                        *
       32 +                    *
       14 +               *
       11 +       *   *
        3 +   *
        0 +---+---+---+---+----+---+---+
             40  40.5 43  43.5 47  50  60

      It tells to use the lowest possible  duty cycle, 3, for temperatures of
      +40C and below, but  at +40.5C it will  immediately switch from  3 to
      11, and run at that duty cycle up to +43C, switching to the next grade
      at +43.5C.  Note  the 0.5C steps - they  prevent  QCTRL from choosing
      approximate (noisy) values as a result of interpolation between the two
      tick-marks. Then,  beyond duty cycle of 14,  we do not  care any longer
      about duty  cycle values, as  the fan  is expected  to  run smoothly at
      higher speeds. 

   4. Finally, a hysteresis loop  is possible - when the CPU cools  down, its
      fan might be  left  running  at  higher speed  unless some  appreciable
      temperature has been achieved. For hysteresis  loops, there are two new
      markers: "^" (temperature  rise  course)  and  "v" (temperature decline
      course). Example:

          As stored in file:                    As parsed by QCTRL:

      255 +        v v *                   255 +        vvvv* * * *
          |                		       |       v   ^      
       11 +      * ^ ^              =>	    11 +* * * *^^^^       
          |                  		       |                   
        0 +------+-----+-----		     0 +------+-----+------
                40     65    		             40     65

      Normally, the "^" markers  should  lie  below the "v"  markers  at  the
      same temperature. The "*" can be thought of as "v" and "^" combined  in
      one point.

   All customizations can be effected immediately by invoking:
   
   QCTRL.EXE /FAN<fan#>:CTRL=<sensor#>,<filename.ext>
   e.g.
   QCTRL /FAN1:CTRL=2,mycfg.cfg

   The fan can be restored to automatic control by:

   QCTRL /FAN1:RESET
   or
   QCTRL /FAN1:DUTY=255
   (where 255 is the maximum duty cycle as reported by /Q).

   The same option allows   to try out certain duty   cycle values (USE  WITH
   CARE): QCTRL /FAN1:DUTY=50

   When  satisfactory results  have been achieved  and  tried out by  running
   CPU-intensive software, the entry "CALL=<path>\QCTRL.EXE <parameters>" can
   be added to CONFIG.SYS.

   Tip: The closer this entry is to  the beginning of CONFIG.SYS, the earlier
   will software fan control take over during startup. 

4.3 Advanced configuration with "qctrl"

   The "qctrl" utility supports the following command-line parameters:

   /RESET = reinitialize the system monitoring chip and program it with the
   curent configuration. 

   /Q = query the characteristics and current readings of hardware monitoring
   chip. 

   /SHOWFAN  = display additional  data for  fan configuration. Used together
   with /FAN<fan#>:CTRL parameter. 

   /FAN<fan#>[:<settings>] =  query or configure  a specific fan.  This is an
   option specific  to the   Winbond W83697HF hardware  monitoring  solution.
   <fan#>  specifies a fan  socket (the numbering  starts with 1).  There are
   the following possible settings:

               	 RESET  Resets the fan to its 100% duty cycle and cancels any
                        other settings in effect.
     DUTY:<x>[:<y>][l]  Sets fan  duty cycle  to <x> (0 to 255). This cancels
                        the   software  control  mode  (CTRL).  An   optional
                        argument, <y>, specifies a divisor which can  be 1 to
                        255. Finally, adding  "l" to  the values switches the
                        fan control into low-frequency mode. Usually there is
                        no need for any parameters besides <x>.
 CTRL:<sensor#>,<file>  Reads  the  fan  control  chart  from a  file, giving
                        effect to  the  software control mode. See  above for
                        guidelines on writing these configuration files.
         DIV:<divisor>  Applies the  given  divisor to  be  used  for fan RPM
                        readings. Use this if the fan speed is being reported
                        incorrectly. Acceptable values are 0 to 7 for Winbond
                        (not  implemented  for ITE). This parameter  does not
                        change the previous mode selected with /FAN.

   /POST[:<sensor#>  =  query  or   configure   real-time   display   of  CPU
   temperature on the POST (power-on self-test) indicator, port 80h. Use this
   feature if you have an external POST card,  or your mainboard comes with a
   built-in two-digit POST panel  (e.g.  certain EPoX and  ABIT boards).  The
   temperature is measured a few times per second, rounded down to one degree
   and   displayed in  decimal form   on the indicator.   "AA"  will mean the
   temperature reading exceeds  100C. "FF" appears  when the POST display is
   disabled (with "/POST:" or "/POST:0"). 


   Examples of command line:

                 /FAN1  Display the current state of fan 1.
                 /POST  Check which sensor is routed to the POST card.
           /FAN1:RESET  Reset fan 1, which is usually the same as CPU fan.
         /FAN1:DUTY=11  Set duty cycle of fan 1 to 11.
       /FAN1:DUTY=22:2  Set  duty  cycle  of  fan 1, additionally programming
                        its divisor.
        /FAN1:DUTY=64l  Run at duty cycle 64, low frequency mode.
        /FAN1:DUTY=255  Run at full duty cycle (255 is always the maximum).
   /FAN1:CTRL=2,c:\cfgs\fan.txt /SHOWFAN /POST:2
                        Start  software fan  control using  sensor 2, display
                        the detailed information about fan  control setup and
                        enable the POST  card to display  current readings of
                        sensor 2.


5. Technical description of a "Quiet PC"

5.1 Hardware

   In a "Quiet  PC",  the system  monitoring  circuitry  has to provide   two
   capabilities: collecting  temperature readings from   a set of  inputs (of
   which one is always attached to a CPU temperature sensor and the others be
   used as  ambient/chipset/user-mounted   sensors),  and   controlling   the
   rotation speed of fans  by applying  pulse-width  modulation (PWM)  to the
   fan's 12V  DC supply. A range  of levels (as much as   256), known as duty
   cycle values,  defines the proportion of "off"  time to "on" time, roughly
   simulating a reduced DC voltage by virtue of frequent alteration. 

   12V +             12V +-+   +-+     12V +---+ +---+   12V +-----------  
       :                 : |   | |         :   | |   |       :             
    0V +-----------   0V + +---+ +---   0V +   +-+   +-   0V +           
           0%                33%                67%               100%

   The fan  therefore is able  to run at a  variety of rotation speeds from a
   complete stop to full power. 

   W83697HF supports 2 fans and  3 sensors (with  0.5C sensitivity).  IT8712
   supports  5 fans and  5 sensors (with 1C  sensitivity), but this software
   currently handles only 3 of both.

5.2 Operating system kernel

   The kernel is responsible for delivering timer  events, or any other timed
   events, to the driver. 

5.3 The driver

   At  certain  periods of time (typically  more  than once per  second), the
   driver receives  a   timer event  from   kernel.  It then    examines each
   fan-sensor pair that  was put under software  control  and decides whether
   the   fan duty  cycle  needs to  be   changed  in response to  temperature
   alteration. 

   The driver also responds to   requests of control program, reporting   the
   sensor readings and accepting new software control setups. 

5.4 Control program

   The control   program interfaces with the  driver  and is  responsible for
   translating between user-readable and internal data formats. It parses the
   fan configuration  file and reduces it  into two  one-dimensional arrays -
   the "rise" cycle ("^" marks) and the "fall" ("v" marks): 

       0         55.5 56 56.5 57 57.5      125.5C
     +---+      +---+---+---+---+---+     +---+
     |20 | ...  |40 |40 |45 |45 |50 | ... |255| Rise cycle
     +---+      +---+---+---+---+---+     +---+
     |20 | ...  |70 |70 |75 |77 |80 | ... |255| Fall cycle
     +---+      +---+---+---+---+---+     +---+

   A "*" mark,  or intersection of  "^" and "v" lines in  a single point as a
   result of interpolation, will result in a cell having equal values in rise
   and fall cycle. 


6. Related software:

6.1 OS/2

   ControlYourFans (by Piotr Oniszczuk)
      This is a lightweight  user-mode implementation of software fan control
      for Winbond chips. Can be used as a replacement to this package. 

   StHwMon (by Stefan Milcke)
      A  solution   for  monitoring  various   system  parameters,  including
      temperatures   and  fan   speeds.    Includes  safeguards   to  prevent
      overheating. 

   VIA KTxxx power management tools, 823xcool.zip
      Reduce power consumption on several VIA chipsets, take special measures
      to   protect  the  CPU from   overheating  in   kernel  panic dead-ends
      (e.g. SYS1503). 

6.2 Linux

   See "Linux-Ecology-HOWTO" for a list of similar software packages.


7. Troubleshooting suggestions 

   Problem: my mainboard  is listed as supported but  nothing  happens when I
   turn on the software fan control.

   Solution:

        1. Check which connectors  are the fans in your PC attached to. There
           is always a dedicated connector for  CPU fan (which is most likely
           to be covered by the  software control capability). Some fans come
           only with a four-pin connector, these are completely unsupported.
        2. Ensure  you  have selected  the  right  sensor/fan pair  on  QCTRL
           command line.


8. Contacting the author 

   The author can be contacted at <andrew_belov@newmail.ru>.

   $Id: readme.txt,v 1.7 2007-04-06 13:21:00 andrew_belov Exp $
