Hardware/LPC/W83627.cs
author moel.mich
Sun, 07 Feb 2010 19:53:51 +0000
changeset 31 c4d1fb76a9e1
parent 30 420adf504011
permissions -rw-r--r--
Added initial support for W83627HF. Some refactoring for IHardware classes.
moel@14
     1
/*
moel@14
     2
  
moel@14
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@14
     4
moel@14
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@14
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@14
     7
  the License. You may obtain a copy of the License at
moel@14
     8
 
moel@14
     9
  http://www.mozilla.org/MPL/
moel@14
    10
moel@14
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@14
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@14
    13
  for the specific language governing rights and limitations under the License.
moel@14
    14
moel@14
    15
  The Original Code is the Open Hardware Monitor code.
moel@14
    16
moel@14
    17
  The Initial Developer of the Original Code is 
moel@14
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@14
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@14
    20
  the Initial Developer. All Rights Reserved.
moel@14
    21
moel@14
    22
  Contributor(s):
moel@14
    23
moel@14
    24
  Alternatively, the contents of this file may be used under the terms of
moel@14
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@14
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@14
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@14
    28
  of those above. If you wish to allow use of your version of this file only
moel@14
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@14
    30
  use your version of this file under the terms of the MPL, indicate your
moel@14
    31
  decision by deleting the provisions above and replace them with the notice
moel@14
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@14
    33
  the provisions above, a recipient may use your version of this file under
moel@14
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@14
    35
 
moel@14
    36
*/
moel@14
    37
moel@14
    38
using System;
moel@1
    39
using System.Collections.Generic;
moel@1
    40
using System.Drawing;
moel@1
    41
using System.Text;
moel@1
    42
moel@1
    43
