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

sens_lm90.c

/*
 * Natinal Semiconductor LM75 temperature sensor chip
 *
 ***************************************************************
 * Before calling these routines, one must call method->Open() *
 * After calling these routines, one must call method->Close() *
 ***************************************************************
 *

National Semiconductor
         Chip         Temp    Volt    Fan     SMBus   IOport
        lm90           2       -       -       yes     no

Analog Devices
         Chip         Temp    Volt    Fan     SMBus   IOport
        ADM1020        2       -       -       yes     no
        ADM1021        2       -       -       yes     no
        ADM1023        2       -       -       yes     no

 *
 * by YRS
 */


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

/* external (global) data */
extern int smb_slave;
extern LM_METHODS method_smb;


#define     LM90_ADDR_START         0x90  /*0x90-0x9E*/
#define     LM90_ADDR_END           0x9E

#define LM90_LTEMP            0x00
#define LM90_RTEMPH           0x01
#define LM90_RTEMPL           0x10
#define LM90_OFFSTH           0x11
#define LM90_OFFSTL           0x12
#define LM90_VENDID           0xFE
#define LM90_DEVID            0xFF

static int lm90chipid = 0;

static      int         lm90_probe(LM_METHODS *);
static      int         lm90_ident(LM_METHODS *);
static      float lm90_temp(LM_METHODS *, int);
static      int         lm90_fanrpm(LM_METHODS *, int);
static      float lm90_volt(LM_METHODS *, int);

#define BUFF_LEN 128
static char buff[BUFF_LEN];

SENSOR lm90 = {
      buff,
      lm90_probe,
      lm90_temp,
      lm90_volt,
      lm90_fanrpm
};

enum lm90_chips {
      NOSENSER,
      LM90,
      ADM1020,
      ADM1023
};

static char *lm90chip[] = {
      "No Sensor",
      "Nat.Semi.Con. Chip LM90",
      "Analog Dev. Chip ADM1020",
      "Analog Dev. Chip ADM1021/1023",
      NULL };


#define LM90_chkRegNum 8

/* Register checked for probing */
static int chkReg[] = {
      0x00, 0x01, 0x02, 0x03,
      0x04, 0x05, 0x06, 0x07,
      0x08, 0x10, 0x11, 0x12,
      0x13, 0x14, 0x19, 0x20,
      0x21, 0xBF, 0xFE, 0xFF,
      -1 };


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

      if (method != &method_smb)
            return 0;

      save = smb_slave;

      for (n = LM90_ADDR_START; n <= LM90_ADDR_END; ) {
            if (!(smb_slave = get_smb_slave(n, LM90_ADDR_END)))
                  goto ret0;
            else {
                  if (lm90_ident(method)
                              && chkReg_Probe(smb_slave, "Probing LM90 chip:\n",
                                          chkReg, method) >= LM90_chkRegNum)
                        goto ret1;
                  else
                        n = smb_slave + 2;
            }
      }

ret0:
      smb_slave = save;
      return 0;
ret1:
      kill_smb_slave(smb_slave);
      strcpy(buff, lm90chip[lm90chipid]);
      return lm90chipid;
}

static int lm90_ident(LM_METHODS *method)
{
      int vend, revd;

      vend = method->Read(LM90_VENDID);
      revd = method->Read(LM90_DEVID);
      if (vend == 0x01 && revd == 0x21)
            lm90chipid = LM90;
      else if (vend == 0x41) {
            if ((revd && 0xF0) == 0x30)
                  lm90chipid = ADM1023;
            else
                  lm90chipid = ADM1020;
      }

      return lm90chipid;
}

/*
 *    \retval     0xFFFF      no sensor
 *    \retval     other temperature
 *  no = 0,1,2,...
 */
static      float lm90_temp( LM_METHODS *method, int no )
{
      int n = 0, k = 0;
      float offset = 0.0;

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

      if (no == 0)
            n = method->Read(LM90_LTEMP);
      else if (no == 1) {
            if (lm90chipid != ADM1020) {
                  if ((n = method->Read(LM90_OFFSTH)) == 0xFF)
                        n = 0;
                  if ((k = method->Read(LM90_OFFSTL)) == 0xFF)
                        k = 0;
                  else
                        k >>= 5;
                  offset = (float) n + 0.125 * (float) k;
            }
            n = method->Read(LM90_RTEMPH);
            if ((k = method->Read(LM90_RTEMPL)) == 0xFF)
                  k = 0;
            else
                  k >>= 5;
      }
      if (n >= 0x80)
            n = k = 0;

      return ((float) n + 0.125 * (float) k - offset);
}

/* lm90 is only for temperature sensor */

static      float lm90_volt(LM_METHODS *method, int no)
{
      return 0xFFFF;
}

static      int         lm90_fanrpm(LM_METHODS *method, int no)
{
      return 0xFFFF;
}


Generated by  Doxygen 1.6.0   Back to index