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