Hardware/Mainboard/SuperIOHardware.cs
author moel.mich
Sat, 30 Apr 2011 21:01:54 +0000
changeset 276 04905193c432
parent 275 35788ddd1825
child 277 5c80f37c0330
permissions -rw-r--r--
Added a mainboard specific configuration for the ASUS P8P67-M Pro and fixed a few problems in the NCT677X implementation.
     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 
    54     private delegate float? ReadValueDelegate(int index);
    55     private delegate void UpdateDelegate();
    56 
    57     // delegates for mainboard specific sensor reading code
    58     private readonly ReadValueDelegate readVoltage;
    59     private readonly ReadValueDelegate readTemperature;
    60     private readonly ReadValueDelegate readFan;
    61 
    62     // delegate for post update mainboard specific code
    63     private readonly UpdateDelegate postUpdate;
    64 
    65     // mainboard specific mutex
    66     private readonly Mutex mutex;
    67 
    68     public SuperIOHardware(Mainboard mainboard, ISuperIO superIO, 
    69       Manufacturer manufacturer, Model model, ISettings settings) 
    70       : base(ChipName.GetName(superIO.Chip), new Identifier("lpc", 
    71         superIO.Chip.ToString().ToLower(CultureInfo.InvariantCulture)), 
    72         settings)
    73     {
    74       this.mainboard = mainboard;
    75       this.superIO = superIO;
    76 
    77       this.readVoltage = (index) => superIO.Voltages[index];
    78       this.readTemperature = (index) => superIO.Temperatures[index];
    79       this.readFan = (index) => superIO.Fans[index];
    80 
    81       this.postUpdate = () => { };
    82 
    83       List<Voltage> v = new List<Voltage>();
    84       List<Temperature> t = new List<Temperature>();
    85       List<Fan> f = new List<Fan>();
    86 
    87       switch (superIO.Chip) {
    88         case Chip.IT8712F:
    89         case Chip.IT8716F:
    90         case Chip.IT8718F:
    91         case Chip.IT8720F: 
    92         case Chip.IT8726F:
    93           switch (manufacturer) {
    94             case Manufacturer.ASUS:
    95               switch (model) {
    96                 case Model.Crosshair_III_Formula: // IT8720F
    97                   v.Add(new Voltage("VBat", 8));
    98                   t.Add(new Temperature("CPU", 0));
    99                   for (int i = 0; i < superIO.Fans.Length; i++)
   100                     f.Add(new Fan("Fan #" + (i + 1), i));
   101                   break;
   102                 case Model.M2N_SLI_DELUXE:                
   103                   v.Add(new Voltage("CPU VCore", 0));
   104                   v.Add(new Voltage("+3.3V", 1));
   105                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   106                   v.Add(new Voltage("+12V", 4, 30, 10));
   107                   v.Add(new Voltage("+5VSB", 7, 6.8f, 10));
   108                   v.Add(new Voltage("VBat", 8));
   109                   t.Add(new Temperature("CPU", 0));
   110                   t.Add(new Temperature("Motherboard", 1));
   111                   f.Add(new Fan("CPU Fan", 0));
   112                   f.Add(new Fan("Chassis Fan #1", 1));
   113                   f.Add(new Fan("Power Fan", 2));
   114                   break;
   115                 case Model.M4A79XTD_EVO: // IT8720F           
   116                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   117                   v.Add(new Voltage("VBat", 8));
   118                   t.Add(new Temperature("CPU", 0));
   119                   t.Add(new Temperature("Motherboard", 1));
   120                   f.Add(new Fan("CPU Fan", 0));
   121                   f.Add(new Fan("Chassis Fan #1", 1));
   122                   f.Add(new Fan("Chassis Fan #2", 2));
   123                   break;
   124                 default:
   125                   v.Add(new Voltage("CPU VCore", 0));
   126                   v.Add(new Voltage("Voltage #2", 1, true));
   127                   v.Add(new Voltage("Voltage #3", 2, true));
   128                   v.Add(new Voltage("Voltage #4", 3, true));
   129                   v.Add(new Voltage("Voltage #5", 4, true));
   130                   v.Add(new Voltage("Voltage #6", 5, true));
   131                   v.Add(new Voltage("Voltage #7", 6, true));
   132                   v.Add(new Voltage("Voltage #8", 7, true));
   133                   v.Add(new Voltage("VBat", 8));
   134                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   135                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   136                   for (int i = 0; i < superIO.Fans.Length; i++)
   137                     f.Add(new Fan("Fan #" + (i + 1), i));
   138                   break;
   139               }
   140               break;
   141 
   142             case Manufacturer.ASRock:
   143               switch (model) {
   144                 case Model.P55_Deluxe: // IT8720F
   145                   
   146                   v.Add(new Voltage("CPU VCore", 0));
   147                   v.Add(new Voltage("+3.3V", 2));
   148                   v.Add(new Voltage("+12V", 4, 30, 10));
   149                   v.Add(new Voltage("+5V", 5, 6.8f, 10));
   150                   v.Add(new Voltage("VBat", 8));                  
   151                   t.Add(new Temperature("CPU", 0));
   152                   t.Add(new Temperature("Motherboard", 1));
   153                   f.Add(new Fan("CPU Fan", 0));
   154                   f.Add(new Fan("Chassis Fan #1", 1));
   155 
   156                   // this mutex is also used by the official ASRock tool
   157                   mutex = new Mutex(false, "ASRockOCMark");
   158                   
   159                   bool exclusiveAccess = false;
   160                   try {
   161                     exclusiveAccess = mutex.WaitOne(10, false);
   162                   } catch (AbandonedMutexException) { } 
   163                     catch (InvalidOperationException) { }  
   164 
   165                   // only read additional fans if we get exclusive access
   166                   if (exclusiveAccess) {
   167 
   168                     f.Add(new Fan("Chassis Fan #2", 2));
   169                     f.Add(new Fan("Chassis Fan #3", 3));
   170                     f.Add(new Fan("Power Fan", 4));
   171 
   172                     readFan = (index) => {
   173                       if (index < 2) {
   174                         return superIO.Fans[index];
   175                       } else {
   176                         // get GPIO 80-87
   177                         byte? gpio = superIO.ReadGPIO(7);
   178                         if (!gpio.HasValue)
   179                           return null;
   180 
   181                         // read the last 3 fans based on GPIO 83-85
   182                         int[] masks = { 0x05, 0x03, 0x06 };
   183                         return (((gpio.Value >> 3) & 0x07) ==
   184                           masks[index - 2]) ? superIO.Fans[2] : null;
   185                       }
   186                     };
   187 
   188                     int fanIndex = 0;
   189                     postUpdate = () => {
   190                       // get GPIO 80-87
   191                       byte? gpio = superIO.ReadGPIO(7);
   192                       if (!gpio.HasValue)
   193                         return;
   194 
   195                       // prepare the GPIO 83-85 for the next update
   196                       int[] masks = { 0x05, 0x03, 0x06 };
   197                       superIO.WriteGPIO(7,
   198                         (byte)((gpio.Value & 0xC7) | (masks[fanIndex] << 3)));
   199                       fanIndex = (fanIndex + 1) % 3;
   200                     };
   201                   }
   202 
   203                   break;
   204                 default:
   205                   v.Add(new Voltage("CPU VCore", 0));
   206                   v.Add(new Voltage("Voltage #2", 1, true));
   207                   v.Add(new Voltage("Voltage #3", 2, true));
   208                   v.Add(new Voltage("Voltage #4", 3, true));
   209                   v.Add(new Voltage("Voltage #5", 4, true));
   210                   v.Add(new Voltage("Voltage #6", 5, true));
   211                   v.Add(new Voltage("Voltage #7", 6, true));
   212                   v.Add(new Voltage("Voltage #8", 7, true));
   213                   v.Add(new Voltage("VBat", 8));
   214                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   215                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   216                   for (int i = 0; i < superIO.Fans.Length; i++)
   217                     f.Add(new Fan("Fan #" + (i + 1), i));
   218                   break;
   219               };
   220               break;
   221 
   222             case Manufacturer.DFI:
   223               switch (model) {
   224                 case Model.LP_BI_P45_T2RS_Elite: // IT8718F
   225                   v.Add(new Voltage("CPU VCore", 0));
   226                   v.Add(new Voltage("FSB VTT", 1));
   227                   v.Add(new Voltage("+3.3V", 2));
   228                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   229                   v.Add(new Voltage("+12V", 4, 30, 10));
   230                   v.Add(new Voltage("NB Core", 5));
   231                   v.Add(new Voltage("VDIMM", 6));
   232                   v.Add(new Voltage("+5VSB", 7, 6.8f, 10));
   233                   v.Add(new Voltage("VBat", 8));
   234                   t.Add(new Temperature("CPU", 0));
   235                   t.Add(new Temperature("System", 1));
   236                   t.Add(new Temperature("Chipset", 2));
   237                   f.Add(new Fan("Fan #1", 0));
   238                   f.Add(new Fan("Fan #2", 1));
   239                   f.Add(new Fan("Fan #3", 2));
   240                   break;
   241                 case Model.LP_DK_P55_T3eH9: // IT8720F
   242                   v.Add(new Voltage("CPU VCore", 0));
   243                   v.Add(new Voltage("VTT", 1));
   244                   v.Add(new Voltage("+3.3V", 2));
   245                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   246                   v.Add(new Voltage("+12V", 4, 30, 10));
   247                   v.Add(new Voltage("CPU PLL", 5));
   248                   v.Add(new Voltage("DRAM", 6));
   249                   v.Add(new Voltage("+5VSB", 7, 6.8f, 10));
   250                   v.Add(new Voltage("VBat", 8));
   251                   t.Add(new Temperature("Chipset", 0));
   252                   t.Add(new Temperature("CPU PWM", 1));
   253                   t.Add(new Temperature("CPU", 2));
   254                   f.Add(new Fan("Fan #1", 0));
   255                   f.Add(new Fan("Fan #2", 1));
   256                   f.Add(new Fan("Fan #3", 2));
   257                   break;
   258                 default:
   259                   v.Add(new Voltage("CPU VCore", 0));
   260                   v.Add(new Voltage("VTT", 1, true));
   261                   v.Add(new Voltage("+3.3V", 2, true));
   262                   v.Add(new Voltage("+5V", 3, 6.8f, 10, 0, true));
   263                   v.Add(new Voltage("+12V", 4, 30, 10, 0, true));
   264                   v.Add(new Voltage("Voltage #6", 5, true));
   265                   v.Add(new Voltage("DRAM", 6, true));
   266                   v.Add(new Voltage("+5VSB", 7, 6.8f, 10, 0, true));
   267                   v.Add(new Voltage("VBat", 8));
   268                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   269                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   270                   for (int i = 0; i < superIO.Fans.Length; i++)
   271                     f.Add(new Fan("Fan #" + (i + 1), i));
   272                   break;
   273               }
   274               break;
   275 
   276             case Manufacturer.Gigabyte:
   277               switch (model) {
   278                 case Model._965P_S3: // IT8718F
   279                   v.Add(new Voltage("CPU VCore", 0));
   280                   v.Add(new Voltage("DRAM", 1));
   281                   v.Add(new Voltage("+3.3V", 2));
   282                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   283                   v.Add(new Voltage("+12V", 7, 27, 9.1f));
   284                   v.Add(new Voltage("VBat", 8));
   285                   t.Add(new Temperature("System", 0));
   286                   t.Add(new Temperature("CPU", 1));
   287                   f.Add(new Fan("CPU Fan", 0));
   288                   f.Add(new Fan("System Fan", 1));
   289                   break;
   290                 case Model.EP45_DS3R: // IT8718F
   291                 case Model.EP45_UD3R: 
   292                 case Model.X38_DS5:    
   293                   v.Add(new Voltage("CPU VCore", 0));
   294                   v.Add(new Voltage("DRAM", 1));
   295                   v.Add(new Voltage("+3.3V", 2));
   296                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   297                   v.Add(new Voltage("+12V", 7, 27, 9.1f));
   298                   v.Add(new Voltage("VBat", 8));
   299                   t.Add(new Temperature("System", 0));
   300                   t.Add(new Temperature("CPU", 1));
   301                   f.Add(new Fan("CPU Fan", 0));
   302                   f.Add(new Fan("System Fan #2", 1));
   303                   f.Add(new Fan("Power Fan", 2));
   304                   f.Add(new Fan("System Fan #1", 3));
   305                   break;
   306                 case Model.EX58_EXTREME: // IT8720F 
   307                   v.Add(new Voltage("CPU VCore", 0));
   308                   v.Add(new Voltage("DRAM", 1));
   309                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   310                   v.Add(new Voltage("VBat", 8));
   311                   t.Add(new Temperature("System", 0));
   312                   t.Add(new Temperature("CPU", 1));
   313                   t.Add(new Temperature("Northbridge", 2));
   314                   f.Add(new Fan("CPU Fan", 0));
   315                   f.Add(new Fan("System Fan #2", 1));
   316                   f.Add(new Fan("Power Fan", 2));
   317                   f.Add(new Fan("System Fan #1", 3));
   318                   break;
   319                 case Model.P35_DS3: // IT8718F 
   320                 case Model.P35_DS3L: // IT8718F
   321                   v.Add(new Voltage("CPU VCore", 0));
   322                   v.Add(new Voltage("DRAM", 1));
   323                   v.Add(new Voltage("+3.3V", 2));
   324                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   325                   v.Add(new Voltage("+12V", 7, 27, 9.1f));
   326                   v.Add(new Voltage("VBat", 8));
   327                   t.Add(new Temperature("System", 0));
   328                   t.Add(new Temperature("CPU", 1));
   329                   f.Add(new Fan("CPU Fan", 0));
   330                   f.Add(new Fan("System Fan #1", 1));
   331                   f.Add(new Fan("System Fan #2", 2));
   332                   f.Add(new Fan("Power Fan", 3));
   333                   break;
   334                 case Model.P55_UD4: // IT8720F
   335                 case Model.P55M_UD4: // IT8720F
   336                   v.Add(new Voltage("CPU VCore", 0));
   337                   v.Add(new Voltage("DRAM", 1));
   338                   v.Add(new Voltage("+3.3V", 2));
   339                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   340                   v.Add(new Voltage("+12V", 5, 27, 9.1f));
   341                   v.Add(new Voltage("VBat", 8));
   342                   t.Add(new Temperature("System", 0));
   343                   t.Add(new Temperature("CPU", 2));
   344                   f.Add(new Fan("CPU Fan", 0));
   345                   f.Add(new Fan("System Fan #2", 1));
   346                   f.Add(new Fan("Power Fan", 2));
   347                   f.Add(new Fan("System Fan #1", 3));
   348                   break;
   349                 case Model.GA_MA770T_UD3: // IT8720F
   350                   v.Add(new Voltage("CPU VCore", 0));
   351                   v.Add(new Voltage("DRAM", 1));
   352                   v.Add(new Voltage("+3.3V", 2));
   353                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   354                   v.Add(new Voltage("+12V", 4, 27, 9.1f));
   355                   v.Add(new Voltage("VBat", 8));
   356                   t.Add(new Temperature("System", 0));
   357                   t.Add(new Temperature("CPU", 1));
   358                   f.Add(new Fan("CPU Fan", 0));
   359                   f.Add(new Fan("System Fan #1", 1));
   360                   f.Add(new Fan("System Fan #2", 2));
   361                   f.Add(new Fan("Power Fan", 3));
   362                   break;
   363                 case Model.GA_MA785GMT_UD2H: // IT8718F
   364                   v.Add(new Voltage("CPU VCore", 0));
   365                   v.Add(new Voltage("DRAM", 1));
   366                   v.Add(new Voltage("+3.3V", 2));
   367                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   368                   v.Add(new Voltage("+12V", 4, 27, 9.1f));
   369                   v.Add(new Voltage("VBat", 8));
   370                   t.Add(new Temperature("System", 0));
   371                   t.Add(new Temperature("CPU", 1));
   372                   f.Add(new Fan("CPU Fan", 0));
   373                   f.Add(new Fan("System Fan", 1));
   374                   f.Add(new Fan("NB Fan", 2));
   375                   break;
   376                 case Model.X58A_UD3R: // IT8720F 
   377                   v.Add(new Voltage("CPU VCore", 0));
   378                   v.Add(new Voltage("DRAM", 1));
   379                   v.Add(new Voltage("+3.3V", 2));
   380                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   381                   v.Add(new Voltage("+12V", 5, 27, 9.1f));
   382                   v.Add(new Voltage("VBat", 8));
   383                   t.Add(new Temperature("System", 0));
   384                   t.Add(new Temperature("CPU", 1));
   385                   t.Add(new Temperature("Northbridge", 2));
   386                   f.Add(new Fan("CPU Fan", 0));
   387                   f.Add(new Fan("System Fan #2", 1));
   388                   f.Add(new Fan("Power Fan", 2));
   389                   f.Add(new Fan("System Fan #1", 3));
   390                   break;
   391                 default:
   392                   v.Add(new Voltage("CPU VCore", 0));
   393                   v.Add(new Voltage("DRAM", 1, true));
   394                   v.Add(new Voltage("+3.3V", 2, true));
   395                   v.Add(new Voltage("+5V", 3, 6.8f, 10, 0, true));
   396                   v.Add(new Voltage("Voltage #5", 4, true));
   397                   v.Add(new Voltage("Voltage #6", 5, true));
   398                   v.Add(new Voltage("Voltage #7", 6, true));
   399                   v.Add(new Voltage("Voltage #8", 7, true));
   400                   v.Add(new Voltage("VBat", 8));
   401                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   402                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   403                   for (int i = 0; i < superIO.Fans.Length; i++)
   404                     f.Add(new Fan("Fan #" + (i + 1), i));
   405                   break;
   406               }
   407               break;
   408 
   409             default:
   410               v.Add(new Voltage("CPU VCore", 0));
   411               v.Add(new Voltage("Voltage #2", 1, true));
   412               v.Add(new Voltage("Voltage #3", 2, true));
   413               v.Add(new Voltage("Voltage #4", 3, true));
   414               v.Add(new Voltage("Voltage #5", 4, true));
   415               v.Add(new Voltage("Voltage #6", 5, true));
   416               v.Add(new Voltage("Voltage #7", 6, true));
   417               v.Add(new Voltage("Voltage #8", 7, true));
   418               v.Add(new Voltage("VBat", 8));
   419               for (int i = 0; i < superIO.Temperatures.Length; i++)
   420                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   421               for (int i = 0; i < superIO.Fans.Length; i++)
   422                 f.Add(new Fan("Fan #" + (i + 1), i));
   423               break;
   424           }
   425           break;
   426 
   427         case Chip.IT8721F:
   428           switch (manufacturer) {
   429             case Manufacturer.ECS:
   430               switch (model) {
   431                 case Model.A890GXM_A: // IT8721F
   432                   v.Add(new Voltage("CPU VCore", 0));
   433                   v.Add(new Voltage("VDIMM", 1));
   434                   v.Add(new Voltage("NB Voltage", 2));
   435                   v.Add(new Voltage("Analog +3.3V", 3, 10, 10));
   436                   // v.Add(new Voltage("VDIMM", 6, true));
   437                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   438                   v.Add(new Voltage("VBat", 8, 10, 10));
   439                   t.Add(new Temperature("CPU", 0));
   440                   t.Add(new Temperature("System", 1));
   441                   t.Add(new Temperature("Northbridge", 2));
   442                   f.Add(new Fan("CPU Fan", 0));
   443                   f.Add(new Fan("System Fan", 1));
   444                   f.Add(new Fan("Power Fan", 2));
   445                   break;
   446                 default:
   447                   v.Add(new Voltage("Voltage #1", 0, true));
   448                   v.Add(new Voltage("Voltage #2", 1, true));
   449                   v.Add(new Voltage("Voltage #3", 2, true));
   450                   v.Add(new Voltage("Analog +3.3V", 3, 10, 10, 0, true));
   451                   v.Add(new Voltage("Voltage #5", 4, true));
   452                   v.Add(new Voltage("Voltage #6", 5, true));
   453                   v.Add(new Voltage("Voltage #7", 6, true));
   454                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   455                   v.Add(new Voltage("VBat", 8, 10, 10));
   456                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   457                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   458                   for (int i = 0; i < superIO.Fans.Length; i++)
   459                     f.Add(new Fan("Fan #" + (i + 1), i));
   460                   break;
   461               }
   462               break;
   463             default:
   464               v.Add(new Voltage("Voltage #1", 0, true));
   465               v.Add(new Voltage("Voltage #2", 1, true));
   466               v.Add(new Voltage("Voltage #3", 2, true));
   467               v.Add(new Voltage("Analog +3.3V", 3, 10, 10, 0, true));
   468               v.Add(new Voltage("Voltage #5", 4, true));
   469               v.Add(new Voltage("Voltage #6", 5, true));
   470               v.Add(new Voltage("Voltage #7", 6, true));
   471               v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   472               v.Add(new Voltage("VBat", 8, 10, 10));
   473               for (int i = 0; i < superIO.Temperatures.Length; i++)
   474                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   475               for (int i = 0; i < superIO.Fans.Length; i++)
   476                 f.Add(new Fan("Fan #" + (i + 1), i));
   477               break;
   478           }
   479           break;
   480           
   481         case Chip.F71858:
   482           v.Add(new Voltage("VCC3V", 0, 150, 150));
   483           v.Add(new Voltage("VSB3V", 1, 150, 150));
   484           v.Add(new Voltage("Battery", 2, 150, 150));
   485           for (int i = 0; i < superIO.Temperatures.Length; i++)
   486             t.Add(new Temperature("Temperature #" + (i + 1), i));
   487           for (int i = 0; i < superIO.Fans.Length; i++)
   488             f.Add(new Fan("Fan #" + (i + 1), i));
   489           break;
   490         case Chip.F71862: 
   491         case Chip.F71869: 
   492         case Chip.F71882:
   493         case Chip.F71889ED: 
   494         case Chip.F71889F:
   495           switch (manufacturer) {
   496             case Manufacturer.EVGA:
   497               switch (model) {
   498                 case Model.X58_SLI_Classified: // F71882 
   499                   v.Add(new Voltage("VCC3V", 0, 150, 150));
   500                   v.Add(new Voltage("CPU VCore", 1, 47, 100));
   501                   v.Add(new Voltage("DIMM", 2, 47, 100));
   502                   v.Add(new Voltage("CPU VTT", 3, 24, 100));
   503                   v.Add(new Voltage("IOH Vcore", 4, 24, 100));
   504                   v.Add(new Voltage("+5V", 5, 51, 12));
   505                   v.Add(new Voltage("+12V", 6, 56, 6.8f));
   506                   v.Add(new Voltage("3VSB", 7, 150, 150));
   507                   v.Add(new Voltage("VBat", 8, 150, 150));
   508                   t.Add(new Temperature("CPU", 0));
   509                   t.Add(new Temperature("VREG", 1));
   510                   t.Add(new Temperature("System", 2));
   511                   f.Add(new Fan("CPU Fan", 0));
   512                   f.Add(new Fan("Power Fan", 1));
   513                   f.Add(new Fan("Chassis Fan", 2));
   514                   break;
   515                 default:
   516                   v.Add(new Voltage("VCC3V", 0, 150, 150));
   517                   v.Add(new Voltage("CPU VCore", 1));
   518                   v.Add(new Voltage("Voltage #3", 2, true));
   519                   v.Add(new Voltage("Voltage #4", 3, true));
   520                   v.Add(new Voltage("Voltage #5", 4, true));
   521                   v.Add(new Voltage("Voltage #6", 5, true));
   522                   v.Add(new Voltage("Voltage #7", 6, true));
   523                   v.Add(new Voltage("VSB3V", 7, 150, 150));
   524                   v.Add(new Voltage("VBat", 8, 150, 150));
   525                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   526                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   527                   for (int i = 0; i < superIO.Fans.Length; i++)
   528                     f.Add(new Fan("Fan #" + (i + 1), i));
   529                   break;
   530               }
   531               break;
   532             default:
   533               v.Add(new Voltage("VCC3V", 0, 150, 150));
   534               v.Add(new Voltage("CPU VCore", 1));
   535               v.Add(new Voltage("Voltage #3", 2, true));
   536               v.Add(new Voltage("Voltage #4", 3, true));
   537               v.Add(new Voltage("Voltage #5", 4, true));
   538               v.Add(new Voltage("Voltage #6", 5, true));
   539               v.Add(new Voltage("Voltage #7", 6, true));
   540               v.Add(new Voltage("VSB3V", 7, 150, 150));
   541               v.Add(new Voltage("VBat", 8, 150, 150));
   542               for (int i = 0; i < superIO.Temperatures.Length; i++)
   543                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   544               for (int i = 0; i < superIO.Fans.Length; i++)
   545                 f.Add(new Fan("Fan #" + (i + 1), i));
   546               break;
   547           }
   548           break;
   549 
   550         case Chip.W83627EHF:
   551           switch (manufacturer) {
   552             case Manufacturer.ASRock:
   553               switch (model) {
   554                 case Model.AOD790GX_128M: // W83627EHF
   555                   v.Add(new Voltage("CPU VCore", 0));
   556                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   557                   v.Add(new Voltage("+3.3V", 4, 10, 10));
   558                   v.Add(new Voltage("+5V", 5, 20, 10));
   559                   v.Add(new Voltage("+12V", 6, 28, 5));
   560                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   561                   v.Add(new Voltage("VBAT", 8, 34, 34));
   562                   t.Add(new Temperature("CPU", 0));
   563                   t.Add(new Temperature("Motherboard", 2));
   564                   f.Add(new Fan("CPU Fan", 0));
   565                   f.Add(new Fan("Chassis Fan", 1));                 
   566                   break;
   567                 default:
   568                   v.Add(new Voltage("CPU VCore", 0));
   569                   v.Add(new Voltage("Voltage #2", 1, true));
   570                   v.Add(new Voltage("AVCC", 2, 34, 34));
   571                   v.Add(new Voltage("3VCC", 3, 34, 34));
   572                   v.Add(new Voltage("Voltage #5", 4, true));
   573                   v.Add(new Voltage("Voltage #6", 5, true));
   574                   v.Add(new Voltage("Voltage #7", 6, true));
   575                   v.Add(new Voltage("3VSB", 7, 34, 34));
   576                   v.Add(new Voltage("VBAT", 8, 34, 34));
   577                   v.Add(new Voltage("Voltage #10", 9, true));
   578                   t.Add(new Temperature("CPU", 0));
   579                   t.Add(new Temperature("Auxiliary", 1));
   580                   t.Add(new Temperature("System", 2));
   581                   f.Add(new Fan("System Fan", 0));
   582                   f.Add(new Fan("CPU Fan", 1));
   583                   f.Add(new Fan("Auxiliary Fan", 2));
   584                   f.Add(new Fan("CPU Fan #2", 3));
   585                   f.Add(new Fan("Auxiliary Fan #2", 4));
   586                   break;
   587               } break;
   588             default:
   589               v.Add(new Voltage("CPU VCore", 0));
   590               v.Add(new Voltage("Voltage #2", 1, true));
   591               v.Add(new Voltage("AVCC", 2, 34, 34));
   592               v.Add(new Voltage("3VCC", 3, 34, 34));
   593               v.Add(new Voltage("Voltage #5", 4, true));
   594               v.Add(new Voltage("Voltage #6", 5, true));
   595               v.Add(new Voltage("Voltage #7", 6, true));
   596               v.Add(new Voltage("3VSB", 7, 34, 34));
   597               v.Add(new Voltage("VBAT", 8, 34, 34));
   598               v.Add(new Voltage("Voltage #10", 9, true));
   599               t.Add(new Temperature("CPU", 0));
   600               t.Add(new Temperature("Auxiliary", 1));
   601               t.Add(new Temperature("System", 2));
   602               f.Add(new Fan("System Fan", 0));
   603               f.Add(new Fan("CPU Fan", 1));
   604               f.Add(new Fan("Auxiliary Fan", 2));
   605               f.Add(new Fan("CPU Fan #2", 3));
   606               f.Add(new Fan("Auxiliary Fan #2", 4));
   607               break;
   608           }
   609           break;
   610         case Chip.W83627DHG: 
   611         case Chip.W83627DHGP:                      
   612         case Chip.W83667HG:
   613         case Chip.W83667HGB:
   614           switch (manufacturer) {
   615             case Manufacturer.ASRock:
   616               switch (model) {
   617                 case Model._880GMH_USB3: // W83627DHG-P
   618                   v.Add(new Voltage("CPU VCore", 0));
   619                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   620                   v.Add(new Voltage("+5V", 5, 15, 7.5f));
   621                   v.Add(new Voltage("+12V", 6, 56, 10));
   622                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   623                   v.Add(new Voltage("VBAT", 8, 34, 34));
   624                   t.Add(new Temperature("CPU", 0));
   625                   t.Add(new Temperature("Motherboard", 2));
   626                   f.Add(new Fan("Chassis Fan", 0));
   627                   f.Add(new Fan("CPU Fan", 1));
   628                   f.Add(new Fan("Power Fan", 2));
   629                   break;
   630                 default:
   631                   v.Add(new Voltage("CPU VCore", 0));
   632                   v.Add(new Voltage("Voltage #2", 1, true));
   633                   v.Add(new Voltage("AVCC", 2, 34, 34));
   634                   v.Add(new Voltage("3VCC", 3, 34, 34));
   635                   v.Add(new Voltage("Voltage #5", 4, true));
   636                   v.Add(new Voltage("Voltage #6", 5, true));
   637                   v.Add(new Voltage("Voltage #7", 6, true));
   638                   v.Add(new Voltage("3VSB", 7, 34, 34));
   639                   v.Add(new Voltage("VBAT", 8, 34, 34));
   640                   t.Add(new Temperature("CPU", 0));
   641                   t.Add(new Temperature("Auxiliary", 1));
   642                   t.Add(new Temperature("System", 2));
   643                   f.Add(new Fan("System Fan", 0));
   644                   f.Add(new Fan("CPU Fan", 1));
   645                   f.Add(new Fan("Auxiliary Fan", 2));
   646                   f.Add(new Fan("CPU Fan #2", 3));
   647                   f.Add(new Fan("Auxiliary Fan #2", 4));
   648                   break;
   649               }
   650               break;
   651             case Manufacturer.ASUS:
   652               switch (model) {
   653                 case Model.P6X58D_E: // W83667HG                 
   654                 case Model.Rampage_II_GENE: // W83667HG 
   655                   v.Add(new Voltage("CPU VCore", 0));
   656                   v.Add(new Voltage("+12V", 1, 11.5f, 1.91f));
   657                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   658                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   659                   v.Add(new Voltage("+5V", 4, 15, 7.5f));
   660                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   661                   v.Add(new Voltage("VBAT", 8, 34, 34));
   662                   t.Add(new Temperature("CPU", 0));
   663                   t.Add(new Temperature("Motherboard", 2));
   664                   f.Add(new Fan("Chassis Fan #1", 0));
   665                   f.Add(new Fan("CPU Fan", 1));
   666                   f.Add(new Fan("Power Fan", 2));
   667                   f.Add(new Fan("Chassis Fan #2", 3));
   668                   f.Add(new Fan("Chassis Fan #3", 4));
   669                   break;
   670                 case Model.Rampage_Extreme: // W83667HG 
   671                   v.Add(new Voltage("CPU VCore", 0));
   672                   v.Add(new Voltage("+12V", 1, 12, 2));
   673                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   674                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   675                   v.Add(new Voltage("+5V", 4, 15, 7.5f));
   676                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   677                   v.Add(new Voltage("VBAT", 8, 34, 34));
   678                   t.Add(new Temperature("CPU", 0));
   679                   t.Add(new Temperature("Motherboard", 2));
   680                   f.Add(new Fan("Chassis Fan #1", 0));
   681                   f.Add(new Fan("CPU Fan", 1));
   682                   f.Add(new Fan("Power Fan", 2));
   683                   f.Add(new Fan("Chassis Fan #2", 3));
   684                   f.Add(new Fan("Chassis Fan #3", 4));
   685                   break;
   686                 default:
   687                   v.Add(new Voltage("CPU VCore", 0));
   688                   v.Add(new Voltage("Voltage #2", 1, true));
   689                   v.Add(new Voltage("AVCC", 2, 34, 34));
   690                   v.Add(new Voltage("3VCC", 3, 34, 34));
   691                   v.Add(new Voltage("Voltage #5", 4, true));
   692                   v.Add(new Voltage("Voltage #6", 5, true));
   693                   v.Add(new Voltage("Voltage #7", 6, true));
   694                   v.Add(new Voltage("3VSB", 7, 34, 34));
   695                   v.Add(new Voltage("VBAT", 8, 34, 34));
   696                   t.Add(new Temperature("CPU", 0));
   697                   t.Add(new Temperature("Auxiliary", 1));
   698                   t.Add(new Temperature("System", 2));
   699                   f.Add(new Fan("System Fan", 0));
   700                   f.Add(new Fan("CPU Fan", 1));
   701                   f.Add(new Fan("Auxiliary Fan", 2));
   702                   f.Add(new Fan("CPU Fan #2", 3));
   703                   f.Add(new Fan("Auxiliary Fan #2", 4));
   704                   break;
   705               }
   706               break;
   707             default:
   708               v.Add(new Voltage("CPU VCore", 0));
   709               v.Add(new Voltage("Voltage #2", 1, true));
   710               v.Add(new Voltage("AVCC", 2, 34, 34));
   711               v.Add(new Voltage("3VCC", 3, 34, 34));
   712               v.Add(new Voltage("Voltage #5", 4, true));
   713               v.Add(new Voltage("Voltage #6", 5, true));
   714               v.Add(new Voltage("Voltage #7", 6, true));
   715               v.Add(new Voltage("3VSB", 7, 34, 34));
   716               v.Add(new Voltage("VBAT", 8, 34, 34));
   717               t.Add(new Temperature("CPU", 0));
   718               t.Add(new Temperature("Auxiliary", 1));
   719               t.Add(new Temperature("System", 2));
   720               f.Add(new Fan("System Fan", 0));
   721               f.Add(new Fan("CPU Fan", 1));
   722               f.Add(new Fan("Auxiliary Fan", 2));
   723               f.Add(new Fan("CPU Fan #2", 3));
   724               f.Add(new Fan("Auxiliary Fan #2", 4));
   725               break;
   726           } 
   727           break;
   728         case Chip.W83627HF: 
   729         case Chip.W83627THF: 
   730         case Chip.W83687THF:
   731           v.Add(new Voltage("CPU VCore", 0));
   732           v.Add(new Voltage("Voltage #2", 1, true));
   733           v.Add(new Voltage("Voltage #3", 2, true));
   734           v.Add(new Voltage("AVCC", 3, 34, 51));
   735           v.Add(new Voltage("Voltage #5", 4, true));
   736           v.Add(new Voltage("5VSB", 5, 34, 51));
   737           v.Add(new Voltage("VBAT", 6));
   738           t.Add(new Temperature("CPU", 0));
   739           t.Add(new Temperature("Auxiliary", 1));
   740           t.Add(new Temperature("System", 2));
   741           f.Add(new Fan("System Fan", 0));
   742           f.Add(new Fan("CPU Fan", 1));
   743           f.Add(new Fan("Auxiliary Fan", 2));
   744           break;
   745         case Chip.NCT6771F:
   746         case Chip.NCT6776F:
   747           switch (manufacturer) {
   748             case Manufacturer.ASUS:
   749               switch (model) {
   750                 case Model.P8P67_PRO: // NCT6776F
   751                   v.Add(new Voltage("CPU VCore", 0));
   752                   v.Add(new Voltage("Voltage #2", 1, true));
   753                   v.Add(new Voltage("AVCC", 2, 34, 34));
   754                   v.Add(new Voltage("3VCC", 3, 34, 34));
   755                   v.Add(new Voltage("Voltage #5", 4, true));
   756                   v.Add(new Voltage("Voltage #6", 5, true));
   757                   v.Add(new Voltage("Voltage #7", 6, true));
   758                   v.Add(new Voltage("3VSB", 7, 34, 34));
   759                   v.Add(new Voltage("VBAT", 8, 34, 34));
   760                   t.Add(new Temperature("CPU", 1));
   761                   t.Add(new Temperature("Auxiliary", 2));
   762                   t.Add(new Temperature("System", 3));
   763                   f.Add(new Fan("System Fan", 0));
   764                   f.Add(new Fan("CPU Fan", 1));
   765                   f.Add(new Fan("Auxiliary Fan", 2));
   766                   f.Add(new Fan("Auxiliary Fan #2", 3));
   767                   f.Add(new Fan("Auxiliary Fan #3", 4));
   768                   break;
   769                 case Model.P8P67_M_PRO: // NCT6776F
   770                   v.Add(new Voltage("CPU VCore", 0));
   771                   v.Add(new Voltage("+12V", 1, 11, 1));
   772                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   773                   v.Add(new Voltage("+3V", 3, 34, 34));
   774                   v.Add(new Voltage("+5V", 4, 12, 3));
   775                   v.Add(new Voltage("Voltage #6", 5, true));
   776                   v.Add(new Voltage("Voltage #7", 6, true));
   777                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   778                   v.Add(new Voltage("VBAT", 8, 34, 34));
   779                   t.Add(new Temperature("CPU", 0));
   780                   t.Add(new Temperature("Motherboard", 3));
   781                   f.Add(new Fan("Chassis Fan #1", 0));
   782                   f.Add(new Fan("CPU Fan", 1));
   783                   f.Add(new Fan("Chassis Fan #2", 2));
   784                   f.Add(new Fan("Power Fan", 3));
   785                   f.Add(new Fan("Auxiliary Fan", 4));
   786                   break;
   787                 default:
   788                   v.Add(new Voltage("CPU VCore", 0));
   789                   v.Add(new Voltage("Voltage #2", 1, true));
   790                   v.Add(new Voltage("AVCC", 2, 34, 34));
   791                   v.Add(new Voltage("3VCC", 3, 34, 34));
   792                   v.Add(new Voltage("Voltage #5", 4, true));
   793                   v.Add(new Voltage("Voltage #6", 5, true));
   794                   v.Add(new Voltage("Voltage #7", 6, true));
   795                   v.Add(new Voltage("3VSB", 7, 34, 34));
   796                   v.Add(new Voltage("VBAT", 8, 34, 34));
   797                   t.Add(new Temperature("CPU", 0));
   798                   t.Add(new Temperature("CPU", 1));
   799                   t.Add(new Temperature("Auxiliary", 2));
   800                   t.Add(new Temperature("System", 3));
   801                   for (int i = 0; i < superIO.Fans.Length; i++)
   802                     f.Add(new Fan("Fan #" + (i + 1), i));
   803                   break;
   804               }
   805               break;
   806             default:
   807               v.Add(new Voltage("CPU VCore", 0));
   808               v.Add(new Voltage("Voltage #2", 1, true));
   809               v.Add(new Voltage("AVCC", 2, 34, 34));
   810               v.Add(new Voltage("3VCC", 3, 34, 34));
   811               v.Add(new Voltage("Voltage #5", 4, true));
   812               v.Add(new Voltage("Voltage #6", 5, true));
   813               v.Add(new Voltage("Voltage #7", 6, true));
   814               v.Add(new Voltage("3VSB", 7, 34, 34));
   815               v.Add(new Voltage("VBAT", 8, 34, 34));
   816               t.Add(new Temperature("CPU", 0));
   817               t.Add(new Temperature("CPU", 1));
   818               t.Add(new Temperature("Auxiliary", 2));
   819               t.Add(new Temperature("System", 3));
   820               for (int i = 0; i < superIO.Fans.Length; i++)
   821                 f.Add(new Fan("Fan #" + (i + 1), i));
   822               break;
   823           }
   824           break;
   825         default:
   826           for (int i = 0; i < superIO.Voltages.Length; i++)
   827             v.Add(new Voltage("Voltage #" + (i + 1), i, true));
   828           for (int i = 0; i < superIO.Temperatures.Length; i++)
   829             t.Add(new Temperature("Temperature #" + (i + 1), i));
   830           for (int i = 0; i < superIO.Fans.Length; i++)
   831             f.Add(new Fan("Fan #" + (i + 1), i));
   832           break;
   833       }
   834 
   835       const string formula = "Voltage = value + (value - Vf) * Ri / Rf.";
   836       foreach (Voltage voltage in v) 
   837         if (voltage.Index < superIO.Voltages.Length) {
   838           Sensor sensor = new Sensor(voltage.Name, voltage.Index, 
   839             voltage.Hidden, SensorType.Voltage, this, new [] {
   840             new ParameterDescription("Ri [kΩ]", "Input resistance.\n" + 
   841               formula, voltage.Ri),
   842             new ParameterDescription("Rf [kΩ]", "Reference resistance.\n" + 
   843               formula, voltage.Rf),
   844             new ParameterDescription("Vf [V]", "Reference voltage.\n" + 
   845               formula, voltage.Vf)
   846             }, settings);
   847           voltages.Add(sensor);
   848       }
   849 
   850       foreach (Temperature temperature in t) 
   851         if (temperature.Index < superIO.Temperatures.Length) {
   852         Sensor sensor = new Sensor(temperature.Name, temperature.Index,
   853           SensorType.Temperature, this, new [] {
   854           new ParameterDescription("Offset [°C]", "Temperature offset.", 0)
   855         }, settings);
   856         temperatures.Add(sensor);
   857       }
   858 
   859       foreach (Fan fan in f)
   860         if (fan.Index < superIO.Fans.Length) {
   861           Sensor sensor = new Sensor(fan.Name, fan.Index, SensorType.Fan,
   862             this, settings);
   863           fans.Add(sensor);
   864         }
   865     }
   866 
   867     public override HardwareType HardwareType {
   868       get { return HardwareType.SuperIO; }
   869     }
   870 
   871     public override IHardware Parent {
   872       get { return mainboard; }
   873     }
   874 
   875 
   876     public override string GetReport() {
   877       return superIO.GetReport();
   878     }
   879 
   880     public override void Update() {
   881       superIO.Update();
   882 
   883       foreach (Sensor sensor in voltages) {
   884         float? value = readVoltage(sensor.Index);
   885         if (value.HasValue) {
   886           sensor.Value = value + (value - sensor.Parameters[2].Value) *
   887             sensor.Parameters[0].Value / sensor.Parameters[1].Value;
   888           ActivateSensor(sensor);
   889         }
   890       }
   891 
   892       foreach (Sensor sensor in temperatures) {
   893         float? value = readTemperature(sensor.Index);
   894         if (value.HasValue) {
   895           sensor.Value = value + sensor.Parameters[0].Value;
   896           ActivateSensor(sensor);
   897         }
   898       }
   899 
   900       foreach (Sensor sensor in fans) {
   901         float? value = readFan(sensor.Index);
   902         if (value.HasValue) {
   903           sensor.Value = value;
   904           if (value.Value > 0)
   905             ActivateSensor(sensor);
   906         }
   907       }
   908 
   909       postUpdate();
   910     }
   911 
   912     private class Voltage {
   913       public readonly string Name;
   914       public readonly int Index;
   915       public readonly float Ri;
   916       public readonly float Rf;
   917       public readonly float Vf;
   918       public readonly bool Hidden;
   919 
   920       public Voltage(string name, int index) :
   921         this(name, index, false) { }
   922       
   923       public Voltage(string name, int index, bool hidden) :
   924         this(name, index, 0, 1, 0, hidden) { }
   925       
   926       public Voltage(string name, int index, float ri, float rf) :
   927         this(name, index, ri, rf, 0, false) { }
   928       
   929       // float ri = 0, float rf = 1, float vf = 0, bool hidden = false) 
   930       
   931       public Voltage(string name, int index, 
   932         float ri, float rf, float vf, bool hidden) 
   933       {
   934         this.Name = name;
   935         this.Index = index;
   936         this.Ri = ri;
   937         this.Rf = rf;
   938         this.Vf = vf;
   939         this.Hidden = hidden;
   940       }
   941     }
   942 
   943     private class Temperature {
   944       public readonly string Name;
   945       public readonly int Index;
   946 
   947       public Temperature(string name, int index) {
   948         this.Name = name;
   949         this.Index = index;
   950       }
   951     }
   952 
   953     private class Fan {
   954       public readonly string Name;
   955       public readonly int Index;
   956 
   957       public Fan(string name, int index) {
   958         this.Name = name;
   959         this.Index = index;
   960       }
   961     }
   962   }
   963 }