Added support for more than one Heatmaster fan controller.
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.Runtime.InteropServices;
41 namespace OpenHardwareMonitor.Hardware.ATI {
43 [StructLayout(LayoutKind.Sequential)]
44 internal struct ADLAdapterInfo {
46 public int AdapterIndex;
47 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
50 public int DeviceNumber;
51 public int FunctionNumber;
53 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
54 public string AdapterName;
55 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
56 public string DisplayName;
59 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
60 public string DriverPath;
61 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
62 public string DriverPathExt;
63 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
64 public string PNPString;
65 public int OSDisplayIndex;
68 [StructLayout(LayoutKind.Sequential)]
69 internal struct ADLPMActivity {
71 public int EngineClock;
72 public int MemoryClock;
74 public int ActivityPercent;
75 public int CurrentPerformanceLevel;
76 public int CurrentBusSpeed;
77 public int CurrentBusLanes;
78 public int MaximumBusLanes;
82 [StructLayout(LayoutKind.Sequential)]
83 internal struct ADLTemperature {
85 public int Temperature;
88 [StructLayout(LayoutKind.Sequential)]
89 internal struct ADLFanSpeedValue {
96 [StructLayout(LayoutKind.Sequential)]
97 internal struct ADLFanSpeedInfo {
100 public int MinPercent;
101 public int MaxPercent;
107 public const int ADL_MAX_PATH = 256;
108 public const int ADL_MAX_ADAPTERS = 40;
109 public const int ADL_MAX_DISPLAYS = 40;
110 public const int ADL_MAX_DEVICENAME = 32;
111 public const int ADL_OK = 0;
112 public const int ADL_ERR = -1;
113 public const int ADL_DRIVER_OK = 0;
114 public const int ADL_MAX_GLSYNC_PORTS = 8;
115 public const int ADL_MAX_GLSYNC_PORT_LEDS = 8;
116 public const int ADL_MAX_NUM_DISPLAYMODES = 1024;
118 public const int ADL_DL_FANCTRL_SPEED_TYPE_PERCENT = 1;
119 public const int ADL_DL_FANCTRL_SPEED_TYPE_RPM = 2;
121 public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_READ = 1;
122 public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE = 2;
123 public const int ADL_DL_FANCTRL_SUPPORTS_RPM_READ = 4;
124 public const int ADL_DL_FANCTRL_SUPPORTS_RPM_WRITE = 8;
126 public const int ATI_VENDOR_ID1 = 1002;
127 public const int ATI_VENDOR_ID2 = 0x1002;
129 private delegate int ADL_Main_Control_CreateDelegate(
130 ADL_Main_Memory_AllocDelegate callback, int enumConnectedAdapters);
131 private delegate int ADL_Adapter_AdapterInfo_GetDelegate(IntPtr info,
134 public delegate int ADL_Main_Control_DestroyDelegate();
135 public delegate int ADL_Adapter_NumberOfAdapters_GetDelegate(
136 ref int numAdapters);
137 public delegate int ADL_Adapter_ID_GetDelegate(int adapterIndex,
139 public delegate int ADL_Display_AdapterID_GetDelegate(int adapterIndex,
141 public delegate int ADL_Adapter_Active_GetDelegate(int adapterIndex,
143 public delegate int ADL_Overdrive5_CurrentActivity_GetDelegate(
144 int iAdapterIndex, ref ADLPMActivity activity);
145 public delegate int ADL_Overdrive5_Temperature_GetDelegate(int adapterIndex,
146 int thermalControllerIndex, ref ADLTemperature temperature);
147 public delegate int ADL_Overdrive5_FanSpeed_GetDelegate(int adapterIndex,
148 int thermalControllerIndex, ref ADLFanSpeedValue fanSpeedValue);
149 public delegate int ADL_Overdrive5_FanSpeedInfo_GetDelegate(
150 int adapterIndex, int thermalControllerIndex,
151 ref ADLFanSpeedInfo fanSpeedInfo);
153 private static ADL_Main_Control_CreateDelegate
154 _ADL_Main_Control_Create;
155 private static ADL_Adapter_AdapterInfo_GetDelegate
156 _ADL_Adapter_AdapterInfo_Get;
158 public static ADL_Main_Control_DestroyDelegate
159 ADL_Main_Control_Destroy;
160 public static ADL_Adapter_NumberOfAdapters_GetDelegate
161 ADL_Adapter_NumberOfAdapters_Get;
162 public static ADL_Adapter_ID_GetDelegate
164 public static ADL_Display_AdapterID_GetDelegate
165 _ADL_Display_AdapterID_Get;
166 public static ADL_Adapter_Active_GetDelegate
167 ADL_Adapter_Active_Get;
168 public static ADL_Overdrive5_CurrentActivity_GetDelegate
169 ADL_Overdrive5_CurrentActivity_Get;
170 public static ADL_Overdrive5_Temperature_GetDelegate
171 ADL_Overdrive5_Temperature_Get;
172 public static ADL_Overdrive5_FanSpeed_GetDelegate
173 ADL_Overdrive5_FanSpeed_Get;
174 public static ADL_Overdrive5_FanSpeedInfo_GetDelegate
175 ADL_Overdrive5_FanSpeedInfo_Get;
177 private static string dllName;
179 private static void GetDelegate<T>(string entryPoint, out T newDelegate)
182 DllImportAttribute attribute = new DllImportAttribute(dllName);
183 attribute.CallingConvention = CallingConvention.StdCall;
184 attribute.PreserveSig = true;
185 attribute.EntryPoint = entryPoint;
186 PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
189 private static void CreateDelegates(string name) {
190 int p = (int)Environment.OSVersion.Platform;
191 if ((p == 4) || (p == 128))
192 dllName = name + ".so";
194 dllName = name + ".dll";
196 GetDelegate("ADL_Main_Control_Create",
197 out _ADL_Main_Control_Create);
198 GetDelegate("ADL_Adapter_AdapterInfo_Get",
199 out _ADL_Adapter_AdapterInfo_Get);
200 GetDelegate("ADL_Main_Control_Destroy",
201 out ADL_Main_Control_Destroy);
202 GetDelegate("ADL_Adapter_NumberOfAdapters_Get",
203 out ADL_Adapter_NumberOfAdapters_Get);
204 GetDelegate("ADL_Adapter_ID_Get",
205 out _ADL_Adapter_ID_Get);
206 GetDelegate("ADL_Display_AdapterID_Get",
207 out _ADL_Display_AdapterID_Get);
208 GetDelegate("ADL_Adapter_Active_Get",
209 out ADL_Adapter_Active_Get);
210 GetDelegate("ADL_Overdrive5_CurrentActivity_Get",
211 out ADL_Overdrive5_CurrentActivity_Get);
212 GetDelegate("ADL_Overdrive5_Temperature_Get",
213 out ADL_Overdrive5_Temperature_Get);
214 GetDelegate("ADL_Overdrive5_FanSpeed_Get",
215 out ADL_Overdrive5_FanSpeed_Get);
216 GetDelegate("ADL_Overdrive5_FanSpeedInfo_Get",
217 out ADL_Overdrive5_FanSpeedInfo_Get);
221 CreateDelegates("atiadlxx");
226 public static int ADL_Main_Control_Create(int enumConnectedAdapters) {
229 return _ADL_Main_Control_Create(Main_Memory_Alloc,
230 enumConnectedAdapters);
232 CreateDelegates("atiadlxy");
233 return _ADL_Main_Control_Create(Main_Memory_Alloc,
234 enumConnectedAdapters);
241 public static int ADL_Adapter_AdapterInfo_Get(ADLAdapterInfo[] info) {
242 int elementSize = Marshal.SizeOf(typeof(ADLAdapterInfo));
243 int size = info.Length * elementSize;
244 IntPtr ptr = Marshal.AllocHGlobal(size);
245 int result = _ADL_Adapter_AdapterInfo_Get(ptr, size);
246 for (int i = 0; i < info.Length; i++)
247 info[i] = (ADLAdapterInfo)
248 Marshal.PtrToStructure((IntPtr)((long)ptr + i * elementSize),
249 typeof(ADLAdapterInfo));
250 Marshal.FreeHGlobal(ptr);
254 public static int ADL_Adapter_ID_Get(int adapterIndex,
257 return _ADL_Adapter_ID_Get(adapterIndex, out adapterID);
258 } catch (EntryPointNotFoundException) {
260 return _ADL_Display_AdapterID_Get(adapterIndex, out adapterID);
261 } catch (EntryPointNotFoundException) {
268 private delegate IntPtr ADL_Main_Memory_AllocDelegate(int size);
270 private static IntPtr Main_Memory_Alloc(int size) {
271 return Marshal.AllocHGlobal(size);;
274 private static void Main_Memory_Free(IntPtr buffer) {
275 if (IntPtr.Zero != buffer)
276 Marshal.FreeHGlobal(buffer);