Hardware/ATI/ADL.cs
author moel.mich
Thu, 07 Oct 2010 19:34:36 +0000
changeset 217 d93ddd6ca0af
parent 195 0ee888c485d5
child 247 6dc755f1970e
permissions -rw-r--r--
Added a new sensor type "Level" for wear or charge level (or any other percentage based sensors that don't fit into Load or Control).
     1 /*
     2   
     3   Version: MPL 1.1/GPL 2.0/LGPL 2.1
     4 
     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
     8  
     9   http://www.mozilla.org/MPL/
    10 
    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.
    14 
    15   The Original Code is the Open Hardware Monitor code.
    16 
    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.
    21 
    22   Contributor(s):
    23 
    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.
    35  
    36 */
    37 
    38 using System;
    39 using System.Runtime.InteropServices;
    40 
    41 namespace OpenHardwareMonitor.Hardware.ATI {
    42   
    43   [StructLayout(LayoutKind.Sequential)]
    44   internal struct ADLAdapterInfo {
    45     public int Size;
    46     public int AdapterIndex;
    47     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
    48     public string UDID;
    49     public int BusNumber;
    50     public int DeviceNumber;
    51     public int FunctionNumber;
    52     public int VendorID;
    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;
    57     public int Present;
    58     public int Exist;
    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;
    66   }
    67 
    68   [StructLayout(LayoutKind.Sequential)]
    69   internal struct ADLPMActivity {
    70     public int Size;
    71     public int EngineClock;
    72     public int MemoryClock;
    73     public int Vddc;
    74     public int ActivityPercent;
    75     public int CurrentPerformanceLevel;
    76     public int CurrentBusSpeed;
    77     public int CurrentBusLanes;
    78     public int MaximumBusLanes;
    79     public int Reserved;
    80   }
    81 
    82   [StructLayout(LayoutKind.Sequential)]
    83   internal struct ADLTemperature {
    84     public int Size;
    85     public int Temperature;
    86   }
    87 
    88   [StructLayout(LayoutKind.Sequential)]
    89   internal struct ADLFanSpeedValue {
    90     public int Size;
    91     public int SpeedType;
    92     public int FanSpeed;
    93     public int Flags;
    94   }
    95 
    96   [StructLayout(LayoutKind.Sequential)]
    97   internal struct ADLFanSpeedInfo {
    98     public int Size;
    99     public int Flags;
   100     public int MinPercent;
   101     public int MaxPercent;
   102     public int MinRPM;
   103     public int MaxRPM;
   104   }
   105 
   106   internal class ADL {
   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;
   117 
   118     public const int ADL_DL_FANCTRL_SPEED_TYPE_PERCENT = 1;
   119     public const int ADL_DL_FANCTRL_SPEED_TYPE_RPM = 2;
   120 
   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;
   125 
   126     public const int ATI_VENDOR_ID1 = 1002;
   127     public const int ATI_VENDOR_ID2 = 0x1002;
   128 
   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,
   132       int size);
   133 
   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,
   138       out int adapterID);
   139     public delegate int ADL_Display_AdapterID_GetDelegate(int adapterIndex,
   140       out int adapterID);      	
   141     public delegate int ADL_Adapter_Active_GetDelegate(int adapterIndex,
   142       out int status);
   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);
   152 
   153     private static ADL_Main_Control_CreateDelegate
   154       _ADL_Main_Control_Create;
   155     private static ADL_Adapter_AdapterInfo_GetDelegate
   156       _ADL_Adapter_AdapterInfo_Get;
   157 
   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 
   163       _ADL_Adapter_ID_Get;
   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;
   176 
   177     private static string dllName;
   178 
   179     private static void GetDelegate<T>(string entryPoint, out T newDelegate)
   180       where T : class 
   181     {
   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);
   187     }
   188 
   189     private static void CreateDelegates(string name) {
   190       int p = (int)Environment.OSVersion.Platform;
   191       if ((p == 4) || (p == 128))
   192         dllName = name + ".so";
   193       else
   194         dllName = name + ".dll";
   195 
   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);
   218     }
   219 
   220     static ADL() {
   221       CreateDelegates("atiadlxx");
   222     }
   223 
   224     private ADL() { }
   225 
   226     public static int ADL_Main_Control_Create(int enumConnectedAdapters) {
   227       try {
   228         try {
   229           return _ADL_Main_Control_Create(Main_Memory_Alloc,
   230             enumConnectedAdapters);
   231         } catch {
   232           CreateDelegates("atiadlxy");
   233           return _ADL_Main_Control_Create(Main_Memory_Alloc,
   234             enumConnectedAdapters);
   235         }
   236       } catch {
   237         return ADL_ERR;
   238       }
   239     }
   240 
   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);
   251       return result;
   252     }
   253 
   254     public static int ADL_Adapter_ID_Get(int adapterIndex,
   255       out int adapterID) {
   256       try {
   257         return _ADL_Adapter_ID_Get(adapterIndex, out adapterID);
   258       } catch (EntryPointNotFoundException) {
   259         try {
   260           return _ADL_Display_AdapterID_Get(adapterIndex, out adapterID);
   261         } catch (EntryPointNotFoundException) {
   262           adapterID = 1;
   263           return ADL_OK;
   264         }
   265       }
   266     }
   267 
   268     private delegate IntPtr ADL_Main_Memory_AllocDelegate(int size);
   269 
   270     // create a Main_Memory_Alloc delegate and keep it alive
   271     private static ADL_Main_Memory_AllocDelegate Main_Memory_Alloc =
   272       delegate(int size) {
   273         return Marshal.AllocHGlobal(size);
   274       };
   275 
   276     private static void Main_Memory_Free(IntPtr buffer) {
   277       if (IntPtr.Zero != buffer)
   278         Marshal.FreeHGlobal(buffer);
   279     }
   280   }
   281 }