12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505 |
- /******************************************************************************
- *
- * Name: ski2c.c
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.57 $
- * Date: $Date: 2003/01/28 09:17:38 $
- * Purpose: Functions to access Voltage and Temperature Sensor
- *
- ******************************************************************************/
- /******************************************************************************
- *
- * (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- * 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: ski2c.c,v $
- * Revision 1.57 2003/01/28 09:17:38 rschmidt
- * Fixed handling for sensors on YUKON Fiber.
- * Editorial changes.
- *
- * Revision 1.56 2002/12/19 14:20:41 rschmidt
- * Added debugging code in SkI2cWait().
- * Replaced all I2C-write operations with function SkI2cWrite().
- * Fixed compiler warning because of uninitialized 'Time' in SkI2cEvent().
- * Editorial changes.
- *
- * Revision 1.55 2002/10/15 07:23:55 rschmidt
- * Added setting of the GIYukon32Bit bool variable to distinguish
- * 32-bit adapters.
- * Editorial changes (TWSI).
- *
- * Revision 1.54 2002/08/13 09:05:06 rschmidt
- * Added new thresholds if VAUX is not available (GIVauxAvail).
- * Merged defines for PHY PLL 3V3 voltage (A and B).
- * Editorial changes.
- *
- * Revision 1.53 2002/08/08 11:04:53 rwahl
- * Added missing comment for revision 1.51
- *
- * Revision 1.52 2002/08/08 10:09:02 jschmalz
- * Sensor init state caused wrong error log entry
- *
- * Revision 1.51 2002/08/06 09:43:03 jschmalz
- * Extensions and changes for Yukon
- *
- * Revision 1.50 2002/08/02 12:09:22 rschmidt
- * Added support for YUKON sensors.
- * Editorial changes.
- *
- * Revision 1.49 2002/07/30 11:07:52 rschmidt
- * Replaced MaxSens init by update for Copper in SkI2cInit1(),
- * because it was already initialized in SkI2cInit0().
- * Editorial changes.
- *
- * Revision 1.48 2001/08/16 12:44:33 afischer
- * LM80 sensor init values corrected
- *
- * Revision 1.47 2001/04/05 11:38:09 rassmann
- * Set SenState to idle in SkI2cWaitIrq().
- * Changed error message in SkI2cWaitIrq().
- *
- * Revision 1.46 2001/04/02 14:03:35 rassmann
- * Changed pAC to IoC in SK_IN32().
- *
- * Revision 1.45 2001/03/21 12:12:49 rassmann
- * Resetting I2C_READY interrupt in SkI2cInit1().
- *
- * Revision 1.44 2000/08/07 15:49:03 gklug
- * Fix: SK_INFAST only in NetWare driver.
- *
- * Revision 1.43 2000/08/03 14:28:17 rassmann
- * Added function to wait for I2C being ready before resetting the board.
- * Replaced one duplicate "out of range" message with correct one.
- *
- * Revision 1.42 1999/11/22 13:35:12 cgoos
- * Changed license header to GPL.
- *
- * Revision 1.41 1999/09/14 14:11:30 malthoff
- * The 1000BT Dual Link adapter has got only one Fan.
- * The second Fan has been removed.
- *
- * Revision 1.40 1999/05/27 13:37:27 malthoff
- * Set divisor of 1 for fan count calculation.
- *
- * Revision 1.39 1999/05/20 14:54:43 malthoff
- * I2c.DummyReads is not used in Diagnostics.
- *
- * Revision 1.38 1999/05/20 09:20:56 cgoos
- * Changes for 1000Base-T (up to 9 sensors and fans).
- *
- * Revision 1.37 1999/03/25 15:11:36 gklug
- * fix: reset error flag if sensor reads correct value
- *
- * Revision 1.36 1999/01/07 14:11:16 gklug
- * fix: break added
- *
- * Revision 1.35 1999/01/05 15:31:49 gklug
- * fix: CLEAR STAT command is now added correctly
- *
- * Revision 1.34 1998/12/01 13:45:16 gklug
- * fix: introduced Init level, because we don't need reinits
- *
- * Revision 1.33 1998/11/09 14:54:25 malthoff
- * Modify I2C Transfer Timeout handling for Diagnostics.
- *
- * Revision 1.32 1998/11/03 06:54:35 gklug
- * fix: Need dummy reads at the beginning to init sensors
- *
- * Revision 1.31 1998/11/03 06:42:42 gklug
- * fix: select correctVIO range only if between warning levels
- *
- * Revision 1.30 1998/11/02 07:36:53 gklug
- * fix: Error should not include WARNING message
- *
- * Revision 1.29 1998/10/30 15:07:43 malthoff
- * Disable 'I2C does not compelete' error log for diagnostics.
- *
- * Revision 1.28 1998/10/22 09:48:11 gklug
- * fix: SysKonnectFileId typo
- *
- * Revision 1.27 1998/10/20 09:59:46 gklug
- * add: parameter to SkOsGetTime
- *
- * Revision 1.26 1998/10/09 06:10:59 malthoff
- * Remove ID_sccs by SysKonnectFileId.
- *
- * Revision 1.25 1998/09/08 12:40:26 gklug
- * fix: syntax error in if clause
- *
- * Revision 1.24 1998/09/08 12:19:42 gklug
- * chg: INIT Level checking
- *
- * Revision 1.23 1998/09/08 07:37:20 gklug
- * fix: log error if PCI_IO voltage sensor could not be initialized
- *
- * Revision 1.22 1998/09/04 08:30:03 malthoff
- * Bugfixes during SK_DIAG testing:
- * - correct NS2BCLK() macro
- * - correct SkI2cSndDev()
- * - correct SkI2cWait() loop waiting for an event
- *
- * Revision 1.21 1998/08/27 14:46:01 gklug
- * chg: if-then-else replaced by switch
- *
- * Revision 1.20 1998/08/27 14:40:07 gklug
- * test: integral types
- *
- * Revision 1.19 1998/08/25 07:51:54 gklug
- * fix: typos for compiling
- *
- * Revision 1.18 1998/08/25 06:12:24 gklug
- * add: count errors and warnings
- * fix: check not the sensor state but the ErrFlag!
- *
- * Revision 1.17 1998/08/25 05:56:48 gklug
- * add: CheckSensor function
- *
- * Revision 1.16 1998/08/20 11:41:10 gklug
- * chg: omit STRCPY macro by using char * as Sensor Description
- *
- * Revision 1.15 1998/08/20 11:37:35 gklug
- * chg: change Ioc to IoC
- *
- * Revision 1.14 1998/08/20 11:32:52 gklug
- * fix: Para compile error
- *
- * Revision 1.13 1998/08/20 11:27:41 gklug
- * fix: Compile bugs with new awrning constants
- *
- * Revision 1.12 1998/08/20 08:53:05 gklug
- * fix: compiler errors
- * add: Threshold values
- *
- * Revision 1.11 1998/08/19 12:39:22 malthoff
- * Compiler Fix: Some names have changed.
- *
- * Revision 1.10 1998/08/19 12:20:56 gklug
- * fix: remove struct from C files (see CCC)
- *
- * Revision 1.9 1998/08/19 06:28:46 malthoff
- * SkOsGetTime returns SK_U64 now.
- *
- * Revision 1.8 1998/08/17 13:53:33 gklug
- * fix: Parameter of event function and its result
- *
- * Revision 1.7 1998/08/17 07:02:15 malthoff
- * Modify the functions for accessing the I2C SW Registers.
- * Modify SkI2cWait().
- * Put Lm80RcvReg into sklm80.c
- * Remove Compiler Errors.
- *
- * Revision 1.6 1998/08/14 07:13:20 malthoff
- * remove pAc with pAC
- * remove smc with pAC
- * change names to new convention
- *
- * Revision 1.5 1998/08/14 06:24:49 gklug
- * add: init level 1 and 2
- *
- * Revision 1.4 1998/08/12 14:31:12 gklug
- * add: error log for unknown event
- *
- * Revision 1.3 1998/08/12 13:37:04 gklug
- * add: Init 0 function
- *
- * Revision 1.2 1998/08/11 07:27:15 gklug
- * add: functions of the interface
- * adapt rest of source to C coding Conventions
- * rmv: unnecessary code taken from Mona Lisa
- *
- * Revision 1.1 1998/06/19 14:28:43 malthoff
- * Created. Sources taken from ML Projekt.
- * Sources have to be reworked for GE.
- *
- *
- ******************************************************************************/
- #include <config.h>
- #ifdef CONFIG_SK98
- /*
- * I2C Protocol
- */
- static const char SysKonnectFileId[] =
- "$Id: ski2c.c,v 1.57 2003/01/28 09:17:38 rschmidt Exp $";
- #include "h/skdrv1st.h" /* Driver Specific Definitions */
- #include "h/lm80.h"
- #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
- #ifdef __C2MAN__
- /*
- I2C protocol implementation.
- General Description:
- The I2C protocol is used for the temperature sensors and for
- the serial EEPROM which hold the configuration.
- This file covers functions that allow to read write and do
- some bulk requests a specified I2C address.
- The Genesis has 2 I2C buses. One for the EEPROM which holds
- the VPD Data and one for temperature and voltage sensor.
- The following picture shows the I2C buses, I2C devices and
- their control registers.
- Note: The VPD functions are in skvpd.c
- .
- . PCI Config I2C Bus for VPD Data:
- .
- . +------------+
- . | VPD EEPROM |
- . +------------+
- . |
- . | <-- I2C
- . |
- . +-----------+-----------+
- . | |
- . +-----------------+ +-----------------+
- . | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG |
- . +-----------------+ +-----------------+
- .
- .
- . I2C Bus for LM80 sensor:
- .
- . +-----------------+
- . | Temperature and |
- . | Voltage Sensor |
- . | LM80 |
- . +-----------------+
- . |
- . |
- . I2C --> |
- . |
- . +----+
- . +-------------->| OR |<--+
- . | +----+ |
- . +------+------+ |
- . | | |
- . +--------+ +--------+ +----------+
- . | B2_I2C | | B2_I2C | | B2_I2C |
- . | _CTRL | | _DATA | | _SW |
- . +--------+ +--------+ +----------+
- .
- The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
- and B2_I2C_DATA registers.
- For driver software it is recommended to use the I2C control and
- data register, because I2C bus timing is done by the ASIC and
- an interrupt may be received when the I2C request is completed.
- Clock Rate Timing: MIN MAX generated by
- VPD EEPROM: 50 kHz 100 kHz HW
- LM80 over I2C Ctrl/Data reg. 50 kHz 100 kHz HW
- LM80 over B2_I2C_SW register 0 400 kHz SW
- Note: The clock generated by the hardware is dependend on the
- PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
- clock is 50 kHz.
- */
- intro()
- {}
- #endif
- #ifdef SK_DIAG
- /*
- * I2C Fast Mode timing values used by the LM80.
- * If new devices are added to the I2C bus the timing values have to be checked.
- */
- #ifndef I2C_SLOW_TIMING
- #define T_CLK_LOW 1300L /* clock low time in ns */
- #define T_CLK_HIGH 600L /* clock high time in ns */
- #define T_DATA_IN_SETUP 100L /* data in Set-up Time */
- #define T_START_HOLD 600L /* start condition hold time */
- #define T_START_SETUP 600L /* start condition Set-up time */
- #define T_STOP_SETUP 600L /* stop condition Set-up time */
- #define T_BUS_IDLE 1300L /* time the bus must free after Tx */
- #define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */
- #else /* I2C_SLOW_TIMING */
- /* I2C Standard Mode Timing */
- #define T_CLK_LOW 4700L /* clock low time in ns */
- #define T_CLK_HIGH 4000L /* clock high time in ns */
- #define T_DATA_IN_SETUP 250L /* data in Set-up Time */
- #define T_START_HOLD 4000L /* start condition hold time */
- #define T_START_SETUP 4700L /* start condition Set-up time */
- #define T_STOP_SETUP 4000L /* stop condition Set-up time */
- #define T_BUS_IDLE 4700L /* time the bus must free after Tx */
- #endif /* !I2C_SLOW_TIMING */
- #define NS2BCLK(x) (((x)*125)/10000)
- /*
- * I2C Wire Operations
- *
- * About I2C_CLK_LOW():
- *
- * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
- * clock to low, to prevent the ASIC and the I2C data client from driving the
- * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
- * send an 'ACK'). See also Concentrator Bugreport No. 10192.
- */
- #define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA)
- #define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA)
- #define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
- #define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
- #define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK)
- #define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
- #define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK)
- #define NS2CLKT(x) ((x*125L)/10000)
- /*--------------- I2C Interface Register Functions --------------- */
- /*
- * sending one bit
- */
- void SkI2cSndBit(
- SK_IOC IoC, /* I/O Context */
- SK_U8 Bit) /* Bit to send */
- {
- I2C_DATA_OUT(IoC);
- if (Bit) {
- I2C_DATA_HIGH(IoC);
- }
- else {
- I2C_DATA_LOW(IoC);
- }
- SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
- I2C_CLK_HIGH(IoC);
- SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
- I2C_CLK_LOW(IoC);
- } /* SkI2cSndBit*/
- /*
- * Signal a start to the I2C Bus.
- *
- * A start is signaled when data goes to low in a high clock cycle.
- *
- * Ends with Clock Low.
- *
- * Status: not tested
- */
- void SkI2cStart(
- SK_IOC IoC) /* I/O Context */
- {
- /* Init data and Clock to output lines */
- /* Set Data high */
- I2C_DATA_OUT(IoC);
- I2C_DATA_HIGH(IoC);
- /* Set Clock high */
- I2C_CLK_HIGH(IoC);
- SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
- /* Set Data Low */
- I2C_DATA_LOW(IoC);
- SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
- /* Clock low without Data to Input */
- I2C_START_COND(IoC);
- SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
- } /* SkI2cStart */
- void SkI2cStop(
- SK_IOC IoC) /* I/O Context */
- {
- /* Init data and Clock to output lines */
- /* Set Data low */
- I2C_DATA_OUT(IoC);
- I2C_DATA_LOW(IoC);
- SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
- /* Set Clock high */
- I2C_CLK_HIGH(IoC);
- SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
- /*
- * Set Data High: Do it by setting the Data Line to Input.
- * Because of a pull up resistor the Data Line
- * floods to high.
- */
- I2C_DATA_IN(IoC);
- /*
- * When I2C activity is stopped
- * o DATA should be set to input and
- * o CLOCK should be set to high!
- */
- SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
- } /* SkI2cStop */
- /*
- * Receive just one bit via the I2C bus.
- *
- * Note: Clock must be set to LOW before calling this function.
- *
- * Returns The received bit.
- */
- int SkI2cRcvBit(
- SK_IOC IoC) /* I/O Context */
- {
- int Bit;
- SK_U8 I2cSwCtrl;
- /* Init data as input line */
- I2C_DATA_IN(IoC);
- SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
- I2C_CLK_HIGH(IoC);
- SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
- SK_I2C_GET_SW(IoC, &I2cSwCtrl);
- Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
- I2C_CLK_LOW(IoC);
- SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
- return(Bit);
- } /* SkI2cRcvBit */
- /*
- * Receive an ACK.
- *
- * returns 0 If acknowledged
- * 1 in case of an error
- */
- int SkI2cRcvAck(
- SK_IOC IoC) /* I/O Context */
- {
- /*
- * Received bit must be zero.
- */
- return(SkI2cRcvBit(IoC) != 0);
- } /* SkI2cRcvAck */
- /*
- * Send an NACK.
- */
- void SkI2cSndNAck(
- SK_IOC IoC) /* I/O Context */
- {
- /*
- * Received bit must be zero.
- */
- SkI2cSndBit(IoC, 1);
- } /* SkI2cSndNAck */
- /*
- * Send an ACK.
- */
- void SkI2cSndAck(
- SK_IOC IoC) /* I/O Context */
- {
- /*
- * Received bit must be zero.
- *
- */
- SkI2cSndBit(IoC, 0);
- } /* SkI2cSndAck */
- /*
- * Send one byte to the I2C device and wait for ACK.
- *
- * Return acknowleged status.
- */
- int SkI2cSndByte(
- SK_IOC IoC, /* I/O Context */
- int Byte) /* byte to send */
- {
- int i;
- for (i = 0; i < 8; i++) {
- if (Byte & (1<<(7-i))) {
- SkI2cSndBit(IoC, 1);
- }
- else {
- SkI2cSndBit(IoC, 0);
- }
- }
- return(SkI2cRcvAck(IoC));
- } /* SkI2cSndByte */
- /*
- * Receive one byte and ack it.
- *
- * Return byte.
- */
- int SkI2cRcvByte(
- SK_IOC IoC, /* I/O Context */
- int Last) /* Last Byte Flag */
- {
- int i;
- int Byte = 0;
- for (i = 0; i < 8; i++) {
- Byte <<= 1;
- Byte |= SkI2cRcvBit(IoC);
- }
- if (Last) {
- SkI2cSndNAck(IoC);
- }
- else {
- SkI2cSndAck(IoC);
- }
- return(Byte);
- } /* SkI2cRcvByte */
- /*
- * Start dialog and send device address
- *
- * Return 0 if acknowleged, 1 in case of an error
- */
- int SkI2cSndDev(
- SK_IOC IoC, /* I/O Context */
- int Addr, /* Device Address */
- int Rw) /* Read / Write Flag */
- {
- SkI2cStart(IoC);
- Rw = ~Rw;
- Rw &= I2C_WRITE;
- return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
- } /* SkI2cSndDev */
- #endif /* SK_DIAG */
- /*----------------- I2C CTRL Register Functions ----------*/
- /*
- * waits for a completion of an I2C transfer
- *
- * returns 0: success, transfer completes
- * 1: error, transfer does not complete, I2C transfer
- * killed, wait loop terminated.
- */
- int SkI2cWait(
- SK_AC *pAC, /* Adapter Context */
- SK_IOC IoC, /* I/O Context */
- int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */
- {
- SK_U64 StartTime;
- SK_U64 CurrentTime;
- SK_U32 I2cCtrl;
- StartTime = SkOsGetTime(pAC);
- do {
- CurrentTime = SkOsGetTime(pAC);
- if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
- SK_I2C_STOP(IoC);
- #ifndef SK_DIAG
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
- #endif /* !SK_DIAG */
- return(1);
- }
- SK_I2C_GET_CTL(IoC, &I2cCtrl);
- #ifdef xYUKON_DBG
- printf("StartTime=%lu, CurrentTime=%lu\n",
- StartTime, CurrentTime);
- if (kbhit()) {
- return(1);
- }
- #endif /* YUKON_DBG */
- } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
- return(0);
- } /* SkI2cWait */
- /*
- * waits for a completion of an I2C transfer
- *
- * Returns
- * Nothing
- */
- void SkI2cWaitIrq(
- SK_AC *pAC, /* Adapter Context */
- SK_IOC IoC) /* I/O Context */
- {
- SK_SENSOR *pSen;
- SK_U64 StartTime;
- SK_U32 IrqSrc;
- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
- if (pSen->SenState == SK_SEN_IDLE) {
- return;
- }
- StartTime = SkOsGetTime(pAC);
- do {
- if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
- SK_I2C_STOP(IoC);
- #ifndef SK_DIAG
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
- #endif /* !SK_DIAG */
- return;
- }
- SK_IN32(IoC, B0_ISRC, &IrqSrc);
- } while ((IrqSrc & IS_I2C_READY) == 0);
- pSen->SenState = SK_SEN_IDLE;
- return;
- } /* SkI2cWaitIrq */
- /*
- * writes a single byte or 4 bytes into the I2C device
- *
- * returns 0: success
- * 1: error
- */
- int SkI2cWrite(
- SK_AC *pAC, /* Adapter Context */
- SK_IOC IoC, /* I/O Context */
- SK_U32 I2cData, /* I2C Data to write */
- int I2cDev, /* I2C Device Address */
- int I2cReg, /* I2C Device Register Address */
- int I2cBurst) /* I2C Burst Flag */
- {
- SK_OUT32(IoC, B2_I2C_DATA, I2cData);
- SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst);
- return(SkI2cWait(pAC, IoC, I2C_WRITE));
- } /* SkI2cWrite*/
- #ifdef SK_DIAG
- /*
- * reads a single byte or 4 bytes from the I2C device
- *
- * returns the word read
- */
- SK_U32 SkI2cRead(
- SK_AC *pAC, /* Adapter Context */
- SK_IOC IoC, /* I/O Context */
- int I2cDev, /* I2C Device Address */
- int I2cReg, /* I2C Device Register Address */
- int I2cBurst) /* I2C Burst Flag */
- {
- SK_U32 Data;
- SK_OUT32(IoC, B2_I2C_DATA, 0);
- SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst);
- if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
- w_print("%s\n", SKERR_I2C_E002MSG);
- }
- SK_IN32(IoC, B2_I2C_DATA, &Data);
- return(Data);
- } /* SkI2cRead */
- #endif /* SK_DIAG */
- /*
- * read a sensor's value
- *
- * This function reads a sensor's value from the I2C sensor chip. 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 SkI2cReadSensor(
- SK_AC *pAC, /* Adapter Context */
- SK_IOC IoC, /* I/O Context */
- SK_SENSOR *pSen) /* Sensor to be read */
- {
- if (pSen->SenRead != NULL) {
- return((*pSen->SenRead)(pAC, IoC, pSen));
- }
- else
- return(0); /* no success */
- } /* SkI2cReadSensor*/
- /*
- * Do the Init state 0 initialization
- */
- static int SkI2cInit0(
- SK_AC *pAC) /* Adapter Context */
- {
- int i;
- /* Begin with first sensor */
- pAC->I2c.CurrSens = 0;
- /* Begin with timeout control for state machine */
- pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
- /* Set sensor number to zero */
- pAC->I2c.MaxSens = 0;
- #ifndef SK_DIAG
- /* Initialize Number of Dummy Reads */
- pAC->I2c.DummyReads = SK_MAX_SENSORS;
- #endif
- for (i = 0; i < SK_MAX_SENSORS; i++) {
- pAC->I2c.SenTable[i].SenDesc = "unknown";
- pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
- pAC->I2c.SenTable[i].SenThreErrHigh = 0;
- pAC->I2c.SenTable[i].SenThreErrLow = 0;
- pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
- pAC->I2c.SenTable[i].SenThreWarnLow = 0;
- pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
- pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
- pAC->I2c.SenTable[i].SenValue = 0;
- pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
- pAC->I2c.SenTable[i].SenErrCts = 0;
- pAC->I2c.SenTable[i].SenBegErrTS = 0;
- pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
- pAC->I2c.SenTable[i].SenRead = NULL;
- pAC->I2c.SenTable[i].SenDev = 0;
- }
- /* Now we are "INIT data"ed */
- pAC->I2c.InitLevel = SK_INIT_DATA;
- return(0);
- } /* SkI2cInit0*/
- /*
- * Do the init state 1 initialization
- *
- * initialize the following register of the LM80:
- * Configuration register:
- * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
- *
- * Interrupt Mask Register 1:
- * - all interrupts are Disabled (0xff)
- *
- * Interrupt Mask Register 2:
- * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
- *
- * Fan Divisor/RST_OUT register:
- * - Divisors set to 1 (bits 00), all others 0s.
- *
- * OS# Configuration/Temperature resolution Register:
- * - all 0s
- *
- */
- static int SkI2cInit1(
- SK_AC *pAC, /* Adapter Context */
- SK_IOC IoC) /* I/O Context */
- {
- int i;
- SK_U8 I2cSwCtrl;
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
- if (pAC->I2c.InitLevel != SK_INIT_DATA) {
- /* ReInit not needed in I2C module */
- return(0);
- }
- /* Set the Direction of I2C-Data Pin to IN */
- SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
- /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
- SK_I2C_GET_SW(IoC, &I2cSwCtrl);
- if ((I2cSwCtrl & I2C_DATA) == 0) {
- /* this is a 32-Bit board */
- pAC->GIni.GIYukon32Bit = SK_TRUE;
- return(0);
- }
- /* Check for 64 Bit Yukon without sensors */
- if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_CFG, 0) != 0) {
- return(0);
- }
- (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_1, 0);
- (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_2, 0);
- (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_FAN_CTRL, 0);
- (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_TEMP_CTRL, 0);
- (void)SkI2cWrite(pAC, IoC, LM80_CFG_START, LM80_ADDR, LM80_CFG, 0);
- /*
- * MaxSens has to be updated here, because PhyType is not
- * set when performing Init Level 0
- */
- pAC->I2c.MaxSens = 5;
- pPrt = &pAC->GIni.GP[0];
- if (pAC->GIni.GIGenesis) {
- if (pPrt->PhyType == SK_PHY_BCOM) {
- if (pAC->GIni.GIMacsFound == 1) {
- pAC->I2c.MaxSens += 1;
- }
- else {
- pAC->I2c.MaxSens += 3;
- }
- }
- }
- else {
- pAC->I2c.MaxSens += 3;
- }
- for (i = 0; i < pAC->I2c.MaxSens; i++) {
- switch (i) {
- case 0:
- pAC->I2c.SenTable[i].SenDesc = "Temperature";
- pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
- break;
- case 1:
- pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
- break;
- case 2:
- pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
- pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
- break;
- case 3:
- pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
- break;
- case 4:
- if (pAC->GIni.GIGenesis) {
- if (pPrt->PhyType == SK_PHY_BCOM) {
- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
- }
- else {
- pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
- }
- }
- else {
- pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
- if (pAC->GIni.GIVauxAvail) {
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
- }
- else {
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
- }
- }
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
- break;
- case 5:
- if (pAC->GIni.GIGenesis) {
- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
- }
- else {
- pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC-Co 1V5";
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
- }
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
- break;
- case 6:
- if (pAC->GIni.GIGenesis) {
- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
- }
- else {
- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
- }
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
- break;
- case 7:
- if (pAC->GIni.GIGenesis) {
- pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
- pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
- }
- else {
- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
- }
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
- SKERR_I2C_E001, SKERR_I2C_E001MSG);
- break;
- }
- pAC->I2c.SenTable[i].SenValue = 0;
- pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
- pAC->I2c.SenTable[i].SenErrCts = 0;
- pAC->I2c.SenTable[i].SenBegErrTS = 0;
- pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
- pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
- pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
- }
- #ifndef SK_DIAG
- pAC->I2c.DummyReads = pAC->I2c.MaxSens;
- #endif /* !SK_DIAG */
- /* Clear I2C IRQ */
- SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
- /* Now we are I/O initialized */
- pAC->I2c.InitLevel = SK_INIT_IO;
- return(0);
- } /* SkI2cInit1 */
- /*
- * Init level 2: Start first sensor read.
- */
- static int SkI2cInit2(
- SK_AC *pAC, /* Adapter Context */
- SK_IOC IoC) /* I/O Context */
- {
- int ReadComplete;
- SK_SENSOR *pSen;
- if (pAC->I2c.InitLevel != SK_INIT_IO) {
- /* ReInit not needed in I2C module */
- /* Init0 and Init2 not permitted */
- return(0);
- }
- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
- ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
- if (ReadComplete) {
- SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
- }
- /* Now we are correctly initialized */
- pAC->I2c.InitLevel = SK_INIT_RUN;
- return(0);
- } /* SkI2cInit2*/
- /*
- * Initialize I2C devices
- *
- * Get the first voltage value and discard it.
- * Go into temperature read mode. A default pointer is not set.
- *
- * The things to be done depend on the init level in the parameter list:
- * Level 0:
- * Initialize only the data structures. Do NOT access hardware.
- * Level 1:
- * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
- * Level 2:
- * Everything is possible. Interrupts may be used from now on.
- *
- * return:
- * 0 = success
- * other = error.
- */
- int SkI2cInit(
- SK_AC *pAC, /* Adapter Context */
- SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */
- int Level) /* Init Level */
- {
- switch (Level) {
- case SK_INIT_DATA:
- return(SkI2cInit0(pAC));
- case SK_INIT_IO:
- return(SkI2cInit1(pAC, IoC));
- case SK_INIT_RUN:
- return(SkI2cInit2(pAC, IoC));
- default:
- break;
- }
- return(0);
- } /* SkI2cInit */
- #ifndef SK_DIAG
- /*
- * Interrupt service function for the I2C Interface
- *
- * Clears the Interrupt source
- *
- * Reads the register and check it for sending a trap.
- *
- * Starts the timer if necessary.
- */
- void SkI2cIsr(
- SK_AC *pAC, /* Adapter Context */
- SK_IOC IoC) /* I/O Context */
- {
- SK_EVPARA Para;
- /* Clear I2C IRQ */
- SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
- Para.Para64 = 0;
- SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
- } /* SkI2cIsr */
- /*
- * Check this sensors Value against the threshold and send events.
- */
- static void SkI2cCheckSensor(
- SK_AC *pAC, /* Adapter Context */
- SK_SENSOR *pSen)
- {
- SK_EVPARA ParaLocal;
- SK_BOOL TooHigh; /* Is sensor too high? */
- SK_BOOL TooLow; /* Is sensor too low? */
- SK_U64 CurrTime; /* Current Time */
- SK_BOOL DoTrapSend; /* We need to send a trap */
- SK_BOOL DoErrLog; /* We need to log the error */
- SK_BOOL IsError; /* We need to log the error */
- /* Check Dummy Reads first */
- if (pAC->I2c.DummyReads > 0) {
- pAC->I2c.DummyReads--;
- return;
- }
- /* Get the current time */
- CurrTime = SkOsGetTime(pAC);
- /* Set para to the most useful setting: The current sensor. */
- ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
- /* Check the Value against the thresholds. First: Error Thresholds */
- TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
- TooLow = (pSen->SenValue < pSen->SenThreErrLow);
- IsError = SK_FALSE;
- if (TooHigh || TooLow) {
- /* Error condition is satisfied */
- DoTrapSend = SK_TRUE;
- DoErrLog = SK_TRUE;
- /* Now error condition is satisfied */
- IsError = SK_TRUE;
- if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
- /* This state is the former one */
- /* So check first whether we have to send a trap */
- if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
- CurrTime) {
- /*
- * Do NOT send the Trap. The hold back time
- * has to run out first.
- */
- DoTrapSend = SK_FALSE;
- }
- /* Check now whether we have to log an Error */
- if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
- CurrTime) {
- /*
- * Do NOT log the error. The hold back time
- * has to run out first.
- */
- DoErrLog = SK_FALSE;
- }
- }
- else {
- /* We came from a different state -> Set Begin Time Stamp */
- pSen->SenBegErrTS = CurrTime;
- pSen->SenErrFlag = SK_SEN_ERR_ERR;
- }
- if (DoTrapSend) {
- /* Set current Time */
- pSen->SenLastErrTrapTS = CurrTime;
- pSen->SenErrCts++;
- /* Queue PNMI Event */
- SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
- SK_PNMI_EVT_SEN_ERR_UPP :
- SK_PNMI_EVT_SEN_ERR_LOW),
- ParaLocal);
- }
- if (DoErrLog) {
- /* Set current Time */
- pSen->SenLastErrLogTS = CurrTime;
- if (pSen->SenType == SK_SEN_TEMP) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011,
- SKERR_I2C_E011MSG);
- } else if (pSen->SenType == SK_SEN_VOLT) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012,
- SKERR_I2C_E012MSG);
- } else
- {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015,
- SKERR_I2C_E015MSG);
- }
- }
- }
- /* Check the Value against the thresholds */
- /* 2nd: Warning thresholds */
- TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
- TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
- if (!IsError && (TooHigh || TooLow)) {
- /* Error condition is satisfied */
- DoTrapSend = SK_TRUE;
- DoErrLog = SK_TRUE;
- if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
- /* This state is the former one */
- /* So check first whether we have to send a trap */
- if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD >
- CurrTime) {
- /*
- * Do NOT send the Trap. The hold back time
- * has to run out first.
- */
- DoTrapSend = SK_FALSE;
- }
- /* Check now whether we have to log an Error */
- if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD >
- CurrTime) {
- /*
- * Do NOT log the error. The hold back time
- * has to run out first.
- */
- DoErrLog = SK_FALSE;
- }
- }
- else {
- /* We came from a different state -> Set Begin Time Stamp */
- pSen->SenBegWarnTS = CurrTime;
- pSen->SenErrFlag = SK_SEN_ERR_WARN;
- }
- if (DoTrapSend) {
- /* Set current Time */
- pSen->SenLastWarnTrapTS = CurrTime;
- pSen->SenWarnCts++;
- /* Queue PNMI Event */
- SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
- SK_PNMI_EVT_SEN_WAR_UPP :
- SK_PNMI_EVT_SEN_WAR_LOW),
- ParaLocal);
- }
- if (DoErrLog) {
- /* Set current Time */
- pSen->SenLastWarnLogTS = CurrTime;
- if (pSen->SenType == SK_SEN_TEMP) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009,
- SKERR_I2C_E009MSG);
- } else if (pSen->SenType == SK_SEN_VOLT) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010,
- SKERR_I2C_E010MSG);
- } else
- {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014,
- SKERR_I2C_E014MSG);
- }
- }
- }
- /* Check for NO error at all */
- if (!IsError && !TooHigh && !TooLow) {
- /* Set o.k. Status if no error and no warning condition */
- pSen->SenErrFlag = SK_SEN_ERR_OK;
- }
- /* End of check against the thresholds */
- /* Bug fix AF: 16.Aug.2001: Correct the init base
- * of LM80 sensor.
- */
- if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
- pSen->SenInit = SK_SEN_DYN_INIT_NONE;
- if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
- /* 5V PCI-IO Voltage */
- pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
- pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
- }
- else {
- /* 3.3V PCI-IO Voltage */
- pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
- pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
- }
- }
- #if 0
- /* Dynamic thresholds also for VAUX of LM80 sensor */
- if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
- pSen->SenInit = SK_SEN_DYN_INIT_NONE;
- /* 3.3V VAUX Voltage */
- if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
- pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
- pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
- }
- /* 0V VAUX Voltage */
- else {
- pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
- pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
- }
- }
- /*
- * Check initialization state:
- * The VIO Thresholds need adaption
- */
- if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
- pSen->SenValue > SK_SEN_WARNLOW2C &&
- pSen->SenValue < SK_SEN_WARNHIGH2) {
- pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
- pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
- pSen->SenInit = SK_TRUE;
- }
- if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
- pSen->SenValue > SK_SEN_WARNLOW2 &&
- pSen->SenValue < SK_SEN_WARNHIGH2C) {
- pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
- pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
- pSen->SenInit = SK_TRUE;
- }
- #endif
- if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
- }
- } /* SkI2cCheckSensor*/
- /*
- * The only Event to be served is the timeout event
- *
- */
- int SkI2cEvent(
- SK_AC *pAC, /* Adapter Context */
- SK_IOC IoC, /* I/O Context */
- SK_U32 Event, /* Module specific Event */
- SK_EVPARA Para) /* Event specific Parameter */
- {
- int ReadComplete;
- SK_SENSOR *pSen;
- SK_U32 Time;
- SK_EVPARA ParaLocal;
- int i;
- /* New case: no sensors */
- if (pAC->I2c.MaxSens == 0) {
- return(0);
- }
- switch (Event) {
- case SK_I2CEV_IRQ:
- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
- ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
- if (ReadComplete) {
- /* Check sensor against defined thresholds */
- SkI2cCheckSensor (pAC, pSen);
- /* Increment Current sensor and set appropriate Timeout */
- pAC->I2c.CurrSens++;
- if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
- pAC->I2c.CurrSens = 0;
- Time = SK_I2C_TIM_LONG;
- }
- else {
- Time = SK_I2C_TIM_SHORT;
- }
- /* Start Timer */
- ParaLocal.Para64 = (SK_U64)0;
- pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
- SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
- SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
- }
- else {
- /* Start Timer */
- ParaLocal.Para64 = (SK_U64)0;
- pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
- SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
- SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
- }
- break;
- case SK_I2CEV_TIM:
- if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
- ParaLocal.Para64 = (SK_U64)0;
- SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
- ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
- if (ReadComplete) {
- /* Check sensor against defined thresholds */
- SkI2cCheckSensor (pAC, pSen);
- /* Increment Current sensor and set appropriate Timeout */
- pAC->I2c.CurrSens++;
- if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
- pAC->I2c.CurrSens = 0;
- Time = SK_I2C_TIM_LONG;
- }
- else {
- Time = SK_I2C_TIM_SHORT;
- }
- /* Start Timer */
- ParaLocal.Para64 = (SK_U64)0;
- pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
- SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
- SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
- }
- }
- else {
- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
- pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
- SK_I2C_STOP(IoC);
- /* Increment Current sensor and set appropriate Timeout */
- pAC->I2c.CurrSens++;
- if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
- pAC->I2c.CurrSens = 0;
- Time = SK_I2C_TIM_LONG;
- }
- else {
- Time = SK_I2C_TIM_SHORT;
- }
- /* Start Timer */
- ParaLocal.Para64 = (SK_U64)0;
- pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
- SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
- SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
- }
- break;
- case SK_I2CEV_CLEAR:
- for (i = 0; i < SK_MAX_SENSORS; i++) {
- pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
- pAC->I2c.SenTable[i].SenErrCts = 0;
- pAC->I2c.SenTable[i].SenWarnCts = 0;
- pAC->I2c.SenTable[i].SenBegErrTS = 0;
- pAC->I2c.SenTable[i].SenBegWarnTS = 0;
- pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
- pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
- pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
- pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
- }
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
- }
- return(0);
- } /* SkI2cEvent*/
- #endif /* !SK_DIAG */
- #endif /* CONFIG_SK98 */
|