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 ******************************************************************************/
234 static const char SysKonnectFileId[] =
235 "$Id: ski2c.c,v 1.57 2003/01/28 09:17:38 rschmidt Exp $";
237 #include "h/skdrv1st.h" /* Driver Specific Definitions */
239 #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
243 I2C protocol implementation.
247 The I2C protocol is used for the temperature sensors and for
248 the serial EEPROM which hold the configuration.
250 This file covers functions that allow to read write and do
251 some bulk requests a specified I2C address.
253 The Genesis has 2 I2C buses. One for the EEPROM which holds
254 the VPD Data and one for temperature and voltage sensor.
255 The following picture shows the I2C buses, I2C devices and
256 their control registers.
258 Note: The VPD functions are in skvpd.c
260 . PCI Config I2C Bus for VPD Data:
268 . +-----------+-----------+
270 . +-----------------+ +-----------------+
271 . | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG |
272 . +-----------------+ +-----------------+
275 . I2C Bus for LM80 sensor:
277 . +-----------------+
278 . | Temperature and |
281 . +-----------------+
287 . +-------------->| OR |<--+
291 . +--------+ +--------+ +----------+
292 . | B2_I2C | | B2_I2C | | B2_I2C |
293 . | _CTRL | | _DATA | | _SW |
294 . +--------+ +--------+ +----------+
296 The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
297 and B2_I2C_DATA registers.
298 For driver software it is recommended to use the I2C control and
299 data register, because I2C bus timing is done by the ASIC and
300 an interrupt may be received when the I2C request is completed.
302 Clock Rate Timing: MIN MAX generated by
303 VPD EEPROM: 50 kHz 100 kHz HW
304 LM80 over I2C Ctrl/Data reg. 50 kHz 100 kHz HW
305 LM80 over B2_I2C_SW register 0 400 kHz SW
307 Note: The clock generated by the hardware is dependend on the
308 PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
317 * I2C Fast Mode timing values used by the LM80.
318 * If new devices are added to the I2C bus the timing values have to be checked.
320 #ifndef I2C_SLOW_TIMING
321 #define T_CLK_LOW 1300L /* clock low time in ns */
322 #define T_CLK_HIGH 600L /* clock high time in ns */
323 #define T_DATA_IN_SETUP 100L /* data in Set-up Time */
324 #define T_START_HOLD 600L /* start condition hold time */
325 #define T_START_SETUP 600L /* start condition Set-up time */
326 #define T_STOP_SETUP 600L /* stop condition Set-up time */
327 #define T_BUS_IDLE 1300L /* time the bus must free after Tx */
328 #define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */
329 #else /* I2C_SLOW_TIMING */
330 /* I2C Standard Mode Timing */
331 #define T_CLK_LOW 4700L /* clock low time in ns */
332 #define T_CLK_HIGH 4000L /* clock high time in ns */
333 #define T_DATA_IN_SETUP 250L /* data in Set-up Time */
334 #define T_START_HOLD 4000L /* start condition hold time */
335 #define T_START_SETUP 4700L /* start condition Set-up time */
336 #define T_STOP_SETUP 4000L /* stop condition Set-up time */
337 #define T_BUS_IDLE 4700L /* time the bus must free after Tx */
338 #endif /* !I2C_SLOW_TIMING */
340 #define NS2BCLK(x) (((x)*125)/10000)
343 * I2C Wire Operations
345 * About I2C_CLK_LOW():
347 * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
348 * clock to low, to prevent the ASIC and the I2C data client from driving the
349 * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
350 * send an 'ACK'). See also Concentrator Bugreport No. 10192.
352 #define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA)
353 #define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA)
354 #define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
355 #define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
356 #define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK)
357 #define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
358 #define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK)
360 #define NS2CLKT(x) ((x*125L)/10000)
362 /*--------------- I2C Interface Register Functions --------------- */
368 SK_IOC IoC, /* I/O Context */
369 SK_U8 Bit) /* Bit to send */
378 SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
380 SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
386 * Signal a start to the I2C Bus.
388 * A start is signaled when data goes to low in a high clock cycle.
390 * Ends with Clock Low.
395 SK_IOC IoC) /* I/O Context */
397 /* Init data and Clock to output lines */
404 SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
409 SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
411 /* Clock low without Data to Input */
414 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
419 SK_IOC IoC) /* I/O Context */
421 /* Init data and Clock to output lines */
426 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
431 SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
434 * Set Data High: Do it by setting the Data Line to Input.
435 * Because of a pull up resistor the Data Line
441 * When I2C activity is stopped
442 * o DATA should be set to input and
443 * o CLOCK should be set to high!
445 SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
450 * Receive just one bit via the I2C bus.
452 * Note: Clock must be set to LOW before calling this function.
454 * Returns The received bit.
457 SK_IOC IoC) /* I/O Context */
462 /* Init data as input line */
465 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
469 SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
471 SK_I2C_GET_SW(IoC, &I2cSwCtrl);
473 Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
476 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
485 * returns 0 If acknowledged
486 * 1 in case of an error
489 SK_IOC IoC) /* I/O Context */
492 * Received bit must be zero.
494 return(SkI2cRcvBit(IoC) != 0);
502 SK_IOC IoC) /* I/O Context */
505 * Received bit must be zero.
515 SK_IOC IoC) /* I/O Context */
518 * Received bit must be zero.
526 * Send one byte to the I2C device and wait for ACK.
528 * Return acknowleged status.
531 SK_IOC IoC, /* I/O Context */
532 int Byte) /* byte to send */
536 for (i = 0; i < 8; i++) {
537 if (Byte & (1<<(7-i))) {
545 return(SkI2cRcvAck(IoC));
550 * Receive one byte and ack it.
555 SK_IOC IoC, /* I/O Context */
556 int Last) /* Last Byte Flag */
561 for (i = 0; i < 8; i++) {
563 Byte |= SkI2cRcvBit(IoC);
578 * Start dialog and send device address
580 * Return 0 if acknowleged, 1 in case of an error
583 SK_IOC IoC, /* I/O Context */
584 int Addr, /* Device Address */
585 int Rw) /* Read / Write Flag */
590 return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
595 /*----------------- I2C CTRL Register Functions ----------*/
598 * waits for a completion of an I2C transfer
600 * returns 0: success, transfer completes
601 * 1: error, transfer does not complete, I2C transfer
602 * killed, wait loop terminated.
605 SK_AC *pAC, /* Adapter Context */
606 SK_IOC IoC, /* I/O Context */
607 int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */
613 StartTime = SkOsGetTime(pAC);
616 CurrentTime = SkOsGetTime(pAC);
618 if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
622 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
623 #endif /* !SK_DIAG */
627 SK_I2C_GET_CTL(IoC, &I2cCtrl);
630 printf("StartTime=%lu, CurrentTime=%lu\n",
631 StartTime, CurrentTime);
635 #endif /* YUKON_DBG */
637 } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
644 * waits for a completion of an I2C transfer
650 SK_AC *pAC, /* Adapter Context */
651 SK_IOC IoC) /* I/O Context */
657 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
659 if (pSen->SenState == SK_SEN_IDLE) {
663 StartTime = SkOsGetTime(pAC);
665 if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
668 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
669 #endif /* !SK_DIAG */
672 SK_IN32(IoC, B0_ISRC, &IrqSrc);
673 } while ((IrqSrc & IS_I2C_READY) == 0);
675 pSen->SenState = SK_SEN_IDLE;
680 * writes a single byte or 4 bytes into the I2C device
686 SK_AC *pAC, /* Adapter Context */
687 SK_IOC IoC, /* I/O Context */
688 SK_U32 I2cData, /* I2C Data to write */
689 int I2cDev, /* I2C Device Address */
690 int I2cReg, /* I2C Device Register Address */
691 int I2cBurst) /* I2C Burst Flag */
693 SK_OUT32(IoC, B2_I2C_DATA, I2cData);
694 SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst);
696 return(SkI2cWait(pAC, IoC, I2C_WRITE));
703 * reads a single byte or 4 bytes from the I2C device
705 * returns the word read
708 SK_AC *pAC, /* Adapter Context */
709 SK_IOC IoC, /* I/O Context */
710 int I2cDev, /* I2C Device Address */
711 int I2cReg, /* I2C Device Register Address */
712 int I2cBurst) /* I2C Burst Flag */
716 SK_OUT32(IoC, B2_I2C_DATA, 0);
717 SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst);
719 if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
720 w_print("%s\n", SKERR_I2C_E002MSG);
723 SK_IN32(IoC, B2_I2C_DATA, &Data);
731 * read a sensor's value
733 * This function reads a sensor's value from the I2C sensor chip. The sensor
734 * is defined by its index into the sensors database in the struct pAC points
737 * 1 if the read is completed
738 * 0 if the read must be continued (I2C Bus still allocated)
741 SK_AC *pAC, /* Adapter Context */
742 SK_IOC IoC, /* I/O Context */
743 SK_SENSOR *pSen) /* Sensor to be read */
745 if (pSen->SenRead != NULL) {
746 return((*pSen->SenRead)(pAC, IoC, pSen));
749 return(0); /* no success */
750 } /* SkI2cReadSensor*/
753 * Do the Init state 0 initialization
755 static int SkI2cInit0(
756 SK_AC *pAC) /* Adapter Context */
760 /* Begin with first sensor */
761 pAC->I2c.CurrSens = 0;
763 /* Begin with timeout control for state machine */
764 pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
766 /* Set sensor number to zero */
767 pAC->I2c.MaxSens = 0;
770 /* Initialize Number of Dummy Reads */
771 pAC->I2c.DummyReads = SK_MAX_SENSORS;
774 for (i = 0; i < SK_MAX_SENSORS; i++) {
775 pAC->I2c.SenTable[i].SenDesc = "unknown";
776 pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
777 pAC->I2c.SenTable[i].SenThreErrHigh = 0;
778 pAC->I2c.SenTable[i].SenThreErrLow = 0;
779 pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
780 pAC->I2c.SenTable[i].SenThreWarnLow = 0;
781 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
782 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
783 pAC->I2c.SenTable[i].SenValue = 0;
784 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
785 pAC->I2c.SenTable[i].SenErrCts = 0;
786 pAC->I2c.SenTable[i].SenBegErrTS = 0;
787 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
788 pAC->I2c.SenTable[i].SenRead = NULL;
789 pAC->I2c.SenTable[i].SenDev = 0;
792 /* Now we are "INIT data"ed */
793 pAC->I2c.InitLevel = SK_INIT_DATA;
799 * Do the init state 1 initialization
801 * initialize the following register of the LM80:
802 * Configuration register:
803 * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
805 * Interrupt Mask Register 1:
806 * - all interrupts are Disabled (0xff)
808 * Interrupt Mask Register 2:
809 * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
811 * Fan Divisor/RST_OUT register:
812 * - Divisors set to 1 (bits 00), all others 0s.
814 * OS# Configuration/Temperature resolution Register:
818 static int SkI2cInit1(
819 SK_AC *pAC, /* Adapter Context */
820 SK_IOC IoC) /* I/O Context */
824 SK_GEPORT *pPrt; /* GIni Port struct pointer */
826 if (pAC->I2c.InitLevel != SK_INIT_DATA) {
827 /* ReInit not needed in I2C module */
831 /* Set the Direction of I2C-Data Pin to IN */
832 SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
833 /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
834 SK_I2C_GET_SW(IoC, &I2cSwCtrl);
836 if ((I2cSwCtrl & I2C_DATA) == 0) {
837 /* this is a 32-Bit board */
838 pAC->GIni.GIYukon32Bit = SK_TRUE;
842 /* Check for 64 Bit Yukon without sensors */
843 if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_CFG, 0) != 0) {
847 (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_1, 0);
849 (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_2, 0);
851 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_FAN_CTRL, 0);
853 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_TEMP_CTRL, 0);
855 (void)SkI2cWrite(pAC, IoC, LM80_CFG_START, LM80_ADDR, LM80_CFG, 0);
858 * MaxSens has to be updated here, because PhyType is not
859 * set when performing Init Level 0
861 pAC->I2c.MaxSens = 5;
863 pPrt = &pAC->GIni.GP[0];
865 if (pAC->GIni.GIGenesis) {
866 if (pPrt->PhyType == SK_PHY_BCOM) {
867 if (pAC->GIni.GIMacsFound == 1) {
868 pAC->I2c.MaxSens += 1;
871 pAC->I2c.MaxSens += 3;
876 pAC->I2c.MaxSens += 3;
879 for (i = 0; i < pAC->I2c.MaxSens; i++) {
882 pAC->I2c.SenTable[i].SenDesc = "Temperature";
883 pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
884 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
885 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
886 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
887 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
888 pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
891 pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
892 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
893 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
894 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
895 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
896 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
897 pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
900 pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
901 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
902 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
903 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
904 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
905 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
906 pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
907 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
910 pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
911 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
912 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
913 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
914 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
915 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
916 pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
919 if (pAC->GIni.GIGenesis) {
920 if (pPrt->PhyType == SK_PHY_BCOM) {
921 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
922 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
923 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
924 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
925 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
928 pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
929 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
930 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
931 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
932 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
936 pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
937 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
938 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
939 if (pAC->GIni.GIVauxAvail) {
940 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
941 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
944 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
945 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
948 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
949 pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
952 if (pAC->GIni.GIGenesis) {
953 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
954 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
955 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
956 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
957 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
960 pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC-Co 1V5";
961 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
962 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
963 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
964 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
966 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
967 pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
970 if (pAC->GIni.GIGenesis) {
971 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
974 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
976 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
977 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
978 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
979 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
980 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
981 pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
984 if (pAC->GIni.GIGenesis) {
985 pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
986 pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
987 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
988 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
989 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
990 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
991 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
994 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
995 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
996 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
997 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
998 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
999 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
1000 pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
1004 SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
1005 SKERR_I2C_E001, SKERR_I2C_E001MSG);
1009 pAC->I2c.SenTable[i].SenValue = 0;
1010 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
1011 pAC->I2c.SenTable[i].SenErrCts = 0;
1012 pAC->I2c.SenTable[i].SenBegErrTS = 0;
1013 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
1014 pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
1015 pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
1019 pAC->I2c.DummyReads = pAC->I2c.MaxSens;
1020 #endif /* !SK_DIAG */
1023 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
1025 /* Now we are I/O initialized */
1026 pAC->I2c.InitLevel = SK_INIT_IO;
1032 * Init level 2: Start first sensor read.
1034 static int SkI2cInit2(
1035 SK_AC *pAC, /* Adapter Context */
1036 SK_IOC IoC) /* I/O Context */
1041 if (pAC->I2c.InitLevel != SK_INIT_IO) {
1042 /* ReInit not needed in I2C module */
1043 /* Init0 and Init2 not permitted */
1047 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1048 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1051 SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
1054 /* Now we are correctly initialized */
1055 pAC->I2c.InitLevel = SK_INIT_RUN;
1062 * Initialize I2C devices
1064 * Get the first voltage value and discard it.
1065 * Go into temperature read mode. A default pointer is not set.
1067 * The things to be done depend on the init level in the parameter list:
1069 * Initialize only the data structures. Do NOT access hardware.
1071 * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
1073 * Everything is possible. Interrupts may be used from now on.
1080 SK_AC *pAC, /* Adapter Context */
1081 SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */
1082 int Level) /* Init Level */
1087 return(SkI2cInit0(pAC));
1089 return(SkI2cInit1(pAC, IoC));
1091 return(SkI2cInit2(pAC, IoC));
1103 * Interrupt service function for the I2C Interface
1105 * Clears the Interrupt source
1107 * Reads the register and check it for sending a trap.
1109 * Starts the timer if necessary.
1112 SK_AC *pAC, /* Adapter Context */
1113 SK_IOC IoC) /* I/O Context */
1118 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
1121 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
1126 * Check this sensors Value against the threshold and send events.
1128 static void SkI2cCheckSensor(
1129 SK_AC *pAC, /* Adapter Context */
1132 SK_EVPARA ParaLocal;
1133 SK_BOOL TooHigh; /* Is sensor too high? */
1134 SK_BOOL TooLow; /* Is sensor too low? */
1135 SK_U64 CurrTime; /* Current Time */
1136 SK_BOOL DoTrapSend; /* We need to send a trap */
1137 SK_BOOL DoErrLog; /* We need to log the error */
1138 SK_BOOL IsError; /* We need to log the error */
1140 /* Check Dummy Reads first */
1141 if (pAC->I2c.DummyReads > 0) {
1142 pAC->I2c.DummyReads--;
1146 /* Get the current time */
1147 CurrTime = SkOsGetTime(pAC);
1149 /* Set para to the most useful setting: The current sensor. */
1150 ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
1152 /* Check the Value against the thresholds. First: Error Thresholds */
1153 TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
1154 TooLow = (pSen->SenValue < pSen->SenThreErrLow);
1157 if (TooHigh || TooLow) {
1158 /* Error condition is satisfied */
1159 DoTrapSend = SK_TRUE;
1162 /* Now error condition is satisfied */
1165 if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
1166 /* This state is the former one */
1168 /* So check first whether we have to send a trap */
1169 if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
1172 * Do NOT send the Trap. The hold back time
1173 * has to run out first.
1175 DoTrapSend = SK_FALSE;
1178 /* Check now whether we have to log an Error */
1179 if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
1182 * Do NOT log the error. The hold back time
1183 * has to run out first.
1185 DoErrLog = SK_FALSE;
1189 /* We came from a different state -> Set Begin Time Stamp */
1190 pSen->SenBegErrTS = CurrTime;
1191 pSen->SenErrFlag = SK_SEN_ERR_ERR;
1195 /* Set current Time */
1196 pSen->SenLastErrTrapTS = CurrTime;
1199 /* Queue PNMI Event */
1200 SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1201 SK_PNMI_EVT_SEN_ERR_UPP :
1202 SK_PNMI_EVT_SEN_ERR_LOW),
1207 /* Set current Time */
1208 pSen->SenLastErrLogTS = CurrTime;
1210 if (pSen->SenType == SK_SEN_TEMP) {
1211 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011,
1213 } else if (pSen->SenType == SK_SEN_VOLT) {
1214 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012,
1218 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015,
1224 /* Check the Value against the thresholds */
1225 /* 2nd: Warning thresholds */
1226 TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
1227 TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
1229 if (!IsError && (TooHigh || TooLow)) {
1230 /* Error condition is satisfied */
1231 DoTrapSend = SK_TRUE;
1234 if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
1235 /* This state is the former one */
1237 /* So check first whether we have to send a trap */
1238 if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD >
1241 * Do NOT send the Trap. The hold back time
1242 * has to run out first.
1244 DoTrapSend = SK_FALSE;
1247 /* Check now whether we have to log an Error */
1248 if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD >
1251 * Do NOT log the error. The hold back time
1252 * has to run out first.
1254 DoErrLog = SK_FALSE;
1258 /* We came from a different state -> Set Begin Time Stamp */
1259 pSen->SenBegWarnTS = CurrTime;
1260 pSen->SenErrFlag = SK_SEN_ERR_WARN;
1264 /* Set current Time */
1265 pSen->SenLastWarnTrapTS = CurrTime;
1268 /* Queue PNMI Event */
1269 SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1270 SK_PNMI_EVT_SEN_WAR_UPP :
1271 SK_PNMI_EVT_SEN_WAR_LOW),
1276 /* Set current Time */
1277 pSen->SenLastWarnLogTS = CurrTime;
1279 if (pSen->SenType == SK_SEN_TEMP) {
1280 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009,
1282 } else if (pSen->SenType == SK_SEN_VOLT) {
1283 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010,
1287 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014,
1293 /* Check for NO error at all */
1294 if (!IsError && !TooHigh && !TooLow) {
1295 /* Set o.k. Status if no error and no warning condition */
1296 pSen->SenErrFlag = SK_SEN_ERR_OK;
1299 /* End of check against the thresholds */
1301 /* Bug fix AF: 16.Aug.2001: Correct the init base
1304 if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
1306 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1308 if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
1309 /* 5V PCI-IO Voltage */
1310 pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
1311 pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
1314 /* 3.3V PCI-IO Voltage */
1315 pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
1316 pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
1321 /* Dynamic thresholds also for VAUX of LM80 sensor */
1322 if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
1324 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1326 /* 3.3V VAUX Voltage */
1327 if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
1328 pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
1329 pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
1331 /* 0V VAUX Voltage */
1333 pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
1334 pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
1339 * Check initialization state:
1340 * The VIO Thresholds need adaption
1342 if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1343 pSen->SenValue > SK_SEN_WARNLOW2C &&
1344 pSen->SenValue < SK_SEN_WARNHIGH2) {
1345 pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
1346 pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
1347 pSen->SenInit = SK_TRUE;
1350 if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1351 pSen->SenValue > SK_SEN_WARNLOW2 &&
1352 pSen->SenValue < SK_SEN_WARNHIGH2C) {
1353 pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
1354 pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
1355 pSen->SenInit = SK_TRUE;
1359 if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
1360 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
1362 } /* SkI2cCheckSensor*/
1366 * The only Event to be served is the timeout event
1370 SK_AC *pAC, /* Adapter Context */
1371 SK_IOC IoC, /* I/O Context */
1372 SK_U32 Event, /* Module specific Event */
1373 SK_EVPARA Para) /* Event specific Parameter */
1378 SK_EVPARA ParaLocal;
1381 /* New case: no sensors */
1382 if (pAC->I2c.MaxSens == 0) {
1388 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1389 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1392 /* Check sensor against defined thresholds */
1393 SkI2cCheckSensor (pAC, pSen);
1395 /* Increment Current sensor and set appropriate Timeout */
1396 pAC->I2c.CurrSens++;
1397 if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
1398 pAC->I2c.CurrSens = 0;
1399 Time = SK_I2C_TIM_LONG;
1402 Time = SK_I2C_TIM_SHORT;
1406 ParaLocal.Para64 = (SK_U64)0;
1408 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1410 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1411 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1415 ParaLocal.Para64 = (SK_U64)0;
1417 pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
1419 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
1420 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1424 if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
1426 ParaLocal.Para64 = (SK_U64)0;
1427 SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
1429 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1430 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1433 /* Check sensor against defined thresholds */
1434 SkI2cCheckSensor (pAC, pSen);
1436 /* Increment Current sensor and set appropriate Timeout */
1437 pAC->I2c.CurrSens++;
1438 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1439 pAC->I2c.CurrSens = 0;
1440 Time = SK_I2C_TIM_LONG;
1443 Time = SK_I2C_TIM_SHORT;
1447 ParaLocal.Para64 = (SK_U64)0;
1449 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1451 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1452 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1456 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1457 pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
1460 /* Increment Current sensor and set appropriate Timeout */
1461 pAC->I2c.CurrSens++;
1462 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1463 pAC->I2c.CurrSens = 0;
1464 Time = SK_I2C_TIM_LONG;
1467 Time = SK_I2C_TIM_SHORT;
1471 ParaLocal.Para64 = (SK_U64)0;
1473 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1475 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1476 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1479 case SK_I2CEV_CLEAR:
1480 for (i = 0; i < SK_MAX_SENSORS; i++) {
1481 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
1482 pAC->I2c.SenTable[i].SenErrCts = 0;
1483 pAC->I2c.SenTable[i].SenWarnCts = 0;
1484 pAC->I2c.SenTable[i].SenBegErrTS = 0;
1485 pAC->I2c.SenTable[i].SenBegWarnTS = 0;
1486 pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
1487 pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
1488 pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
1489 pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
1493 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
1499 #endif /* !SK_DIAG */