Hardware/LPC/LPCGroup.cs
author moel.mich
Thu, 28 Jan 2010 19:31:10 +0000
changeset 6 56c9d6c8c08b
child 7 9523a3322777
permissions -rw-r--r--
Fixed 5th fan channel for IT87 chips. Added ADL status code to report.
     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 const ushort REGISTER_PORT = 0x2e;
    51     private const ushort VALUE_PORT = 0x2f;
    52 
    53     // Registers
    54     private const byte CONFIGURATION_CONTROL_REGISTER = 0x02;
    55     private const byte DEVCIE_SELECT_REGISTER = 0x07;
    56     private const byte CHIP_ID_REGISTER = 0x20;
    57     private const byte CHIP_REVISION_REGISTER = 0x21;
    58 
    59     private static byte ReadByte(byte register) {
    60       WinRing0.WriteIoPortByte(REGISTER_PORT, register);
    61       return WinRing0.ReadIoPortByte(VALUE_PORT);
    62     }
    63 
    64     private static ushort ReadWord(byte register) {
    65       ushort value;
    66       WinRing0.WriteIoPortByte(REGISTER_PORT, register);
    67       value = (ushort)(((ushort)WinRing0.ReadIoPortByte(VALUE_PORT)) << 8);
    68       WinRing0.WriteIoPortByte(REGISTER_PORT, (byte)(register + 1));
    69       value |= (ushort)WinRing0.ReadIoPortByte(VALUE_PORT);
    70       return value;
    71     }
    72 
    73     private static void Select(byte logicalDeviceNumber) {
    74       WinRing0.WriteIoPortByte(REGISTER_PORT, DEVCIE_SELECT_REGISTER);
    75       WinRing0.WriteIoPortByte(VALUE_PORT, 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     private const byte IT87_ENVIRONMENT_CONTROLLER_BASE_ADDR_REG = 0x60;
    86 
    87     private static void IT87Enter() {
    88       WinRing0.WriteIoPortByte(REGISTER_PORT, 0x87);
    89       WinRing0.WriteIoPortByte(REGISTER_PORT, 0x01);
    90       WinRing0.WriteIoPortByte(REGISTER_PORT, 0x55);
    91       WinRing0.WriteIoPortByte(REGISTER_PORT, 0x55);
    92     }
    93 
    94     internal static void IT87Exit() {
    95       WinRing0.WriteIoPortByte(REGISTER_PORT, CONFIGURATION_CONTROL_REGISTER);
    96       WinRing0.WriteIoPortByte(VALUE_PORT, 0x02);
    97     }
    98 
    99     // Winbond
   100     private static void WinbondEnter() {
   101       WinRing0.WriteIoPortByte(REGISTER_PORT, 0x87);
   102       WinRing0.WriteIoPortByte(REGISTER_PORT, 0x87);
   103     }
   104 
   105     private static void WinbondExit() {
   106       WinRing0.WriteIoPortByte(REGISTER_PORT, 0xAA);      
   107     }
   108 
   109     public LPCGroup() {
   110       if (!WinRing0.IsAvailable)
   111         return;
   112 
   113       WinbondEnter();
   114 
   115       byte id = ReadByte(CHIP_ID_REGISTER);
   116       byte revision = ReadByte(CHIP_REVISION_REGISTER);
   117       switch (id) {
   118         case 0xA0:
   119           switch (revision & 0xF0) {
   120             case 0x20: chip = Chip.W83627DHG; break;
   121             default: chip = Chip.Unknown; break;
   122           } break;
   123         default: chip = Chip.Unknown; break;
   124       }
   125       if (chip != Chip.Unknown) {
   126 
   127         WinbondExit();
   128 
   129         W83627DHG w83627dhg = new W83627DHG(revision);
   130         if (w83627dhg.IsAvailable)
   131           hardware.Add(w83627dhg);
   132         return;
   133       }
   134 
   135       IT87Enter();
   136 
   137       switch (ReadWord(CHIP_ID_REGISTER)) {
   138         case 0x8716: chip = Chip.IT8716F; break;
   139         case 0x8718: chip = Chip.IT8718F; break;
   140         case 0x8720: chip = Chip.IT8720F; break;
   141         case 0x8726: chip = Chip.IT8726F; break;
   142         default: chip = Chip.Unknown; break;
   143       }
   144 
   145       if (chip != Chip.Unknown) {        
   146         Select(IT87_ENVIRONMENT_CONTROLLER_LDN);
   147         ushort address = ReadWord(IT87_ENVIRONMENT_CONTROLLER_BASE_ADDR_REG);
   148         Thread.Sleep(1);
   149         ushort verify = ReadWord(IT87_ENVIRONMENT_CONTROLLER_BASE_ADDR_REG);
   150 
   151         IT87Exit();
   152 
   153         if (address != verify || address == 0 || (address & 0xF007) != 0)
   154           return;
   155 
   156         IT87 it87 = new IT87(chip, address);
   157         if (it87.IsAvailable)
   158           hardware.Add(it87);
   159         
   160         return;
   161       }                
   162     }
   163 
   164     public IHardware[] Hardware {
   165       get {
   166         return hardware.ToArray();
   167       }
   168     }
   169 
   170     public string GetReport() {
   171       return null;
   172     }
   173 
   174     public void Close() { }
   175   }
   176 }