namespace OpenHardwareMonitor.Hardware.LPC {
moel@31
    44
  public class W83627 : Winbond, IHardware {
moel@31
    45
   
moel@13
    46
    private Sensor[] temperatures;
moel@13
    47
    private Sensor[] fans;
moel@13
    48
    private Sensor[] voltages;
moel@13
    49
moel@13
    50
    private float[] voltageGains;
moel@31
    51
    private string[] fanNames;
moel@13
    52
moel@13
    53
    // Hardware Monitor Registers
moel@31
    54
    private const byte VOLTAGE_BASE_REG = 0x20;   
moel@13
    55
    private const byte TEMPERATURE_BASE_REG = 0x50;
moel@13
    56
    private const byte TEMPERATURE_SYS_REG = 0x27;
moel@13
    57
moel@13
    58
    private byte[] FAN_TACHO_REG = new byte[] { 0x28, 0x29, 0x2A, 0x3F, 0x53 };
moel@31
    59
    private byte[] FAN_TACHO_BANK = new byte[] { 0, 0, 0, 0, 5 };       
moel@13
    60
    private byte[] FAN_BIT_REG = new byte[] { 0x47, 0x4B, 0x4C, 0x59, 0x5D };
moel@13
    61
    private byte[] FAN_DIV_BIT0 = new byte[] { 36, 38, 30, 8, 10 };
moel@13
    62
    private byte[] FAN_DIV_BIT1 = new byte[] { 37, 39, 31, 9, 11 };
moel@13
    63
    private byte[] FAN_DIV_BIT2 = new byte[] { 5, 6, 7, 23, 15 };
moel@13
    64
moel@31
    65
    public W83627(Chip chip, byte revision, ushort address) 
moel@31
    66
      : base(chip, revision, address)
moel@31
    67
    {
moel@31
    68
     
moel@13
    69
      temperatures = new Sensor[3];
moel@13
    70
      temperatures[0] = new Sensor("CPU", 0, SensorType.Temperature, this);
moel@13
    71
      temperatures[1] = new Sensor("Auxiliary", 1, SensorType.Temperature, this);
moel@13
    72
      temperatures[2] = new Sensor("System", 2, SensorType.Temperature, this);
moel@13
    73
moel@19
    74
      switch (chip) {
moel@31
    75
        case Chip.W83627DHG:
moel@31
    76
        case Chip.W83627DHGP: 
moel@31
    77
          fanNames = new string[] { "System", "CPU #1", "Auxiliary #1", 
moel@31
    78
            "CPU #2", "Auxiliary #2" };
moel@31
    79
          voltageGains = new float[] { 0.008f, 1, 1, 0.016f, 1, 1, 1, 0.016f };
moel@31
    80
          voltages = new Sensor[3];
moel@31
    81
          voltages[0] = new Sensor("CPU VCore", 0, SensorType.Voltage, this);
moel@31
    82
          voltages[1] = new Sensor("+3.3V", 3, SensorType.Voltage, this);
moel@31
    83
          voltages[2] = new Sensor("Battery", 7, SensorType.Voltage, this);
moel@31
    84
          break;
moel@31
    85
        case Chip.W83627HF: 
moel@31
    86
          fanNames = new string[] { "Fan #1", "Fan #2", "Fan #3" };
moel@31
    87
          voltageGains = new float[] { 0.016f, 1, 0.016f, 1, 1, 1, 1, 0.016f };
moel@31
    88
          voltages = new Sensor[3];
moel@31
    89
          voltages[0] = new Sensor("CPU VCore", 0, SensorType.Voltage, this);
moel@31
    90
          voltages[1] = new Sensor("+3.3V", 2, SensorType.Voltage, this);
moel@31
    91
          voltages[2] = new Sensor("Battery", 7, SensorType.Voltage, this);
moel@31
    92
          break;
moel@31
    93
        default: fanNames = new string[0];
moel@31
    94
          break;
moel@19
    95
      }
moel@31
    96
      
moel@31
    97
      fans = new Sensor[fanNames.Length];
moel@31
    98
      for (int i = 0; i < fanNames.Length; i++)
moel@31
    99
        fans[i] = new Sensor(fanNames[i], i, SensorType.Fan, this);
moel@31
   100
    }    
moel@1
   101
moel@13
   102
    public void Update() {
moel@13
   103
      foreach (Sensor sensor in voltages) {
moel@13
   104
        if (sensor.Index < 7) {
moel@13
   105
          int value = ReadByte(0, (byte)(VOLTAGE_BASE_REG + sensor.Index));
moel@13
   106
          sensor.Value = voltageGains[sensor.Index] * value;
moel@13
   107
          if (sensor.Value > 0)
moel@13
   108
            ActivateSensor(sensor);
moel@13
   109
          else
moel@13
   110
            DeactivateSensor(sensor);
moel@13
   111
        } else {
moel@13
   112
          // Battery voltage
moel@13
   113
          bool valid = (ReadByte(0, 0x5D) & 0x01) > 0;
moel@13
   114
          if (valid) {
moel@13
   115
            sensor.Value = voltageGains[sensor.Index] * 
moel@13
   116
              ReadByte(5, 0x51);
moel@13
   117
            ActivateSensor(sensor);
moel@13
   118
          } else
moel@13
   119
            DeactivateSensor(sensor);
moel@13
   120
        }
moel@13
   121
      }
moel@1
   122
moel@13
   123
      foreach (Sensor sensor in temperatures) {
moel@13
   124
        int value;
moel@13
   125
        if (sensor.Index < 2) {
moel@26
   126
          value = (sbyte)ReadByte((byte)(sensor.Index + 1), TEMPERATURE_BASE_REG);
moel@13
   127
          value = (value << 1) | ReadByte((byte)(sensor.Index + 1),
moel@13
   128
            (byte)(TEMPERATURE_BASE_REG + 1)) >> 7;
moel@13
   129
        } else {
moel@26
   130
          value = (sbyte)ReadByte(0, TEMPERATURE_SYS_REG) << 1;
moel@13
   131
        }
moel@13
   132
        sensor.Value = value / 2.0f;
moel@26
   133
        if (value < 0xFE)
moel@13
   134
          ActivateSensor(sensor);
moel@13
   135
        else
moel@13
   136
          DeactivateSensor(sensor);
moel@13
   137
      }
moel@13
   138
moel@13
   139
      long bits = 0;
moel@13
   140
      for (int i = 0; i < FAN_BIT_REG.Length; i++)
moel@13
   141
        bits = (bits << 8) | ReadByte(0, FAN_BIT_REG[i]);
moel@13
   142
      foreach (Sensor sensor in fans) {
moel@13
   143
        int count = ReadByte(FAN_TACHO_BANK[sensor.Index], 
moel@13
   144
          FAN_TACHO_REG[sensor.Index]);
moel@13
   145
        int divisorBits = (int)(
moel@13
   146
          (((bits >> FAN_DIV_BIT2[sensor.Index]) & 1) << 2) |
moel@13
   147
          (((bits >> FAN_DIV_BIT1[sensor.Index]) & 1) << 1) |
moel@13
   148
           ((bits >> FAN_DIV_BIT0[sensor.Index]) & 1));
moel@13
   149
        int divisor = 1 << divisorBits;
moel@13
   150
        sensor.Value = (count < 0xff) ? 1.35e6f / (count * divisor) : 0;
moel@13
   151
        ActivateSensor(sensor);        
moel@13
   152
      }     
moel@13
   153
    }
moel@1
   154
  }
moel@1
   155
}