Hardware/LPC/LPCGroup.cs
changeset 7 9523a3322777
parent 1 361e324a0ed4
child 9 e5adb0fd4917
     1.1 --- a/Hardware/LPC/LPCGroup.cs	Thu Jan 28 19:31:10 2010 +0000
     1.2 +++ b/Hardware/LPC/LPCGroup.cs	Thu Jan 28 23:29:39 2010 +0000
     1.3 @@ -47,32 +47,32 @@
     1.4      private Chip chip = Chip.Unknown;
     1.5  
     1.6      // I/O Ports
     1.7 -    private const ushort REGISTER_PORT = 0x2e;
     1.8 -    private const ushort VALUE_PORT = 0x2f;
     1.9 +    private ushort[] REGISTER_PORTS = new ushort[] { 0x2e, 0x4e };
    1.10 +    private ushort[] VALUE_PORTS = new ushort[] { 0x2f, 0x4f };
    1.11 +
    1.12 +    private ushort registerPort;
    1.13 +    private ushort valuePort;
    1.14  
    1.15      // Registers
    1.16      private const byte CONFIGURATION_CONTROL_REGISTER = 0x02;
    1.17      private const byte DEVCIE_SELECT_REGISTER = 0x07;
    1.18      private const byte CHIP_ID_REGISTER = 0x20;
    1.19      private const byte CHIP_REVISION_REGISTER = 0x21;
    1.20 +    private const byte BASE_ADDRESS_REGISTER = 0x60;
    1.21  
    1.22 -    private static byte ReadByte(byte register) {
    1.23 -      WinRing0.WriteIoPortByte(REGISTER_PORT, register);
    1.24 -      return WinRing0.ReadIoPortByte(VALUE_PORT);
    1.25 +    private byte ReadByte(byte register) {
    1.26 +      WinRing0.WriteIoPortByte(registerPort, register);
    1.27 +      return WinRing0.ReadIoPortByte(valuePort);
    1.28      }
    1.29  
    1.30 -    private static ushort ReadWord(byte register) {
    1.31 -      ushort value;
    1.32 -      WinRing0.WriteIoPortByte(REGISTER_PORT, register);
    1.33 -      value = (ushort)(((ushort)WinRing0.ReadIoPortByte(VALUE_PORT)) << 8);
    1.34 -      WinRing0.WriteIoPortByte(REGISTER_PORT, (byte)(register + 1));
    1.35 -      value |= (ushort)WinRing0.ReadIoPortByte(VALUE_PORT);
    1.36 -      return value;
    1.37 +    private ushort ReadWord(byte register) {
    1.38 +      return (ushort)((ReadByte(register) << 8) | 
    1.39 +        ReadByte((byte)(register + 1)));
    1.40      }
    1.41  
    1.42 -    private static void Select(byte logicalDeviceNumber) {
    1.43 -      WinRing0.WriteIoPortByte(REGISTER_PORT, DEVCIE_SELECT_REGISTER);
    1.44 -      WinRing0.WriteIoPortByte(VALUE_PORT, logicalDeviceNumber);
    1.45 +    private void Select(byte logicalDeviceNumber) {
    1.46 +      WinRing0.WriteIoPortByte(registerPort, DEVCIE_SELECT_REGISTER);
    1.47 +      WinRing0.WriteIoPortByte(valuePort, logicalDeviceNumber);
    1.48      }
    1.49  
    1.50      // IT87
    1.51 @@ -81,84 +81,137 @@
    1.52      private const ushort IT8720F_CHIP_ID = 0x8720;
    1.53      private const ushort IT8726F_CHIP_ID = 0x8726;
    1.54  
    1.55 -    private const byte IT87_ENVIRONMENT_CONTROLLER_LDN = 0x04;
    1.56 -    private const byte IT87_ENVIRONMENT_CONTROLLER_BASE_ADDR_REG = 0x60;
    1.57 +    private const byte IT87_ENVIRONMENT_CONTROLLER_LDN = 0x04;    
    1.58  
    1.59 -    private static void IT87Enter() {
    1.60 -      WinRing0.WriteIoPortByte(REGISTER_PORT, 0x87);
    1.61 -      WinRing0.WriteIoPortByte(REGISTER_PORT, 0x01);
    1.62 -      WinRing0.WriteIoPortByte(REGISTER_PORT, 0x55);
    1.63 -      WinRing0.WriteIoPortByte(REGISTER_PORT, 0x55);
    1.64 +    private void IT87Enter() {
    1.65 +      WinRing0.WriteIoPortByte(registerPort, 0x87);
    1.66 +      WinRing0.WriteIoPortByte(registerPort, 0x01);
    1.67 +      WinRing0.WriteIoPortByte(registerPort, 0x55);
    1.68 +      WinRing0.WriteIoPortByte(registerPort, 0x55);
    1.69      }
    1.70  
    1.71 -    internal static void IT87Exit() {
    1.72 -      WinRing0.WriteIoPortByte(REGISTER_PORT, CONFIGURATION_CONTROL_REGISTER);
    1.73 -      WinRing0.WriteIoPortByte(VALUE_PORT, 0x02);
    1.74 +    internal void IT87Exit() {
    1.75 +      WinRing0.WriteIoPortByte(registerPort, CONFIGURATION_CONTROL_REGISTER);
    1.76 +      WinRing0.WriteIoPortByte(valuePort, 0x02);
    1.77      }
    1.78  
    1.79 -    // Winbond
    1.80 -    private static void WinbondEnter() {
    1.81 -      WinRing0.WriteIoPortByte(REGISTER_PORT, 0x87);
    1.82 -      WinRing0.WriteIoPortByte(REGISTER_PORT, 0x87);
    1.83 +    // Winbond, Fintek
    1.84 +    private const byte FINTEK_VENDOR_ID_REGISTER = 0x23;
    1.85 +    private const ushort FINTEK_VENDOR_ID = 0x1934;
    1.86 +
    1.87 +    private const byte W83627DHG_HARDWARE_MONITOR_LDN = 0x0B;
    1.88 +    private const byte F71882FG_HARDWARE_MONITOR_LDN = 0x04;
    1.89 +
    1.90 +    private void WinbondFintekEnter() {
    1.91 +      WinRing0.WriteIoPortByte(registerPort, 0x87);
    1.92 +      WinRing0.WriteIoPortByte(registerPort, 0x87);
    1.93      }
    1.94  
    1.95 -    private static void WinbondExit() {
    1.96 -      WinRing0.WriteIoPortByte(REGISTER_PORT, 0xAA);      
    1.97 +    private void WinbondFintekExit() {
    1.98 +      WinRing0.WriteIoPortByte(registerPort, 0xAA);      
    1.99      }
   1.100  
   1.101      public LPCGroup() {
   1.102        if (!WinRing0.IsAvailable)
   1.103          return;
   1.104  
   1.105 -      WinbondEnter();
   1.106 +      for (int i = 0; i < REGISTER_PORTS.Length; i++) {
   1.107 +        registerPort = REGISTER_PORTS[i];
   1.108 +        valuePort = VALUE_PORTS[i];
   1.109  
   1.110 -      byte id = ReadByte(CHIP_ID_REGISTER);
   1.111 -      byte revision = ReadByte(CHIP_REVISION_REGISTER);
   1.112 -      switch (id) {
   1.113 -        case 0xA0:
   1.114 -          switch (revision & 0xF0) {
   1.115 -            case 0x20: chip = Chip.W83627DHG; break;
   1.116 -            default: chip = Chip.Unknown; break;
   1.117 -          } break;
   1.118 -        default: chip = Chip.Unknown; break;
   1.119 -      }
   1.120 -      if (chip != Chip.Unknown) {
   1.121 +        WinbondFintekEnter();
   1.122  
   1.123 -        WinbondExit();
   1.124 +        byte hardwareMonitorLDN;
   1.125 +        byte id = ReadByte(CHIP_ID_REGISTER);
   1.126 +        byte revision = ReadByte(CHIP_REVISION_REGISTER);
   1.127 +        switch (id) {
   1.128 +          case 0xA0:
   1.129 +            switch (revision & 0xF0) {
   1.130 +              case 0x20: 
   1.131 +                chip = Chip.W83627DHG;
   1.132 +                hardwareMonitorLDN = W83627DHG_HARDWARE_MONITOR_LDN;  
   1.133 +                break;
   1.134 +              default: 
   1.135 +                chip = Chip.Unknown;
   1.136 +                hardwareMonitorLDN = 0;
   1.137 +                break;
   1.138 +            } break;
   1.139 +          case 0x05:
   1.140 +            switch (revision) {
   1.141 +              case 0x41: 
   1.142 +                chip = Chip.F71882FG;
   1.143 +                hardwareMonitorLDN = F71882FG_HARDWARE_MONITOR_LDN; 
   1.144 +                break;
   1.145 +              default: 
   1.146 +                chip = Chip.Unknown; 
   1.147 +                hardwareMonitorLDN = 0;
   1.148 +                break;
   1.149 +            } break;
   1.150 +          default:
   1.151 +            chip = Chip.Unknown; 
   1.152 +            hardwareMonitorLDN = 0;
   1.153 +            break;
   1.154 +        }
   1.155 +        if (chip != Chip.Unknown) {
   1.156  
   1.157 -        W83627DHG w83627dhg = new W83627DHG(revision);
   1.158 -        if (w83627dhg.IsAvailable)
   1.159 -          hardware.Add(w83627dhg);
   1.160 -        return;
   1.161 -      }
   1.162 +          Select(hardwareMonitorLDN);
   1.163 +          ushort address = ReadWord(BASE_ADDRESS_REGISTER);
   1.164 +          Thread.Sleep(1);
   1.165 +          ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
   1.166  
   1.167 -      IT87Enter();
   1.168 +          ushort vendorID = 0;
   1.169 +          if (chip == Chip.F71882FG)
   1.170 +            vendorID = ReadWord(FINTEK_VENDOR_ID_REGISTER);
   1.171  
   1.172 -      switch (ReadWord(CHIP_ID_REGISTER)) {
   1.173 -        case 0x8716: chip = Chip.IT8716F; break;
   1.174 -        case 0x8718: chip = Chip.IT8718F; break;
   1.175 -        case 0x8720: chip = Chip.IT8720F; break;
   1.176 -        case 0x8726: chip = Chip.IT8726F; break;
   1.177 -        default: chip = Chip.Unknown; break;
   1.178 -      }
   1.179 +          WinbondFintekExit();
   1.180  
   1.181 -      if (chip != Chip.Unknown) {        
   1.182 -        Select(IT87_ENVIRONMENT_CONTROLLER_LDN);
   1.183 -        ushort address = ReadWord(IT87_ENVIRONMENT_CONTROLLER_BASE_ADDR_REG);
   1.184 -        Thread.Sleep(1);
   1.185 -        ushort verify = ReadWord(IT87_ENVIRONMENT_CONTROLLER_BASE_ADDR_REG);
   1.186 +          if (address != verify || address == 0 || (address & 0xF007) != 0)
   1.187 +            return;
   1.188 +          
   1.189 +          switch (chip) {
   1.190 +            case Chip.W83627DHG:
   1.191 +              W83627DHG w83627dhg = new W83627DHG(revision, address);
   1.192 +              if (w83627dhg.IsAvailable)
   1.193 +                hardware.Add(w83627dhg);
   1.194 +              break;
   1.195 +            case Chip.F71882FG:  
   1.196 +              if (vendorID == FINTEK_VENDOR_ID)
   1.197 +                hardware.Add(new F71882FG(address));
   1.198 +              break;
   1.199 +            default: break;
   1.200 +          }
   1.201 +          
   1.202 +          return;
   1.203 +        }
   1.204  
   1.205 -        IT87Exit();
   1.206 +        IT87Enter();
   1.207  
   1.208 -        if (address != verify || address == 0 || (address & 0xF007) != 0)
   1.209 +        switch (ReadWord(CHIP_ID_REGISTER)) {
   1.210 +          case 0x8716: chip = Chip.IT8716F; break;
   1.211 +          case 0x8718: chip = Chip.IT8718F; break;
   1.212 +          case 0x8720: chip = Chip.IT8720F; break;
   1.213 +          case 0x8726: chip = Chip.IT8726F; break;
   1.214 +          default: chip = Chip.Unknown; break;
   1.215 +        }
   1.216 +
   1.217 +        if (chip != Chip.Unknown) {
   1.218 +          Select(IT87_ENVIRONMENT_CONTROLLER_LDN);
   1.219 +          ushort address = ReadWord(BASE_ADDRESS_REGISTER);
   1.220 +          Thread.Sleep(1);
   1.221 +          ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
   1.222 +
   1.223 +          IT87Exit();
   1.224 +
   1.225 +          if (address != verify || address == 0 || (address & 0xF007) != 0)
   1.226 +            return;
   1.227 +
   1.228 +          IT87 it87 = new IT87(chip, address);
   1.229 +          if (it87.IsAvailable)
   1.230 +            hardware.Add(it87);
   1.231 +
   1.232            return;
   1.233 -
   1.234 -        IT87 it87 = new IT87(chip, address);
   1.235 -        if (it87.IsAvailable)
   1.236 -          hardware.Add(it87);
   1.237 -        
   1.238 -        return;
   1.239 -      }                
   1.240 +        }
   1.241 +      }   
   1.242      }
   1.243  
   1.244      public IHardware[] Hardware {