Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / drivers / net / sk98lin / ski2c.c
1 /******************************************************************************
2  *
3  * Name:        ski2c.c
4  * Project:     Gigabit Ethernet Adapters, TWSI-Module
5  * Version:     $Revision: 1.59 $
6  * Date:        $Date: 2003/10/20 09:07:25 $
7  * Purpose:     Functions to access Voltage and Temperature Sensor
8  *
9  ******************************************************************************/
10
11 /******************************************************************************
12  *
13  *      (C)Copyright 1998-2002 SysKonnect.
14  *      (C)Copyright 2002-2003 Marvell.
15  *
16  *      This program is free software; you can redistribute it and/or modify
17  *      it under the terms of the GNU General Public License as published by
18  *      the Free Software Foundation; either version 2 of the License, or
19  *      (at your option) any later version.
20  *
21  *      The information in this file is provided "AS IS" without warranty.
22  *
23  ******************************************************************************/
24
25 /*
26  *      I2C Protocol
27  */
28 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
29 static const char SysKonnectFileId[] =
30         "@(#) $Id: ski2c.c,v 1.59 2003/10/20 09:07:25 rschmidt Exp $ (C) Marvell. ";
31 #endif
32
33 #include "h/skdrv1st.h"         /* Driver Specific Definitions */
34 #include "h/lm80.h"
35 #include "h/skdrv2nd.h"         /* Adapter Control- and Driver specific Def. */
36
37 #ifdef __C2MAN__
38 /*
39         I2C protocol implementation.
40
41         General Description:
42
43         The I2C protocol is used for the temperature sensors and for
44         the serial EEPROM which hold the configuration.
45
46         This file covers functions that allow to read write and do
47         some bulk requests a specified I2C address.
48
49         The Genesis has 2 I2C buses. One for the EEPROM which holds
50         the VPD Data and one for temperature and voltage sensor.
51         The following picture shows the I2C buses, I2C devices and
52         their control registers.
53
54         Note: The VPD functions are in skvpd.c
55 .
56 .       PCI Config I2C Bus for VPD Data:
57 .
58 .                     +------------+
59 .                     | VPD EEPROM |
60 .                     +------------+
61 .                            |
62 .                            | <-- I2C
63 .                            |
64 .                +-----------+-----------+
65 .                |                       |
66 .       +-----------------+     +-----------------+
67 .       | PCI_VPD_ADR_REG |     | PCI_VPD_DAT_REG |
68 .       +-----------------+     +-----------------+
69 .
70 .
71 .       I2C Bus for LM80 sensor:
72 .
73 .                       +-----------------+
74 .                       | Temperature and |
75 .                       | Voltage Sensor  |
76 .                       |       LM80      |
77 .                       +-----------------+
78 .                               |
79 .                               |
80 .                       I2C --> |
81 .                               |
82 .                            +----+
83 .            +-------------->| OR |<--+
84 .            |               +----+   |
85 .     +------+------+                 |
86 .     |             |                 |
87 . +--------+    +--------+      +----------+
88 . | B2_I2C |    | B2_I2C |      |  B2_I2C  |
89 . | _CTRL  |    | _DATA  |      |   _SW    |
90 . +--------+    +--------+      +----------+
91 .
92         The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
93         and B2_I2C_DATA registers.
94         For driver software it is recommended to use the I2C control and
95         data register, because I2C bus timing is done by the ASIC and
96         an interrupt may be received when the I2C request is completed.
97
98         Clock Rate Timing:                      MIN     MAX     generated by
99                 VPD EEPROM:                     50 kHz  100 kHz         HW
100                 LM80 over I2C Ctrl/Data reg.    50 kHz  100 kHz         HW
101                 LM80 over B2_I2C_SW register    0       400 kHz         SW
102
103         Note:   The clock generated by the hardware is dependend on the
104                 PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
105                 clock is 50 kHz.
106  */
107 intro()
108 {}
109 #endif
110
111 #ifdef SK_DIAG
112 /*
113  * I2C Fast Mode timing values used by the LM80.
114  * If new devices are added to the I2C bus the timing values have to be checked.
115  */
116 #ifndef I2C_SLOW_TIMING
117 #define T_CLK_LOW                       1300L   /* clock low time in ns */
118 #define T_CLK_HIGH                       600L   /* clock high time in ns */
119 #define T_DATA_IN_SETUP          100L   /* data in Set-up Time */
120 #define T_START_HOLD             600L   /* start condition hold time */
121 #define T_START_SETUP            600L   /* start condition Set-up time */
122 #define T_STOP_SETUP             600L   /* stop condition Set-up time */
123 #define T_BUS_IDLE                      1300L   /* time the bus must free after Tx */
124 #define T_CLK_2_DATA_OUT         900L   /* max. clock low to data output valid */
125 #else   /* I2C_SLOW_TIMING */
126 /* I2C Standard Mode Timing */
127 #define T_CLK_LOW                       4700L   /* clock low time in ns */
128 #define T_CLK_HIGH                      4000L   /* clock high time in ns */
129 #define T_DATA_IN_SETUP          250L   /* data in Set-up Time */
130 #define T_START_HOLD            4000L   /* start condition hold time */
131 #define T_START_SETUP           4700L   /* start condition Set-up time */
132 #define T_STOP_SETUP            4000L   /* stop condition Set-up time */
133 #define T_BUS_IDLE                      4700L   /* time the bus must free after Tx */
134 #endif  /* !I2C_SLOW_TIMING */
135
136 #define NS2BCLK(x)      (((x)*125)/10000)
137
138 /*
139  * I2C Wire Operations
140  *
141  * About I2C_CLK_LOW():
142  *
143  * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
144  * clock to low, to prevent the ASIC and the I2C data client from driving the
145  * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
146  * send an 'ACK'). See also Concentrator Bugreport No. 10192.
147  */
148 #define I2C_DATA_HIGH(IoC)      SK_I2C_SET_BIT(IoC, I2C_DATA)
149 #define I2C_DATA_LOW(IoC)       SK_I2C_CLR_BIT(IoC, I2C_DATA)
150 #define I2C_DATA_OUT(IoC)       SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
151 #define I2C_DATA_IN(IoC)        SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
152 #define I2C_CLK_HIGH(IoC)       SK_I2C_SET_BIT(IoC, I2C_CLK)
153 #define I2C_CLK_LOW(IoC)        SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
154 #define I2C_START_COND(IoC)     SK_I2C_CLR_BIT(IoC, I2C_CLK)
155
156 #define NS2CLKT(x)      ((x*125L)/10000)
157
158 /*--------------- I2C Interface Register Functions --------------- */
159
160 /*
161  * sending one bit
162  */
163 void SkI2cSndBit(
164 SK_IOC  IoC,    /* I/O Context */
165 SK_U8   Bit)    /* Bit to send */
166 {
167         I2C_DATA_OUT(IoC);
168         if (Bit) {
169                 I2C_DATA_HIGH(IoC);
170         }
171         else {
172                 I2C_DATA_LOW(IoC);
173         }
174         SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
175         I2C_CLK_HIGH(IoC);
176         SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
177         I2C_CLK_LOW(IoC);
178 }       /* SkI2cSndBit*/
179
180
181 /*
182  * Signal a start to the I2C Bus.
183  *
184  * A start is signaled when data goes to low in a high clock cycle.
185  *
186  * Ends with Clock Low.
187  *
188  * Status: not tested
189  */
190 void SkI2cStart(
191 SK_IOC  IoC)    /* I/O Context */
192 {
193         /* Init data and Clock to output lines */
194         /* Set Data high */
195         I2C_DATA_OUT(IoC);
196         I2C_DATA_HIGH(IoC);
197         /* Set Clock high */
198         I2C_CLK_HIGH(IoC);
199
200         SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
201
202         /* Set Data Low */
203         I2C_DATA_LOW(IoC);
204
205         SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
206
207         /* Clock low without Data to Input */
208         I2C_START_COND(IoC);
209
210         SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
211 }       /* SkI2cStart */
212
213
214 void SkI2cStop(
215 SK_IOC  IoC)    /* I/O Context */
216 {
217         /* Init data and Clock to output lines */
218         /* Set Data low */
219         I2C_DATA_OUT(IoC);
220         I2C_DATA_LOW(IoC);
221
222         SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
223
224         /* Set Clock high */
225         I2C_CLK_HIGH(IoC);
226
227         SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
228
229         /*
230          * Set Data High:       Do it by setting the Data Line to Input.
231          *                      Because of a pull up resistor the Data Line
232          *                      floods to high.
233          */
234         I2C_DATA_IN(IoC);
235
236         /*
237          *      When I2C activity is stopped
238          *       o      DATA should be set to input and
239          *       o      CLOCK should be set to high!
240          */
241         SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
242 }       /* SkI2cStop */
243
244
245 /*
246  * Receive just one bit via the I2C bus.
247  *
248  * Note:        Clock must be set to LOW before calling this function.
249  *
250  * Returns The received bit.
251  */
252 int SkI2cRcvBit(
253 SK_IOC  IoC)    /* I/O Context */
254 {
255         int     Bit;
256         SK_U8   I2cSwCtrl;
257
258         /* Init data as input line */
259         I2C_DATA_IN(IoC);
260
261         SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
262
263         I2C_CLK_HIGH(IoC);
264
265         SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
266
267         SK_I2C_GET_SW(IoC, &I2cSwCtrl);
268         
269         Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
270
271         I2C_CLK_LOW(IoC);
272         SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
273
274         return(Bit);
275 }       /* SkI2cRcvBit */
276
277
278 /*
279  * Receive an ACK.
280  *
281  * returns      0 If acknowledged
282  *              1 in case of an error
283  */
284 int SkI2cRcvAck(
285 SK_IOC  IoC)    /* I/O Context */
286 {
287         /*
288          * Received bit must be zero.
289          */
290         return(SkI2cRcvBit(IoC) != 0);
291 }       /* SkI2cRcvAck */
292
293
294 /*
295  * Send an NACK.
296  */
297 void SkI2cSndNAck(
298 SK_IOC  IoC)    /* I/O Context */
299 {
300         /*
301          * Received bit must be zero.
302          */
303         SkI2cSndBit(IoC, 1);
304 }       /* SkI2cSndNAck */
305
306
307 /*
308  * Send an ACK.
309  */
310 void SkI2cSndAck(
311 SK_IOC IoC)     /* I/O Context */
312 {
313         /*
314          * Received bit must be zero.
315          */
316         SkI2cSndBit(IoC, 0);
317 }       /* SkI2cSndAck */
318
319
320 /*
321  * Send one byte to the I2C device and wait for ACK.
322  *
323  * Return acknowleged status.
324  */
325 int SkI2cSndByte(
326 SK_IOC  IoC,    /* I/O Context */
327 int             Byte)   /* byte to send */
328 {
329         int     i;
330
331         for (i = 0; i < 8; i++) {
332                 if (Byte & (1<<(7-i))) {
333                         SkI2cSndBit(IoC, 1);
334                 }
335                 else {
336                         SkI2cSndBit(IoC, 0);
337                 }
338         }
339
340         return(SkI2cRcvAck(IoC));
341 }       /* SkI2cSndByte */
342
343
344 /*
345  * Receive one byte and ack it.
346  *
347  * Return byte.
348  */
349 int SkI2cRcvByte(
350 SK_IOC  IoC,    /* I/O Context */
351 int             Last)   /* Last Byte Flag */
352 {
353         int     i;
354         int     Byte = 0;
355
356         for (i = 0; i < 8; i++) {
357                 Byte <<= 1;
358                 Byte |= SkI2cRcvBit(IoC);
359         }
360
361         if (Last) {
362                 SkI2cSndNAck(IoC);
363         }
364         else {
365                 SkI2cSndAck(IoC);
366         }
367
368         return(Byte);
369 }       /* SkI2cRcvByte */
370
371
372 /*
373  * Start dialog and send device address
374  *
375  * Return 0 if acknowleged, 1 in case of an error
376  */
377 int     SkI2cSndDev(
378 SK_IOC  IoC,    /* I/O Context */
379 int             Addr,   /* Device Address */
380 int             Rw)             /* Read / Write Flag */
381 {
382         SkI2cStart(IoC);
383         Rw = ~Rw;
384         Rw &= I2C_WRITE;
385         return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
386 }       /* SkI2cSndDev */
387
388 #endif /* SK_DIAG */
389
390 /*----------------- I2C CTRL Register Functions ----------*/
391
392 /*
393  * waits for a completion of an I2C transfer
394  *
395  * returns      0:      success, transfer completes
396  *                      1:      error,   transfer does not complete, I2C transfer
397  *                                               killed, wait loop terminated.
398  */
399 int     SkI2cWait(
400 SK_AC   *pAC,   /* Adapter Context */
401 SK_IOC  IoC,    /* I/O Context */
402 int             Event)  /* complete event to wait for (I2C_READ or I2C_WRITE) */
403 {
404         SK_U64  StartTime;
405         SK_U64  CurrentTime;
406         SK_U32  I2cCtrl;
407
408         StartTime = SkOsGetTime(pAC);
409         
410         do {
411                 CurrentTime = SkOsGetTime(pAC);
412
413                 if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
414                         
415                         SK_I2C_STOP(IoC);
416 #ifndef SK_DIAG
417                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
418 #endif /* !SK_DIAG */
419                         return(1);
420                 }
421                 
422                 SK_I2C_GET_CTL(IoC, &I2cCtrl);
423
424 #ifdef xYUKON_DBG
425                 printf("StartTime=%lu, CurrentTime=%lu\n",
426                         StartTime, CurrentTime);
427                 if (kbhit()) {
428                         return(1);
429                 }
430 #endif /* YUKON_DBG */
431         
432         } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
433
434         return(0);
435 }       /* SkI2cWait */
436
437
438 /*
439  * waits for a completion of an I2C transfer
440  *
441  * Returns
442  *      Nothing
443  */
444 void SkI2cWaitIrq(
445 SK_AC   *pAC,   /* Adapter Context */
446 SK_IOC  IoC)    /* I/O Context */
447 {
448         SK_SENSOR       *pSen;
449         SK_U64          StartTime;
450         SK_U32          IrqSrc;
451
452         pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
453
454         if (pSen->SenState == SK_SEN_IDLE) {
455                 return;
456         }
457
458         StartTime = SkOsGetTime(pAC);
459         
460         do {
461                 if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
462                         
463                         SK_I2C_STOP(IoC);
464 #ifndef SK_DIAG
465                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
466 #endif /* !SK_DIAG */
467                         return;
468                 }
469                 
470                 SK_IN32(IoC, B0_ISRC, &IrqSrc);
471
472         } while ((IrqSrc & IS_I2C_READY) == 0);
473
474         pSen->SenState = SK_SEN_IDLE;
475         return;
476 }       /* SkI2cWaitIrq */
477
478 /*
479  * writes a single byte or 4 bytes into the I2C device
480  *
481  * returns      0:      success
482  *                      1:      error
483  */
484 int SkI2cWrite(
485 SK_AC   *pAC,           /* Adapter Context */
486 SK_IOC  IoC,            /* I/O Context */
487 SK_U32  I2cData,        /* I2C Data to write */
488 int             I2cDev,         /* I2C Device Address */
489 int             I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
490 int             I2cReg,         /* I2C Device Register Address */
491 int             I2cBurst)       /* I2C Burst Flag */
492 {
493         SK_OUT32(IoC, B2_I2C_DATA, I2cData);
494         
495         SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst);
496         
497         return(SkI2cWait(pAC, IoC, I2C_WRITE));
498 }       /* SkI2cWrite*/
499
500
501 #ifdef  SK_DIAG
502 /*
503  * reads a single byte or 4 bytes from the I2C device
504  *
505  * returns      the word read
506  */
507 SK_U32 SkI2cRead(
508 SK_AC   *pAC,           /* Adapter Context */
509 SK_IOC  IoC,            /* I/O Context */
510 int             I2cDev,         /* I2C Device Address */
511 int             I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
512 int             I2cReg,         /* I2C Device Register Address */
513 int             I2cBurst)       /* I2C Burst Flag */
514 {
515         SK_U32  Data;
516
517         SK_OUT32(IoC, B2_I2C_DATA, 0);
518         SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst);
519         
520         if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
521                 w_print("%s\n", SKERR_I2C_E002MSG);
522         }
523         
524         SK_IN32(IoC, B2_I2C_DATA, &Data);
525         
526         return(Data);
527 }       /* SkI2cRead */
528 #endif /* SK_DIAG */
529
530
531 /*
532  * read a sensor's value
533  *
534  * This function reads a sensor's value from the I2C sensor chip. The sensor
535  * is defined by its index into the sensors database in the struct pAC points
536  * to.
537  * Returns
538  *              1 if the read is completed
539  *              0 if the read must be continued (I2C Bus still allocated)
540  */
541 int     SkI2cReadSensor(
542 SK_AC           *pAC,   /* Adapter Context */
543 SK_IOC          IoC,    /* I/O Context */
544 SK_SENSOR       *pSen)  /* Sensor to be read */
545 {
546     if (pSen->SenRead != NULL) {
547         return((*pSen->SenRead)(pAC, IoC, pSen));
548     }
549         else {
550         return(0); /* no success */
551         }
552 }       /* SkI2cReadSensor */
553
554 /*
555  * Do the Init state 0 initialization
556  */
557 static int SkI2cInit0(
558 SK_AC   *pAC)   /* Adapter Context */
559 {
560         int     i;
561
562         /* Begin with first sensor */
563         pAC->I2c.CurrSens = 0;
564         
565         /* Begin with timeout control for state machine */
566         pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
567         
568         /* Set sensor number to zero */
569         pAC->I2c.MaxSens = 0;
570
571 #ifndef SK_DIAG
572         /* Initialize Number of Dummy Reads */
573         pAC->I2c.DummyReads = SK_MAX_SENSORS;
574 #endif
575
576         for (i = 0; i < SK_MAX_SENSORS; i++) {
577                 pAC->I2c.SenTable[i].SenDesc = "unknown";
578                 pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
579                 pAC->I2c.SenTable[i].SenThreErrHigh = 0;
580                 pAC->I2c.SenTable[i].SenThreErrLow = 0;
581                 pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
582                 pAC->I2c.SenTable[i].SenThreWarnLow = 0;
583                 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
584                 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
585                 pAC->I2c.SenTable[i].SenValue = 0;
586                 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
587                 pAC->I2c.SenTable[i].SenErrCts = 0;
588                 pAC->I2c.SenTable[i].SenBegErrTS = 0;
589                 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
590                 pAC->I2c.SenTable[i].SenRead = NULL;
591                 pAC->I2c.SenTable[i].SenDev = 0;
592         }
593
594         /* Now we are "INIT data"ed */
595         pAC->I2c.InitLevel = SK_INIT_DATA;
596         return(0);
597 }       /* SkI2cInit0*/
598
599
600 /*
601  * Do the init state 1 initialization
602  *
603  * initialize the following register of the LM80:
604  * Configuration register:
605  * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
606  *
607  * Interrupt Mask Register 1:
608  * - all interrupts are Disabled (0xff)
609  *
610  * Interrupt Mask Register 2:
611  * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
612  *
613  * Fan Divisor/RST_OUT register:
614  * - Divisors set to 1 (bits 00), all others 0s.
615  *
616  * OS# Configuration/Temperature resolution Register:
617  * - all 0s
618  *
619  */
620 static int SkI2cInit1(
621 SK_AC   *pAC,   /* Adapter Context */
622 SK_IOC  IoC)    /* I/O Context */
623 {
624     int i;
625     SK_U8 I2cSwCtrl;
626         SK_GEPORT *pPrt;        /* GIni Port struct pointer */
627
628         if (pAC->I2c.InitLevel != SK_INIT_DATA) {
629                 /* ReInit not needed in I2C module */
630                 return(0);
631         }
632
633     /* Set the Direction of I2C-Data Pin to IN */
634     SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
635     /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
636         SK_I2C_GET_SW(IoC, &I2cSwCtrl);
637
638         if ((I2cSwCtrl & I2C_DATA) == 0) {
639                 /* this is a 32-Bit board */
640                 pAC->GIni.GIYukon32Bit = SK_TRUE;
641         return(0);
642     }
643
644         /* Check for 64 Bit Yukon without sensors */
645         if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) {
646         return(0);
647     }
648
649         (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0);
650         
651         (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0);
652         
653         (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0);
654         
655         (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
656         
657         (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV,
658                 LM80_CFG, 0);
659         
660         /*
661          * MaxSens has to be updated here, because PhyType is not
662          * set when performing Init Level 0
663          */
664     pAC->I2c.MaxSens = 5;
665         
666         pPrt = &pAC->GIni.GP[0];
667         
668         if (pAC->GIni.GIGenesis) {
669                 if (pPrt->PhyType == SK_PHY_BCOM) {
670                         if (pAC->GIni.GIMacsFound == 1) {
671                                 pAC->I2c.MaxSens += 1;
672                         }
673                         else {
674                                 pAC->I2c.MaxSens += 3;
675                         }
676                 }
677         }
678         else {
679                 pAC->I2c.MaxSens += 3;
680         }
681         
682         for (i = 0; i < pAC->I2c.MaxSens; i++) {
683                 switch (i) {
684                 case 0:
685                         pAC->I2c.SenTable[i].SenDesc = "Temperature";
686                         pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
687                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
688                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
689                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
690                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
691                         pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
692                         break;
693                 case 1:
694                         pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
695                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
696                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
697                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
698                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
699                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
700                         pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
701                         break;
702                 case 2:
703                         pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
704                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
705                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
706                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
707                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
708                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
709                         pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
710                         pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
711                         break;
712                 case 3:
713                         pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
714                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
715                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
716                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
717                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
718                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
719                         pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
720                         break;
721                 case 4:
722                         if (pAC->GIni.GIGenesis) {
723                                 if (pPrt->PhyType == SK_PHY_BCOM) {
724                                         pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
725                                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
726                                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
727                                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
728                                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
729                                 }
730                                 else {
731                                         pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
732                                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
733                                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
734                                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
735                                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
736                                 }
737                         }
738                         else {
739                                 pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
740                                 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
741                                 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
742                                 if (pAC->GIni.GIVauxAvail) {
743                                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
744                                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
745                                 }
746                                 else {
747                                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
748                                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
749                                 }
750                         }
751                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
752                         pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
753                         break;
754                 case 5:
755                         if (pAC->GIni.GIGenesis) {
756                                 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
757                                 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
758                                 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
759                                 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
760                                 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
761                         }
762                         else {
763                                 pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5";
764                                 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
765                                 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
766                                 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
767                                 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
768                         }
769                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
770                         pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
771                         break;
772                 case 6:
773                         if (pAC->GIni.GIGenesis) {
774                                 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
775                         }
776                         else {
777                                 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
778                         }
779                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
780                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
781                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
782                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
783                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
784                         pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
785                         break;
786                 case 7:
787                         if (pAC->GIni.GIGenesis) {
788                                 pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
789                                 pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
790                                 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
791                                 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
792                                 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
793                                 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
794                                 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
795                         }
796                         else {
797                                 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
798                                 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
799                                 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
800                                 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
801                                 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
802                                 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
803                                 pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
804                         }
805                         break;
806                 default:
807                         SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
808                                 SKERR_I2C_E001, SKERR_I2C_E001MSG);
809                         break;
810                 }
811
812                 pAC->I2c.SenTable[i].SenValue = 0;
813                 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
814                 pAC->I2c.SenTable[i].SenErrCts = 0;
815                 pAC->I2c.SenTable[i].SenBegErrTS = 0;
816                 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
817                 pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
818                 pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
819         }
820
821 #ifndef SK_DIAG
822         pAC->I2c.DummyReads = pAC->I2c.MaxSens;
823 #endif /* !SK_DIAG */
824         
825         /* Clear I2C IRQ */
826         SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
827         
828         /* Now we are I/O initialized */
829         pAC->I2c.InitLevel = SK_INIT_IO;
830         return(0);
831 }       /* SkI2cInit1 */
832
833
834 /*
835  * Init level 2: Start first sensor read.
836  */
837 static int SkI2cInit2(
838 SK_AC   *pAC,   /* Adapter Context */
839 SK_IOC  IoC)    /* I/O Context */
840 {
841         int             ReadComplete;
842         SK_SENSOR       *pSen;
843
844         if (pAC->I2c.InitLevel != SK_INIT_IO) {
845                 /* ReInit not needed in I2C module */
846                 /* Init0 and Init2 not permitted */
847                 return(0);
848         }
849
850         pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
851         ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
852
853         if (ReadComplete) {
854                 SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
855         }
856
857         /* Now we are correctly initialized */
858         pAC->I2c.InitLevel = SK_INIT_RUN;
859
860         return(0);
861 }       /* SkI2cInit2*/
862
863
864 /*
865  * Initialize I2C devices
866  *
867  * Get the first voltage value and discard it.
868  * Go into temperature read mode. A default pointer is not set.
869  *
870  * The things to be done depend on the init level in the parameter list:
871  * Level 0:
872  *      Initialize only the data structures. Do NOT access hardware.
873  * Level 1:
874  *      Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
875  * Level 2:
876  *      Everything is possible. Interrupts may be used from now on.
877  *
878  * return:
879  *      0 = success
880  *      other = error.
881  */
882 int     SkI2cInit(
883 SK_AC   *pAC,   /* Adapter Context */
884 SK_IOC  IoC,    /* I/O Context needed in levels 1 and 2 */
885 int             Level)  /* Init Level */
886 {
887
888         switch (Level) {
889         case SK_INIT_DATA:
890                 return(SkI2cInit0(pAC));
891         case SK_INIT_IO:
892                 return(SkI2cInit1(pAC, IoC));
893         case SK_INIT_RUN:
894                 return(SkI2cInit2(pAC, IoC));
895         default:
896                 break;
897         }
898
899         return(0);
900 }       /* SkI2cInit */
901
902
903 #ifndef SK_DIAG
904
905 /*
906  * Interrupt service function for the I2C Interface
907  *
908  * Clears the Interrupt source
909  *
910  * Reads the register and check it for sending a trap.
911  *
912  * Starts the timer if necessary.
913  */
914 void SkI2cIsr(
915 SK_AC   *pAC,   /* Adapter Context */
916 SK_IOC  IoC)    /* I/O Context */
917 {
918         SK_EVPARA       Para;
919
920         /* Clear I2C IRQ */
921         SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
922
923         Para.Para64 = 0;
924         SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
925 }       /* SkI2cIsr */
926
927
928 /*
929  * Check this sensors Value against the threshold and send events.
930  */
931 static void SkI2cCheckSensor(
932 SK_AC           *pAC,   /* Adapter Context */
933 SK_SENSOR       *pSen)
934 {
935         SK_EVPARA       ParaLocal;
936         SK_BOOL         TooHigh;        /* Is sensor too high? */
937         SK_BOOL         TooLow;         /* Is sensor too low? */
938         SK_U64          CurrTime;       /* Current Time */
939         SK_BOOL         DoTrapSend;     /* We need to send a trap */
940         SK_BOOL         DoErrLog;       /* We need to log the error */
941         SK_BOOL         IsError;        /* We need to log the error */
942
943         /* Check Dummy Reads first */
944         if (pAC->I2c.DummyReads > 0) {
945                 pAC->I2c.DummyReads--;
946                 return;
947         }
948
949         /* Get the current time */
950         CurrTime = SkOsGetTime(pAC);
951
952         /* Set para to the most useful setting: The current sensor. */
953         ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
954
955         /* Check the Value against the thresholds. First: Error Thresholds */
956         TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
957         TooLow = (pSen->SenValue < pSen->SenThreErrLow);
958                 
959         IsError = SK_FALSE;
960         if (TooHigh || TooLow) {
961                 /* Error condition is satisfied */
962                 DoTrapSend = SK_TRUE;
963                 DoErrLog = SK_TRUE;
964
965                 /* Now error condition is satisfied */
966                 IsError = SK_TRUE;
967
968                 if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
969                         /* This state is the former one */
970
971                         /* So check first whether we have to send a trap */
972                         if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
973                             CurrTime) {
974                                 /*
975                                  * Do NOT send the Trap. The hold back time
976                                  * has to run out first.
977                                  */
978                                 DoTrapSend = SK_FALSE;
979                         }
980
981                         /* Check now whether we have to log an Error */
982                         if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
983                             CurrTime) {
984                                 /*
985                                  * Do NOT log the error. The hold back time
986                                  * has to run out first.
987                                  */
988                                 DoErrLog = SK_FALSE;
989                         }
990                 }
991                 else {
992                         /* We came from a different state -> Set Begin Time Stamp */
993                         pSen->SenBegErrTS = CurrTime;
994                         pSen->SenErrFlag = SK_SEN_ERR_ERR;
995                 }
996
997                 if (DoTrapSend) {
998                         /* Set current Time */
999                         pSen->SenLastErrTrapTS = CurrTime;
1000                         pSen->SenErrCts++;
1001
1002                         /* Queue PNMI Event */
1003                         SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1004                                 SK_PNMI_EVT_SEN_ERR_UPP :
1005                                 SK_PNMI_EVT_SEN_ERR_LOW),
1006                                 ParaLocal);
1007                 }
1008
1009                 if (DoErrLog) {
1010                         /* Set current Time */
1011                         pSen->SenLastErrLogTS = CurrTime;
1012
1013                         if (pSen->SenType == SK_SEN_TEMP) {
1014                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG);
1015                         }
1016                         else if (pSen->SenType == SK_SEN_VOLT) {
1017                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG);
1018                         }
1019                         else {
1020                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG);
1021                         }
1022                 }
1023         }
1024
1025         /* Check the Value against the thresholds */
1026         /* 2nd: Warning thresholds */
1027         TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
1028         TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
1029                 
1030         if (!IsError && (TooHigh || TooLow)) {
1031                 /* Error condition is satisfied */
1032                 DoTrapSend = SK_TRUE;
1033                 DoErrLog = SK_TRUE;
1034
1035                 if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
1036                         /* This state is the former one */
1037
1038                         /* So check first whether we have to send a trap */
1039                         if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) {
1040                                 /*
1041                                  * Do NOT send the Trap. The hold back time
1042                                  * has to run out first.
1043                                  */
1044                                 DoTrapSend = SK_FALSE;
1045                         }
1046
1047                         /* Check now whether we have to log an Error */
1048                         if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) {
1049                                 /*
1050                                  * Do NOT log the error. The hold back time
1051                                  * has to run out first.
1052                                  */
1053                                 DoErrLog = SK_FALSE;
1054                         }
1055                 }
1056                 else {
1057                         /* We came from a different state -> Set Begin Time Stamp */
1058                         pSen->SenBegWarnTS = CurrTime;
1059                         pSen->SenErrFlag = SK_SEN_ERR_WARN;
1060                 }
1061
1062                 if (DoTrapSend) {
1063                         /* Set current Time */
1064                         pSen->SenLastWarnTrapTS = CurrTime;
1065                         pSen->SenWarnCts++;
1066
1067                         /* Queue PNMI Event */
1068                         SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1069                                 SK_PNMI_EVT_SEN_WAR_UPP :
1070                                 SK_PNMI_EVT_SEN_WAR_LOW),
1071                                 ParaLocal);
1072                 }
1073
1074                 if (DoErrLog) {
1075                         /* Set current Time */
1076                         pSen->SenLastWarnLogTS = CurrTime;
1077
1078                         if (pSen->SenType == SK_SEN_TEMP) {
1079                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG);
1080                         }
1081                         else if (pSen->SenType == SK_SEN_VOLT) {
1082                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG);
1083                         }
1084                         else {
1085                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG);
1086                         }
1087                 }
1088         }
1089
1090         /* Check for NO error at all */
1091         if (!IsError && !TooHigh && !TooLow) {
1092                 /* Set o.k. Status if no error and no warning condition */
1093                 pSen->SenErrFlag = SK_SEN_ERR_OK;
1094         }
1095
1096         /* End of check against the thresholds */
1097
1098         /* Bug fix AF: 16.Aug.2001: Correct the init base
1099          * of LM80 sensor.
1100          */
1101         if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
1102
1103         pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1104
1105                 if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
1106                         /* 5V PCI-IO Voltage */
1107                         pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
1108                         pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
1109                 }
1110                 else {
1111                         /* 3.3V PCI-IO Voltage */
1112                         pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
1113                         pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
1114                 }
1115         }
1116         
1117 #ifdef TEST_ONLY
1118     /* Dynamic thresholds also for VAUX of LM80 sensor */
1119         if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
1120
1121         pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1122
1123                 /* 3.3V VAUX Voltage */
1124                 if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
1125                         pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
1126                         pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
1127                 }
1128                 /* 0V VAUX Voltage */
1129                 else {
1130                         pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
1131                         pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
1132                 }
1133         }
1134
1135         /*
1136          * Check initialization state:
1137          * The VIO Thresholds need adaption
1138          */
1139         if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1140              pSen->SenValue > SK_SEN_WARNLOW2C &&
1141              pSen->SenValue < SK_SEN_WARNHIGH2) {
1142                 pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
1143                 pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
1144                 pSen->SenInit = SK_TRUE;
1145         }
1146
1147         if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1148              pSen->SenValue > SK_SEN_WARNLOW2 &&
1149              pSen->SenValue < SK_SEN_WARNHIGH2C) {
1150                 pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
1151                 pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
1152                 pSen->SenInit = SK_TRUE;
1153         }
1154 #endif
1155
1156         if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
1157                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
1158         }
1159 }       /* SkI2cCheckSensor */
1160
1161
1162 /*
1163  * The only Event to be served is the timeout event
1164  *
1165  */
1166 int     SkI2cEvent(
1167 SK_AC           *pAC,   /* Adapter Context */
1168 SK_IOC          IoC,    /* I/O Context */
1169 SK_U32          Event,  /* Module specific Event */
1170 SK_EVPARA       Para)   /* Event specific Parameter */
1171 {
1172         int                     ReadComplete;
1173         SK_SENSOR       *pSen;
1174         SK_U32          Time;
1175         SK_EVPARA       ParaLocal;
1176         int                     i;
1177
1178         /* New case: no sensors */
1179         if (pAC->I2c.MaxSens == 0) {
1180                 return(0);
1181         }
1182
1183         switch (Event) {
1184         case SK_I2CEV_IRQ:
1185                 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1186                 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1187
1188                 if (ReadComplete) {
1189                         /* Check sensor against defined thresholds */
1190                         SkI2cCheckSensor(pAC, pSen);
1191
1192                         /* Increment Current sensor and set appropriate Timeout */
1193                         pAC->I2c.CurrSens++;
1194                         if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
1195                                 pAC->I2c.CurrSens = 0;
1196                                 Time = SK_I2C_TIM_LONG;
1197                         }
1198                         else {
1199                                 Time = SK_I2C_TIM_SHORT;
1200                         }
1201
1202                         /* Start Timer */
1203                         ParaLocal.Para64 = (SK_U64)0;
1204
1205                         pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1206                         
1207                         SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1208                                 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1209                 }
1210         else {
1211                         /* Start Timer */
1212                         ParaLocal.Para64 = (SK_U64)0;
1213
1214                         pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
1215
1216             SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
1217                                 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1218                 }
1219                 break;
1220         case SK_I2CEV_TIM:
1221                 if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
1222
1223                         ParaLocal.Para64 = (SK_U64)0;
1224                         SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
1225
1226                         pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1227                         ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1228
1229                         if (ReadComplete) {
1230                                 /* Check sensor against defined thresholds */
1231                                 SkI2cCheckSensor(pAC, pSen);
1232
1233                                 /* Increment Current sensor and set appropriate Timeout */
1234                                 pAC->I2c.CurrSens++;
1235                                 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1236                                         pAC->I2c.CurrSens = 0;
1237                                         Time = SK_I2C_TIM_LONG;
1238                                 }
1239                                 else {
1240                                         Time = SK_I2C_TIM_SHORT;
1241                                 }
1242
1243                                 /* Start Timer */
1244                                 ParaLocal.Para64 = (SK_U64)0;
1245
1246                                 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1247
1248                                 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1249                                         SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1250                         }
1251                 }
1252                 else {
1253                         pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1254                         pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
1255                         SK_I2C_STOP(IoC);
1256
1257                         /* Increment Current sensor and set appropriate Timeout */
1258                         pAC->I2c.CurrSens++;
1259                         if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1260                                 pAC->I2c.CurrSens = 0;
1261                                 Time = SK_I2C_TIM_LONG;
1262                         }
1263                         else {
1264                                 Time = SK_I2C_TIM_SHORT;
1265                         }
1266
1267                         /* Start Timer */
1268                         ParaLocal.Para64 = (SK_U64)0;
1269
1270                         pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1271
1272                         SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1273                                 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1274                 }
1275                 break;
1276         case SK_I2CEV_CLEAR:
1277                 for (i = 0; i < SK_MAX_SENSORS; i++) {
1278                         pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
1279                         pAC->I2c.SenTable[i].SenErrCts = 0;
1280                         pAC->I2c.SenTable[i].SenWarnCts = 0;
1281                         pAC->I2c.SenTable[i].SenBegErrTS = 0;
1282                         pAC->I2c.SenTable[i].SenBegWarnTS = 0;
1283                         pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
1284                         pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
1285                         pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
1286                         pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
1287                 }
1288                 break;
1289         default:
1290                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
1291         }
1292
1293         return(0);
1294 }       /* SkI2cEvent*/
1295
1296 #endif /* !SK_DIAG */