1 /******************************************************************************
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.57 $
6 * Date: $Date: 2003/01/28 09:17:38 $
7 * Purpose: Functions to access Voltage and Temperature Sensor
9 ******************************************************************************/
11 /******************************************************************************
13 * (C)Copyright 1998-2003 SysKonnect GmbH.
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * The information in this file is provided "AS IS" without warranty.
22 ******************************************************************************/
24 /******************************************************************************
29 * Revision 1.57 2003/01/28 09:17:38 rschmidt
30 * Fixed handling for sensors on YUKON Fiber.
33 * Revision 1.56 2002/12/19 14:20:41 rschmidt
34 * Added debugging code in SkI2cWait().
35 * Replaced all I2C-write operations with function SkI2cWrite().
36 * Fixed compiler warning because of uninitialized 'Time' in SkI2cEvent().
39 * Revision 1.55 2002/10/15 07:23:55 rschmidt
40 * Added setting of the GIYukon32Bit bool variable to distinguish
42 * Editorial changes (TWSI).
44 * Revision 1.54 2002/08/13 09:05:06 rschmidt
45 * Added new thresholds if VAUX is not available (GIVauxAvail).
46 * Merged defines for PHY PLL 3V3 voltage (A and B).
49 * Revision 1.53 2002/08/08 11:04:53 rwahl
50 * Added missing comment for revision 1.51
52 * Revision 1.52 2002/08/08 10:09:02 jschmalz
53 * Sensor init state caused wrong error log entry
55 * Revision 1.51 2002/08/06 09:43:03 jschmalz
56 * Extensions and changes for Yukon
58 * Revision 1.50 2002/08/02 12:09:22 rschmidt
59 * Added support for YUKON sensors.
62 * Revision 1.49 2002/07/30 11:07:52 rschmidt
63 * Replaced MaxSens init by update for Copper in SkI2cInit1(),
64 * because it was already initialized in SkI2cInit0().
67 * Revision 1.48 2001/08/16 12:44:33 afischer
68 * LM80 sensor init values corrected
70 * Revision 1.47 2001/04/05 11:38:09 rassmann
71 * Set SenState to idle in SkI2cWaitIrq().
72 * Changed error message in SkI2cWaitIrq().
74 * Revision 1.46 2001/04/02 14:03:35 rassmann
75 * Changed pAC to IoC in SK_IN32().
77 * Revision 1.45 2001/03/21 12:12:49 rassmann
78 * Resetting I2C_READY interrupt in SkI2cInit1().
80 * Revision 1.44 2000/08/07 15:49:03 gklug
81 * Fix: SK_INFAST only in NetWare driver.
83 * Revision 1.43 2000/08/03 14:28:17 rassmann
84 * Added function to wait for I2C being ready before resetting the board.
85 * Replaced one duplicate "out of range" message with correct one.
87 * Revision 1.42 1999/11/22 13:35:12 cgoos
88 * Changed license header to GPL.
90 * Revision 1.41 1999/09/14 14:11:30 malthoff
91 * The 1000BT Dual Link adapter has got only one Fan.
92 * The second Fan has been removed.
94 * Revision 1.40 1999/05/27 13:37:27 malthoff
95 * Set divisor of 1 for fan count calculation.
97 * Revision 1.39 1999/05/20 14:54:43 malthoff
98 * I2c.DummyReads is not used in Diagnostics.
100 * Revision 1.38 1999/05/20 09:20:56 cgoos
101 * Changes for 1000Base-T (up to 9 sensors and fans).
103 * Revision 1.37 1999/03/25 15:11:36 gklug
104 * fix: reset error flag if sensor reads correct value
106 * Revision 1.36 1999/01/07 14:11:16 gklug
109 * Revision 1.35 1999/01/05 15:31:49 gklug
110 * fix: CLEAR STAT command is now added correctly
112 * Revision 1.34 1998/12/01 13:45:16 gklug
113 * fix: introduced Init level, because we don't need reinits
115 * Revision 1.33 1998/11/09 14:54:25 malthoff
116 * Modify I2C Transfer Timeout handling for Diagnostics.
118 * Revision 1.32 1998/11/03 06:54:35 gklug
119 * fix: Need dummy reads at the beginning to init sensors
121 * Revision 1.31 1998/11/03 06:42:42 gklug
122 * fix: select correctVIO range only if between warning levels
124 * Revision 1.30 1998/11/02 07:36:53 gklug
125 * fix: Error should not include WARNING message
127 * Revision 1.29 1998/10/30 15:07:43 malthoff
128 * Disable 'I2C does not compelete' error log for diagnostics.
130 * Revision 1.28 1998/10/22 09:48:11 gklug
131 * fix: SysKonnectFileId typo
133 * Revision 1.27 1998/10/20 09:59:46 gklug
134 * add: parameter to SkOsGetTime
136 * Revision 1.26 1998/10/09 06:10:59 malthoff
137 * Remove ID_sccs by SysKonnectFileId.
139 * Revision 1.25 1998/09/08 12:40:26 gklug
140 * fix: syntax error in if clause
142 * Revision 1.24 1998/09/08 12:19:42 gklug
143 * chg: INIT Level checking
145 * Revision 1.23 1998/09/08 07:37:20 gklug
146 * fix: log error if PCI_IO voltage sensor could not be initialized
148 * Revision 1.22 1998/09/04 08:30:03 malthoff
149 * Bugfixes during SK_DIAG testing:
150 * - correct NS2BCLK() macro
151 * - correct SkI2cSndDev()
152 * - correct SkI2cWait() loop waiting for an event
154 * Revision 1.21 1998/08/27 14:46:01 gklug
155 * chg: if-then-else replaced by switch
157 * Revision 1.20 1998/08/27 14:40:07 gklug
158 * test: integral types
160 * Revision 1.19 1998/08/25 07:51:54 gklug
161 * fix: typos for compiling
163 * Revision 1.18 1998/08/25 06:12:24 gklug
164 * add: count errors and warnings
165 * fix: check not the sensor state but the ErrFlag!
167 * Revision 1.17 1998/08/25 05:56:48 gklug
168 * add: CheckSensor function
170 * Revision 1.16 1998/08/20 11:41:10 gklug
171 * chg: omit STRCPY macro by using char * as Sensor Description
173 * Revision 1.15 1998/08/20 11:37:35 gklug
174 * chg: change Ioc to IoC
176 * Revision 1.14 1998/08/20 11:32:52 gklug
177 * fix: Para compile error
179 * Revision 1.13 1998/08/20 11:27:41 gklug
180 * fix: Compile bugs with new awrning constants
182 * Revision 1.12 1998/08/20 08:53:05 gklug
183 * fix: compiler errors
184 * add: Threshold values
186 * Revision 1.11 1998/08/19 12:39:22 malthoff
187 * Compiler Fix: Some names have changed.
189 * Revision 1.10 1998/08/19 12:20:56 gklug
190 * fix: remove struct from C files (see CCC)
192 * Revision 1.9 1998/08/19 06:28:46 malthoff
193 * SkOsGetTime returns SK_U64 now.
195 * Revision 1.8 1998/08/17 13:53:33 gklug
196 * fix: Parameter of event function and its result
198 * Revision 1.7 1998/08/17 07:02:15 malthoff
199 * Modify the functions for accessing the I2C SW Registers.
200 * Modify SkI2cWait().
201 * Put Lm80RcvReg into sklm80.c
202 * Remove Compiler Errors.
204 * Revision 1.6 1998/08/14 07:13:20 malthoff
205 * remove pAc with pAC
206 * remove smc with pAC
207 * change names to new convention
209 * Revision 1.5 1998/08/14 06:24:49 gklug
210 * add: init level 1 and 2
212 * Revision 1.4 1998/08/12 14:31:12 gklug
213 * add: error log for unknown event
215 * Revision 1.3 1998/08/12 13:37:04 gklug
216 * add: Init 0 function
218 * Revision 1.2 1998/08/11 07:27:15 gklug
219 * add: functions of the interface
220 * adapt rest of source to C coding Conventions
221 * rmv: unnecessary code taken from Mona Lisa
223 * Revision 1.1 1998/06/19 14:28:43 malthoff
224 * Created. Sources taken from ML Projekt.
225 * Sources have to be reworked for GE.
228 ******************************************************************************/
238 static const char SysKonnectFileId[] =
239 "$Id: ski2c.c,v 1.57 2003/01/28 09:17:38 rschmidt Exp $";
241 #include "h/skdrv1st.h" /* Driver Specific Definitions */
243 #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
247 I2C protocol implementation.
251 The I2C protocol is used for the temperature sensors and for
252 the serial EEPROM which hold the configuration.
254 This file covers functions that allow to read write and do
255 some bulk requests a specified I2C address.
257 The Genesis has 2 I2C buses. One for the EEPROM which holds
258 the VPD Data and one for temperature and voltage sensor.
259 The following picture shows the I2C buses, I2C devices and
260 their control registers.
262 Note: The VPD functions are in skvpd.c
264 . PCI Config I2C Bus for VPD Data:
272 . +-----------+-----------+
274 . +-----------------+ +-----------------+
275 . | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG |
276 . +-----------------+ +-----------------+
279 . I2C Bus for LM80 sensor:
281 . +-----------------+
282 . | Temperature and |
285 . +-----------------+
291 . +-------------->| OR |<--+
295 . +--------+ +--------+ +----------+
296 . | B2_I2C | | B2_I2C | | B2_I2C |
297 . | _CTRL | | _DATA | | _SW |
298 . +--------+ +--------+ +----------+
300 The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
301 and B2_I2C_DATA registers.
302 For driver software it is recommended to use the I2C control and
303 data register, because I2C bus timing is done by the ASIC and
304 an interrupt may be received when the I2C request is completed.
306 Clock Rate Timing: MIN MAX generated by
307 VPD EEPROM: 50 kHz 100 kHz HW
308 LM80 over I2C Ctrl/Data reg. 50 kHz 100 kHz HW
309 LM80 over B2_I2C_SW register 0 400 kHz SW
311 Note: The clock generated by the hardware is dependend on the
312 PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
321 * I2C Fast Mode timing values used by the LM80.
322 * If new devices are added to the I2C bus the timing values have to be checked.
324 #ifndef I2C_SLOW_TIMING
325 #define T_CLK_LOW 1300L /* clock low time in ns */
326 #define T_CLK_HIGH 600L /* clock high time in ns */
327 #define T_DATA_IN_SETUP 100L /* data in Set-up Time */
328 #define T_START_HOLD 600L /* start condition hold time */
329 #define T_START_SETUP 600L /* start condition Set-up time */
330 #define T_STOP_SETUP 600L /* stop condition Set-up time */
331 #define T_BUS_IDLE 1300L /* time the bus must free after Tx */
332 #define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */
333 #else /* I2C_SLOW_TIMING */
334 /* I2C Standard Mode Timing */
335 #define T_CLK_LOW 4700L /* clock low time in ns */
336 #define T_CLK_HIGH 4000L /* clock high time in ns */
337 #define T_DATA_IN_SETUP 250L /* data in Set-up Time */
338 #define T_START_HOLD 4000L /* start condition hold time */
339 #define T_START_SETUP 4700L /* start condition Set-up time */
340 #define T_STOP_SETUP 4000L /* stop condition Set-up time */
341 #define T_BUS_IDLE 4700L /* time the bus must free after Tx */
342 #endif /* !I2C_SLOW_TIMING */
344 #define NS2BCLK(x) (((x)*125)/10000)
347 * I2C Wire Operations
349 * About I2C_CLK_LOW():
351 * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
352 * clock to low, to prevent the ASIC and the I2C data client from driving the
353 * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
354 * send an 'ACK'). See also Concentrator Bugreport No. 10192.
356 #define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA)
357 #define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA)
358 #define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
359 #define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
360 #define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK)
361 #define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
362 #define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK)
364 #define NS2CLKT(x) ((x*125L)/10000)
366 /*--------------- I2C Interface Register Functions --------------- */
372 SK_IOC IoC, /* I/O Context */
373 SK_U8 Bit) /* Bit to send */
382 SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
384 SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
390 * Signal a start to the I2C Bus.
392 * A start is signaled when data goes to low in a high clock cycle.
394 * Ends with Clock Low.
399 SK_IOC IoC) /* I/O Context */
401 /* Init data and Clock to output lines */
408 SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
413 SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
415 /* Clock low without Data to Input */
418 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
423 SK_IOC IoC) /* I/O Context */
425 /* Init data and Clock to output lines */
430 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
435 SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
438 * Set Data High: Do it by setting the Data Line to Input.
439 * Because of a pull up resistor the Data Line
445 * When I2C activity is stopped
446 * o DATA should be set to input and
447 * o CLOCK should be set to high!
449 SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
454 * Receive just one bit via the I2C bus.
456 * Note: Clock must be set to LOW before calling this function.
458 * Returns The received bit.
461 SK_IOC IoC) /* I/O Context */
466 /* Init data as input line */
469 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
473 SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
475 SK_I2C_GET_SW(IoC, &I2cSwCtrl);
477 Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
480 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
489 * returns 0 If acknowledged
490 * 1 in case of an error
493 SK_IOC IoC) /* I/O Context */
496 * Received bit must be zero.
498 return(SkI2cRcvBit(IoC) != 0);
506 SK_IOC IoC) /* I/O Context */
509 * Received bit must be zero.
519 SK_IOC IoC) /* I/O Context */
522 * Received bit must be zero.
530 * Send one byte to the I2C device and wait for ACK.
532 * Return acknowleged status.
535 SK_IOC IoC, /* I/O Context */
536 int Byte) /* byte to send */
540 for (i = 0; i < 8; i++) {
541 if (Byte & (1<<(7-i))) {
549 return(SkI2cRcvAck(IoC));
554 * Receive one byte and ack it.
559 SK_IOC IoC, /* I/O Context */
560 int Last) /* Last Byte Flag */
565 for (i = 0; i < 8; i++) {
567 Byte |= SkI2cRcvBit(IoC);
582 * Start dialog and send device address
584 * Return 0 if acknowleged, 1 in case of an error
587 SK_IOC IoC, /* I/O Context */
588 int Addr, /* Device Address */
589 int Rw) /* Read / Write Flag */
594 return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
599 /*----------------- I2C CTRL Register Functions ----------*/
602 * waits for a completion of an I2C transfer
604 * returns 0: success, transfer completes
605 * 1: error, transfer does not complete, I2C transfer
606 * killed, wait loop terminated.
609 SK_AC *pAC, /* Adapter Context */
610 SK_IOC IoC, /* I/O Context */
611 int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */
617 StartTime = SkOsGetTime(pAC);
620 CurrentTime = SkOsGetTime(pAC);
622 if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
626 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
627 #endif /* !SK_DIAG */
631 SK_I2C_GET_CTL(IoC, &I2cCtrl);
634 printf("StartTime=%lu, CurrentTime=%lu\n",
635 StartTime, CurrentTime);
639 #endif /* YUKON_DBG */
641 } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
648 * waits for a completion of an I2C transfer
654 SK_AC *pAC, /* Adapter Context */
655 SK_IOC IoC) /* I/O Context */
661 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
663 if (pSen->SenState == SK_SEN_IDLE) {
667 StartTime = SkOsGetTime(pAC);
669 if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
672 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
673 #endif /* !SK_DIAG */
676 SK_IN32(IoC, B0_ISRC, &IrqSrc);
677 } while ((IrqSrc & IS_I2C_READY) == 0);
679 pSen->SenState = SK_SEN_IDLE;
684 * writes a single byte or 4 bytes into the I2C device
690 SK_AC *pAC, /* Adapter Context */
691 SK_IOC IoC, /* I/O Context */
692 SK_U32 I2cData, /* I2C Data to write */
693 int I2cDev, /* I2C Device Address */
694 int I2cReg, /* I2C Device Register Address */
695 int I2cBurst) /* I2C Burst Flag */
697 SK_OUT32(IoC, B2_I2C_DATA, I2cData);
698 SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst);
700 return(SkI2cWait(pAC, IoC, I2C_WRITE));
707 * reads a single byte or 4 bytes from the I2C device
709 * returns the word read
712 SK_AC *pAC, /* Adapter Context */
713 SK_IOC IoC, /* I/O Context */
714 int I2cDev, /* I2C Device Address */
715 int I2cReg, /* I2C Device Register Address */
716 int I2cBurst) /* I2C Burst Flag */
720 SK_OUT32(IoC, B2_I2C_DATA, 0);
721 SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst);
723 if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
724 w_print("%s\n", SKERR_I2C_E002MSG);
727 SK_IN32(IoC, B2_I2C_DATA, &Data);
735 * read a sensor's value
737 * This function reads a sensor's value from the I2C sensor chip. The sensor
738 * is defined by its index into the sensors database in the struct pAC points
741 * 1 if the read is completed
742 * 0 if the read must be continued (I2C Bus still allocated)
745 SK_AC *pAC, /* Adapter Context */
746 SK_IOC IoC, /* I/O Context */
747 SK_SENSOR *pSen) /* Sensor to be read */
749 if (pSen->SenRead != NULL) {
750 return((*pSen->SenRead)(pAC, IoC, pSen));
753 return(0); /* no success */
754 } /* SkI2cReadSensor*/
757 * Do the Init state 0 initialization
759 static int SkI2cInit0(
760 SK_AC *pAC) /* Adapter Context */
764 /* Begin with first sensor */
765 pAC->I2c.CurrSens = 0;
767 /* Begin with timeout control for state machine */
768 pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
770 /* Set sensor number to zero */
771 pAC->I2c.MaxSens = 0;
774 /* Initialize Number of Dummy Reads */
775 pAC->I2c.DummyReads = SK_MAX_SENSORS;
778 for (i = 0; i < SK_MAX_SENSORS; i++) {
779 pAC->I2c.SenTable[i].SenDesc = "unknown";
780 pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
781 pAC->I2c.SenTable[i].SenThreErrHigh = 0;
782 pAC->I2c.SenTable[i].SenThreErrLow = 0;
783 pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
784 pAC->I2c.SenTable[i].SenThreWarnLow = 0;
785 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
786 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
787 pAC->I2c.SenTable[i].SenValue = 0;
788 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
789 pAC->I2c.SenTable[i].SenErrCts = 0;
790 pAC->I2c.SenTable[i].SenBegErrTS = 0;
791 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
792 pAC->I2c.SenTable[i].SenRead = NULL;
793 pAC->I2c.SenTable[i].SenDev = 0;
796 /* Now we are "INIT data"ed */
797 pAC->I2c.InitLevel = SK_INIT_DATA;
803 * Do the init state 1 initialization
805 * initialize the following register of the LM80:
806 * Configuration register:
807 * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
809 * Interrupt Mask Register 1:
810 * - all interrupts are Disabled (0xff)
812 * Interrupt Mask Register 2:
813 * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
815 * Fan Divisor/RST_OUT register:
816 * - Divisors set to 1 (bits 00), all others 0s.
818 * OS# Configuration/Temperature resolution Register:
822 static int SkI2cInit1(
823 SK_AC *pAC, /* Adapter Context */
824 SK_IOC IoC) /* I/O Context */
828 SK_GEPORT *pPrt; /* GIni Port struct pointer */
830 if (pAC->I2c.InitLevel != SK_INIT_DATA) {
831 /* ReInit not needed in I2C module */
835 /* Set the Direction of I2C-Data Pin to IN */
836 SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
837 /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
838 SK_I2C_GET_SW(IoC, &I2cSwCtrl);
840 if ((I2cSwCtrl & I2C_DATA) == 0) {
841 /* this is a 32-Bit board */
842 pAC->GIni.GIYukon32Bit = SK_TRUE;
846 /* Check for 64 Bit Yukon without sensors */
847 if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_CFG, 0) != 0) {
851 (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_1, 0);
853 (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_2, 0);
855 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_FAN_CTRL, 0);
857 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_TEMP_CTRL, 0);
859 (void)SkI2cWrite(pAC, IoC, LM80_CFG_START, LM80_ADDR, LM80_CFG, 0);
862 * MaxSens has to be updated here, because PhyType is not
863 * set when performing Init Level 0
865 pAC->I2c.MaxSens = 5;
867 pPrt = &pAC->GIni.GP[0];
869 if (pAC->GIni.GIGenesis) {
870 if (pPrt->PhyType == SK_PHY_BCOM) {
871 if (pAC->GIni.GIMacsFound == 1) {
872 pAC->I2c.MaxSens += 1;
875 pAC->I2c.MaxSens += 3;
880 pAC->I2c.MaxSens += 3;
883 for (i = 0; i < pAC->I2c.MaxSens; i++) {
886 pAC->I2c.SenTable[i].SenDesc = "Temperature";
887 pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
888 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
889 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
890 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
891 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
892 pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
895 pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
896 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
897 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
898 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
899 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
900 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
901 pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
904 pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
905 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
906 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
907 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
908 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
909 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
910 pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
911 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
914 pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
915 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
916 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
917 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
918 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
919 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
920 pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
923 if (pAC->GIni.GIGenesis) {
924 if (pPrt->PhyType == SK_PHY_BCOM) {
925 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
926 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
927 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
928 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
929 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
932 pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
933 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
934 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
935 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
936 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
940 pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
941 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
942 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
943 if (pAC->GIni.GIVauxAvail) {
944 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
945 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
948 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
949 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
952 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
953 pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
956 if (pAC->GIni.GIGenesis) {
957 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
958 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
959 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
960 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
961 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
964 pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC-Co 1V5";
965 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
966 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
967 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
968 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
970 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
971 pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
974 if (pAC->GIni.GIGenesis) {
975 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
978 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
980 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
981 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
982 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
983 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
984 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
985 pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
988 if (pAC->GIni.GIGenesis) {
989 pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
990 pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
991 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
992 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
993 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
994 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
995 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
998 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
999 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
1000 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
1001 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
1002 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
1003 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
1004 pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
1008 SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
1009 SKERR_I2C_E001, SKERR_I2C_E001MSG);
1013 pAC->I2c.SenTable[i].SenValue = 0;
1014 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
1015 pAC->I2c.SenTable[i].SenErrCts = 0;
1016 pAC->I2c.SenTable[i].SenBegErrTS = 0;
1017 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
1018 pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
1019 pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
1023 pAC->I2c.DummyReads = pAC->I2c.MaxSens;
1024 #endif /* !SK_DIAG */
1027 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
1029 /* Now we are I/O initialized */
1030 pAC->I2c.InitLevel = SK_INIT_IO;
1036 * Init level 2: Start first sensor read.
1038 static int SkI2cInit2(
1039 SK_AC *pAC, /* Adapter Context */
1040 SK_IOC IoC) /* I/O Context */
1045 if (pAC->I2c.InitLevel != SK_INIT_IO) {
1046 /* ReInit not needed in I2C module */
1047 /* Init0 and Init2 not permitted */
1051 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1052 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1055 SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
1058 /* Now we are correctly initialized */
1059 pAC->I2c.InitLevel = SK_INIT_RUN;
1066 * Initialize I2C devices
1068 * Get the first voltage value and discard it.
1069 * Go into temperature read mode. A default pointer is not set.
1071 * The things to be done depend on the init level in the parameter list:
1073 * Initialize only the data structures. Do NOT access hardware.
1075 * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
1077 * Everything is possible. Interrupts may be used from now on.
1084 SK_AC *pAC, /* Adapter Context */
1085 SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */
1086 int Level) /* Init Level */
1091 return(SkI2cInit0(pAC));
1093 return(SkI2cInit1(pAC, IoC));
1095 return(SkI2cInit2(pAC, IoC));
1107 * Interrupt service function for the I2C Interface
1109 * Clears the Interrupt source
1111 * Reads the register and check it for sending a trap.
1113 * Starts the timer if necessary.
1116 SK_AC *pAC, /* Adapter Context */
1117 SK_IOC IoC) /* I/O Context */
1122 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
1125 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
1130 * Check this sensors Value against the threshold and send events.
1132 static void SkI2cCheckSensor(
1133 SK_AC *pAC, /* Adapter Context */
1136 SK_EVPARA ParaLocal;
1137 SK_BOOL TooHigh; /* Is sensor too high? */
1138 SK_BOOL TooLow; /* Is sensor too low? */
1139 SK_U64 CurrTime; /* Current Time */
1140 SK_BOOL DoTrapSend; /* We need to send a trap */
1141 SK_BOOL DoErrLog; /* We need to log the error */
1142 SK_BOOL IsError; /* We need to log the error */
1144 /* Check Dummy Reads first */
1145 if (pAC->I2c.DummyReads > 0) {
1146 pAC->I2c.DummyReads--;
1150 /* Get the current time */
1151 CurrTime = SkOsGetTime(pAC);
1153 /* Set para to the most useful setting: The current sensor. */
1154 ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
1156 /* Check the Value against the thresholds. First: Error Thresholds */
1157 TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
1158 TooLow = (pSen->SenValue < pSen->SenThreErrLow);
1161 if (TooHigh || TooLow) {
1162 /* Error condition is satisfied */
1163 DoTrapSend = SK_TRUE;
1166 /* Now error condition is satisfied */
1169 if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
1170 /* This state is the former one */
1172 /* So check first whether we have to send a trap */
1173 if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
1176 * Do NOT send the Trap. The hold back time
1177 * has to run out first.
1179 DoTrapSend = SK_FALSE;
1182 /* Check now whether we have to log an Error */
1183 if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
1186 * Do NOT log the error. The hold back time
1187 * has to run out first.
1189 DoErrLog = SK_FALSE;
1193 /* We came from a different state -> Set Begin Time Stamp */
1194 pSen->SenBegErrTS = CurrTime;
1195 pSen->SenErrFlag = SK_SEN_ERR_ERR;
1199 /* Set current Time */
1200 pSen->SenLastErrTrapTS = CurrTime;
1203 /* Queue PNMI Event */
1204 SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1205 SK_PNMI_EVT_SEN_ERR_UPP :
1206 SK_PNMI_EVT_SEN_ERR_LOW),
1211 /* Set current Time */
1212 pSen->SenLastErrLogTS = CurrTime;
1214 if (pSen->SenType == SK_SEN_TEMP) {
1215 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011,
1217 } else if (pSen->SenType == SK_SEN_VOLT) {
1218 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012,
1222 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015,
1228 /* Check the Value against the thresholds */
1229 /* 2nd: Warning thresholds */
1230 TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
1231 TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
1233 if (!IsError && (TooHigh || TooLow)) {
1234 /* Error condition is satisfied */
1235 DoTrapSend = SK_TRUE;
1238 if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
1239 /* This state is the former one */
1241 /* So check first whether we have to send a trap */
1242 if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD >
1245 * Do NOT send the Trap. The hold back time
1246 * has to run out first.
1248 DoTrapSend = SK_FALSE;
1251 /* Check now whether we have to log an Error */
1252 if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD >
1255 * Do NOT log the error. The hold back time
1256 * has to run out first.
1258 DoErrLog = SK_FALSE;
1262 /* We came from a different state -> Set Begin Time Stamp */
1263 pSen->SenBegWarnTS = CurrTime;
1264 pSen->SenErrFlag = SK_SEN_ERR_WARN;
1268 /* Set current Time */
1269 pSen->SenLastWarnTrapTS = CurrTime;
1272 /* Queue PNMI Event */
1273 SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1274 SK_PNMI_EVT_SEN_WAR_UPP :
1275 SK_PNMI_EVT_SEN_WAR_LOW),
1280 /* Set current Time */
1281 pSen->SenLastWarnLogTS = CurrTime;
1283 if (pSen->SenType == SK_SEN_TEMP) {
1284 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009,
1286 } else if (pSen->SenType == SK_SEN_VOLT) {
1287 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010,
1291 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014,
1297 /* Check for NO error at all */
1298 if (!IsError && !TooHigh && !TooLow) {
1299 /* Set o.k. Status if no error and no warning condition */
1300 pSen->SenErrFlag = SK_SEN_ERR_OK;
1303 /* End of check against the thresholds */
1305 /* Bug fix AF: 16.Aug.2001: Correct the init base
1308 if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
1310 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1312 if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
1313 /* 5V PCI-IO Voltage */
1314 pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
1315 pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
1318 /* 3.3V PCI-IO Voltage */
1319 pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
1320 pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
1325 /* Dynamic thresholds also for VAUX of LM80 sensor */
1326 if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
1328 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1330 /* 3.3V VAUX Voltage */
1331 if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
1332 pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
1333 pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
1335 /* 0V VAUX Voltage */
1337 pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
1338 pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
1343 * Check initialization state:
1344 * The VIO Thresholds need adaption
1346 if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1347 pSen->SenValue > SK_SEN_WARNLOW2C &&
1348 pSen->SenValue < SK_SEN_WARNHIGH2) {
1349 pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
1350 pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
1351 pSen->SenInit = SK_TRUE;
1354 if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1355 pSen->SenValue > SK_SEN_WARNLOW2 &&
1356 pSen->SenValue < SK_SEN_WARNHIGH2C) {
1357 pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
1358 pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
1359 pSen->SenInit = SK_TRUE;
1363 if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
1364 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
1366 } /* SkI2cCheckSensor*/
1370 * The only Event to be served is the timeout event
1374 SK_AC *pAC, /* Adapter Context */
1375 SK_IOC IoC, /* I/O Context */
1376 SK_U32 Event, /* Module specific Event */
1377 SK_EVPARA Para) /* Event specific Parameter */
1382 SK_EVPARA ParaLocal;
1385 /* New case: no sensors */
1386 if (pAC->I2c.MaxSens == 0) {
1392 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1393 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1396 /* Check sensor against defined thresholds */
1397 SkI2cCheckSensor (pAC, pSen);
1399 /* Increment Current sensor and set appropriate Timeout */
1400 pAC->I2c.CurrSens++;
1401 if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
1402 pAC->I2c.CurrSens = 0;
1403 Time = SK_I2C_TIM_LONG;
1406 Time = SK_I2C_TIM_SHORT;
1410 ParaLocal.Para64 = (SK_U64)0;
1412 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1414 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1415 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1419 ParaLocal.Para64 = (SK_U64)0;
1421 pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
1423 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
1424 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1428 if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
1430 ParaLocal.Para64 = (SK_U64)0;
1431 SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
1433 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1434 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1437 /* Check sensor against defined thresholds */
1438 SkI2cCheckSensor (pAC, pSen);
1440 /* Increment Current sensor and set appropriate Timeout */
1441 pAC->I2c.CurrSens++;
1442 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1443 pAC->I2c.CurrSens = 0;
1444 Time = SK_I2C_TIM_LONG;
1447 Time = SK_I2C_TIM_SHORT;
1451 ParaLocal.Para64 = (SK_U64)0;
1453 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1455 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1456 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1460 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1461 pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
1464 /* Increment Current sensor and set appropriate Timeout */
1465 pAC->I2c.CurrSens++;
1466 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1467 pAC->I2c.CurrSens = 0;
1468 Time = SK_I2C_TIM_LONG;
1471 Time = SK_I2C_TIM_SHORT;
1475 ParaLocal.Para64 = (SK_U64)0;
1477 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1479 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1480 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1483 case SK_I2CEV_CLEAR:
1484 for (i = 0; i < SK_MAX_SENSORS; i++) {
1485 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
1486 pAC->I2c.SenTable[i].SenErrCts = 0;
1487 pAC->I2c.SenTable[i].SenWarnCts = 0;
1488 pAC->I2c.SenTable[i].SenBegErrTS = 0;
1489 pAC->I2c.SenTable[i].SenBegWarnTS = 0;
1490 pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
1491 pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
1492 pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
1493 pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
1497 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
1503 #endif /* !SK_DIAG */
1505 #endif /* CONFIG_SK98 */