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 ******************************************************************************/
236 static const char SysKonnectFileId[] =
237 "$Id: ski2c.c,v 1.57 2003/01/28 09:17:38 rschmidt Exp $";
239 #include "h/skdrv1st.h" /* Driver Specific Definitions */
241 #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
245 I2C protocol implementation.
249 The I2C protocol is used for the temperature sensors and for
250 the serial EEPROM which hold the configuration.
252 This file covers functions that allow to read write and do
253 some bulk requests a specified I2C address.
255 The Genesis has 2 I2C buses. One for the EEPROM which holds
256 the VPD Data and one for temperature and voltage sensor.
257 The following picture shows the I2C buses, I2C devices and
258 their control registers.
260 Note: The VPD functions are in skvpd.c
262 . PCI Config I2C Bus for VPD Data:
270 . +-----------+-----------+
272 . +-----------------+ +-----------------+
273 . | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG |
274 . +-----------------+ +-----------------+
277 . I2C Bus for LM80 sensor:
279 . +-----------------+
280 . | Temperature and |
283 . +-----------------+
289 . +-------------->| OR |<--+
293 . +--------+ +--------+ +----------+
294 . | B2_I2C | | B2_I2C | | B2_I2C |
295 . | _CTRL | | _DATA | | _SW |
296 . +--------+ +--------+ +----------+
298 The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
299 and B2_I2C_DATA registers.
300 For driver software it is recommended to use the I2C control and
301 data register, because I2C bus timing is done by the ASIC and
302 an interrupt may be received when the I2C request is completed.
304 Clock Rate Timing: MIN MAX generated by
305 VPD EEPROM: 50 kHz 100 kHz HW
306 LM80 over I2C Ctrl/Data reg. 50 kHz 100 kHz HW
307 LM80 over B2_I2C_SW register 0 400 kHz SW
309 Note: The clock generated by the hardware is dependend on the
310 PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
319 * I2C Fast Mode timing values used by the LM80.
320 * If new devices are added to the I2C bus the timing values have to be checked.
322 #ifndef I2C_SLOW_TIMING
323 #define T_CLK_LOW 1300L /* clock low time in ns */
324 #define T_CLK_HIGH 600L /* clock high time in ns */
325 #define T_DATA_IN_SETUP 100L /* data in Set-up Time */
326 #define T_START_HOLD 600L /* start condition hold time */
327 #define T_START_SETUP 600L /* start condition Set-up time */
328 #define T_STOP_SETUP 600L /* stop condition Set-up time */
329 #define T_BUS_IDLE 1300L /* time the bus must free after Tx */
330 #define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */
331 #else /* I2C_SLOW_TIMING */
332 /* I2C Standard Mode Timing */
333 #define T_CLK_LOW 4700L /* clock low time in ns */
334 #define T_CLK_HIGH 4000L /* clock high time in ns */
335 #define T_DATA_IN_SETUP 250L /* data in Set-up Time */
336 #define T_START_HOLD 4000L /* start condition hold time */
337 #define T_START_SETUP 4700L /* start condition Set-up time */
338 #define T_STOP_SETUP 4000L /* stop condition Set-up time */
339 #define T_BUS_IDLE 4700L /* time the bus must free after Tx */
340 #endif /* !I2C_SLOW_TIMING */
342 #define NS2BCLK(x) (((x)*125)/10000)
345 * I2C Wire Operations
347 * About I2C_CLK_LOW():
349 * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
350 * clock to low, to prevent the ASIC and the I2C data client from driving the
351 * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
352 * send an 'ACK'). See also Concentrator Bugreport No. 10192.
354 #define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA)
355 #define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA)
356 #define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
357 #define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
358 #define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK)
359 #define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
360 #define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK)
362 #define NS2CLKT(x) ((x*125L)/10000)
364 /*--------------- I2C Interface Register Functions --------------- */
370 SK_IOC IoC, /* I/O Context */
371 SK_U8 Bit) /* Bit to send */
380 SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
382 SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
388 * Signal a start to the I2C Bus.
390 * A start is signaled when data goes to low in a high clock cycle.
392 * Ends with Clock Low.
397 SK_IOC IoC) /* I/O Context */
399 /* Init data and Clock to output lines */
406 SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
411 SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
413 /* Clock low without Data to Input */
416 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
421 SK_IOC IoC) /* I/O Context */
423 /* Init data and Clock to output lines */
428 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
433 SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
436 * Set Data High: Do it by setting the Data Line to Input.
437 * Because of a pull up resistor the Data Line
443 * When I2C activity is stopped
444 * o DATA should be set to input and
445 * o CLOCK should be set to high!
447 SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
452 * Receive just one bit via the I2C bus.
454 * Note: Clock must be set to LOW before calling this function.
456 * Returns The received bit.
459 SK_IOC IoC) /* I/O Context */
464 /* Init data as input line */
467 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
471 SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
473 SK_I2C_GET_SW(IoC, &I2cSwCtrl);
475 Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
478 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
487 * returns 0 If acknowledged
488 * 1 in case of an error
491 SK_IOC IoC) /* I/O Context */
494 * Received bit must be zero.
496 return(SkI2cRcvBit(IoC) != 0);
504 SK_IOC IoC) /* I/O Context */
507 * Received bit must be zero.
517 SK_IOC IoC) /* I/O Context */
520 * Received bit must be zero.
528 * Send one byte to the I2C device and wait for ACK.
530 * Return acknowleged status.
533 SK_IOC IoC, /* I/O Context */
534 int Byte) /* byte to send */
538 for (i = 0; i < 8; i++) {
539 if (Byte & (1<<(7-i))) {
547 return(SkI2cRcvAck(IoC));
552 * Receive one byte and ack it.
557 SK_IOC IoC, /* I/O Context */
558 int Last) /* Last Byte Flag */
563 for (i = 0; i < 8; i++) {
565 Byte |= SkI2cRcvBit(IoC);
580 * Start dialog and send device address
582 * Return 0 if acknowleged, 1 in case of an error
585 SK_IOC IoC, /* I/O Context */
586 int Addr, /* Device Address */
587 int Rw) /* Read / Write Flag */
592 return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
597 /*----------------- I2C CTRL Register Functions ----------*/
600 * waits for a completion of an I2C transfer
602 * returns 0: success, transfer completes
603 * 1: error, transfer does not complete, I2C transfer
604 * killed, wait loop terminated.
607 SK_AC *pAC, /* Adapter Context */
608 SK_IOC IoC, /* I/O Context */
609 int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */
615 StartTime = SkOsGetTime(pAC);
618 CurrentTime = SkOsGetTime(pAC);
620 if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
624 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
625 #endif /* !SK_DIAG */
629 SK_I2C_GET_CTL(IoC, &I2cCtrl);
632 printf("StartTime=%lu, CurrentTime=%lu\n",
633 StartTime, CurrentTime);
637 #endif /* YUKON_DBG */
639 } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
646 * waits for a completion of an I2C transfer
652 SK_AC *pAC, /* Adapter Context */
653 SK_IOC IoC) /* I/O Context */
659 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
661 if (pSen->SenState == SK_SEN_IDLE) {
665 StartTime = SkOsGetTime(pAC);
667 if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
670 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
671 #endif /* !SK_DIAG */
674 SK_IN32(IoC, B0_ISRC, &IrqSrc);
675 } while ((IrqSrc & IS_I2C_READY) == 0);
677 pSen->SenState = SK_SEN_IDLE;
682 * writes a single byte or 4 bytes into the I2C device
688 SK_AC *pAC, /* Adapter Context */
689 SK_IOC IoC, /* I/O Context */
690 SK_U32 I2cData, /* I2C Data to write */
691 int I2cDev, /* I2C Device Address */
692 int I2cReg, /* I2C Device Register Address */
693 int I2cBurst) /* I2C Burst Flag */
695 SK_OUT32(IoC, B2_I2C_DATA, I2cData);
696 SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst);
698 return(SkI2cWait(pAC, IoC, I2C_WRITE));
705 * reads a single byte or 4 bytes from the I2C device
707 * returns the word read
710 SK_AC *pAC, /* Adapter Context */
711 SK_IOC IoC, /* I/O Context */
712 int I2cDev, /* I2C Device Address */
713 int I2cReg, /* I2C Device Register Address */
714 int I2cBurst) /* I2C Burst Flag */
718 SK_OUT32(IoC, B2_I2C_DATA, 0);
719 SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst);
721 if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
722 w_print("%s\n", SKERR_I2C_E002MSG);
725 SK_IN32(IoC, B2_I2C_DATA, &Data);
733 * read a sensor's value
735 * This function reads a sensor's value from the I2C sensor chip. The sensor
736 * is defined by its index into the sensors database in the struct pAC points
739 * 1 if the read is completed
740 * 0 if the read must be continued (I2C Bus still allocated)
743 SK_AC *pAC, /* Adapter Context */
744 SK_IOC IoC, /* I/O Context */
745 SK_SENSOR *pSen) /* Sensor to be read */
747 if (pSen->SenRead != NULL) {
748 return((*pSen->SenRead)(pAC, IoC, pSen));
751 return(0); /* no success */
752 } /* SkI2cReadSensor*/
755 * Do the Init state 0 initialization
757 static int SkI2cInit0(
758 SK_AC *pAC) /* Adapter Context */
762 /* Begin with first sensor */
763 pAC->I2c.CurrSens = 0;
765 /* Begin with timeout control for state machine */
766 pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
768 /* Set sensor number to zero */
769 pAC->I2c.MaxSens = 0;
772 /* Initialize Number of Dummy Reads */
773 pAC->I2c.DummyReads = SK_MAX_SENSORS;
776 for (i = 0; i < SK_MAX_SENSORS; i++) {
777 pAC->I2c.SenTable[i].SenDesc = "unknown";
778 pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
779 pAC->I2c.SenTable[i].SenThreErrHigh = 0;
780 pAC->I2c.SenTable[i].SenThreErrLow = 0;
781 pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
782 pAC->I2c.SenTable[i].SenThreWarnLow = 0;
783 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
784 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
785 pAC->I2c.SenTable[i].SenValue = 0;
786 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
787 pAC->I2c.SenTable[i].SenErrCts = 0;
788 pAC->I2c.SenTable[i].SenBegErrTS = 0;
789 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
790 pAC->I2c.SenTable[i].SenRead = NULL;
791 pAC->I2c.SenTable[i].SenDev = 0;
794 /* Now we are "INIT data"ed */
795 pAC->I2c.InitLevel = SK_INIT_DATA;
801 * Do the init state 1 initialization
803 * initialize the following register of the LM80:
804 * Configuration register:
805 * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
807 * Interrupt Mask Register 1:
808 * - all interrupts are Disabled (0xff)
810 * Interrupt Mask Register 2:
811 * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
813 * Fan Divisor/RST_OUT register:
814 * - Divisors set to 1 (bits 00), all others 0s.
816 * OS# Configuration/Temperature resolution Register:
820 static int SkI2cInit1(
821 SK_AC *pAC, /* Adapter Context */
822 SK_IOC IoC) /* I/O Context */
826 SK_GEPORT *pPrt; /* GIni Port struct pointer */
828 if (pAC->I2c.InitLevel != SK_INIT_DATA) {
829 /* ReInit not needed in I2C module */
833 /* Set the Direction of I2C-Data Pin to IN */
834 SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
835 /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
836 SK_I2C_GET_SW(IoC, &I2cSwCtrl);
838 if ((I2cSwCtrl & I2C_DATA) == 0) {
839 /* this is a 32-Bit board */
840 pAC->GIni.GIYukon32Bit = SK_TRUE;
844 /* Check for 64 Bit Yukon without sensors */
845 if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_CFG, 0) != 0) {
849 (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_1, 0);
851 (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_2, 0);
853 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_FAN_CTRL, 0);
855 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_TEMP_CTRL, 0);
857 (void)SkI2cWrite(pAC, IoC, LM80_CFG_START, LM80_ADDR, LM80_CFG, 0);
860 * MaxSens has to be updated here, because PhyType is not
861 * set when performing Init Level 0
863 pAC->I2c.MaxSens = 5;
865 pPrt = &pAC->GIni.GP[0];
867 if (pAC->GIni.GIGenesis) {
868 if (pPrt->PhyType == SK_PHY_BCOM) {
869 if (pAC->GIni.GIMacsFound == 1) {
870 pAC->I2c.MaxSens += 1;
873 pAC->I2c.MaxSens += 3;
878 pAC->I2c.MaxSens += 3;
881 for (i = 0; i < pAC->I2c.MaxSens; i++) {
884 pAC->I2c.SenTable[i].SenDesc = "Temperature";
885 pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
886 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
887 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
888 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
889 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
890 pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
893 pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
894 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
895 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
896 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
897 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
898 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
899 pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
902 pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
903 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
904 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
905 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
906 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
907 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
908 pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
909 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
912 pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
913 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
914 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
915 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
916 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
917 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
918 pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
921 if (pAC->GIni.GIGenesis) {
922 if (pPrt->PhyType == SK_PHY_BCOM) {
923 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
924 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
925 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
926 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
927 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
930 pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
931 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
932 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
933 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
934 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
938 pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
939 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
940 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
941 if (pAC->GIni.GIVauxAvail) {
942 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
943 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
946 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
947 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
950 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
951 pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
954 if (pAC->GIni.GIGenesis) {
955 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
956 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
957 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
958 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
959 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
962 pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC-Co 1V5";
963 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
964 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
965 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
966 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
968 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
969 pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
972 if (pAC->GIni.GIGenesis) {
973 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
976 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
978 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
979 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
980 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
981 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
982 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
983 pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
986 if (pAC->GIni.GIGenesis) {
987 pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
988 pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
989 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
990 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
991 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
992 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
993 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
996 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
997 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
998 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
999 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
1000 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
1001 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
1002 pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
1006 SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
1007 SKERR_I2C_E001, SKERR_I2C_E001MSG);
1011 pAC->I2c.SenTable[i].SenValue = 0;
1012 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
1013 pAC->I2c.SenTable[i].SenErrCts = 0;
1014 pAC->I2c.SenTable[i].SenBegErrTS = 0;
1015 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
1016 pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
1017 pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
1021 pAC->I2c.DummyReads = pAC->I2c.MaxSens;
1022 #endif /* !SK_DIAG */
1025 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
1027 /* Now we are I/O initialized */
1028 pAC->I2c.InitLevel = SK_INIT_IO;
1034 * Init level 2: Start first sensor read.
1036 static int SkI2cInit2(
1037 SK_AC *pAC, /* Adapter Context */
1038 SK_IOC IoC) /* I/O Context */
1043 if (pAC->I2c.InitLevel != SK_INIT_IO) {
1044 /* ReInit not needed in I2C module */
1045 /* Init0 and Init2 not permitted */
1049 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1050 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1053 SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
1056 /* Now we are correctly initialized */
1057 pAC->I2c.InitLevel = SK_INIT_RUN;
1064 * Initialize I2C devices
1066 * Get the first voltage value and discard it.
1067 * Go into temperature read mode. A default pointer is not set.
1069 * The things to be done depend on the init level in the parameter list:
1071 * Initialize only the data structures. Do NOT access hardware.
1073 * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
1075 * Everything is possible. Interrupts may be used from now on.
1082 SK_AC *pAC, /* Adapter Context */
1083 SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */
1084 int Level) /* Init Level */
1089 return(SkI2cInit0(pAC));
1091 return(SkI2cInit1(pAC, IoC));
1093 return(SkI2cInit2(pAC, IoC));
1105 * Interrupt service function for the I2C Interface
1107 * Clears the Interrupt source
1109 * Reads the register and check it for sending a trap.
1111 * Starts the timer if necessary.
1114 SK_AC *pAC, /* Adapter Context */
1115 SK_IOC IoC) /* I/O Context */
1120 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
1123 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
1128 * Check this sensors Value against the threshold and send events.
1130 static void SkI2cCheckSensor(
1131 SK_AC *pAC, /* Adapter Context */
1134 SK_EVPARA ParaLocal;
1135 SK_BOOL TooHigh; /* Is sensor too high? */
1136 SK_BOOL TooLow; /* Is sensor too low? */
1137 SK_U64 CurrTime; /* Current Time */
1138 SK_BOOL DoTrapSend; /* We need to send a trap */
1139 SK_BOOL DoErrLog; /* We need to log the error */
1140 SK_BOOL IsError; /* We need to log the error */
1142 /* Check Dummy Reads first */
1143 if (pAC->I2c.DummyReads > 0) {
1144 pAC->I2c.DummyReads--;
1148 /* Get the current time */
1149 CurrTime = SkOsGetTime(pAC);
1151 /* Set para to the most useful setting: The current sensor. */
1152 ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
1154 /* Check the Value against the thresholds. First: Error Thresholds */
1155 TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
1156 TooLow = (pSen->SenValue < pSen->SenThreErrLow);
1159 if (TooHigh || TooLow) {
1160 /* Error condition is satisfied */
1161 DoTrapSend = SK_TRUE;
1164 /* Now error condition is satisfied */
1167 if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
1168 /* This state is the former one */
1170 /* So check first whether we have to send a trap */
1171 if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
1174 * Do NOT send the Trap. The hold back time
1175 * has to run out first.
1177 DoTrapSend = SK_FALSE;
1180 /* Check now whether we have to log an Error */
1181 if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
1184 * Do NOT log the error. The hold back time
1185 * has to run out first.
1187 DoErrLog = SK_FALSE;
1191 /* We came from a different state -> Set Begin Time Stamp */
1192 pSen->SenBegErrTS = CurrTime;
1193 pSen->SenErrFlag = SK_SEN_ERR_ERR;
1197 /* Set current Time */
1198 pSen->SenLastErrTrapTS = CurrTime;
1201 /* Queue PNMI Event */
1202 SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1203 SK_PNMI_EVT_SEN_ERR_UPP :
1204 SK_PNMI_EVT_SEN_ERR_LOW),
1209 /* Set current Time */
1210 pSen->SenLastErrLogTS = CurrTime;
1212 if (pSen->SenType == SK_SEN_TEMP) {
1213 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011,
1215 } else if (pSen->SenType == SK_SEN_VOLT) {
1216 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012,
1220 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015,
1226 /* Check the Value against the thresholds */
1227 /* 2nd: Warning thresholds */
1228 TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
1229 TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
1231 if (!IsError && (TooHigh || TooLow)) {
1232 /* Error condition is satisfied */
1233 DoTrapSend = SK_TRUE;
1236 if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
1237 /* This state is the former one */
1239 /* So check first whether we have to send a trap */
1240 if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD >
1243 * Do NOT send the Trap. The hold back time
1244 * has to run out first.
1246 DoTrapSend = SK_FALSE;
1249 /* Check now whether we have to log an Error */
1250 if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD >
1253 * Do NOT log the error. The hold back time
1254 * has to run out first.
1256 DoErrLog = SK_FALSE;
1260 /* We came from a different state -> Set Begin Time Stamp */
1261 pSen->SenBegWarnTS = CurrTime;
1262 pSen->SenErrFlag = SK_SEN_ERR_WARN;
1266 /* Set current Time */
1267 pSen->SenLastWarnTrapTS = CurrTime;
1270 /* Queue PNMI Event */
1271 SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1272 SK_PNMI_EVT_SEN_WAR_UPP :
1273 SK_PNMI_EVT_SEN_WAR_LOW),
1278 /* Set current Time */
1279 pSen->SenLastWarnLogTS = CurrTime;
1281 if (pSen->SenType == SK_SEN_TEMP) {
1282 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009,
1284 } else if (pSen->SenType == SK_SEN_VOLT) {
1285 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010,
1289 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014,
1295 /* Check for NO error at all */
1296 if (!IsError && !TooHigh && !TooLow) {
1297 /* Set o.k. Status if no error and no warning condition */
1298 pSen->SenErrFlag = SK_SEN_ERR_OK;
1301 /* End of check against the thresholds */
1303 /* Bug fix AF: 16.Aug.2001: Correct the init base
1306 if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
1308 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1310 if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
1311 /* 5V PCI-IO Voltage */
1312 pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
1313 pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
1316 /* 3.3V PCI-IO Voltage */
1317 pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
1318 pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
1323 /* Dynamic thresholds also for VAUX of LM80 sensor */
1324 if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
1326 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1328 /* 3.3V VAUX Voltage */
1329 if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
1330 pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
1331 pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
1333 /* 0V VAUX Voltage */
1335 pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
1336 pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
1341 * Check initialization state:
1342 * The VIO Thresholds need adaption
1344 if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1345 pSen->SenValue > SK_SEN_WARNLOW2C &&
1346 pSen->SenValue < SK_SEN_WARNHIGH2) {
1347 pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
1348 pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
1349 pSen->SenInit = SK_TRUE;
1352 if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1353 pSen->SenValue > SK_SEN_WARNLOW2 &&
1354 pSen->SenValue < SK_SEN_WARNHIGH2C) {
1355 pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
1356 pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
1357 pSen->SenInit = SK_TRUE;
1361 if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
1362 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
1364 } /* SkI2cCheckSensor*/
1368 * The only Event to be served is the timeout event
1372 SK_AC *pAC, /* Adapter Context */
1373 SK_IOC IoC, /* I/O Context */
1374 SK_U32 Event, /* Module specific Event */
1375 SK_EVPARA Para) /* Event specific Parameter */
1380 SK_EVPARA ParaLocal;
1383 /* New case: no sensors */
1384 if (pAC->I2c.MaxSens == 0) {
1390 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1391 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1394 /* Check sensor against defined thresholds */
1395 SkI2cCheckSensor (pAC, pSen);
1397 /* Increment Current sensor and set appropriate Timeout */
1398 pAC->I2c.CurrSens++;
1399 if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
1400 pAC->I2c.CurrSens = 0;
1401 Time = SK_I2C_TIM_LONG;
1404 Time = SK_I2C_TIM_SHORT;
1408 ParaLocal.Para64 = (SK_U64)0;
1410 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1412 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1413 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1417 ParaLocal.Para64 = (SK_U64)0;
1419 pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
1421 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
1422 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1426 if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
1428 ParaLocal.Para64 = (SK_U64)0;
1429 SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
1431 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1432 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1435 /* Check sensor against defined thresholds */
1436 SkI2cCheckSensor (pAC, pSen);
1438 /* Increment Current sensor and set appropriate Timeout */
1439 pAC->I2c.CurrSens++;
1440 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1441 pAC->I2c.CurrSens = 0;
1442 Time = SK_I2C_TIM_LONG;
1445 Time = SK_I2C_TIM_SHORT;
1449 ParaLocal.Para64 = (SK_U64)0;
1451 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1453 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1454 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1458 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1459 pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
1462 /* Increment Current sensor and set appropriate Timeout */
1463 pAC->I2c.CurrSens++;
1464 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1465 pAC->I2c.CurrSens = 0;
1466 Time = SK_I2C_TIM_LONG;
1469 Time = SK_I2C_TIM_SHORT;
1473 ParaLocal.Para64 = (SK_U64)0;
1475 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1477 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1478 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1481 case SK_I2CEV_CLEAR:
1482 for (i = 0; i < SK_MAX_SENSORS; i++) {
1483 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
1484 pAC->I2c.SenTable[i].SenErrCts = 0;
1485 pAC->I2c.SenTable[i].SenWarnCts = 0;
1486 pAC->I2c.SenTable[i].SenBegErrTS = 0;
1487 pAC->I2c.SenTable[i].SenBegWarnTS = 0;
1488 pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
1489 pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
1490 pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
1491 pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
1495 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
1501 #endif /* !SK_DIAG */