/*
* 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;
}
syntax highlighted by Code2HTML, v. 0.9.1