Hardware/LPC/LPCGroup.cs
author moel.mich
Sun, 07 Feb 2010 19:53:51 +0000
changeset 31 c4d1fb76a9e1
parent 21 ac4bfce27a02
child 34 dc276daadb2c
permissions -rw-r--r--
Added initial support for W83627HF. Some refactoring for IHardware classes.
     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-2010
    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.Text;
    41 using System.Threading;
    42 
    43 namespace OpenHardwareMonitor.Hardware.LPC {
    44   public class LPCGroup : IGroup {
    45     private List<IHardware> hardware = new List<IHardware>();
    46 
    47     private Chip chip = Chip.Unknown;
    48 
    49     // I/O Ports
    50     private ushort[] REGISTER_PORTS = new ushort[] { 0x2e, 0x4e };
    51     private ushort[] VALUE_PORTS = new ushort[] { 0x2f, 0x4f };
    52 
    53     private ushort registerPort;
    54     private ushort valuePort;
    55 
    56     // Registers
    57     private const byte CONFIGURATION_CONTROL_REGISTER = 0x02;
    58     private const byte DEVCIE_SELECT_REGISTER = 0x07;
    59     private const byte CHIP_ID_REGISTER = 0x20;
    60     private const byte CHIP_REVISION_REGISTER = 0x21;
    61     private const byte BASE_ADDRESS_REGISTER = 0x60;
    62 
    63     private byte ReadByte(byte register) {
    64       WinRing0.WriteIoPortByte(registerPort, register);
    65       return WinRing0.ReadIoPortByte(valuePort);
    66     } 
    67 
    68     private ushort ReadWord(byte register) {
    69       return (ushort)((ReadByte(register) << 8) | 
    70         ReadByte((byte)(register + 1)));
    71     }
    72 
    73     private void Select(byte logicalDeviceNumber) {
    74       WinRing0.WriteIoPortByte(registerPort, DEVCIE_SELECT_REGISTER);
    75       WinRing0.WriteIoPortByte(valuePort, logicalDeviceNumber);
    76     }
    77 
    78     private const byte IT87_ENVIRONMENT_CONTROLLER_LDN = 0x04;    
    79 
    80     private void IT87Enter() {
    81       WinRing0.WriteIoPortByte(registerPort, 0x87);
    82       WinRing0.WriteIoPortByte(registerPort, 0x01);
    83       WinRing0.WriteIoPortByte(registerPort, 0x55);
    84       WinRing0.WriteIoPortByte(registerPort, 0x55);
    85     }
    86 
    87     internal void IT87Exit() {
    88       WinRing0.WriteIoPortByte(registerPort, CONFIGURATION_CONTROL_REGISTER);
    89       WinRing0.WriteIoPortByte(valuePort, 0x02);
    90     }
    91 
    92     // Winbond, Fintek
    93     private const byte FINTEK_VENDOR_ID_REGISTER = 0x23;
    94     private const ushort FINTEK_VENDOR_ID = 0x1934;
    95 
    96     private const byte W83627_HARDWARE_MONITOR_LDN = 0x0B;
    97 
    98     private const byte F71858_HARDWARE_MONITOR_LDN = 0x02;
    99     private const byte FINTEK_HARDWARE_MONITOR_LDN = 0x04;
   100 
   101     private void WinbondFintekEnter() {
   102       WinRing0.WriteIoPortByte(registerPort, 0x87);
   103       WinRing0.WriteIoPortByte(registerPort, 0x87);
   104     }
   105 
   106     private void WinbondFintekExit() {
   107       WinRing0.WriteIoPortByte(registerPort, 0xAA);      
   108     }
   109 
   110     public LPCGroup() {
   111       if (!WinRing0.IsAvailable)
   112         return;
   113 
   114       for (int i = 0; i < REGISTER_PORTS.Length; i++) {
   115         registerPort = REGISTER_PORTS[i];
   116         valuePort = VALUE_PORTS[i];
   117 
   118         WinbondFintekEnter();
   119 
   120         byte logicalDeviceNumber;
   121         byte id = ReadByte(CHIP_ID_REGISTER);
   122         byte revision = ReadByte(CHIP_REVISION_REGISTER);
   123         switch (id) {
   124           case 0x05:
   125             switch (revision) {
   126               case 0x41:
   127                 chip = Chip.F71882;
   128                 logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
   129                 break;
   130               default:
   131                 chip = Chip.Unknown;
   132                 logicalDeviceNumber = 0;
   133                 break;
   134             } break;
   135           case 0x06:
   136             switch (revision) {             
   137               case 0x01:
   138                 chip = Chip.F71862;
   139                 logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
   140                 break;
   141               default:
   142                 chip = Chip.Unknown;
   143                 logicalDeviceNumber = 0;
   144                 break;
   145             } break;
   146           case 0x07:
   147             switch (revision) {
   148               case 0x23:
   149                 chip = Chip.F71889;
   150                 logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
   151                 break;
   152               default:
   153                 chip = Chip.Unknown;
   154                 logicalDeviceNumber = 0;
   155                 break;
   156             } break;
   157           case 0x08:
   158             switch (revision) {
   159               case 0x14:
   160                 chip = Chip.F71869;
   161                 logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
   162                 break;
   163               default:
   164                 chip = Chip.Unknown;
   165                 logicalDeviceNumber = 0;
   166                 break;
   167             } break;
   168           case 0x52:
   169             switch (revision) {
   170               case 0x17:
   171               case 0x3A:
   172                 chip = Chip.W83627HF;
   173                 logicalDeviceNumber = W83627_HARDWARE_MONITOR_LDN;
   174                 break;
   175               default:
   176                 chip = Chip.Unknown;
   177                 logicalDeviceNumber = 0;
   178                 break;
   179             } break;
   180           case 0xA0:
   181             switch (revision & 0xF0) {
   182               case 0x20: 
   183                 chip = Chip.W83627DHG;
   184                 logicalDeviceNumber = W83627_HARDWARE_MONITOR_LDN;  
   185                 break;
   186               default: 
   187                 chip = Chip.Unknown;
   188                 logicalDeviceNumber = 0;
   189                 break;
   190             } break;
   191           case 0xB0:
   192             switch (revision & 0xF0) {
   193               case 0x70:
   194                 chip = Chip.W83627DHGP;
   195                 logicalDeviceNumber = W83627_HARDWARE_MONITOR_LDN;
   196                 break;
   197               default:
   198                 chip = Chip.Unknown;
   199                 logicalDeviceNumber = 0;
   200                 break;
   201             } break;  
   202           default:
   203             chip = Chip.Unknown; 
   204             logicalDeviceNumber = 0;
   205             break;
   206         }
   207         if (chip != Chip.Unknown) {
   208 
   209           Select(logicalDeviceNumber);
   210           ushort address = ReadWord(BASE_ADDRESS_REGISTER);
   211           Thread.Sleep(1);
   212           ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
   213 
   214           ushort vendorID = 0;
   215           if (chip == Chip.F71862 || chip == Chip.F71882 || chip == Chip.F71889)
   216             vendorID = ReadWord(FINTEK_VENDOR_ID_REGISTER);
   217 
   218           WinbondFintekExit();
   219 
   220           if (address != verify || address == 0 || (address & 0xF007) != 0)
   221             return;
   222           
   223           switch (chip) {
   224             case Chip.W83627DHG:
   225             case Chip.W83627DHGP:
   226             case Chip.W83627HF:
   227               W83627 w83627 = new W83627(chip, revision, address);
   228               if (w83627.IsAvailable)
   229                 hardware.Add(w83627);
   230               break;
   231             case Chip.F71862:
   232             case Chip.F71882:
   233             case Chip.F71889: 
   234               if (vendorID == FINTEK_VENDOR_ID)
   235                 hardware.Add(new F718XX(chip, address));
   236               break;
   237             case Chip.F71869:
   238               hardware.Add(new F718XX(chip, address));
   239               break;
   240             default: break;
   241           }
   242           
   243           return;
   244         }
   245 
   246         IT87Enter();
   247 
   248         switch (ReadWord(CHIP_ID_REGISTER)) {
   249           case 0x8716: chip = Chip.IT8716F; break;
   250           case 0x8718: chip = Chip.IT8718F; break;
   251           case 0x8720: chip = Chip.IT8720F; break;
   252           case 0x8726: chip = Chip.IT8726F; break;
   253           default: chip = Chip.Unknown; break;
   254         }
   255 
   256         if (chip != Chip.Unknown) {
   257           Select(IT87_ENVIRONMENT_CONTROLLER_LDN);
   258           ushort address = ReadWord(BASE_ADDRESS_REGISTER);
   259           Thread.Sleep(1);
   260           ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
   261 
   262           IT87Exit();
   263 
   264           if (address != verify || address == 0 || (address & 0xF007) != 0)
   265             return;
   266 
   267           IT87XX it87 = new IT87XX(chip, address);
   268           if (it87.IsAvailable)
   269             hardware.Add(it87);
   270 
   271           return;
   272         }
   273       }   
   274     }
   275 
   276     public IHardware[] Hardware {
   277       get {
   278         return hardware.ToArray();
   279       }
   280     }
   281 
   282     public string GetReport() {
   283       return null;
   284     }
   285 
   286     public void Close() { }
   287   }
   288 }