Hardware/LPC/LMSensors.cs
author moel.mich
Sun, 08 May 2011 22:10:13 +0000
changeset 279 6bce967ba1b5
parent 266 2687ac753d90
child 323 3f2d9ebacf38
permissions -rwxr-xr-x
Fixed the bus and core clock reading on AMD family 10h model Ah CPUs. The new "Core Performance Boost" feature of these CPUs resulted in very low accuracy of the bus speed (and as a consequence also an inaccurate TSC multiplier). This fixed Issue 205.
moel@136
     1
/*
moel@136
     2
  
moel@136
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@136
     4
moel@136
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@136
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@136
     7
  the License. You may obtain a copy of the License at
moel@136
     8
 
moel@136
     9
  http://www.mozilla.org/MPL/
moel@136
    10
moel@136
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@136
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@136
    13
  for the specific language governing rights and limitations under the License.
moel@136
    14
moel@136
    15
  The Original Code is the Open Hardware Monitor code.
moel@136
    16
moel@136
    17
  The Initial Developer of the Original Code is 
moel@136
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@266
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2011
moel@136
    20
  the Initial Developer. All Rights Reserved.
moel@136
    21
moel@136
    22
  Contributor(s):
moel@136
    23
moel@136
    24
  Alternatively, the contents of this file may be used under the terms of
moel@136
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@136
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@136
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@136
    28
  of those above. If you wish to allow use of your version of this file only
moel@136
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@136
    30
  use your version of this file under the terms of the MPL, indicate your
moel@136
    31
  decision by deleting the provisions above and replace them with the notice
moel@136
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@136
    33
  the provisions above, a recipient may use your version of this file under
moel@136
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@136
    35
 
moel@136
    36
*/
moel@136
    37
moel@136
    38
using System.Collections.Generic;
moel@166
    39
using System.Globalization;
moel@136
    40
using System.IO;
moel@268
    41
using System.Text;
moel@136
    42
moel@136
    43
