]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/sk98lin/ski2c.c
85xx: Drop FIT support to allow u-boot image to fit in 512k
[karo-tx-uboot.git] / drivers / net / 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 #include <config.h>
232
233 /*
234  *      I2C Protocol
235  */
236 static const char SysKonnectFileId[] =
237         "$Id: ski2c.c,v 1.57 2003/01/28 09:17:38 rschmidt Exp $";
238
239 #include "h/skdrv1st.h"         /* Driver Specific Definitions */
240 #include "h/lm80.h"
241 #include "h/skdrv2nd.h"         /* Adapter Control- and Driver specific Def. */
242
243 #ifdef __C2MAN__
244 /*
245         I2C protocol implementation.
246
247         General Description:
248
249         The I2C protocol is used for the temperature sensors and for
250         the serial EEPROM which hold the configuration.
251
252         This file covers functions that allow to read write and do
253         some bulk requests a specified I2C address.
254
255         The Genesis has 2 I2C buses. One for the EEPROM which holds
256         the VPD Data and one for temperature and voltage sensor.
257         The following picture shows the I2C buses, I2C devices and
258         their control registers.
259
260         Note: The VPD functions are in skvpd.c
261 .
262 .       PCI Config I2C Bus for VPD Data:
263 .
264 .                     +------------+
265 .                     | VPD EEPROM |
266 .                     +------------+
267 .                            |
268 .                            | <-- I2C
269 .                            |
270 .                +-----------+-----------+
271 .                |                       |
272 .       +-----------------+     +-----------------+
273 .       | PCI_VPD_ADR_REG |     | PCI_VPD_DAT_REG |
274 .       +-----------------+     +-----------------+
275 .
276 .
277 .       I2C Bus for LM80 sensor:
278 .
279 .                       +-----------------+
280 .                       | Temperature and |
281 .                       | Voltage Sensor  |
282 .                       |       LM80      |
283 .                       +-----------------+
284 .                               |
285 .                               |
286 .                       I2C --> |
287 .                               |
288 .                            +----+
289 .            +-------------->| OR |<--+
290 .            |               +----+   |
291 .     +------+------+                 |
292 .     |             |                 |
293 . +--------+    +--------+      +----------+
294 . | B2_I2C |    | B2_I2C |      |  B2_I2C  |
295 . | _CTRL  |    | _DATA  |      |   _SW    |
296 . +--------+    +--------+      +----------+
297 .
298         The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
299         and B2_I2C_DATA registers.
300         For driver software it is recommended to use the I2C control and
301         data register, because I2C bus timing is done by the ASIC and
302         an interrupt may be received when the I2C request is completed.
303
304         Clock Rate Timing:                      MIN     MAX     generated by
305                 VPD EEPROM:                     50 kHz  100 kHz         HW
306                 LM80 over I2C Ctrl/Data reg.    50 kHz  100 kHz         HW
307                 LM80 over B2_I2C_SW register    0       400 kHz         SW
308
309         Note:   The clock generated by the hardware is dependend on the
310                 PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
311                 clock is 50 kHz.
312  */
313 intro()
314 {}
315 #endif
316
317 #ifdef  SK_DIAG
318 /*
319  * I2C Fast Mode timing values used by the LM80.
320  * If new devices are added to the I2C bus the timing values have to be checked.
321  */
322 #ifndef I2C_SLOW_TIMING
323 #define T_CLK_LOW                       1300L   /* clock low time in ns */
324 #define T_CLK_HIGH                       600L   /* clock high time in ns */
325 #define T_DATA_IN_SETUP          100L   /* data in Set-up Time */
326 #define T_START_HOLD             600L   /* start condition hold time */
327 #define T_START_SETUP            600L   /* start condition Set-up time */
328 #define T_STOP_SETUP             600L   /* stop condition Set-up time */
329 #define T_BUS_IDLE                      1300L   /* time the bus must free after Tx */
330 #define T_CLK_2_DATA_OUT         900L   /* max. clock low to data output valid */
331 #else   /* I2C_SLOW_TIMING */
332 /* I2C Standard Mode Timing */
333 #define T_CLK_LOW                       4700L   /* clock low time in ns */
334 #define T_CLK_HIGH                      4000L   /* clock high time in ns */
335 #define T_DATA_IN_SETUP          250L   /* data in Set-up Time */
336 #define T_START_HOLD            4000L   /* start condition hold time */
337 #define T_START_SETUP           4700L   /* start condition Set-up time */
338 #define T_STOP_SETUP            4000L   /* stop condition Set-up time */
339 #define T_BUS_IDLE                      4700L   /* time the bus must free after Tx */
340 #endif  /* !I2C_SLOW_TIMING */
341
342 #define NS2BCLK(x)      (((x)*125)/10000)
343
344 /*
345  * I2C Wire Operations
346  *
347  * About I2C_CLK_LOW():
348  *
349  * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
350  * clock to low, to prevent the ASIC and the I2C data client from driving the
351  * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
352  * send an 'ACK'). See also Concentrator Bugreport No. 10192.
353  */
354 #define I2C_DATA_HIGH(IoC)      SK_I2C_SET_BIT(IoC, I2C_DATA)
355 #define I2C_DATA_LOW(IoC)       SK_I2C_CLR_BIT(IoC, I2C_DATA)
356 #define I2C_DATA_OUT(IoC)       SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
357 #define I2C_DATA_IN(IoC)        SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
358 #define I2C_CLK_HIGH(IoC)       SK_I2C_SET_BIT(IoC, I2C_CLK)
359 #define I2C_CLK_LOW(IoC)        SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
360 #define I2C_START_COND(IoC)     SK_I2C_CLR_BIT(IoC, I2C_CLK)
361
362 #define NS2CLKT(x)      ((x*125L)/10000)
363
364 /*--------------- I2C Interface Register Functions --------------- */
365
366 /*
367  * sending one bit
368  */
369 void SkI2cSndBit(
370 SK_IOC  IoC,    /* I/O Context */
371 SK_U8   Bit)    /* Bit to send */
372 {
373         I2C_DATA_OUT(IoC);
374         if (Bit) {
375                 I2C_DATA_HIGH(IoC);
376         }
377         else {
378                 I2C_DATA_LOW(IoC);
379         }
380         SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
381         I2C_CLK_HIGH(IoC);
382         SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
383         I2C_CLK_LOW(IoC);
384 }       /* SkI2cSndBit*/
385
386
387 /*
388  * Signal a start to the I2C Bus.
389  *
390  * A start is signaled when data goes to low in a high clock cycle.
391  *
392  * Ends with Clock Low.
393  *
394  * Status: not tested
395  */
396 void SkI2cStart(
397 SK_IOC  IoC)    /* I/O Context */
398 {
399         /* Init data and Clock to output lines */
400         /* Set Data high */
401         I2C_DATA_OUT(IoC);
402         I2C_DATA_HIGH(IoC);
403         /* Set Clock high */
404         I2C_CLK_HIGH(IoC);
405
406         SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
407
408         /* Set Data Low */
409         I2C_DATA_LOW(IoC);
410
411         SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
412
413         /* Clock low without Data to Input */
414         I2C_START_COND(IoC);
415
416         SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
417 }       /* SkI2cStart */
418
419
420 void SkI2cStop(
421 SK_IOC  IoC)    /* I/O Context */
422 {
423         /* Init data and Clock to output lines */
424         /* Set Data low */
425         I2C_DATA_OUT(IoC);
426         I2C_DATA_LOW(IoC);
427
428         SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
429
430         /* Set Clock high */
431         I2C_CLK_HIGH(IoC);
432
433         SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
434
435         /*
436          * Set Data High:       Do it by setting the Data Line to Input.
437          *                      Because of a pull up resistor the Data Line
438          *                      floods to high.
439          */
440         I2C_DATA_IN(IoC);
441
442         /*
443          *      When I2C activity is stopped
444          *       o      DATA should be set to input and
445          *       o      CLOCK should be set to high!
446          */
447         SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
448 }       /* SkI2cStop */
449
450
451 /*
452  * Receive just one bit via the I2C bus.
453  *
454  * Note:        Clock must be set to LOW before calling this function.
455  *
456  * Returns The received bit.
457  */
458 int SkI2cRcvBit(
459 SK_IOC  IoC)    /* I/O Context */
460 {
461         int     Bit;
462         SK_U8   I2cSwCtrl;
463
464         /* Init data as input line */
465         I2C_DATA_IN(IoC);
466
467         SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
468
469         I2C_CLK_HIGH(IoC);
470
471         SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
472
473         SK_I2C_GET_SW(IoC, &I2cSwCtrl);
474
475         Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
476
477         I2C_CLK_LOW(IoC);
478         SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
479
480         return(Bit);
481 }       /* SkI2cRcvBit */
482
483
484 /*
485  * Receive an ACK.
486  *
487  * returns      0 If acknowledged
488  *              1 in case of an error
489  */
490 int SkI2cRcvAck(
491 SK_IOC  IoC)    /* I/O Context */
492 {
493         /*
494          * Received bit must be zero.
495          */
496         return(SkI2cRcvBit(IoC) != 0);
497 }       /* SkI2cRcvAck */
498
499
500 /*
501  * Send an NACK.
502  */
503 void SkI2cSndNAck(
504 SK_IOC  IoC)    /* I/O Context */
505 {
506         /*
507          * Received bit must be zero.
508          */
509         SkI2cSndBit(IoC, 1);
510 }       /* SkI2cSndNAck */
511
512
513 /*
514  * Send an ACK.
515  */
516 void SkI2cSndAck(
517 SK_IOC IoC)     /* I/O Context */
518 {
519         /*
520          * Received bit must be zero.
521          *
522          */
523         SkI2cSndBit(IoC, 0);
524 }       /* SkI2cSndAck */
525
526
527 /*
528  * Send one byte to the I2C device and wait for ACK.
529  *
530  * Return acknowleged status.
531  */
532 int SkI2cSndByte(
533 SK_IOC  IoC,    /* I/O Context */
534 int             Byte)   /* byte to send */
535 {
536         int     i;
537
538         for (i = 0; i < 8; i++) {
539                 if (Byte & (1<<(7-i))) {
540                         SkI2cSndBit(IoC, 1);
541                 }
542                 else {
543                         SkI2cSndBit(IoC, 0);
544                 }
545         }
546
547         return(SkI2cRcvAck(IoC));
548 }       /* SkI2cSndByte */
549
550
551 /*
552  * Receive one byte and ack it.
553  *
554  * Return byte.
555  */
556 int SkI2cRcvByte(
557 SK_IOC  IoC,    /* I/O Context */
558 int             Last)   /* Last Byte Flag */
559 {
560         int     i;
561         int     Byte = 0;
562
563         for (i = 0; i < 8; i++) {
564                 Byte <<= 1;
565                 Byte |= SkI2cRcvBit(IoC);
566         }
567
568         if (Last) {
569                 SkI2cSndNAck(IoC);
570         }
571         else {
572                 SkI2cSndAck(IoC);
573         }
574
575         return(Byte);
576 }       /* SkI2cRcvByte */
577
578
579 /*
580  * Start dialog and send device address
581  *
582  * Return 0 if acknowleged, 1 in case of an error
583  */
584 int     SkI2cSndDev(
585 SK_IOC  IoC,    /* I/O Context */
586 int             Addr,   /* Device Address */
587 int             Rw)             /* Read / Write Flag */
588 {
589         SkI2cStart(IoC);
590         Rw = ~Rw;
591         Rw &= I2C_WRITE;
592         return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
593 }       /* SkI2cSndDev */
594
595 #endif  /* SK_DIAG */
596
597 /*----------------- I2C CTRL Register Functions ----------*/
598
599 /*
600  * waits for a completion of an I2C transfer
601  *
602  * returns      0:      success, transfer completes
603  *                      1:      error,   transfer does not complete, I2C transfer
604  *                                               killed, wait loop terminated.
605  */
606 int     SkI2cWait(
607 SK_AC   *pAC,   /* Adapter Context */
608 SK_IOC  IoC,    /* I/O Context */
609 int             Event)  /* complete event to wait for (I2C_READ or I2C_WRITE) */
610 {
611         SK_U64  StartTime;
612         SK_U64  CurrentTime;
613         SK_U32  I2cCtrl;
614
615         StartTime = SkOsGetTime(pAC);
616
617         do {
618                 CurrentTime = SkOsGetTime(pAC);
619
620                 if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
621
622                         SK_I2C_STOP(IoC);
623 #ifndef SK_DIAG
624                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
625 #endif  /* !SK_DIAG */
626                         return(1);
627                 }
628
629                 SK_I2C_GET_CTL(IoC, &I2cCtrl);
630
631 #ifdef xYUKON_DBG
632                 printf("StartTime=%lu, CurrentTime=%lu\n",
633                         StartTime, CurrentTime);
634                 if (kbhit()) {
635                         return(1);
636                 }
637 #endif /* YUKON_DBG */
638
639         } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
640
641         return(0);
642 }       /* SkI2cWait */
643
644
645 /*
646  * waits for a completion of an I2C transfer
647  *
648  * Returns
649  *      Nothing
650  */
651 void SkI2cWaitIrq(
652 SK_AC   *pAC,   /* Adapter Context */
653 SK_IOC  IoC)    /* I/O Context */
654 {
655         SK_SENSOR       *pSen;
656         SK_U64          StartTime;
657         SK_U32          IrqSrc;
658
659         pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
660
661         if (pSen->SenState == SK_SEN_IDLE) {
662                 return;
663         }
664
665         StartTime = SkOsGetTime(pAC);
666         do {
667                 if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
668                         SK_I2C_STOP(IoC);
669 #ifndef SK_DIAG
670                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
671 #endif  /* !SK_DIAG */
672                         return;
673                 }
674                 SK_IN32(IoC, B0_ISRC, &IrqSrc);
675         } while ((IrqSrc & IS_I2C_READY) == 0);
676
677         pSen->SenState = SK_SEN_IDLE;
678         return;
679 }       /* SkI2cWaitIrq */
680
681 /*
682  * writes a single byte or 4 bytes into the I2C device
683  *
684  * returns      0:      success
685  *                      1:      error
686  */
687 int SkI2cWrite(
688 SK_AC   *pAC,           /* Adapter Context */
689 SK_IOC  IoC,            /* I/O Context */
690 SK_U32  I2cData,        /* I2C Data to write */
691 int             I2cDev,         /* I2C Device Address */
692 int             I2cReg,         /* I2C Device Register Address */
693 int             I2cBurst)       /* I2C Burst Flag */
694 {
695         SK_OUT32(IoC, B2_I2C_DATA, I2cData);
696         SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst);
697
698         return(SkI2cWait(pAC, IoC, I2C_WRITE));
699 }       /* SkI2cWrite*/
700
701
702 #ifdef  SK_DIAG
703
704 /*
705  * reads a single byte or 4 bytes from the I2C device
706  *
707  * returns      the word read
708  */
709 SK_U32 SkI2cRead(
710 SK_AC   *pAC,           /* Adapter Context */
711 SK_IOC  IoC,            /* I/O Context */
712 int             I2cDev,         /* I2C Device Address */
713 int             I2cReg,         /* I2C Device Register Address */
714 int             I2cBurst)       /* I2C Burst Flag */
715 {
716         SK_U32  Data;
717
718         SK_OUT32(IoC, B2_I2C_DATA, 0);
719         SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst);
720
721         if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
722                 w_print("%s\n", SKERR_I2C_E002MSG);
723         }
724
725         SK_IN32(IoC, B2_I2C_DATA, &Data);
726         return(Data);
727 }       /* SkI2cRead */
728
729 #endif  /* SK_DIAG */
730
731
732 /*
733  * read a sensor's value
734  *
735  * This function reads a sensor's value from the I2C sensor chip. The sensor
736  * is defined by its index into the sensors database in the struct pAC points
737  * to.
738  * Returns
739  *              1 if the read is completed
740  *              0 if the read must be continued (I2C Bus still allocated)
741  */
742 int     SkI2cReadSensor(
743 SK_AC           *pAC,   /* Adapter Context */
744 SK_IOC          IoC,    /* I/O Context */
745 SK_SENSOR       *pSen)  /* Sensor to be read */
746 {
747     if (pSen->SenRead != NULL) {
748         return((*pSen->SenRead)(pAC, IoC, pSen));
749     }
750     else
751         return(0); /* no success */
752 }       /* SkI2cReadSensor*/
753
754 /*
755  * Do the Init state 0 initialization
756  */
757 static int SkI2cInit0(
758 SK_AC   *pAC)   /* Adapter Context */
759 {
760         int     i;
761
762         /* Begin with first sensor */
763         pAC->I2c.CurrSens = 0;
764
765         /* Begin with timeout control for state machine */
766         pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
767
768         /* Set sensor number to zero */
769         pAC->I2c.MaxSens = 0;
770
771 #ifndef SK_DIAG
772         /* Initialize Number of Dummy Reads */
773         pAC->I2c.DummyReads = SK_MAX_SENSORS;
774 #endif
775
776         for (i = 0; i < SK_MAX_SENSORS; i++) {
777                 pAC->I2c.SenTable[i].SenDesc = "unknown";
778                 pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
779                 pAC->I2c.SenTable[i].SenThreErrHigh = 0;
780                 pAC->I2c.SenTable[i].SenThreErrLow = 0;
781                 pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
782                 pAC->I2c.SenTable[i].SenThreWarnLow = 0;
783                 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
784                 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
785                 pAC->I2c.SenTable[i].SenValue = 0;
786                 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
787                 pAC->I2c.SenTable[i].SenErrCts = 0;
788                 pAC->I2c.SenTable[i].SenBegErrTS = 0;
789                 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
790                 pAC->I2c.SenTable[i].SenRead = NULL;
791                 pAC->I2c.SenTable[i].SenDev = 0;
792         }
793
794         /* Now we are "INIT data"ed */
795         pAC->I2c.InitLevel = SK_INIT_DATA;
796         return(0);
797 }       /* SkI2cInit0*/
798
799
800 /*
801  * Do the init state 1 initialization
802  *
803  * initialize the following register of the LM80:
804  * Configuration register:
805  * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
806  *
807  * Interrupt Mask Register 1:
808  * - all interrupts are Disabled (0xff)
809  *
810  * Interrupt Mask Register 2:
811  * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
812  *
813  * Fan Divisor/RST_OUT register:
814  * - Divisors set to 1 (bits 00), all others 0s.
815  *
816  * OS# Configuration/Temperature resolution Register:
817  * - all 0s
818  *
819  */
820 static int SkI2cInit1(
821 SK_AC   *pAC,   /* Adapter Context */
822 SK_IOC  IoC)    /* I/O Context */
823 {
824     int i;
825     SK_U8 I2cSwCtrl;
826         SK_GEPORT *pPrt;        /* GIni Port struct pointer */
827
828         if (pAC->I2c.InitLevel != SK_INIT_DATA) {
829                 /* ReInit not needed in I2C module */
830                 return(0);
831         }
832
833     /* Set the Direction of I2C-Data Pin to IN */
834     SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
835     /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
836         SK_I2C_GET_SW(IoC, &I2cSwCtrl);
837
838         if ((I2cSwCtrl & I2C_DATA) == 0) {
839                 /* this is a 32-Bit board */
840                 pAC->GIni.GIYukon32Bit = SK_TRUE;
841         return(0);
842     }
843
844         /* Check for 64 Bit Yukon without sensors */
845         if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_CFG, 0) != 0) {
846         return(0);
847     }
848
849         (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_1, 0);
850
851         (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_2, 0);
852
853         (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_FAN_CTRL, 0);
854
855         (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_TEMP_CTRL, 0);
856
857         (void)SkI2cWrite(pAC, IoC, LM80_CFG_START, LM80_ADDR, LM80_CFG, 0);
858
859         /*
860          * MaxSens has to be updated here, because PhyType is not
861          * set when performing Init Level 0
862          */
863     pAC->I2c.MaxSens = 5;
864
865         pPrt = &pAC->GIni.GP[0];
866
867         if (pAC->GIni.GIGenesis) {
868                 if (pPrt->PhyType == SK_PHY_BCOM) {
869                         if (pAC->GIni.GIMacsFound == 1) {
870                                 pAC->I2c.MaxSens += 1;
871                         }
872                         else {
873                                 pAC->I2c.MaxSens += 3;
874                         }
875                 }
876         }
877         else {
878                 pAC->I2c.MaxSens += 3;
879         }
880
881         for (i = 0; i < pAC->I2c.MaxSens; i++) {
882                 switch (i) {
883                 case 0:
884                         pAC->I2c.SenTable[i].SenDesc = "Temperature";
885                         pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
886                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
887                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
888                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
889                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
890                         pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
891                         break;
892                 case 1:
893                         pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
894                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
895                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
896                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
897                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
898                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
899                         pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
900                         break;
901                 case 2:
902                         pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
903                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
904                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
905                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
906                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
907                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
908                         pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
909                         pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
910                         break;
911                 case 3:
912                         pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
913                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
914                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
915                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
916                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
917                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
918                         pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
919                         break;
920                 case 4:
921                         if (pAC->GIni.GIGenesis) {
922                                 if (pPrt->PhyType == SK_PHY_BCOM) {
923                                         pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
924                                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
925                                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
926                                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
927                                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
928                                 }
929                                 else {
930                                         pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
931                                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
932                                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
933                                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
934                                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
935                                 }
936                         }
937                         else {
938                                 pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
939                                 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
940                                 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
941                                 if (pAC->GIni.GIVauxAvail) {
942                                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
943                                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
944                                 }
945                                 else {
946                                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
947                                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
948                                 }
949                         }
950                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
951                         pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
952                         break;
953                 case 5:
954                         if (pAC->GIni.GIGenesis) {
955                                 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
956                                 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
957                                 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
958                                 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
959                                 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
960                         }
961                         else {
962                                 pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC-Co 1V5";
963                                 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
964                                 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
965                                 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
966                                 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
967                         }
968                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
969                         pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
970                         break;
971                 case 6:
972                         if (pAC->GIni.GIGenesis) {
973                                 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
974                         }
975                         else {
976                                 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
977                         }
978                         pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
979                         pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
980                         pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
981                         pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
982                         pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
983                         pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
984                         break;
985                 case 7:
986                         if (pAC->GIni.GIGenesis) {
987                                 pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
988                                 pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
989                                 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
990                                 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
991                                 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
992                                 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
993                                 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
994                         }
995                         else {
996                                 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
997                                 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
998                                 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
999                                 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
1000                                 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
1001                                 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
1002                                 pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
1003                         }
1004                         break;
1005                 default:
1006                         SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
1007                                 SKERR_I2C_E001, SKERR_I2C_E001MSG);
1008                         break;
1009                 }
1010
1011                 pAC->I2c.SenTable[i].SenValue = 0;
1012                 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
1013                 pAC->I2c.SenTable[i].SenErrCts = 0;
1014                 pAC->I2c.SenTable[i].SenBegErrTS = 0;
1015                 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
1016                 pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
1017                 pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
1018         }
1019
1020 #ifndef SK_DIAG
1021         pAC->I2c.DummyReads = pAC->I2c.MaxSens;
1022 #endif  /* !SK_DIAG */
1023
1024         /* Clear I2C IRQ */
1025         SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
1026
1027         /* Now we are I/O initialized */
1028         pAC->I2c.InitLevel = SK_INIT_IO;
1029         return(0);
1030 }       /* SkI2cInit1 */
1031
1032
1033 /*
1034  * Init level 2: Start first sensor read.
1035  */
1036 static int SkI2cInit2(
1037 SK_AC   *pAC,   /* Adapter Context */
1038 SK_IOC  IoC)    /* I/O Context */
1039 {
1040         int             ReadComplete;
1041         SK_SENSOR       *pSen;
1042
1043         if (pAC->I2c.InitLevel != SK_INIT_IO) {
1044                 /* ReInit not needed in I2C module */
1045                 /* Init0 and Init2 not permitted */
1046                 return(0);
1047         }
1048
1049         pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1050         ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1051
1052         if (ReadComplete) {
1053                 SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
1054         }
1055
1056         /* Now we are correctly initialized */
1057         pAC->I2c.InitLevel = SK_INIT_RUN;
1058
1059         return(0);
1060 }       /* SkI2cInit2*/
1061
1062
1063 /*
1064  * Initialize I2C devices
1065  *
1066  * Get the first voltage value and discard it.
1067  * Go into temperature read mode. A default pointer is not set.
1068  *
1069  * The things to be done depend on the init level in the parameter list:
1070  * Level 0:
1071  *      Initialize only the data structures. Do NOT access hardware.
1072  * Level 1:
1073  *      Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
1074  * Level 2:
1075  *      Everything is possible. Interrupts may be used from now on.
1076  *
1077  * return:
1078  *      0 = success
1079  *      other = error.
1080  */
1081 int     SkI2cInit(
1082 SK_AC   *pAC,   /* Adapter Context */
1083 SK_IOC  IoC,    /* I/O Context needed in levels 1 and 2 */
1084 int             Level)  /* Init Level */
1085 {
1086
1087         switch (Level) {
1088         case SK_INIT_DATA:
1089                 return(SkI2cInit0(pAC));
1090         case SK_INIT_IO:
1091                 return(SkI2cInit1(pAC, IoC));
1092         case SK_INIT_RUN:
1093                 return(SkI2cInit2(pAC, IoC));
1094         default:
1095                 break;
1096         }
1097
1098         return(0);
1099 }       /* SkI2cInit */
1100
1101
1102 #ifndef SK_DIAG
1103
1104 /*
1105  * Interrupt service function for the I2C Interface
1106  *
1107  * Clears the Interrupt source
1108  *
1109  * Reads the register and check it for sending a trap.
1110  *
1111  * Starts the timer if necessary.
1112  */
1113 void SkI2cIsr(
1114 SK_AC   *pAC,   /* Adapter Context */
1115 SK_IOC  IoC)    /* I/O Context */
1116 {
1117         SK_EVPARA       Para;
1118
1119         /* Clear I2C IRQ */
1120         SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
1121
1122         Para.Para64 = 0;
1123         SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
1124 }       /* SkI2cIsr */
1125
1126
1127 /*
1128  * Check this sensors Value against the threshold and send events.
1129  */
1130 static void SkI2cCheckSensor(
1131 SK_AC           *pAC,   /* Adapter Context */
1132 SK_SENSOR       *pSen)
1133 {
1134         SK_EVPARA       ParaLocal;
1135         SK_BOOL         TooHigh;        /* Is sensor too high? */
1136         SK_BOOL         TooLow;         /* Is sensor too low? */
1137         SK_U64          CurrTime;       /* Current Time */
1138         SK_BOOL         DoTrapSend;     /* We need to send a trap */
1139         SK_BOOL         DoErrLog;       /* We need to log the error */
1140         SK_BOOL         IsError;        /* We need to log the error */
1141
1142         /* Check Dummy Reads first */
1143         if (pAC->I2c.DummyReads > 0) {
1144                 pAC->I2c.DummyReads--;
1145                 return;
1146         }
1147
1148         /* Get the current time */
1149         CurrTime = SkOsGetTime(pAC);
1150
1151         /* Set para to the most useful setting: The current sensor. */
1152         ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
1153
1154         /* Check the Value against the thresholds. First: Error Thresholds */
1155         TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
1156         TooLow = (pSen->SenValue < pSen->SenThreErrLow);
1157
1158         IsError = SK_FALSE;
1159         if (TooHigh || TooLow) {
1160                 /* Error condition is satisfied */
1161                 DoTrapSend = SK_TRUE;
1162                 DoErrLog = SK_TRUE;
1163
1164                 /* Now error condition is satisfied */
1165                 IsError = SK_TRUE;
1166
1167                 if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
1168                         /* This state is the former one */
1169
1170                         /* So check first whether we have to send a trap */
1171                         if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
1172                             CurrTime) {
1173                                 /*
1174                                  * Do NOT send the Trap. The hold back time
1175                                  * has to run out first.
1176                                  */
1177                                 DoTrapSend = SK_FALSE;
1178                         }
1179
1180                         /* Check now whether we have to log an Error */
1181                         if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
1182                             CurrTime) {
1183                                 /*
1184                                  * Do NOT log the error. The hold back time
1185                                  * has to run out first.
1186                                  */
1187                                 DoErrLog = SK_FALSE;
1188                         }
1189                 }
1190                 else {
1191                         /* We came from a different state -> Set Begin Time Stamp */
1192                         pSen->SenBegErrTS = CurrTime;
1193                         pSen->SenErrFlag = SK_SEN_ERR_ERR;
1194                 }
1195
1196                 if (DoTrapSend) {
1197                         /* Set current Time */
1198                         pSen->SenLastErrTrapTS = CurrTime;
1199                         pSen->SenErrCts++;
1200
1201                         /* Queue PNMI Event */
1202                         SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1203                                 SK_PNMI_EVT_SEN_ERR_UPP :
1204                                 SK_PNMI_EVT_SEN_ERR_LOW),
1205                                 ParaLocal);
1206                 }
1207
1208                 if (DoErrLog) {
1209                         /* Set current Time */
1210                         pSen->SenLastErrLogTS = CurrTime;
1211
1212                         if (pSen->SenType == SK_SEN_TEMP) {
1213                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011,
1214                                         SKERR_I2C_E011MSG);
1215                         } else if (pSen->SenType == SK_SEN_VOLT) {
1216                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012,
1217                                         SKERR_I2C_E012MSG);
1218                         } else
1219                         {
1220                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015,
1221                                         SKERR_I2C_E015MSG);
1222                         }
1223                 }
1224         }
1225
1226         /* Check the Value against the thresholds */
1227         /* 2nd: Warning thresholds */
1228         TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
1229         TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
1230
1231         if (!IsError && (TooHigh || TooLow)) {
1232                 /* Error condition is satisfied */
1233                 DoTrapSend = SK_TRUE;
1234                 DoErrLog = SK_TRUE;
1235
1236                 if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
1237                         /* This state is the former one */
1238
1239                         /* So check first whether we have to send a trap */
1240                         if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD >
1241                             CurrTime) {
1242                                 /*
1243                                  * Do NOT send the Trap. The hold back time
1244                                  * has to run out first.
1245                                  */
1246                                 DoTrapSend = SK_FALSE;
1247                         }
1248
1249                         /* Check now whether we have to log an Error */
1250                         if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD >
1251                             CurrTime) {
1252                                 /*
1253                                  * Do NOT log the error. The hold back time
1254                                  * has to run out first.
1255                                  */
1256                                 DoErrLog = SK_FALSE;
1257                         }
1258                 }
1259                 else {
1260                         /* We came from a different state -> Set Begin Time Stamp */
1261                         pSen->SenBegWarnTS = CurrTime;
1262                         pSen->SenErrFlag = SK_SEN_ERR_WARN;
1263                 }
1264
1265                 if (DoTrapSend) {
1266                         /* Set current Time */
1267                         pSen->SenLastWarnTrapTS = CurrTime;
1268                         pSen->SenWarnCts++;
1269
1270                         /* Queue PNMI Event */
1271                         SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1272                                 SK_PNMI_EVT_SEN_WAR_UPP :
1273                                 SK_PNMI_EVT_SEN_WAR_LOW),
1274                                 ParaLocal);
1275                 }
1276
1277                 if (DoErrLog) {
1278                         /* Set current Time */
1279                         pSen->SenLastWarnLogTS = CurrTime;
1280
1281                         if (pSen->SenType == SK_SEN_TEMP) {
1282                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009,
1283                                         SKERR_I2C_E009MSG);
1284                         } else if (pSen->SenType == SK_SEN_VOLT) {
1285                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010,
1286                                         SKERR_I2C_E010MSG);
1287                         } else
1288                         {
1289                                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014,
1290                                         SKERR_I2C_E014MSG);
1291                         }
1292                 }
1293         }
1294
1295         /* Check for NO error at all */
1296         if (!IsError && !TooHigh && !TooLow) {
1297                 /* Set o.k. Status if no error and no warning condition */
1298                 pSen->SenErrFlag = SK_SEN_ERR_OK;
1299         }
1300
1301         /* End of check against the thresholds */
1302
1303         /* Bug fix AF: 16.Aug.2001: Correct the init base
1304          * of LM80 sensor.
1305          */
1306         if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
1307
1308         pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1309
1310                 if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
1311                         /* 5V PCI-IO Voltage */
1312                         pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
1313                         pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
1314                 }
1315                 else {
1316                         /* 3.3V PCI-IO Voltage */
1317                         pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
1318                         pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
1319                 }
1320         }
1321
1322 #if 0
1323     /* Dynamic thresholds also for VAUX of LM80 sensor */
1324         if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
1325
1326         pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1327
1328                 /* 3.3V VAUX Voltage */
1329                 if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
1330                         pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
1331                         pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
1332                 }
1333                 /* 0V VAUX Voltage */
1334                 else {
1335                         pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
1336                         pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
1337                 }
1338         }
1339
1340         /*
1341          * Check initialization state:
1342          * The VIO Thresholds need adaption
1343          */
1344         if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1345              pSen->SenValue > SK_SEN_WARNLOW2C &&
1346              pSen->SenValue < SK_SEN_WARNHIGH2) {
1347                 pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
1348                 pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
1349                 pSen->SenInit = SK_TRUE;
1350         }
1351
1352         if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1353              pSen->SenValue > SK_SEN_WARNLOW2 &&
1354              pSen->SenValue < SK_SEN_WARNHIGH2C) {
1355                 pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
1356                 pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
1357                 pSen->SenInit = SK_TRUE;
1358         }
1359 #endif
1360
1361         if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
1362                 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
1363         }
1364 }       /* SkI2cCheckSensor*/
1365
1366
1367 /*
1368  * The only Event to be served is the timeout event
1369  *
1370  */
1371 int     SkI2cEvent(
1372 SK_AC           *pAC,   /* Adapter Context */
1373 SK_IOC          IoC,    /* I/O Context */
1374 SK_U32          Event,  /* Module specific Event */
1375 SK_EVPARA       Para)   /* Event specific Parameter */
1376 {
1377         int                     ReadComplete;
1378         SK_SENSOR       *pSen;
1379         SK_U32          Time;
1380         SK_EVPARA       ParaLocal;
1381         int                     i;
1382
1383         /* New case: no sensors */
1384         if (pAC->I2c.MaxSens == 0) {
1385                 return(0);
1386         }
1387
1388         switch (Event) {
1389         case SK_I2CEV_IRQ:
1390                 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1391                 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1392
1393                 if (ReadComplete) {
1394                         /* Check sensor against defined thresholds */
1395                         SkI2cCheckSensor (pAC, pSen);
1396
1397                         /* Increment Current sensor and set appropriate Timeout */
1398                         pAC->I2c.CurrSens++;
1399                         if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
1400                                 pAC->I2c.CurrSens = 0;
1401                                 Time = SK_I2C_TIM_LONG;
1402                         }
1403                         else {
1404                                 Time = SK_I2C_TIM_SHORT;
1405                         }
1406
1407                         /* Start Timer */
1408                         ParaLocal.Para64 = (SK_U64)0;
1409
1410                         pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1411
1412                         SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1413                                 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1414                 }
1415         else {
1416                         /* Start Timer */
1417                         ParaLocal.Para64 = (SK_U64)0;
1418
1419                         pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
1420
1421             SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
1422                                 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1423                 }
1424                 break;
1425         case SK_I2CEV_TIM:
1426                 if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
1427
1428                         ParaLocal.Para64 = (SK_U64)0;
1429                         SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
1430
1431                         pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1432                         ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1433
1434                         if (ReadComplete) {
1435                                 /* Check sensor against defined thresholds */
1436                                 SkI2cCheckSensor (pAC, pSen);
1437
1438                                 /* Increment Current sensor and set appropriate Timeout */
1439                                 pAC->I2c.CurrSens++;
1440                                 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1441                                         pAC->I2c.CurrSens = 0;
1442                                         Time = SK_I2C_TIM_LONG;
1443                                 }
1444                                 else {
1445                                         Time = SK_I2C_TIM_SHORT;
1446                                 }
1447
1448                                 /* Start Timer */
1449                                 ParaLocal.Para64 = (SK_U64)0;
1450
1451                                 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1452
1453                                 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1454                                         SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1455                         }
1456                 }
1457                 else {
1458                         pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1459                         pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
1460                         SK_I2C_STOP(IoC);
1461
1462                         /* Increment Current sensor and set appropriate Timeout */
1463                         pAC->I2c.CurrSens++;
1464                         if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1465                                 pAC->I2c.CurrSens = 0;
1466                                 Time = SK_I2C_TIM_LONG;
1467                         }
1468                         else {
1469                                 Time = SK_I2C_TIM_SHORT;
1470                         }
1471
1472                         /* Start Timer */
1473                         ParaLocal.Para64 = (SK_U64)0;
1474
1475                         pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1476
1477                         SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1478                                 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1479                 }
1480                 break;
1481         case SK_I2CEV_CLEAR:
1482                 for (i = 0; i < SK_MAX_SENSORS; i++) {
1483                         pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
1484                         pAC->I2c.SenTable[i].SenErrCts = 0;
1485                         pAC->I2c.SenTable[i].SenWarnCts = 0;
1486                         pAC->I2c.SenTable[i].SenBegErrTS = 0;
1487                         pAC->I2c.SenTable[i].SenBegWarnTS = 0;
1488                         pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
1489                         pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
1490                         pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
1491                         pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
1492                 }
1493                 break;
1494         default:
1495                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
1496         }
1497
1498         return(0);
1499 }       /* SkI2cEvent*/
1500
1501 #endif  /* !SK_DIAG */