Hardware/Mainboard/SuperIOHardware.cs
author moel.mich
Wed, 31 Aug 2011 22:48:49 +0000
changeset 323 3f2d9ebacf38
parent 320 df3493f75225
child 332 19b1e150e7af
permissions -rw-r--r--
Added first experimental support for fan control on the NCT677X super I/O chips.
     1 /*
     2   
     3   Version: MPL 1.1/GPL 2.0/LGPL 2.1
     4 
     5   The contents of this file are subject to the Mozilla Public License Version
     6   1.1 (the "License"); you may not use this file except in compliance with
     7   the License. You may obtain a copy of the License at
     8  
     9   http://www.mozilla.org/MPL/
    10 
    11   Software distributed under the License is distributed on an "AS IS" basis,
    12   WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    13   for the specific language governing rights and limitations under the License.
    14 
    15   The Original Code is the Open Hardware Monitor code.
    16 
    17   The Initial Developer of the Original Code is 
    18   Michael Möller <m.moeller@gmx.ch>.
    19   Portions created by the Initial Developer are Copyright (C) 2009-2011
    20   the Initial Developer. All Rights Reserved.
    21 
    22   Contributor(s):
    23 
    24   Alternatively, the contents of this file may be used under the terms of
    25   either the GNU General Public License Version 2 or later (the "GPL"), or
    26   the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    27   in which case the provisions of the GPL or the LGPL are applicable instead
    28   of those above. If you wish to allow use of your version of this file only
    29   under the terms of either the GPL or the LGPL, and not to allow others to
    30   use your version of this file under the terms of the MPL, indicate your
    31   decision by deleting the provisions above and replace them with the notice
    32   and other provisions required by the GPL or the LGPL. If you do not delete
    33   the provisions above, a recipient may use your version of this file under
    34   the terms of any one of the MPL, the GPL or the LGPL.
    35  
    36 */
    37 
    38 using System;
    39 using System.Collections.Generic;
    40 using System.Globalization;
    41 using System.Threading;
    42 using OpenHardwareMonitor.Hardware.LPC;
    43 
    44 namespace OpenHardwareMonitor.Hardware.Mainboard {
    45   internal class SuperIOHardware : Hardware {
    46 
    47     private readonly Mainboard mainboard;
    48     private readonly ISuperIO superIO;
    49 
    50     private readonly List<Sensor> voltages = new List<Sensor>();
    51     private readonly List<Sensor> temperatures = new List<Sensor>();
    52     private readonly List<Sensor> fans = new List<Sensor>();
    53     private readonly List<Sensor> controls = new List<Sensor>();
    54 
    55     private delegate float? ReadValueDelegate(int index);
    56     private delegate void UpdateDelegate();
    57 
    58     // delegates for mainboard specific sensor reading code
    59     private readonly ReadValueDelegate readVoltage;
    60     private readonly ReadValueDelegate readTemperature;
    61     private readonly ReadValueDelegate readFan;
    62     private readonly ReadValueDelegate readControl;
    63 
    64     // delegate for post update mainboard specific code
    65     private readonly UpdateDelegate postUpdate;
    66 
    67     // mainboard specific mutex
    68     private readonly Mutex mutex;
    69 
    70     public SuperIOHardware(Mainboard mainboard, ISuperIO superIO, 
    71       Manufacturer manufacturer, Model model, ISettings settings) 
    72       : base(ChipName.GetName(superIO.Chip), new Identifier("lpc", 
    73         superIO.Chip.ToString().ToLower(CultureInfo.InvariantCulture)), 
    74         settings)
    75     {
    76       this.mainboard = mainboard;
    77       this.superIO = superIO;
    78 
    79       this.readVoltage = (index) => superIO.Voltages[index];
    80       this.readTemperature = (index) => superIO.Temperatures[index];
    81       this.readFan = (index) => superIO.Fans[index];
    82       this.readControl = (index) => superIO.Controls[index];
    83 
    84       this.postUpdate = () => { };
    85 
    86       List<Voltage> v = new List<Voltage>();
    87       List<Temperature> t = new List<Temperature>();
    88       List<Fan> f = new List<Fan>();
    89       List<Ctrl> c = new List<Ctrl>();
    90 
    91       switch (superIO.Chip) {
    92         case Chip.IT8712F:
    93         case Chip.IT8716F:
    94         case Chip.IT8718F:
    95         case Chip.IT8720F: 
    96         case Chip.IT8726F:        
    97           switch (manufacturer) {
    98             case Manufacturer.ASUS:
    99               switch (model) {
   100                 case Model.Crosshair_III_Formula: // IT8720F
   101                   v.Add(new Voltage("VBat", 8));
   102                   t.Add(new Temperature("CPU", 0));
   103                   for (int i = 0; i < superIO.Fans.Length; i++)
   104                     f.Add(new Fan("Fan #" + (i + 1), i));
   105                   break;
   106                 case Model.M2N_SLI_DELUXE:                
   107                   v.Add(new Voltage("CPU VCore", 0));
   108                   v.Add(new Voltage("+3.3V", 1));
   109                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   110                   v.Add(new Voltage("+12V", 4, 30, 10));
   111                   v.Add(new Voltage("+5VSB", 7, 6.8f, 10));
   112                   v.Add(new Voltage("VBat", 8));
   113                   t.Add(new Temperature("CPU", 0));
   114                   t.Add(new Temperature("Motherboard", 1));
   115                   f.Add(new Fan("CPU Fan", 0));
   116                   f.Add(new Fan("Chassis Fan #1", 1));
   117                   f.Add(new Fan("Power Fan", 2));
   118                   break;
   119                 case Model.M4A79XTD_EVO: // IT8720F           
   120                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   121                   v.Add(new Voltage("VBat", 8));
   122                   t.Add(new Temperature("CPU", 0));
   123                   t.Add(new Temperature("Motherboard", 1));
   124                   f.Add(new Fan("CPU Fan", 0));
   125                   f.Add(new Fan("Chassis Fan #1", 1));
   126                   f.Add(new Fan("Chassis Fan #2", 2));
   127                   break;
   128                 default:
   129                   v.Add(new Voltage("CPU VCore", 0));
   130                   v.Add(new Voltage("Voltage #2", 1, true));
   131                   v.Add(new Voltage("Voltage #3", 2, true));
   132                   v.Add(new Voltage("Voltage #4", 3, true));
   133                   v.Add(new Voltage("Voltage #5", 4, true));
   134                   v.Add(new Voltage("Voltage #6", 5, true));
   135                   v.Add(new Voltage("Voltage #7", 6, true));
   136                   v.Add(new Voltage("Voltage #8", 7, true));
   137                   v.Add(new Voltage("VBat", 8));
   138                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   139                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   140                   for (int i = 0; i < superIO.Fans.Length; i++)
   141                     f.Add(new Fan("Fan #" + (i + 1), i));
   142                   break;
   143               }
   144               break;
   145 
   146             case Manufacturer.ASRock:
   147               switch (model) {
   148                 case Model.P55_Deluxe: // IT8720F
   149                   
   150                   v.Add(new Voltage("CPU VCore", 0));
   151                   v.Add(new Voltage("+3.3V", 2));
   152                   v.Add(new Voltage("+12V", 4, 30, 10));
   153                   v.Add(new Voltage("+5V", 5, 6.8f, 10));
   154                   v.Add(new Voltage("VBat", 8));                  
   155                   t.Add(new Temperature("CPU", 0));
   156                   t.Add(new Temperature("Motherboard", 1));
   157                   f.Add(new Fan("CPU Fan", 0));
   158                   f.Add(new Fan("Chassis Fan #1", 1));
   159 
   160                   // this mutex is also used by the official ASRock tool
   161                   mutex = new Mutex(false, "ASRockOCMark");
   162                   
   163                   bool exclusiveAccess = false;
   164                   try {
   165                     exclusiveAccess = mutex.WaitOne(10, false);
   166                   } catch (AbandonedMutexException) { } 
   167                     catch (InvalidOperationException) { }  
   168 
   169                   // only read additional fans if we get exclusive access
   170                   if (exclusiveAccess) {
   171 
   172                     f.Add(new Fan("Chassis Fan #2", 2));
   173                     f.Add(new Fan("Chassis Fan #3", 3));
   174                     f.Add(new Fan("Power Fan", 4));
   175 
   176                     readFan = (index) => {
   177                       if (index < 2) {
   178                         return superIO.Fans[index];
   179                       } else {
   180                         // get GPIO 80-87
   181                         byte? gpio = superIO.ReadGPIO(7);
   182                         if (!gpio.HasValue)
   183                           return null;
   184 
   185                         // read the last 3 fans based on GPIO 83-85
   186                         int[] masks = { 0x05, 0x03, 0x06 };
   187                         return (((gpio.Value >> 3) & 0x07) ==
   188                           masks[index - 2]) ? superIO.Fans[2] : null;
   189                       }
   190                     };
   191 
   192                     int fanIndex = 0;
   193                     postUpdate = () => {
   194                       // get GPIO 80-87
   195                       byte? gpio = superIO.ReadGPIO(7);
   196                       if (!gpio.HasValue)
   197                         return;
   198 
   199                       // prepare the GPIO 83-85 for the next update
   200                       int[] masks = { 0x05, 0x03, 0x06 };
   201                       superIO.WriteGPIO(7,
   202                         (byte)((gpio.Value & 0xC7) | (masks[fanIndex] << 3)));
   203                       fanIndex = (fanIndex + 1) % 3;
   204                     };
   205                   }
   206 
   207                   break;
   208                 default:
   209                   v.Add(new Voltage("CPU VCore", 0));
   210                   v.Add(new Voltage("Voltage #2", 1, true));
   211                   v.Add(new Voltage("Voltage #3", 2, true));
   212                   v.Add(new Voltage("Voltage #4", 3, true));
   213                   v.Add(new Voltage("Voltage #5", 4, true));
   214                   v.Add(new Voltage("Voltage #6", 5, true));
   215                   v.Add(new Voltage("Voltage #7", 6, true));
   216                   v.Add(new Voltage("Voltage #8", 7, true));
   217                   v.Add(new Voltage("VBat", 8));
   218                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   219                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   220                   for (int i = 0; i < superIO.Fans.Length; i++)
   221                     f.Add(new Fan("Fan #" + (i + 1), i));
   222                   break;
   223               };
   224               break;
   225 
   226             case Manufacturer.DFI:
   227               switch (model) {
   228                 case Model.LP_BI_P45_T2RS_Elite: // IT8718F
   229                   v.Add(new Voltage("CPU VCore", 0));
   230                   v.Add(new Voltage("FSB VTT", 1));
   231                   v.Add(new Voltage("+3.3V", 2));
   232                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   233                   v.Add(new Voltage("+12V", 4, 30, 10));
   234                   v.Add(new Voltage("NB Core", 5));
   235                   v.Add(new Voltage("VDIMM", 6));
   236                   v.Add(new Voltage("+5VSB", 7, 6.8f, 10));
   237                   v.Add(new Voltage("VBat", 8));
   238                   t.Add(new Temperature("CPU", 0));
   239                   t.Add(new Temperature("System", 1));
   240                   t.Add(new Temperature("Chipset", 2));
   241                   f.Add(new Fan("Fan #1", 0));
   242                   f.Add(new Fan("Fan #2", 1));
   243                   f.Add(new Fan("Fan #3", 2));
   244                   break;
   245                 case Model.LP_DK_P55_T3eH9: // IT8720F
   246                   v.Add(new Voltage("CPU VCore", 0));
   247                   v.Add(new Voltage("VTT", 1));
   248                   v.Add(new Voltage("+3.3V", 2));
   249                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   250                   v.Add(new Voltage("+12V", 4, 30, 10));
   251                   v.Add(new Voltage("CPU PLL", 5));
   252                   v.Add(new Voltage("DRAM", 6));
   253                   v.Add(new Voltage("+5VSB", 7, 6.8f, 10));
   254                   v.Add(new Voltage("VBat", 8));
   255                   t.Add(new Temperature("Chipset", 0));
   256                   t.Add(new Temperature("CPU PWM", 1));
   257                   t.Add(new Temperature("CPU", 2));
   258                   f.Add(new Fan("Fan #1", 0));
   259                   f.Add(new Fan("Fan #2", 1));
   260                   f.Add(new Fan("Fan #3", 2));
   261                   break;
   262                 default:
   263                   v.Add(new Voltage("CPU VCore", 0));
   264                   v.Add(new Voltage("VTT", 1, true));
   265                   v.Add(new Voltage("+3.3V", 2, true));
   266                   v.Add(new Voltage("+5V", 3, 6.8f, 10, 0, true));
   267                   v.Add(new Voltage("+12V", 4, 30, 10, 0, true));
   268                   v.Add(new Voltage("Voltage #6", 5, true));
   269                   v.Add(new Voltage("DRAM", 6, true));
   270                   v.Add(new Voltage("+5VSB", 7, 6.8f, 10, 0, true));
   271                   v.Add(new Voltage("VBat", 8));
   272                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   273                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   274                   for (int i = 0; i < superIO.Fans.Length; i++)
   275                     f.Add(new Fan("Fan #" + (i + 1), i));
   276                   break;
   277               }
   278               break;
   279 
   280             case Manufacturer.Gigabyte:
   281               switch (model) {
   282                 case Model._965P_S3: // IT8718F
   283                   v.Add(new Voltage("CPU VCore", 0));
   284                   v.Add(new Voltage("DRAM", 1));
   285                   v.Add(new Voltage("+3.3V", 2));
   286                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   287                   v.Add(new Voltage("+12V", 7, 27, 9.1f));
   288                   v.Add(new Voltage("VBat", 8));
   289                   t.Add(new Temperature("System", 0));
   290                   t.Add(new Temperature("CPU", 1));
   291                   f.Add(new Fan("CPU Fan", 0));
   292                   f.Add(new Fan("System Fan", 1));
   293                   break;
   294                 case Model.EP45_DS3R: // IT8718F
   295                 case Model.EP45_UD3R: 
   296                 case Model.X38_DS5:    
   297                   v.Add(new Voltage("CPU VCore", 0));
   298                   v.Add(new Voltage("DRAM", 1));
   299                   v.Add(new Voltage("+3.3V", 2));
   300                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   301                   v.Add(new Voltage("+12V", 7, 27, 9.1f));
   302                   v.Add(new Voltage("VBat", 8));
   303                   t.Add(new Temperature("System", 0));
   304                   t.Add(new Temperature("CPU", 1));
   305                   f.Add(new Fan("CPU Fan", 0));
   306                   f.Add(new Fan("System Fan #2", 1));
   307                   f.Add(new Fan("Power Fan", 2));
   308                   f.Add(new Fan("System Fan #1", 3));
   309                   break;
   310                 case Model.EX58_EXTREME: // IT8720F 
   311                   v.Add(new Voltage("CPU VCore", 0));
   312                   v.Add(new Voltage("DRAM", 1));
   313                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   314                   v.Add(new Voltage("VBat", 8));
   315                   t.Add(new Temperature("System", 0));
   316                   t.Add(new Temperature("CPU", 1));
   317                   t.Add(new Temperature("Northbridge", 2));
   318                   f.Add(new Fan("CPU Fan", 0));
   319                   f.Add(new Fan("System Fan #2", 1));
   320                   f.Add(new Fan("Power Fan", 2));
   321                   f.Add(new Fan("System Fan #1", 3));
   322                   break;
   323                 case Model.P35_DS3: // IT8718F 
   324                 case Model.P35_DS3L: // IT8718F
   325                   v.Add(new Voltage("CPU VCore", 0));
   326                   v.Add(new Voltage("DRAM", 1));
   327                   v.Add(new Voltage("+3.3V", 2));
   328                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   329                   v.Add(new Voltage("+12V", 7, 27, 9.1f));
   330                   v.Add(new Voltage("VBat", 8));
   331                   t.Add(new Temperature("System", 0));
   332                   t.Add(new Temperature("CPU", 1));
   333                   f.Add(new Fan("CPU Fan", 0));
   334                   f.Add(new Fan("System Fan #1", 1));
   335                   f.Add(new Fan("System Fan #2", 2));
   336                   f.Add(new Fan("Power Fan", 3));
   337                   break;
   338                 case Model.P55_UD4: // IT8720F
   339                 case Model.P55M_UD4: // IT8720F
   340                   v.Add(new Voltage("CPU VCore", 0));
   341                   v.Add(new Voltage("DRAM", 1));
   342                   v.Add(new Voltage("+3.3V", 2));
   343                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   344                   v.Add(new Voltage("+12V", 5, 27, 9.1f));
   345                   v.Add(new Voltage("VBat", 8));
   346                   t.Add(new Temperature("System", 0));
   347                   t.Add(new Temperature("CPU", 2));
   348                   f.Add(new Fan("CPU Fan", 0));
   349                   f.Add(new Fan("System Fan #2", 1));
   350                   f.Add(new Fan("Power Fan", 2));
   351                   f.Add(new Fan("System Fan #1", 3));
   352                   break;
   353                 case Model.GA_MA770T_UD3: // IT8720F
   354                   v.Add(new Voltage("CPU VCore", 0));
   355                   v.Add(new Voltage("DRAM", 1));
   356                   v.Add(new Voltage("+3.3V", 2));
   357                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   358                   v.Add(new Voltage("+12V", 4, 27, 9.1f));
   359                   v.Add(new Voltage("VBat", 8));
   360                   t.Add(new Temperature("System", 0));
   361                   t.Add(new Temperature("CPU", 1));
   362                   f.Add(new Fan("CPU Fan", 0));
   363                   f.Add(new Fan("System Fan #1", 1));
   364                   f.Add(new Fan("System Fan #2", 2));
   365                   f.Add(new Fan("Power Fan", 3));
   366                   break;
   367                 case Model.GA_MA785GMT_UD2H: // IT8718F
   368                   v.Add(new Voltage("CPU VCore", 0));
   369                   v.Add(new Voltage("DRAM", 1));
   370                   v.Add(new Voltage("+3.3V", 2));
   371                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   372                   v.Add(new Voltage("+12V", 4, 27, 9.1f));
   373                   v.Add(new Voltage("VBat", 8));
   374                   t.Add(new Temperature("System", 0));
   375                   t.Add(new Temperature("CPU", 1));
   376                   f.Add(new Fan("CPU Fan", 0));
   377                   f.Add(new Fan("System Fan", 1));
   378                   f.Add(new Fan("NB Fan", 2));
   379                   break;
   380                 case Model.X58A_UD3R: // IT8720F 
   381                   v.Add(new Voltage("CPU VCore", 0));
   382                   v.Add(new Voltage("DRAM", 1));
   383                   v.Add(new Voltage("+3.3V", 2));
   384                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   385                   v.Add(new Voltage("+12V", 5, 27, 9.1f));
   386                   v.Add(new Voltage("VBat", 8));
   387                   t.Add(new Temperature("System", 0));
   388                   t.Add(new Temperature("CPU", 1));
   389                   t.Add(new Temperature("Northbridge", 2));
   390                   f.Add(new Fan("CPU Fan", 0));
   391                   f.Add(new Fan("System Fan #2", 1));
   392                   f.Add(new Fan("Power Fan", 2));
   393                   f.Add(new Fan("System Fan #1", 3));
   394                   break;
   395                 default:
   396                   v.Add(new Voltage("CPU VCore", 0));
   397                   v.Add(new Voltage("DRAM", 1, true));
   398                   v.Add(new Voltage("+3.3V", 2, true));
   399                   v.Add(new Voltage("+5V", 3, 6.8f, 10, 0, true));
   400                   v.Add(new Voltage("Voltage #5", 4, true));
   401                   v.Add(new Voltage("Voltage #6", 5, true));
   402                   v.Add(new Voltage("Voltage #7", 6, true));
   403                   v.Add(new Voltage("Voltage #8", 7, true));
   404                   v.Add(new Voltage("VBat", 8));
   405                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   406                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   407                   for (int i = 0; i < superIO.Fans.Length; i++)
   408                     f.Add(new Fan("Fan #" + (i + 1), i));
   409                   break;
   410               }
   411               break;
   412 
   413             default:
   414               v.Add(new Voltage("CPU VCore", 0));
   415               v.Add(new Voltage("Voltage #2", 1, true));
   416               v.Add(new Voltage("Voltage #3", 2, true));
   417               v.Add(new Voltage("Voltage #4", 3, true));
   418               v.Add(new Voltage("Voltage #5", 4, true));
   419               v.Add(new Voltage("Voltage #6", 5, true));
   420               v.Add(new Voltage("Voltage #7", 6, true));
   421               v.Add(new Voltage("Voltage #8", 7, true));
   422               v.Add(new Voltage("VBat", 8));
   423               for (int i = 0; i < superIO.Temperatures.Length; i++)
   424                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   425               for (int i = 0; i < superIO.Fans.Length; i++)
   426                 f.Add(new Fan("Fan #" + (i + 1), i));
   427               break;
   428           }
   429           break;
   430 
   431         case Chip.IT8721F:
   432         case Chip.IT8728F:
   433         case Chip.IT8772E:
   434           switch (manufacturer) {
   435             case Manufacturer.ECS:
   436               switch (model) {
   437                 case Model.A890GXM_A: // IT8721F
   438                   v.Add(new Voltage("CPU VCore", 0));
   439                   v.Add(new Voltage("VDIMM", 1));
   440                   v.Add(new Voltage("NB Voltage", 2));
   441                   v.Add(new Voltage("Analog +3.3V", 3, 10, 10));
   442                   // v.Add(new Voltage("VDIMM", 6, true));
   443                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   444                   v.Add(new Voltage("VBat", 8, 10, 10));
   445                   t.Add(new Temperature("CPU", 0));
   446                   t.Add(new Temperature("System", 1));
   447                   t.Add(new Temperature("Northbridge", 2));
   448                   f.Add(new Fan("CPU Fan", 0));
   449                   f.Add(new Fan("System Fan", 1));
   450                   f.Add(new Fan("Power Fan", 2));
   451                   break;
   452                 default:
   453                   v.Add(new Voltage("Voltage #1", 0, true));
   454                   v.Add(new Voltage("Voltage #2", 1, true));
   455                   v.Add(new Voltage("Voltage #3", 2, true));
   456                   v.Add(new Voltage("Analog +3.3V", 3, 10, 10, 0, true));
   457                   v.Add(new Voltage("Voltage #5", 4, true));
   458                   v.Add(new Voltage("Voltage #6", 5, true));
   459                   v.Add(new Voltage("Voltage #7", 6, true));
   460                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   461                   v.Add(new Voltage("VBat", 8, 10, 10));
   462                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   463                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   464                   for (int i = 0; i < superIO.Fans.Length; i++)
   465                     f.Add(new Fan("Fan #" + (i + 1), i));
   466                   break;
   467               }
   468               break;
   469             case Manufacturer.Gigabyte:
   470               switch (model) {
   471                 case Model.P67A_UD4_B3: // IT8728F
   472                   v.Add(new Voltage("+12V", 0, 100, 10));
   473                   v.Add(new Voltage("+5V", 1, 15, 10));
   474                   v.Add(new Voltage("Voltage #3", 2, true));
   475                   v.Add(new Voltage("Voltage #4", 3, true));
   476                   v.Add(new Voltage("Voltage #5", 4, true));
   477                   v.Add(new Voltage("CPU VCore", 5));
   478                   v.Add(new Voltage("DRAM", 6));
   479                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   480                   v.Add(new Voltage("VBat", 8, 10, 10));
   481                   t.Add(new Temperature("System", 0));
   482                   t.Add(new Temperature("CPU", 2));
   483                   f.Add(new Fan("CPU Fan", 0));
   484                   f.Add(new Fan("System Fan #2", 1));
   485                   f.Add(new Fan("Power Fan", 2));
   486                   f.Add(new Fan("System Fan #1", 3));
   487                   break;
   488                 case Model.H67A_UD3H_B3: // IT8728F
   489                   v.Add(new Voltage("VTT", 0));
   490                   v.Add(new Voltage("+5V", 1, 15, 10));
   491                   v.Add(new Voltage("+12V", 2, 68, 22));
   492                   v.Add(new Voltage("Voltage #4", 3, true));
   493                   v.Add(new Voltage("Voltage #5", 4, true));
   494                   v.Add(new Voltage("CPU VCore", 5));
   495                   v.Add(new Voltage("DRAM", 6));
   496                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   497                   v.Add(new Voltage("VBat", 8, 10, 10));
   498                   t.Add(new Temperature("System", 0));
   499                   t.Add(new Temperature("CPU", 2));
   500                   f.Add(new Fan("CPU Fan", 0));
   501                   f.Add(new Fan("System Fan #1", 1));
   502                   f.Add(new Fan("Power Fan", 2));
   503                   f.Add(new Fan("System Fan #2", 3));
   504                   break;
   505                 case Model.Z68X_UD7_B3: // IT8728F
   506                   v.Add(new Voltage("VTT", 0));
   507                   v.Add(new Voltage("+3.3V", 1, 13.3f, 20.5f));
   508                   v.Add(new Voltage("+12V", 2, 68, 22));
   509                   v.Add(new Voltage("+5V", 3, 14.3f, 20));
   510                   v.Add(new Voltage("CPU VCore", 5));
   511                   v.Add(new Voltage("DRAM", 6));
   512                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   513                   v.Add(new Voltage("VBat", 8, 10, 10));
   514                   t.Add(new Temperature("System", 0));
   515                   t.Add(new Temperature("CPU", 1));
   516                   t.Add(new Temperature("System 3", 2));
   517                   f.Add(new Fan("CPU Fan", 0));
   518                   f.Add(new Fan("Power Fan", 1));
   519                   f.Add(new Fan("System Fan #1", 2));
   520                   f.Add(new Fan("System Fan #2", 3));
   521                   f.Add(new Fan("System Fan #3", 4));
   522                   break;
   523                 default:
   524                   v.Add(new Voltage("Voltage #1", 0, true));
   525                   v.Add(new Voltage("Voltage #2", 1, true));
   526                   v.Add(new Voltage("Voltage #3", 2, true));
   527                   v.Add(new Voltage("Voltage #4", 3, true));
   528                   v.Add(new Voltage("Voltage #5", 4, true));
   529                   v.Add(new Voltage("Voltage #6", 5, true));
   530                   v.Add(new Voltage("Voltage #7", 6, true));
   531                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   532                   v.Add(new Voltage("VBat", 8, 10, 10));
   533                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   534                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   535                   for (int i = 0; i < superIO.Fans.Length; i++)
   536                     f.Add(new Fan("Fan #" + (i + 1), i));
   537                   break;
   538               }
   539               break;
   540             case Manufacturer.Shuttle:
   541               switch (model) {
   542                 case Model.FH67: // IT8772E 
   543                   v.Add(new Voltage("CPU VCore", 0));
   544                   v.Add(new Voltage("DRAM", 1));
   545                   v.Add(new Voltage("PCH VCCIO", 2));
   546                   v.Add(new Voltage("CPU VCCIO", 3));
   547                   v.Add(new Voltage("Graphic Voltage", 4));
   548                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   549                   v.Add(new Voltage("VBat", 8, 10, 10));
   550                   t.Add(new Temperature("System", 0));
   551                   t.Add(new Temperature("CPU", 1));                  
   552                   f.Add(new Fan("Fan #1", 0));
   553                   f.Add(new Fan("CPU Fan", 1));
   554                   break;
   555                 default:
   556                   v.Add(new Voltage("Voltage #1", 0, true));
   557                   v.Add(new Voltage("Voltage #2", 1, true));
   558                   v.Add(new Voltage("Voltage #3", 2, true));
   559                   v.Add(new Voltage("Voltage #4", 3, true));
   560                   v.Add(new Voltage("Voltage #5", 4, true));
   561                   v.Add(new Voltage("Voltage #6", 5, true));
   562                   v.Add(new Voltage("Voltage #7", 6, true));
   563                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   564                   v.Add(new Voltage("VBat", 8, 10, 10));
   565                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   566                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   567                   for (int i = 0; i < superIO.Fans.Length; i++)
   568                     f.Add(new Fan("Fan #" + (i + 1), i));
   569                   break;
   570               }
   571               break;
   572             default:
   573               v.Add(new Voltage("Voltage #1", 0, true));
   574               v.Add(new Voltage("Voltage #2", 1, true));
   575               v.Add(new Voltage("Voltage #3", 2, true));
   576               v.Add(new Voltage("Voltage #4", 3, true));
   577               v.Add(new Voltage("Voltage #5", 4, true));
   578               v.Add(new Voltage("Voltage #6", 5, true));
   579               v.Add(new Voltage("Voltage #7", 6, true));
   580               v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   581               v.Add(new Voltage("VBat", 8, 10, 10));
   582               for (int i = 0; i < superIO.Temperatures.Length; i++)
   583                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   584               for (int i = 0; i < superIO.Fans.Length; i++)
   585                 f.Add(new Fan("Fan #" + (i + 1), i));
   586               break;
   587           }
   588           break;
   589           
   590         case Chip.F71858:
   591           v.Add(new Voltage("VCC3V", 0, 150, 150));
   592           v.Add(new Voltage("VSB3V", 1, 150, 150));
   593           v.Add(new Voltage("Battery", 2, 150, 150));
   594           for (int i = 0; i < superIO.Temperatures.Length; i++)
   595             t.Add(new Temperature("Temperature #" + (i + 1), i));
   596           for (int i = 0; i < superIO.Fans.Length; i++)
   597             f.Add(new Fan("Fan #" + (i + 1), i));
   598           break;
   599         case Chip.F71862: 
   600         case Chip.F71869: 
   601         case Chip.F71882:
   602         case Chip.F71889AD: 
   603         case Chip.F71889ED: 
   604         case Chip.F71889F:
   605           switch (manufacturer) {
   606             case Manufacturer.EVGA:
   607               switch (model) {
   608                 case Model.X58_SLI_Classified: // F71882 
   609                   v.Add(new Voltage("VCC3V", 0, 150, 150));
   610                   v.Add(new Voltage("CPU VCore", 1, 47, 100));
   611                   v.Add(new Voltage("DIMM", 2, 47, 100));
   612                   v.Add(new Voltage("CPU VTT", 3, 24, 100));
   613                   v.Add(new Voltage("IOH Vcore", 4, 24, 100));
   614                   v.Add(new Voltage("+5V", 5, 51, 12));
   615                   v.Add(new Voltage("+12V", 6, 56, 6.8f));
   616                   v.Add(new Voltage("3VSB", 7, 150, 150));
   617                   v.Add(new Voltage("VBat", 8, 150, 150));
   618                   t.Add(new Temperature("CPU", 0));
   619                   t.Add(new Temperature("VREG", 1));
   620                   t.Add(new Temperature("System", 2));
   621                   f.Add(new Fan("CPU Fan", 0));
   622                   f.Add(new Fan("Power Fan", 1));
   623                   f.Add(new Fan("Chassis Fan", 2));
   624                   break;
   625                 default:
   626                   v.Add(new Voltage("VCC3V", 0, 150, 150));
   627                   v.Add(new Voltage("CPU VCore", 1));
   628                   v.Add(new Voltage("Voltage #3", 2, true));
   629                   v.Add(new Voltage("Voltage #4", 3, true));
   630                   v.Add(new Voltage("Voltage #5", 4, true));
   631                   v.Add(new Voltage("Voltage #6", 5, true));
   632                   v.Add(new Voltage("Voltage #7", 6, true));
   633                   v.Add(new Voltage("VSB3V", 7, 150, 150));
   634                   v.Add(new Voltage("VBat", 8, 150, 150));
   635                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   636                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   637                   for (int i = 0; i < superIO.Fans.Length; i++)
   638                     f.Add(new Fan("Fan #" + (i + 1), i));
   639                   break;
   640               }
   641               break;
   642             default:
   643               v.Add(new Voltage("VCC3V", 0, 150, 150));
   644               v.Add(new Voltage("CPU VCore", 1));
   645               v.Add(new Voltage("Voltage #3", 2, true));
   646               v.Add(new Voltage("Voltage #4", 3, true));
   647               v.Add(new Voltage("Voltage #5", 4, true));
   648               v.Add(new Voltage("Voltage #6", 5, true));
   649               v.Add(new Voltage("Voltage #7", 6, true));
   650               v.Add(new Voltage("VSB3V", 7, 150, 150));
   651               v.Add(new Voltage("VBat", 8, 150, 150));
   652               for (int i = 0; i < superIO.Temperatures.Length; i++)
   653                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   654               for (int i = 0; i < superIO.Fans.Length; i++)
   655                 f.Add(new Fan("Fan #" + (i + 1), i));
   656               break;
   657           }
   658           break;
   659 
   660         case Chip.W83627EHF:
   661           switch (manufacturer) {
   662             case Manufacturer.ASRock:
   663               switch (model) {
   664                 case Model.AOD790GX_128M: // W83627EHF
   665                   v.Add(new Voltage("CPU VCore", 0));
   666                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   667                   v.Add(new Voltage("+3.3V", 4, 10, 10));
   668                   v.Add(new Voltage("+5V", 5, 20, 10));
   669                   v.Add(new Voltage("+12V", 6, 28, 5));
   670                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   671                   v.Add(new Voltage("VBAT", 8, 34, 34));
   672                   t.Add(new Temperature("CPU", 0));
   673                   t.Add(new Temperature("Motherboard", 2));
   674                   f.Add(new Fan("CPU Fan", 0));
   675                   f.Add(new Fan("Chassis Fan", 1));                 
   676                   break;
   677                 default:
   678                   v.Add(new Voltage("CPU VCore", 0));
   679                   v.Add(new Voltage("Voltage #2", 1, true));
   680                   v.Add(new Voltage("AVCC", 2, 34, 34));
   681                   v.Add(new Voltage("3VCC", 3, 34, 34));
   682                   v.Add(new Voltage("Voltage #5", 4, true));
   683                   v.Add(new Voltage("Voltage #6", 5, true));
   684                   v.Add(new Voltage("Voltage #7", 6, true));
   685                   v.Add(new Voltage("3VSB", 7, 34, 34));
   686                   v.Add(new Voltage("VBAT", 8, 34, 34));
   687                   v.Add(new Voltage("Voltage #10", 9, true));
   688                   t.Add(new Temperature("CPU", 0));
   689                   t.Add(new Temperature("Auxiliary", 1));
   690                   t.Add(new Temperature("System", 2));
   691                   f.Add(new Fan("System Fan", 0));
   692                   f.Add(new Fan("CPU Fan", 1));
   693                   f.Add(new Fan("Auxiliary Fan", 2));
   694                   f.Add(new Fan("CPU Fan #2", 3));
   695                   f.Add(new Fan("Auxiliary Fan #2", 4));
   696                   break;
   697               } break;
   698             default:
   699               v.Add(new Voltage("CPU VCore", 0));
   700               v.Add(new Voltage("Voltage #2", 1, true));
   701               v.Add(new Voltage("AVCC", 2, 34, 34));
   702               v.Add(new Voltage("3VCC", 3, 34, 34));
   703               v.Add(new Voltage("Voltage #5", 4, true));
   704               v.Add(new Voltage("Voltage #6", 5, true));
   705               v.Add(new Voltage("Voltage #7", 6, true));
   706               v.Add(new Voltage("3VSB", 7, 34, 34));
   707               v.Add(new Voltage("VBAT", 8, 34, 34));
   708               v.Add(new Voltage("Voltage #10", 9, true));
   709               t.Add(new Temperature("CPU", 0));
   710               t.Add(new Temperature("Auxiliary", 1));
   711               t.Add(new Temperature("System", 2));
   712               f.Add(new Fan("System Fan", 0));
   713               f.Add(new Fan("CPU Fan", 1));
   714               f.Add(new Fan("Auxiliary Fan", 2));
   715               f.Add(new Fan("CPU Fan #2", 3));
   716               f.Add(new Fan("Auxiliary Fan #2", 4));
   717               break;
   718           }
   719           break;
   720         case Chip.W83627DHG: 
   721         case Chip.W83627DHGP:                      
   722         case Chip.W83667HG:
   723         case Chip.W83667HGB:
   724           switch (manufacturer) {
   725             case Manufacturer.ASRock:
   726               switch (model) {
   727                 case Model._880GMH_USB3: // W83627DHG-P
   728                   v.Add(new Voltage("CPU VCore", 0));
   729                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   730                   v.Add(new Voltage("+5V", 5, 15, 7.5f));
   731                   v.Add(new Voltage("+12V", 6, 56, 10));
   732                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   733                   v.Add(new Voltage("VBAT", 8, 34, 34));
   734                   t.Add(new Temperature("CPU", 0));
   735                   t.Add(new Temperature("Motherboard", 2));
   736                   f.Add(new Fan("Chassis Fan", 0));
   737                   f.Add(new Fan("CPU Fan", 1));
   738                   f.Add(new Fan("Power Fan", 2));
   739                   break;
   740                 default:
   741                   v.Add(new Voltage("CPU VCore", 0));
   742                   v.Add(new Voltage("Voltage #2", 1, true));
   743                   v.Add(new Voltage("AVCC", 2, 34, 34));
   744                   v.Add(new Voltage("3VCC", 3, 34, 34));
   745                   v.Add(new Voltage("Voltage #5", 4, true));
   746                   v.Add(new Voltage("Voltage #6", 5, true));
   747                   v.Add(new Voltage("Voltage #7", 6, true));
   748                   v.Add(new Voltage("3VSB", 7, 34, 34));
   749                   v.Add(new Voltage("VBAT", 8, 34, 34));
   750                   t.Add(new Temperature("CPU", 0));
   751                   t.Add(new Temperature("Auxiliary", 1));
   752                   t.Add(new Temperature("System", 2));
   753                   f.Add(new Fan("System Fan", 0));
   754                   f.Add(new Fan("CPU Fan", 1));
   755                   f.Add(new Fan("Auxiliary Fan", 2));
   756                   f.Add(new Fan("CPU Fan #2", 3));
   757                   f.Add(new Fan("Auxiliary Fan #2", 4));
   758                   break;
   759               }
   760               break;
   761             case Manufacturer.ASUS:
   762               switch (model) {
   763                 case Model.P6X58D_E: // W83667HG                 
   764                 case Model.Rampage_II_GENE: // W83667HG 
   765                   v.Add(new Voltage("CPU VCore", 0));
   766                   v.Add(new Voltage("+12V", 1, 11.5f, 1.91f));
   767                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   768                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   769                   v.Add(new Voltage("+5V", 4, 15, 7.5f));
   770                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   771                   v.Add(new Voltage("VBAT", 8, 34, 34));
   772                   t.Add(new Temperature("CPU", 0));
   773                   t.Add(new Temperature("Motherboard", 2));
   774                   f.Add(new Fan("Chassis Fan #1", 0));
   775                   f.Add(new Fan("CPU Fan", 1));
   776                   f.Add(new Fan("Power Fan", 2));
   777                   f.Add(new Fan("Chassis Fan #2", 3));
   778                   f.Add(new Fan("Chassis Fan #3", 4));
   779                   break;
   780                 case Model.Rampage_Extreme: // W83667HG 
   781                   v.Add(new Voltage("CPU VCore", 0));
   782                   v.Add(new Voltage("+12V", 1, 12, 2));
   783                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   784                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   785                   v.Add(new Voltage("+5V", 4, 15, 7.5f));
   786                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   787                   v.Add(new Voltage("VBAT", 8, 34, 34));
   788                   t.Add(new Temperature("CPU", 0));
   789                   t.Add(new Temperature("Motherboard", 2));
   790                   f.Add(new Fan("Chassis Fan #1", 0));
   791                   f.Add(new Fan("CPU Fan", 1));
   792                   f.Add(new Fan("Power Fan", 2));
   793                   f.Add(new Fan("Chassis Fan #2", 3));
   794                   f.Add(new Fan("Chassis Fan #3", 4));
   795                   break;
   796                 default:
   797                   v.Add(new Voltage("CPU VCore", 0));
   798                   v.Add(new Voltage("Voltage #2", 1, true));
   799                   v.Add(new Voltage("AVCC", 2, 34, 34));
   800                   v.Add(new Voltage("3VCC", 3, 34, 34));
   801                   v.Add(new Voltage("Voltage #5", 4, true));
   802                   v.Add(new Voltage("Voltage #6", 5, true));
   803                   v.Add(new Voltage("Voltage #7", 6, true));
   804                   v.Add(new Voltage("3VSB", 7, 34, 34));
   805                   v.Add(new Voltage("VBAT", 8, 34, 34));
   806                   t.Add(new Temperature("CPU", 0));
   807                   t.Add(new Temperature("Auxiliary", 1));
   808                   t.Add(new Temperature("System", 2));
   809                   f.Add(new Fan("System Fan", 0));
   810                   f.Add(new Fan("CPU Fan", 1));
   811                   f.Add(new Fan("Auxiliary Fan", 2));
   812                   f.Add(new Fan("CPU Fan #2", 3));
   813                   f.Add(new Fan("Auxiliary Fan #2", 4));
   814                   break;
   815               }
   816               break;
   817             default:
   818               v.Add(new Voltage("CPU VCore", 0));
   819               v.Add(new Voltage("Voltage #2", 1, true));
   820               v.Add(new Voltage("AVCC", 2, 34, 34));
   821               v.Add(new Voltage("3VCC", 3, 34, 34));
   822               v.Add(new Voltage("Voltage #5", 4, true));
   823               v.Add(new Voltage("Voltage #6", 5, true));
   824               v.Add(new Voltage("Voltage #7", 6, true));
   825               v.Add(new Voltage("3VSB", 7, 34, 34));
   826               v.Add(new Voltage("VBAT", 8, 34, 34));
   827               t.Add(new Temperature("CPU", 0));
   828               t.Add(new Temperature("Auxiliary", 1));
   829               t.Add(new Temperature("System", 2));
   830               f.Add(new Fan("System Fan", 0));
   831               f.Add(new Fan("CPU Fan", 1));
   832               f.Add(new Fan("Auxiliary Fan", 2));
   833               f.Add(new Fan("CPU Fan #2", 3));
   834               f.Add(new Fan("Auxiliary Fan #2", 4));
   835               break;
   836           } 
   837           break;
   838         case Chip.W83627HF: 
   839         case Chip.W83627THF: 
   840         case Chip.W83687THF:
   841           v.Add(new Voltage("CPU VCore", 0));
   842           v.Add(new Voltage("Voltage #2", 1, true));
   843           v.Add(new Voltage("Voltage #3", 2, true));
   844           v.Add(new Voltage("AVCC", 3, 34, 51));
   845           v.Add(new Voltage("Voltage #5", 4, true));
   846           v.Add(new Voltage("5VSB", 5, 34, 51));
   847           v.Add(new Voltage("VBAT", 6));
   848           t.Add(new Temperature("CPU", 0));
   849           t.Add(new Temperature("Auxiliary", 1));
   850           t.Add(new Temperature("System", 2));
   851           f.Add(new Fan("System Fan", 0));
   852           f.Add(new Fan("CPU Fan", 1));
   853           f.Add(new Fan("Auxiliary Fan", 2));
   854           break;
   855         case Chip.NCT6771F:
   856         case Chip.NCT6776F:
   857           switch (manufacturer) {
   858             case Manufacturer.ASUS:
   859               switch (model) {
   860                 case Model.P8P67: // NCT6776F
   861                 case Model.P8P67_EVO: // NCT6776F
   862                 case Model.P8P67_PRO: // NCT6776F
   863                   v.Add(new Voltage("CPU VCore", 0));
   864                   v.Add(new Voltage("+12V", 1, 11, 1));
   865                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   866                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   867                   v.Add(new Voltage("+5V", 4, 12, 3));
   868                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   869                   v.Add(new Voltage("VBAT", 8, 34, 34));
   870                   t.Add(new Temperature("CPU", 0));
   871                   t.Add(new Temperature("Auxiliary", 2));
   872                   t.Add(new Temperature("Motherboard", 3));
   873                   f.Add(new Fan("Chassis Fan #1", 0));
   874                   f.Add(new Fan("CPU Fan", 1));
   875                   f.Add(new Fan("Power Fan", 2));
   876                   f.Add(new Fan("Chassis Fan #2", 3));
   877                   c.Add(new Ctrl("Chassis Fan #2", 0));
   878                   c.Add(new Ctrl("CPU Fan", 1));
   879                   c.Add(new Ctrl("Chassis Fan #1", 2));
   880                   break;
   881                 case Model.P8P67_M_PRO: // NCT6776F
   882                   v.Add(new Voltage("CPU VCore", 0));
   883                   v.Add(new Voltage("+12V", 1, 11, 1));
   884                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   885                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   886                   v.Add(new Voltage("+5V", 4, 12, 3));
   887                   v.Add(new Voltage("Voltage #6", 5, true));
   888                   v.Add(new Voltage("Voltage #7", 6, true));
   889                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   890                   v.Add(new Voltage("VBAT", 8, 34, 34));
   891                   t.Add(new Temperature("CPU", 0));
   892                   t.Add(new Temperature("Motherboard", 3));
   893                   f.Add(new Fan("Chassis Fan #1", 0));
   894                   f.Add(new Fan("CPU Fan", 1));
   895                   f.Add(new Fan("Chassis Fan #2", 2));
   896                   f.Add(new Fan("Power Fan", 3));
   897                   f.Add(new Fan("Auxiliary Fan", 4));
   898                   break;
   899                 default:
   900                   v.Add(new Voltage("CPU VCore", 0));
   901                   v.Add(new Voltage("Voltage #2", 1, true));
   902                   v.Add(new Voltage("AVCC", 2, 34, 34));
   903                   v.Add(new Voltage("3VCC", 3, 34, 34));
   904                   v.Add(new Voltage("Voltage #5", 4, true));
   905                   v.Add(new Voltage("Voltage #6", 5, true));
   906                   v.Add(new Voltage("Voltage #7", 6, true));
   907                   v.Add(new Voltage("3VSB", 7, 34, 34));
   908                   v.Add(new Voltage("VBAT", 8, 34, 34));
   909                   t.Add(new Temperature("CPU", 0));
   910                   t.Add(new Temperature("CPU", 1));
   911                   t.Add(new Temperature("Auxiliary", 2));
   912                   t.Add(new Temperature("System", 3));
   913                   for (int i = 0; i < superIO.Fans.Length; i++)
   914                     f.Add(new Fan("Fan #" + (i + 1), i));
   915                   break;
   916               }
   917               break;
   918             default:
   919               v.Add(new Voltage("CPU VCore", 0));
   920               v.Add(new Voltage("Voltage #2", 1, true));
   921               v.Add(new Voltage("AVCC", 2, 34, 34));
   922               v.Add(new Voltage("3VCC", 3, 34, 34));
   923               v.Add(new Voltage("Voltage #5", 4, true));
   924               v.Add(new Voltage("Voltage #6", 5, true));
   925               v.Add(new Voltage("Voltage #7", 6, true));
   926               v.Add(new Voltage("3VSB", 7, 34, 34));
   927               v.Add(new Voltage("VBAT", 8, 34, 34));
   928               t.Add(new Temperature("CPU", 0));
   929               t.Add(new Temperature("CPU", 1));
   930               t.Add(new Temperature("Auxiliary", 2));
   931               t.Add(new Temperature("System", 3));
   932               for (int i = 0; i < superIO.Fans.Length; i++)
   933                 f.Add(new Fan("Fan #" + (i + 1), i));
   934               break;
   935           }
   936           break;
   937         default:
   938           for (int i = 0; i < superIO.Voltages.Length; i++)
   939             v.Add(new Voltage("Voltage #" + (i + 1), i, true));
   940           for (int i = 0; i < superIO.Temperatures.Length; i++)
   941             t.Add(new Temperature("Temperature #" + (i + 1), i));
   942           for (int i = 0; i < superIO.Fans.Length; i++)
   943             f.Add(new Fan("Fan #" + (i + 1), i));
   944           for (int i = 0; i < superIO.Controls.Length; i++)
   945             c.Add(new Ctrl("Fan Control #" + (i + 1), i));
   946           break;
   947       }
   948 
   949       const string formula = "Voltage = value + (value - Vf) * Ri / Rf.";
   950       foreach (Voltage voltage in v) 
   951         if (voltage.Index < superIO.Voltages.Length) {
   952           Sensor sensor = new Sensor(voltage.Name, voltage.Index, 
   953             voltage.Hidden, SensorType.Voltage, this, new [] {
   954             new ParameterDescription("Ri [kΩ]", "Input resistance.\n" + 
   955               formula, voltage.Ri),
   956             new ParameterDescription("Rf [kΩ]", "Reference resistance.\n" + 
   957               formula, voltage.Rf),
   958             new ParameterDescription("Vf [V]", "Reference voltage.\n" + 
   959               formula, voltage.Vf)
   960             }, settings);
   961           voltages.Add(sensor);
   962       }
   963 
   964       foreach (Temperature temperature in t) 
   965         if (temperature.Index < superIO.Temperatures.Length) {
   966         Sensor sensor = new Sensor(temperature.Name, temperature.Index,
   967           SensorType.Temperature, this, new [] {
   968           new ParameterDescription("Offset [°C]", "Temperature offset.", 0)
   969         }, settings);
   970         temperatures.Add(sensor);
   971       }
   972 
   973       foreach (Fan fan in f)
   974         if (fan.Index < superIO.Fans.Length) {
   975           Sensor sensor = new Sensor(fan.Name, fan.Index, SensorType.Fan,
   976             this, settings);
   977           fans.Add(sensor);
   978         }
   979 
   980       foreach (Ctrl ctrl in c) {
   981         int index = ctrl.Index;
   982         if (index < superIO.Controls.Length) {
   983           Sensor sensor = new Sensor(ctrl.Name, index, SensorType.Control,
   984             this, settings);
   985           Control control = new Control(sensor, settings, 0, 100);
   986           control.ControlModeChanged += (cc) => {
   987             if (cc.ControlMode == ControlMode.Default) {
   988               superIO.SetControl(index, null);
   989             } else {
   990               superIO.SetControl(index, (byte)(cc.SoftwareValue * 2.55));
   991             }
   992           };
   993           control.SoftwareControlValueChanged += (cc) => {
   994             if (cc.ControlMode == ControlMode.Software) 
   995               superIO.SetControl(index, (byte)(cc.SoftwareValue * 2.55));
   996           };
   997           if (control.ControlMode == ControlMode.Software) 
   998             superIO.SetControl(index, (byte)(control.SoftwareValue * 2.55));
   999           sensor.Control = control;
  1000           controls.Add(sensor);
  1001         }
  1002       }
  1003     }
  1004 
  1005     public override HardwareType HardwareType {
  1006       get { return HardwareType.SuperIO; }
  1007     }
  1008 
  1009     public override IHardware Parent {
  1010       get { return mainboard; }
  1011     }
  1012 
  1013 
  1014     public override string GetReport() {
  1015       return superIO.GetReport();
  1016     }
  1017 
  1018     public override void Update() {
  1019       superIO.Update();
  1020 
  1021       foreach (Sensor sensor in voltages) {
  1022         float? value = readVoltage(sensor.Index);
  1023         if (value.HasValue) {
  1024           sensor.Value = value + (value - sensor.Parameters[2].Value) *
  1025             sensor.Parameters[0].Value / sensor.Parameters[1].Value;
  1026           ActivateSensor(sensor);
  1027         }
  1028       }
  1029 
  1030       foreach (Sensor sensor in temperatures) {
  1031         float? value = readTemperature(sensor.Index);
  1032         if (value.HasValue) {
  1033           sensor.Value = value + sensor.Parameters[0].Value;
  1034           ActivateSensor(sensor);
  1035         }
  1036       }
  1037 
  1038       foreach (Sensor sensor in fans) {
  1039         float? value = readFan(sensor.Index);
  1040         if (value.HasValue) {
  1041           sensor.Value = value;
  1042           if (value.Value > 0)
  1043             ActivateSensor(sensor);
  1044         }
  1045       }
  1046 
  1047       foreach (Sensor sensor in controls) {
  1048         float? value = readControl(sensor.Index);
  1049         if (value.HasValue) {
  1050           sensor.Value = value;
  1051           ActivateSensor(sensor);
  1052         }
  1053       }
  1054 
  1055       postUpdate();
  1056     }
  1057 
  1058     public override void Close() {
  1059       foreach (Sensor sensor in controls) {
  1060         // restore all controls back to default
  1061         superIO.SetControl(sensor.Index, null);
  1062       }
  1063       base.Close();
  1064     }
  1065 
  1066     private class Voltage {
  1067       public readonly string Name;
  1068       public readonly int Index;
  1069       public readonly float Ri;
  1070       public readonly float Rf;
  1071       public readonly float Vf;
  1072       public readonly bool Hidden;
  1073 
  1074       public Voltage(string name, int index) :
  1075         this(name, index, false) { }
  1076       
  1077       public Voltage(string name, int index, bool hidden) :
  1078         this(name, index, 0, 1, 0, hidden) { }
  1079       
  1080       public Voltage(string name, int index, float ri, float rf) :
  1081         this(name, index, ri, rf, 0, false) { }
  1082       
  1083       // float ri = 0, float rf = 1, float vf = 0, bool hidden = false) 
  1084       
  1085       public Voltage(string name, int index, 
  1086         float ri, float rf, float vf, bool hidden) 
  1087       {
  1088         this.Name = name;
  1089         this.Index = index;
  1090         this.Ri = ri;
  1091         this.Rf = rf;
  1092         this.Vf = vf;
  1093         this.Hidden = hidden;
  1094       }
  1095     }
  1096 
  1097     private class Temperature {
  1098       public readonly string Name;
  1099       public readonly int Index;
  1100 
  1101       public Temperature(string name, int index) {
  1102         this.Name = name;
  1103         this.Index = index;
  1104       }
  1105     }
  1106 
  1107     private class Fan {
  1108       public readonly string Name;
  1109       public readonly int Index;
  1110 
  1111       public Fan(string name, int index) {
  1112         this.Name = name;
  1113         this.Index = index;
  1114       }
  1115     }
  1116 
  1117     private class Ctrl {
  1118       public readonly string Name;
  1119       public readonly int Index;
  1120 
  1121       public Ctrl(string name, int index) {
  1122         this.Name = name;
  1123         this.Index = index;
  1124       }
  1125     }
  1126   }
  1127 }