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