1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Hardware/LPC/W83627.cs Sun Feb 07 19:48:32 2010 +0000
1.3 @@ -0,0 +1,266 @@
1.4 +/*
1.5 +
1.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
1.7 +
1.8 + The contents of this file are subject to the Mozilla Public License Version
1.9 + 1.1 (the "License"); you may not use this file except in compliance with
1.10 + the License. You may obtain a copy of the License at
1.11 +
1.12 + http://www.mozilla.org/MPL/
1.13 +
1.14 + Software distributed under the License is distributed on an "AS IS" basis,
1.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1.16 + for the specific language governing rights and limitations under the License.
1.17 +
1.18 + The Original Code is the Open Hardware Monitor code.
1.19 +
1.20 + The Initial Developer of the Original Code is
1.21 + Michael Möller <m.moeller@gmx.ch>.
1.22 + Portions created by the Initial Developer are Copyright (C) 2009-2010
1.23 + the Initial Developer. All Rights Reserved.
1.24 +
1.25 + Contributor(s):
1.26 +
1.27 + Alternatively, the contents of this file may be used under the terms of
1.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
1.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1.30 + in which case the provisions of the GPL or the LGPL are applicable instead
1.31 + of those above. If you wish to allow use of your version of this file only
1.32 + under the terms of either the GPL or the LGPL, and not to allow others to
1.33 + use your version of this file under the terms of the MPL, indicate your
1.34 + decision by deleting the provisions above and replace them with the notice
1.35 + and other provisions required by the GPL or the LGPL. If you do not delete
1.36 + the provisions above, a recipient may use your version of this file under
1.37 + the terms of any one of the MPL, the GPL or the LGPL.
1.38 +
1.39 +*/
1.40 +
1.41 +using System;
1.42 +using System.Collections.Generic;
1.43 +using System.Drawing;
1.44 +using System.Text;
1.45 +
1.46 +namespace OpenHardwareMonitor.Hardware.LPC {
1.47 + public class W83627DHG : IHardware {
1.48 +
1.49 + private Chip chip;
1.50 + private byte revision;
1.51 +
1.52 + private string name;
1.53 + private Image icon;
1.54 +
1.55 + private bool available = false;
1.56 + private ushort address;
1.57 +
1.58 + private List<ISensor> active = new List<ISensor>();
1.59 +
1.60 + private Sensor[] temperatures;
1.61 + private Sensor[] fans;
1.62 + private Sensor[] voltages;
1.63 +
1.64 + private float[] voltageGains;
1.65 +
1.66 + // Consts
1.67 + private const ushort WINBOND_VENDOR_ID = 0x5CA3;
1.68 + private const byte HIGH_BYTE = 0x80;
1.69 +
1.70 + // Hardware Monitor
1.71 + private const byte ADDRESS_REGISTER_OFFSET = 0x05;
1.72 + private const byte DATA_REGISTER_OFFSET = 0x06;
1.73 +
1.74 + // Hardware Monitor Registers
1.75 + private const byte VOLTAGE_BASE_REG = 0x20;
1.76 + private const byte BANK_SELECT_REGISTER = 0x04E;
1.77 + private const byte VENDOR_ID_REGISTER = 0x4F;
1.78 + private const byte FIRST_BANK_REGISTER = 0x50;
1.79 + private const byte TEMPERATURE_BASE_REG = 0x50;
1.80 + private const byte TEMPERATURE_SYS_REG = 0x27;
1.81 +
1.82 + private byte[] FAN_TACHO_REG = new byte[] { 0x28, 0x29, 0x2A, 0x3F, 0x53 };
1.83 + private byte[] FAN_TACHO_BANK = new byte[] { 0, 0, 0, 0, 5 };
1.84 + private string[] FAN_NAME = new string[]
1.85 + { "System", "CPU #1", "Auxiliary #1", "CPU #2", "Auxiliary #2" };
1.86 + private byte[] FAN_BIT_REG = new byte[] { 0x47, 0x4B, 0x4C, 0x59, 0x5D };
1.87 + private byte[] FAN_DIV_BIT0 = new byte[] { 36, 38, 30, 8, 10 };
1.88 + private byte[] FAN_DIV_BIT1 = new byte[] { 37, 39, 31, 9, 11 };
1.89 + private byte[] FAN_DIV_BIT2 = new byte[] { 5, 6, 7, 23, 15 };
1.90 +
1.91 + private byte ReadByte(byte bank, byte register) {
1.92 + WinRing0.WriteIoPortByte(
1.93 + (ushort)(address + ADDRESS_REGISTER_OFFSET), BANK_SELECT_REGISTER);
1.94 + WinRing0.WriteIoPortByte(
1.95 + (ushort)(address + DATA_REGISTER_OFFSET), bank);
1.96 + WinRing0.WriteIoPortByte(
1.97 + (ushort)(address + ADDRESS_REGISTER_OFFSET), register);
1.98 + return WinRing0.ReadIoPortByte(
1.99 + (ushort)(address + DATA_REGISTER_OFFSET));
1.100 + }
1.101 +
1.102 + public W83627DHG(Chip chip, byte revision, ushort address) {
1.103 + this.chip = chip;
1.104 + this.revision = revision;
1.105 + this.address = address;
1.106 +
1.107 + // Check vendor id
1.108 + ushort vendorId =
1.109 + (ushort)((ReadByte(HIGH_BYTE, VENDOR_ID_REGISTER) << 8) |
1.110 + ReadByte(0, VENDOR_ID_REGISTER));
1.111 + if (vendorId != WINBOND_VENDOR_ID)
1.112 + return;
1.113 +
1.114 + voltageGains = new float[] { 0.008f, 1, 1, 0.016f, 1, 1, 1, 0.016f };
1.115 + voltages = new Sensor[3];
1.116 + voltages[0] = new Sensor("CPU VCore", 0, SensorType.Voltage, this);
1.117 + voltages[1] = new Sensor("+3.3V", 3, SensorType.Voltage, this);
1.118 + voltages[2] = new Sensor("Battery", 7, SensorType.Voltage, this);
1.119 +
1.120 + temperatures = new Sensor[3];
1.121 + temperatures[0] = new Sensor("CPU", 0, SensorType.Temperature, this);
1.122 + temperatures[1] = new Sensor("Auxiliary", 1, SensorType.Temperature, this);
1.123 + temperatures[2] = new Sensor("System", 2, SensorType.Temperature, this);
1.124 +
1.125 + fans = new Sensor[FAN_NAME.Length];
1.126 + for (int i = 0; i < FAN_NAME.Length; i++)
1.127 + fans[i] = new Sensor(FAN_NAME[i], i, SensorType.Fan, this);
1.128 +
1.129 + switch (chip) {
1.130 + case Chip.W83627DHG: name = "Winbond W83627DHG"; break;
1.131 + case Chip.W83627DHGP: name = "Winbond W83627DHG-P"; break;
1.132 + default: return;
1.133 + }
1.134 +
1.135 + this.icon = Utilities.EmbeddedResources.GetImage("chip.png");
1.136 + available = true;
1.137 + }
1.138 +
1.139 + public bool IsAvailable {
1.140 + get { return available; }
1.141 + }
1.142 +
1.143 + public string Name {
1.144 + get { return name; }
1.145 + }
1.146 +
1.147 + public string Identifier {
1.148 + get { return "/lpc/" + chip.ToString().ToLower(); }
1.149 + }
1.150 +
1.151 + public Image Icon {
1.152 + get { return icon; }
1.153 + }
1.154 +
1.155 + public ISensor[] Sensors {
1.156 + get { return active.ToArray(); }
1.157 + }
1.158 +
1.159 + public string GetReport() {
1.160 + StringBuilder r = new StringBuilder();
1.161 +
1.162 + r.AppendLine("LPC W83627DHG");
1.163 + r.AppendLine();
1.164 + r.Append("Chip ID: 0x"); r.AppendLine(chip.ToString("X"));
1.165 + r.Append("Chip revision: 0x"); r.AppendLine(revision.ToString("X"));
1.166 + r.Append("Base Adress: 0x"); r.AppendLine(address.ToString("X4"));
1.167 + r.AppendLine();
1.168 + r.AppendLine("Hardware Monitor Registers");
1.169 + r.AppendLine();
1.170 + r.AppendLine(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
1.171 + r.AppendLine();
1.172 + for (int i = 0; i < 0x7; i++) {
1.173 + r.Append(" "); r.Append((i << 4).ToString("X2")); r.Append(" ");
1.174 + for (int j = 0; j <= 0xF; j++) {
1.175 + r.Append(" ");
1.176 + r.Append(ReadByte(0, (byte)((i << 4) | j)).ToString("X2"));
1.177 + }
1.178 + r.AppendLine();
1.179 + }
1.180 + for (int k = 1; k <=5; k++) {
1.181 + r.AppendLine("Bank " + k);
1.182 + for (int i = 0x5; i < 0x6; i++) {
1.183 + r.Append(" "); r.Append((i << 4).ToString("X2")); r.Append(" ");
1.184 + for (int j = 0; j <= 0xF; j++) {
1.185 + r.Append(" ");
1.186 + r.Append(ReadByte((byte)(k),
1.187 + (byte)((i << 4) | j)).ToString("X2"));
1.188 + }
1.189 + r.AppendLine();
1.190 + }
1.191 + }
1.192 + r.AppendLine();
1.193 +
1.194 + return r.ToString();
1.195 + }
1.196 +
1.197 + public void Update() {
1.198 + foreach (Sensor sensor in voltages) {
1.199 + if (sensor.Index < 7) {
1.200 + int value = ReadByte(0, (byte)(VOLTAGE_BASE_REG + sensor.Index));
1.201 + sensor.Value = voltageGains[sensor.Index] * value;
1.202 + if (sensor.Value > 0)
1.203 + ActivateSensor(sensor);
1.204 + else
1.205 + DeactivateSensor(sensor);
1.206 + } else {
1.207 + // Battery voltage
1.208 + bool valid = (ReadByte(0, 0x5D) & 0x01) > 0;
1.209 + if (valid) {
1.210 + sensor.Value = voltageGains[sensor.Index] *
1.211 + ReadByte(5, 0x51);
1.212 + ActivateSensor(sensor);
1.213 + } else
1.214 + DeactivateSensor(sensor);
1.215 + }
1.216 + }
1.217 +
1.218 + foreach (Sensor sensor in temperatures) {
1.219 + int value;
1.220 + if (sensor.Index < 2) {
1.221 + value = (sbyte)ReadByte((byte)(sensor.Index + 1), TEMPERATURE_BASE_REG);
1.222 + value = (value << 1) | ReadByte((byte)(sensor.Index + 1),
1.223 + (byte)(TEMPERATURE_BASE_REG + 1)) >> 7;
1.224 + } else {
1.225 + value = (sbyte)ReadByte(0, TEMPERATURE_SYS_REG) << 1;
1.226 + }
1.227 + sensor.Value = value / 2.0f;
1.228 + if (value < 0xFE)
1.229 + ActivateSensor(sensor);
1.230 + else
1.231 + DeactivateSensor(sensor);
1.232 + }
1.233 +
1.234 + long bits = 0;
1.235 + for (int i = 0; i < FAN_BIT_REG.Length; i++)
1.236 + bits = (bits << 8) | ReadByte(0, FAN_BIT_REG[i]);
1.237 + foreach (Sensor sensor in fans) {
1.238 + int count = ReadByte(FAN_TACHO_BANK[sensor.Index],
1.239 + FAN_TACHO_REG[sensor.Index]);
1.240 + int divisorBits = (int)(
1.241 + (((bits >> FAN_DIV_BIT2[sensor.Index]) & 1) << 2) |
1.242 + (((bits >> FAN_DIV_BIT1[sensor.Index]) & 1) << 1) |
1.243 + ((bits >> FAN_DIV_BIT0[sensor.Index]) & 1));
1.244 + int divisor = 1 << divisorBits;
1.245 + sensor.Value = (count < 0xff) ? 1.35e6f / (count * divisor) : 0;
1.246 + ActivateSensor(sensor);
1.247 + }
1.248 + }
1.249 +
1.250 + private void ActivateSensor(Sensor sensor) {
1.251 + if (!active.Contains(sensor)) {
1.252 + active.Add(sensor);
1.253 + if (SensorAdded != null)
1.254 + SensorAdded(sensor);
1.255 + }
1.256 + }
1.257 +
1.258 + private void DeactivateSensor(Sensor sensor) {
1.259 + if (active.Contains(sensor)) {
1.260 + active.Remove(sensor);
1.261 + if (SensorRemoved != null)
1.262 + SensorRemoved(sensor);
1.263 + }
1.264 + }
1.265 +
1.266 + public event SensorEventHandler SensorAdded;
1.267 + public event SensorEventHandler SensorRemoved;
1.268 + }
1.269 +}
2.1 --- a/Hardware/LPC/W83627DHG.cs Sun Feb 07 16:42:26 2010 +0000
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,266 +0,0 @@
2.4 -/*
2.5 -
2.6 - Version: MPL 1.1/GPL 2.0/LGPL 2.1
2.7 -
2.8 - The contents of this file are subject to the Mozilla Public License Version
2.9 - 1.1 (the "License"); you may not use this file except in compliance with
2.10 - the License. You may obtain a copy of the License at
2.11 -
2.12 - http://www.mozilla.org/MPL/
2.13 -
2.14 - Software distributed under the License is distributed on an "AS IS" basis,
2.15 - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
2.16 - for the specific language governing rights and limitations under the License.
2.17 -
2.18 - The Original Code is the Open Hardware Monitor code.
2.19 -
2.20 - The Initial Developer of the Original Code is
2.21 - Michael Möller <m.moeller@gmx.ch>.
2.22 - Portions created by the Initial Developer are Copyright (C) 2009-2010
2.23 - the Initial Developer. All Rights Reserved.
2.24 -
2.25 - Contributor(s):
2.26 -
2.27 - Alternatively, the contents of this file may be used under the terms of
2.28 - either the GNU General Public License Version 2 or later (the "GPL"), or
2.29 - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
2.30 - in which case the provisions of the GPL or the LGPL are applicable instead
2.31 - of those above. If you wish to allow use of your version of this file only
2.32 - under the terms of either the GPL or the LGPL, and not to allow others to
2.33 - use your version of this file under the terms of the MPL, indicate your
2.34 - decision by deleting the provisions above and replace them with the notice
2.35 - and other provisions required by the GPL or the LGPL. If you do not delete
2.36 - the provisions above, a recipient may use your version of this file under
2.37 - the terms of any one of the MPL, the GPL or the LGPL.
2.38 -
2.39 -*/
2.40 -
2.41 -using System;
2.42 -using System.Collections.Generic;
2.43 -using System.Drawing;
2.44 -using System.Text;
2.45 -
2.46 -namespace OpenHardwareMonitor.Hardware.LPC {
2.47 - public class W83627DHG : IHardware {
2.48 -
2.49 - private Chip chip;
2.50 - private byte revision;
2.51 -
2.52 - private string name;
2.53 - private Image icon;
2.54 -
2.55 - private bool available = false;
2.56 - private ushort address;
2.57 -
2.58 - private List<ISensor> active = new List<ISensor>();
2.59 -
2.60 - private Sensor[] temperatures;
2.61 - private Sensor[] fans;
2.62 - private Sensor[] voltages;
2.63 -
2.64 - private float[] voltageGains;
2.65 -
2.66 - // Consts
2.67 - private const ushort WINBOND_VENDOR_ID = 0x5CA3;
2.68 - private const byte HIGH_BYTE = 0x80;
2.69 -
2.70 - // Hardware Monitor
2.71 - private const byte ADDRESS_REGISTER_OFFSET = 0x05;
2.72 - private const byte DATA_REGISTER_OFFSET = 0x06;
2.73 -
2.74 - // Hardware Monitor Registers
2.75 - private const byte VOLTAGE_BASE_REG = 0x20;
2.76 - private const byte BANK_SELECT_REGISTER = 0x04E;
2.77 - private const byte VENDOR_ID_REGISTER = 0x4F;
2.78 - private const byte FIRST_BANK_REGISTER = 0x50;
2.79 - private const byte TEMPERATURE_BASE_REG = 0x50;
2.80 - private const byte TEMPERATURE_SYS_REG = 0x27;
2.81 -
2.82 - private byte[] FAN_TACHO_REG = new byte[] { 0x28, 0x29, 0x2A, 0x3F, 0x53 };
2.83 - private byte[] FAN_TACHO_BANK = new byte[] { 0, 0, 0, 0, 5 };
2.84 - private string[] FAN_NAME = new string[]
2.85 - { "System", "CPU #1", "Auxiliary #1", "CPU #2", "Auxiliary #2" };
2.86 - private byte[] FAN_BIT_REG = new byte[] { 0x47, 0x4B, 0x4C, 0x59, 0x5D };
2.87 - private byte[] FAN_DIV_BIT0 = new byte[] { 36, 38, 30, 8, 10 };
2.88 - private byte[] FAN_DIV_BIT1 = new byte[] { 37, 39, 31, 9, 11 };
2.89 - private byte[] FAN_DIV_BIT2 = new byte[] { 5, 6, 7, 23, 15 };
2.90 -
2.91 - private byte ReadByte(byte bank, byte register) {
2.92 - WinRing0.WriteIoPortByte(
2.93 - (ushort)(address + ADDRESS_REGISTER_OFFSET), BANK_SELECT_REGISTER);
2.94 - WinRing0.WriteIoPortByte(
2.95 - (ushort)(address + DATA_REGISTER_OFFSET), bank);
2.96 - WinRing0.WriteIoPortByte(
2.97 - (ushort)(address + ADDRESS_REGISTER_OFFSET), register);
2.98 - return WinRing0.ReadIoPortByte(
2.99 - (ushort)(address + DATA_REGISTER_OFFSET));
2.100 - }
2.101 -
2.102 - public W83627DHG(Chip chip, byte revision, ushort address) {
2.103 - this.chip = chip;
2.104 - this.revision = revision;
2.105 - this.address = address;
2.106 -
2.107 - // Check vendor id
2.108 - ushort vendorId =
2.109 - (ushort)((ReadByte(HIGH_BYTE, VENDOR_ID_REGISTER) << 8) |
2.110 - ReadByte(0, VENDOR_ID_REGISTER));
2.111 - if (vendorId != WINBOND_VENDOR_ID)
2.112 - return;
2.113 -
2.114 - voltageGains = new float[] { 0.008f, 1, 1, 0.016f, 1, 1, 1, 0.016f };
2.115 - voltages = new Sensor[3];
2.116 - voltages[0] = new Sensor("CPU VCore", 0, SensorType.Voltage, this);
2.117 - voltages[1] = new Sensor("+3.3V", 3, SensorType.Voltage, this);
2.118 - voltages[2] = new Sensor("Battery", 7, SensorType.Voltage, this);
2.119 -
2.120 - temperatures = new Sensor[3];
2.121 - temperatures[0] = new Sensor("CPU", 0, SensorType.Temperature, this);
2.122 - temperatures[1] = new Sensor("Auxiliary", 1, SensorType.Temperature, this);
2.123 - temperatures[2] = new Sensor("System", 2, SensorType.Temperature, this);
2.124 -
2.125 - fans = new Sensor[FAN_NAME.Length];
2.126 - for (int i = 0; i < FAN_NAME.Length; i++)
2.127 - fans[i] = new Sensor(FAN_NAME[i], i, SensorType.Fan, this);
2.128 -
2.129 - switch (chip) {
2.130 - case Chip.W83627DHG: name = "Winbond W83627DHG"; break;
2.131 - case Chip.W83627DHGP: name = "Winbond W83627DHG-P"; break;
2.132 - default: return;
2.133 - }
2.134 -
2.135 - this.icon = Utilities.EmbeddedResources.GetImage("chip.png");
2.136 - available = true;
2.137 - }
2.138 -
2.139 - public bool IsAvailable {
2.140 - get { return available; }
2.141 - }
2.142 -
2.143 - public string Name {
2.144 - get { return name; }
2.145 - }
2.146 -
2.147 - public string Identifier {
2.148 - get { return "/lpc/" + chip.ToString().ToLower(); }
2.149 - }
2.150 -
2.151 - public Image Icon {
2.152 - get { return icon; }
2.153 - }
2.154 -
2.155 - public ISensor[] Sensors {
2.156 - get { return active.ToArray(); }
2.157 - }
2.158 -
2.159 - public string GetReport() {
2.160 - StringBuilder r = new StringBuilder();
2.161 -
2.162 - r.AppendLine("LPC W83627DHG");
2.163 - r.AppendLine();
2.164 - r.Append("Chip ID: 0x"); r.AppendLine(chip.ToString("X"));
2.165 - r.Append("Chip revision: 0x"); r.AppendLine(revision.ToString("X"));
2.166 - r.Append("Base Adress: 0x"); r.AppendLine(address.ToString("X4"));
2.167 - r.AppendLine();
2.168 - r.AppendLine("Hardware Monitor Registers");
2.169 - r.AppendLine();
2.170 - r.AppendLine(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
2.171 - r.AppendLine();
2.172 - for (int i = 0; i < 0x7; i++) {
2.173 - r.Append(" "); r.Append((i << 4).ToString("X2")); r.Append(" ");
2.174 - for (int j = 0; j <= 0xF; j++) {
2.175 - r.Append(" ");
2.176 - r.Append(ReadByte(0, (byte)((i << 4) | j)).ToString("X2"));
2.177 - }
2.178 - r.AppendLine();
2.179 - }
2.180 - for (int k = 1; k <=5; k++) {
2.181 - r.AppendLine("Bank " + k);
2.182 - for (int i = 0x5; i < 0x6; i++) {
2.183 - r.Append(" "); r.Append((i << 4).ToString("X2")); r.Append(" ");
2.184 - for (int j = 0; j <= 0xF; j++) {
2.185 - r.Append(" ");
2.186 - r.Append(ReadByte((byte)(k),
2.187 - (byte)((i << 4) | j)).ToString("X2"));
2.188 - }
2.189 - r.AppendLine();
2.190 - }
2.191 - }
2.192 - r.AppendLine();
2.193 -
2.194 - return r.ToString();
2.195 - }
2.196 -
2.197 - public void Update() {
2.198 - foreach (Sensor sensor in voltages) {
2.199 - if (sensor.Index < 7) {
2.200 - int value = ReadByte(0, (byte)(VOLTAGE_BASE_REG + sensor.Index));
2.201 - sensor.Value = voltageGains[sensor.Index] * value;
2.202 - if (sensor.Value > 0)
2.203 - ActivateSensor(sensor);
2.204 - else
2.205 - DeactivateSensor(sensor);
2.206 - } else {
2.207 - // Battery voltage
2.208 - bool valid = (ReadByte(0, 0x5D) & 0x01) > 0;
2.209 - if (valid) {
2.210 - sensor.Value = voltageGains[sensor.Index] *
2.211 - ReadByte(5, 0x51);
2.212 - ActivateSensor(sensor);
2.213 - } else
2.214 - DeactivateSensor(sensor);
2.215 - }
2.216 - }
2.217 -
2.218 - foreach (Sensor sensor in temperatures) {
2.219 - int value;
2.220 - if (sensor.Index < 2) {
2.221 - value = (sbyte)ReadByte((byte)(sensor.Index + 1), TEMPERATURE_BASE_REG);
2.222 - value = (value << 1) | ReadByte((byte)(sensor.Index + 1),
2.223 - (byte)(TEMPERATURE_BASE_REG + 1)) >> 7;
2.224 - } else {
2.225 - value = (sbyte)ReadByte(0, TEMPERATURE_SYS_REG) << 1;
2.226 - }
2.227 - sensor.Value = value / 2.0f;
2.228 - if (value < 0xFE)
2.229 - ActivateSensor(sensor);
2.230 - else
2.231 - DeactivateSensor(sensor);
2.232 - }
2.233 -
2.234 - long bits = 0;
2.235 - for (int i = 0; i < FAN_BIT_REG.Length; i++)
2.236 - bits = (bits << 8) | ReadByte(0, FAN_BIT_REG[i]);
2.237 - foreach (Sensor sensor in fans) {
2.238 - int count = ReadByte(FAN_TACHO_BANK[sensor.Index],
2.239 - FAN_TACHO_REG[sensor.Index]);
2.240 - int divisorBits = (int)(
2.241 - (((bits >> FAN_DIV_BIT2[sensor.Index]) & 1) << 2) |
2.242 - (((bits >> FAN_DIV_BIT1[sensor.Index]) & 1) << 1) |
2.243 - ((bits >> FAN_DIV_BIT0[sensor.Index]) & 1));
2.244 - int divisor = 1 << divisorBits;
2.245 - sensor.Value = (count < 0xff) ? 1.35e6f / (count * divisor) : 0;
2.246 - ActivateSensor(sensor);
2.247 - }
2.248 - }
2.249 -
2.250 - private void ActivateSensor(Sensor sensor) {
2.251 - if (!active.Contains(sensor)) {
2.252 - active.Add(sensor);
2.253 - if (SensorAdded != null)
2.254 - SensorAdded(sensor);
2.255 - }
2.256 - }
2.257 -
2.258 - private void DeactivateSensor(Sensor sensor) {
2.259 - if (active.Contains(sensor)) {
2.260 - active.Remove(sensor);
2.261 - if (SensorRemoved != null)
2.262 - SensorRemoved(sensor);
2.263 - }
2.264 - }
2.265 -
2.266 - public event SensorEventHandler SensorAdded;
2.267 - public event SensorEventHandler SensorRemoved;
2.268 - }
2.269 -}