namespace OpenHardwareMonitor.Hardware.LPC {
moel@136
    44
moel@165
    45
  internal class LMSensors {
moel@136
    46
moel@195
    47
    private readonly List<LMChip> lmChips = new List<LMChip>();
moel@136
    48
moel@136
    49
    public LMSensors() {
moel@266
    50
      string[] basePaths = Directory.GetDirectories("/sys/class/hwmon/");
moel@266
    51
      foreach (string basePath in basePaths) {
moel@266
    52
        foreach (string devicePath in new[] { "/device", "" }) {
moel@266
    53
          string path = basePath + devicePath;
moel@136
    54
moel@266
    55
          string name = null;
moel@266
    56
          try {
moel@266
    57
            using (StreamReader reader = new StreamReader(path + "/name"))
moel@266
    58
              name = reader.ReadLine();
moel@266
    59
          } catch (IOException) { }
moel@136
    60
moel@266
    61
          switch (name) {
moel@266
    62
            case "atk0110":
moel@266
    63
              lmChips.Add(new LMChip(Chip.ATK0110, path)); break;
moel@266
    64
moel@266
    65
            case "f71858fg":
moel@266
    66
              lmChips.Add(new LMChip(Chip.F71858, path)); break;
moel@266
    67
            case "f71862fg":
moel@266
    68
              lmChips.Add(new LMChip(Chip.F71862, path)); break;
moel@266
    69
            case "f71882fg":
moel@266
    70
              lmChips.Add(new LMChip(Chip.F71882, path)); break;
moel@266
    71
            case "f71889fg":
moel@266
    72
              lmChips.Add(new LMChip(Chip.F71889F, path)); break;
moel@266
    73
moel@266
    74
            case "it8712":
moel@266
    75
              lmChips.Add(new LMChip(Chip.IT8712F, path)); break;
moel@266
    76
            case "it8716":
moel@266
    77
              lmChips.Add(new LMChip(Chip.IT8716F, path)); break;
moel@266
    78
            case "it8718":
moel@266
    79
              lmChips.Add(new LMChip(Chip.IT8718F, path)); break;
moel@266
    80
            case "it8720":
moel@266
    81
              lmChips.Add(new LMChip(Chip.IT8720F, path)); break;
moel@266
    82
moel@266
    83
            case "w83627ehf":
moel@266
    84
              lmChips.Add(new LMChip(Chip.W83627EHF, path)); break;
moel@266
    85
            case "w83627dhg":
moel@266
    86
              lmChips.Add(new LMChip(Chip.W83627DHG, path)); break;
moel@266
    87
            case "w83667hg":
moel@266
    88
              lmChips.Add(new LMChip(Chip.W83667HG, path)); break;
moel@266
    89
            case "w83627hf":
moel@266
    90
              lmChips.Add(new LMChip(Chip.W83627HF, path)); break;
moel@266
    91
            case "w83627thf":
moel@266
    92
              lmChips.Add(new LMChip(Chip.W83627THF, path)); break;
moel@266
    93
            case "w83687thf":
moel@266
    94
              lmChips.Add(new LMChip(Chip.W83687THF, path)); break;
moel@266
    95
          }
moel@136
    96
        }
moel@136
    97
      }
moel@136
    98
    }
moel@136
    99
moel@136
   100
    public void Close() {
moel@136
   101
      foreach (LMChip lmChip in lmChips)
moel@136
   102
        lmChip.Close();
moel@136
   103
    }
moel@136
   104
moel@136
   105
    public ISuperIO[] SuperIO {
moel@136
   106
      get {
moel@136
   107
        return lmChips.ToArray();
moel@136
   108
      }
moel@136
   109
    }
moel@136
   110
moel@136
   111
    private class LMChip : ISuperIO {
moel@136
   112
moel@136
   113
      private string path;
moel@195
   114
      private readonly Chip chip;
moel@136
   115
moel@195
   116
      private readonly float?[] voltages;
moel@195
   117
      private readonly float?[] temperatures;
moel@195
   118
      private readonly float?[] fans;
moel@136
   119
moel@268
   120
      private readonly FileStream[] voltageStreams;
moel@268
   121
      private readonly FileStream[] temperatureStreams;
moel@268
   122
      private readonly FileStream[] fanStreams;
moel@136
   123
moel@136
   124
      public Chip Chip { get { return chip; } }
moel@136
   125
      public float?[] Voltages { get { return voltages; } }
moel@136
   126
      public float?[] Temperatures { get { return temperatures; } }
moel@136
   127
      public float?[] Fans { get { return fans; } }
moel@136
   128
moel@136
   129
moel@136
   130
      public LMChip(Chip chip, string path) {
moel@136
   131
        this.path = path;
moel@136
   132
        this.chip = chip;
moel@136
   133
moel@136
   134
        string[] voltagePaths = Directory.GetFiles(path, "in*_input");
moel@136
   135
        this.voltages = new float?[voltagePaths.Length];
moel@268
   136
        this.voltageStreams = new FileStream[voltagePaths.Length];
moel@136
   137
        for (int i = 0; i < voltagePaths.Length; i++)
moel@268
   138
          voltageStreams[i] = new FileStream(voltagePaths[i],
moel@268
   139
            FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
moel@136
   140
moel@136
   141
        string[] temperaturePaths = Directory.GetFiles(path, "temp*_input");
moel@136
   142
        this.temperatures = new float?[temperaturePaths.Length];
moel@268
   143
        this.temperatureStreams = new FileStream[temperaturePaths.Length];
moel@136
   144
        for (int i = 0; i < temperaturePaths.Length; i++)
moel@268
   145
          temperatureStreams[i] = new FileStream(temperaturePaths[i],
moel@268
   146
            FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
moel@136
   147
moel@136
   148
        string[] fanPaths = Directory.GetFiles(path, "fan*_input");
moel@136
   149
        this.fans = new float?[fanPaths.Length];
moel@268
   150
        this.fanStreams = new FileStream[fanPaths.Length];
moel@136
   151
        for (int i = 0; i < fanPaths.Length; i++)
moel@268
   152
          fanStreams[i] = new FileStream(fanPaths[i],
moel@268
   153
            FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
moel@136
   154
      }
moel@136
   155
moel@228
   156
      public byte? ReadGPIO(int index) {
moel@228
   157
        return null;
moel@228
   158
      }
moel@228
   159
moel@228
   160
      public void WriteGPIO(int index, byte value) { }
moel@228
   161
moel@136
   162
      public string GetReport() {
moel@136
   163
        return null;
moel@136
   164
      }
moel@136
   165
moel@268
   166
      private string ReadFirstLine(Stream stream) {
moel@268
   167
        StringBuilder sb = new StringBuilder();
moel@268
   168
        try {
moel@268
   169
          stream.Seek(0, SeekOrigin.Begin);
moel@268
   170
          int b = stream.ReadByte();
moel@268
   171
          while (b != -1 && b != 10) {
moel@268
   172
            sb.Append((char)b);
moel@268
   173
            b = stream.ReadByte();
moel@268
   174
          }
moel@268
   175
        } catch { }
moel@268
   176
        return sb.ToString();
moel@268
   177
      }
moel@268
   178
moel@136
   179
      public void Update() {
moel@136
   180
        for (int i = 0; i < voltages.Length; i++) {
moel@268
   181
          string s = ReadFirstLine(voltageStreams[i]);
moel@136
   182
          try {
moel@268
   183
            voltages[i] = 0.001f *
moel@166
   184
              long.Parse(s, CultureInfo.InvariantCulture);
moel@136
   185
          } catch {
moel@136
   186
            voltages[i] = null;
moel@136
   187
          }
moel@136
   188
        }
moel@136
   189
moel@136
   190
        for (int i = 0; i < temperatures.Length; i++) {
moel@268
   191
          string s = ReadFirstLine(temperatureStreams[i]);
moel@136
   192
          try {
moel@268
   193
            temperatures[i] = 0.001f *
moel@166
   194
              long.Parse(s, CultureInfo.InvariantCulture);
moel@136
   195
          } catch {
moel@136
   196
            temperatures[i] = null;
moel@136
   197
          }
moel@136
   198
        }
moel@136
   199
moel@136
   200
        for (int i = 0; i < fans.Length; i++) {
moel@268
   201
          string s = ReadFirstLine(fanStreams[i]);
moel@136
   202
          try {
moel@166
   203
            fans[i] = long.Parse(s, CultureInfo.InvariantCulture);
moel@136
   204
          } catch {
moel@136
   205
            fans[i] = null;
moel@136
   206
          }
moel@136
   207
        }
moel@136
   208
      }
moel@136
   209
moel@136
   210
      public void Close() {
moel@268
   211
        foreach (FileStream stream in voltageStreams)
moel@268
   212
          stream.Close();
moel@268
   213
        foreach (FileStream stream in temperatureStreams)
moel@268
   214
          stream.Close();
moel@268
   215
        foreach (FileStream stream in fanStreams)
moel@268
   216
          stream.Close();
moel@136
   217
      }
moel@136
   218
    }
moel@136
   219
  }
moel@136
   220
}