⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nforcehosts.~inc

📁 pipe类 pipe类 pipe类 pipe类 pipe类
💻 ~INC
字号:
/////////////////////////////////////////////////////////////////////////////////////
//                 This file is a part of OSCI SMBus engine                        //
//            Support nForce 2, nForce 3 and nForce 4 chipsets                     //
//                                                                                 //
// Copyright (c) 2005 by Dmitriy Arekhta aka Daemon <DaemonES@gmail.com)>          //
// Originally written for LMSensors project by Hans-Frieder Vogt <hfvogt@arcor.de> //                                                             //
/////////////////////////////////////////////////////////////////////////////////////

const
  PCI_VENDOR_ID_NVIDIA = $10de;

  PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS  = $0064;
  PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS = $0084;  PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS  = $00D4;  PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS = $00E4;  PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS  = $0052; //nVidia nForce2 SMBus control register definitions  NFORCE_PCI_SMB1	= $50;  NFORCE_PCI_SMB2	= $54;  NVIDIA_SMB_STS_DONE	    = $80;  NVIDIA_SMB_STS_ALRM	    = $40;  NVIDIA_SMB_STS_RES	    = $20;  NVIDIA_SMB_STS_STATUS   = $1f;  NVIDIA_SMB_PRTCL_WRITE		        = $00;  NVIDIA_SMB_PRTCL_READ		          = $01;  NVIDIA_SMB_PRTCL_QUICK	          = $02;  NVIDIA_SMB_PRTCL_BYTE		          = $04;  NVIDIA_SMB_PRTCL_BYTE_DATA        = $06;  NVIDIA_SMB_PRTCL_WORD_DATA	      =	$08;  NVIDIA_SMB_PRTCL_BLOCK_DATA	      = $0a;  NVIDIA_SMB_PRTCL_PROC_CALL		    = $0c;  NVIDIA_SMB_PRTCL_BLOCK_PROC_CALL  =	$0d;  NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA		= $4a;  NVIDIA_SMB_PRTCL_PEC		          = $80;  //Other  NF_MAX_TIMEOUT = 256;var
  nforce2_ids: array[0..4] of tHostID =
  (
	  (VendorID: PCI_VENDOR_ID_NVIDIA; DeviceID: PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS),	  (VendorID: PCI_VENDOR_ID_NVIDIA; DeviceID: PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS),	  (VendorID: PCI_VENDOR_ID_NVIDIA; DeviceID: PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS),	  (VendorID: PCI_VENDOR_ID_NVIDIA; DeviceID: PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS),	  (VendorID: PCI_VENDOR_ID_NVIDIA; DeviceID: PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS)  );

function NVIDIA_SMB_PRTCL(base: Word): DWord; //protocol, PEC
begin
  result:=base+$00;
end;

function NVIDIA_SMB_STS(base: Word): DWord; //status
begin
  result:=base+$01;
end;

function NVIDIA_SMB_ADDR(base: Word): DWord; //address
begin
  result:=base+$02;
end;

function NVIDIA_SMB_CMD(base: Word): DWord; //command
begin
  result:=base+$03;
end;

function NVIDIA_SMB_DATA(base: Word): DWord; //32 data registers
begin
  result:=base+$04;
end;

function NVIDIA_SMB_BCNT(base: Word): DWord; //number of data bytes
begin
  result:=base+$24;
end;

function NVIDIA_SMB_ALRM_A(base: Word): DWord; //alarm address
begin
  result:=base+$25;
end;

function NVIDIA_SMB_ALRM_D(base: Word): DWord; //2 bytes alarm data
begin
  result:=base+$26;
end;

function nforce2_access (var SMBusHost: tSMBusHost; addr, flags: Word; read_write: Byte;
		                     command: Byte; size: DWord; var data: i2c_smbus_data): LongInt;
