Hardware/LPC/LPCGroup.cs
author moel.mich
Sun, 31 Jan 2010 22:00:31 +0000
changeset 15 0e812fe67bac
parent 9 e5adb0fd4917
child 16 e9abdc6e05af
permissions -rw-r--r--
Release version 0.1.6. Fixed F71882 temperature reading. Added error handling for ATI GPUs (ADL). Fixed sensor events.
     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     // IT87
    79     private const ushort IT8716F_CHIP_ID = 0x8716;
    80     private const ushort IT8718F_CHIP_ID = 0x8718;
    81     private const ushort IT8720F_CHIP_ID = 0x8720;
    82     private const ushort IT8726F_CHIP_ID = 0x8726;
    83 
    84     private const byte IT87_ENVIRONMENT_CONTROLLER_LDN = 0x04;    
    85 
    86     private void IT87Enter() {
    87       WinRing0.WriteIoPortByte(registerPort, 0x87);
    88       WinRing0.WriteIoPortByte(registerPort, 0x01);
    89       WinRing0.WriteIoPortByte(registerPort, 0x55);
    90       WinRing0.WriteIoPortByte(registerPort, 0x55);
    91     }
    92 
    93     internal void IT87Exit() {
    94       WinRing0.WriteIoPortByte(registerPort, CONFIGURATION_CONTROL_REGISTER);
    95       WinRing0.WriteIoPortByte(valuePort, 0x02);
    96     }
    97 
    98     // Winbond, Fintek
    99     private const byte FINTEK_VENDOR_ID_REGISTER = 0x23;
   100     private const ushort FINTEK_VENDOR_ID = 0x1934;
   101 
   102     private const byte W83627DHG_HARDWARE_MONITOR_LDN = 0x0B;
   103     private const byte F71882FG_HARDWARE_MONITOR_LDN = 0x04;
   104 
   105     private void WinbondFintekEnter() {
   106       WinRing0.WriteIoPortByte(registerPort, 0x87);
   107       WinRing0.WriteIoPortByte(registerPort, 0x87);
   108     }
   109 
   110     private void WinbondFintekExit() {
   111       WinRing0.WriteIoPortByte(registerPort, 0xAA);      
   112     }
   113 
   114     public LPCGroup() {
   115       if (!WinRing0.IsAvailable)
   116         return;
   117 
   118       for (int i = 0; i < REGISTER_PORTS.Length; i++) {
   119         registerPort = REGISTER_PORTS[i];
   120         valuePort = VALUE_PORTS[i];
   121 
   122         WinbondFintekEnter();
   123 
   124         byte hardwareMonitorLDN;
   125         byte id = ReadByte(CHIP_ID_REGISTER);
   126         byte revision = ReadByte(CHIP_REVISION_REGISTER);
   127         switch (id) {
   128           case 0xA0:
   129             switch (revision & 0xF0) {
   130               case 0x20: 
   131                 chip = Chip.W83627DHG;
   132                 hardwareMonitorLDN = W83627DHG_HARDWARE_MONITOR_LDN;  
   133                 break;
   134               default: 
   135                 chip = Chip.Unknown;
   136                 hardwareMonitorLDN = 0;
   137                 break;
   138             } break;
   139           case 0x05:
   140             switch (revision) {
   141               case 0x41: 
   142                 chip = Chip.F71882FG;
   143                 hardwareMonitorLDN = F71882FG_HARDWARE_MONITOR_LDN; 
   144                 break;
   145               default: 
   146                 chip = Chip.Unknown; 
   147                 hardwareMonitorLDN = 0;
   148                 break;
   149             } break;
   150           default:
   151             chip = Chip.Unknown; 
   152             hardwareMonitorLDN = 0;
   153             break;
   154         }
   155         if (chip != Chip.Unknown) {
   156 
   157           Select(hardwareMonitorLDN);
   158           ushort address = ReadWord(BASE_ADDRESS_REGISTER);
   159           Thread.Sleep(1);
   160           ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
   161 
   162           ushort vendorID = 0;
   163           if (chip == Chip.F71882FG)
   164             vendorID = ReadWord(FINTEK_VENDOR_ID_REGISTER);
   165 
   166           WinbondFintekExit();
   167 
   168           if (address != verify || address == 0 || (address & 0xF007) != 0)
   169             return;
   170           
   171           switch (chip) {
   172             case Chip.W83627DHG:
   173               W83627DHG w83627dhg = new W83627DHG(revision, address);
   174               if (w83627dhg.IsAvailable)
   175                 hardware.Add(w83627dhg);
   176               break;
   177             case Chip.F71882FG:  
   178               if (vendorID == FINTEK_VENDOR_ID)
   179                 hardware.Add(new F71882(address));
   180               break;
   181             default: break;
   182           }
   183           
   184           return;
   185         }
   186 
   187         IT87Enter();
   188 
   189         switch (ReadWord(CHIP_ID_REGISTER)) {
   190           case 0x8716: chip = Chip.IT8716F; break;
   191           case 0x8718: chip = Chip.IT8718F; break;
   192           case 0x8720: chip = Chip.IT8720F; break;
   193           case 0x8726: chip = Chip.IT8726F; break;
   194           default: chip = Chip.Unknown; break;
   195         }
   196 
   197         if (chip != Chip.Unknown) {
   198           Select(IT87_ENVIRONMENT_CONTROLLER_LDN);
   199           ushort address = ReadWord(BASE_ADDRESS_REGISTER);
   200           Thread.Sleep(1);
   201           ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
   202 
   203           IT87Exit();
   204 
   205           if (address != verify || address == 0 || (address & 0xF007) != 0)
   206             return;
   207 
   208           IT87 it87 = new IT87(chip, address);
   209           if (it87.IsAvailable)
   210             hardware.Add(it87);
   211 
   212           return;
   213         }
   214       }   
   215     }
   216 
   217     public IHardware[] Hardware {
   218       get {
   219         return hardware.ToArray();
   220       }
   221     }
   222 
   223     public string GetReport() {
   224       return null;
   225     }
   226 
   227     public void Close() { }
   228   }
   229 }