Hardware/Mainboard/SuperIOHardware.cs
author moel.mich
Sun, 15 May 2011 17:21:27 +0000
changeset 286 48d7e8d6c0db
parent 277 5c80f37c0330
child 290 22214a7e85a9
permissions -rw-r--r--
Fixed Issue 204.
     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         case Chip.IT8728F:
   429           switch (manufacturer) {
   430             case Manufacturer.ECS:
   431               switch (model) {
   432                 case Model.A890GXM_A: // IT8721F
   433                   v.Add(new Voltage("CPU VCore", 0));
   434                   v.Add(new Voltage("VDIMM", 1));
   435                   v.Add(new Voltage("NB Voltage", 2));
   436                   v.Add(new Voltage("Analog +3.3V", 3, 10, 10));
   437                   // v.Add(new Voltage("VDIMM", 6, true));
   438                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   439                   v.Add(new Voltage("VBat", 8, 10, 10));
   440                   t.Add(new Temperature("CPU", 0));
   441                   t.Add(new Temperature("System", 1));
   442                   t.Add(new Temperature("Northbridge", 2));
   443                   f.Add(new Fan("CPU Fan", 0));
   444                   f.Add(new Fan("System Fan", 1));
   445                   f.Add(new Fan("Power Fan", 2));
   446                   break;
   447                 default:
   448                   v.Add(new Voltage("Voltage #1", 0, true));
   449                   v.Add(new Voltage("Voltage #2", 1, true));
   450                   v.Add(new Voltage("Voltage #3", 2, true));
   451                   v.Add(new Voltage("Analog +3.3V", 3, 10, 10, 0, true));
   452                   v.Add(new Voltage("Voltage #5", 4, true));
   453                   v.Add(new Voltage("Voltage #6", 5, true));
   454                   v.Add(new Voltage("Voltage #7", 6, true));
   455                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   456                   v.Add(new Voltage("VBat", 8, 10, 10));
   457                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   458                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   459                   for (int i = 0; i < superIO.Fans.Length; i++)
   460                     f.Add(new Fan("Fan #" + (i + 1), i));
   461                   break;
   462               }
   463               break;
   464             case Manufacturer.Gigabyte:
   465               switch (model) {
   466                 case Model.P67A_UD4_B3:
   467                   v.Add(new Voltage("+12V", 0, 100, 10));
   468                   v.Add(new Voltage("+5V", 1, 15, 10));
   469                   v.Add(new Voltage("Voltage #3", 2, true));
   470                   v.Add(new Voltage("Voltage #4", 3, true));
   471                   v.Add(new Voltage("Voltage #5", 4, true));
   472                   v.Add(new Voltage("CPU VCore", 5));
   473                   v.Add(new Voltage("DRAM", 6));
   474                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   475                   v.Add(new Voltage("VBat", 8, 10, 10));
   476                   t.Add(new Temperature("System", 0));
   477                   t.Add(new Temperature("CPU", 2));
   478                   f.Add(new Fan("CPU Fan", 0));
   479                   f.Add(new Fan("System Fan #2", 1));
   480                   f.Add(new Fan("Power Fan", 2));
   481                   f.Add(new Fan("System Fan #1", 3));
   482                   break;
   483                 default:
   484                   v.Add(new Voltage("Voltage #1", 0, true));
   485                   v.Add(new Voltage("Voltage #2", 1, true));
   486                   v.Add(new Voltage("Voltage #3", 2, true));
   487                   v.Add(new Voltage("Voltage #4", 3, true));
   488                   v.Add(new Voltage("Voltage #5", 4, true));
   489                   v.Add(new Voltage("Voltage #6", 5, true));
   490                   v.Add(new Voltage("Voltage #7", 6, true));
   491                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   492                   v.Add(new Voltage("VBat", 8, 10, 10));
   493                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   494                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   495                   for (int i = 0; i < superIO.Fans.Length; i++)
   496                     f.Add(new Fan("Fan #" + (i + 1), i));
   497                   break;
   498               }
   499               break;
   500             default:
   501               v.Add(new Voltage("Voltage #1", 0, true));
   502               v.Add(new Voltage("Voltage #2", 1, true));
   503               v.Add(new Voltage("Voltage #3", 2, true));
   504               v.Add(new Voltage("Voltage #4", 3, true));
   505               v.Add(new Voltage("Voltage #5", 4, true));
   506               v.Add(new Voltage("Voltage #6", 5, true));
   507               v.Add(new Voltage("Voltage #7", 6, true));
   508               v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   509               v.Add(new Voltage("VBat", 8, 10, 10));
   510               for (int i = 0; i < superIO.Temperatures.Length; i++)
   511                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   512               for (int i = 0; i < superIO.Fans.Length; i++)
   513                 f.Add(new Fan("Fan #" + (i + 1), i));
   514               break;
   515           }
   516           break;
   517           
   518         case Chip.F71858:
   519           v.Add(new Voltage("VCC3V", 0, 150, 150));
   520           v.Add(new Voltage("VSB3V", 1, 150, 150));
   521           v.Add(new Voltage("Battery", 2, 150, 150));
   522           for (int i = 0; i < superIO.Temperatures.Length; i++)
   523             t.Add(new Temperature("Temperature #" + (i + 1), i));
   524           for (int i = 0; i < superIO.Fans.Length; i++)
   525             f.Add(new Fan("Fan #" + (i + 1), i));
   526           break;
   527         case Chip.F71862: 
   528         case Chip.F71869: 
   529         case Chip.F71882:
   530         case Chip.F71889ED: 
   531         case Chip.F71889F:
   532           switch (manufacturer) {
   533             case Manufacturer.EVGA:
   534               switch (model) {
   535                 case Model.X58_SLI_Classified: // F71882 
   536                   v.Add(new Voltage("VCC3V", 0, 150, 150));
   537                   v.Add(new Voltage("CPU VCore", 1, 47, 100));
   538                   v.Add(new Voltage("DIMM", 2, 47, 100));
   539                   v.Add(new Voltage("CPU VTT", 3, 24, 100));
   540                   v.Add(new Voltage("IOH Vcore", 4, 24, 100));
   541                   v.Add(new Voltage("+5V", 5, 51, 12));
   542                   v.Add(new Voltage("+12V", 6, 56, 6.8f));
   543                   v.Add(new Voltage("3VSB", 7, 150, 150));
   544                   v.Add(new Voltage("VBat", 8, 150, 150));
   545                   t.Add(new Temperature("CPU", 0));
   546                   t.Add(new Temperature("VREG", 1));
   547                   t.Add(new Temperature("System", 2));
   548                   f.Add(new Fan("CPU Fan", 0));
   549                   f.Add(new Fan("Power Fan", 1));
   550                   f.Add(new Fan("Chassis Fan", 2));
   551                   break;
   552                 default:
   553                   v.Add(new Voltage("VCC3V", 0, 150, 150));
   554                   v.Add(new Voltage("CPU VCore", 1));
   555                   v.Add(new Voltage("Voltage #3", 2, true));
   556                   v.Add(new Voltage("Voltage #4", 3, true));
   557                   v.Add(new Voltage("Voltage #5", 4, true));
   558                   v.Add(new Voltage("Voltage #6", 5, true));
   559                   v.Add(new Voltage("Voltage #7", 6, true));
   560                   v.Add(new Voltage("VSB3V", 7, 150, 150));
   561                   v.Add(new Voltage("VBat", 8, 150, 150));
   562                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   563                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   564                   for (int i = 0; i < superIO.Fans.Length; i++)
   565                     f.Add(new Fan("Fan #" + (i + 1), i));
   566                   break;
   567               }
   568               break;
   569             default:
   570               v.Add(new Voltage("VCC3V", 0, 150, 150));
   571               v.Add(new Voltage("CPU VCore", 1));
   572               v.Add(new Voltage("Voltage #3", 2, true));
   573               v.Add(new Voltage("Voltage #4", 3, true));
   574               v.Add(new Voltage("Voltage #5", 4, true));
   575               v.Add(new Voltage("Voltage #6", 5, true));
   576               v.Add(new Voltage("Voltage #7", 6, true));
   577               v.Add(new Voltage("VSB3V", 7, 150, 150));
   578               v.Add(new Voltage("VBat", 8, 150, 150));
   579               for (int i = 0; i < superIO.Temperatures.Length; i++)
   580                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   581               for (int i = 0; i < superIO.Fans.Length; i++)
   582                 f.Add(new Fan("Fan #" + (i + 1), i));
   583               break;
   584           }
   585           break;
   586 
   587         case Chip.W83627EHF:
   588           switch (manufacturer) {
   589             case Manufacturer.ASRock:
   590               switch (model) {
   591                 case Model.AOD790GX_128M: // W83627EHF
   592                   v.Add(new Voltage("CPU VCore", 0));
   593                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   594                   v.Add(new Voltage("+3.3V", 4, 10, 10));
   595                   v.Add(new Voltage("+5V", 5, 20, 10));
   596                   v.Add(new Voltage("+12V", 6, 28, 5));
   597                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   598                   v.Add(new Voltage("VBAT", 8, 34, 34));
   599                   t.Add(new Temperature("CPU", 0));
   600                   t.Add(new Temperature("Motherboard", 2));
   601                   f.Add(new Fan("CPU Fan", 0));
   602                   f.Add(new Fan("Chassis Fan", 1));                 
   603                   break;
   604                 default:
   605                   v.Add(new Voltage("CPU VCore", 0));
   606                   v.Add(new Voltage("Voltage #2", 1, true));
   607                   v.Add(new Voltage("AVCC", 2, 34, 34));
   608                   v.Add(new Voltage("3VCC", 3, 34, 34));
   609                   v.Add(new Voltage("Voltage #5", 4, true));
   610                   v.Add(new Voltage("Voltage #6", 5, true));
   611                   v.Add(new Voltage("Voltage #7", 6, true));
   612                   v.Add(new Voltage("3VSB", 7, 34, 34));
   613                   v.Add(new Voltage("VBAT", 8, 34, 34));
   614                   v.Add(new Voltage("Voltage #10", 9, true));
   615                   t.Add(new Temperature("CPU", 0));
   616                   t.Add(new Temperature("Auxiliary", 1));
   617                   t.Add(new Temperature("System", 2));
   618                   f.Add(new Fan("System Fan", 0));
   619                   f.Add(new Fan("CPU Fan", 1));
   620                   f.Add(new Fan("Auxiliary Fan", 2));
   621                   f.Add(new Fan("CPU Fan #2", 3));
   622                   f.Add(new Fan("Auxiliary Fan #2", 4));
   623                   break;
   624               } break;
   625             default:
   626               v.Add(new Voltage("CPU VCore", 0));
   627               v.Add(new Voltage("Voltage #2", 1, true));
   628               v.Add(new Voltage("AVCC", 2, 34, 34));
   629               v.Add(new Voltage("3VCC", 3, 34, 34));
   630               v.Add(new Voltage("Voltage #5", 4, true));
   631               v.Add(new Voltage("Voltage #6", 5, true));
   632               v.Add(new Voltage("Voltage #7", 6, true));
   633               v.Add(new Voltage("3VSB", 7, 34, 34));
   634               v.Add(new Voltage("VBAT", 8, 34, 34));
   635               v.Add(new Voltage("Voltage #10", 9, true));
   636               t.Add(new Temperature("CPU", 0));
   637               t.Add(new Temperature("Auxiliary", 1));
   638               t.Add(new Temperature("System", 2));
   639               f.Add(new Fan("System Fan", 0));
   640               f.Add(new Fan("CPU Fan", 1));
   641               f.Add(new Fan("Auxiliary Fan", 2));
   642               f.Add(new Fan("CPU Fan #2", 3));
   643               f.Add(new Fan("Auxiliary Fan #2", 4));
   644               break;
   645           }
   646           break;
   647         case Chip.W83627DHG: 
   648         case Chip.W83627DHGP:                      
   649         case Chip.W83667HG:
   650         case Chip.W83667HGB:
   651           switch (manufacturer) {
   652             case Manufacturer.ASRock:
   653               switch (model) {
   654                 case Model._880GMH_USB3: // W83627DHG-P
   655                   v.Add(new Voltage("CPU VCore", 0));
   656                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   657                   v.Add(new Voltage("+5V", 5, 15, 7.5f));
   658                   v.Add(new Voltage("+12V", 6, 56, 10));
   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", 0));
   664                   f.Add(new Fan("CPU Fan", 1));
   665                   f.Add(new Fan("Power Fan", 2));
   666                   break;
   667                 default:
   668                   v.Add(new Voltage("CPU VCore", 0));
   669                   v.Add(new Voltage("Voltage #2", 1, true));
   670                   v.Add(new Voltage("AVCC", 2, 34, 34));
   671                   v.Add(new Voltage("3VCC", 3, 34, 34));
   672                   v.Add(new Voltage("Voltage #5", 4, true));
   673                   v.Add(new Voltage("Voltage #6", 5, true));
   674                   v.Add(new Voltage("Voltage #7", 6, true));
   675                   v.Add(new Voltage("3VSB", 7, 34, 34));
   676                   v.Add(new Voltage("VBAT", 8, 34, 34));
   677                   t.Add(new Temperature("CPU", 0));
   678                   t.Add(new Temperature("Auxiliary", 1));
   679                   t.Add(new Temperature("System", 2));
   680                   f.Add(new Fan("System Fan", 0));
   681                   f.Add(new Fan("CPU Fan", 1));
   682                   f.Add(new Fan("Auxiliary Fan", 2));
   683                   f.Add(new Fan("CPU Fan #2", 3));
   684                   f.Add(new Fan("Auxiliary Fan #2", 4));
   685                   break;
   686               }
   687               break;
   688             case Manufacturer.ASUS:
   689               switch (model) {
   690                 case Model.P6X58D_E: // W83667HG                 
   691                 case Model.Rampage_II_GENE: // W83667HG 
   692                   v.Add(new Voltage("CPU VCore", 0));
   693                   v.Add(new Voltage("+12V", 1, 11.5f, 1.91f));
   694                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   695                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   696                   v.Add(new Voltage("+5V", 4, 15, 7.5f));
   697                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   698                   v.Add(new Voltage("VBAT", 8, 34, 34));
   699                   t.Add(new Temperature("CPU", 0));
   700                   t.Add(new Temperature("Motherboard", 2));
   701                   f.Add(new Fan("Chassis Fan #1", 0));
   702                   f.Add(new Fan("CPU Fan", 1));
   703                   f.Add(new Fan("Power Fan", 2));
   704                   f.Add(new Fan("Chassis Fan #2", 3));
   705                   f.Add(new Fan("Chassis Fan #3", 4));
   706                   break;
   707                 case Model.Rampage_Extreme: // W83667HG 
   708                   v.Add(new Voltage("CPU VCore", 0));
   709                   v.Add(new Voltage("+12V", 1, 12, 2));
   710                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   711                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   712                   v.Add(new Voltage("+5V", 4, 15, 7.5f));
   713                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   714                   v.Add(new Voltage("VBAT", 8, 34, 34));
   715                   t.Add(new Temperature("CPU", 0));
   716                   t.Add(new Temperature("Motherboard", 2));
   717                   f.Add(new Fan("Chassis Fan #1", 0));
   718                   f.Add(new Fan("CPU Fan", 1));
   719                   f.Add(new Fan("Power Fan", 2));
   720                   f.Add(new Fan("Chassis Fan #2", 3));
   721                   f.Add(new Fan("Chassis Fan #3", 4));
   722                   break;
   723                 default:
   724                   v.Add(new Voltage("CPU VCore", 0));
   725                   v.Add(new Voltage("Voltage #2", 1, true));
   726                   v.Add(new Voltage("AVCC", 2, 34, 34));
   727                   v.Add(new Voltage("3VCC", 3, 34, 34));
   728                   v.Add(new Voltage("Voltage #5", 4, true));
   729                   v.Add(new Voltage("Voltage #6", 5, true));
   730                   v.Add(new Voltage("Voltage #7", 6, true));
   731                   v.Add(new Voltage("3VSB", 7, 34, 34));
   732                   v.Add(new Voltage("VBAT", 8, 34, 34));
   733                   t.Add(new Temperature("CPU", 0));
   734                   t.Add(new Temperature("Auxiliary", 1));
   735                   t.Add(new Temperature("System", 2));
   736                   f.Add(new Fan("System Fan", 0));
   737                   f.Add(new Fan("CPU Fan", 1));
   738                   f.Add(new Fan("Auxiliary Fan", 2));
   739                   f.Add(new Fan("CPU Fan #2", 3));
   740                   f.Add(new Fan("Auxiliary Fan #2", 4));
   741                   break;
   742               }
   743               break;
   744             default:
   745               v.Add(new Voltage("CPU VCore", 0));
   746               v.Add(new Voltage("Voltage #2", 1, true));
   747               v.Add(new Voltage("AVCC", 2, 34, 34));
   748               v.Add(new Voltage("3VCC", 3, 34, 34));
   749               v.Add(new Voltage("Voltage #5", 4, true));
   750               v.Add(new Voltage("Voltage #6", 5, true));
   751               v.Add(new Voltage("Voltage #7", 6, true));
   752               v.Add(new Voltage("3VSB", 7, 34, 34));
   753               v.Add(new Voltage("VBAT", 8, 34, 34));
   754               t.Add(new Temperature("CPU", 0));
   755               t.Add(new Temperature("Auxiliary", 1));
   756               t.Add(new Temperature("System", 2));
   757               f.Add(new Fan("System Fan", 0));
   758               f.Add(new Fan("CPU Fan", 1));
   759               f.Add(new Fan("Auxiliary Fan", 2));
   760               f.Add(new Fan("CPU Fan #2", 3));
   761               f.Add(new Fan("Auxiliary Fan #2", 4));
   762               break;
   763           } 
   764           break;
   765         case Chip.W83627HF: 
   766         case Chip.W83627THF: 
   767         case Chip.W83687THF:
   768           v.Add(new Voltage("CPU VCore", 0));
   769           v.Add(new Voltage("Voltage #2", 1, true));
   770           v.Add(new Voltage("Voltage #3", 2, true));
   771           v.Add(new Voltage("AVCC", 3, 34, 51));
   772           v.Add(new Voltage("Voltage #5", 4, true));
   773           v.Add(new Voltage("5VSB", 5, 34, 51));
   774           v.Add(new Voltage("VBAT", 6));
   775           t.Add(new Temperature("CPU", 0));
   776           t.Add(new Temperature("Auxiliary", 1));
   777           t.Add(new Temperature("System", 2));
   778           f.Add(new Fan("System Fan", 0));
   779           f.Add(new Fan("CPU Fan", 1));
   780           f.Add(new Fan("Auxiliary Fan", 2));
   781           break;
   782         case Chip.NCT6771F:
   783         case Chip.NCT6776F:
   784           switch (manufacturer) {
   785             case Manufacturer.ASUS:
   786               switch (model) {
   787                 case Model.P8P67_PRO: // NCT6776F
   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", 1));
   798                   t.Add(new Temperature("Auxiliary", 2));
   799                   t.Add(new Temperature("System", 3));
   800                   f.Add(new Fan("System Fan", 0));
   801                   f.Add(new Fan("CPU Fan", 1));
   802                   f.Add(new Fan("Auxiliary Fan", 2));
   803                   f.Add(new Fan("Auxiliary Fan #2", 3));
   804                   f.Add(new Fan("Auxiliary Fan #3", 4));
   805                   break;
   806                 case Model.P8P67_M_PRO: // NCT6776F
   807                   v.Add(new Voltage("CPU VCore", 0));
   808                   v.Add(new Voltage("+12V", 1, 11, 1));
   809                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   810                   v.Add(new Voltage("+3V", 3, 34, 34));
   811                   v.Add(new Voltage("+5V", 4, 12, 3));
   812                   v.Add(new Voltage("Voltage #6", 5, true));
   813                   v.Add(new Voltage("Voltage #7", 6, true));
   814                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   815                   v.Add(new Voltage("VBAT", 8, 34, 34));
   816                   t.Add(new Temperature("CPU", 0));
   817                   t.Add(new Temperature("Motherboard", 3));
   818                   f.Add(new Fan("Chassis Fan #1", 0));
   819                   f.Add(new Fan("CPU Fan", 1));
   820                   f.Add(new Fan("Chassis Fan #2", 2));
   821                   f.Add(new Fan("Power Fan", 3));
   822                   f.Add(new Fan("Auxiliary Fan", 4));
   823                   break;
   824                 default:
   825                   v.Add(new Voltage("CPU VCore", 0));
   826                   v.Add(new Voltage("Voltage #2", 1, true));
   827                   v.Add(new Voltage("AVCC", 2, 34, 34));
   828                   v.Add(new Voltage("3VCC", 3, 34, 34));
   829                   v.Add(new Voltage("Voltage #5", 4, true));
   830                   v.Add(new Voltage("Voltage #6", 5, true));
   831                   v.Add(new Voltage("Voltage #7", 6, true));
   832                   v.Add(new Voltage("3VSB", 7, 34, 34));
   833                   v.Add(new Voltage("VBAT", 8, 34, 34));
   834                   t.Add(new Temperature("CPU", 0));
   835                   t.Add(new Temperature("CPU", 1));
   836                   t.Add(new Temperature("Auxiliary", 2));
   837                   t.Add(new Temperature("System", 3));
   838                   for (int i = 0; i < superIO.Fans.Length; i++)
   839                     f.Add(new Fan("Fan #" + (i + 1), i));
   840                   break;
   841               }
   842               break;
   843             default:
   844               v.Add(new Voltage("CPU VCore", 0));
   845               v.Add(new Voltage("Voltage #2", 1, true));
   846               v.Add(new Voltage("AVCC", 2, 34, 34));
   847               v.Add(new Voltage("3VCC", 3, 34, 34));
   848               v.Add(new Voltage("Voltage #5", 4, true));
   849               v.Add(new Voltage("Voltage #6", 5, true));
   850               v.Add(new Voltage("Voltage #7", 6, true));
   851               v.Add(new Voltage("3VSB", 7, 34, 34));
   852               v.Add(new Voltage("VBAT", 8, 34, 34));
   853               t.Add(new Temperature("CPU", 0));
   854               t.Add(new Temperature("CPU", 1));
   855               t.Add(new Temperature("Auxiliary", 2));
   856               t.Add(new Temperature("System", 3));
   857               for (int i = 0; i < superIO.Fans.Length; i++)
   858                 f.Add(new Fan("Fan #" + (i + 1), i));
   859               break;
   860           }
   861           break;
   862         default:
   863           for (int i = 0; i < superIO.Voltages.Length; i++)
   864             v.Add(new Voltage("Voltage #" + (i + 1), i, true));
   865           for (int i = 0; i < superIO.Temperatures.Length; i++)
   866             t.Add(new Temperature("Temperature #" + (i + 1), i));
   867           for (int i = 0; i < superIO.Fans.Length; i++)
   868             f.Add(new Fan("Fan #" + (i + 1), i));
   869           break;
   870       }
   871 
   872       const string formula = "Voltage = value + (value - Vf) * Ri / Rf.";
   873       foreach (Voltage voltage in v) 
   874         if (voltage.Index < superIO.Voltages.Length) {
   875           Sensor sensor = new Sensor(voltage.Name, voltage.Index, 
   876             voltage.Hidden, SensorType.Voltage, this, new [] {
   877             new ParameterDescription("Ri [kΩ]", "Input resistance.\n" + 
   878               formula, voltage.Ri),
   879             new ParameterDescription("Rf [kΩ]", "Reference resistance.\n" + 
   880               formula, voltage.Rf),
   881             new ParameterDescription("Vf [V]", "Reference voltage.\n" + 
   882               formula, voltage.Vf)
   883             }, settings);
   884           voltages.Add(sensor);
   885       }
   886 
   887       foreach (Temperature temperature in t) 
   888         if (temperature.Index < superIO.Temperatures.Length) {
   889         Sensor sensor = new Sensor(temperature.Name, temperature.Index,
   890           SensorType.Temperature, this, new [] {
   891           new ParameterDescription("Offset [°C]", "Temperature offset.", 0)
   892         }, settings);
   893         temperatures.Add(sensor);
   894       }
   895 
   896       foreach (Fan fan in f)
   897         if (fan.Index < superIO.Fans.Length) {
   898           Sensor sensor = new Sensor(fan.Name, fan.Index, SensorType.Fan,
   899             this, settings);
   900           fans.Add(sensor);
   901         }
   902     }
   903 
   904     public override HardwareType HardwareType {
   905       get { return HardwareType.SuperIO; }
   906     }
   907 
   908     public override IHardware Parent {
   909       get { return mainboard; }
   910     }
   911 
   912 
   913     public override string GetReport() {
   914       return superIO.GetReport();
   915     }
   916 
   917     public override void Update() {
   918       superIO.Update();
   919 
   920       foreach (Sensor sensor in voltages) {
   921         float? value = readVoltage(sensor.Index);
   922         if (value.HasValue) {
   923           sensor.Value = value + (value - sensor.Parameters[2].Value) *
   924             sensor.Parameters[0].Value / sensor.Parameters[1].Value;
   925           ActivateSensor(sensor);
   926         }
   927       }
   928 
   929       foreach (Sensor sensor in temperatures) {
   930         float? value = readTemperature(sensor.Index);
   931         if (value.HasValue) {
   932           sensor.Value = value + sensor.Parameters[0].Value;
   933           ActivateSensor(sensor);
   934         }
   935       }
   936 
   937       foreach (Sensor sensor in fans) {
   938         float? value = readFan(sensor.Index);
   939         if (value.HasValue) {
   940           sensor.Value = value;
   941           if (value.Value > 0)
   942             ActivateSensor(sensor);
   943         }
   944       }
   945 
   946       postUpdate();
   947     }
   948 
   949     private class Voltage {
   950       public readonly string Name;
   951       public readonly int Index;
   952       public readonly float Ri;
   953       public readonly float Rf;
   954       public readonly float Vf;
   955       public readonly bool Hidden;
   956 
   957       public Voltage(string name, int index) :
   958         this(name, index, false) { }
   959       
   960       public Voltage(string name, int index, bool hidden) :
   961         this(name, index, 0, 1, 0, hidden) { }
   962       
   963       public Voltage(string name, int index, float ri, float rf) :
   964         this(name, index, ri, rf, 0, false) { }
   965       
   966       // float ri = 0, float rf = 1, float vf = 0, bool hidden = false) 
   967       
   968       public Voltage(string name, int index, 
   969         float ri, float rf, float vf, bool hidden) 
   970       {
   971         this.Name = name;
   972         this.Index = index;
   973         this.Ri = ri;
   974         this.Rf = rf;
   975         this.Vf = vf;
   976         this.Hidden = hidden;
   977       }
   978     }
   979 
   980     private class Temperature {
   981       public readonly string Name;
   982       public readonly int Index;
   983 
   984       public Temperature(string name, int index) {
   985         this.Name = name;
   986         this.Index = index;
   987       }
   988     }
   989 
   990     private class Fan {
   991       public readonly string Name;
   992       public readonly int Index;
   993 
   994       public Fan(string name, int index) {
   995         this.Name = name;
   996         this.Index = index;
   997       }
   998     }
   999   }
  1000 }