var
	protocol, pec, temp: Byte;
	len: Byte; //to keep the compiler quiet	timeout, i: DWord;begin
  timeout:=0;
  
  if (read_write = I2C_SMBUS_READ) then protocol:=NVIDIA_SMB_PRTCL_READ
  else protocol:=NVIDIA_SMB_PRTCL_WRITE;

  if ((flags and I2C_CLIENT_PEC) <> 0) then pec:=NVIDIA_SMB_PRTCL_PEC
  else pec:=0;

  case size of

    I2C_SMBUS_QUICK: begin
			protocol:=protocol or NVIDIA_SMB_PRTCL_QUICK;			read_write:=I2C_SMBUS_WRITE;    end;		I2C_SMBUS_BYTE: begin			if (read_write = I2C_SMBUS_WRITE) then oHWIO.IPortIORef.B[NVIDIA_SMB_CMD(SMBusHost.base)]:=command;			protocol:=protocol or NVIDIA_SMB_PRTCL_BYTE;    end;

    I2C_SMBUS_BYTE_DATA: begin
			oHWIO.IPortIORef.B[NVIDIA_SMB_CMD(SMBusHost.base)]:=command;			if (read_write = I2C_SMBUS_WRITE) then oHWIO.IPortIORef.B[NVIDIA_SMB_DATA(SMBusHost.base)]:=data.ByteData;			protocol:=protocol or NVIDIA_SMB_PRTCL_BYTE_DATA;    end;		I2C_SMBUS_WORD_DATA: begin      oHWIO.IPortIORef.B[NVIDIA_SMB_CMD(SMBusHost.base)]:=command;			if (read_write = I2C_SMBUS_WRITE) then      begin				oHWIO.IPortIORef.B[NVIDIA_SMB_DATA(SMBusHost.base)]:=Byte(data.WordData);				oHWIO.IPortIORef.B[NVIDIA_SMB_DATA(SMBusHost.base)+1]:=Byte(data.WordData shr 8);			end;			protocol:=protocol or NVIDIA_SMB_PRTCL_WORD_DATA or pec;    end;

    I2C_SMBUS_BLOCK_DATA: begin
      result:=-1;
      exit;
      {oHWIO.IPortIORef.B[NVIDIA_SMB_CMD(SMBusHost.base)]:=command;
			if (read_write = I2C_SMBUS_WRITE) then      begin				len = min_t(u8, data->block[0], 32);				outb_p(len, NVIDIA_SMB_BCNT);				for (i = 0; i < len; i++)					outb_p(data->block[i + 1], NVIDIA_SMB_DATA+i);			end;			protocol:=protocol or NVIDIA_SMB_PRTCL_BLOCK_DATA or pec;}    end;		I2C_SMBUS_I2C_BLOCK_DATA: begin      result:=-1;      exit;			{len = min_t(u8, data->block[0], 32);			outb_p(command, NVIDIA_SMB_CMD);			outb_p(len, NVIDIA_SMB_BCNT);			if (read_write = I2C_SMBUS_WRITE) then				for (i = 0; i < len; i++)					outb_p(data->block[i + 1], NVIDIA_SMB_DATA+i);			protocol:=protocol or NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA;}    end;
  else
    result:=-1;
    exit;
  end;

  oHWIO.IPortIORef.B[NVIDIA_SMB_ADDR(SMBusHost.base)]:=((addr and $7f) shl 1);
  oHWIO.IPortIORef.B[NVIDIA_SMB_PRTCL(SMBusHost.base)]:=protocol;
  temp:=oHWIO.IPortIORef.B[NVIDIA_SMB_STS(SMBusHost.base)];
  {while (((temp and NVIDIA_SMB_STS_DONE) = 0) and (timeout <= MAX_TIMEOUT)) do
  begin
    inc(timeout);
    temp:=oHWIO.IPortIORef.B[NVIDIA_SMB_STS(SMBusHost.base)];
  end;}

  if (not(temp) and NVIDIA_SMB_STS_DONE) <> 0 then
  begin
		sleep(10);    temp:=oHWIO.IPortIORef.B[NVIDIA_SMB_STS(SMBusHost.base)];	end;	if (not(temp) and NVIDIA_SMB_STS_DONE) <> 0 then  begin    sleep(10); //i2c_delay(trunc(HZ/100));    temp:=oHWIO.IPortIORef.B[NVIDIA_SMB_STS(SMBusHost.base)];	end;
	if ((timeout >= NF_MAX_TIMEOUT) or ((not(temp) and NVIDIA_SMB_STS_DONE <> 0)) or ((temp and NVIDIA_SMB_STS_STATUS) <> 0)) then
  begin
		result:=-1;
    exit;
  end;

  if (read_write = I2C_SMBUS_WRITE) then
  begin
    result:=0;
    exit;
  end;

	case size of
		I2C_SMBUS_BYTE,		I2C_SMBUS_BYTE_DATA: begin      data.ByteData:=oHWIO.IPortIORef.B[NVIDIA_SMB_DATA(SMBusHost.base)];    end;		I2C_SMBUS_WORD_DATA: begin		  //case I2C_SMBUS_PROC_CALL: not supported      data.WordData:=oHWIO.IPortIORef.B[NVIDIA_SMB_DATA(SMBusHost.base)] or (oHWIO.IPortIORef.B[NVIDIA_SMB_DATA(SMBusHost.base)+1] shl 8);    end;		I2C_SMBUS_BLOCK_DATA: begin      result:=-1;      exit;		  //case I2C_SMBUS_BLOCK_PROC_CALL: not supported      {len:=oHWIO.IPortIORef.B[NVIDIA_SMB_BCNT(SMBusHost.base)];      data.Ptr:=data.Ptr+1;			len = min_t(u8, len, 32);}    end;		I2C_SMBUS_I2C_BLOCK_DATA: begin      result:=-1;      exit;			{for (i = 0; i < len; i++)				data->block[i+1] = inb_p(NVIDIA_SMB_DATA + i);			data->block[0] = len;}    end;  end;
  result:=0;
end;

function nForceGetHost(var SMBusHosts: tSMBusHosts; var HostsNum: Byte; HostDevice: tPCIDevice): boolean;
var
  pdata: Word;
  CurrentHost: DWord;
begin
  inc(HostsNum);
  SetLength(SMBusHosts, HostsNum);  CurrentHost:=HostsNum-1;  with SMBusHosts[CurrentHost] do  begin    device.dwBus:=HostDevice.dwBus;    device.dwDev:=HostDevice.dwDev;    device.dwFunc:=HostDevice.dwFunc;    oHWIO.IPCIIORef.GetPCIRWord(device.dwBus, device.dwDev, device.dwFunc, NFORCE_PCI_SMB1, pdata);    base:=pdata and $fffc;    size:=8;  end;  inc(HostsNum);  SetLength(SMBusHosts, HostsNum);  CurrentHost:=HostsNum-1;  with SMBusHosts[CurrentHost] do  begin    device.dwBus:=HostDevice.dwBus;    device.dwDev:=HostDevice.dwDev;    device.dwFunc:=HostDevice.dwFunc;    oHWIO.IPCIIORef.GetPCIRWord(device.dwBus, device.dwDev, device.dwFunc, NFORCE_PCI_SMB2, pdata);    base:=pdata and $fffc;    size:=8;  end;
end;
function nForceFillHostIds: tHostIDs;
var
  i: byte;
begin
  for i:=Low(nforce2_ids) to High(nforce2_ids) do
    begin
      SetLength(result, i+1);
      result[i].VendorID := nforce2_ids[i].VendorID;
      result[i].DeviceID := nforce2_ids[i].DeviceID;
    end;
end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -