Hardware/Mainboard/SuperIOHardware.cs
author moel.mich
Sun, 21 Jul 2013 21:03:31 +0000
changeset 416 f117373bd190
parent 413 362c5e77197d
child 428 3c1cdc197b24
permissions -rw-r--r--
Refactored the SuperIOHardware class.
     1 /*
     2  
     3   This Source Code Form is subject to the terms of the Mozilla Public
     4   License, v. 2.0. If a copy of the MPL was not distributed with this
     5   file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  
     7   Copyright (C) 2009-2013 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 	
     9 */
    10 
    11 using System;
    12 using System.Collections.Generic;
    13 using System.Threading;
    14 using OpenHardwareMonitor.Hardware.LPC;
    15 
    16 namespace OpenHardwareMonitor.Hardware.Mainboard {
    17   internal sealed class SuperIOHardware : Hardware {
    18 
    19     private readonly Mainboard mainboard;
    20     private readonly ISuperIO superIO;
    21 
    22     private readonly List<Sensor> voltages = new List<Sensor>();
    23     private readonly List<Sensor> temperatures = new List<Sensor>();
    24     private readonly List<Sensor> fans = new List<Sensor>();
    25     private readonly List<Sensor> controls = new List<Sensor>();
    26 
    27     private delegate float? ReadValueDelegate(int index);
    28     private delegate void UpdateDelegate();
    29 
    30     // delegates for mainboard specific sensor reading code
    31     private readonly ReadValueDelegate readVoltage;
    32     private readonly ReadValueDelegate readTemperature;
    33     private readonly ReadValueDelegate readFan;
    34     private readonly ReadValueDelegate readControl;
    35 
    36     // delegate for post update mainboard specific code
    37     private readonly UpdateDelegate postUpdate;
    38 
    39     // mainboard specific mutex
    40     private readonly Mutex mutex;
    41 
    42     public SuperIOHardware(Mainboard mainboard, ISuperIO superIO, 
    43       Manufacturer manufacturer, Model model, ISettings settings) 
    44       : base(ChipName.GetName(superIO.Chip), new Identifier("lpc", 
    45         superIO.Chip.ToString().ToLowerInvariant()), settings)
    46     {
    47       this.mainboard = mainboard;
    48       this.superIO = superIO;
    49 
    50       IList<Voltage> v;
    51       IList<Temperature> t;
    52       IList<Fan> f;
    53       IList<Ctrl> c;
    54       GetBoardSpecificConfiguration(superIO, manufacturer, model,
    55         out v, out t, out f, out c,
    56         out readVoltage, out readTemperature, out readFan, out readControl,
    57         out postUpdate, out mutex);
    58 
    59       CreateVoltageSensors(superIO, settings, v);
    60       CreateTemperatureSensors(superIO, settings, t);
    61       CreateFanSensors(superIO, settings, f);
    62       CreateControlSensors(superIO, settings, c);
    63     }
    64 
    65     private void CreateControlSensors(ISuperIO superIO, ISettings settings, 
    66       IList<Ctrl> c) 
    67     {
    68       foreach (Ctrl ctrl in c) {
    69         int index = ctrl.Index;
    70         if (index < superIO.Controls.Length) {
    71           Sensor sensor = new Sensor(ctrl.Name, index, SensorType.Control,
    72             this, settings);
    73           Control control = new Control(sensor, settings, 0, 100);
    74           control.ControlModeChanged += (cc) => {
    75             if (cc.ControlMode == ControlMode.Default) {
    76               superIO.SetControl(index, null);
    77             } else {
    78               superIO.SetControl(index, (byte)(cc.SoftwareValue * 2.55));
    79             }
    80           };
    81           control.SoftwareControlValueChanged += (cc) => {
    82             if (cc.ControlMode == ControlMode.Software)
    83               superIO.SetControl(index, (byte)(cc.SoftwareValue * 2.55));
    84           };
    85           if (control.ControlMode == ControlMode.Software)
    86             superIO.SetControl(index, (byte)(control.SoftwareValue * 2.55));
    87           sensor.Control = control;
    88           controls.Add(sensor);
    89           ActivateSensor(sensor);
    90         }
    91       }
    92     }
    93 
    94     private void CreateFanSensors(ISuperIO superIO, ISettings settings, 
    95       IList<Fan> f) 
    96     {
    97       foreach (Fan fan in f) {
    98         if (fan.Index < superIO.Fans.Length) {
    99           Sensor sensor = new Sensor(fan.Name, fan.Index, SensorType.Fan,
   100             this, settings);
   101           fans.Add(sensor);
   102         }
   103       }
   104     }
   105 
   106     private void CreateTemperatureSensors(ISuperIO superIO, ISettings settings, 
   107       IList<Temperature> t) 
   108     {
   109       foreach (Temperature temperature in t)
   110         if (temperature.Index < superIO.Temperatures.Length) {
   111           Sensor sensor = new Sensor(temperature.Name, temperature.Index,
   112             SensorType.Temperature, this, new[] {
   113           new ParameterDescription("Offset [°C]", "Temperature offset.", 0)
   114         }, settings);
   115           temperatures.Add(sensor);
   116         }
   117     }
   118 
   119     private void CreateVoltageSensors(ISuperIO superIO, ISettings settings, 
   120       IList<Voltage> v) 
   121     {
   122       const string formula = "Voltage = value + (value - Vf) * Ri / Rf.";
   123       foreach (Voltage voltage in v)
   124         if (voltage.Index < superIO.Voltages.Length) {
   125           Sensor sensor = new Sensor(voltage.Name, voltage.Index,
   126             voltage.Hidden, SensorType.Voltage, this, new[] {
   127             new ParameterDescription("Ri [kΩ]", "Input resistance.\n" + 
   128               formula, voltage.Ri),
   129             new ParameterDescription("Rf [kΩ]", "Reference resistance.\n" + 
   130               formula, voltage.Rf),
   131             new ParameterDescription("Vf [V]", "Reference voltage.\n" + 
   132               formula, voltage.Vf)
   133             }, settings);
   134           voltages.Add(sensor);
   135         }
   136     }
   137 
   138     private static void GetBoardSpecificConfiguration(ISuperIO superIO,
   139       Manufacturer manufacturer, Model model, out IList<Voltage> v,
   140       out IList<Temperature> t, out IList<Fan> f, out IList<Ctrl> c,
   141       out ReadValueDelegate readVoltage,
   142       out ReadValueDelegate readTemperature,
   143       out ReadValueDelegate readFan,
   144       out ReadValueDelegate readControl,
   145       out UpdateDelegate postUpdate, out Mutex mutex) {
   146       readVoltage = (index) => superIO.Voltages[index];
   147       readTemperature = (index) => superIO.Temperatures[index];
   148       readFan = (index) => superIO.Fans[index];
   149       readControl = (index) => superIO.Controls[index];
   150 
   151       postUpdate = () => { };
   152       mutex = null;
   153 
   154       v = new List<Voltage>();
   155       t = new List<Temperature>();
   156       f = new List<Fan>();
   157       c = new List<Ctrl>();
   158 
   159       switch (superIO.Chip) {
   160         case Chip.IT8705F:
   161         case Chip.IT8712F:
   162         case Chip.IT8716F:
   163         case Chip.IT8718F:
   164         case Chip.IT8720F:
   165         case Chip.IT8726F:
   166           GetITEConfigurationsA(superIO, manufacturer, model, v, t, f, c,
   167             ref readFan, ref postUpdate, ref mutex);
   168           break;
   169 
   170         case Chip.IT8721F:
   171         case Chip.IT8728F:
   172         case Chip.IT8771E:
   173         case Chip.IT8772E:
   174           GetITEConfigurationsB(superIO, manufacturer, model, v, t, f, c);
   175           break;
   176 
   177         case Chip.F71858:
   178           v.Add(new Voltage("VCC3V", 0, 150, 150));
   179           v.Add(new Voltage("VSB3V", 1, 150, 150));
   180           v.Add(new Voltage("Battery", 2, 150, 150));
   181           for (int i = 0; i < superIO.Temperatures.Length; i++)
   182             t.Add(new Temperature("Temperature #" + (i + 1), i));
   183           for (int i = 0; i < superIO.Fans.Length; i++)
   184             f.Add(new Fan("Fan #" + (i + 1), i));
   185           break;
   186         case Chip.F71862:
   187         case Chip.F71869:
   188         case Chip.F71869A:
   189         case Chip.F71882:
   190         case Chip.F71889AD:
   191         case Chip.F71889ED:
   192         case Chip.F71889F:
   193         case Chip.F71808E:
   194           GetFintekConfiguration(superIO, manufacturer, model, v, t, f);
   195           break;
   196 
   197         case Chip.W83627EHF:
   198           GetWinbondConfigurationEHF(manufacturer, model, v, t, f);
   199           break;
   200         case Chip.W83627DHG:
   201         case Chip.W83627DHGP:
   202         case Chip.W83667HG:
   203         case Chip.W83667HGB:
   204           GetWinbondConfigurationHG(manufacturer, model, v, t, f);
   205           break;
   206         case Chip.W83627HF:
   207         case Chip.W83627THF:
   208         case Chip.W83687THF:
   209           v.Add(new Voltage("CPU VCore", 0));
   210           v.Add(new Voltage("Voltage #2", 1, true));
   211           v.Add(new Voltage("Voltage #3", 2, true));
   212           v.Add(new Voltage("AVCC", 3, 34, 51));
   213           v.Add(new Voltage("Voltage #5", 4, true));
   214           v.Add(new Voltage("5VSB", 5, 34, 51));
   215           v.Add(new Voltage("VBAT", 6));
   216           t.Add(new Temperature("CPU", 0));
   217           t.Add(new Temperature("Auxiliary", 1));
   218           t.Add(new Temperature("System", 2));
   219           f.Add(new Fan("System Fan", 0));
   220           f.Add(new Fan("CPU Fan", 1));
   221           f.Add(new Fan("Auxiliary Fan", 2));
   222           break;
   223         case Chip.NCT6771F:
   224         case Chip.NCT6776F:
   225           GetNuvotonConfigurationF(superIO, manufacturer, model, v, t, f, c);
   226           break;
   227         case Chip.NCT6779D:
   228         case Chip.NCT6791D:
   229           GetNuvotonConfigurationD(superIO, manufacturer, model, v, t, f, c);
   230           break;
   231         default:
   232           GetDefaultConfiguration(superIO, v, t, f, c);
   233           break;
   234       }
   235     }
   236 
   237     private static void GetDefaultConfiguration(ISuperIO superIO, 
   238       IList<Voltage> v, IList<Temperature> t, IList<Fan> f, IList<Ctrl> c) 
   239     {
   240       for (int i = 0; i < superIO.Voltages.Length; i++)
   241         v.Add(new Voltage("Voltage #" + (i + 1), i, true));
   242       for (int i = 0; i < superIO.Temperatures.Length; i++)
   243         t.Add(new Temperature("Temperature #" + (i + 1), i));
   244       for (int i = 0; i < superIO.Fans.Length; i++)
   245         f.Add(new Fan("Fan #" + (i + 1), i));
   246       for (int i = 0; i < superIO.Controls.Length; i++)
   247         c.Add(new Ctrl("Fan Control #" + (i + 1), i));
   248     }
   249 
   250     private static void GetITEConfigurationsA(ISuperIO superIO, 
   251       Manufacturer manufacturer, Model model, 
   252       IList<Voltage> v, IList<Temperature> t, IList<Fan> f, IList<Ctrl> c, 
   253       ref ReadValueDelegate readFan, ref UpdateDelegate postUpdate, 
   254       ref Mutex mutex) 
   255     {
   256       switch (manufacturer) {
   257         case Manufacturer.ASUS:
   258           switch (model) {
   259             case Model.Crosshair_III_Formula: // IT8720F
   260               v.Add(new Voltage("VBat", 8));
   261               t.Add(new Temperature("CPU", 0));
   262               for (int i = 0; i < superIO.Fans.Length; i++)
   263                 f.Add(new Fan("Fan #" + (i + 1), i));
   264               break;
   265             case Model.M2N_SLI_DELUXE:
   266               v.Add(new Voltage("CPU VCore", 0));
   267               v.Add(new Voltage("+3.3V", 1));
   268               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   269               v.Add(new Voltage("+12V", 4, 30, 10));
   270               v.Add(new Voltage("+5VSB", 7, 6.8f, 10));
   271               v.Add(new Voltage("VBat", 8));
   272               t.Add(new Temperature("CPU", 0));
   273               t.Add(new Temperature("Motherboard", 1));
   274               f.Add(new Fan("CPU Fan", 0));
   275               f.Add(new Fan("Chassis Fan #1", 1));
   276               f.Add(new Fan("Power Fan", 2));
   277               break;
   278             case Model.M4A79XTD_EVO: // IT8720F           
   279               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   280               v.Add(new Voltage("VBat", 8));
   281               t.Add(new Temperature("CPU", 0));
   282               t.Add(new Temperature("Motherboard", 1));
   283               f.Add(new Fan("CPU Fan", 0));
   284               f.Add(new Fan("Chassis Fan #1", 1));
   285               f.Add(new Fan("Chassis Fan #2", 2));
   286               break;
   287             default:
   288               v.Add(new Voltage("CPU VCore", 0));
   289               v.Add(new Voltage("Voltage #2", 1, true));
   290               v.Add(new Voltage("Voltage #3", 2, true));
   291               v.Add(new Voltage("Voltage #4", 3, true));
   292               v.Add(new Voltage("Voltage #5", 4, true));
   293               v.Add(new Voltage("Voltage #6", 5, true));
   294               v.Add(new Voltage("Voltage #7", 6, true));
   295               v.Add(new Voltage("Voltage #8", 7, true));
   296               v.Add(new Voltage("VBat", 8));
   297               for (int i = 0; i < superIO.Temperatures.Length; i++)
   298                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   299               for (int i = 0; i < superIO.Fans.Length; i++)
   300                 f.Add(new Fan("Fan #" + (i + 1), i));
   301               for (int i = 0; i < superIO.Controls.Length; i++)
   302                 c.Add(new Ctrl("Fan Control #" + (i + 1), i));
   303               break;
   304           }
   305           break;
   306 
   307         case Manufacturer.ASRock:
   308           switch (model) {
   309             case Model.P55_Deluxe: // IT8720F
   310               GetASRockConfiguration(superIO, v, t, f, 
   311                 ref readFan, ref postUpdate, ref mutex);
   312               break;
   313             default:
   314               v.Add(new Voltage("CPU VCore", 0));
   315               v.Add(new Voltage("Voltage #2", 1, true));
   316               v.Add(new Voltage("Voltage #3", 2, true));
   317               v.Add(new Voltage("Voltage #4", 3, true));
   318               v.Add(new Voltage("Voltage #5", 4, true));
   319               v.Add(new Voltage("Voltage #6", 5, true));
   320               v.Add(new Voltage("Voltage #7", 6, true));
   321               v.Add(new Voltage("Voltage #8", 7, true));
   322               v.Add(new Voltage("VBat", 8));
   323               for (int i = 0; i < superIO.Temperatures.Length; i++)
   324                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   325               for (int i = 0; i < superIO.Fans.Length; i++)
   326                 f.Add(new Fan("Fan #" + (i + 1), i));
   327               break;
   328           };
   329           break;
   330 
   331         case Manufacturer.DFI:
   332           switch (model) {
   333             case Model.LP_BI_P45_T2RS_Elite: // IT8718F
   334               v.Add(new Voltage("CPU VCore", 0));
   335               v.Add(new Voltage("FSB VTT", 1));
   336               v.Add(new Voltage("+3.3V", 2));
   337               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   338               v.Add(new Voltage("+12V", 4, 30, 10));
   339               v.Add(new Voltage("NB Core", 5));
   340               v.Add(new Voltage("VDIMM", 6));
   341               v.Add(new Voltage("+5VSB", 7, 6.8f, 10));
   342               v.Add(new Voltage("VBat", 8));
   343               t.Add(new Temperature("CPU", 0));
   344               t.Add(new Temperature("System", 1));
   345               t.Add(new Temperature("Chipset", 2));
   346               f.Add(new Fan("Fan #1", 0));
   347               f.Add(new Fan("Fan #2", 1));
   348               f.Add(new Fan("Fan #3", 2));
   349               break;
   350             case Model.LP_DK_P55_T3eH9: // IT8720F
   351               v.Add(new Voltage("CPU VCore", 0));
   352               v.Add(new Voltage("VTT", 1));
   353               v.Add(new Voltage("+3.3V", 2));
   354               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   355               v.Add(new Voltage("+12V", 4, 30, 10));
   356               v.Add(new Voltage("CPU PLL", 5));
   357               v.Add(new Voltage("DRAM", 6));
   358               v.Add(new Voltage("+5VSB", 7, 6.8f, 10));
   359               v.Add(new Voltage("VBat", 8));
   360               t.Add(new Temperature("Chipset", 0));
   361               t.Add(new Temperature("CPU PWM", 1));
   362               t.Add(new Temperature("CPU", 2));
   363               f.Add(new Fan("Fan #1", 0));
   364               f.Add(new Fan("Fan #2", 1));
   365               f.Add(new Fan("Fan #3", 2));
   366               break;
   367             default:
   368               v.Add(new Voltage("CPU VCore", 0));
   369               v.Add(new Voltage("VTT", 1, true));
   370               v.Add(new Voltage("+3.3V", 2, true));
   371               v.Add(new Voltage("+5V", 3, 6.8f, 10, 0, true));
   372               v.Add(new Voltage("+12V", 4, 30, 10, 0, true));
   373               v.Add(new Voltage("Voltage #6", 5, true));
   374               v.Add(new Voltage("DRAM", 6, true));
   375               v.Add(new Voltage("+5VSB", 7, 6.8f, 10, 0, true));
   376               v.Add(new Voltage("VBat", 8));
   377               for (int i = 0; i < superIO.Temperatures.Length; i++)
   378                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   379               for (int i = 0; i < superIO.Fans.Length; i++)
   380                 f.Add(new Fan("Fan #" + (i + 1), i));
   381               for (int i = 0; i < superIO.Controls.Length; i++)
   382                 c.Add(new Ctrl("Fan Control #" + (i + 1), i));
   383               break;
   384           }
   385           break;
   386 
   387         case Manufacturer.Gigabyte:
   388           switch (model) {
   389             case Model._965P_S3: // IT8718F
   390               v.Add(new Voltage("CPU VCore", 0));
   391               v.Add(new Voltage("DRAM", 1));
   392               v.Add(new Voltage("+3.3V", 2));
   393               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   394               v.Add(new Voltage("+12V", 7, 24.3f, 8.2f));
   395               v.Add(new Voltage("VBat", 8));
   396               t.Add(new Temperature("System", 0));
   397               t.Add(new Temperature("CPU", 1));
   398               f.Add(new Fan("CPU Fan", 0));
   399               f.Add(new Fan("System Fan", 1));
   400               break;
   401             case Model.EP45_DS3R: // IT8718F
   402             case Model.EP45_UD3R:
   403             case Model.X38_DS5:
   404               v.Add(new Voltage("CPU VCore", 0));
   405               v.Add(new Voltage("DRAM", 1));
   406               v.Add(new Voltage("+3.3V", 2));
   407               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   408               v.Add(new Voltage("+12V", 7, 24.3f, 8.2f));
   409               v.Add(new Voltage("VBat", 8));
   410               t.Add(new Temperature("System", 0));
   411               t.Add(new Temperature("CPU", 1));
   412               f.Add(new Fan("CPU Fan", 0));
   413               f.Add(new Fan("System Fan #2", 1));
   414               f.Add(new Fan("Power Fan", 2));
   415               f.Add(new Fan("System Fan #1", 3));
   416               break;
   417             case Model.EX58_EXTREME: // IT8720F                 
   418               v.Add(new Voltage("CPU VCore", 0));
   419               v.Add(new Voltage("DRAM", 1));
   420               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   421               v.Add(new Voltage("VBat", 8));
   422               t.Add(new Temperature("System", 0));
   423               t.Add(new Temperature("CPU", 1));
   424               t.Add(new Temperature("Northbridge", 2));
   425               f.Add(new Fan("CPU Fan", 0));
   426               f.Add(new Fan("System Fan #2", 1));
   427               f.Add(new Fan("Power Fan", 2));
   428               f.Add(new Fan("System Fan #1", 3));
   429               break;
   430             case Model.P35_DS3: // IT8718F 
   431             case Model.P35_DS3L: // IT8718F
   432               v.Add(new Voltage("CPU VCore", 0));
   433               v.Add(new Voltage("DRAM", 1));
   434               v.Add(new Voltage("+3.3V", 2));
   435               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   436               v.Add(new Voltage("+12V", 7, 24.3f, 8.2f));
   437               v.Add(new Voltage("VBat", 8));
   438               t.Add(new Temperature("System", 0));
   439               t.Add(new Temperature("CPU", 1));
   440               f.Add(new Fan("CPU Fan", 0));
   441               f.Add(new Fan("System Fan #1", 1));
   442               f.Add(new Fan("System Fan #2", 2));
   443               f.Add(new Fan("Power Fan", 3));
   444               break;
   445             case Model.P55_UD4: // IT8720F
   446             case Model.P55A_UD3: // IT8720F
   447             case Model.P55M_UD4: // IT8720F                
   448             case Model.H55_USB3: // IT8720F
   449             case Model.EX58_UD3R: // IT8720F 
   450               v.Add(new Voltage("CPU VCore", 0));
   451               v.Add(new Voltage("DRAM", 1));
   452               v.Add(new Voltage("+3.3V", 2));
   453               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   454               v.Add(new Voltage("+12V", 5, 24.3f, 8.2f));
   455               v.Add(new Voltage("VBat", 8));
   456               t.Add(new Temperature("System", 0));
   457               t.Add(new Temperature("CPU", 2));
   458               f.Add(new Fan("CPU Fan", 0));
   459               f.Add(new Fan("System Fan #2", 1));
   460               f.Add(new Fan("Power Fan", 2));
   461               f.Add(new Fan("System Fan #1", 3));
   462               break;
   463             case Model.H55N_USB3: // IT8720F
   464               v.Add(new Voltage("CPU VCore", 0));
   465               v.Add(new Voltage("DRAM", 1));
   466               v.Add(new Voltage("+3.3V", 2));
   467               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   468               v.Add(new Voltage("+12V", 5, 24.3f, 8.2f));
   469               v.Add(new Voltage("VBat", 8));
   470               t.Add(new Temperature("System", 0));
   471               t.Add(new Temperature("CPU", 2));
   472               f.Add(new Fan("CPU Fan", 0));
   473               f.Add(new Fan("System Fan", 1));
   474               break;
   475             case Model.G41M_Combo: // IT8718F
   476             case Model.G41MT_S2: // IT8718F
   477             case Model.G41MT_S2P: // IT8718F
   478               v.Add(new Voltage("CPU VCore", 0));
   479               v.Add(new Voltage("DRAM", 1));
   480               v.Add(new Voltage("+3.3V", 2));
   481               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   482               v.Add(new Voltage("+12V", 7, 24.3f, 8.2f));
   483               v.Add(new Voltage("VBat", 8));
   484               t.Add(new Temperature("CPU", 2));
   485               f.Add(new Fan("CPU Fan", 0));
   486               f.Add(new Fan("System Fan", 1));
   487               break;
   488             case Model.GA_970A_UD3: // IT8720F
   489               v.Add(new Voltage("CPU VCore", 0));
   490               v.Add(new Voltage("DRAM", 1));
   491               v.Add(new Voltage("+3.3V", 2));
   492               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   493               v.Add(new Voltage("+12V", 4, 24.3f, 8.2f));
   494               v.Add(new Voltage("VBat", 8));
   495               t.Add(new Temperature("System", 0));
   496               t.Add(new Temperature("CPU", 1));
   497               f.Add(new Fan("CPU Fan", 0));
   498               f.Add(new Fan("System Fan #1", 1));
   499               f.Add(new Fan("System Fan #2", 2));
   500               f.Add(new Fan("Power Fan", 4));
   501               c.Add(new Ctrl("PWM 1", 0));
   502               c.Add(new Ctrl("PWM 2", 1));
   503               c.Add(new Ctrl("PWM 3", 2));
   504               break;
   505             case Model.GA_MA770T_UD3: // IT8720F
   506             case Model.GA_MA770T_UD3P: // IT8720F                
   507             case Model.GA_MA790X_UD3P: // IT8720F
   508               v.Add(new Voltage("CPU VCore", 0));
   509               v.Add(new Voltage("DRAM", 1));
   510               v.Add(new Voltage("+3.3V", 2));
   511               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   512               v.Add(new Voltage("+12V", 4, 24.3f, 8.2f));
   513               v.Add(new Voltage("VBat", 8));
   514               t.Add(new Temperature("System", 0));
   515               t.Add(new Temperature("CPU", 1));
   516               f.Add(new Fan("CPU Fan", 0));
   517               f.Add(new Fan("System Fan #1", 1));
   518               f.Add(new Fan("System Fan #2", 2));
   519               f.Add(new Fan("Power Fan", 3));
   520               break;
   521             case Model.GA_MA78LM_S2H: // IT8718F
   522               v.Add(new Voltage("CPU VCore", 0));
   523               v.Add(new Voltage("DRAM", 1));
   524               v.Add(new Voltage("+3.3V", 2));
   525               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   526               v.Add(new Voltage("+12V", 4, 24.3f, 8.2f));
   527               v.Add(new Voltage("VBat", 8));
   528               t.Add(new Temperature("System", 0));
   529               t.Add(new Temperature("CPU", 1));
   530               t.Add(new Temperature("VRM", 2));
   531               f.Add(new Fan("CPU Fan", 0));
   532               f.Add(new Fan("System Fan #1", 1));
   533               f.Add(new Fan("System Fan #2", 2));
   534               f.Add(new Fan("Power Fan", 3));
   535               break;
   536             case Model.GA_MA785GM_US2H: // IT8718F
   537             case Model.GA_MA785GMT_UD2H: // IT8718F
   538               v.Add(new Voltage("CPU VCore", 0));
   539               v.Add(new Voltage("DRAM", 1));
   540               v.Add(new Voltage("+3.3V", 2));
   541               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   542               v.Add(new Voltage("+12V", 4, 24.3f, 8.2f));
   543               v.Add(new Voltage("VBat", 8));
   544               t.Add(new Temperature("System", 0));
   545               t.Add(new Temperature("CPU", 1));
   546               f.Add(new Fan("CPU Fan", 0));
   547               f.Add(new Fan("System Fan", 1));
   548               f.Add(new Fan("NB Fan", 2));
   549               break;
   550             case Model.X58A_UD3R: // IT8720F 
   551               v.Add(new Voltage("CPU VCore", 0));
   552               v.Add(new Voltage("DRAM", 1));
   553               v.Add(new Voltage("+3.3V", 2));
   554               v.Add(new Voltage("+5V", 3, 6.8f, 10));
   555               v.Add(new Voltage("+12V", 5, 24.3f, 8.2f));
   556               v.Add(new Voltage("VBat", 8));
   557               t.Add(new Temperature("System", 0));
   558               t.Add(new Temperature("CPU", 1));
   559               t.Add(new Temperature("Northbridge", 2));
   560               f.Add(new Fan("CPU Fan", 0));
   561               f.Add(new Fan("System Fan #2", 1));
   562               f.Add(new Fan("Power Fan", 2));
   563               f.Add(new Fan("System Fan #1", 3));
   564               break;
   565             default:
   566               v.Add(new Voltage("CPU VCore", 0));
   567               v.Add(new Voltage("DRAM", 1, true));
   568               v.Add(new Voltage("+3.3V", 2, true));
   569               v.Add(new Voltage("+5V", 3, 6.8f, 10, 0, true));
   570               v.Add(new Voltage("Voltage #5", 4, true));
   571               v.Add(new Voltage("Voltage #6", 5, true));
   572               v.Add(new Voltage("Voltage #7", 6, true));
   573               v.Add(new Voltage("Voltage #8", 7, true));
   574               v.Add(new Voltage("VBat", 8));
   575               for (int i = 0; i < superIO.Temperatures.Length; i++)
   576                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   577               for (int i = 0; i < superIO.Fans.Length; i++)
   578                 f.Add(new Fan("Fan #" + (i + 1), i));
   579               for (int i = 0; i < superIO.Controls.Length; i++)
   580                 c.Add(new Ctrl("Fan Control #" + (i + 1), i));
   581               break;
   582           }
   583           break;
   584 
   585         default:
   586           v.Add(new Voltage("CPU VCore", 0));
   587           v.Add(new Voltage("Voltage #2", 1, true));
   588           v.Add(new Voltage("Voltage #3", 2, true));
   589           v.Add(new Voltage("Voltage #4", 3, true));
   590           v.Add(new Voltage("Voltage #5", 4, true));
   591           v.Add(new Voltage("Voltage #6", 5, true));
   592           v.Add(new Voltage("Voltage #7", 6, true));
   593           v.Add(new Voltage("Voltage #8", 7, true));
   594           v.Add(new Voltage("VBat", 8));
   595           for (int i = 0; i < superIO.Temperatures.Length; i++)
   596             t.Add(new Temperature("Temperature #" + (i + 1), i));
   597           for (int i = 0; i < superIO.Fans.Length; i++)
   598             f.Add(new Fan("Fan #" + (i + 1), i));
   599           for (int i = 0; i < superIO.Controls.Length; i++)
   600             c.Add(new Ctrl("Fan Control #" + (i + 1), i));
   601           break;
   602       }
   603     }
   604 
   605     private static void GetASRockConfiguration(ISuperIO superIO, 
   606       IList<Voltage> v, IList<Temperature> t, IList<Fan> f, 
   607       ref ReadValueDelegate readFan, ref UpdateDelegate postUpdate, 
   608       ref Mutex mutex) 
   609     {
   610       v.Add(new Voltage("CPU VCore", 0));
   611       v.Add(new Voltage("+3.3V", 2));
   612       v.Add(new Voltage("+12V", 4, 30, 10));
   613       v.Add(new Voltage("+5V", 5, 6.8f, 10));
   614       v.Add(new Voltage("VBat", 8));
   615       t.Add(new Temperature("CPU", 0));
   616       t.Add(new Temperature("Motherboard", 1));
   617       f.Add(new Fan("CPU Fan", 0));
   618       f.Add(new Fan("Chassis Fan #1", 1));
   619 
   620       // this mutex is also used by the official ASRock tool
   621       mutex = new Mutex(false, "ASRockOCMark");
   622 
   623       bool exclusiveAccess = false;
   624       try {
   625         exclusiveAccess = mutex.WaitOne(10, false);
   626       } catch (AbandonedMutexException) { } 
   627         catch (InvalidOperationException) { }
   628 
   629       // only read additional fans if we get exclusive access
   630       if (exclusiveAccess) {
   631 
   632         f.Add(new Fan("Chassis Fan #2", 2));
   633         f.Add(new Fan("Chassis Fan #3", 3));
   634         f.Add(new Fan("Power Fan", 4));
   635 
   636         readFan = (index) => {
   637           if (index < 2) {
   638             return superIO.Fans[index];
   639           } else {
   640             // get GPIO 80-87
   641             byte? gpio = superIO.ReadGPIO(7);
   642             if (!gpio.HasValue)
   643               return null;
   644 
   645             // read the last 3 fans based on GPIO 83-85
   646             int[] masks = { 0x05, 0x03, 0x06 };
   647             return (((gpio.Value >> 3) & 0x07) ==
   648               masks[index - 2]) ? superIO.Fans[2] : null;
   649           }
   650         };
   651 
   652         int fanIndex = 0;
   653         postUpdate = () => {
   654           // get GPIO 80-87
   655           byte? gpio = superIO.ReadGPIO(7);
   656           if (!gpio.HasValue)
   657             return;
   658 
   659           // prepare the GPIO 83-85 for the next update
   660           int[] masks = { 0x05, 0x03, 0x06 };
   661           superIO.WriteGPIO(7,
   662             (byte)((gpio.Value & 0xC7) | (masks[fanIndex] << 3)));
   663           fanIndex = (fanIndex + 1) % 3;
   664         };
   665       }
   666     }
   667 
   668     private static void GetITEConfigurationsB(ISuperIO superIO,
   669       Manufacturer manufacturer, Model model,
   670       IList<Voltage> v, IList<Temperature> t, IList<Fan> f, IList<Ctrl> c) 
   671     {
   672       switch (manufacturer) {
   673         case Manufacturer.ECS:
   674           switch (model) {
   675             case Model.A890GXM_A: // IT8721F
   676               v.Add(new Voltage("CPU VCore", 0));
   677               v.Add(new Voltage("VDIMM", 1));
   678               v.Add(new Voltage("NB Voltage", 2));
   679               v.Add(new Voltage("Analog +3.3V", 3, 10, 10));
   680               // v.Add(new Voltage("VDIMM", 6, true));
   681               v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   682               v.Add(new Voltage("VBat", 8, 10, 10));
   683               t.Add(new Temperature("CPU", 0));
   684               t.Add(new Temperature("System", 1));
   685               t.Add(new Temperature("Northbridge", 2));
   686               f.Add(new Fan("CPU Fan", 0));
   687               f.Add(new Fan("System Fan", 1));
   688               f.Add(new Fan("Power Fan", 2));
   689               break;
   690             default:
   691               v.Add(new Voltage("Voltage #1", 0, true));
   692               v.Add(new Voltage("Voltage #2", 1, true));
   693               v.Add(new Voltage("Voltage #3", 2, true));
   694               v.Add(new Voltage("Analog +3.3V", 3, 10, 10, 0, true));
   695               v.Add(new Voltage("Voltage #5", 4, true));
   696               v.Add(new Voltage("Voltage #6", 5, true));
   697               v.Add(new Voltage("Voltage #7", 6, true));
   698               v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   699               v.Add(new Voltage("VBat", 8, 10, 10));
   700               for (int i = 0; i < superIO.Temperatures.Length; i++)
   701                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   702               for (int i = 0; i < superIO.Fans.Length; i++)
   703                 f.Add(new Fan("Fan #" + (i + 1), i));
   704               for (int i = 0; i < superIO.Controls.Length; i++)
   705                 c.Add(new Ctrl("Fan Control #" + (i + 1), i));
   706               break;
   707           }
   708           break;
   709         case Manufacturer.Gigabyte:
   710           switch (model) {
   711             case Model.H61M_DS2_REV_1_2: // IT8728F
   712             case Model.H61M_USB3_B3_REV_2_0: // IT8728F
   713               v.Add(new Voltage("VTT", 0));
   714               v.Add(new Voltage("+12V", 2, 30.9f, 10));
   715               v.Add(new Voltage("CPU VCore", 5));
   716               v.Add(new Voltage("DRAM", 6));
   717               v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   718               v.Add(new Voltage("VBat", 8, 10, 10));
   719               t.Add(new Temperature("System", 0));
   720               t.Add(new Temperature("CPU", 2));
   721               f.Add(new Fan("CPU Fan", 0));
   722               f.Add(new Fan("System Fan", 1));
   723               break;
   724             case Model.H67A_UD3H_B3: // IT8728F
   725             case Model.H67A_USB3_B3: // IT8728F                
   726               v.Add(new Voltage("VTT", 0));
   727               v.Add(new Voltage("+5V", 1, 15, 10));
   728               v.Add(new Voltage("+12V", 2, 30.9f, 10));
   729               v.Add(new Voltage("CPU VCore", 5));
   730               v.Add(new Voltage("DRAM", 6));
   731               v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   732               v.Add(new Voltage("VBat", 8, 10, 10));
   733               t.Add(new Temperature("System", 0));
   734               t.Add(new Temperature("CPU", 2));
   735               f.Add(new Fan("CPU Fan", 0));
   736               f.Add(new Fan("System Fan #1", 1));
   737               f.Add(new Fan("Power Fan", 2));
   738               f.Add(new Fan("System Fan #2", 3));
   739               break;
   740             case Model.Z68A_D3H_B3: // IT8728F
   741               v.Add(new Voltage("VTT", 0));
   742               v.Add(new Voltage("+3.3V", 1, 6.49f, 10));
   743               v.Add(new Voltage("+12V", 2, 30.9f, 10));
   744               v.Add(new Voltage("+5V", 3, 7.15f, 10));
   745               v.Add(new Voltage("CPU VCore", 5));
   746               v.Add(new Voltage("DRAM", 6));
   747               v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   748               v.Add(new Voltage("VBat", 8, 10, 10));
   749               t.Add(new Temperature("System", 0));
   750               t.Add(new Temperature("CPU", 2));
   751               f.Add(new Fan("CPU Fan", 0));
   752               f.Add(new Fan("System Fan #1", 1));
   753               f.Add(new Fan("Power Fan", 2));
   754               f.Add(new Fan("System Fan #2", 3));
   755               break;
   756             case Model.P67A_UD3_B3: // IT8728F
   757             case Model.P67A_UD3R_B3: // IT8728F
   758             case Model.P67A_UD4_B3: // IT8728F                
   759             case Model.Z68AP_D3: // IT8728F
   760             case Model.Z68X_UD3H_B3: // IT8728F               
   761               v.Add(new Voltage("VTT", 0));
   762               v.Add(new Voltage("+3.3V", 1, 6.49f, 10));
   763               v.Add(new Voltage("+12V", 2, 30.9f, 10));
   764               v.Add(new Voltage("+5V", 3, 7.15f, 10));
   765               v.Add(new Voltage("CPU VCore", 5));
   766               v.Add(new Voltage("DRAM", 6));
   767               v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   768               v.Add(new Voltage("VBat", 8, 10, 10));
   769               t.Add(new Temperature("System", 0));
   770               t.Add(new Temperature("CPU", 2));
   771               f.Add(new Fan("CPU Fan", 0));
   772               f.Add(new Fan("System Fan #2", 1));
   773               f.Add(new Fan("Power Fan", 2));
   774               f.Add(new Fan("System Fan #1", 3));
   775               break;
   776             case Model.Z68X_UD7_B3: // IT8728F
   777               v.Add(new Voltage("VTT", 0));
   778               v.Add(new Voltage("+3.3V", 1, 6.49f, 10));
   779               v.Add(new Voltage("+12V", 2, 30.9f, 10));
   780               v.Add(new Voltage("+5V", 3, 7.15f, 10));
   781               v.Add(new Voltage("CPU VCore", 5));
   782               v.Add(new Voltage("DRAM", 6));
   783               v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   784               v.Add(new Voltage("VBat", 8, 10, 10));
   785               t.Add(new Temperature("System", 0));
   786               t.Add(new Temperature("CPU", 1));
   787               t.Add(new Temperature("System 3", 2));
   788               f.Add(new Fan("CPU Fan", 0));
   789               f.Add(new Fan("Power Fan", 1));
   790               f.Add(new Fan("System Fan #1", 2));
   791               f.Add(new Fan("System Fan #2", 3));
   792               f.Add(new Fan("System Fan #3", 4));
   793               break;
   794             default:
   795               v.Add(new Voltage("Voltage #1", 0, true));
   796               v.Add(new Voltage("Voltage #2", 1, true));
   797               v.Add(new Voltage("Voltage #3", 2, true));
   798               v.Add(new Voltage("Voltage #4", 3, true));
   799               v.Add(new Voltage("Voltage #5", 4, true));
   800               v.Add(new Voltage("Voltage #6", 5, true));
   801               v.Add(new Voltage("Voltage #7", 6, true));
   802               v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   803               v.Add(new Voltage("VBat", 8, 10, 10));
   804               for (int i = 0; i < superIO.Temperatures.Length; i++)
   805                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   806               for (int i = 0; i < superIO.Fans.Length; i++)
   807                 f.Add(new Fan("Fan #" + (i + 1), i));
   808               for (int i = 0; i < superIO.Controls.Length; i++)
   809                 c.Add(new Ctrl("Fan Control #" + (i + 1), i));
   810               break;
   811           }
   812           break;
   813         case Manufacturer.Shuttle:
   814           switch (model) {
   815             case Model.FH67: // IT8772E 
   816               v.Add(new Voltage("CPU VCore", 0));
   817               v.Add(new Voltage("DRAM", 1));
   818               v.Add(new Voltage("PCH VCCIO", 2));
   819               v.Add(new Voltage("CPU VCCIO", 3));
   820               v.Add(new Voltage("Graphic Voltage", 4));
   821               v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   822               v.Add(new Voltage("VBat", 8, 10, 10));
   823               t.Add(new Temperature("System", 0));
   824               t.Add(new Temperature("CPU", 1));
   825               f.Add(new Fan("Fan #1", 0));
   826               f.Add(new Fan("CPU Fan", 1));
   827               break;
   828             default:
   829               v.Add(new Voltage("Voltage #1", 0, true));
   830               v.Add(new Voltage("Voltage #2", 1, true));
   831               v.Add(new Voltage("Voltage #3", 2, true));
   832               v.Add(new Voltage("Voltage #4", 3, true));
   833               v.Add(new Voltage("Voltage #5", 4, true));
   834               v.Add(new Voltage("Voltage #6", 5, true));
   835               v.Add(new Voltage("Voltage #7", 6, true));
   836               v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   837               v.Add(new Voltage("VBat", 8, 10, 10));
   838               for (int i = 0; i < superIO.Temperatures.Length; i++)
   839                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   840               for (int i = 0; i < superIO.Fans.Length; i++)
   841                 f.Add(new Fan("Fan #" + (i + 1), i));
   842               for (int i = 0; i < superIO.Controls.Length; i++)
   843                 c.Add(new Ctrl("Fan Control #" + (i + 1), i));
   844               break;
   845           }
   846           break;
   847         default:
   848           v.Add(new Voltage("Voltage #1", 0, true));
   849           v.Add(new Voltage("Voltage #2", 1, true));
   850           v.Add(new Voltage("Voltage #3", 2, true));
   851           v.Add(new Voltage("Voltage #4", 3, true));
   852           v.Add(new Voltage("Voltage #5", 4, true));
   853           v.Add(new Voltage("Voltage #6", 5, true));
   854           v.Add(new Voltage("Voltage #7", 6, true));
   855           v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   856           v.Add(new Voltage("VBat", 8, 10, 10));
   857           for (int i = 0; i < superIO.Temperatures.Length; i++)
   858             t.Add(new Temperature("Temperature #" + (i + 1), i));
   859           for (int i = 0; i < superIO.Fans.Length; i++)
   860             f.Add(new Fan("Fan #" + (i + 1), i));
   861           for (int i = 0; i < superIO.Controls.Length; i++)
   862             c.Add(new Ctrl("Fan Control #" + (i + 1), i));
   863           break;
   864       }
   865     }
   866 
   867     private static void GetFintekConfiguration(ISuperIO superIO,
   868       Manufacturer manufacturer, Model model,
   869       IList<Voltage> v, IList<Temperature> t, IList<Fan> f) 
   870     {
   871       switch (manufacturer) {
   872         case Manufacturer.EVGA:
   873           switch (model) {
   874             case Model.X58_SLI_Classified: // F71882 
   875               v.Add(new Voltage("VCC3V", 0, 150, 150));
   876               v.Add(new Voltage("CPU VCore", 1, 47, 100));
   877               v.Add(new Voltage("DIMM", 2, 47, 100));
   878               v.Add(new Voltage("CPU VTT", 3, 24, 100));
   879               v.Add(new Voltage("IOH Vcore", 4, 24, 100));
   880               v.Add(new Voltage("+5V", 5, 51, 12));
   881               v.Add(new Voltage("+12V", 6, 56, 6.8f));
   882               v.Add(new Voltage("3VSB", 7, 150, 150));
   883               v.Add(new Voltage("VBat", 8, 150, 150));
   884               t.Add(new Temperature("CPU", 0));
   885               t.Add(new Temperature("VREG", 1));
   886               t.Add(new Temperature("System", 2));
   887               f.Add(new Fan("CPU Fan", 0));
   888               f.Add(new Fan("Power Fan", 1));
   889               f.Add(new Fan("Chassis Fan", 2));
   890               break;
   891             default:
   892               v.Add(new Voltage("VCC3V", 0, 150, 150));
   893               v.Add(new Voltage("CPU VCore", 1));
   894               v.Add(new Voltage("Voltage #3", 2, true));
   895               v.Add(new Voltage("Voltage #4", 3, true));
   896               v.Add(new Voltage("Voltage #5", 4, true));
   897               v.Add(new Voltage("Voltage #6", 5, true));
   898               v.Add(new Voltage("Voltage #7", 6, true));
   899               v.Add(new Voltage("VSB3V", 7, 150, 150));
   900               v.Add(new Voltage("VBat", 8, 150, 150));
   901               for (int i = 0; i < superIO.Temperatures.Length; i++)
   902                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   903               for (int i = 0; i < superIO.Fans.Length; i++)
   904                 f.Add(new Fan("Fan #" + (i + 1), i));
   905               break;
   906           }
   907           break;
   908         default:
   909           v.Add(new Voltage("VCC3V", 0, 150, 150));
   910           v.Add(new Voltage("CPU VCore", 1));
   911           v.Add(new Voltage("Voltage #3", 2, true));
   912           v.Add(new Voltage("Voltage #4", 3, true));
   913           v.Add(new Voltage("Voltage #5", 4, true));
   914           v.Add(new Voltage("Voltage #6", 5, true));
   915           if (superIO.Chip != Chip.F71808E)
   916             v.Add(new Voltage("Voltage #7", 6, true));
   917           v.Add(new Voltage("VSB3V", 7, 150, 150));
   918           v.Add(new Voltage("VBat", 8, 150, 150));
   919           for (int i = 0; i < superIO.Temperatures.Length; i++)
   920             t.Add(new Temperature("Temperature #" + (i + 1), i));
   921           for (int i = 0; i < superIO.Fans.Length; i++)
   922             f.Add(new Fan("Fan #" + (i + 1), i));
   923           break;
   924       }
   925     }
   926 
   927     private static void GetNuvotonConfigurationF(ISuperIO superIO, 
   928       Manufacturer manufacturer, Model model, 
   929       IList<Voltage> v, IList<Temperature> t, IList<Fan> f, IList<Ctrl> c) 
   930     {
   931       switch (manufacturer) {
   932         case Manufacturer.ASUS:
   933           switch (model) {
   934             case Model.P8P67: // NCT6776F
   935             case Model.P8P67_EVO: // NCT6776F
   936             case Model.P8P67_PRO: // NCT6776F
   937               v.Add(new Voltage("CPU VCore", 0));
   938               v.Add(new Voltage("+12V", 1, 11, 1));
   939               v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   940               v.Add(new Voltage("+3.3V", 3, 34, 34));
   941               v.Add(new Voltage("+5V", 4, 12, 3));
   942               v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   943               v.Add(new Voltage("VBAT", 8, 34, 34));
   944               t.Add(new Temperature("CPU", 0));
   945               t.Add(new Temperature("Auxiliary", 2));
   946               t.Add(new Temperature("Motherboard", 3));
   947               f.Add(new Fan("Chassis Fan #1", 0));
   948               f.Add(new Fan("CPU Fan", 1));
   949               f.Add(new Fan("Power Fan", 2));
   950               f.Add(new Fan("Chassis Fan #2", 3));
   951               c.Add(new Ctrl("Chassis Fan #2", 0));
   952               c.Add(new Ctrl("CPU Fan", 1));
   953               c.Add(new Ctrl("Chassis Fan #1", 2));
   954               break;
   955             case Model.P8P67_M_PRO: // NCT6776F
   956               v.Add(new Voltage("CPU VCore", 0));
   957               v.Add(new Voltage("+12V", 1, 11, 1));
   958               v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   959               v.Add(new Voltage("+3.3V", 3, 34, 34));
   960               v.Add(new Voltage("+5V", 4, 12, 3));
   961               v.Add(new Voltage("Voltage #6", 5, true));
   962               v.Add(new Voltage("Voltage #7", 6, true));
   963               v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   964               v.Add(new Voltage("VBAT", 8, 34, 34));
   965               t.Add(new Temperature("CPU", 0));
   966               t.Add(new Temperature("Motherboard", 3));
   967               f.Add(new Fan("Chassis Fan #1", 0));
   968               f.Add(new Fan("CPU Fan", 1));
   969               f.Add(new Fan("Chassis Fan #2", 2));
   970               f.Add(new Fan("Power Fan", 3));
   971               f.Add(new Fan("Auxiliary Fan", 4));
   972               break;
   973             case Model.P8Z68_V_PRO: // NCT6776F
   974               v.Add(new Voltage("CPU VCore", 0));
   975               v.Add(new Voltage("+12V", 1, 11, 1));
   976               v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   977               v.Add(new Voltage("+3.3V", 3, 34, 34));
   978               v.Add(new Voltage("+5V", 4, 12, 3));
   979               v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   980               v.Add(new Voltage("VBAT", 8, 34, 34));
   981               t.Add(new Temperature("CPU", 0));
   982               t.Add(new Temperature("Auxiliary", 2));
   983               t.Add(new Temperature("Motherboard", 3));
   984               for (int i = 0; i < superIO.Fans.Length; i++)
   985                 f.Add(new Fan("Fan #" + (i + 1), i));
   986               for (int i = 0; i < superIO.Controls.Length; i++)
   987                 c.Add(new Ctrl("Fan #" + (i + 1), i));
   988               break;
   989             case Model.P9X79: // NCT6776F
   990               v.Add(new Voltage("CPU VCore", 0));
   991               v.Add(new Voltage("+12V", 1, 11, 1));
   992               v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   993               v.Add(new Voltage("+3.3V", 3, 34, 34));
   994               v.Add(new Voltage("+5V", 4, 12, 3));
   995               v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   996               v.Add(new Voltage("VBAT", 8, 34, 34));
   997               t.Add(new Temperature("CPU", 0));
   998               t.Add(new Temperature("Motherboard", 3));
   999               for (int i = 0; i < superIO.Fans.Length; i++)
  1000                 f.Add(new Fan("Fan #" + (i + 1), i));
  1001               for (int i = 0; i < superIO.Controls.Length; i++)
  1002                 c.Add(new Ctrl("Fan Control #" + (i + 1), i));
  1003               break;
  1004             default:
  1005               v.Add(new Voltage("CPU VCore", 0));
  1006               v.Add(new Voltage("Voltage #2", 1, true));
  1007               v.Add(new Voltage("AVCC", 2, 34, 34));
  1008               v.Add(new Voltage("3VCC", 3, 34, 34));
  1009               v.Add(new Voltage("Voltage #5", 4, true));
  1010               v.Add(new Voltage("Voltage #6", 5, true));
  1011               v.Add(new Voltage("Voltage #7", 6, true));
  1012               v.Add(new Voltage("3VSB", 7, 34, 34));
  1013               v.Add(new Voltage("VBAT", 8, 34, 34));
  1014               t.Add(new Temperature("CPU Core", 0));
  1015               t.Add(new Temperature("Temperature #1", 1));
  1016               t.Add(new Temperature("Temperature #2", 2));
  1017               t.Add(new Temperature("Temperature #3", 3));
  1018               for (int i = 0; i < superIO.Fans.Length; i++)
  1019                 f.Add(new Fan("Fan #" + (i + 1), i));
  1020               for (int i = 0; i < superIO.Controls.Length; i++)
  1021                 c.Add(new Ctrl("Fan Control #" + (i + 1), i));
  1022               break;
  1023           }
  1024           break;
  1025         default:
  1026           v.Add(new Voltage("CPU VCore", 0));
  1027           v.Add(new Voltage("Voltage #2", 1, true));
  1028           v.Add(new Voltage("AVCC", 2, 34, 34));
  1029           v.Add(new Voltage("3VCC", 3, 34, 34));
  1030           v.Add(new Voltage("Voltage #5", 4, true));
  1031           v.Add(new Voltage("Voltage #6", 5, true));
  1032           v.Add(new Voltage("Voltage #7", 6, true));
  1033           v.Add(new Voltage("3VSB", 7, 34, 34));
  1034           v.Add(new Voltage("VBAT", 8, 34, 34));
  1035           t.Add(new Temperature("CPU Core", 0));
  1036           t.Add(new Temperature("Temperature #1", 1));
  1037           t.Add(new Temperature("Temperature #2", 2));
  1038           t.Add(new Temperature("Temperature #3", 3));
  1039           for (int i = 0; i < superIO.Fans.Length; i++)
  1040             f.Add(new Fan("Fan #" + (i + 1), i));
  1041           for (int i = 0; i < superIO.Controls.Length; i++)
  1042             c.Add(new Ctrl("Fan Control #" + (i + 1), i));
  1043           break;
  1044       }
  1045     }
  1046 
  1047     private static void GetNuvotonConfigurationD(ISuperIO superIO,
  1048       Manufacturer manufacturer, Model model,
  1049       IList<Voltage> v, IList<Temperature> t, IList<Fan> f, IList<Ctrl> c) 
  1050     {
  1051       switch (manufacturer) {
  1052         case Manufacturer.ASUS:
  1053           switch (model) {
  1054             case Model.P8Z77_V: // NCT6779D
  1055               v.Add(new Voltage("CPU VCore", 0));
  1056               v.Add(new Voltage("Voltage #2", 1, true));
  1057               v.Add(new Voltage("AVCC", 2, 34, 34));
  1058               v.Add(new Voltage("3VCC", 3, 34, 34));
  1059               v.Add(new Voltage("Voltage #5", 4, true));
  1060               v.Add(new Voltage("Voltage #6", 5, true));
  1061               v.Add(new Voltage("Voltage #7", 6, true));
  1062               v.Add(new Voltage("3VSB", 7, 34, 34));
  1063               v.Add(new Voltage("VBAT", 8, 34, 34));
  1064               v.Add(new Voltage("VTT", 9));
  1065               v.Add(new Voltage("Voltage #11", 10, true));
  1066               v.Add(new Voltage("Voltage #12", 11, true));
  1067               v.Add(new Voltage("Voltage #13", 12, true));
  1068               v.Add(new Voltage("Voltage #14", 13, true));
  1069               v.Add(new Voltage("Voltage #15", 14, true));
  1070               t.Add(new Temperature("CPU Core", 0));
  1071               t.Add(new Temperature("Auxiliary", 1));
  1072               t.Add(new Temperature("Motherboard", 2));
  1073               f.Add(new Fan("Chassis Fan #1", 0));
  1074               f.Add(new Fan("CPU Fan", 1));
  1075               f.Add(new Fan("Chassis Fan #2", 2));
  1076               f.Add(new Fan("Chassis Fan #3", 3));
  1077               c.Add(new Ctrl("Chassis Fan #1", 0));
  1078               c.Add(new Ctrl("CPU  Fan", 1));
  1079               c.Add(new Ctrl("Chassis Fan #2", 2));
  1080               c.Add(new Ctrl("Chassis Fan #3", 3));
  1081               break;
  1082             default:
  1083               v.Add(new Voltage("CPU VCore", 0));
  1084               v.Add(new Voltage("Voltage #2", 1, true));
  1085               v.Add(new Voltage("AVCC", 2, 34, 34));
  1086               v.Add(new Voltage("3VCC", 3, 34, 34));
  1087               v.Add(new Voltage("Voltage #5", 4, true));
  1088               v.Add(new Voltage("Voltage #6", 5, true));
  1089               v.Add(new Voltage("Voltage #7", 6, true));
  1090               v.Add(new Voltage("3VSB", 7, 34, 34));
  1091               v.Add(new Voltage("VBAT", 8, 34, 34));
  1092               v.Add(new Voltage("VTT", 9));
  1093               v.Add(new Voltage("Voltage #11", 10, true));
  1094               v.Add(new Voltage("Voltage #12", 11, true));
  1095               v.Add(new Voltage("Voltage #13", 12, true));
  1096               v.Add(new Voltage("Voltage #14", 13, true));
  1097               v.Add(new Voltage("Voltage #15", 14, true));
  1098               t.Add(new Temperature("CPU Core", 0));
  1099               t.Add(new Temperature("Temperature #1", 1));
  1100               t.Add(new Temperature("Temperature #2", 2));
  1101               t.Add(new Temperature("Temperature #3", 3));
  1102               t.Add(new Temperature("Temperature #4", 4));
  1103               t.Add(new Temperature("Temperature #5", 5));
  1104               t.Add(new Temperature("Temperature #6", 6));
  1105               for (int i = 0; i < superIO.Fans.Length; i++)
  1106                 f.Add(new Fan("Fan #" + (i + 1), i));
  1107               for (int i = 0; i < superIO.Controls.Length; i++)
  1108                 c.Add(new Ctrl("Fan Control #" + (i + 1), i));
  1109               break;
  1110           }
  1111           break;
  1112         default:
  1113           v.Add(new Voltage("CPU VCore", 0));
  1114           v.Add(new Voltage("Voltage #2", 1, true));
  1115           v.Add(new Voltage("AVCC", 2, 34, 34));
  1116           v.Add(new Voltage("3VCC", 3, 34, 34));
  1117           v.Add(new Voltage("Voltage #5", 4, true));
  1118           v.Add(new Voltage("Voltage #6", 5, true));
  1119           v.Add(new Voltage("Voltage #7", 6, true));
  1120           v.Add(new Voltage("3VSB", 7, 34, 34));
  1121           v.Add(new Voltage("VBAT", 8, 34, 34));
  1122           v.Add(new Voltage("VTT", 9));
  1123           v.Add(new Voltage("Voltage #11", 10, true));
  1124           v.Add(new Voltage("Voltage #12", 11, true));
  1125           v.Add(new Voltage("Voltage #13", 12, true));
  1126           v.Add(new Voltage("Voltage #14", 13, true));
  1127           v.Add(new Voltage("Voltage #15", 14, true));
  1128           t.Add(new Temperature("CPU Core", 0));
  1129           t.Add(new Temperature("Temperature #1", 1));
  1130           t.Add(new Temperature("Temperature #2", 2));
  1131           t.Add(new Temperature("Temperature #3", 3));
  1132           t.Add(new Temperature("Temperature #4", 4));
  1133           t.Add(new Temperature("Temperature #5", 5));
  1134           t.Add(new Temperature("Temperature #6", 6));
  1135           for (int i = 0; i < superIO.Fans.Length; i++)
  1136             f.Add(new Fan("Fan #" + (i + 1), i));
  1137           for (int i = 0; i < superIO.Controls.Length; i++)
  1138             c.Add(new Ctrl("Fan Control #" + (i + 1), i));
  1139           break;
  1140       }
  1141     }
  1142 
  1143     private static void GetWinbondConfigurationEHF(Manufacturer manufacturer,
  1144       Model model, IList<Voltage> v, IList<Temperature> t, IList<Fan> f) 
  1145     {
  1146       switch (manufacturer) {
  1147         case Manufacturer.ASRock:
  1148           switch (model) {
  1149             case Model.AOD790GX_128M: // W83627EHF
  1150               v.Add(new Voltage("CPU VCore", 0));
  1151               v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
  1152               v.Add(new Voltage("+3.3V", 4, 10, 10));
  1153               v.Add(new Voltage("+5V", 5, 20, 10));
  1154               v.Add(new Voltage("+12V", 6, 28, 5));
  1155               v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
  1156               v.Add(new Voltage("VBAT", 8, 34, 34));
  1157               t.Add(new Temperature("CPU", 0));
  1158               t.Add(new Temperature("Motherboard", 2));
  1159               f.Add(new Fan("CPU Fan", 0));
  1160               f.Add(new Fan("Chassis Fan", 1));
  1161               break;
  1162             default:
  1163               v.Add(new Voltage("CPU VCore", 0));
  1164               v.Add(new Voltage("Voltage #2", 1, true));
  1165               v.Add(new Voltage("AVCC", 2, 34, 34));
  1166               v.Add(new Voltage("3VCC", 3, 34, 34));
  1167               v.Add(new Voltage("Voltage #5", 4, true));
  1168               v.Add(new Voltage("Voltage #6", 5, true));
  1169               v.Add(new Voltage("Voltage #7", 6, true));
  1170               v.Add(new Voltage("3VSB", 7, 34, 34));
  1171               v.Add(new Voltage("VBAT", 8, 34, 34));
  1172               v.Add(new Voltage("Voltage #10", 9, true));
  1173               t.Add(new Temperature("CPU", 0));
  1174               t.Add(new Temperature("Auxiliary", 1));
  1175               t.Add(new Temperature("System", 2));
  1176               f.Add(new Fan("System Fan", 0));
  1177               f.Add(new Fan("CPU Fan", 1));
  1178               f.Add(new Fan("Auxiliary Fan", 2));
  1179               f.Add(new Fan("CPU Fan #2", 3));
  1180               f.Add(new Fan("Auxiliary Fan #2", 4));
  1181               break;
  1182           } break;
  1183         default:
  1184           v.Add(new Voltage("CPU VCore", 0));
  1185           v.Add(new Voltage("Voltage #2", 1, true));
  1186           v.Add(new Voltage("AVCC", 2, 34, 34));
  1187           v.Add(new Voltage("3VCC", 3, 34, 34));
  1188           v.Add(new Voltage("Voltage #5", 4, true));
  1189           v.Add(new Voltage("Voltage #6", 5, true));
  1190           v.Add(new Voltage("Voltage #7", 6, true));
  1191           v.Add(new Voltage("3VSB", 7, 34, 34));
  1192           v.Add(new Voltage("VBAT", 8, 34, 34));
  1193           v.Add(new Voltage("Voltage #10", 9, true));
  1194           t.Add(new Temperature("CPU", 0));
  1195           t.Add(new Temperature("Auxiliary", 1));
  1196           t.Add(new Temperature("System", 2));
  1197           f.Add(new Fan("System Fan", 0));
  1198           f.Add(new Fan("CPU Fan", 1));
  1199           f.Add(new Fan("Auxiliary Fan", 2));
  1200           f.Add(new Fan("CPU Fan #2", 3));
  1201           f.Add(new Fan("Auxiliary Fan #2", 4));
  1202           break;
  1203       }
  1204     }
  1205 
  1206     private static void GetWinbondConfigurationHG(Manufacturer manufacturer,
  1207       Model model, IList<Voltage> v, IList<Temperature> t, IList<Fan> f) 
  1208     {
  1209       switch (manufacturer) {
  1210         case Manufacturer.ASRock:
  1211           switch (model) {
  1212             case Model._880GMH_USB3: // W83627DHG-P
  1213               v.Add(new Voltage("CPU VCore", 0));
  1214               v.Add(new Voltage("+3.3V", 3, 34, 34));
  1215               v.Add(new Voltage("+5V", 5, 15, 7.5f));
  1216               v.Add(new Voltage("+12V", 6, 56, 10));
  1217               v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
  1218               v.Add(new Voltage("VBAT", 8, 34, 34));
  1219               t.Add(new Temperature("CPU", 0));
  1220               t.Add(new Temperature("Motherboard", 2));
  1221               f.Add(new Fan("Chassis Fan", 0));
  1222               f.Add(new Fan("CPU Fan", 1));
  1223               f.Add(new Fan("Power Fan", 2));
  1224               break;
  1225             default:
  1226               v.Add(new Voltage("CPU VCore", 0));
  1227               v.Add(new Voltage("Voltage #2", 1, true));
  1228               v.Add(new Voltage("AVCC", 2, 34, 34));
  1229               v.Add(new Voltage("3VCC", 3, 34, 34));
  1230               v.Add(new Voltage("Voltage #5", 4, true));
  1231               v.Add(new Voltage("Voltage #6", 5, true));
  1232               v.Add(new Voltage("Voltage #7", 6, true));
  1233               v.Add(new Voltage("3VSB", 7, 34, 34));
  1234               v.Add(new Voltage("VBAT", 8, 34, 34));
  1235               t.Add(new Temperature("CPU", 0));
  1236               t.Add(new Temperature("Auxiliary", 1));
  1237               t.Add(new Temperature("System", 2));
  1238               f.Add(new Fan("System Fan", 0));
  1239               f.Add(new Fan("CPU Fan", 1));
  1240               f.Add(new Fan("Auxiliary Fan", 2));
  1241               f.Add(new Fan("CPU Fan #2", 3));
  1242               f.Add(new Fan("Auxiliary Fan #2", 4));
  1243               break;
  1244           }
  1245           break;
  1246         case Manufacturer.ASUS:
  1247           switch (model) {
  1248             case Model.P6T: // W83667HG
  1249             case Model.P6X58D_E: // W83667HG                 
  1250             case Model.Rampage_II_GENE: // W83667HG 
  1251               v.Add(new Voltage("CPU VCore", 0));
  1252               v.Add(new Voltage("+12V", 1, 11.5f, 1.91f));
  1253               v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
  1254               v.Add(new Voltage("+3.3V", 3, 34, 34));
  1255               v.Add(new Voltage("+5V", 4, 15, 7.5f));
  1256               v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
  1257               v.Add(new Voltage("VBAT", 8, 34, 34));
  1258               t.Add(new Temperature("CPU", 0));
  1259               t.Add(new Temperature("Motherboard", 2));
  1260               f.Add(new Fan("Chassis Fan #1", 0));
  1261               f.Add(new Fan("CPU Fan", 1));
  1262               f.Add(new Fan("Power Fan", 2));
  1263               f.Add(new Fan("Chassis Fan #2", 3));
  1264               f.Add(new Fan("Chassis Fan #3", 4));
  1265               break;
  1266             case Model.Rampage_Extreme: // W83667HG 
  1267               v.Add(new Voltage("CPU VCore", 0));
  1268               v.Add(new Voltage("+12V", 1, 12, 2));
  1269               v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
  1270               v.Add(new Voltage("+3.3V", 3, 34, 34));
  1271               v.Add(new Voltage("+5V", 4, 15, 7.5f));
  1272               v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
  1273               v.Add(new Voltage("VBAT", 8, 34, 34));
  1274               t.Add(new Temperature("CPU", 0));
  1275               t.Add(new Temperature("Motherboard", 2));
  1276               f.Add(new Fan("Chassis Fan #1", 0));
  1277               f.Add(new Fan("CPU Fan", 1));
  1278               f.Add(new Fan("Power Fan", 2));
  1279               f.Add(new Fan("Chassis Fan #2", 3));
  1280               f.Add(new Fan("Chassis Fan #3", 4));
  1281               break;
  1282             default:
  1283               v.Add(new Voltage("CPU VCore", 0));
  1284               v.Add(new Voltage("Voltage #2", 1, true));
  1285               v.Add(new Voltage("AVCC", 2, 34, 34));
  1286               v.Add(new Voltage("3VCC", 3, 34, 34));
  1287               v.Add(new Voltage("Voltage #5", 4, true));
  1288               v.Add(new Voltage("Voltage #6", 5, true));
  1289               v.Add(new Voltage("Voltage #7", 6, true));
  1290               v.Add(new Voltage("3VSB", 7, 34, 34));
  1291               v.Add(new Voltage("VBAT", 8, 34, 34));
  1292               t.Add(new Temperature("CPU", 0));
  1293               t.Add(new Temperature("Auxiliary", 1));
  1294               t.Add(new Temperature("System", 2));
  1295               f.Add(new Fan("System Fan", 0));
  1296               f.Add(new Fan("CPU Fan", 1));
  1297               f.Add(new Fan("Auxiliary Fan", 2));
  1298               f.Add(new Fan("CPU Fan #2", 3));
  1299               f.Add(new Fan("Auxiliary Fan #2", 4));
  1300               break;
  1301           }
  1302           break;
  1303         default:
  1304           v.Add(new Voltage("CPU VCore", 0));
  1305           v.Add(new Voltage("Voltage #2", 1, true));
  1306           v.Add(new Voltage("AVCC", 2, 34, 34));
  1307           v.Add(new Voltage("3VCC", 3, 34, 34));
  1308           v.Add(new Voltage("Voltage #5", 4, true));
  1309           v.Add(new Voltage("Voltage #6", 5, true));
  1310           v.Add(new Voltage("Voltage #7", 6, true));
  1311           v.Add(new Voltage("3VSB", 7, 34, 34));
  1312           v.Add(new Voltage("VBAT", 8, 34, 34));
  1313           t.Add(new Temperature("CPU", 0));
  1314           t.Add(new Temperature("Auxiliary", 1));
  1315           t.Add(new Temperature("System", 2));
  1316           f.Add(new Fan("System Fan", 0));
  1317           f.Add(new Fan("CPU Fan", 1));
  1318           f.Add(new Fan("Auxiliary Fan", 2));
  1319           f.Add(new Fan("CPU Fan #2", 3));
  1320           f.Add(new Fan("Auxiliary Fan #2", 4));
  1321           break;
  1322       }
  1323     }
  1324 
  1325     public override HardwareType HardwareType {
  1326       get { return HardwareType.SuperIO; }
  1327     }
  1328 
  1329     public override IHardware Parent {
  1330       get { return mainboard; }
  1331     }
  1332 
  1333 
  1334     public override string GetReport() {
  1335       return superIO.GetReport();
  1336     }
  1337 
  1338     public override void Update() {
  1339       superIO.Update();
  1340 
  1341       foreach (Sensor sensor in voltages) {
  1342         float? value = readVoltage(sensor.Index);
  1343         if (value.HasValue) {
  1344           sensor.Value = value + (value - sensor.Parameters[2].Value) *
  1345             sensor.Parameters[0].Value / sensor.Parameters[1].Value;
  1346           ActivateSensor(sensor);
  1347         }
  1348       }
  1349 
  1350       foreach (Sensor sensor in temperatures) {
  1351         float? value = readTemperature(sensor.Index);
  1352         if (value.HasValue) {
  1353           sensor.Value = value + sensor.Parameters[0].Value;
  1354           ActivateSensor(sensor);
  1355         }
  1356       }
  1357 
  1358       foreach (Sensor sensor in fans) {
  1359         float? value = readFan(sensor.Index);
  1360         if (value.HasValue) {
  1361           sensor.Value = value;
  1362           if (value.Value > 0)
  1363             ActivateSensor(sensor);
  1364         }
  1365       }
  1366 
  1367       foreach (Sensor sensor in controls) {
  1368         float? value = readControl(sensor.Index);
  1369         sensor.Value = value;                
  1370       }
  1371 
  1372       postUpdate();
  1373     }
  1374 
  1375     public override void Close() {
  1376       foreach (Sensor sensor in controls) {
  1377         // restore all controls back to default
  1378         superIO.SetControl(sensor.Index, null);
  1379       }
  1380       base.Close();
  1381     }
  1382 
  1383     private class Voltage {
  1384       public readonly string Name;
  1385       public readonly int Index;
  1386       public readonly float Ri;
  1387       public readonly float Rf;
  1388       public readonly float Vf;
  1389       public readonly bool Hidden;
  1390 
  1391       public Voltage(string name, int index) :
  1392         this(name, index, false) { }
  1393       
  1394       public Voltage(string name, int index, bool hidden) :
  1395         this(name, index, 0, 1, 0, hidden) { }
  1396       
  1397       public Voltage(string name, int index, float ri, float rf) :
  1398         this(name, index, ri, rf, 0, false) { }
  1399       
  1400       // float ri = 0, float rf = 1, float vf = 0, bool hidden = false) 
  1401       
  1402       public Voltage(string name, int index, 
  1403         float ri, float rf, float vf, bool hidden) 
  1404       {
  1405         this.Name = name;
  1406         this.Index = index;
  1407         this.Ri = ri;
  1408         this.Rf = rf;
  1409         this.Vf = vf;
  1410         this.Hidden = hidden;
  1411       }
  1412     }
  1413 
  1414     private class Temperature {
  1415       public readonly string Name;
  1416       public readonly int Index;
  1417 
  1418       public Temperature(string name, int index) {
  1419         this.Name = name;
  1420         this.Index = index;
  1421       }
  1422     }
  1423 
  1424     private class Fan {
  1425       public readonly string Name;
  1426       public readonly int Index;
  1427 
  1428       public Fan(string name, int index) {
  1429         this.Name = name;
  1430         this.Index = index;
  1431       }
  1432     }
  1433 
  1434     private class Ctrl {
  1435       public readonly string Name;
  1436       public readonly int Index;
  1437 
  1438       public Ctrl(string name, int index) {
  1439         this.Name = name;
  1440         this.Index = index;
  1441       }
  1442     }
  1443   }
  1444 }