Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | /****************************************************************************** * * Name: sklm80.c * Project: GEnesis, PCI Gigabit Ethernet Adapter * Version: $Revision: 1.16 $ * Date: $Date: 1999/05/27 14:05:47 $ * Purpose: Funktions to access Voltage and Temperature Sensor (LM80) * ******************************************************************************/ /****************************************************************************** * * (C)Copyright 1998,1999 SysKonnect, * a business unit of Schneider & Koch & Co. Datensysteme GmbH. * * See the file "skge.c" for further information. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * The information in this file is provided "AS IS" without warranty. * ******************************************************************************/ /****************************************************************************** * * History: * * $Log: sklm80.c,v $ * Revision 1.16 1999/05/27 14:05:47 malthoff * Fans: Set SenVal to 0 if the fan value is 0 or 0xff. Both values * are outside the limits (0: div zero error, 0xff: value not in * range, assume 0). * * Revision 1.15 1999/05/27 13:38:51 malthoff * Pervent from Division by zero errors. * * Revision 1.14 1999/05/20 09:20:01 cgoos * Changes for 1000Base-T (Fan sensors). * * Revision 1.13 1998/10/22 09:48:14 gklug * fix: SysKonnectFileId typo * * Revision 1.12 1998/10/09 06:12:06 malthoff * Remove ID_sccs by SysKonnectFileId. * * Revision 1.11 1998/09/04 08:33:48 malthoff * bug fix: SenState = SK_SEN_IDLE when * leaving SK_SEN_VALEXT state * * Revision 1.10 1998/08/20 12:02:10 gklug * fix: compiler warnings type mismatch * * Revision 1.9 1998/08/20 11:37:38 gklug * chg: change Ioc to IoC * * Revision 1.8 1998/08/19 12:20:58 gklug * fix: remove struct from C files (see CCC) * * Revision 1.7 1998/08/17 07:04:57 malthoff * Take SkLm80RcvReg() function from ski2c.c. * Add IoC parameter to BREAK_OR_WAIT() macro. * * Revision 1.6 1998/08/14 07:11:28 malthoff * remove pAc with pAC. * * Revision 1.5 1998/08/14 06:46:55 gklug * fix: temperature can get negative * * Revision 1.4 1998/08/13 08:27:04 gklug * add: temperature reading now o.k. * fix: pSen declaration, SK_ERR_LOG call, ADDR macro * * Revision 1.3 1998/08/13 07:28:21 gklug * fix: pSen was wrong initialized * add: correct conversion for voltage readings * * Revision 1.2 1998/08/11 07:52:14 gklug * add: Lm80 read sensor function * * Revision 1.1 1998/07/17 09:57:12 gklug * initial version * * * ******************************************************************************/ /* LM80 functions */ static const char SysKonnectFileId[] = "$Id: sklm80.c,v 1.16 1999/05/27 14:05:47 malthoff Exp $" ; #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/lm80.h" #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ #ifdef SK_DIAG #define BREAK_OR_WAIT(pAC,IoC,Event) SkI2cWait(pAC,IoC,Event) #else /* nSK_DIAG */ #define BREAK_OR_WAIT(pAC,IoC,Event) break #endif /* nSK_DIAG */ #ifdef SK_DIAG /* * read the regeister 'reg' from the device 'device' * * return read error -1 * success the read value */ int SkLm80RcvReg( SK_IOC IoC, /* Adapter Context */ int Dev, /* I2C device address */ int Reg) /* register to read */ { int Val = 0; int TempExt; /* Signal device number */ if (SkI2cSndDev(IoC, Dev, I2C_WRITE)) { return(-1); } if (SkI2cSndByte(IoC, Reg)) { return(-1); } /* repeat start */ if (SkI2cSndDev(IoC, Dev, I2C_READ)) { return(-1); } switch(Reg) { case LM80_TEMP_IN: Val = (int)SkI2cRcvByte(IoC, 1) ; /* First: correct the value: it might be negative */ if ((Val & 0x80) != 0) { /* Value is negative */ Val = Val - 256; } Val = Val * SK_LM80_TEMP_LSB; SkI2cStop(IoC); TempExt = (int) SkLm80RcvReg(IoC,LM80_ADDR,LM80_TEMP_CTRL); if (Val > 0) { Val += ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB); } else { Val -= ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB); } return(Val); break; case LM80_VT0_IN: case LM80_VT1_IN: case LM80_VT2_IN: case LM80_VT3_IN: Val = (int) SkI2cRcvByte(IoC, 1) * SK_LM80_VT_LSB; break; default: Val = (int) SkI2cRcvByte(IoC, 1); break; } SkI2cStop(IoC); return(Val); } #endif /* SK_DIAG */ /* * read a sensors value (LM80 specific) * * This function reads a sensors value from the I2c sensor chip LM80. The * sensor is defined by its index into the sensors database in the struct * pAC points to. * * Returns 1 if the read is completed * 0 if the read must be continued (I2c Bus still allocated) */ int SkLm80ReadSensor( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* IoContext needed in level 1 and 2 */ SK_SENSOR *pSen) /* Sensor to be read */ { SK_I32 Value; switch(pSen->SenState) { case SK_SEN_IDLE: /* Send address to ADDR register */ SK_I2C_CTL(IoC,I2C_READ,pSen->SenDev,pSen->SenReg,0); pSen->SenState = SK_SEN_VALUE ; BREAK_OR_WAIT(pAC, IoC, I2C_READ) ; case SK_SEN_VALUE: /* Read value from data register */ SK_IN32(IoC,B2_I2C_DATA, ((SK_U32 *)&Value)); Value &= 0xff; /* only least significant byte is valid */ /* Do NOT check the Value against the thresholds */ /* Checking is done in the calling instance */ if (pSen->SenType == SK_SEN_VOLT) { /* Voltage sensor */ pSen->SenValue = Value * SK_LM80_VT_LSB; pSen->SenState = SK_SEN_IDLE ; return(1); } if (pSen->SenType == SK_SEN_FAN) { if (Value != 0 && Value != 0xff) { /* Fan speed counter */ pSen->SenValue = SK_LM80_FAN_FAKTOR/Value; } else { /* Indicate Fan error */ pSen->SenValue = 0; } pSen->SenState = SK_SEN_IDLE ; return(1); } /* First: correct the value: it might be negative */ if ((Value & 0x80) != 0) { /* Value is negative */ Value = Value - 256; } /* We have a temperature sensor and need to get the signed * extension. For now we get the extension from the last * reading, so in the normal case we won't see flickering * temperatures. */ pSen->SenValue = (Value * SK_LM80_TEMP_LSB) + (pSen->SenValue % SK_LM80_TEMP_LSB); /* Send address to ADDR register */ SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, LM80_TEMP_CTRL, 0); pSen->SenState = SK_SEN_VALEXT ; BREAK_OR_WAIT(pAC, IoC, I2C_READ) ; case SK_SEN_VALEXT: /* Read value from data register */ SK_IN32(IoC,B2_I2C_DATA,((SK_U32 *)&Value)); Value &= LM80_TEMP_LSB_9; /* only bit 7 is valid */ /* cut the LSB bit */ pSen->SenValue = ((pSen->SenValue / SK_LM80_TEMP_LSB) * SK_LM80_TEMP_LSB) ; if (pSen->SenValue < 0) { /* Value negative: The bit value must be subtracted */ pSen->SenValue -= ((Value >> 7) * SK_LM80_TEMPEXT_LSB); } else { /* Value positive: The bit value must be added */ pSen->SenValue += ((Value >> 7) * SK_LM80_TEMPEXT_LSB); } pSen->SenState = SK_SEN_IDLE ; return(1); default: SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E007, SKERR_I2C_E007MSG) ; return(1); } /* Not completed */ return(0) ; } |