Logo Search packages:      
Sourcecode: xmbmon version File versions  Download package

sens_it87.c

/*
 * Integrated Technology Express IT8705F/IT8712F hardware monitor chip
 *
 ***************************************************************
 * Before calling these routines, one must call method->Open() *
 * After calling these routines, one must call method->Close() *
 ***************************************************************
 *

Integrated Technology Express
         Chip         Temp    Volt    Fan     SMBus   IOport
        it8705         3       8       3       yes     yes
        it8712         3       8       3       yes     yes

SiS
         Chip         Temp    Volt    Fan     SMBus   IOport
        sis950         3       8       3       yes     yes

 *
 * by YRS
 */


#include    <stdio.h>
#include    "sensors.h"

/* external (global) data */
extern int smb_slave;
extern LM_METHODS method_isa, method_smb;
extern int numSMBSlave, canSMBSlave[128];


#define     IT87_ADDR_START         0x50  /*0x50-0x5E*/
#define     IT87_ADDR_END           0x5E

#define     IT87_SMBADDR      0x48
#define     IT87_REGCHIP      0x58
#define     IT87_CHIPID       0x90

/* temp nr=0,1,2; volt nr=0,1,...6; fan nr=0,1,2 */
#define     IT87_TEMP(nr)     (0x29 + (nr))
#define     IT87_VOLT(nr)     (0x20 + (nr))
#define     IT87_FAN(nr)      (0x0D + (nr))
#define     IT87_FANDIV       0x0B

static      int         it87_probe(LM_METHODS *);
static      float it87_temp(LM_METHODS *, int);
static      int         it87_fanrpm(LM_METHODS *, int);
static      float it87_volt(LM_METHODS *, int);

SENSOR it87 = {
      "Int.Tec.Exp. Chip IT8705F/IT8712F or SIS950",
      it87_probe,
      it87_temp,
      it87_volt,
      it87_fanrpm
};


#define IT87_chkRegNum 8

/* Register checked for probing */
static int chkReg[] = {
      0x00, 0x01, 0x02, 0x03,
      0x0A, 0x48, 0x50, 0x51,
      0x20, 0x21, 0x22, 0x23,
      0x24, 0x25, 0x26, 0x27,
      0x28, 0x29, 0x2A, 0x2B,
      0x0B, 0x0D, 0x0E, 0x0F,
      -1 };


/*
 *  return 0 if not probed
 */
static      int     it87_probe(LM_METHODS *method)
{
      int n, save;

      if (method != &method_isa  && method != &method_smb)
            return 0;

      save = smb_slave;

      if (method == &method_smb) {
            for (n = IT87_ADDR_START; n <= IT87_ADDR_END;) {
                  if (!(smb_slave = get_smb_slave(n, IT87_ADDR_END)))
                        goto ret0;
                  else if (smb_slave != 2 * method->Read(IT87_SMBADDR))
                        goto ret0;
                  else {
                        if (method->Read(IT87_REGCHIP) == IT87_CHIPID
                              && chkReg_Probe(smb_slave,
                                    "Probing ITE7805/7812/SIS950 chip:\n", chkReg, method)
                                          >= IT87_chkRegNum)
                              goto ret1;
                        else
                              n = smb_slave + 2;
                  }
            }
            goto ret0;
      } else {
            if (method->Read(IT87_REGCHIP) == IT87_CHIPID
                  && chkReg_Probe(0, "Probing ITE7805/7812/SIS950 chip:\n",
                        chkReg, method) >= IT87_chkRegNum)
                  goto ret1;
      }

ret0:
      smb_slave = save;
      return 0;
ret1:
      if (method == &method_smb)
            kill_smb_slave(smb_slave);
      return 1;
}


/*
 *    \retval     0xFFFF      no sensor
 *    \retval     other temperature
 *  no = 0,1,2,...
 */
static      float it87_temp( LM_METHODS *method, int no )
{
      if (no < 0 || 2 < no)
            return 0xFFFF;

      return (float) method->Read(IT87_TEMP(no));
}


/*
 *    \retval     0x0000FFFF  no sensor
 *  no = 0,1,2,...
 */
static      float it87_volt(LM_METHODS *method, int no)
{
      float fac;

      if (no < 0 || 6 < no)
            return 0xFFFF;

      switch (no) {
            case 0:
            case 1:
            case 2:
                  fac = 0.016;
                  break;
            case 3:
                  fac = 0.016 * 1.68;
                  break;
            case 4:
                  fac = 0.016 * 3.80;
                  break;
            case 5:
                  fac = - 0.016 * 3.477;
                  break;
            case 6:
                  fac = - 0.016 * 1.505;
      }

      return (float) method->Read(IT87_VOLT(no)) * fac;
}


/*
      Controlling Fan Divisor for 1st/2nd fans: CR = 0x0B.
      lowest three bits for fan1, next three bits for fan2

         7       3     0
        +-+-+-+-+-+-+-+-+     xxx = 000,..,111  div1fac = 1,..,128
        |   |y y y|x x x|     yyy = 000,..,111  div2fac = 1,..,128
        +-+-+-+-+-+-+-+-+    initial values: xx=001, yy=001

      No divisor available for fan3.

 */

/*
 *    \retval     0x0000FFFF  no sensor
 *  no = 0,1,2,...
 *
 *  Clock is 22.5kHz (22,500 x 60 = 1350000 counts/minute)
 */
static      int         it87_fanrpm(LM_METHODS *method, int no)
{
      int   r, n;
      static int div[3] = {1,1,1};

      if (no < 0 || 2 < no)
            return 0xFFFF;

      n = method->Read(IT87_FANDIV);
      div[0] =  n & 0x07;
      div[1] = (n >> 3) & 0x07;

      r = method->Read(IT87_FAN(no));
      if (r == 0xFF) {
            /* change divisor for the sake of next call ! */
            if (no != 2) {
                  if (div[no] < 7)
                        ++(div[no]);
                  else
                        div[no] = 0;
                  r = (n & 0x3F) | div[0] | (div[1] << 3);
                  method->Write(IT87_FANDIV, r);
            }
            return 0xFFFF;
      } else if (r == 0) {
            return 0xFFFF;
      }

      return 1350000 / (r * (1 << div[no]));
}

Generated by  Doxygen 1.6.0   Back to index