Hardware/LPC/LPCGroup.cs
author moel.mich
Mon, 01 Feb 2010 20:16:26 +0000
changeset 16 e9abdc6e05af
parent 13 d32fc5f2e822
child 19 890e8fca7f33
permissions -rw-r--r--
Added support for Fintek F71862, F71869, F71889.
     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 W83627DHG_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 0xA0:
   169             switch (revision & 0xF0) {
   170               case 0x20: 
   171                 chip = Chip.W83627DHG;
   172                 logicalDeviceNumber = W83627DHG_HARDWARE_MONITOR_LDN;  
   173                 break;
   174               default: 
   175                 chip = Chip.Unknown;
   176                 logicalDeviceNumber = 0;
   177                 break;
   178             } break;          
   179           default:
   180             chip = Chip.Unknown; 
   181             logicalDeviceNumber = 0;
   182             break;
   183         }
   184         if (chip != Chip.Unknown) {
   185 
   186           Select(logicalDeviceNumber);
   187           ushort address = ReadWord(BASE_ADDRESS_REGISTER);
   188           Thread.Sleep(1);
   189           ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
   190 
   191           ushort vendorID = 0;
   192           if (chip == Chip.F71862 || chip == Chip.F71882 || chip == Chip.F71889)
   193             vendorID = ReadWord(FINTEK_VENDOR_ID_REGISTER);
   194 
   195           WinbondFintekExit();
   196 
   197           if (address != verify || address == 0 || (address & 0xF007) != 0)
   198             return;
   199           
   200           switch (chip) {
   201             case Chip.W83627DHG:
   202               W83627DHG w83627dhg = new W83627DHG(revision, address);
   203               if (w83627dhg.IsAvailable)
   204                 hardware.Add(w83627dhg);
   205               break;
   206             case Chip.F71862:
   207             case Chip.F71882:
   208             case Chip.F71889: 
   209               if (vendorID == FINTEK_VENDOR_ID)
   210                 hardware.Add(new F718XX(chip, address));
   211               break;
   212             case Chip.F71869:
   213               hardware.Add(new F718XX(chip, address));
   214               break;
   215             default: break;
   216           }
   217           
   218           return;
   219         }
   220 
   221         IT87Enter();
   222 
   223         switch (ReadWord(CHIP_ID_REGISTER)) {
   224           case 0x8716: chip = Chip.IT8716; break;
   225           case 0x8718: chip = Chip.IT8718; break;
   226           case 0x8720: chip = Chip.IT8720; break;
   227           case 0x8726: chip = Chip.IT8726; break;
   228           default: chip = Chip.Unknown; break;
   229         }
   230 
   231         if (chip != Chip.Unknown) {
   232           Select(IT87_ENVIRONMENT_CONTROLLER_LDN);
   233           ushort address = ReadWord(BASE_ADDRESS_REGISTER);
   234           Thread.Sleep(1);
   235           ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
   236 
   237           IT87Exit();
   238 
   239           if (address != verify || address == 0 || (address & 0xF007) != 0)
   240             return;
   241 
   242           IT87XX it87 = new IT87XX(chip, address);
   243           if (it87.IsAvailable)
   244             hardware.Add(it87);
   245 
   246           return;
   247         }
   248       }   
   249     }
   250 
   251     public IHardware[] Hardware {
   252       get {
   253         return hardware.ToArray();
   254       }
   255     }
   256 
   257     public string GetReport() {
   258       return null;
   259     }
   260 
   261     public void Close() { }
   262   }
   263 }