]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/sk98lin/ski2c.c
* Add support for SK98xx driver
[karo-tx-uboot.git] / drivers / sk98lin / ski2c.c
1 /******************************************************************************
2  *
3  * Name:        ski2c.c
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
8  *
9  ******************************************************************************/
10
11 /******************************************************************************
12  *
13  *      (C)Copyright 1998-2003 SysKonnect GmbH.
14  *
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.
19  *
20  *      The information in this file is provided "AS IS" without warranty.
21  *
22  ******************************************************************************/
23
24 /******************************************************************************
25  *
26  * History:
27  *
28  *      $Log: ski2c.c,v $
29  *      Revision 1.57  2003/01/28 09:17:38  rschmidt
30  *      Fixed handling for sensors on YUKON Fiber.
31  *      Editorial changes.
32  *      
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().
37  *      Editorial changes.
38  *      
39  *      Revision 1.55  2002/10/15 07:23:55  rschmidt
40  *      Added setting of the GIYukon32Bit bool variable to distinguish
41  *      32-bit adapters.
42  *      Editorial changes (TWSI).
43  *      
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).
47  *      Editorial changes.
48  *      
49  *      Revision 1.53  2002/08/08 11:04:53  rwahl
50  *      Added missing comment for revision 1.51
51  *      
52  *      Revision 1.52  2002/08/08 10:09:02  jschmalz
53  *      Sensor init state caused wrong error log entry
54  *      
55  *      Revision 1.51  2002/08/06 09:43:03  jschmalz
56  *      Extensions and changes for Yukon
57  *      
58  *      Revision 1.50  2002/08/02 12:09:22  rschmidt
59  *      Added support for YUKON sensors.
60  *      Editorial changes.
61  *      
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().
65  *      Editorial changes.
66  *      
67  *      Revision 1.48  2001/08/16 12:44:33  afischer
68  *      LM80 sensor init values corrected
69  *      
70  *      Revision 1.47  2001/04/05 11:38:09  rassmann
71  *      Set SenState to idle in SkI2cWaitIrq().
72  *      Changed error message in SkI2cWaitIrq().
73  *      
74  *      Revision 1.46  2001/04/02 14:03:35  rassmann
75  *      Changed pAC to IoC in SK_IN32().
76  *      
77  *      Revision 1.45  2001/03/21 12:12:49  rassmann
78  *      Resetting I2C_READY interrupt in SkI2cInit1().
79  *      
80  *      Revision 1.44  2000/08/07 15:49:03  gklug
81  *      Fix: SK_INFAST only in NetWare driver.
82  *      
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.
86  *      
87  *      Revision 1.42  1999/11/22 13:35:12  cgoos
88  *      Changed license header to GPL.
89  *      
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.
93  *      
94  *      Revision 1.40  1999/05/27 13:37:27  malthoff
95  *      Set divisor of 1 for fan count calculation.
96  *      
97  *      Revision 1.39  1999/05/20 14:54:43  malthoff
98  *      I2c.DummyReads is not used in Diagnostics.
99  *      
100  *      Revision 1.38  1999/05/20 09:20:56  cgoos
101  *      Changes for 1000Base-T (up to 9 sensors and fans).
102  *      
103  *      Revision 1.37  1999/03/25 15:11:36  gklug
104  *      fix: reset error flag if sensor reads correct value
105  *      
106  *      Revision 1.36  1999/01/07 14:11:16  gklug
107  *      fix: break added
108  *      
109  *      Revision 1.35  1999/01/05 15:31:49  gklug
110  *      fix: CLEAR STAT command is now added correctly
111  *      
112  *      Revision 1.34  1998/12/01 13:45:16  gklug
113  *      fix: introduced Init level, because we don't need reinits
114  *      
115  *      Revision 1.33  1998/11/09 14:54:25  malthoff
116  *      Modify I2C Transfer Timeout handling for Diagnostics.
117  *      
118  *      Revision 1.32  1998/11/03 06:54:35  gklug
119  *      fix: Need dummy reads at the beginning to init sensors
120  *
121  *      Revision 1.31  1998/11/03 06:42:42  gklug
122  *      fix: select correctVIO range only if between warning levels
123  *      
124  *      Revision 1.30  1998/11/02 07:36:53  gklug
125  *      fix: Error should not include WARNING message
126  *      
127  *      Revision 1.29  1998/10/30 15:07:43  malthoff
128  *      Disable 'I2C does not compelete' error log for diagnostics.
129  *      
130  *      Revision 1.28  1998/10/22 09:48:11  gklug
131  *      fix: SysKonnectFileId typo
132  *      
133  *      Revision 1.27  1998/10/20 09:59:46  gklug
134  *      add: parameter to SkOsGetTime
135  *      
136  *      Revision 1.26  1998/10/09 06:10:59  malthoff
137  *      Remove ID_sccs by SysKonnectFileId.
138  *      
139  *      Revision 1.25  1998/09/08 12:40:26  gklug
140  *      fix: syntax error in if clause
141  *      
142  *      Revision 1.24  1998/09/08 12:19:42  gklug
143  *      chg: INIT Level checking
144  *      
145  *      Revision 1.23  1998/09/08 07:37:20  gklug
146  *      fix: log error if PCI_IO voltage sensor could not be initialized
147  *      
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
153  *      
154  *      Revision 1.21  1998/08/27 14:46:01  gklug
155  *      chg: if-then-else replaced by switch
156  *
157  *      Revision 1.20  1998/08/27 14:40:07  gklug
158  *      test: integral types
159  *      
160  *      Revision 1.19  1998/08/25 07:51:54  gklug
161  *      fix: typos for compiling
162  *      
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!
166  *      
167  *      Revision 1.17  1998/08/25 05:56:48  gklug
168  *      add: CheckSensor function
169  *      
170  *      Revision 1.16  1998/08/20 11:41:10  gklug
171  *      chg: omit STRCPY macro by using char * as Sensor Description
172  *      
173  *      Revision 1.15  1998/08/20 11:37:35  gklug
174  *      chg: change Ioc to IoC
175  *      
176  *      Revision 1.14  1998/08/20 11:32:52  gklug
177  *      fix: Para compile error
178  *      
179  *      Revision 1.13  1998/08/20 11:27:41  gklug
180  *      fix: Compile bugs with new awrning constants
181  *      
182  *      Revision 1.12  1998/08/20 08:53:05  gklug
183  *      fix: compiler errors
184  *      add: Threshold values
185  *      
186  *      Revision 1.11  1998/08/19 12:39:22  malthoff
187  *      Compiler Fix: Some names have changed.
188  *      
189  *      Revision 1.10  1998/08/19 12:20:56  gklug
190  *      fix: remove struct from C files (see CCC)
191  *      
192  *      Revision 1.9  1998/08/19 06:28:46  malthoff
193  *      SkOsGetTime returns SK_U64 now.
194  *      
195  *      Revision 1.8  1998/08/17 13:53:33  gklug
196  *      fix: Parameter of event function and its result
197  *      
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.
203  *      
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
208  *
209  *      Revision 1.5  1998/08/14 06:24:49  gklug
210  *      add: init level 1 and 2
211  *
212  *      Revision 1.4  1998/08/12 14:31:12  gklug
213  *      add: error log for unknown event
214  *
215  *      Revision 1.3  1998/08/12 13:37:04  gklug
216  *      add: Init 0 function
217  *
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
222  *
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.
226  *
227  *
228  ******************************************************************************/
229
230
231 /*
232  *      I2C Protocol
233  */
234 static const char SysKonnectFileId[] =
235         "$Id: ski2c.c,v 1.57 2003/01/28 09:17:38 rschmidt Exp $";
236
237 #include "h/skdrv1st.h"         /* Driver Specific Definitions */
238 #include "h/lm80.h"
239 #include "h/skdrv2nd.h"         /* Adapter Control- and Driver specific Def. */
240
241 #ifdef __C2MAN__
242 /*
243         I2C protocol implementation.
244
245         General Description:
246
247         The I2C protocol is used for the temperature sensors and for
248         the serial EEPROM which hold the configuration.
249
250         This file covers functions that allow to read write and do
251         some bulk requests a specified I2C address.
252
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.
257
258         Note: The VPD functions are in skvpd.c
259 .
260 .       PCI Config I2C Bus for VPD Data:
261 .
262 .                     +------------+
263 .                     | VPD EEPROM |
264 .                     +------------+
265 .                            |
266 .                            | <-- I2C
267 .                            |
268 .                +-----------+-----------+
269 .                |                       |
270 .       +-----------------+     +-----------------+
271 .       | PCI_VPD_ADR_REG |     | PCI_VPD_DAT_REG |
272 .       +-----------------+     +-----------------+
273 .
274 .
275 .       I2C Bus for LM80 sensor:
276 .
277 .                       +-----------------+
278 .                       | Temperature and |
279 .                       | Voltage Sensor  |
280 .                       |       LM80      |
281 .                       +-----------------+
282 .                               |
283 .                               |
284 .                       I2C --> |
285 .                               |
286 .                            +----+
287 .            +-------------->| OR |<--+
288 .            |               +----+   |
289 .     +------+------+                 |
290 .     |             |                 |
291 . +--------+    +--------+      +----------+
292 . | B2_I2C |    | B2_I2C |      |  B2_I2C  |
293 . | _CTRL  |    | _DATA  |      |   _SW    |
294 . +--------+    +--------+      +----------+
295 .
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.
301
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
306
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
309                 clock is 50 kHz.
310  */
311 intro()
312 {}
313 #endif
314
315 #ifdef  SK_DIAG
316 /*
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.
319  */
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 */
339
340 #define NS2BCLK(x)      (((x)*125)/10000)
341
342 /*
343  * I2C Wire Operations
344  *
345  * About I2C_CLK_LOW():
346  *
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.
351  */
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)
359
360 #define NS2CLKT(x)      ((x*125L)/10000)
361
362 /*--------------- I2C Interface Register Functions --------------- */
363
364 /*
365  * sending one bit
366  */
367 void SkI2cSndBit(
368 SK_IOC  IoC,    /* I/O Context */
369 SK_U8   Bit)    /* Bit to send */
370 {
371         I2C_DATA_OUT(IoC);
372         if (Bit) {
373                 I2C_DATA_HIGH(IoC);
374         }
375         else {
376                 I2C_DATA_LOW(IoC);
377         }
378         SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
379         I2C_CLK_HIGH(IoC);
380         SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
381         I2C_CLK_LOW(IoC);
382 }       /* SkI2cSndBit*/
383
384
385 /*
386  * Signal a start to the I2C Bus.
387  *
388  * A start is signaled when data goes to low in a high clock cycle.
389  *
390  * Ends with Clock Low.
391  *
392  * Status: not tested
393  */
394 void SkI2cStart(
395 SK_IOC  IoC)    /* I/O Context */
396 {
397         /* Init data and Clock to output lines */
398         /* Set Data high */
399         I2C_DATA_OUT(IoC);
400         I2C_DATA_HIGH(IoC);
401         /* Set Clock high */
402         I2C_CLK_HIGH(IoC);
403
404         SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
405
406         /* Set Data Low */
407         I2C_DATA_LOW(IoC);
408
409         SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
410
411         /* Clock low without Data to Input */
412         I2C_START_COND(IoC);
413
414         SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
415 }       /* SkI2cStart */
416
417
418 void SkI2cStop(
419 SK_IOC  IoC)    /* I/O Context */
420 {
421         /* Init data and Clock to output lines */
422         /* Set Data low */
423         I2C_DATA_OUT(IoC);
424         I2C_DATA_LOW(IoC);
425
426         SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
427
428         /* Set Clock high */
429         I2C_CLK_HIGH(IoC);
430
431         SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
432
433         /*
434          * Set Data High:       Do it by setting the Data Line to Input.
435          *                      Because of a pull up resistor the Data Line
436          *                      floods to high.
437          */
438         I2C_DATA_IN(IoC);
439
440         /*
441          *      When I2C activity is stopped
442          *       o      DATA should be set to input and
443          *       o      CLOCK should be set to high!
444          */
445         SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
446 }       /* SkI2cStop */
447
448
449 /*
450  * Receive just one bit via the I2C bus.
451  *
452  * Note:        Clock must be set to LOW before calling this function.
453  *
454  * Returns The received bit.
455  */
456 int SkI2cRcvBit(
457 SK_IOC  IoC)    /* I/O Context */
458 {
459         int     Bit;
460         SK_U8   I2cSwCtrl;
461
462         /* Init data as input line */
463         I2C_DATA_IN(IoC);
464
465         SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
466
467         I2C_CLK_HIGH(IoC);
468
469         SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
470
471         SK_I2C_GET_SW(IoC, &I2cSwCtrl);
472         
473         Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
474
475         I2C_CLK_LOW(IoC);
476         SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
477
478         return(Bit);
479 }       /* SkI2cRcvBit */
480
481
482 /*
483  * Receive an ACK.
484  *
485  * returns      0 If acknowledged
486  *              1 in case of an error
487  */
488 int SkI2cRcvAck(
489 SK_IOC  IoC)    /* I/O Context */
490 {
491         /*
492          * Received bit must be zero.
493          */
494         return(SkI2cRcvBit(IoC) != 0);
495 }       /* SkI2cRcvAck */
496
497
498 /*
499  * Send an NACK.
500  */
501 void SkI2cSndNAck(
502 SK_IOC  IoC)    /* I/O Context */
503 {
504         /*
505          * Received bit must be zero.
506          */
507         SkI2cSndBit(IoC, 1);
508 }       /* SkI2cSndNAck */
509
510
511 /*
512  * Send an ACK.
513  */
514 void SkI2cSndAck(
515 SK_IOC IoC)     /* I/O Context */
516 {
517         /*
518          * Received bit must be zero.
519          *
520          */
521         SkI2cSndBit(IoC, 0);
522 }       /* SkI2cSndAck */
523
524
525 /*
526  * Send one byte to the I2C device and wait for ACK.
527  *
528  * Return acknowleged status.
529  */
530 int SkI2cSndByte(
531 SK_IOC  IoC,    /* I/O Context */
532 int             Byte)   /* byte to send */
533 {
534         int     i;
535
536         for (i = 0; i < 8; i++) {
537                 if (Byte & (1<<(7-i))) {
538                         SkI2cSndBit(IoC, 1);
539                 }
540                 else {
541                         SkI2cSndBit(IoC, 0);
542                 }
543         }
544
545         return(SkI2cRcvAck(IoC));
546 }       /* SkI2cSndByte */
547
548
549 /*
550  * Receive one byte and ack it.
551  *
552  * Return byte.
553  */
554 int SkI2cRcvByte(
555 SK_IOC  IoC,    /* I/O Context */
556 int             Last)   /* Last Byte Flag */
557 {
558         int     i;
559         int     Byte = 0;
560
561         for (i = 0; i < 8; i++) {
562                 Byte <<= 1;
563                 Byte |= SkI2cRcvBit(IoC);
564         }
565
566         if (Last) {
567                 SkI2cSndNAck(IoC);
568         }
569         else {
570                 SkI2cSndAck(IoC);
571         }
572
573         return(Byte);
574 }       /* SkI2cRcvByte */
575
576
577 /*
578  * Start dialog and send device address
579  *
580  * Return 0 if acknowleged, 1 in case of an error
581  */
582 int     SkI2cSndDev(
583 SK_IOC  IoC,    /* I/O Context */
584 int             Addr,   /* Device Address */
585 int             Rw)             /* Read / Write Flag */
586 {
587         SkI2cStart(IoC);
588         Rw = ~Rw;
589         Rw &= I2C_WRITE;
590         return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
591 }       /* SkI2cSndDev */
592
593 #endif  /* SK_DIAG */
594
595 /*----------------- I2C CTRL Register Functions ----------*/
596
597 /*
598  * waits for a completion of an I2C transfer
599  *
600  * returns      0:      success, transfer completes
601  *                      1:      error,   transfer does not complete, I2C transfer
602  *                                               killed, wait loop terminated.
603  */
604 int     SkI2cWait(
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) */
608 {
609         SK_U64  StartTime;
610         SK_U64  CurrentTime;
611         SK_U32  I2cCtrl;
612
613         StartTime = SkOsGetTime(pAC);
614         
615         do {
616                 CurrentTime = SkOsGetTime(pAC);
617
618                 if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
619                         
620                         SK_I2C_STOP(IoC);
621 #ifndef SK_DIAG
622                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
623 #endif  /* !SK_DIAG */
624                         return(1);
625                 }
626                 
627                 SK_I2C_GET_CTL(IoC, &I2cCtrl);
628
629 #ifdef xYUKON_DBG
630                 printf("StartTime=%lu, CurrentTime=%lu\n",
631                         StartTime, CurrentTime);
632                 if (kbhit()) {
633                         return(1);
634                 }
635 #endif /* YUKON_DBG */
636         
637         } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
638
639         return(0);
640 }       /* SkI2cWait */
641
642
643 /*
644  * waits for a completion of an I2C transfer
645  *
646  * Returns
647  *      Nothing
648  */
649 void SkI2cWaitIrq(
650 SK_AC   *pAC,   /* Adapter Context */
651 SK_IOC  IoC)    /* I/O Context */
652 {
653         SK_SENSOR       *pSen;
654         SK_U64          StartTime;
655         SK_U32          IrqSrc;
656
657         pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
658
659         if (pSen->SenState == SK_SEN_IDLE) {
660                 return;
661         }
662
663         StartTime = SkOsGetTime(pAC);
664         do {
665                 if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
666                         SK_I2C_STOP(IoC);
667 #ifndef SK_DIAG
668                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
669 #endif  /* !SK_DIAG */
670                         return;
671                 }
672                 SK_IN32(IoC, B0_ISRC, &IrqSrc);
673         } while ((IrqSrc & IS_I2C_READY) == 0);
674
675         pSen->SenState = SK_SEN_IDLE;
676         return;
677 }       /* SkI2cWaitIrq */
678
679 /*
680  * writes a single byte or 4 bytes into the I2C device
681  *
682  * returns      0:      success
683  *                      1:      error
684  */
685 int SkI2cWrite(
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 */
692 {
693         SK_OUT32(IoC, B2_I2C_DATA, I2cData);
694         SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst);
695         
696         return(SkI2cWait(pAC, IoC, I2C_WRITE));
697 }       /* SkI2cWrite*/
698
699
700 #ifdef  SK_DIAG
701
702 /*
703  * reads a single byte or 4 bytes from the I2C device
704  *
705  * returns      the word read
706  */
707 SK_U32 SkI2cRead(
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 */
713 {
714         SK_U32  Data;
715
716         SK_OUT32(IoC, B2_I2C_DATA, 0);
717         SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst);
718         
719         if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
720                 w_print("%s\n", SKERR_I2C_E002MSG);
721         }
722         
723         SK_IN32(IoC, B2_I2C_DATA, &Data);
724         return(Data);
725 }       /* SkI2cRead */
726
727 #endif  /* SK_DIAG */
728
729
730 /*
731  * read a sensor's value
732  *
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
735  * to.
736  * Returns
737  *              1 if the read is completed
738  *              0 if the read must be continued (I2C Bus still allocated)
739  */
740 int     SkI2cReadSensor(
741 SK_AC           *pAC,   /* Adapter Context */
742 SK_IOC          IoC,    /* I/O Context */
743 SK_SENSOR       *pSen)  /* Sensor to be read */
744 {
745     if (pSen->SenRead != NULL) {
746         return((*pSen->SenRead)(pAC, IoC, pSen));
747     }
748     else
749         return(0); /* no success */
750 }       /* SkI2cReadSensor*/
751
752 /*
753  * Do the Init state 0 initialization
754  */
755 static int SkI2cInit0(
756 SK_AC   *pAC)   /* Adapter Context */
757 {
758         int     i;
759
760         /* Begin with first sensor */
761         pAC->I2c.CurrSens = 0;
762         
763         /* Begin with timeout control for state machine */
764         pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
765         
766         /* Set sensor number to zero */
767         pAC->I2c.MaxSens = 0;
768
769 #ifndef SK_DIAG
770         /* Initialize Number of Dummy Reads */
771         pAC->I2c.DummyReads = SK_MAX_SENSORS;
772 #endif
773
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;
790         }
791
792         /* Now we are "INIT data"ed */
793         pAC->I2c.InitLevel = SK_INIT_DATA;
794         return(0);
795 }       /* SkI2cInit0*/
796
797
798 /*
799  * Do the init state 1 initialization
800  *
801  * initialize the following register of the LM80:
802  * Configuration register:
803  * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
804  *
805  * Interrupt Mask Register 1:
806  * - all interrupts are Disabled (0xff)
807  *
808  * Interrupt Mask Register 2:
809  * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
810  *
811  * Fan Divisor/RST_OUT register:
812  * - Divisors set to 1 (bits 00), all others 0s.
813  *
814  * OS# Configuration/Temperature resolution Register:
815  * - all 0s
816  *
817  */
818 static int SkI2cInit1(
819 SK_AC   *pAC,   /* Adapter Context */
820 SK_IOC  IoC)    /* I/O Context */
821 {
822     int i;
823     SK_U8 I2cSwCtrl;
824         SK_GEPORT *pPrt;        /* GIni Port struct pointer */
825
826         if (pAC->I2c.InitLevel != SK_INIT_DATA) {
827                 /* ReInit not needed in I2C module */
828                 return(0);
829         }
830
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);
835
836         if ((I2cSwCtrl & I2C_DATA) == 0) {
837                 /* this is a 32-Bit board */
838                 pAC->GIni.GIYukon32Bit = SK_TRUE;
839         return(0);
840     }
841
842         /* Check for 64 Bit Yukon without sensors */
843         if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_CFG, 0) != 0) {
844         return(0);
845     }
846
847         (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_1, 0);
848         
849         (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_2, 0);
850         
851         (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_FAN_CTRL, 0);
852         
853         (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_TEMP_CTRL, 0);
854         
855         (void)SkI2cWrite(pAC, IoC, LM80_CFG_START, LM80_ADDR, LM80_CFG, 0);
856         
857         /*
858          * MaxSens has to be updated here, because PhyType is not
859          * set when performing Init Level 0
860          */
861     pAC->I2c.MaxSens = 5;
862         
863         pPrt = &pAC->GIni.GP[0];
864         
865         if (pAC->GIni.GIGenesis) {
866                 if (pPrt->PhyType == SK_PHY_BCOM) {
867                         if (pAC->GIni.GIMacsFound == 1) {
868                                 pAC->I2c.MaxSens += 1;
869                         }
870                         else {
871                                 pAC->I2c.MaxSens += 3;
872                         }
873                 }
874         }
875         else {
876                 pAC->I2c.MaxSens += 3;
877         }
878         
879         for (i = 0; i < pAC->I2c.MaxSens; i++) {
880                 switch (i) {
881                 case 0:
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;
889                         break;
890                 case 1:
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;
898                         break;
899                 case 2:
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;
908                         break;
909                 case 3:
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;
917                         break;
918                 case 4:
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;
926                                 }
927                                 else {
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;
933                                 }
934                         }
935                         else {
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;
942                                 }
943                                 else {
944                                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
945                                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
946                                 }
947                         }
948                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
949                         pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
950                         break;
951                 case 5:
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;
958                         }
959                         else {
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;
965                         }
966                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
967                         pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
968                         break;
969                 case 6:
970                         if (pAC->GIni.GIGenesis) {
971                                 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
972                         }
973                         else {
974                                 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
975                         }
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;
982                         break;
983                 case 7:
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;
992                         }
993                         else {
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;
1001                         }
1002                         break;
1003                 default:
1004                         SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
1005                                 SKERR_I2C_E001, SKERR_I2C_E001MSG);
1006                         break;
1007                 }
1008
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;
1016         }
1017
1018 #ifndef SK_DIAG
1019         pAC->I2c.DummyReads = pAC->I2c.MaxSens;
1020 #endif  /* !SK_DIAG */
1021         
1022         /* Clear I2C IRQ */
1023         SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
1024         
1025         /* Now we are I/O initialized */
1026         pAC->I2c.InitLevel = SK_INIT_IO;
1027         return(0);
1028 }       /* SkI2cInit1 */
1029
1030
1031 /*
1032  * Init level 2: Start first sensor read.
1033  */
1034 static int SkI2cInit2(
1035 SK_AC   *pAC,   /* Adapter Context */
1036 SK_IOC  IoC)    /* I/O Context */
1037 {
1038         int             ReadComplete;
1039         SK_SENSOR       *pSen;
1040
1041         if (pAC->I2c.InitLevel != SK_INIT_IO) {
1042                 /* ReInit not needed in I2C module */
1043                 /* Init0 and Init2 not permitted */
1044                 return(0);
1045         }
1046
1047         pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1048         ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1049
1050         if (ReadComplete) {
1051                 SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
1052         }
1053
1054         /* Now we are correctly initialized */
1055         pAC->I2c.InitLevel = SK_INIT_RUN;
1056
1057         return(0);
1058 }       /* SkI2cInit2*/
1059
1060
1061 /*
1062  * Initialize I2C devices
1063  *
1064  * Get the first voltage value and discard it.
1065  * Go into temperature read mode. A default pointer is not set.
1066  *
1067  * The things to be done depend on the init level in the parameter list:
1068  * Level 0:
1069  *      Initialize only the data structures. Do NOT access hardware.
1070  * Level 1:
1071  *      Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
1072  * Level 2:
1073  *      Everything is possible. Interrupts may be used from now on.
1074  *
1075  * return:
1076  *      0 = success
1077  *      other = error.
1078  */
1079 int     SkI2cInit(
1080 SK_AC   *pAC,   /* Adapter Context */
1081 SK_IOC  IoC,    /* I/O Context needed in levels 1 and 2 */
1082 int             Level)  /* Init Level */
1083 {
1084
1085         switch (Level) {
1086         case SK_INIT_DATA:
1087                 return(SkI2cInit0(pAC));
1088         case SK_INIT_IO:
1089                 return(SkI2cInit1(pAC, IoC));
1090         case SK_INIT_RUN:
1091                 return(SkI2cInit2(pAC, IoC));
1092         default:
1093                 break;
1094         }
1095
1096         return(0);
1097 }       /* SkI2cInit */
1098
1099
1100 #ifndef SK_DIAG
1101
1102 /*
1103  * Interrupt service function for the I2C Interface
1104  *
1105  * Clears the Interrupt source
1106  *
1107  * Reads the register and check it for sending a trap.
1108  *
1109  * Starts the timer if necessary.
1110  */
1111 void SkI2cIsr(
1112 SK_AC   *pAC,   /* Adapter Context */
1113 SK_IOC  IoC)    /* I/O Context */
1114 {
1115         SK_EVPARA       Para;
1116
1117         /* Clear I2C IRQ */
1118         SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
1119
1120         Para.Para64 = 0;
1121         SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
1122 }       /* SkI2cIsr */
1123
1124
1125 /*
1126  * Check this sensors Value against the threshold and send events.
1127  */
1128 static void SkI2cCheckSensor(
1129 SK_AC           *pAC,   /* Adapter Context */
1130 SK_SENSOR       *pSen)
1131 {
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 */
1139
1140         /* Check Dummy Reads first */
1141         if (pAC->I2c.DummyReads > 0) {
1142                 pAC->I2c.DummyReads--;
1143                 return;
1144         }
1145
1146         /* Get the current time */
1147         CurrTime = SkOsGetTime(pAC);
1148
1149         /* Set para to the most useful setting: The current sensor. */
1150         ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
1151
1152         /* Check the Value against the thresholds. First: Error Thresholds */
1153         TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
1154         TooLow = (pSen->SenValue < pSen->SenThreErrLow);
1155                 
1156         IsError = SK_FALSE;
1157         if (TooHigh || TooLow) {
1158                 /* Error condition is satisfied */
1159                 DoTrapSend = SK_TRUE;
1160                 DoErrLog = SK_TRUE;
1161
1162                 /* Now error condition is satisfied */
1163                 IsError = SK_TRUE;
1164
1165                 if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
1166                         /* This state is the former one */
1167
1168                         /* So check first whether we have to send a trap */
1169                         if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
1170                             CurrTime) {
1171                                 /*
1172                                  * Do NOT send the Trap. The hold back time
1173                                  * has to run out first.
1174                                  */
1175                                 DoTrapSend = SK_FALSE;
1176                         }
1177
1178                         /* Check now whether we have to log an Error */
1179                         if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
1180                             CurrTime) {
1181                                 /*
1182                                  * Do NOT log the error. The hold back time
1183                                  * has to run out first.
1184                                  */
1185                                 DoErrLog = SK_FALSE;
1186                         }
1187                 }
1188                 else {
1189                         /* We came from a different state -> Set Begin Time Stamp */
1190                         pSen->SenBegErrTS = CurrTime;
1191                         pSen->SenErrFlag = SK_SEN_ERR_ERR;
1192                 }
1193
1194                 if (DoTrapSend) {
1195                         /* Set current Time */
1196                         pSen->SenLastErrTrapTS = CurrTime;
1197                         pSen->SenErrCts++;
1198
1199                         /* Queue PNMI Event */
1200                         SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1201                                 SK_PNMI_EVT_SEN_ERR_UPP :
1202                                 SK_PNMI_EVT_SEN_ERR_LOW),
1203                                 ParaLocal);
1204                 }
1205
1206                 if (DoErrLog) {
1207                         /* Set current Time */
1208                         pSen->SenLastErrLogTS = CurrTime;
1209
1210                         if (pSen->SenType == SK_SEN_TEMP) {
1211                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011,
1212                                         SKERR_I2C_E011MSG);
1213                         } else if (pSen->SenType == SK_SEN_VOLT) {
1214                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012,
1215                                         SKERR_I2C_E012MSG);
1216                         } else
1217                         {
1218                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015,
1219                                         SKERR_I2C_E015MSG);
1220                         }
1221                 }
1222         }
1223
1224         /* Check the Value against the thresholds */
1225         /* 2nd: Warning thresholds */
1226         TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
1227         TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
1228                 
1229         if (!IsError && (TooHigh || TooLow)) {
1230                 /* Error condition is satisfied */
1231                 DoTrapSend = SK_TRUE;
1232                 DoErrLog = SK_TRUE;
1233
1234                 if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
1235                         /* This state is the former one */
1236
1237                         /* So check first whether we have to send a trap */
1238                         if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD >
1239                             CurrTime) {
1240                                 /*
1241                                  * Do NOT send the Trap. The hold back time
1242                                  * has to run out first.
1243                                  */
1244                                 DoTrapSend = SK_FALSE;
1245                         }
1246
1247                         /* Check now whether we have to log an Error */
1248                         if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD >
1249                             CurrTime) {
1250                                 /*
1251                                  * Do NOT log the error. The hold back time
1252                                  * has to run out first.
1253                                  */
1254                                 DoErrLog = SK_FALSE;
1255                         }
1256                 }
1257                 else {
1258                         /* We came from a different state -> Set Begin Time Stamp */
1259                         pSen->SenBegWarnTS = CurrTime;
1260                         pSen->SenErrFlag = SK_SEN_ERR_WARN;
1261                 }
1262
1263                 if (DoTrapSend) {
1264                         /* Set current Time */
1265                         pSen->SenLastWarnTrapTS = CurrTime;
1266                         pSen->SenWarnCts++;
1267
1268                         /* Queue PNMI Event */
1269                         SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1270                                 SK_PNMI_EVT_SEN_WAR_UPP :
1271                                 SK_PNMI_EVT_SEN_WAR_LOW),
1272                                 ParaLocal);
1273                 }
1274
1275                 if (DoErrLog) {
1276                         /* Set current Time */
1277                         pSen->SenLastWarnLogTS = CurrTime;
1278
1279                         if (pSen->SenType == SK_SEN_TEMP) {
1280                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009,
1281                                         SKERR_I2C_E009MSG);
1282                         } else if (pSen->SenType == SK_SEN_VOLT) {
1283                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010,
1284                                         SKERR_I2C_E010MSG);
1285                         } else
1286                         {
1287                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014,
1288                                         SKERR_I2C_E014MSG);
1289                         }
1290                 }
1291         }
1292
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;
1297         }
1298
1299         /* End of check against the thresholds */
1300
1301         /* Bug fix AF: 16.Aug.2001: Correct the init base
1302          * of LM80 sensor.
1303          */
1304         if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
1305
1306         pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1307
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;
1312                 }
1313                 else {
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;
1317                 }
1318         }
1319         
1320 #if 0
1321     /* Dynamic thresholds also for VAUX of LM80 sensor */
1322         if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
1323
1324         pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1325
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;
1330                 }
1331                 /* 0V VAUX Voltage */
1332                 else {
1333                         pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
1334                         pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
1335                 }
1336         }
1337
1338         /*
1339          * Check initialization state:
1340          * The VIO Thresholds need adaption
1341          */
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;
1348         }
1349
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;
1356         }
1357 #endif
1358
1359         if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
1360                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
1361         }
1362 }       /* SkI2cCheckSensor*/
1363
1364
1365 /*
1366  * The only Event to be served is the timeout event
1367  *
1368  */
1369 int     SkI2cEvent(
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 */
1374 {
1375         int                     ReadComplete;
1376         SK_SENSOR       *pSen;
1377         SK_U32          Time;
1378         SK_EVPARA       ParaLocal;
1379         int                     i;
1380
1381         /* New case: no sensors */
1382         if (pAC->I2c.MaxSens == 0) {
1383                 return(0);
1384         }
1385
1386         switch (Event) {
1387         case SK_I2CEV_IRQ:
1388                 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1389                 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1390
1391                 if (ReadComplete) {
1392                         /* Check sensor against defined thresholds */
1393                         SkI2cCheckSensor (pAC, pSen);
1394
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;
1400                         }
1401                         else {
1402                                 Time = SK_I2C_TIM_SHORT;
1403                         }
1404
1405                         /* Start Timer */
1406                         ParaLocal.Para64 = (SK_U64)0;
1407
1408                         pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1409                         
1410                         SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1411                                 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1412                 }
1413         else {
1414                         /* Start Timer */
1415                         ParaLocal.Para64 = (SK_U64)0;
1416
1417                         pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
1418
1419             SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
1420                                 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1421                 }
1422                 break;
1423         case SK_I2CEV_TIM:
1424                 if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
1425
1426                         ParaLocal.Para64 = (SK_U64)0;
1427                         SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
1428
1429                         pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1430                         ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1431
1432                         if (ReadComplete) {
1433                                 /* Check sensor against defined thresholds */
1434                                 SkI2cCheckSensor (pAC, pSen);
1435
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;
1441                                 }
1442                                 else {
1443                                         Time = SK_I2C_TIM_SHORT;
1444                                 }
1445
1446                                 /* Start Timer */
1447                                 ParaLocal.Para64 = (SK_U64)0;
1448
1449                                 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1450
1451                                 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1452                                         SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1453                         }
1454                 }
1455                 else {
1456                         pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1457                         pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
1458                         SK_I2C_STOP(IoC);
1459
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;
1465                         }
1466                         else {
1467                                 Time = SK_I2C_TIM_SHORT;
1468                         }
1469
1470                         /* Start Timer */
1471                         ParaLocal.Para64 = (SK_U64)0;
1472
1473                         pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1474
1475                         SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1476                                 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1477                 }
1478                 break;
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;
1490                 }
1491                 break;
1492         default:
1493                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
1494         }
1495
1496         return(0);
1497 }       /* SkI2cEvent*/
1498
1499 #endif  /* !SK_DIAG */