Extended the ITE super I/O voltage reading by adding hidden voltage sensors for unknown channels. Added a few known DFI and Gigabyte mainboard voltage configurations.
3 Version: MPL 1.1/GPL 2.0/LGPL 2.1
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
9 http://www.mozilla.org/MPL/
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.
15 The Original Code is the Open Hardware Monitor code.
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.
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.
39 using System.Collections.Generic;
43 namespace OpenHardwareMonitor.Hardware.LPC {
44 public class IT87XX : LPCHardware, IHardware {
46 private bool available = false;
47 private ushort address;
49 private readonly ushort addressReg;
50 private readonly ushort dataReg;
52 private List<Sensor> voltages = new List<Sensor>(9);
53 private List<Sensor> temperatures = new List<Sensor>(3);
54 private Sensor[] fans;
57 private const byte ITE_VENDOR_ID = 0x90;
59 // Environment Controller
60 private const byte ADDRESS_REGISTER_OFFSET = 0x05;
61 private const byte DATA_REGISTER_OFFSET = 0x06;
63 // Environment Controller Registers
64 private const byte CONFIGURATION_REGISTER = 0x00;
65 private const byte TEMPERATURE_BASE_REG = 0x29;
66 private const byte VENDOR_ID_REGISTER = 0x58;
67 private const byte FAN_TACHOMETER_16_BIT_ENABLE_REGISTER = 0x0c;
68 private byte[] FAN_TACHOMETER_REG =
69 new byte[] { 0x0d, 0x0e, 0x0f, 0x80, 0x82 };
70 private byte[] FAN_TACHOMETER_EXT_REG =
71 new byte[] { 0x18, 0x19, 0x1a, 0x81, 0x83 };
72 private const byte VOLTAGE_BASE_REG = 0x20;
74 private byte ReadByte(byte register, out bool valid) {
75 WinRing0.WriteIoPortByte(addressReg, register);
76 byte value = WinRing0.ReadIoPortByte(dataReg);
77 valid = register == WinRing0.ReadIoPortByte(addressReg);
81 public IT87XX(Chip chip, ushort address, Mainboard.Manufacturer
82 mainboardManufacturer, Mainboard.Model mainboardModel) : base (chip) {
84 this.address = address;
85 this.addressReg = (ushort)(address + ADDRESS_REGISTER_OFFSET);
86 this.dataReg = (ushort)(address + DATA_REGISTER_OFFSET);
90 byte vendorId = ReadByte(VENDOR_ID_REGISTER, out valid);
91 if (!valid || vendorId != ITE_VENDOR_ID)
94 // Bit 0x10 of the configuration register should always be 1
95 if ((ReadByte(CONFIGURATION_REGISTER, out valid) & 0x10) == 0)
100 string[] temperatureLabels;
101 List<Voltage> voltageConfigs = new List<Voltage>();
102 switch (mainboardManufacturer) {
103 case Mainboard.Manufacturer.DFI:
104 switch (mainboardModel) {
105 case Mainboard.Model.LP_BI_P45_T2RS_Elite:
106 voltageConfigs.Add(new Voltage("CPU VCore", 0));
107 voltageConfigs.Add(new Voltage("FSB VTT", 1));
108 voltageConfigs.Add(new Voltage("+3.3V", 2));
109 voltageConfigs.Add(new Voltage("+5V", 3, 6.8f, 10, 0));
110 voltageConfigs.Add(new Voltage("+12V", 4, 30, 10, 0));
111 voltageConfigs.Add(new Voltage("NB Core", 5));
112 voltageConfigs.Add(new Voltage("VDIMM", 6));
113 voltageConfigs.Add(new Voltage("+5VSB", 7, 6.8f, 10, 0));
114 voltageConfigs.Add(new Voltage("VBat", 8));
115 temperatureLabels = new string[] {
116 "CPU", "System", "Chipset" };
118 case Mainboard.Model.LP_DK_P55_T3eH9:
119 voltageConfigs.Add(new Voltage("CPU VCore", 0));
120 voltageConfigs.Add(new Voltage("VTT", 1));
121 voltageConfigs.Add(new Voltage("+3.3V", 2));
122 voltageConfigs.Add(new Voltage("+5V", 3, 6.8f, 10, 0));
123 voltageConfigs.Add(new Voltage("+12V", 4, 30, 10, 0));
124 voltageConfigs.Add(new Voltage("CPU PLL", 5));
125 voltageConfigs.Add(new Voltage("DRAM", 6));
126 voltageConfigs.Add(new Voltage("+5VSB", 7, 6.8f, 10, 0));
127 voltageConfigs.Add(new Voltage("VBat", 8));
128 temperatureLabels = new string[] {
129 "Chipset", "CPU PWM", "CPU" };
132 voltageConfigs.Add(new Voltage("CPU VCore", 0));
133 voltageConfigs.Add(new Voltage("VTT", 1, true));
134 voltageConfigs.Add(new Voltage("+3.3V", 2, true));
135 voltageConfigs.Add(new Voltage("+5V", 3, 6.8f, 10, 0, true));
136 voltageConfigs.Add(new Voltage("+12V", 4, 30, 10, 0, true));
137 voltageConfigs.Add(new Voltage("Voltage #6", 5, true));
138 voltageConfigs.Add(new Voltage("DRAM", 6, true));
139 voltageConfigs.Add(new Voltage("+5VSB", 7, 6.8f, 10, 0, true));
140 voltageConfigs.Add(new Voltage("VBat", 8));
141 temperatureLabels = new string[] {
142 "Temperature #1", "Temperature #2", "Temperature #3" };
147 case Mainboard.Manufacturer.Gigabyte:
148 switch (mainboardModel) {
149 case Mainboard.Model.EP45_DS3R:
150 case Mainboard.Model.P35_DS3:
151 voltageConfigs.Add(new Voltage("CPU VCore", 0));
152 voltageConfigs.Add(new Voltage("DRAM", 1));
153 voltageConfigs.Add(new Voltage("+3.3V", 2));
154 voltageConfigs.Add(new Voltage("+5V", 3, 6.8f, 10, 0));
155 voltageConfigs.Add(new Voltage("+12V", 7, 27, 9.1f, 0));
156 voltageConfigs.Add(new Voltage("VBat", 8));
158 case Mainboard.Model.GA_MA785GMT_UD2H:
159 voltageConfigs.Add(new Voltage("CPU VCore", 0));
160 voltageConfigs.Add(new Voltage("DRAM", 1));
161 voltageConfigs.Add(new Voltage("+3.3V", 2));
162 voltageConfigs.Add(new Voltage("+5V", 3, 6.8f, 10, 0));
163 voltageConfigs.Add(new Voltage("+12V", 4, 27, 9.1f, 0));
164 voltageConfigs.Add(new Voltage("VBat", 8));
167 voltageConfigs.Add(new Voltage("CPU VCore", 0));
168 voltageConfigs.Add(new Voltage("DRAM", 1, true));
169 voltageConfigs.Add(new Voltage("+3.3V", 2, true));
170 voltageConfigs.Add(new Voltage("+5V", 3, 6.8f, 10, 0, true));
171 voltageConfigs.Add(new Voltage("Voltage #5", 4, true));
172 voltageConfigs.Add(new Voltage("Voltage #6", 5, true));
173 voltageConfigs.Add(new Voltage("Voltage #7", 6, true));
174 voltageConfigs.Add(new Voltage("+12V", 7, 27, 9.1f, 0, true));
175 voltageConfigs.Add(new Voltage("VBat", 8));
178 temperatureLabels = new string[] { "System", "CPU" };
182 voltageConfigs.Add(new Voltage("CPU VCore", 0));
183 voltageConfigs.Add(new Voltage("Voltage #2", 1, true));
184 voltageConfigs.Add(new Voltage("Voltage #3", 2, true));
185 voltageConfigs.Add(new Voltage("Voltage #4", 3, true));
186 voltageConfigs.Add(new Voltage("Voltage #5", 4, true));
187 voltageConfigs.Add(new Voltage("Voltage #6", 5, true));
188 voltageConfigs.Add(new Voltage("Voltage #7", 6, true));
189 voltageConfigs.Add(new Voltage("Voltage #8", 7, true));
190 voltageConfigs.Add(new Voltage("VBat", 8));
191 temperatureLabels = new string[] {
192 "Temperature #1", "Temperature #2", "Temperature #3" };
196 string formula = "Voltage = value + (value - Vf) * Ri / Rf.";
197 foreach (Voltage voltage in voltageConfigs)
198 voltages.Add(new Sensor(voltage.Name, voltage.Index, voltage.Hidden,
199 null, SensorType.Voltage, this, new ParameterDescription[] {
200 new ParameterDescription("Ri [kΩ]", "Input resistance.\n" +
201 formula, voltage.Ri),
202 new ParameterDescription("Rf [kΩ]", "Reference resistance.\n" +
203 formula, voltage.Rf),
204 new ParameterDescription("Vf [V]", "Reference voltage.\n" +
208 for (int i = 0; i < temperatureLabels.Length; i++)
209 if (temperatureLabels[i] != null) {
210 temperatures.Add(new Sensor(temperatureLabels[i], i, null,
211 SensorType.Temperature, this, new ParameterDescription[] {
212 new ParameterDescription("Offset [°C]", "Temperature offset.", 0)
216 fans = new Sensor[5];
217 for (int i = 0; i < fans.Length; i++)
218 fans[i] = new Sensor("Fan #" + (i + 1), i, SensorType.Fan, this);
223 public bool IsAvailable {
224 get { return available; }
227 public override string GetReport() {
228 StringBuilder r = new StringBuilder();
230 r.AppendLine("LPC " + this.GetType().Name);
232 r.Append("Chip ID: 0x"); r.AppendLine(chip.ToString("X"));
233 r.Append("Chip Name: "); r.AppendLine(name);
234 r.Append("Base Address: 0x"); r.AppendLine(address.ToString("X4"));
236 r.AppendLine("Environment Controller Registers");
239 r.AppendLine(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
241 for (int i = 0; i <= 0xA; i++) {
242 r.Append(" "); r.Append((i << 4).ToString("X2")); r.Append(" ");
243 for (int j = 0; j <= 0xF; j++) {
246 byte value = ReadByte((byte)((i << 4) | j), out valid);
248 r.Append(value.ToString("X2"));
259 public override void Update() {
261 foreach (Sensor sensor in voltages) {
263 float value = 0.001f * ((int)ReadByte(
264 (byte)(VOLTAGE_BASE_REG + sensor.Index), out valid) << 4);
268 sensor.Value = value + (value - sensor.Parameters[2].Value) *
269 sensor.Parameters[0].Value / sensor.Parameters[1].Value;
271 ActivateSensor(sensor);
274 foreach (Sensor sensor in temperatures) {
276 sbyte value = (sbyte)ReadByte(
277 (byte)(TEMPERATURE_BASE_REG + sensor.Index), out valid);
281 sensor.Value = value + sensor.Parameters[0].Value;
282 if (value < sbyte.MaxValue && value > 0)
283 ActivateSensor(sensor);
286 foreach (Sensor sensor in fans) {
288 int value = ReadByte(FAN_TACHOMETER_REG[sensor.Index], out valid);
291 value |= ReadByte(FAN_TACHOMETER_EXT_REG[sensor.Index], out valid) << 8;
296 sensor.Value = (value < 0xffff) ? 1.35e6f / ((value) * 2) : 0;
297 if (sensor.Value > 0)
298 ActivateSensor(sensor);
305 private class Voltage {
306 public readonly string Name;
307 public readonly int Index;
308 public readonly float Ri;
309 public readonly float Rf;
310 public readonly float Vf;
311 public readonly bool Hidden;
313 public Voltage(string name, int index) :
314 this(name, index, 0, 1, 0, false) { }
316 public Voltage(string name, int index, bool hidden) :
317 this(name, index, 0, 1, 0, hidden) { }
319 public Voltage(string name, int index, float ri, float rf, float vf) :
320 this(name, index, ri, rf, vf, false) { }
322 public Voltage(string name, int index, float ri, float rf, float vf,
330 this.Hidden = hidden;