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