1/****************************************************************************** 2 * 3 * Name: sklm80.c 4 * Project: Gigabit Ethernet Adapters, TWSI-Module 5 * Version: $Revision: 1.1.1.1 $ 6 * Date: $Date: 2007/08/03 18:52:48 $ 7 * Purpose: Functions to access Voltage and Temperature Sensor (LM80) 8 * 9 ******************************************************************************/ 10 11/****************************************************************************** 12 * 13 * (C)Copyright 1998-2002 SysKonnect. 14 * (C)Copyright 2002-2003 Marvell. 15 * 16 * This program is free software; you can redistribute it and/or modify 17 * it under the terms of the GNU General Public License as published by 18 * the Free Software Foundation; either version 2 of the License, or 19 * (at your option) any later version. 20 * 21 * The information in this file is provided "AS IS" without warranty. 22 * 23 ******************************************************************************/ 24 25/* 26 LM80 functions 27*/ 28#if (defined(DEBUG) || (!defined(LINT) && !defined(SK_SLIM))) 29static const char SysKonnectFileId[] = 30 "@(#) $Id: sklm80.c,v 1.1.1.1 2007/08/03 18:52:48 Exp $ (C) Marvell. "; 31#endif 32 33#include "h/skdrv1st.h" /* Driver Specific Definitions */ 34#include "h/lm80.h" 35#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ 36 37#define BREAK_OR_WAIT(pAC,IoC,Event) break 38 39/* 40 * read a sensors value (LM80 specific) 41 * 42 * This function reads a sensors value from the I2C sensor chip LM80. 43 * The sensor is defined by its index into the sensors database in the struct 44 * pAC points to. 45 * 46 * Returns 1 if the read is completed 47 * 0 if the read must be continued (I2C Bus still allocated) 48 */ 49int SkLm80ReadSensor( 50SK_AC *pAC, /* Adapter Context */ 51SK_IOC IoC, /* I/O Context needed in level 1 and 2 */ 52SK_SENSOR *pSen) /* Sensor to be read */ 53{ 54 SK_I32 Value; 55 56 switch (pSen->SenState) { 57 case SK_SEN_IDLE: 58 /* Send address to ADDR register */ 59 SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, pSen->SenReg, 0); 60 61 pSen->SenState = SK_SEN_VALUE ; 62 BREAK_OR_WAIT(pAC, IoC, I2C_READ); 63 64 case SK_SEN_VALUE: 65 /* Read value from data register */ 66 SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value)); 67 68 Value &= 0xff; /* only least significant byte is valid */ 69 70 /* Do NOT check the Value against the thresholds */ 71 /* Checking is done in the calling instance */ 72 73 if (pSen->SenType == SK_SEN_VOLT) { 74 /* Voltage sensor */ 75 pSen->SenValue = Value * SK_LM80_VT_LSB; 76 pSen->SenState = SK_SEN_IDLE ; 77 return(1); 78 } 79 80 if (pSen->SenType == SK_SEN_FAN) { 81 if (Value != 0 && Value != 0xff) { 82 /* Fan speed counter */ 83 pSen->SenValue = SK_LM80_FAN_FAKTOR/Value; 84 } 85 else { 86 /* Indicate Fan error */ 87 pSen->SenValue = 0; 88 } 89 pSen->SenState = SK_SEN_IDLE ; 90 return(1); 91 } 92 93 /* First: correct the value: it might be negative */ 94 if ((Value & 0x80) != 0) { 95 /* Value is negative */ 96 Value = Value - 256; 97 } 98 99 /* We have a temperature sensor and need to get the signed extension. 100 * For now we get the extension from the last reading, so in the normal 101 * case we won't see flickering temperatures. 102 */ 103 pSen->SenValue = (Value * SK_LM80_TEMP_LSB) + 104 (pSen->SenValue % SK_LM80_TEMP_LSB); 105 106 /* Send address to ADDR register */ 107 SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, LM80_TEMP_CTRL, 0); 108 109 pSen->SenState = SK_SEN_VALEXT ; 110 BREAK_OR_WAIT(pAC, IoC, I2C_READ); 111 112 case SK_SEN_VALEXT: 113 /* Read value from data register */ 114 SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value)); 115 Value &= LM80_TEMP_LSB_9; /* only bit 7 is valid */ 116 117 /* cut the LSB bit */ 118 pSen->SenValue = ((pSen->SenValue / SK_LM80_TEMP_LSB) * 119 SK_LM80_TEMP_LSB); 120 121 if (pSen->SenValue < 0) { 122 /* Value negative: The bit value must be subtracted */ 123 pSen->SenValue -= ((Value >> 7) * SK_LM80_TEMPEXT_LSB); 124 } 125 else { 126 /* Value positive: The bit value must be added */ 127 pSen->SenValue += ((Value >> 7) * SK_LM80_TEMPEXT_LSB); 128 } 129 130 pSen->SenState = SK_SEN_IDLE ; 131 return(1); 132 133 default: 134 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E007, SKERR_I2C_E007MSG); 135 return(1); 136 } 137 138 /* Not completed */ 139 return(0); 140} 141