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